Skip to main content
AMend.7
Associate III
October 23, 2023
Question

STM32H5 external loader

  • October 23, 2023
  • 20 replies
  • 15025 views

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

20 replies

Tesla DeLorean
Guru
October 23, 2023

Could probably get something close via  https://github.com/STMicroelectronics/stm32-external-loader/tree/main/STM32L5x_boards/MX25LM51245G_STM32L562E-DK

With a pin list I could probably patch the current one, or port one of the H7/U5 variants I have working.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
KDJEM.1
Technical Moderator
October 24, 2023

Hi @AMend.7 ,

Besides, the reply shared by @Tesla DeLorean, thanks to STM32CubeProgrammer software description you can create your own external loader.

For that, please follow the steps shared in UM2237 and precisely 2.3.3 Developing customized loaders for external memory section.

I hope this help you!

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Tesla DeLorean
Guru
October 24, 2023

I think having some XSPI examples for the H5 would seem like a more pressing need.

https://github.com/STMicroelectronics/stm32-external-loader/tree/main

Ported some of my Winbond Quad examples over to H5, building at least, but not something I can test in the near term.

I think the manual falls short of the overall complexity and difficulty in constructing and testing external loaders. And they could have be designed with a lot better thought to allow for pin level configurability.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
KDJEM.1
Technical Moderator
October 25, 2023

Hi @AMend.7 ,

I noted that the same request is already shared with your FAE.

For sure he will get back to you if a project is available.

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Tesla DeLorean
Guru
October 25, 2023

Yes, having in the OSPI / XSPI Examples directory would be the way to go, using the BSP/CSP code or whatever so there's a single point of change for porting. Ideally putting code here would force the dog-fooding of tools/resources, ie one where ST has to get it right and tested because it's what they have to use day in and out.

I did order up some additional NUCLEO-H5's from DigiKey, but I should be able to patch the .STLDR before they get here.

; ARI STM32H563VIT6 MX25LM51245G
;
; PE11 ------> OCTOSPI1_NCS AF6
; PB2 ------> OCTOSPI1_DQS AF10
; PA3 ------> OCTOSPI1_CLK AF3
; PD11 ------> OCTOSPI1_IO0 AF9
; PD12 ------> OCTOSPI1_IO1 AF9
; PC2 ------> OCTOSPI1_IO2 AF9
; PD13 ------> OCTOSPI1_IO3 AF9
; PE7 ------> OCTOSPI1_IO4 AF10
; PE8 ------> OCTOSPI1_IO5 AF10
; PE9 ------> OCTOSPI1_IO6 AF10
; PE10 ------> OCTOSPI1_IO7 AF10
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
AMend.7
AMend.7Author
Associate III
October 25, 2023

I discovered that there is an MX25LM51245G driver equivalent to the one used in the flash loader project for the U5 dev boards, but adapted for the XSPI interface. I'll try to make the flash loader from this driver.

\STM32Cube_FW_H5_V1.1.1\Drivers\BSP\Components\mx25lm51245g

I don't understand why ST changed from OSPI to XSPI in the STM32H5's HAL library, if the H5's OSPI hardware is the same as the U5's.

Tesla DeLorean
Guru
October 25, 2023

That and I could only find 8 IO pins on the H5 I was looking at. The code churn drives me mental..

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
October 27, 2023

Ok, looks like my H5 boards will come in on Monday

@Aziz BRIGUI is there some rational behind H5 external loaders building at 0x20003004 ?

========================================================================

** ELF Header Information

 File Name: MX25LM51245G_STM32H573I-DK.stldr

 Machine class: ELFCLASS32 (32-bit)
 Data encoding: ELFDATA2LSB (Little endian)
 Header version: EV_CURRENT (Current version)
 Operating System ABI: none
 ABI Version: 0
 File Type: ET_EXEC (Executable) (2)
 Machine: EM_ARM (ARM)

 Image Entry point: 0x20003005
 Flags: None (0x05000000)

 ARM ELF revision: 5 (ABI version 2)

 Conforms to Base float procedure-call standard

 Header size: 52 bytes (0x34)
 Program header entry size: 32 bytes (0x20)
 Section header entry size: 40 bytes (0x28)

 Program header entries: 2
 Section header entries: 20

 Program header offset: 159376 (0x00026e90)
 Section header offset: 159440 (0x00026ed0)

 Section header string table index: 1

========================================================================

** Program header #0 (PT_LOAD) [PF_R]
 Size : 200 bytes
 Virtual address: 0x00000000 (Alignment 4)


====================================

** Program header #1 (PT_LOAD) [PF_X + PF_W + PF_R]
 Size : 16205 bytes
 Virtual address: 0x20003004 (Alignment 4)


========================================================================
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
ABasi.2
Senior
July 24, 2024

hi!

did you succeed to make the external loader?

I'm trying my best, I have a functional driver for a quad quad spi memory but when I make the external loader it doesn't work (read data failed)

I'm using the NUCLEO-H563ZI with a MX25L512 

I think I have problem with the linker file

if you have succeeded can you share your project?

best regards

 

 

Tesla DeLorean
Guru
July 24, 2024

Ultimately I did get the OCTO part (MX25LM) working for Ari, as I recall.

I do have my own H5 QSPI External Loaders working too now, for the MX25L and W25Q series, and can build to order. This for the MX25L64 but just needs a recompile with pin details for an MX25L512

https://github.com/cturvey/stm32extldr/tree/main/h5_mx25l6433f

This is my H5 Linker Script for a build using HAL and GNU/GCC + MAKE, ie not Cube and without interrupt non-sense.

https://github.com/cturvey/stm32extldr/blob/main/ExternalLoader_H5.ld

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
ABasi.2
Senior
July 25, 2024

thank you!

today  i will try to use your linker file!

i only have two  questions if you want to answer:

RAM_INFO (r) : ORIGIN = 0, LENGTH = 1K /* 200-byte StorageInfo */
RAM_PROG (xrw) : ORIGIN = 0x20003004, LENGTH = 256K-12292 /* 0x20003004 for H5 ?? */

1) why the origin is at 0x20003004?

2) in the Loader_src.c file i have to change the address of VTOR.

if i understand well the line SCB->VTOR = 0x20000000 | 0x200; should be modified in SCB->VTOR = 0x20003004;

am i correct?

thank you!

ABasi.2
Senior
July 28, 2024

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
 
 
 
 

 

Tesla DeLorean
Guru
July 28, 2024

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 VenmoUp vote any posts that you find helpful, it shows what's working..
ABasi.2
Senior
July 30, 2024

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
Senior
July 30, 2024

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
Senior
July 30, 2024

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!

 

 

 

 

Tesla DeLorean
Guru
July 30, 2024

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 VenmoUp vote any posts that you find helpful, it shows what's working..