2019-08-21 10:20 AM
Hello,
I am using the STM32L053 microcontroller and it is currently communicating with another microcontroller (NRF52 ) through SPI protocol. The STM32L053 is slave and the other is the master.
The application consists of :
1) The Master(nRF52) sends a command to the Slave(STM32L053).
2) The Slave process the command, then sends the response depending on the received command.
Problem :
The data transfer from master(nRF52) to slave( STM32L053 ) is working properly.But in some transactions the slave(STM32L053 ) is sending incorrect 1st byte to master(nRF52).
In such cases I can see the correct response in memory. But while putting data on SPI lines the 1st byte is changing.
This issue is not there for every SPI transaction but it is happening for some in between transactions.
Example :
Response data in slave(STM32L053 ) memory : {0x15, 0x01,0x03,0x10,0x53,0x49,0x54,..}
So the slave(STM32L053 ) is supposed to send this same data on SPI. But here on SPI data lines I am seeing different 1st byte.
I have attached the images where you can see that on MISO line the 1st byte is changed to 0x09.
The changed byte i.e 0x09 is 1st byte of the previous transaction. So whenever there is change in 1st data byte in that case the changed byte is from previous transaction.
The configurations for Slave(STM32L053 ) SPI are mentioned below :
The STM32L053 is using DMA for SPI communication.
The CPOL and CPHA are compatible between the two boards i.e Mode 2 (CPOL =1 and CPHA = 0).
SPI data rate is 250Kbps (Master i.e nRF52 configures data rate).
Pin Configuration :
GPIO_InitStruct.Pin = CO_UC_NSS_Pin|CO_UC_MISO_Pin|CO_UC_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = CO_UC_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH ;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
SPI configuration :
void config_SPI2(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_SLAVE;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
SPI DMA configurations
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
static DMA_HandleTypeDef hdma_spi2_rx;
static DMA_HandleTypeDef hdma_spi2_tx;
if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
enable_SPI_clock(spiHandle);
/* USER CODE END SPI2_MspInit 0 */
/* SPI2 DMA Init */
/* SPI2_RX Init */
hdma_spi2_rx.Instance = DMA1_Channel6;
hdma_spi2_rx.Init.Request = DMA_REQUEST_2;
hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_rx.Init.Mode = DMA_CIRCULAR;
hdma_spi2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(spiHandle,hdmarx,hdma_spi2_rx);
/* SPI2_TX Init */
hdma_spi2_tx.Instance = DMA1_Channel7;
hdma_spi2_tx.Init.Request = DMA_REQUEST_2;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi2_tx);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
}
I am using IARWorkbench for STM32 .
Any help is appreciate! Thanks in advance and best regards.
Vaibhav Mahajan
2019-08-21 01:57 PM
Do you take into consideration that the SPI buffers data, i.e. at the moment when a byte *starts* to be transmitted, the SPI already requests from DMA the next byte?
JW
2019-08-21 08:57 PM
Hi JW,
"Do you take into consideration that the SPI buffers data, i.e. at the moment when a byte *starts* to be transmitted, the SPI already requests from DMA the next byte?"
Could you please explain what do you mean by this?