20
20
#include "cmsis.h"
21
21
#include "pinmap.h"
22
22
#include "error.h"
23
+ #include "fsl_clock_manager.h"
24
+ #include "fsl_dspi_hal.h"
23
25
24
26
static const PinMap PinMap_SPI_SCLK [] = {
25
27
@@ -42,40 +44,98 @@ static const PinMap PinMap_SPI_SSEL[] = {
42
44
};
43
45
44
46
void spi_init (spi_t * obj , PinName mosi , PinName miso , PinName sclk , PinName ssel ) {
45
-
47
+ // determine the SPI to use
48
+ uint32_t spi_mosi = pinmap_peripheral (mosi , PinMap_SPI_MOSI );
49
+ uint32_t spi_miso = pinmap_peripheral (miso , PinMap_SPI_MISO );
50
+ uint32_t spi_sclk = pinmap_peripheral (sclk , PinMap_SPI_SCLK );
51
+ uint32_t spi_ssel = pinmap_peripheral (ssel , PinMap_SPI_SSEL );
52
+ uint32_t spi_data = pinmap_merge (spi_mosi , spi_miso );
53
+ uint32_t spi_cntl = pinmap_merge (spi_sclk , spi_ssel );
54
+
55
+ obj -> instance = pinmap_merge (spi_data , spi_cntl );
56
+ if ((int )obj -> instance == NC ) {
57
+ error ("SPI pinout mapping failed" );
58
+ }
59
+
60
+ // enable power and clocking
61
+ clock_manager_set_gate (kClockModuleSPI , obj -> instance , true);
62
+
63
+ dspi_hal_disable (obj -> instance );
64
+ // set default format and frequency
65
+ if (ssel == NC ) {
66
+ spi_format (obj , 8 , 0 , 0 ); // 8 bits, mode 0, master
67
+ } else {
68
+ spi_format (obj , 8 , 0 , 1 ); // 8 bits, mode 0, slave
69
+ }
70
+ spi_frequency (obj , 1000000 );
71
+
72
+ dspi_hal_enable (obj -> instance );
73
+
74
+ // pin out the spi pins
75
+ pinmap_pinout (mosi , PinMap_SPI_MOSI );
76
+ pinmap_pinout (miso , PinMap_SPI_MISO );
77
+ pinmap_pinout (sclk , PinMap_SPI_SCLK );
78
+ if (ssel != NC ) {
79
+ pinmap_pinout (ssel , PinMap_SPI_SSEL );
80
+ }
46
81
}
47
82
48
83
void spi_free (spi_t * obj ) {
49
84
// [TODO]
50
85
}
51
86
void spi_format (spi_t * obj , int bits , int mode , int slave ) {
52
-
87
+ dspi_data_format_config_t config = {0 };
88
+ config .bitsPerFrame = (uint32_t )bits ;
89
+ config .clkPolarity = (mode & 0x2 ) ? kDspiClockPolarity_ActiveLow : kDspiClockPolarity_ActiveHigh ;
90
+ config .clkPhase = (mode & 0x1 ) ? kDspiClockPhase_SecondEdge : kDspiClockPhase_FirstEdge ;
91
+ config .direction = kDspiMsbFirst ;
92
+ dspi_status_t result = dspi_hal_configure_data_format (obj -> instance , kDspiCtar0 , & config );
93
+ if (result != kStatus_DSPI_Success ) {
94
+ error ("Failed to configure SPI data format" );
95
+ }
96
+
97
+ if (slave ) {
98
+ dspi_hal_set_master_slave (obj -> instance , kDspiSlave );
99
+ } else {
100
+ dspi_hal_set_master_slave (obj -> instance , kDspiMaster );
101
+ }
53
102
}
54
103
55
104
void spi_frequency (spi_t * obj , int hz ) {
56
-
105
+ uint32_t busClock ;
106
+ clock_manager_get_frequency (kBusClock , & busClock );
107
+ dspi_hal_set_baud (obj -> instance , kDspiCtar0 , hz , busClock );
57
108
}
58
109
59
110
static inline int spi_writeable (spi_t * obj ) {
60
- return 1 ;
111
+ return dspi_hal_get_status_flag ( obj -> instance , kDspiTxFifoFillRequest ) ;
61
112
}
62
113
63
114
static inline int spi_readable (spi_t * obj ) {
64
- return 1 ;
115
+ return dspi_hal_get_status_flag ( obj -> instance , kDspiRxFifoDrainRequest ) ;
65
116
}
66
117
67
118
int spi_master_write (spi_t * obj , int value ) {
68
- return 1 ;
119
+ // wait tx buffer empty
120
+ while (!spi_writeable (obj ));
121
+ dspi_command_config_t command = {0 };
122
+ command .isEndOfQueue = true;
123
+ dspi_hal_write_data_master_mode (obj -> instance , & command , (uint16_t )value );
124
+
125
+ // wait rx buffer full
126
+ while (!spi_readable (obj ));
127
+ return dspi_hal_read_data (obj -> instance ) & 0xff ;
69
128
}
70
129
71
130
int spi_slave_receive (spi_t * obj ) {
72
- return 1 ;
131
+ return spi_readable ( obj ) ;
73
132
}
74
133
75
134
int spi_slave_read (spi_t * obj ) {
76
- return 1 ;
135
+ return dspi_hal_read_data ( obj -> instance ) ;
77
136
}
78
137
79
138
void spi_slave_write (spi_t * obj , int value ) {
80
-
139
+ while (!spi_writeable (obj ));
140
+ dspi_hal_write_data_slave_mode (obj -> instance , (uint32_t )value );
81
141
}
0 commit comments