cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H5 external loader

AMend.7
Associate III

Hi,

 I need the project used to generate the external loader: MX25LM51245G_STM32H573I-DK.stldr. My custom board uses a STM32H563VIT6 and the same octo-spi flash from Macronix used in the STM32H573I-DK board. But with different gpios connections. So this project would be of great help to develop the external flash loader for my board.

 

Ari

35 REPLIES 35
ABasi.2
Associate III

Hello!

i have followed your advise , i have instrumented with UART 

 

i found someting really strange to me:

 

the problem occours in this piece of code (that work without problem in the main):

uint8_t CSP_QUADSPI_Init(void)
{
 
uint8_t mark1[] = "MARK1";
uint8_t mark2[] = "MARK2";
uint8_t mark3[] = "MARK3";
 
HAL_UART_Transmit(&huart3,mark1,sizeof(mark1),1000);
 
  //prepare QSPI peripheral for ST-Link Utility operations
  if(HAL_XSPI_DeInit(&hospi1) != HAL_OK)
  {
  HAL_UART_Transmit(&huart3,mark2,sizeof(mark2),1000);
  return HAL_ERROR;
  }
 
  HAL_UART_Transmit(&huart3,mark3,sizeof(mark3),1000);
 
  MX_OCTOSPI1_Init();
 
  if(QSPI_ResetChip() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  HAL_Delay(1);
 
  if(QSPI_AutoPollingMemReady() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  if(QSPI_WriteEnable() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  if(QSPI_Configuration() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  return HAL_OK;
}
 
on the UART we can see "MARK1",but the code does'nt return from HAL_XSPI_DeInit(&hospi1)
after "MARK1" nothing more appen on the UART, no "MARK2" and no "MARK3"
 
it seems the code is stuck inside HAL_XSPI_DeInit(&hospi1) that is code written by cube ide , the function is in the file stm32h5xx_hal_xspi.c 
 
i attach the file at this message
 
 
 
 

 

Make sure hospi1 structure has the instance defined, there is not static initialization in loaders. Perhaps Hard Faulting or delays not working

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ABasi.2
Associate III

Hi!

you were right!

the problem was the call to the HAL_XSPI_DeInit(&hospi1) before the call to MX_OCTOSPI1_Init()!

its not possible to just remove the HAL_XSPI_DeInit(&hospi1), because during the sectors erase the init is called before each sector erase by the st programmer

so i use this method:

uint8_t CSP_QUADSPI_Init(void)
{
 
  console(consoleDefault,"INIT QUADSPI\r\n");
 
  //prepare QSPI peripheral for ST-Link Utility operations
 
  if(hospi1.Instance == OCTOSPI1)
  {
       if(HAL_XSPI_DeInit(&hospi1) != HAL_OK)
       {
        console(consoleDefault,"DEINIT ERROR\r\n");
       return HAL_ERROR;
      }
     console(consoleDefault,"DEINIT OK\r\n");
  }
 
  MX_OCTOSPI1_Init();
 
  if(QSPI_ResetChip() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  HAL_Delay(1);
 
  if(QSPI_AutoPollingMemReady() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  if(QSPI_WriteEnable() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  if(QSPI_Configuration() != HAL_OK)
  {
    return HAL_ERROR;
  }
 
  return HAL_OK;
}

now i am able to read an sector erase the external memory!!!

but not to write....

 

the write function is called multiple times.. but only the first is going OK

 

int
Write(uint32_t Address, uint32_t Size, uint8_t* buffer) {
 
 
console(consoleDefault,"WRITE\r\n");
__set_PRIMASK(0); //enable interrupts
 
 
if(hospi1.Instance != OCTOSPI1)
{
console(consoleDefault,"INSTANCE err\r\n");
}
 
if (HAL_XSPI_Abort(&hospi1) != HAL_OK) {
    console(consoleDefault,"WRITE abort err\r\n");
        __set_PRIMASK(1); //disable interrupts
        return LOADER_FAIL;
    }
 
    if (CSP_QSPI_WriteMemory((uint8_t*) buffer, (Address & (0x0fffffff)), Size) != HAL_OK) {
    console(consoleDefault,"WRITE err\r\n");
        __set_PRIMASK(1); //disable interrupts
        return LOADER_FAIL;
    }
 
    __set_PRIMASK(1); //disable interrupts
    return LOADER_OK;
}
 
the second time the HAL_XSPI_Abort return ERROR!
 
i don't know why this firmware is like the Omero odyssey...

 

 

 

ABasi.2
Associate III

found the issue..

 

the HAL_XSPI_Abort(&hospi1)  if don't have anything to abort return an error.. 

hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE;

 

the first time we call it the memory is in memory mapped mode.. so it is necessary and  it work.. the second time it is not necessary and return error..

 

i have added a check on the status of the periferal before call the abort function and added the function that enable memory mapped mode at the end of the write (i do'n know if is necessary the last call of the write)..

 

so .. only the chip erase now is missing (its optional)

ABasi.2
Associate III

finally all is working!

the chip erase was a problem of timeout , the default autopolling have HAL_XSPI_TIMEOUT_DEFAULT_VALUE for timeout that is 5s, my memory have a typical erasing time of 140s to max 200s so i have increased the value to 200s and now its working!

 

i have tried to remove the offset to RAM (xrw) : ORIGIN = 0x20003004, LENGTH = 256K - 12292 but its actually necessary ..  i think only ST could explain why!

 

i attache to this comment my working  linker file and loader_src.c 

 

thank you to everyone for the really precious advise!

 

 

 

 

Yes, the 0x20003004 needs a bit more documentation from ST, but is what other working H5 loaders use.

The +4 offset comes from the fact that ST stuffs opcodes at +0 to call the entry point functions, ie Init(), Read(), etc.

/**
  * @brief  Initializes the QSPI interface.
  * @retval QSPI memory status
  */
static uint8_t BSP_XSPI_Init(XSPI_HandleTypeDef *hospi)
{
  //memset(hospi, 0, sizeof(XSPI_HandleTypeDef));

  hospi->Instance = OCTOSPI1; // For DeInit to bite on

  /* Call the DeInit function to reset the driver */
  if (HAL_XSPI_DeInit(hospi) != HAL_OK)
  {
    return(XSPI_ERROR);
  }

  /* System level initialization */
  BSP_XSPI_MspInit(hospi, NULL);

  /* OSPI initialization */
  hospi->Init.FifoThresholdByte       = 1; // 1..32 Interrupt threshold
...
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..