2020-04-24 11:33 AM
Hi everybody!
I've been struggling with this monster for a few days now. I'm trying to make it do some very basic (pun not intended) things and I have little hair left... But let's cut a (too) long story short: I'd like to send with the SPI a few bytes to a device. I'm using polling (DMA and INT's is an epic drama for another time), although that's not relevant at this point. So let's just send a byte (8 bits) thru SPI. I've set up the GPIOs for the SPI normal, as alternate functions (most of this code has been generated by CubeMX) - with NSS port as normal output - like this:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_SPI_InitTypeDef SPI_InitStruct = {0};
GPIO_InitStruct.Pin = CK_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = MOSI_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = MISO_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
And this is the interesting part, the SPI setup:
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; // this is like using Bytes, right?
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.CRCPoly = 7;
LL_SPI_SetRxFIFOThreshold(SPI4, LL_SPI_RX_FIFO_TH_QUARTER); //the infamous FIFO, ignored in most STM examples,
// just like the NSS output
LL_SPI_Init(SPI4, &SPI_InitStruct);
LL_SPI_SetStandard(SPI4, LL_SPI_PROTOCOL_MOTOROLA);
// then I enable SPI:
SET_BIT(SPI4->CR1, SPI_CR1_SPE);
// so far, so good. And now I try to send a byte:
SPI1->DR = data; //data defined as a uint8_t of a whatever value
what I get is 8 bits of 'data' on MOSI and CLK outputs, followed by another 8 bits of CLK and MOSI=0. In total 16 bits/pulses. Why is that?! How can I convince this animal to give what is set up for - 8 bits? What do I miss?
Thank you in advance for any input!
Solved! Go to Solution.
2020-04-24 11:59 AM
You're pushing 16 bits into the register. You need to access it as a byte, rather than a word.
Use LL_SPI_TransmitData8, or duplicate its functionality:
/**
* @brief Write 8-Bits in the data register
* @rmtoll DR DR LL_SPI_TransmitData8
* @param SPIx SPI Instance
* @param TxData Value between Min_Data=0x00 and Max_Data=0xFF
* @retval None
*/
__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData)
{
#if defined (__GNUC__)
__IO uint8_t *spidr = ((__IO uint8_t *)&SPIx->DR);
*spidr = TxData;
#else
*((__IO uint8_t *)&SPIx->DR) = TxData;
#endif /* __GNUC__ */
}
2020-04-24 11:59 AM
You're pushing 16 bits into the register. You need to access it as a byte, rather than a word.
Use LL_SPI_TransmitData8, or duplicate its functionality:
/**
* @brief Write 8-Bits in the data register
* @rmtoll DR DR LL_SPI_TransmitData8
* @param SPIx SPI Instance
* @param TxData Value between Min_Data=0x00 and Max_Data=0xFF
* @retval None
*/
__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData)
{
#if defined (__GNUC__)
__IO uint8_t *spidr = ((__IO uint8_t *)&SPIx->DR);
*spidr = TxData;
#else
*((__IO uint8_t *)&SPIx->DR) = TxData;
#endif /* __GNUC__ */
}
2020-04-24 10:01 PM
Thank you, TDK! I will try this... I thought if I set SPI for 8 bits data processing, this what it will do. I would have rather expected that even if I intentionally put a 16 bit word into the DR, to have only 8 bits shifted out. I've also tried SPI1->DR=(uint8)data, although data was already defined as 8 bits. It was the wrong place for that hint.
But I've got your point and thanks again for that.
2020-04-24 11:34 PM
Yes, it works! Many thanks TDK :thumbs_up: