Skip to content

Commit 59b71f1

Browse files
authored
improved block read routine
1 parent e37d7ea commit 59b71f1

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

STM32F4/libraries/SPI/src/SPI.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,32 @@ uint16 SPIClass::read(void)
321321

322322
void SPIClass::read(uint8 *buf, uint32 len)
323323
{
324-
spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it.
324+
if ( len == 0 ) return;
325+
spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it.
325326
spi_reg_map * regs = _currentSetting->spi_d->regs;
327+
#if 1
328+
// start sequence: write byte 0
329+
regs->DR = 0x00FF; // write the first byte
330+
// main loop
331+
while ( (--len) ) {
332+
while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag
333+
noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data
334+
regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag.
335+
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register
336+
*buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag.
337+
interrupts(); // let systick do its job
338+
}
339+
// read remaining last byte
340+
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register
341+
*buf++ = (uint8)(regs->DR); // read and store the received byte
342+
#else
326343
// start sequence
327344
while ( (len--)>0) {
328345
regs->DR = 0x00FF; // " write the data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
329346
while ( (regs->SR & SPI_SR_RXNE)==0 ) ; // wait till data is available in the Rx register
330347
*buf++ = (uint8)(regs->DR); // read and store the received byte
331-
}
348+
}
349+
#endif
332350
}
333351

334352
void SPIClass::write(uint16 data)
@@ -339,7 +357,6 @@ void SPIClass::write(uint16 data)
339357
* This almost doubles the speed of this function.
340358
*/
341359
spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
342-
//return;
343360
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
344361
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
345362
}

0 commit comments

Comments
 (0)