From 910072c7db2c0f81452589cc8fdf965457824aa1 Mon Sep 17 00:00:00 2001 From: victorpv Date: Mon, 10 Jul 2017 12:08:59 -0500 Subject: [PATCH] Changes tabs for spaces. --- STM32F1/libraries/SPI/src/SPI.cpp | 684 +++++++++++++++--------------- 1 file changed, 342 insertions(+), 342 deletions(-) diff --git a/STM32F1/libraries/SPI/src/SPI.cpp b/STM32F1/libraries/SPI/src/SPI.cpp index 998f9b0..94e5031 100644 --- a/STM32F1/libraries/SPI/src/SPI.cpp +++ b/STM32F1/libraries/SPI/src/SPI.cpp @@ -94,14 +94,14 @@ static const spi_pins board_spi_pins[] __FLASH__ = { SPIClass::SPIClass(uint32 spi_num) { - _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed + _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed - + switch (spi_num) { #if BOARD_NR_SPI >= 1 case 1: _currentSetting->spi_d = SPI1; - _spi1_this = (void*) this; + _spi1_this = (void*) this; break; #endif #if BOARD_NR_SPI >= 2 @@ -119,25 +119,25 @@ SPIClass::SPIClass(uint32 spi_num) { default: ASSERT(0); } - - // Init things specific to each SPI device - // clock divider setup is a bit of hack, and needs to be improved at a later date. - _settings[0].spi_d = SPI1; - _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); - _settings[0].spiDmaDev = DMA1; - _settings[0].spiTxDmaChannel = DMA_CH3; - _settings[0].spiRxDmaChannel = DMA_CH2; - _settings[1].spi_d = SPI2; - _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); - _settings[1].spiDmaDev = DMA1; - _settings[1].spiTxDmaChannel = DMA_CH5; - _settings[1].spiRxDmaChannel = DMA_CH4; + + // Init things specific to each SPI device + // clock divider setup is a bit of hack, and needs to be improved at a later date. + _settings[0].spi_d = SPI1; + _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); + _settings[0].spiDmaDev = DMA1; + _settings[0].spiTxDmaChannel = DMA_CH3; + _settings[0].spiRxDmaChannel = DMA_CH2; + _settings[1].spi_d = SPI2; + _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); + _settings[1].spiDmaDev = DMA1; + _settings[1].spiTxDmaChannel = DMA_CH5; + _settings[1].spiRxDmaChannel = DMA_CH4; #if BOARD_NR_SPI >= 3 - _settings[2].spi_d = SPI3; - _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock); - _settings[2].spiDmaDev = DMA2; - _settings[2].spiTxDmaChannel = DMA_CH2; - _settings[2].spiRxDmaChannel = DMA_CH1; + _settings[2].spi_d = SPI3; + _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock); + _settings[2].spiDmaDev = DMA2; + _settings[2].spiTxDmaChannel = DMA_CH2; + _settings[2].spiRxDmaChannel = DMA_CH1; #endif // added for DMA callbacks. @@ -148,11 +148,11 @@ SPIClass::SPIClass(uint32 spi_num) { * Set up/tear down */ void SPIClass::updateSettings(void) { - uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS); - #ifdef SPI_DEBUG - Serial.print("spi_master_enable("); Serial.print(_currentSetting->clockDivider); Serial.print(","); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")"); - #endif - spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags); + uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS); + #ifdef SPI_DEBUG + Serial.print("spi_master_enable("); Serial.print(_currentSetting->clockDivider); Serial.print(","); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")"); + #endif + spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags); } void SPIClass::begin(void) { @@ -167,9 +167,9 @@ void SPIClass::beginSlave(void) { spi_init(_currentSetting->spi_d); configure_gpios(_currentSetting->spi_d, 0); uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_RX_ONLY); - #ifdef SPI_DEBUG - Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")"); - #endif + #ifdef SPI_DEBUG + Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")"); + #endif spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags); // added for DMA callbacks. _currentSetting->state = SPI_STATE_READY; @@ -199,23 +199,23 @@ void SPIClass::end(void) { /* Roger Clark added 3 functions */ void SPIClass::setClockDivider(uint32_t clockDivider) { - #ifdef SPI_DEBUG - Serial.print("Clock divider set to "); Serial.println(clockDivider); - #endif - _currentSetting->clockDivider = clockDivider; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR); - _currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR); + #ifdef SPI_DEBUG + Serial.print("Clock divider set to "); Serial.println(clockDivider); + #endif + _currentSetting->clockDivider = clockDivider; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR); + _currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR); } void SPIClass::setBitOrder(BitOrder bitOrder) { - #ifdef SPI_DEBUG - Serial.print("Bit order set to "); Serial.println(bitOrder); - #endif - _currentSetting->bitOrder = bitOrder; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST); - if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST; - _currentSetting->spi_d->regs->CR1 = cr1; + #ifdef SPI_DEBUG + Serial.print("Bit order set to "); Serial.println(bitOrder); + #endif + _currentSetting->bitOrder = bitOrder; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST); + if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST; + _currentSetting->spi_d->regs->CR1 = cr1; } /* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly. @@ -224,11 +224,11 @@ void SPIClass::setBitOrder(BitOrder bitOrder) */ void SPIClass::setDataSize(uint32 datasize) { - _currentSetting->dataSize = datasize; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF); - uint8 en = spi_is_enabled(_currentSetting->spi_d); - spi_peripheral_disable(_currentSetting->spi_d); - _currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en; + _currentSetting->dataSize = datasize; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF); + uint8 en = spi_is_enabled(_currentSetting->spi_d); + spi_peripheral_disable(_currentSetting->spi_d); + _currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en; } void SPIClass::setDataMode(uint8_t dataMode) @@ -258,56 +258,56 @@ bit 0 - CPHA : Clock phase If someone finds this is not the case or sees a logic error with this let me know ;-) */ - #ifdef SPI_DEBUG - Serial.print("Data mode set to "); Serial.println(dataMode); - #endif - _currentSetting->dataMode = dataMode; - uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA); - _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA)); + #ifdef SPI_DEBUG + Serial.print("Data mode set to "); Serial.println(dataMode); + #endif + _currentSetting->dataMode = dataMode; + uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA); + _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA)); } void SPIClass::beginTransaction(uint8_t pin, SPISettings settings) { - #ifdef SPI_DEBUG - Serial.println("SPIClass::beginTransaction"); - #endif - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - setDataSize(settings.dataSize); - setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); - begin(); + #ifdef SPI_DEBUG + Serial.println("SPIClass::beginTransaction"); + #endif + setBitOrder(settings.bitOrder); + setDataMode(settings.dataMode); + setDataSize(settings.dataSize); + setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); + begin(); } void SPIClass::beginTransactionSlave(SPISettings settings) { - #ifdef SPI_DEBUG - Serial.println(F("SPIClass::beginTransactionSlave")); - #endif - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - setDataSize(settings.dataSize); - beginSlave(); + #ifdef SPI_DEBUG + Serial.println(F("SPIClass::beginTransactionSlave")); + #endif + setBitOrder(settings.bitOrder); + setDataMode(settings.dataMode); + setDataSize(settings.dataSize); + beginSlave(); } void SPIClass::endTransaction(void) { - #ifdef SPI_DEBUG - Serial.println("SPIClass::endTransaction"); - #endif - //digitalWrite(_SSPin,HIGH); + #ifdef SPI_DEBUG + Serial.println("SPIClass::endTransaction"); + #endif + //digitalWrite(_SSPin,HIGH); #if false // code from SAM core - uint8_t mode = interruptMode; - if (mode > 0) { - if (mode < 16) { - if (mode & 1) PIOA->PIO_IER = interruptMask[0]; - if (mode & 2) PIOB->PIO_IER = interruptMask[1]; - if (mode & 4) PIOC->PIO_IER = interruptMask[2]; - if (mode & 8) PIOD->PIO_IER = interruptMask[3]; - } else { - if (interruptSave) interrupts(); - } - } + uint8_t mode = interruptMode; + if (mode > 0) { + if (mode < 16) { + if (mode & 1) PIOA->PIO_IER = interruptMask[0]; + if (mode & 2) PIOB->PIO_IER = interruptMask[1]; + if (mode & 4) PIOC->PIO_IER = interruptMask[2]; + if (mode & 8) PIOD->PIO_IER = interruptMask[3]; + } else { + if (interruptSave) interrupts(); + } + } #endif } @@ -318,80 +318,80 @@ void SPIClass::endTransaction(void) uint16 SPIClass::read(void) { - while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ; - return (uint16)spi_rx_reg(_currentSetting->spi_d); + while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ; + return (uint16)spi_rx_reg(_currentSetting->spi_d); } void SPIClass::read(uint8 *buf, uint32 len) { - if ( len == 0 ) return; - spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it. - spi_reg_map * regs = _currentSetting->spi_d->regs; - // start sequence: write byte 0 - regs->DR = 0x00FF; // write the first byte - // main loop - while ( (--len) ) { - while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag - noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data - regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. - while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register - *buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. - interrupts(); // let systick do its job - } - // read remaining last byte - while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register - *buf++ = (uint8)(regs->DR); // read and store the received byte + if ( len == 0 ) return; + spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it. + spi_reg_map * regs = _currentSetting->spi_d->regs; + // start sequence: write byte 0 + regs->DR = 0x00FF; // write the first byte + // main loop + while ( (--len) ) { + while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag + noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data + regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register + *buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. + interrupts(); // let systick do its job + } + // read remaining last byte + while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register + *buf++ = (uint8)(regs->DR); // read and store the received byte } void SPIClass::write(uint16 data) { - /* Added for 16bit data Victor Perez. Roger Clark - * Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, - * by taking the Tx code from transfer(byte) - * This almost doubles the speed of this function. - */ - spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + /* Added for 16bit data Victor Perez. Roger Clark + * Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, + * by taking the Tx code from transfer(byte) + * This almost doubles the speed of this function. + */ + spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." } void SPIClass::write(uint16 data, uint32 n) { - // Added by stevstrong: Repeatedly send same data by the specified number of times - spi_reg_map * regs = _currentSetting->spi_d->regs; - while ( (n--)>0 ) { - regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty - } - while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning + // Added by stevstrong: Repeatedly send same data by the specified number of times + spi_reg_map * regs = _currentSetting->spi_d->regs; + while ( (n--)>0 ) { + regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) + while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty + } + while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning } void SPIClass::write(void *data, uint32 length) { - spi_dev * spi_d = _currentSetting->spi_d; - spi_tx(spi_d, (void*)data, length); // data can be array of bytes or words - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + spi_dev * spi_d = _currentSetting->spi_d; + spi_tx(spi_d, (void*)data, length); // data can be array of bytes or words + while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." } uint8 SPIClass::transfer(uint8 byte) const { - spi_dev * spi_d = _currentSetting->spi_d; - spi_rx_reg(spi_d); // read any previous data - spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." + spi_dev * spi_d = _currentSetting->spi_d; + spi_rx_reg(spi_d); // read any previous data + spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register + while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." } uint16_t SPIClass::transfer16(uint16_t wr_data) const { - spi_dev * spi_d = _currentSetting->spi_d; - spi_rx_reg(spi_d); // read any previous data - 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)." - while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - return (uint16)spi_rx_reg(spi_d); // "... and read the last received data." + spi_dev * spi_d = _currentSetting->spi_d; + spi_rx_reg(spi_d); // read any previous data + 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)." + while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + return (uint16)spi_rx_reg(spi_d); // "... and read the last received data." } /* Roger Clark and Victor Perez, 2015 @@ -402,54 +402,54 @@ uint16_t SPIClass::transfer16(uint16_t wr_data) const */ void SPIClass::dmaTransferSet(void *transmitBuf, void *receiveBuf) { dma_init(_currentSetting->spiDmaDev); - //spi_rx_dma_enable(_currentSetting->spi_d); - //spi_tx_dma_enable(_currentSetting->spi_d); - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, + //spi_rx_dma_enable(_currentSetting->spi_d); + //spi_tx_dma_enable(_currentSetting->spi_d); + dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, receiveBuf, dma_bit_size, (DMA_MINC_MODE | DMA_TRNS_CMPLT ));// receive buffer DMA - if (!transmitBuf) { - transmitBuf = &ff; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, + if (!transmitBuf) { + transmitBuf = &ff; + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly - } - else { + } + else { dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, transmitBuf, dma_bit_size, (DMA_MINC_MODE | DMA_FROM_MEM ));// Transmit buffer DMA - } - dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW); - dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, DMA_PRIORITY_VERY_HIGH); + } + dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW); + dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, DMA_PRIORITY_VERY_HIGH); } uint8 SPIClass::dmaTransferRepeat(uint16 length) { - if (length == 0) return 0; - if (spi_is_rx_nonempty(_currentSetting->spi_d) == 1) spi_rx_reg(_currentSetting->spi_d); - _currentSetting->state = SPI_STATE_TRANSFER; - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length); - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit - spi_rx_dma_enable(_currentSetting->spi_d); - spi_tx_dma_enable(_currentSetting->spi_d); + if (length == 0) return 0; + if (spi_is_rx_nonempty(_currentSetting->spi_d) == 1) spi_rx_reg(_currentSetting->spi_d); + _currentSetting->state = SPI_STATE_TRANSFER; + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length); + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit + spi_rx_dma_enable(_currentSetting->spi_d); + spi_tx_dma_enable(_currentSetting->spi_d); if (_currentSetting->receiveCallback){ return 0; } //uint32_t m = millis(); uint8 b = 0; uint32_t m = millis(); - while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) { - //Avoid interrupts and just loop waiting for the flag to be set. - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } + while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) { + //Avoid interrupts and just loop waiting for the flag to be set. + if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } } - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - spi_tx_dma_disable(_currentSetting->spi_d); - spi_rx_dma_disable(_currentSetting->spi_d); + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + spi_tx_dma_disable(_currentSetting->spi_d); + spi_rx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - _currentSetting->state = SPI_STATE_READY; + dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + _currentSetting->state = SPI_STATE_READY; return b; } @@ -461,8 +461,8 @@ uint8 SPIClass::dmaTransferRepeat(uint16 length) { */ uint8 SPIClass::dmaTransfer(void *transmitBuf, void *receiveBuf, uint16 length) { - dmaTransferSet(transmitBuf, receiveBuf); - return dmaTransferRepeat(length); + dmaTransferSet(transmitBuf, receiveBuf); + return dmaTransferRepeat(length); } /* Roger Clark and Victor Perez, 2015 @@ -482,29 +482,29 @@ void SPIClass::dmaSendSet(void * transmitBuf, bool minc) { } uint8 SPIClass::dmaSendRepeat(uint16 length) { - if (length == 0) return 0; - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); - _currentSetting->state = SPI_STATE_TRANSMIT; - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit - spi_tx_dma_enable(_currentSetting->spi_d); - if (_currentSetting->transmitCallback) - { - return 0; - } - uint32_t m = millis(); - uint8 b = 0; - while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) { - //Avoid interrupts and just loop waiting for the flag to be set. - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } - } - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - spi_tx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - _currentSetting->state = SPI_STATE_READY; - return b; + if (length == 0) return 0; + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); + _currentSetting->state = SPI_STATE_TRANSMIT; + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit + spi_tx_dma_enable(_currentSetting->spi_d); + if (_currentSetting->transmitCallback) + { + return 0; + } + uint32_t m = millis(); + uint8 b = 0; + while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) { + //Avoid interrupts and just loop waiting for the flag to be set. + if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } + } + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + spi_tx_dma_disable(_currentSetting->spi_d); + dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + _currentSetting->state = SPI_STATE_READY; + return b; } uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc) { @@ -513,42 +513,42 @@ uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc) { } uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) { - uint8 b = 0; + uint8 b = 0; - if (_currentSetting->state != SPI_STATE_READY) - { + if (_currentSetting->state != SPI_STATE_READY) + { - uint32_t m = millis(); - while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set. - //delayMicroseconds(10); - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } - } - - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." - spi_tx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - _currentSetting->state = SPI_STATE_READY; - } + uint32_t m = millis(); + while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set. + //delayMicroseconds(10); + if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } + } + + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI." + spi_tx_dma_disable(_currentSetting->spi_d); + dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + _currentSetting->state = SPI_STATE_READY; + } - - if (length == 0) return 0; - uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); + + if (length == 0) return 0; + uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); - - dma_init(_currentSetting->spiDmaDev); - // TX - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, - transmitBuf, dma_bit_size, flags);// Transmit buffer DMA - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit - spi_tx_dma_enable(_currentSetting->spi_d); + + dma_init(_currentSetting->spiDmaDev); + // TX + dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; + dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, + transmitBuf, dma_bit_size, flags);// Transmit buffer DMA + dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); + dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit + spi_tx_dma_enable(_currentSetting->spi_d); - _currentSetting->state = SPI_STATE_TRANSMIT; + _currentSetting->state = SPI_STATE_TRANSMIT; - return b; + return b; } @@ -558,51 +558,51 @@ uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) { */ void SPIClass::onReceive(void(*callback)(void)) { - _currentSetting->receiveCallback = callback; - if (callback){ - switch (_currentSetting->spi_d->clk_id) { - case RCC_SPI1: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback); - break; - case RCC_SPI2: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback); - break; - #if BOARD_NR_SPI >= 3 - case RCC_SPI3: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback); - break; - #endif - default: - ASSERT(0); - } - } - else { - dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - } + _currentSetting->receiveCallback = callback; + if (callback){ + switch (_currentSetting->spi_d->clk_id) { + case RCC_SPI1: + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback); + break; + case RCC_SPI2: + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback); + break; + #if BOARD_NR_SPI >= 3 + case RCC_SPI3: + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback); + break; + #endif + default: + ASSERT(0); + } + } + else { + dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); + } } void SPIClass::onTransmit(void(*callback)(void)) { - _currentSetting->transmitCallback = callback; - if (callback){ - switch (_currentSetting->spi_d->clk_id) { - case RCC_SPI1: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback); - break; - case RCC_SPI2: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback); - break; - #if BOARD_NR_SPI >= 3 - case RCC_SPI3: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback); - break; - #endif - default: - ASSERT(0); - } - } - else { - dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - } + _currentSetting->transmitCallback = callback; + if (callback){ + switch (_currentSetting->spi_d->clk_id) { + case RCC_SPI1: + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback); + break; + case RCC_SPI2: + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback); + break; + #if BOARD_NR_SPI >= 3 + case RCC_SPI3: + dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback); + break; + #endif + default: + ASSERT(0); + } + } + else { + dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + } } /* @@ -611,44 +611,44 @@ void SPIClass::onTransmit(void(*callback)(void)) { */ void SPIClass::EventCallback() { - while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0" - switch (_currentSetting->state) { - case SPI_STATE_TRANSFER: - while (spi_is_rx_nonempty(_currentSetting->spi_d)); - _currentSetting->state = SPI_STATE_READY; - spi_tx_dma_disable(_currentSetting->spi_d); - spi_rx_dma_disable(_currentSetting->spi_d); - //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); + while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..." + while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0" + switch (_currentSetting->state) { + case SPI_STATE_TRANSFER: + while (spi_is_rx_nonempty(_currentSetting->spi_d)); + _currentSetting->state = SPI_STATE_READY; + spi_tx_dma_disable(_currentSetting->spi_d); + spi_rx_dma_disable(_currentSetting->spi_d); + //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - if (_currentSetting->receiveCallback) - { - _currentSetting->receiveCallback(); - } - break; - case SPI_STATE_TRANSMIT: - _currentSetting->state = SPI_STATE_READY; - spi_tx_dma_disable(_currentSetting->spi_d); - //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - if (_currentSetting->transmitCallback) - { - _currentSetting->transmitCallback(); - } + if (_currentSetting->receiveCallback) + { + _currentSetting->receiveCallback(); + } + break; + case SPI_STATE_TRANSMIT: + _currentSetting->state = SPI_STATE_READY; + spi_tx_dma_disable(_currentSetting->spi_d); + //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + if (_currentSetting->transmitCallback) + { + _currentSetting->transmitCallback(); + } - break; - default: - // we shouldn't get here, so better to add an assert and fail. - return; - } + break; + default: + // we shouldn't get here, so better to add an assert and fail. + return; + } } void SPIClass::attachInterrupt(void) { - // Should be enableInterrupt() + // Should be enableInterrupt() } void SPIClass::detachInterrupt(void) { - // Should be disableInterrupt() + // Should be disableInterrupt() } /* @@ -699,11 +699,11 @@ void SPIClass::_spi1EventCallback() } void SPIClass::_spi2EventCallback() { - reinterpret_cast(_spi2_this)->EventCallback(); + reinterpret_cast(_spi2_this)->EventCallback(); } #if BOARD_NR_SPI >= 3 void SPIClass::_spi3EventCallback() { - reinterpret_cast(_spi3_this)->EventCallback(); + reinterpret_cast(_spi3_this)->EventCallback(); } #endif /* @@ -711,57 +711,57 @@ void SPIClass::_spi3EventCallback() { */ static const spi_pins* dev_to_spi_pins(spi_dev *dev) { - switch (dev->clk_id) { + switch (dev->clk_id) { #if BOARD_NR_SPI >= 1 - case RCC_SPI1: return board_spi_pins; + case RCC_SPI1: return board_spi_pins; #endif #if BOARD_NR_SPI >= 2 - case RCC_SPI2: return board_spi_pins + 1; + case RCC_SPI2: return board_spi_pins + 1; #endif #if BOARD_NR_SPI >= 3 - case RCC_SPI3: return board_spi_pins + 2; + case RCC_SPI3: return board_spi_pins + 2; #endif - default: return NULL; - } + default: return NULL; + } } static void disable_pwm(const stm32_pin_info *i) { - if (i->timer_device) { - timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); - } + if (i->timer_device) { + timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); + } } static void configure_gpios(spi_dev *dev, bool as_master) { - const spi_pins *pins = dev_to_spi_pins(dev); + const spi_pins *pins = dev_to_spi_pins(dev); - if (!pins) { - return; - } + if (!pins) { + return; + } - const stm32_pin_info *nssi = &PIN_MAP[pins->nss]; - const stm32_pin_info *scki = &PIN_MAP[pins->sck]; - const stm32_pin_info *misoi = &PIN_MAP[pins->miso]; - const stm32_pin_info *mosii = &PIN_MAP[pins->mosi]; + const stm32_pin_info *nssi = &PIN_MAP[pins->nss]; + const stm32_pin_info *scki = &PIN_MAP[pins->sck]; + const stm32_pin_info *misoi = &PIN_MAP[pins->miso]; + const stm32_pin_info *mosii = &PIN_MAP[pins->mosi]; - disable_pwm(nssi); - disable_pwm(scki); - disable_pwm(misoi); - disable_pwm(mosii); + disable_pwm(nssi); + disable_pwm(scki); + disable_pwm(misoi); + disable_pwm(mosii); - spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit, - scki->gpio_device, scki->gpio_bit, misoi->gpio_bit, - mosii->gpio_bit); + spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit, + scki->gpio_device, scki->gpio_bit, misoi->gpio_bit, + mosii->gpio_bit); } static const spi_baud_rate baud_rates[8] __FLASH__ = { - SPI_BAUD_PCLK_DIV_2, - SPI_BAUD_PCLK_DIV_4, - SPI_BAUD_PCLK_DIV_8, - SPI_BAUD_PCLK_DIV_16, - SPI_BAUD_PCLK_DIV_32, - SPI_BAUD_PCLK_DIV_64, - SPI_BAUD_PCLK_DIV_128, - SPI_BAUD_PCLK_DIV_256, + SPI_BAUD_PCLK_DIV_2, + SPI_BAUD_PCLK_DIV_4, + SPI_BAUD_PCLK_DIV_8, + SPI_BAUD_PCLK_DIV_16, + SPI_BAUD_PCLK_DIV_32, + SPI_BAUD_PCLK_DIV_64, + SPI_BAUD_PCLK_DIV_128, + SPI_BAUD_PCLK_DIV_256, }; /* @@ -769,22 +769,22 @@ static const spi_baud_rate baud_rates[8] __FLASH__ = { * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). */ static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) { - uint32_t clock = 0, i; - #ifdef SPI_DEBUG - Serial.print("determine_baud_rate("); Serial.print(freq); Serial.println(")"); - #endif - switch (rcc_dev_clk(dev->clk_id)) - { - case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz - case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz - } - clock /= 2; - i = 0; - while (i < 7 && freq < clock) { - clock /= 2; - i++; - } - return baud_rates[i]; + uint32_t clock = 0, i; + #ifdef SPI_DEBUG + Serial.print("determine_baud_rate("); Serial.print(freq); Serial.println(")"); + #endif + switch (rcc_dev_clk(dev->clk_id)) + { + case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz + case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz + } + clock /= 2; + i = 0; + while (i < 7 && freq < clock) { + clock /= 2; + i++; + } + return baud_rates[i]; } SPIClass SPI(1);