From b892004cc236553618c29c7afb43663f00af9016 Mon Sep 17 00:00:00 2001 From: victorpv Date: Mon, 10 Jul 2017 12:00:29 -0500 Subject: [PATCH 1/2] Add files via upload --- STM32F1/libraries/SPI/src/SPI.cpp | 362 +++++++++++++++++++++--------- STM32F1/libraries/SPI/src/SPI.h | 81 +++++-- 2 files changed, 313 insertions(+), 130 deletions(-) diff --git a/STM32F1/libraries/SPI/src/SPI.cpp b/STM32F1/libraries/SPI/src/SPI.cpp index f0d9f7f..998f9b0 100644 --- a/STM32F1/libraries/SPI/src/SPI.cpp +++ b/STM32F1/libraries/SPI/src/SPI.cpp @@ -101,16 +101,19 @@ SPIClass::SPIClass(uint32 spi_num) { #if BOARD_NR_SPI >= 1 case 1: _currentSetting->spi_d = SPI1; + _spi1_this = (void*) this; break; #endif #if BOARD_NR_SPI >= 2 case 2: _currentSetting->spi_d = SPI2; + _spi2_this = (void*) this; break; #endif #if BOARD_NR_SPI >= 3 case 3: _currentSetting->spi_d = SPI3; + _spi3_this = (void*) this; break; #endif default: @@ -137,6 +140,8 @@ SPIClass::SPIClass(uint32 spi_num) { _settings[2].spiRxDmaChannel = DMA_CH1; #endif + // added for DMA callbacks. + _currentSetting->state = SPI_STATE_IDLE; } /* @@ -154,6 +159,8 @@ void SPIClass::begin(void) { spi_init(_currentSetting->spi_d); configure_gpios(_currentSetting->spi_d, 1); updateSettings(); + // added for DMA callbacks. + _currentSetting->state = SPI_STATE_READY; } void SPIClass::beginSlave(void) { @@ -164,6 +171,8 @@ void SPIClass::beginSlave(void) { 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; } void SPIClass::end(void) { @@ -182,6 +191,9 @@ void SPIClass::end(void) { while (spi_is_busy(_currentSetting->spi_d)) ; spi_peripheral_disable(_currentSetting->spi_d); + // added for DMA callbacks. + // Need to add unsetting the callbacks for the DMA channels. + _currentSetting->state = SPI_STATE_IDLE; } /* Roger Clark added 3 functions */ @@ -384,98 +396,126 @@ uint16_t SPIClass::transfer16(uint16_t wr_data) const /* Roger Clark and Victor Perez, 2015 * Performs a DMA SPI transfer with at least a receive buffer. -* If a TX buffer is not provided, FF is sent over and over for the length of the transfer. -* On exit TX buffer is not modified, and RX buffer contains the received data. +* If a TX buffer is not provided, FF is sent over and over for the lenght of the transfer. +* On exit TX buffer is not modified, and RX buffer cotains the received data. * Still in progress. */ -uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length) -{ - if (length == 0) return 0; - uint8 b = 0; -// dma1_ch3_Active=true; +void SPIClass::dmaTransferSet(void *transmitBuf, void *receiveBuf) { dma_init(_currentSetting->spiDmaDev); -// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event); - - // RX + //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));// receive buffer DMA - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length); - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive - - // TX - uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM); - if ( transmitBuf==0 ) { - static uint8_t ff = 0XFF; - transmitBuf = &ff; - flags ^= DMA_MINC_MODE; // remove increment mode + 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, + transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly } + else { 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 + 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); +} - spi_rx_reg(_currentSetting->spi_d); //Clear the RX buffer in case a byte is waiting on it. +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); // must be the last enable to avoid DMA error flag - + 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. - //delayMicroseconds(10); + 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." + 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); // And disable generation of DMA request from the SPI port so other peripherals can use the channels - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); + 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; return b; } +/* Roger Clark and Victor Perez, 2015 +* Performs a DMA SPI transfer with at least a receive buffer. +* If a TX buffer is not provided, FF is sent over and over for the length of the transfer. +* On exit TX buffer is not modified, and RX buffer contains the received data. +* Still in progress. +*/ + +uint8 SPIClass::dmaTransfer(void *transmitBuf, void *receiveBuf, uint16 length) { + dmaTransferSet(transmitBuf, receiveBuf); + return dmaTransferRepeat(length); +} + /* Roger Clark and Victor Perez, 2015 * Performs a DMA SPI send using a TX buffer. * On exit TX buffer is not modified. * Still in progress. * 2016 - stevstrong - reworked to automatically detect bit size from SPI setting */ -uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc) -{ + +void SPIClass::dmaSendSet(void * transmitBuf, bool minc) { + uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); + dma_init(_currentSetting->spiDmaDev); + 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_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW); +} + +uint8 SPIClass::dmaSendRepeat(uint16 length) { if (length == 0) return 0; - uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); - uint8 b = 0; - 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_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); - - 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); + 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) { + dmaSendSet(transmitBuf, minc); + return dmaSendRepeat(length); +} -uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) -{ - static bool isRunning=false; +uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) { uint8 b = 0; - if (isRunning) + if (_currentSetting->state != SPI_STATE_READY) { uint32_t m = millis(); @@ -488,29 +528,121 @@ uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) 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); - isRunning=false; + _currentSetting->state = SPI_STATE_READY; } if (length == 0) return 0; uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); - dma_init(_currentSetting->spiDmaDev); + + 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_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); - isRunning=true; + _currentSetting->state = SPI_STATE_TRANSMIT; return b; } +/* + New functions added to manage callbacks. + Victor Perez 2017 +*/ + +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); + } +} + +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); + } +} + +/* + TODO: check if better to first call the customer code, next disable the DMA requests. + Also see if we need to check whether callbacks are set or not, may be better to be checked during the initial setup and only set the callback to EventCallback if they are set. +*/ + +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); + + 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; + } +} + void SPIClass::attachInterrupt(void) { // Should be enableInterrupt() } @@ -557,85 +689,101 @@ uint8 SPIClass::recv(void) { return this->read(); } - /* - * Auxiliary functions - */ + DMA call back functions, one per port. +*/ + +void SPIClass::_spi1EventCallback() +{ + reinterpret_cast(_spi1_this)->EventCallback(); +} + +void SPIClass::_spi2EventCallback() { + reinterpret_cast(_spi2_this)->EventCallback(); +} +#if BOARD_NR_SPI >= 3 +void SPIClass::_spi3EventCallback() { + reinterpret_cast(_spi3_this)->EventCallback(); +} +#endif +/* +* Auxiliary functions +*/ 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, }; /* - * Note: This assumes you're on a LeafLabs-style board - * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). - */ +* Note: This assumes you're on a LeafLabs-style board +* (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++; - } + 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]; } diff --git a/STM32F1/libraries/SPI/src/SPI.h b/STM32F1/libraries/SPI/src/SPI.h index 4d9b563..2160d26 100644 --- a/STM32F1/libraries/SPI/src/SPI.h +++ b/STM32F1/libraries/SPI/src/SPI.h @@ -99,6 +99,13 @@ #define DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT #define DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT +typedef enum { + SPI_STATE_IDLE, + SPI_STATE_READY, + SPI_STATE_RECEIVE, + SPI_STATE_TRANSMIT, + SPI_STATE_TRANSFER + } spi_mode_t; class SPISettings { public: SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { @@ -134,21 +141,31 @@ private: this->dataSize = dataSize; } uint32_t clock; + uint32_t dataSize; + uint32_t clockDivider; BitOrder bitOrder; uint8_t dataMode; - uint32_t dataSize; - + uint8_t _SSPin; + volatile spi_mode_t state; spi_dev *spi_d; - uint8_t _SSPin; - uint32_t clockDivider; dma_channel spiRxDmaChannel, spiTxDmaChannel; dma_dev* spiDmaDev; + void (*receiveCallback)(void) = NULL; + void (*transmitCallback)(void) = NULL; friend class SPIClass; }; -volatile static bool dma1_ch3_Active; +/* + Should move this to within the class once tested out, just for tidyness +*/ +static uint8_t ff = 0XFF; +static void (*_spi1_this); +static void (*_spi2_this); +#if BOARD_NR_SPI >= 3 +static void (*_spi3_this); +#endif /** * @brief Wirish SPI interface. @@ -217,7 +234,15 @@ public: */ void setDataSize(uint32 ds); - + /* Victor Perez 2017. Added to set and clear callback functions for callback + * on DMA transfer completion. + * onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed + * onTransmit used to set the callback in case of dmaSend (tx only). That function + * will NOT be called in case of TX/RX + */ + void onReceive(void(*)(void)); + void onTransmit(void(*)(void)); + /* * I/O */ @@ -279,7 +304,9 @@ public: * @param receiveBuf buffer Bytes to save received data. * @param length Number of bytes in buffer to transmit. */ - uint8 dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length); + uint8 dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length); + void dmaTransferSet(void *transmitBuf, void *receiveBuf); + uint8 dmaTransferRepeat(uint16 length); /** * @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode. @@ -289,9 +316,13 @@ public: * * @param data buffer half words to transmit, * @param length Number of bytes in buffer to transmit. + * @param minc Set to use Memory Increment mode, clear to use Circular mode. */ - uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1); - uint8 dmaSendAsync(void * transmitBuf, uint16 length, bool minc = 1); + uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1); + void dmaSendSet(void * transmitBuf, bool minc); + uint8 dmaSendRepeat(uint16 length); + + uint8 dmaSendAsync(void * transmitBuf, uint16 length, bool minc = 1); /* * Pin accessors */ @@ -325,7 +356,7 @@ public: spi_dev* c_dev(void) { return _currentSetting->spi_d; } - spi_dev *dev(){ return _currentSetting->spi_d;} + spi_dev *dev(){ return _currentSetting->spi_d;} /** * @brief Sets the number of the SPI peripheral to be used by @@ -335,10 +366,10 @@ public: * or 1-3 in high density devices. */ - void setModule(int spi_num) - { - _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed - } + void setModule(int spi_num) + { + _currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed + } /* -- The following methods are deprecated --------------------------- */ @@ -374,19 +405,23 @@ public: uint8 recv(void); private: -/* - static inline void DMA1_CH3_Event() { - dma1_ch3_Active = 0; -// dma_disable(DMA1, DMA_CH3); -// dma_disable(DMA1, DMA_CH2); - - // To Do. Need to wait for - } -*/ + SPISettings _settings[BOARD_NR_SPI]; SPISettings *_currentSetting; void updateSettings(void); + /* + * Functions added for DMA transfers with Callback. + * Experimental. + */ + + void EventCallback(void); + + static void _spi1EventCallback(void); + static void _spi2EventCallback(void); + #if BOARD_NR_SPI >= 3 + static void _spi3EventCallback(void); + #endif /* spi_dev *spi_d; uint8_t _SSPin; From 910072c7db2c0f81452589cc8fdf965457824aa1 Mon Sep 17 00:00:00 2001 From: victorpv Date: Mon, 10 Jul 2017 12:08:59 -0500 Subject: [PATCH 2/2] 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);