Skip to content

Commit

Permalink
STM32F1: Sync SPI changes from maple master (MarlinFirmware#15266)
Browse files Browse the repository at this point in the history
  • Loading branch information
tpruvot authored and thinkyhead committed Sep 15, 2019
1 parent 20fbb75 commit 02d400e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 23 deletions.
34 changes: 11 additions & 23 deletions Marlin/src/HAL/HAL_STM32F1/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -297,17 +296,15 @@ 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) {
// Added by stevestrong: write two consecutive bytes in 8 bit mode (DFF=0)
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) {
Expand All @@ -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."
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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 */ }
Expand Down
8 changes: 8 additions & 0 deletions Marlin/src/HAL/HAL_STM32F1/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,12 @@ class SPIClass {
*/
};

/**
* @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;

0 comments on commit 02d400e

Please sign in to comment.