3131
3232#include " SPI.h"
3333
34- // #define SPI_DEBUG
3534
3635#include < libmaple/timer.h>
3736#include < libmaple/util.h>
@@ -92,11 +91,10 @@ static const spi_pins board_spi_pins[] __FLASH__ = {
9291 * Constructor
9392 */
9493
95- SPIClass::SPIClass (uint32 spi_num) {
96-
94+ SPIClass::SPIClass (uint32 spi_num)
95+ {
9796 _currentSetting=&_settings[spi_num-1 ];// SPI channels are called 1 2 and 3 but the array is zero indexed
9897
99-
10098 switch (spi_num) {
10199#if BOARD_NR_SPI >= 1
102100 case 1 :
@@ -119,7 +117,7 @@ SPIClass::SPIClass(uint32 spi_num) {
119117 default :
120118 ASSERT (0 );
121119 }
122-
120+
123121 // Init things specific to each SPI device
124122 // clock divider setup is a bit of hack, and needs to be improved at a later date.
125123 _settings[0 ].spi_d = SPI1;
@@ -149,9 +147,6 @@ SPIClass::SPIClass(uint32 spi_num) {
149147 */
150148void SPIClass::updateSettings (void ) {
151149 uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS);
152- #ifdef SPI_DEBUG
153- Serial.print (" spi_master_enable(" ); Serial.print (_currentSetting->clockDivider ); Serial.print (" ," ); Serial.print (_currentSetting->dataMode ); Serial.print (" ," ); Serial.print (flags); Serial.println (" )" );
154- #endif
155150 spi_master_enable (_currentSetting->spi_d , (spi_baud_rate)_currentSetting->clockDivider , (spi_mode)_currentSetting->dataMode , flags);
156151}
157152
@@ -167,9 +162,6 @@ void SPIClass::beginSlave(void) {
167162 spi_init (_currentSetting->spi_d );
168163 configure_gpios (_currentSetting->spi_d , 0 );
169164 uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_RX_ONLY);
170- #ifdef SPI_DEBUG
171- Serial.print (" spi_slave_enable(" ); Serial.print (_currentSetting->dataMode ); Serial.print (" ," ); Serial.print (flags); Serial.println (" )" );
172- #endif
173165 spi_slave_enable (_currentSetting->spi_d , (spi_mode)_currentSetting->dataMode , flags);
174166 // added for DMA callbacks.
175167 _currentSetting->state = SPI_STATE_READY;
@@ -199,19 +191,13 @@ void SPIClass::end(void) {
199191/* Roger Clark added 3 functions */
200192void SPIClass::setClockDivider (uint32_t clockDivider)
201193{
202- #ifdef SPI_DEBUG
203- Serial.print (" Clock divider set to " ); Serial.println (clockDivider);
204- #endif
205194 _currentSetting->clockDivider = clockDivider;
206195 uint32 cr1 = _currentSetting->spi_d ->regs ->CR1 & ~(SPI_CR1_BR);
207196 _currentSetting->spi_d ->regs ->CR1 = cr1 | (clockDivider & SPI_CR1_BR);
208197}
209198
210199void SPIClass::setBitOrder (BitOrder bitOrder)
211200{
212- #ifdef SPI_DEBUG
213- Serial.print (" Bit order set to " ); Serial.println (bitOrder);
214- #endif
215201 _currentSetting->bitOrder = bitOrder;
216202 uint32 cr1 = _currentSetting->spi_d ->regs ->CR1 & ~(SPI_CR1_LSBFIRST);
217203 if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST;
@@ -258,19 +244,13 @@ bit 0 - CPHA : Clock phase
258244
259245If someone finds this is not the case or sees a logic error with this let me know ;-)
260246 */
261- #ifdef SPI_DEBUG
262- Serial.print (" Data mode set to " ); Serial.println (dataMode);
263- #endif
264247 _currentSetting->dataMode = dataMode;
265248 uint32 cr1 = _currentSetting->spi_d ->regs ->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA);
266249 _currentSetting->spi_d ->regs ->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA));
267250}
268251
269252void SPIClass::beginTransaction (uint8_t pin, SPISettings settings)
270253{
271- #ifdef SPI_DEBUG
272- Serial.println (" SPIClass::beginTransaction" );
273- #endif
274254 setBitOrder (settings.bitOrder );
275255 setDataMode (settings.dataMode );
276256 setDataSize (settings.dataSize );
@@ -280,9 +260,6 @@ void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
280260
281261void SPIClass::beginTransactionSlave (SPISettings settings)
282262{
283- #ifdef SPI_DEBUG
284- Serial.println (F (" SPIClass::beginTransactionSlave" ));
285- #endif
286263 setBitOrder (settings.bitOrder );
287264 setDataMode (settings.dataMode );
288265 setDataSize (settings.dataSize );
@@ -291,9 +268,6 @@ void SPIClass::beginTransactionSlave(SPISettings settings)
291268
292269void SPIClass::endTransaction (void )
293270{
294- #ifdef SPI_DEBUG
295- Serial.println (" SPIClass::endTransaction" );
296- #endif
297271 // digitalWrite(_SSPin,HIGH);
298272#if false
299273// code from SAM core
@@ -355,6 +329,16 @@ void SPIClass::write(uint16 data)
355329 while (spi_is_busy (_currentSetting->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
356330}
357331
332+ void SPIClass::write16 (uint16 data)
333+ {
334+ // Added by stevestrong: write two consecutive bytes in 8 bit mode (DFF=0)
335+ spi_tx_reg (_currentSetting->spi_d , data>>8 ); // write high byte
336+ while (spi_is_tx_empty (_currentSetting->spi_d ) == 0 ); // Wait until TXE=1
337+ spi_tx_reg (_currentSetting->spi_d , data); // write low byte
338+ while (spi_is_tx_empty (_currentSetting->spi_d ) == 0 ); // Wait until TXE=1
339+ while (spi_is_busy (_currentSetting->spi_d ) != 0 ); // wait until BSY=0
340+ }
341+
358342void SPIClass::write (uint16 data, uint32 n)
359343{
360344 // Added by stevstrong: Repeatedly send same data by the specified number of times
@@ -384,14 +368,21 @@ uint8 SPIClass::transfer(uint8 byte) const
384368 return (uint8)spi_rx_reg (spi_d); // "... and read the last received data."
385369}
386370
387- uint16_t SPIClass::transfer16 (uint16_t wr_data ) const
371+ uint16_t SPIClass::transfer16 (uint16_t data ) const
388372{
373+ // Modified by stevestrong: write & read two consecutive bytes in 8 bit mode (DFF=0)
374+ // This is more effective than two distinct byte transfers
389375 spi_dev * spi_d = _currentSetting->spi_d ;
390- spi_rx_reg (spi_d); // read any previous data
391- spi_tx_reg (spi_d, wr_data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
392- while (spi_is_tx_empty (spi_d) == 0 ); // "5. Wait until TXE=1 ..."
393- while (spi_is_busy (spi_d) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
394- return (uint16)spi_rx_reg (spi_d); // "... and read the last received data."
376+ spi_rx_reg (spi_d); // read any previous data
377+ spi_tx_reg (spi_d, data>>8 ); // write high byte
378+ while (spi_is_tx_empty (spi_d) == 0 ); // wait until TXE=1
379+ while (spi_is_busy (spi_d) != 0 ); // wait until BSY=0
380+ uint16_t ret = spi_rx_reg (spi_d)<<8 ; // read and shift high byte
381+ spi_tx_reg (spi_d, data); // write low byte
382+ while (spi_is_tx_empty (spi_d) == 0 ); // wait until TXE=1
383+ while (spi_is_busy (spi_d) != 0 ); // wait until BSY=0
384+ ret += spi_rx_reg (spi_d); // read low byte
385+ return ret;
395386}
396387
397388/* Roger Clark and Victor Perez, 2015
@@ -523,19 +514,17 @@ uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) {
523514 // delayMicroseconds(10);
524515 if ((millis () - m) > DMA_TIMEOUT) { b = 2 ; break ; }
525516 }
526-
517+
527518 while (spi_is_tx_empty (_currentSetting->spi_d ) == 0 ); // "5. Wait until TXE=1 ..."
528519 while (spi_is_busy (_currentSetting->spi_d ) != 0 ); // "... and then wait until BSY=0 before disabling the SPI."
529520 spi_tx_dma_disable (_currentSetting->spi_d );
530521 dma_disable (_currentSetting->spiDmaDev , _currentSetting->spiTxDmaChannel );
531522 _currentSetting->state = SPI_STATE_READY;
532523 }
533524
534-
535525 if (length == 0 ) return 0 ;
536526 uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
537527
538-
539528 dma_init (_currentSetting->spiDmaDev );
540529 // TX
541530 dma_xfer_size dma_bit_size = (_currentSetting->dataSize ==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
@@ -770,9 +759,6 @@ static const spi_baud_rate baud_rates[8] __FLASH__ = {
770759*/
771760static spi_baud_rate determine_baud_rate (spi_dev *dev, uint32_t freq) {
772761 uint32_t clock = 0 , i;
773- #ifdef SPI_DEBUG
774- Serial.print (" determine_baud_rate(" ); Serial.print (freq); Serial.println (" )" );
775- #endif
776762 switch (rcc_dev_clk (dev->clk_id ))
777763 {
778764 case RCC_APB2: clock = STM32_PCLK2; break ; // 72 Mhz
0 commit comments