SPI Issue - HAL_BUSY (STM32L4)
I've been having issues with getting an SD card working on an STM32L4R5ZI Nucleo board when using essentially the same code (with minor tweaks) without issues on the STM32WB55 Nucleo board. I've been going through the code of both to determine where the problem is with the STM32L4 board. I assumed I had a configuration issue in main (which I might still have, but the issue I found isn't what I was expecting).
When running my SD_IO_Init function, it's writing dummy bits but when it calls HAL_SPI_TransmitReceive(), it's receiving HAL_BUSY as a response. Usually when I'm having issues with my code, it's my implementation that's the issue but I'm not sure if that's necessarily the case here. Below is the code I'm running:
/* SPI INIT */
static void MX_SPI1_Init(void)
{
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_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
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();
}
}
/* MAIN */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_LPUART1_UART_Init();
MX_USART3_UART_Init();
MX_USB_OTG_FS_PCD_Init();
MX_SPI1_Init();
MX_FATFS_Init();
BSP_SD_Init();
while (1)
{
}
}
/* SD INIT */
void SD_IO_Init(void)
{
sd_spi.Instance = SPI1;
SD_IO_CSState(1);
for (uint8_t counter = 0; counter <= 9; counter++)
{
/* Send dummy byte 0xFF */
SD_IO_WriteByte(SD_DUMMY_BYTE);
}
}
uint8_t SD_IO_WriteByte(uint8_t Data)
{
HAL_StatusTypeDef status = HAL_OK;
uint8_t data;
status = HAL_SPI_TransmitReceive(&sd_spi, (uint8_t*) &Data, &data, 1, SD_DATATIMEOUT);
if(status != HAL_OK)
{
/* Execute user timeout callback */
//SPIx_Error();
//Handle error here
}
return data;
}HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,
uint32_t Timeout)
{
uint16_t initial_TxXferCount;
uint16_t initial_RxXferCount;
uint32_t tmp_mode;
HAL_SPI_StateTypeDef tmp_state;
uint32_t tickstart;
#if (USE_SPI_CRC != 0U)
__IO uint32_t tmpreg = 0U;
uint32_t spi_cr1;
uint32_t spi_cr2;
__IO uint8_t *ptmpreg8;
__IO uint8_t tmpreg8 = 0;
#endif /* USE_SPI_CRC */
/* Variable used to alternate Rx and Tx during transfer */
uint32_t txallowed = 1U;
HAL_StatusTypeDef errorcode = HAL_OK;
/* Check Direction parameter */
assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
/* Process Locked */
__HAL_LOCK(hspi);
/* Init tickstart for timeout management*/
tickstart = HAL_GetTick();
/* Init temporary variables */
tmp_state = hspi->State;
tmp_mode = hspi->Init.Mode;
initial_TxXferCount = Size;
initial_RxXferCount = Size;
#if (USE_SPI_CRC != 0U)
spi_cr1 = READ_REG(hspi->Instance->CR1);
spi_cr2 = READ_REG(hspi->Instance->CR2);
#endif /* USE_SPI_CRC */
if (!((tmp_state == HAL_SPI_STATE_READY) || \
((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
{
errorcode = HAL_BUSY; /* RETURNING HAL_BUSY HERE */
goto error;
}
........ I hesitate to report this as a bug as experience shows this is usually an issue on my end but I don't really understand what's causing it to return busy (it appears to be handled on the HAL side. If that's not working, I assume that would be considered a bug).
It currently shows "tmp_state" to be "HAL_SPI_STATE_RESET." I'm not sure where hspi->State is being set
The only thing I could find regarding this state when searching had to do with HAL_SPI callbacks but I'm not using any interrupts so I'm not entirely sure what might cause that problem (or if I need to place empty functions to replace the weak callback functions?). Essentially, I'm not really sure I understand the issue or where to go from here.
Any help you can give would be greatly appreciated. Thanks!
