diff --git a/Marlin/src/HAL/HAL_STM32F1/SPI.cpp b/Marlin/src/HAL/HAL_STM32F1/SPI.cpp index d8bf68d15..d14e64458 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SPI.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/SPI.cpp @@ -178,8 +178,7 @@ void SPIClass::end() { // FIXME [0.1.0] remove this once you have an interrupt based driver volatile uint16_t rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d); } - while (!spi_is_tx_empty(_currentSetting->spi_d)) { /* nada */ } - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } + waitSpiTxEnd(_currentSetting->spi_d); spi_peripheral_disable(_currentSetting->spi_d); // added for DMA callbacks. @@ -297,8 +296,7 @@ void SPIClass::write(uint16_t data) { * 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)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); } void SPIClass::write16(uint16_t data) { @@ -306,8 +304,7 @@ void SPIClass::write16(uint16_t data) { spi_tx_reg(_currentSetting->spi_d, data>>8); // write high byte while (!spi_is_tx_empty(_currentSetting->spi_d)) { /* nada */ } // Wait until TXE=1 spi_tx_reg(_currentSetting->spi_d, data); // write low byte - while (!spi_is_tx_empty(_currentSetting->spi_d)) { /* nada */ } // Wait until TXE=1 - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } // wait until BSY=0 + waitSpiTxEnd(_currentSetting->spi_d); } void SPIClass::write(uint16_t data, uint32_t n) { @@ -323,16 +320,14 @@ void SPIClass::write(uint16_t data, uint32_t n) { void SPIClass::write(const void *data, uint32_t length) { spi_dev * spi_d = _currentSetting->spi_d; spi_tx(spi_d, data, length); // data can be array of bytes or words - while (!spi_is_tx_empty(spi_d)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d)) { /* nada */ } // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(spi_d); } uint8_t SPIClass::transfer(uint8_t 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)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(spi_d)) { /* nada */ } // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(spi_d); return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." } @@ -342,12 +337,10 @@ uint16_t SPIClass::transfer16(uint16_t data) const { spi_dev * spi_d = _currentSetting->spi_d; spi_rx_reg(spi_d); // read any previous data spi_tx_reg(spi_d, data>>8); // write high byte - while (!spi_is_tx_empty(spi_d)) { /* nada */ } // wait until TXE=1 - while (spi_is_busy(spi_d)) { /* nada */ } // wait until BSY=0 + waitSpiTxEnd(spi_d); // wait until TXE=1 and then wait until BSY=0 uint16_t ret = spi_rx_reg(spi_d)<<8; // read and shift high byte spi_tx_reg(spi_d, data); // write low byte - while (!spi_is_tx_empty(spi_d)) { /* nada */ } // wait until TXE=1 - while (spi_is_busy(spi_d)) { /* nada */ } // wait until BSY=0 + waitSpiTxEnd(spi_d); // wait until TXE=1 and then wait until BSY=0 ret += spi_rx_reg(spi_d); // read low byte return ret; } @@ -400,8 +393,7 @@ uint8_t SPIClass::dmaTransferRepeat(uint16_t length) { if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } } - while (!spi_is_tx_empty(_currentSetting->spi_d)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); // until TXE=1 and BSY=0 spi_tx_dma_disable(_currentSetting->spi_d); spi_rx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); @@ -456,8 +448,7 @@ uint8_t SPIClass::dmaSendRepeat(uint16_t length) { // 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)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); // until TXE=1 and BSY=0 spi_tx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); @@ -480,9 +471,7 @@ uint8_t SPIClass::dmaSendAsync(const void * transmitBuf, uint16_t length, bool m //delayMicroseconds(10); if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } } - - while (!spi_is_tx_empty(_currentSetting->spi_d)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } // "... and then wait until BSY=0 before disabling the SPI." + waitSpiTxEnd(_currentSetting->spi_d); // until TXE=1 and BSY=0 spi_tx_dma_disable(_currentSetting->spi_d); dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); _currentSetting->state = SPI_STATE_READY; @@ -572,8 +561,7 @@ void SPIClass::onTransmit(void(*callback)(void)) { * 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)) { /* nada */ } // "5. Wait until TXE=1 ..." - while (spi_is_busy(_currentSetting->spi_d)) { /* nada */ } // "... and then wait until BSY=0" + waitSpiTxEnd(_currentSetting->spi_d); switch (_currentSetting->state) { case SPI_STATE_TRANSFER: while (spi_is_rx_nonempty(_currentSetting->spi_d)) { /* nada */ } diff --git a/Marlin/src/HAL/HAL_STM32F1/SPI.h b/Marlin/src/HAL/HAL_STM32F1/SPI.h index 4f6841697..ef9d91baf 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SPI.h +++ b/Marlin/src/HAL/HAL_STM32F1/SPI.h @@ -406,4 +406,12 @@ private: */ }; +/** + * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset. + */ +static inline void waitSpiTxEnd(spi_dev *spi_d) { + while (spi_is_tx_empty(spi_d) == 0) { /* nada */ } // wait until TXE=1 + while (spi_is_busy(spi_d) != 0) { /* nada */ } // wait until BSY=0 +} + extern SPIClass SPI;