@@ -59,11 +59,12 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
59
59
error ("SPI pinout mapping failed" );
60
60
}
61
61
62
- SIM -> SCGC5 |= ( 1 << 11 ) | ( 1 << 12 ); // PortC & D
63
- SIM -> SCGC6 |= 1 << 12 ; // spi clocks
62
+ SIM -> SCGC5 |= SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK ;
63
+ SIM -> SCGC6 |= SIM_SCGC6_SPI0_MASK ;
64
64
65
65
// halted state
66
- obj -> spi -> MCR = SPI_MCR_HALT_MASK ;
66
+ obj -> spi -> MCR &= ~SPI_MCR_MDIS_MASK ;
67
+ obj -> spi -> MCR |= SPI_MCR_HALT_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK ;
67
68
68
69
// set default format and frequency
69
70
if (ssel == NC ) {
@@ -111,50 +112,60 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
111
112
obj -> spi -> CTAR [0 ] |= (polarity << SPI_CTAR_CPOL_SHIFT ) | (phase << SPI_CTAR_CPHA_SHIFT );
112
113
}
113
114
115
+ static const uint8_t baudrate_prescaler [] = {2 ,3 ,5 ,7 };
116
+ static const uint32_t baudrate_scaler [] = {2 , 4 , 6 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 };
117
+ static const uint8_t delay_prescaler [] = {1 , 3 , 5 , 7 };
118
+
114
119
void spi_frequency (spi_t * obj , int hz ) {
115
120
uint32_t error = 0 ;
116
121
uint32_t p_error = 0xffffffff ;
117
122
uint32_t ref = 0 ;
118
- uint32_t spr = 0 ;
123
+ uint32_t br = 0 ;
119
124
uint32_t ref_spr = 0 ;
120
125
uint32_t ref_prescaler = 0 ;
121
126
122
127
// bus clk
123
- uint32_t PCLK = 48000000u ;
124
- uint32_t prescaler = 1 ;
128
+ uint32_t PCLK = SystemCoreClock ;
125
129
uint32_t divisor = 2 ;
130
+ uint32_t prescaler ;
126
131
127
- for (prescaler = 1 ; prescaler <= 8 ; prescaler ++ ) {
132
+ /* TODO */
133
+ for (uint32_t i = 0 ; i < 4 ; i ++ ) {
134
+ prescaler = baudrate_prescaler [i ];
128
135
divisor = 2 ;
129
- for (spr = 0 ; spr <= 8 ; spr ++ , divisor *= 2 ) {
130
- ref = PCLK / (prescaler * divisor );
131
- if (ref > (uint32_t )hz )
132
- continue ;
133
- error = hz - ref ;
134
- if (error < p_error ) {
135
- ref_spr = spr ;
136
- ref_prescaler = prescaler - 1 ;
137
- p_error = error ;
136
+ for (br = 0 ; br <= 15 ; br ++ , divisor *= 2 ) {
137
+ for (uint32_t dr = 0 ; dr < 2 ; dr ++ ) {
138
+ ref = (PCLK / prescaler ) * ((1U + dr ) / divisor );
139
+ if (ref > (uint32_t )hz )
140
+ continue ;
141
+ error = hz - ref ;
142
+ if (error < p_error ) {
143
+ ref_spr = br ;
144
+ ref_prescaler = i ;
145
+ p_error = error ;
146
+ }
138
147
}
139
148
}
140
149
}
141
150
142
- // set SPPR and SPR
143
- obj -> spi -> CTAR [0 ] = ((ref_prescaler & 0x7 ) << 4 ) | (ref_spr & 0xf );
151
+ // set PBR and BR
152
+ obj -> spi -> CTAR [0 ] = ((ref_prescaler & 0x3 ) << SPI_CTAR_PBR_SHIFT ) | (ref_spr & 0xf );
144
153
}
145
154
146
- static inline int spi_writeable (spi_t * obj ) {
147
- return (obj -> spi -> SR & SPI_SR_TCF_MASK ) ? 1 : 0 ;
155
+ static inline int spi_writeable (spi_t * obj ) {
156
+ return (obj -> spi -> SR & SPI_SR_TFFF_MASK ) ? 1 : 0 ;
148
157
}
149
158
150
- static inline int spi_readable (spi_t * obj ) {
151
- return (obj -> spi -> SR & SPI_SR_TFFF_MASK ) ? 1 : 0 ;
159
+ static inline int spi_readable (spi_t * obj ) {
160
+ return (obj -> spi -> SR & SPI_SR_RFDF_MASK ) ? 0 : 1 ;
152
161
}
153
162
154
163
int spi_master_write (spi_t * obj , int value ) {
155
164
// wait tx buffer empty
156
165
while (!spi_writeable (obj ));
157
- obj -> spi -> PUSHR = SPI_PUSHR_TXDATA (value & 0xff );
166
+ obj -> spi -> PUSHR = SPI_PUSHR_TXDATA (value & 0xff ) /*| SPI_PUSHR_EOQ_MASK*/ ;
167
+
168
+ while (!obj -> spi -> SR & SPI_SR_TCF_MASK ); // wait for transfer to be complete
158
169
159
170
// wait rx buffer full
160
171
while (!spi_readable (obj ));
0 commit comments