Skip to content
Snippets Groups Projects
Commit c3c32706 authored by Emilio Corigliano's avatar Emilio Corigliano
Browse files

[SPI] Implemented multiple of 8 bit operations as composition of 8 bit ones

parent e7db2f43
No related branches found
No related tags found
No related merge requests found
...@@ -104,8 +104,6 @@ public: ...@@ -104,8 +104,6 @@ public:
void set8BitFrameFormat(); void set8BitFrameFormat();
void set16BitFrameFormat();
void enableSoftwareSlaveManagement(); void enableSoftwareSlaveManagement();
void disableSoftwareSlaveManagement(); void disableSoftwareSlaveManagement();
...@@ -331,26 +329,16 @@ inline void SPIBus::disable() { spi->CR1 &= ~SPI_CR1_SPE; } ...@@ -331,26 +329,16 @@ inline void SPIBus::disable() { spi->CR1 &= ~SPI_CR1_SPE; }
inline void SPIBus::set8BitFrameFormat() { spi->CR1 &= ~SPI_CR1_DFF; } inline void SPIBus::set8BitFrameFormat() { spi->CR1 &= ~SPI_CR1_DFF; }
inline void SPIBus::set16BitFrameFormat() { spi->CR1 |= SPI_CR1_DFF; }
#else #else
inline void SPIBus::set8bitRXNE() { spi->CR2 |= SPI_CR2_FRXTH; } inline void SPIBus::set8bitRXNE() { spi->CR2 |= SPI_CR2_FRXTH; }
inline void SPIBus::set16bitRXNE() { spi->CR2 &= ~SPI_CR2_FRXTH; }
inline void SPIBus::set8BitFrameFormat() inline void SPIBus::set8BitFrameFormat()
{ {
spi->CR2 &= ~SPI_CR2_DS; spi->CR2 &= ~SPI_CR2_DS;
set8bitRXNE(); set8bitRXNE();
} }
inline void SPIBus::set16BitFrameFormat()
{
spi->CR2 |= SPI_CR2_DS;
set16bitRXNE();
}
#endif #endif
inline void SPIBus::enableSoftwareSlaveManagement() { spi->CR1 |= SPI_CR1_SSM; } inline void SPIBus::enableSoftwareSlaveManagement() { spi->CR1 |= SPI_CR1_SSM; }
...@@ -443,11 +431,7 @@ inline void SPIBus::configure(SPIBusConfig newConfig) ...@@ -443,11 +431,7 @@ inline void SPIBus::configure(SPIBusConfig newConfig)
enableInternalSlaveSelection(); enableInternalSlaveSelection();
setMasterConfiguration(); setMasterConfiguration();
#ifdef _ARCH_CORTEXM7_STM32F7 set8BitFrameFormat();
// By default the driver uses 8 bit transactions. Therefore, for f7s,
// configure the FIFO threshold to 8 bit
set8bitRXNE();
#endif
// Enable the peripheral // Enable the peripheral
enable(); enable();
...@@ -490,37 +474,20 @@ inline void SPIBus::read(uint8_t* data, size_t nBytes) ...@@ -490,37 +474,20 @@ inline void SPIBus::read(uint8_t* data, size_t nBytes)
inline void SPIBus::read16(uint16_t* data, size_t nBytes) inline void SPIBus::read16(uint16_t* data, size_t nBytes)
{ {
// At the start of the transfer we assume that the RX FIFO is empty // nBytes to be read must be a multiple of 2
assert((spi->SR & SPI_SR_RXNE) == 0); assert(nBytes % 2 == 0);
// Set 16 bit frame format
set16BitFrameFormat();
uint16_t temp[2] = {0};
for (size_t i = 0; i < nBytes / 2; i++) for (size_t i = 0; i < nBytes / 2; i++)
{ {
// Wait until the peripheral is ready to transmit // Receiving MSB
while ((spi->SR & SPI_SR_TXE) == 0) temp[0] = static_cast<uint16_t>(read());
; // Receiving LSB
temp[1] = static_cast<uint16_t>(read());
// Write the data item to transmit // MSB | LSB
spi->DR = 0; data[i] = temp[0] << 8 | temp[1];
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
data[i] = static_cast<uint16_t>(spi->DR);
} }
// Go back to 8 bit frame format
set8BitFrameFormat();
} }
inline void SPIBus::write(uint8_t data) { transfer(data); } inline void SPIBus::write(uint8_t data) { transfer(data); }
...@@ -539,37 +506,16 @@ inline void SPIBus::write(const uint8_t* data, size_t nBytes) ...@@ -539,37 +506,16 @@ inline void SPIBus::write(const uint8_t* data, size_t nBytes)
inline void SPIBus::write16(const uint16_t* data, size_t nBytes) inline void SPIBus::write16(const uint16_t* data, size_t nBytes)
{ {
// At the start of the transfer we assume that the RX FIFO is empty // nBytes to be read must be a multiple of 2
assert((spi->SR & SPI_SR_RXNE) == 0); assert(nBytes % 2 == 0);
// Set 16 bit frame format
set16BitFrameFormat();
for (size_t i = 0; i < nBytes / 2; i++) for (size_t i = 0; i < nBytes / 2; i++)
{ {
// Wait until the peripheral is ready to transmit // Sending MSB
while ((spi->SR & SPI_SR_TXE) == 0) write(static_cast<uint8_t>(data[i] >> 8));
; // Sending LSB
write(static_cast<uint8_t>(data[i]));
// Write the data item to transmit
spi->DR = static_cast<uint16_t>(data[i]);
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
(void)spi->DR;
} }
// Go back to 8 bit frame format
set8BitFrameFormat();
} }
inline uint8_t SPIBus::transfer(uint8_t data) inline uint8_t SPIBus::transfer(uint8_t data)
...@@ -600,52 +546,38 @@ inline uint8_t SPIBus::transfer(uint8_t data) ...@@ -600,52 +546,38 @@ inline uint8_t SPIBus::transfer(uint8_t data)
inline uint16_t SPIBus::transfer16(uint16_t data) inline uint16_t SPIBus::transfer16(uint16_t data)
{ {
// At the start of the transfer we assume that the RX FIFO is empty uint16_t temp[2] = {0};
assert((spi->SR & SPI_SR_RXNE) == 0); // Transferring MSB, putting the read value in the MSB of temp
temp[0] = static_cast<uint16_t>(transfer(static_cast<uint8_t>(data >> 8)));
// Set 16 bit frame format // Transferring LSB, putting the read value in the LSB of temp
set16BitFrameFormat(); temp[1] = static_cast<uint16_t>(transfer(static_cast<uint8_t>(data)));
// MSB | LSB
// Wait until the peripheral is ready to transmit return temp[0] << 8 | temp[1];
while ((spi->SR & SPI_SR_TXE) == 0)
;
// Write the data item to transmit
spi->DR = static_cast<uint16_t>(data);
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
data = static_cast<uint16_t>(spi->DR);
// Go back to 8 bit frame format
set8BitFrameFormat();
return data;
} }
inline uint32_t SPIBus::transfer24(uint32_t data) inline uint32_t SPIBus::transfer24(uint32_t data)
{ {
uint32_t res = static_cast<uint32_t>(transfer16(data >> 8)) << 8; uint32_t temp[3] = {0};
res |= transfer(data); // Transferring MSB, putting the read value in the MSB of temp
temp[0] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 16)));
return res; temp[1] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 8)));
// Transferring LSB, putting the read value in the LSB of temp
temp[2] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data)));
return temp[0] << 16 | temp[1] << 8 | temp[2];
} }
inline uint32_t SPIBus::transfer32(uint32_t data) inline uint32_t SPIBus::transfer32(uint32_t data)
{ {
uint32_t res = static_cast<uint32_t>(transfer16(data >> 16)) << 16; uint32_t temp[4] = {0};
res |= transfer16(data); // Transferring MSB, putting the read value in the MSB of temp
temp[0] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 24)));
return res; temp[1] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 16)));
temp[2] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 8)));
// Transferring LSB, putting the read value in the LSB of temp
temp[3] = transfer(static_cast<uint8_t>(data));
return temp[0] << 24 | temp[1] << 16 | temp[2] << 8 | temp[3];
} }
inline void SPIBus::transfer(uint8_t* data, size_t nBytes) inline void SPIBus::transfer(uint8_t* data, size_t nBytes)
...@@ -656,37 +588,19 @@ inline void SPIBus::transfer(uint8_t* data, size_t nBytes) ...@@ -656,37 +588,19 @@ inline void SPIBus::transfer(uint8_t* data, size_t nBytes)
inline void SPIBus::transfer16(uint16_t* data, size_t nBytes) inline void SPIBus::transfer16(uint16_t* data, size_t nBytes)
{ {
// At the start of the transfer we assume that the RX FIFO is empty // nBytes to be read must be a multiple of 2
assert((spi->SR & SPI_SR_RXNE) == 0); assert(nBytes % 2 == 0);
// Set 16 bit frame format uint16_t temp[2] = {0};
set16BitFrameFormat();
for (size_t i = 0; i < nBytes / 2; i++) for (size_t i = 0; i < nBytes / 2; i++)
{ {
// Wait until the peripheral is ready to transmit temp[0] =
while ((spi->SR & SPI_SR_TXE) == 0) static_cast<uint16_t>(transfer(static_cast<uint8_t>(data[i] >> 8)));
; temp[1] =
static_cast<uint16_t>(transfer(static_cast<uint8_t>(data[i])));
// Write the data item to transmit data[i] = temp[0] << 8 | temp[1];
spi->DR = static_cast<uint16_t>(data[i]);
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
data[i] = static_cast<uint16_t>(spi->DR);
} }
// Go back to 8 bit frame format
set8BitFrameFormat();
} }
} // namespace Boardcore } // namespace Boardcore
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment