Trigger SPI RX polling vs interrupt. What makes the difference?
Hello,
I am using an STM32WL55CC as SPI-Slave to read data from an SPI-master (1 master, 1 slave).
I have an SPI master that is talking occassionaly and I'm waiting for a message to start with a specific start-byte (0x3A) until I start reading a chunk of 60 Bytes.
If I'm polling the SPI line until I see the start-byte and then go ahead and read the rest of the message everything works fine. However, if I trigger the SPI line through an interrupt on the hardware NSS line the data transfer fails after reading the first 3 Bytes and I get an HAL_TIMEOUT returned.
This is the code I am using:
Initialization of SPI:
SPI_INIT()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
//HAL_NVIC_EnableIRQ(EXTI4_IRQn); // ENABLE IN CASE OF INTERRUPT BASED TRIGGER
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
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_HARD_INPUT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}SPI RX-Routine:
uint8_t rx[100] = {0};
uint8_t spiRxFlag = 0;
void SPI_RX()
{
if(HAL_SPI_Receive(&hspi1, rx, 1, 1) == HAL_OK && rx[0] == 0x3A){
spiRxFlag = 1;
}
if(spiRxFlag){
HAL_SPI_Receive(&hspi1, rx+1, 60, 5);
spiRxFlag=0;
}
}If I do it this way, reception works with no problem:
while(1)
{
SPI_RX();
}Now, if I try to trigger SPI_RX() in the interrupt callback (after enabling the interrupt in SPI_INIT() line 16) the reception fails after 3 correct and 1 erroneous byte with an HAL_TIMEOUT.
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
SPI_RX();
}I don't know what is happening here, since I am using the same function to receive data and would be really grateful if someone's got an idea whats going wrong.
If you think you'll need more information I'll be happy to provide that.
Best,
Julius
