2021-04-15 06:16 AM
I am trying to make two STM32F4 with HAL communicate through SPI Simplex mode by changing who is the master node when it's ready to send a message. Both of the platforms start as a slave and they change to master to send a message and then go back to slave.
while (1)
{
configSlave();
while(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY_RX);
HAL_SPI_Receive(&hspi1, (uint8_t *)buff, 13, 1000); /* Including this line generates the issue */
HAL_Delay(10);
configMaster();
HAL_Delay(10);
sendHelloWorld();
HAL_Delay(10);
}
Changing the SPI configuration using configMaster() after configSlave() without calling the receive routine HAL_SPI_Receive() works great. However, my problem comes if I add the receive routine in between.
If I add the HAL_SPI_Receive() in between the configurations when I change the node to master the node will then start sending a constant clock through the CLK pin and bring low the DATA pin until I send the Hello World message. So why could this be happening? Is it a deinitialization problem?
I made sure to deinitialize the SPI peripheral before reconfiguring to each mode and went through the debug mode to check that the SPI register was 0 during deinitialization. Similarly, I made sure to reset to 0 every time the global SPI handler so it would not keep some config from the other mode.
For reference, these are my configMaster() and configSlave() routines:
static void configMaster(void)
{
if(HAL_SPI_DeInit(&hspi1) != HAL_ERROR)
{
memset(&hspi1, 0, sizeof(SPI_HandleTypeDef));
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
}
static void configSlave(void)
{
if(HAL_SPI_DeInit(&hspi1) != HAL_ERROR)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
}
Also the exact point where the master starts sending the clock happens here: HAL_SPI_Init()
/*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
/* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
Communication speed, First bit and CRC calculation state */
WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation));
Any suggestion is welcomed. Thanks