2025-04-21 10:50 AM
MCU: STM32U5G9VJ
I am sending simple single-line commands using the HAL_XPI library and the HSPI peripheral.
Problem (See code at bottom of post):
If I use the blocking call HAL_XSPI_Transmit, I get a timeout.
if I use the DMA call HAL_XSPI_Transmit_DMA, I get a HAL_XSPI_ErrorCallback.
The OSPI peripheral is working fine, it is the HSPI only that is having this issue.
Clock Setup:
Code:
HAL_StatusTypeDef status;
XSPI_RegularCmdTypeDef sCommand = {0};
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = cmd;
// Address Config
sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
sCommand.Address = address;
// Data Config
sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
sCommand.DataLength = data_len;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
status = HAL_XSPI_Command(&hxspi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
if (status != HAL_OK) {
LOG_ERR("HSPI CMD Error: %d\n", status);
Error_Handler();
}
#define USE_DMA 0
#if USE_DMA == 1
is_tx_done = false;
status = HAL_XSPI_Transmit_DMA(&hxspi1, data);
if (status != HAL_OK) {
LOG_ERR("HSPI Error: %d\n", status);
Error_Handler();
}
// wait for the previous transmission to complete
uint64_t timeout_check = 0;
while (!is_tx_done) {
if (++timeout_check > (1E6)) {
LOG_ERR("HSPI Interrupt Timeout\n");
Error_Handler();
}
}
#else
status = HAL_XSPI_Transmit(&hxspi1, data, HAL_XSPI_TIMEOUT_DEFAULT_VALUE);
if (status != HAL_OK) {
LOG_ERR("HSPI CMD Error: %s (%d)\n", HAL_Status_To_String(status), status);
Error_Handler();
}
#endif
HAL_Delay(2);
2025-04-21 12:31 PM
Are we sure this is a Timeout? Not sure clocking out data is gated on any pin state.
Is the peripheral in a busy state when you send the failing transaction?
In Memory Mapped mode?
Interrupt handlers and callbacks, and NVIC all configured?
2025-04-21 1:16 PM
@Tesla DeLorean wrote:Are we sure this is a Timeout? Not sure clocking out data is gated on any pin state.
Yes, HAL_XSPI_Transmit returns HAL_TIMEOUT.
It flushes out the transmit data, but then it times out on the transfer complete flag check:
status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_FT, SET, tickstart, Timeout);
if (status != HAL_OK)
{
break;
}
*((__IO uint8_t *)data_reg) = *hxspi->pBuffPtr;
hxspi->pBuffPtr++;
hxspi->XferCount--;
} while (hxspi->XferCount > 0U);
if (status == HAL_OK)
{
/* Wait till transfer complete flag is set to go back in idle state */
status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout);
@Tesla DeLorean wrote:In Memory Mapped mode?
Interrupt handlers and callbacks, and NVIC all configured?
I have not called any memory map configs. I do have the interrupts and callbacks configured, but I would not expect to need those in the blocking HAL_XSPI_Transmit call. The HAL_XSPI_Transmit_DMA call does hit the errorcallback, so callback is being called in that configuration.