Why would SPI send 16 bits instead of 8?
I have configured my STM32G071 SPI peripheral to transmit 8 bits with the following code:
void spi_config(void)
{
RCC->APBENR2 |= RCC_APBENR2_SPI1EN; //Enable SPI Clock
//Configure for SPI mode (not I2S mode)
SPI1->I2SCFGR &= ~SPI_I2SCFGR_I2SMOD;
//MSB first, Master, Clock Phase: 1, Clock Polarity: 1
//Baud rate (SPI Clock: ~1MHz. Input clock = 64MHz --> fpclk/64);
//Full duplex (not Rx only), Config for SW ctrl of SS
SPI1->CR1 &= ~(SPI_CR1_RXONLY | SPI_CR1_LSBFIRST | SPI_CR1_BR);
SPI1->CR1 |= (SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_MSTR | SPI_CR1_CPOL | SPI_CR1_CPHA);
//Data format (8 bits) - make sure not to set disallowed value
SPI1->CR2 |= SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0;
SPI1->CR2 &= ~SPI_CR2_DS_3;
// SPI1->CR2 |= SPI_CR2_SSOE; //Needed if not using SW SS (to avoid SPI1 being forced into slave mode
SPI1->CR1 |= SPI_CR1_SPE; //Enable SPI
__IO uint32_t tempRd = SPI1->SR; //Clear all flags by reading status register
(void)tempRd; //Avoid compiler warning
}Using the debugger, I have confirmed that the DS bits in CR2 are properly being set to 0111 (8 bits). However, when I scope my MOSI and SCK lines, I see 16 bits being transferred: first the 8 bits I expect, then 8 bits of 0 (8 additional SCK cycles with MOSI held low).
My transmit function is:
bool spi_transmit(uint8_t *pData, uint8_t len, uint32_t timeout)
{
uint8_t dataIdx = 0;
uint32_t startTick = rcc_msGetTicks();
SPI1->CR1 |= SPI_CR1_SPE; //Enable SPI, if not
while(dataIdx < len)
{
if(SPI1->SR & SPI_SR_TXE) //TX Empty
{
SPI1->DR = pData[dataIdx];
dataIdx++;
}
else
{
if((rcc_msGetTicks() - startTick) >= timeout)
{
return(false);
}
}
}
while(SPI1->SR & SPI_SR_BSY) //Wait for busy flag
{
if((rcc_msGetTicks() - startTick) >= timeout)
{
return(false);
}
}
//Clear overrun condition --> DR, SR - see RM0444, p. 1390
__IO uint32_t tempRd = SPI1->DR;
tempRd = SPI1->SR;
(void)tempRd;
return(true);
}When I call it from main, I set the len argument to 1. Through testing, I have confirmed that the while loop in the transmit function is operating properly (only executing once). However, there are still 16 SCLK cycles and 8 extra 0's transmitted.
Fun facts:
RM0444, p. 1185 says bit 11 of SPIx_CR1 is a CRCL bit (CRC length). Earlier RMs (i.e., RM0008 for the F103RB) calls this bit "DFF" for Data Frame Format. The Debugger calls this bit DFF (for the STM32G081). In any event, it is set to '0' (which should be correct for 8-bit data).
Any suggestions for why my SPI peripheral is sending 16 bits?