Question
STM32F0 SPI Timeout Error with illegal HAL state
Posted on August 19, 2016 at 12:28
Hello,
[I have just written my issue in detail and it has been deleted when I clicked Ok. Thanks, I will write it again though.] We are using the STM32F072CB with the HAL driver in our application and facing serious trouble with the SPI. The peripheral code was generated by STM32CubeMx. The CPU runs at 48MHz and the SPI at 3MHz. I have tracked down the problem to be a TIMEOUT condition in HAL_SPI_TransmitReceive(). I can reproduce the error by too frequent calls to that function. The strange (and in my eyes, buggy!) reason for the timeout condition in the TransmitReceive function is an illegal state of the SPI instance, &hspi2. When it runs into timeout, these parts of the state don't make sense: TxXferSize = 31 // ok TxXferCount = 0 // ok RxXferSize = 31 // ok RxXferCount = 1 // wrong So the HAL thinks that there is 1 more word to receive, which i a clear violation of how SPI works and how the HAL function is written. So appart from not understanding this condition, I can solve the problem by implementing a little delay after every TransmitReceive call. Then everything works fine. Here is how I reproduce the behaviour. The following loop is run in the main() right after the initialization of CubeMx:uint8_t txBuffer[31];
uint8_t rxBuffer[31];
while
(1) {
// A short delay avoids trouble
for
(uint32_t i = 0; i < 500; i++);
uint8_t status;
status = HAL_SPI_TransmitReceive(&hspi2 ,txBuffer, rxBuffer, 31, 1000);
printf(
''s''
);
if
(status != 0)
printf(
''\nERROR\n''
);
}
In case you wonder, here are the initialization routines of the SPI:
void
MX_SPI2_Init(
void
)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
// hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if
(HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
}
and
else
if
(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(SPI2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
The clock polarity and phase are triple-checked with the SPI-target and do work in general.
Do you guys have an idea what is going on here and how to solve the issue? Am I missing some timing constraint on when I am allowed to call the HAL TransmitReceive function? Why do I have to wait so long?
Any hints on this problem are much appreciated!
Have a great weekend,
Cheers, Janos
#stm32-stm32f0-spi-bug-problem