Skip to main content
Explorer
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

    This topic has been closed for replies.

    20 replies

    Visitor II
    January 19, 2025

    Hi,

    i'm trying to develop a QuadSPI custom loader for STM32H563ZI with Macronix flash MX25L25645G. I started using the custom loader example attached in youtube video of ST (https://www.youtube.com/watch?v=XqCq0xtQmbI) ,porting library from QSPI to XSPI.

    I found some differences in autopolling function:

    • HAL_StatusTypeDef HAL_QSPI_AutoPolling (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout);

     

    • HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg,
      uint32_t Timeout)

    in XSPI autopolling funcion is missing the "cmd" parameter, how do I manage this for example in the function below?

     

    static uint8_t QSPI_WriteEnable(void) {
    QSPI_CommandTypeDef sCommand;
    QSPI_AutoPollingTypeDef sConfig;

     

    /* Enable write operations ------------------------------------------ */
    sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
    sCommand.Instruction = WRITE_ENABLE_CMD;
    sCommand.AddressMode = QSPI_ADDRESS_NONE;
    sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
    sCommand.DataMode = QSPI_DATA_NONE;
    sCommand.DummyCycles = 0;
    sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
    sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
    sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

     

    if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
    != HAL_OK) {
    return HAL_ERROR;
    }

     

    /* Configure automatic polling mode to wait for write enabling ---- */
    sConfig.Match = 0x02;
    sConfig.Mask = 0x02;
    sConfig.MatchMode = QSPI_MATCH_MODE_AND;
    sConfig.StatusBytesSize = 1;
    sConfig.Interval = 0x10;
    sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;

    sCommand.Instruction = READ_STATUS_REG_CMD;
    sCommand.DataMode = QSPI_DATA_1_LINE;


    if (HAL_QSPI_AutoPolling(&hqspi, &sCommand, &sConfig,
    HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
    return HAL_ERROR;
    }

    return HAL_OK;
    }

    Thank you.

     

    Graduate II
    January 19, 2025

    You can make your own wrapper, but the model now is that you send the command before calling the function, so the function just iterates on the matching against the data stream

    https://github.com/STMicroelectronics/stm32-mx25lm51245g/blob/d2dc02bdadf6b9874384d8725694ef14c7b6988e/mx25lm51245g.c#L85

    //****************************************************************************
    
    /**
     * @brief This function read the SR of the memory and wait the EOP.
     * @PAram hospi: QSPI handle
     * @PAram Timeout
     * @retval None
     */
    static uint8_t XSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hospi, uint32_t Timeout)
    { // sourcer32@gmail.com
     XSPI_RegularCmdTypeDef sCommand = {0};
     XSPI_AutoPollingTypeDef sConfig = {0};
    
     sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
     sCommand.IOSelect = XSPI_IOSELECT;
    
     /* Configure automatic polling mode to wait for memory ready */
     sCommand.Instruction = READ_STATUS_REG1_CMD;
     sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
     sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
     sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
     sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
     sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
     sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
     sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
     sCommand.DataLength = 1;
     sCommand.DummyCycles = 0;
     sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
     sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
    
     if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return(XSPI_ERROR);
     }
    
     sConfig.MatchValue = 0; // 0=READY,1=BUSY
     sConfig.MatchMask = SR1_BUSY;
     sConfig.MatchMode = HAL_XSPI_MATCH_MODE_AND;
     sConfig.IntervalTime = AUTO_POLLING_INTERVAL;
     sConfig.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE;
    
     if (HAL_XSPI_AutoPolling(hospi, &sConfig, Timeout) != HAL_OK)
     {
     return(XSPI_ERROR);
     }
    
     return(XSPI_OK);
    }
    
    //****************************************************************************
    //****************************************************************************
    
    /**
     * @brief This function send a Write Enable and wait it is effective.
     * @PAram hospi: QSPI handle
     * @retval None
     */
    static uint8_t XSPI_WriteEnable(XSPI_HandleTypeDef *hospi)
    { // sourcer32@gmail.com
     XSPI_RegularCmdTypeDef sCommand = {0};
     XSPI_AutoPollingTypeDef sConfig = {0};
    
     sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
     sCommand.IOSelect = XSPI_IOSELECT;
    
     /* Enable write operations */
     sCommand.Instruction = WRITE_ENABLE_CMD;
     sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
     sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
     sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
     sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
     sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
     sCommand.DataMode = HAL_XSPI_DATA_NONE;
     sCommand.DummyCycles = 0;
     sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
     sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
    
     if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return(XSPI_ERROR);
     }
    
     sCommand.Instruction = READ_STATUS_REG1_CMD;
     sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
     sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
     sCommand.DataLength = 1;
    
     if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return(XSPI_ERROR);
     }
    
     /* Configure automatic polling mode to wait for write enabling */
     sConfig.MatchValue = SR1_WREN;
     sConfig.MatchMask = SR1_WREN;
     sConfig.MatchMode = HAL_XSPI_MATCH_MODE_AND;
     sConfig.IntervalTime = AUTO_POLLING_INTERVAL;
     sConfig.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE;
    
     if (HAL_XSPI_AutoPolling(hospi, &sConfig, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return(XSPI_ERROR);
     }
    
     return(XSPI_OK);
    }
    
    //***************************************************************************
    Visitor II
    January 20, 2025

    Hi all,

    Thank you so much, very helpful!

    @Tesla DeLorean  i'm using the following pins:

    • OCTOSPI1_IO3 --> PF6
    • OCTOSPI1_IO2 --> PF7
    • OCTOSPI1_IO0 --> PF8
    • OCTOSPI1_IO1 --> PF9
    • OCTOSPI1_CLK --> PF10
    • OCTOSPI1_NCS --> PE11

    @ABasi.2Can you share also your configuration for the CSP_QSPI_EnableMemoryMappedMode and CSP_QSPI_WriteMemory fuctions?

    Thanks again.

    Graduate
    January 20, 2025

    Hi Berto

    yes no problem, keep in mind my memory is a MX25L512

    uint8_t CSP_QSPI_EnableMemoryMappedMode(void)
    {
     XSPI_RegularCmdTypeDef sCommand;
     XSPI_MemoryMappedTypeDef sMemMappedCfg;
     
    
     // Enable Memory-Mapped mode--------------------------------------------------
     sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
     sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
     sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
     sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
     sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
     sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
     sCommand.Address = 0;
     sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
     sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
     sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
     sCommand.AlternateBytes = 0;
     sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
     sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
     sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
     sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
     sCommand.DataLength = 0;
     sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
     sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
     sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
     sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
    
     sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
    
     if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
     {
     return HAL_ERROR;
     }
    
     if (HAL_XSPI_MemoryMapped(&hospi1,&sMemMappedCfg) != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     return HAL_OK;
    }

     

    uint8_t CSP_QSPI_WriteMemory(uint8_t* buffer, uint32_t address,uint32_t buffer_size)
    {
     XSPI_RegularCmdTypeDef sCommand;
     uint32_t end_addr, current_size, current_addr;
    
     
     // Calculation of the size between the write address and the end of the page
     current_addr = 0;
    
     while(current_addr <= address)
     {
     current_addr += MEMORY_PAGE_SIZE;
     }
     current_size = current_addr - address;
    
     // Check if the size of the data is less than the remaining place in the page
     if(current_size > buffer_size)
     {
     current_size = buffer_size;
     }
    
     // Initialize the adress variables
     current_addr = address;
     end_addr = address + buffer_size;
    
     sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
     sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
     sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
     sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
     sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
     sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
     sCommand.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
     sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
     sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
     sCommand.AlternateBytes = 0;
     sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
     sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
     sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
     sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
     sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
     sCommand.DummyCycles = 0;
     sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
     sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
    
     // Perform the write page by page
     do
     {
     sCommand.Address = current_addr;
     sCommand.DataLength = current_size;
    
     if(current_size == 0)
     {
    	 return HAL_OK;
     }
    
     // Enable write operations
     if(QSPI_WriteEnable() != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Configure the command
     if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Transmission of the data
     if(HAL_XSPI_Transmit(&hospi1, buffer,HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Configure automatic polling mode to wait for end of program
     if(QSPI_AutoPollingMemReady(HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Update the address and size variables for next page programming
     current_addr += current_size;
     buffer += current_size;
     current_size = ((current_addr + MEMORY_PAGE_SIZE) > end_addr) ?	(end_addr - current_addr) : MEMORY_PAGE_SIZE;
    
     }while(current_addr <= end_addr);
    
     return HAL_OK;
    }

     

    Visitor II
    January 20, 2025

    Hi @ABasi.2 ,

    thanks, my configuration is similar as yours, it returns an error in the last check:

    for(var = 0; var < SECTORS_COUNT; var++)
    {
    if(memcmp(buffer_test,(uint8_t*) (0x90000000 + var * MEMORY_SECTOR_SIZE),MEMORY_SECTOR_SIZE) != HAL_OK)
    {
    while(1); //breakpoint - error detected - otherwise QSPI works properly
    }
    }

    Berto_0-1737385542720.png

    Seems is not writing correctly data on the address 0x90000000

    Graduate
    January 20, 2025

    Hi berto

    i think there are some dummy clocks in your configuration that are wrong, another guy in this forum have an issue similar to yours and resolve managing the dummy clocks 

     

    check the parameter 

    sCommand.DummyCycles

     according to your memory datasheet

    Visitor II
    January 20, 2025

    Hi @ABasi.2 ,

    Thank you! I try to check this parameter, do i need to modify this just in the write funcion or in all commands functions?

    Visitor II
    January 21, 2025

    Hi,

    thanks so much for your suggestions, i'm trying to set up the correct dummycycles parameter.

    Just a question, which is your clock configuration to peripheral and octospi prescaler?

     

    Graduate
    January 21, 2025

    hello Berto!

    here my ioc file, i'm using the nucleo-H563ZI

    hope this helps

    notice i have HCLK 250Mhz and the OctoSpi is feeded by the HCLK

     

    Visitor II
    January 21, 2025

    Hi @ABasi.2

    Thanks again, now i can debug the main code without errors but only setting the dummycycles in CSP_QSPI_EnableMemoryMappedMode to "26" but it's not a datasheet value i'm not sure is everything correct.

    Graduate
    January 21, 2025

    Hello Berto

    i don't know if its a valid value of dummy cycle, in my CSP_QSPI_EnableMemoryMappedMode i have 10 

    in all the other function i have 0.

     

     

     

      

    Visitor II
    January 21, 2025

    Yes you're right, i'm checking the datasheet if I find some errors with commands. I let you know,

    Thanks again for support.

    Visitor II
    January 28, 2025

    Hi All,

    I found the error, it was an instruction command on Write funcion. Now i see that seems writing correctly but i have problem reading. Can I see how you set up your WriteMemory and EnableMemoryMappedMode functions?

    Thanks.

    Graduate
    January 28, 2025

    hello Berto!

    i'm glad you found the error.

    yes no problem for the functions, i hope this helps

    uint8_t CSP_QSPI_WriteMemory(uint8_t* buffer, uint32_t address,uint32_t buffer_size)
    {
     XSPI_RegularCmdTypeDef sCommand;
     uint32_t end_addr, current_size, current_addr; 
    
     // Calculation of the size between the write address and the end of the page
     current_addr = 0;
    
     while(current_addr <= address)
     {
     current_addr += MEMORY_PAGE_SIZE;
     }
     current_size = current_addr - address;
    
     // Check if the size of the data is less than the remaining place in the page
     if(current_size > buffer_size)
     {
     current_size = buffer_size;
     }
    
     // Initialize the adress variables
     current_addr = address;
     end_addr = address + buffer_size;
    
     sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
     sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
     sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
     sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
     sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
     sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
     sCommand.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
     sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
     sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
     sCommand.AlternateBytes = 0;
     sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
     sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
     sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
     sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
     sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
     sCommand.DummyCycles = 0;
     sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
     sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
    
     // Perform the write page by page
     do
     {
     sCommand.Address = current_addr;
     sCommand.DataLength = current_size;
    
     if(current_size == 0)
     {
    	 return HAL_OK;
     }
    
     // Enable write operations
     if(QSPI_WriteEnable() != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Configure the command
     if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Transmission of the data
     if(HAL_XSPI_Transmit(&hospi1, buffer,HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Configure automatic polling mode to wait for end of program
     if(QSPI_AutoPollingMemReady(HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     // Update the address and size variables for next page programming
     current_addr += current_size;
     buffer += current_size;
     current_size = ((current_addr + MEMORY_PAGE_SIZE) > end_addr) ?	(end_addr - current_addr) : MEMORY_PAGE_SIZE;
    
     }while(current_addr <= end_addr);
    
     return HAL_OK;
    }
    uint8_t CSP_QSPI_EnableMemoryMappedMode(void)
    {
     XSPI_RegularCmdTypeDef sCommand;
     XSPI_MemoryMappedTypeDef sMemMappedCfg; 
    
     // Enable Memory-Mapped mode--------------------------------------------------
     sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
     sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
     sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
     sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
     sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
     sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
     sCommand.Address = 0;
     sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
     sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
     sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
     sCommand.AlternateBytes = 0;
     sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
     sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
     sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
     sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
     sCommand.DataLength = 0;
     sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
     sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
     sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
     sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
    
     sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
    
     if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
     {
     return HAL_ERROR;
     }
    
     if (HAL_XSPI_MemoryMapped(&hospi1,&sMemMappedCfg) != HAL_OK)
     {
     return HAL_ERROR;
     }
    
     return HAL_OK;
    }

     

    Visitor II
    February 27, 2025

    Hi All,

    Sorry for late reply, in meantime i got my own hardware with STM32H523RCT and Macronix MX25L25645G.

    I'm testing the loader and having the results attached, seems working correctly.

    But when I create the .stldr file and place in STM32CubeProgrammer I can't read neither erase. Do you have any suggestion on this issue?

    Thanks in advance.

    Graduate
    February 27, 2025

    Hello Berto!

    it seems now your write and read functions work correctly

    which is the error the programmer said?

     

    if i have to guess:

     

    1) did you have commented the "test function" you have used in your mail to test the read/write fuctionality?

    2) is it possible to view the linker file the cube create for you and the custom linker you have created?

    3) if you have created a new linker did you change the path to the new linker file?

     

    best reguards

     

    Visitor II
    February 27, 2025

    Hello,

    Sure, attached you can find both linker files.

    Yes i tried both, commenting testing functions and setting the path of created linker.

    Cubeprorgrammer returns the following error:

    Cubepro.png

    Do i need to flash a test.bin before start reading the first time? 

    Thanks so much

    Graduate
    February 27, 2025

    hello

    i didnt see the two linker file Berto

    maybe there is an error in the Dev_Inf.c file or Loader_Src.c file?

    i attach here mine, make sure in Loader_Src.c Init function to use the correct address for SCB->VTOR