@@ -91,30 +91,42 @@ static const spi_pins board_spi_pins[] __FLASH__ = {
9191 */
9292
9393SPIClass::SPIClass (uint32 spi_num) {
94+
95+ _currentSetting=&_settings[spi_num-1 ];// SPI channels are called 1 2 and 3 but the array is zero indexed
96+
97+
9498 switch (spi_num) {
9599#if BOARD_NR_SPI >= 1
96100 case 1 :
97- this ->spi_d = SPI1;
101+ _currentSetting ->spi_d = SPI1;
98102 break ;
99103#endif
100104#if BOARD_NR_SPI >= 2
101105 case 2 :
102- this ->spi_d = SPI2;
106+ _currentSetting ->spi_d = SPI2;
103107 break ;
104108#endif
105109#if BOARD_NR_SPI >= 3
106110 case 3 :
107- this ->spi_d = SPI3;
111+ _currentSetting ->spi_d = SPI3;
108112 break ;
109113#endif
110114 default :
111115 ASSERT (0 );
112116 }
113-
114- bitOrder=MSBFIRST;
115- // pinMode(BOARD_SPI_DEFAULT_SS,OUTPUT);
116-
117117
118+ // Init things specific to each SPI device
119+ // clock divider setup is a bit of hack, and needs to be improved at a later date.
120+ _settings[0 ].spi_d = SPI1;
121+ _settings[0 ].clockDivider = determine_baud_rate (_settings[0 ].spi_d , _settings[0 ].clock );
122+ _settings[1 ].spi_d = SPI2;
123+ _settings[1 ].clockDivider = determine_baud_rate (_settings[1 ].spi_d , _settings[1 ].clock );
124+ #if BOARD_NR_SPI >= 3
125+ _settings[2 ].spi_d = SPI3;
126+ _settings[2 ].clockDivider = determine_baud_rate (_settings[2 ].spi_d , _settings[2 ].clock );
127+ #endif
128+
129+ // pinMode(BOARD_SPI_DEFAULT_SS,OUTPUT);
118130}
119131
120132/*
@@ -123,45 +135,45 @@ SPIClass::SPIClass(uint32 spi_num) {
123135
124136void SPIClass::begin (void ) {
125137
126- uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE | SPI_SOFT_SS);
127- spi_init (spi_d);
128- configure_gpios (spi_d, 1 );
138+ uint32 flags = ((_currentSetting-> bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE | SPI_SOFT_SS);
139+ spi_init (_currentSetting-> spi_d );
140+ configure_gpios (_currentSetting-> spi_d , 1 );
129141 #ifdef SPI_DEBUG
130- Serial.print (" spi_master_enable(" ); Serial.print (clockDivider); Serial.print (" ," ); Serial.print (dataMode); Serial.print (" ," ); Serial.print (flags); Serial.println (" )" );
142+ Serial.print (" spi_master_enable(" ); Serial.print (_currentSetting-> clockDivider ); Serial.print (" ," ); Serial.print (_currentSetting-> dataMode ); Serial.print (" ," ); Serial.print (flags); Serial.println (" )" );
131143 #endif
132- spi_master_enable (spi_d, (spi_baud_rate)clockDivider, (spi_mode)dataMode, flags);
144+ spi_master_enable (_currentSetting-> spi_d , (spi_baud_rate)_currentSetting-> clockDivider , (spi_mode)_currentSetting-> dataMode , flags);
133145}
134146
135147void SPIClass::beginSlave (void ) {
136- if (dataMode >= 4 ) {
148+ if (_currentSetting-> dataMode >= 4 ) {
137149 ASSERT (0 );
138150 return ;
139151 }
140- uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE);
141- spi_init (spi_d);
142- configure_gpios (spi_d, 0 );
152+ uint32 flags = ((_currentSetting-> bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE);
153+ spi_init (_currentSetting-> spi_d );
154+ configure_gpios (_currentSetting-> spi_d , 0 );
143155 #ifdef SPI_DEBUG
144- Serial.print (" spi_slave_enable(" ); Serial.print (dataMode); Serial.print (" ," ); Serial.print (flags); Serial.println (" )" );
156+ Serial.print (" spi_slave_enable(" ); Serial.print (_currentSetting-> dataMode ); Serial.print (" ," ); Serial.print (flags); Serial.println (" )" );
145157 #endif
146- spi_slave_enable (spi_d, (spi_mode)dataMode, flags);
158+ spi_slave_enable (_currentSetting-> spi_d , (spi_mode)_currentSetting-> dataMode , flags);
147159}
148160
149161void SPIClass::end (void ) {
150- if (!spi_is_enabled (this ->spi_d )) {
162+ if (!spi_is_enabled (_currentSetting ->spi_d )) {
151163 return ;
152164 }
153165
154166 // Follows RM0008's sequence for disabling a SPI in master/slave
155167 // full duplex mode.
156- while (spi_is_rx_nonempty (this ->spi_d )) {
168+ while (spi_is_rx_nonempty (_currentSetting ->spi_d )) {
157169 // FIXME [0.1.0] remove this once you have an interrupt based driver
158- volatile uint16 rx __attribute__ ((unused)) = spi_rx_reg (this ->spi_d );
170+ volatile uint16 rx __attribute__ ((unused)) = spi_rx_reg (_currentSetting ->spi_d );
159171 }
160- while (!spi_is_tx_empty (this ->spi_d ))
172+ while (!spi_is_tx_empty (_currentSetting ->spi_d ))
161173 ;
162- while (spi_is_busy (this ->spi_d ))
174+ while (spi_is_busy (_currentSetting ->spi_d ))
163175 ;
164- spi_peripheral_disable (this ->spi_d );
176+ spi_peripheral_disable (_currentSetting ->spi_d );
165177}
166178
167179/* Roger Clark added 3 functions */
@@ -170,7 +182,7 @@ void SPIClass::setClockDivider(uint32_t clockDivider)
170182 #ifdef SPI_DEBUG
171183 Serial.print (" Clock divider set to " ); Serial.println (clockDivider);
172184 #endif
173- this ->clockDivider = clockDivider;
185+ _currentSetting ->clockDivider = clockDivider;
174186 this ->begin ();
175187}
176188
@@ -179,7 +191,7 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
179191 #ifdef SPI_DEBUG
180192 Serial.print (" Bit order set to " ); Serial.println (bitOrder);
181193 #endif
182- this ->bitOrder = bitOrder;
194+ _currentSetting ->bitOrder = bitOrder;
183195 this ->begin ();
184196}
185197
@@ -189,11 +201,11 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
189201*/
190202void SPIClass::setDataSize (uint32 datasize)
191203{
192- uint32 cr1 = this ->spi_d ->regs ->CR1 ;
204+ uint32 cr1 = _currentSetting ->spi_d ->regs ->CR1 ;
193205 datasize &= SPI_CR1_DFF;
194206 cr1 &= ~(SPI_CR1_DFF);
195207 cr1 |= datasize;
196- this ->spi_d ->regs ->CR1 = cr1;
208+ _currentSetting ->spi_d ->regs ->CR1 = cr1;
197209}
198210
199211void SPIClass::setDataMode (uint8_t dataMode)
@@ -228,7 +240,7 @@ If someone finds this is not the case or sees a logic error with this let me kno
228240 #ifdef SPI_DEBUG
229241 Serial.print (" Data mode set to " ); Serial.println (dataMode);
230242 #endif
231- this ->dataMode = dataMode;
243+ _currentSetting ->dataMode = dataMode;
232244 this ->begin ();
233245}
234246
@@ -243,29 +255,9 @@ void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
243255 // digitalWrite(_SSPin,LOW);
244256 setBitOrder (settings.bitOrder );
245257 setDataMode (settings.dataMode );
246- setClockDivider (determine_baud_rate (spi_d, settings.clock ));
258+ setClockDivider (determine_baud_rate (_currentSetting-> spi_d , settings.clock ));
247259 begin ();
248- #if 0
249- // code from SAM core
250- uint8_t mode = interruptMode;
251- if (mode > 0) {
252- if (mode < 16) {
253- if (mode & 1) PIOA->PIO_IDR = interruptMask[0];
254- if (mode & 2) PIOB->PIO_IDR = interruptMask[1];
255- if (mode & 4) PIOC->PIO_IDR = interruptMask[2];
256- if (mode & 8) PIOD->PIO_IDR = interruptMask[3];
257- } else {
258- interruptSave = interruptsStatus();
259- noInterrupts();
260- }
261- }
262- uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
263- bitOrder[ch] = settings.border;
264- SPI_ConfigureNPCS(spi, ch, settings.config);
265- //setBitOrder(pin, settings.border);
266- //setDataMode(pin, settings.datamode);
267- //setClockDivider(pin, settings.clockdiv);
268- #endif
260+
269261}
270262
271263void SPIClass::endTransaction (void )
@@ -304,9 +296,9 @@ uint8 SPIClass::read(void) {
304296void SPIClass::read (uint8 *buf, uint32 len) {
305297 uint32 rxed = 0 ;
306298 while (rxed < len) {
307- while (!spi_is_rx_nonempty (this ->spi_d ))
299+ while (!spi_is_rx_nonempty (_currentSetting ->spi_d ))
308300 ;
309- buf[rxed++] = (uint8)spi_rx_reg (this ->spi_d );
301+ buf[rxed++] = (uint8)spi_rx_reg (_currentSetting ->spi_d );
310302 }
311303}
312304
@@ -319,9 +311,9 @@ void SPIClass::write(uint16 data) {
319311 * This almost doubles the speed of this function.
320312 */
321313
322- spi_tx_reg (this ->spi_d , data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
323- while (spi_is_tx_empty (this ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
324- while (spi_is_busy (this ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
314+ spi_tx_reg (_currentSetting ->spi_d , data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
315+ while (spi_is_tx_empty (_currentSetting ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
316+ while (spi_is_busy (_currentSetting ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
325317}
326318
327319// void SPIClass::write(uint8 byte) {
@@ -333,27 +325,27 @@ void SPIClass::write(uint16 data) {
333325 * This almost doubles the speed of this function.
334326 */
335327
336- // spi_tx_reg(this ->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
337- // while (spi_is_tx_empty(this ->spi_d) == 0); // "5. Wait until TXE=1 ..."
338- // while (spi_is_busy(this ->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
328+ // spi_tx_reg(_currentSetting ->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
329+ // while (spi_is_tx_empty(_currentSetting ->spi_d) == 0); // "5. Wait until TXE=1 ..."
330+ // while (spi_is_busy(_currentSetting ->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
339331// }
340332
341333void SPIClass::write (const uint8 *data, uint32 length) {
342334 uint32 txed = 0 ;
343335 while (txed < length) {
344- txed += spi_tx (this ->spi_d , data + txed, length - txed);
336+ txed += spi_tx (_currentSetting ->spi_d , data + txed, length - txed);
345337 }
346- while (spi_is_tx_empty (this ->spi_d ) == 0 ); // "4. After writing the last data item into the SPI_DR register, wait until TXE=1 ..."
347- while (spi_is_busy (this ->spi_d ) != 0 ); // "... then wait until BSY=0, this indicates that the transmission of the last data is complete."
338+ while (spi_is_tx_empty (_currentSetting ->spi_d ) == 0 ); // "4. After writing the last data item into the SPI_DR register, wait until TXE=1 ..."
339+ while (spi_is_busy (_currentSetting ->spi_d ) != 0 ); // "... then wait until BSY=0, this indicates that the transmission of the last data is complete."
348340}
349341
350342uint8 SPIClass::transfer (uint8 byte) const {
351343 uint8 b;
352- spi_tx_reg (this ->spi_d , byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
353- while (spi_is_rx_nonempty (this ->spi_d ) == 0 ); // "4. Wait until RXNE=1 ..."
354- b = spi_rx_reg (this ->spi_d ); // "... and read the last received data."
355- while (spi_is_tx_empty (this ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
356- while (spi_is_busy (this ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
344+ spi_tx_reg (_currentSetting ->spi_d , byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
345+ while (spi_is_rx_nonempty (_currentSetting ->spi_d ) == 0 ); // "4. Wait until RXNE=1 ..."
346+ b = spi_rx_reg (_currentSetting ->spi_d ); // "... and read the last received data."
347+ while (spi_is_tx_empty (_currentSetting ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
348+ while (spi_is_busy (_currentSetting ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
357349 return b;
358350}
359351/* Roger Clark and Victor Perez, 2015
@@ -365,7 +357,7 @@ uint8 SPIClass::transfer(uint8 byte) const {
365357uint8 SPIClass::dmaTransfer (uint8 *transmitBuf, uint8 *receiveBuf, uint16 length) {
366358 if (length == 0 ) return 0 ;
367359 uint8 b;
368- if (spi_is_rx_nonempty (this ->spi_d ) == 1 ) b = spi_rx_reg (this ->spi_d ); // Clear the RX buffer in case a byte is waiting on it.
360+ if (spi_is_rx_nonempty (_currentSetting ->spi_d ) == 1 ) b = spi_rx_reg (_currentSetting ->spi_d ); // Clear the RX buffer in case a byte is waiting on it.
369361 dma1_ch3_Active=true ;
370362 dma_init (DMA1);
371363 dma_attach_interrupt (DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
@@ -405,8 +397,8 @@ uint8 SPIClass::dmaTransfer(uint8 *transmitBuf, uint8 *receiveBuf, uint16 length
405397 }
406398
407399// }
408- while (spi_is_tx_empty (this ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
409- while (spi_is_busy (this ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
400+ while (spi_is_tx_empty (_currentSetting ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
401+ while (spi_is_busy (_currentSetting ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
410402 dma_disable (DMA1, DMA_CH3);
411403 dma_disable (DMA1, DMA_CH2);
412404 spi_rx_dma_disable (SPI1);
@@ -435,10 +427,10 @@ uint8 SPIClass::dmaSend(uint8 *transmitBuf, uint16 length, bool minc) {
435427 dma_enable (DMA1, DMA_CH3);// enable transmit
436428
437429 while (dma1_ch3_Active);
438- while (spi_is_rx_nonempty (this ->spi_d ) == 0 ); // "4. Wait until RXNE=1 ..."
439- b = spi_rx_reg (this ->spi_d ); // "... and read the last received data."
440- while (spi_is_tx_empty (this ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
441- while (spi_is_busy (this ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
430+ while (spi_is_rx_nonempty (_currentSetting ->spi_d ) == 0 ); // "4. Wait until RXNE=1 ..."
431+ b = spi_rx_reg (_currentSetting ->spi_d ); // "... and read the last received data."
432+ while (spi_is_tx_empty (_currentSetting ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
433+ while (spi_is_busy (_currentSetting ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
442434 dma_disable (DMA1, DMA_CH3);
443435 spi_tx_dma_disable (SPI1);
444436 return b;
@@ -460,10 +452,10 @@ uint8 SPIClass::dmaSend(uint16 *transmitBuf, uint16 length, bool minc) {
460452 dma_enable (DMA1, DMA_CH3);// enable transmit
461453
462454 while (dma1_ch3_Active);
463- while (spi_is_rx_nonempty (this ->spi_d ) == 0 ); // "4. Wait until RXNE=1 ..."
464- b = spi_rx_reg (this ->spi_d ); // "... and read the last received data."
465- while (spi_is_tx_empty (this ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
466- while (spi_is_busy (this ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
455+ while (spi_is_rx_nonempty (_currentSetting ->spi_d ) == 0 ); // "4. Wait until RXNE=1 ..."
456+ b = spi_rx_reg (_currentSetting ->spi_d ); // "... and read the last received data."
457+ while (spi_is_tx_empty (_currentSetting ->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
458+ while (spi_is_busy (_currentSetting ->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
467459 dma_disable (DMA1, DMA_CH3);
468460 spi_tx_dma_disable (SPI1);
469461 return b;
@@ -483,19 +475,19 @@ void SPIClass::detachInterrupt(void) {
483475 */
484476
485477uint8 SPIClass::misoPin (void ) {
486- return dev_to_spi_pins (this ->spi_d )->miso ;
478+ return dev_to_spi_pins (_currentSetting ->spi_d )->miso ;
487479}
488480
489481uint8 SPIClass::mosiPin (void ) {
490- return dev_to_spi_pins (this ->spi_d )->mosi ;
482+ return dev_to_spi_pins (_currentSetting ->spi_d )->mosi ;
491483}
492484
493485uint8 SPIClass::sckPin (void ) {
494- return dev_to_spi_pins (this ->spi_d )->sck ;
486+ return dev_to_spi_pins (_currentSetting ->spi_d )->sck ;
495487}
496488
497489uint8 SPIClass::nssPin (void ) {
498- return dev_to_spi_pins (this ->spi_d )->nss ;
490+ return dev_to_spi_pins (_currentSetting ->spi_d )->nss ;
499491}
500492
501493/*
0 commit comments