Skip to main content
Visitor II
April 21, 2025
Question

HAL_XSPI_Transmit timeout

  • April 21, 2025
  • 2 replies
  • 728 views

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:

LCorb2_1-1745257208096.png

 

LCorb2_0-1745257186264.png

 

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);

 

    This topic has been closed for replies.

    2 replies

    Graduate II
    April 21, 2025

    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?

    LCorb.2Author
    Visitor II
    April 21, 2025

     


    @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. 

    LCorb.2Author
    Visitor II
    April 30, 2025

    I think the issue was the “memory size” settings.  I had this set to 16 Bits, but when I bumped this to 16Gbits it fixed the transmit error.  This seems odd since I am not using memory-mapped mode.

    Some additional questions.

    Background: I am sending 640 bytes of  data with @ 100 MHz

    Instruction: 1 Byte: 0x32
    Address: 3 bytes

    Pin settings: Very High Speed

    1. Clocks are being sent pre-chip select

      There are a series of clocks being sent before the chip select goes low.  I have a free-running clock off; why am I seeing extra clocks?

      LCorb2_11-1746047950145.png

       

    2. The first clock pulse is sometimes missing:

      Every instruction/command is 0x32.

      However, some commands seem to be missing the first clock, and shifting this command to 0x64

      Correct Instruction Bytes – first clock is at 12ns, CMD is 0x32
       
      Incorrect Instruction Byte – first clock is at 20ns, CMD is 0x64
      LCorb2_13-1746047950149.png

       

    3. Delays in the data stream when sending 640 bytes using DMA.

      The data stream has random pauses in the stream when sending 640 bytes @ 100 Mhz.  Perhaps the bus cannot keep up at this speed?

    I am using DMA and enabled burst length of 64

    LCorb2_15-1746047950155.png