@@ -54,7 +54,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
54
54
SPIName spi_ssel = (SPIName )pinmap_peripheral (ssel , PinMap_SPI_SSEL );
55
55
SPIName spi_data = (SPIName )pinmap_merge (spi_mosi , spi_miso );
56
56
SPIName spi_cntl = (SPIName )pinmap_merge (spi_sclk , spi_ssel );
57
-
57
+
58
58
obj -> spi = (SPI_Type * )pinmap_merge (spi_data , spi_cntl );
59
59
if ((int )obj -> spi == NC ) {
60
60
error ("SPI pinout mapping failed" );
@@ -63,9 +63,8 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
63
63
SIM -> SCGC5 |= SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK ;
64
64
SIM -> SCGC6 |= SIM_SCGC6_SPI0_MASK ;
65
65
66
- // halted state
67
- obj -> spi -> MCR &= ~SPI_MCR_MDIS_MASK ;
68
- obj -> spi -> MCR |= SPI_MCR_HALT_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK ;
66
+ obj -> spi -> MCR &= ~(SPI_MCR_MDIS_MASK | SPI_MCR_HALT_MASK );
67
+ //obj->spi->MCR |= SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK;
69
68
70
69
// set default format and frequency
71
70
if (ssel == NC ) {
@@ -77,8 +76,6 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
77
76
78
77
// not halt in the debug mode
79
78
obj -> spi -> SR |= SPI_SR_EOQF_MASK ;
80
- // enable SPI
81
- obj -> spi -> MCR &= (~SPI_MCR_HALT_MASK );
82
79
83
80
// pin out the spi pins
84
81
pinmap_pinout (mosi , PinMap_SPI_MOSI );
@@ -93,9 +90,9 @@ void spi_free(spi_t *obj) {
93
90
// [TODO]
94
91
}
95
92
void spi_format (spi_t * obj , int bits , int mode , int slave ) {
96
- if ((bits != 8 ) && (bits != 16 )) {
97
- error ("Only 8/16 bits SPI supported" );
98
- }
93
+ if ((bits < 4 ) || (bits > 16 ))
94
+ error ("SPI: Only frames between 4 and 16-bit supported" );
95
+
99
96
100
97
if ((mode < 0 ) || (mode > 3 )) {
101
98
error ("SPI mode unsupported" );
@@ -109,64 +106,61 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
109
106
obj -> spi -> MCR |= ((!slave ) << SPI_MCR_MSTR_SHIFT );
110
107
111
108
// CTAR0 is used
112
- obj -> spi -> CTAR [0 ] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK );
113
- obj -> spi -> CTAR [0 ] |= (polarity << SPI_CTAR_CPOL_SHIFT ) | (phase << SPI_CTAR_CPHA_SHIFT );
109
+ obj -> spi -> CTAR [0 ] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_FMSZ_MASK );
110
+ obj -> spi -> CTAR [0 ] |= (polarity << SPI_CTAR_CPOL_SHIFT ) | (phase << SPI_CTAR_CPHA_SHIFT ) | (( bits - 1 ) << SPI_CTAR_FMSZ_SHIFT ) ;
114
111
}
115
112
116
113
static const uint8_t baudrate_prescaler [] = {2 ,3 ,5 ,7 };
117
- static const uint32_t baudrate_scaler [] = {2 , 4 , 6 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 };
118
- static const uint8_t delay_prescaler [] = {1 , 3 , 5 , 7 };
114
+ static const uint16_t baudrate_scaler [] = {2 ,4 ,6 ,8 ,16 ,32 ,64 ,128 ,256 ,512 ,1024 ,2048 ,4096 ,8192 ,16384 ,32768 };
119
115
120
116
void spi_frequency (spi_t * obj , int hz ) {
121
- uint32_t error = 0 ;
117
+ uint32_t f_error = 0 ;
122
118
uint32_t p_error = 0xffffffff ;
123
119
uint32_t ref = 0 ;
124
120
uint32_t br = 0 ;
125
121
uint32_t ref_spr = 0 ;
126
122
uint32_t ref_prescaler = 0 ;
123
+ uint32_t ref_dr = 0 ;
127
124
128
125
// bus clk
129
126
uint32_t PCLK = bus_frequency ();
130
- uint32_t divisor = 2 ;
131
- uint32_t prescaler ;
132
127
133
- /* TODO */
134
128
for (uint32_t i = 0 ; i < 4 ; i ++ ) {
135
- prescaler = baudrate_prescaler [i ];
136
- divisor = 2 ;
137
- for (br = 0 ; br <= 15 ; br ++ , divisor *= 2 ) {
129
+ for (br = 0 ; br <= 15 ; br ++ ) {
138
130
for (uint32_t dr = 0 ; dr < 2 ; dr ++ ) {
139
- ref = (PCLK / prescaler ) * (( 1U + dr ) / divisor ) ;
131
+ ref = (PCLK * (1U + dr ) / baudrate_prescaler [ i ]) / baudrate_scaler [ br ] ;
140
132
if (ref > (uint32_t )hz )
141
133
continue ;
142
- error = hz - ref ;
143
- if (error < p_error ) {
134
+ f_error = hz - ref ;
135
+ if (f_error < p_error ) {
144
136
ref_spr = br ;
145
137
ref_prescaler = i ;
146
- p_error = error ;
138
+ ref_dr = dr ;
139
+ p_error = f_error ;
147
140
}
148
141
}
149
142
}
150
143
}
151
144
152
145
// set PBR and BR
153
- obj -> spi -> CTAR [0 ] = ((ref_prescaler & 0x3 ) << SPI_CTAR_PBR_SHIFT ) | (ref_spr & 0xf );
146
+ obj -> spi -> CTAR [0 ] &= ~(SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK | SPI_CTAR_DBR_MASK );
147
+ obj -> spi -> CTAR [0 ] |= (ref_prescaler << SPI_CTAR_PBR_SHIFT ) | (ref_spr << SPI_CTAR_BR_SHIFT ) | (ref_dr << SPI_CTAR_DBR_SHIFT );
154
148
}
155
149
156
150
static inline int spi_writeable (spi_t * obj ) {
157
151
return (obj -> spi -> SR & SPI_SR_TFFF_MASK ) ? 1 : 0 ;
158
152
}
159
153
160
154
static inline int spi_readable (spi_t * obj ) {
161
- return (obj -> spi -> SR & SPI_SR_RFDF_MASK ) ? 0 : 1 ;
155
+ return (obj -> spi -> SR & SPI_SR_RFDF_MASK ) ? 1 : 0 ;
162
156
}
163
157
164
158
int spi_master_write (spi_t * obj , int value ) {
159
+ //clear RX buffer flag
160
+ obj -> spi -> SR |= SPI_SR_RFDF_MASK ;
165
161
// wait tx buffer empty
166
162
while (!spi_writeable (obj ));
167
- obj -> spi -> PUSHR = SPI_PUSHR_TXDATA (value & 0xff ) /*| SPI_PUSHR_EOQ_MASK*/ ;
168
-
169
- while (!obj -> spi -> SR & SPI_SR_TCF_MASK ); // wait for transfer to be complete
163
+ obj -> spi -> PUSHR = SPI_PUSHR_TXDATA (value & 0xffff ) /*| SPI_PUSHR_EOQ_MASK*/ ;
170
164
171
165
// wait rx buffer full
172
166
while (!spi_readable (obj ));
0 commit comments