Skip to main content
Visitor II
April 15, 2024
Solved

Write, Read code for STM32L412 elusive

  • April 15, 2024
  • 5 replies
  • 3483 views

What code works for the STM32L412 device?

I want to load an RTC calibration value into flash memory and retrieve it on subsequent running of the firmware.

 

I've got the reading of specific calibration values working in a different IC, for ADC calibration, 

ICTempCal1 = (*((volatile uint16_t*)(0x1FF8007A))); 

Will this work with the L412 IC?

 

But I cannot get programming of a page to work. 

I tried 'HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x080E0000,1000);'

But that fails within the routine. I'm assuming the Erase routine worked, but I haven't got far enough to check.

 

I tried the 'STM32CubeL4/Projects/NUCLEO-L4P5ZG/Examples/FLASH
/FLASH_FastProgram' code and found it to fail in the last section, the GetBank routine.

Different IC also.

 

Can anyone give me the code for these operations?

 

    This topic has been closed for replies.
    Best answer by CGadg

    I can get the code to build in 'STM32CubeL4/Projects/NUCLEO-L412KB/Examples/FLASH/FLASH_EraseProgram'

    I'll update after working through that

    5 replies

    ST Employee
    April 22, 2024

    Hello @CGadg 

    By making a few changes to the project:
    'Projects\NUCLEO-L4P5ZG\Examples\FLASH\FLASH_WriteProtection'
    I modified the address of FLASH_USER_START_ADDR start and  FLASH_USER_END_ADDR ADDR to fit with address you mentioned 0x080E0000, and I modified the bank which is located in the memory zone you have selected:

     /* The desired pages are not write protected */
     /* Fill EraseInit structure************************************************/
     EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
     EraseInitStruct.Banks = FLASH_BANK_2;
     EraseInitStruct.Page = StartPage;
     EraseInitStruct.NbPages = EndPage - StartPage + 1;
    #define FLASH_USER_START_ADDR ADDR_FLASH_PAGE_224 /* Start @ of user Flash area */
    #define FLASH_USER_END_ADDR ADDR_FLASH_PAGE_228 /* End @ of user Flash area */

    For the example you mentioned
    'STM32CubeL4/Projects/NUCLEO-L4P5ZG/Examples/FLASH/FLASH_FastProgram' 
    I make the changes that you are asking to make in the code and the example works and the routine is done:

    #define FLASH_USER_START_ADDR ADDR_FLASH_PAGE_224 /* Start @ of user Flash area */
    #define FLASH_USER_END_ADDR ADDR_FLASH_PAGE_228 /* End @ of user Flash area */
    #define DATA_32 ((uint32_t)0x12345678)
    typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
     while (Address < (FLASH_USER_END_ADDR - (FLASH_ROW_SIZE*sizeof(uint64_t))))
     {
     if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, 1000) == HAL_OK)
     {
     Address = Address +0x8U ; //+ (FLASH_ROW_SIZE*sizeof(uint64_t));
     }
     else
     {
     /* Error occurred while writing data in Flash memory.
     User can add here some code to deal with this error */
     while (1)
     {
     BSP_LED_On(LED3);
     }
     }
     }
    
     if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, (uint64_t)src_addr) != HAL_OK)
     {
     /* Error occurred while writing data in Flash memory.
     User can add here some code to deal with this error */
     while (1)
     {
     BSP_LED_On(LED3);
     }
     }
    
     /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
     HAL_FLASH_Lock();
    
     /* Check if the programmed data is OK
     MemoryProgramStatus = 0: data programmed correctly
     MemoryProgramStatus != 0: number of words not programmed correctly ******/
     Address = FLASH_USER_START_ADDR;
     MemoryProgramStatus = 0x0;
    
     while (Address < FLASH_USER_END_ADDR)
     {
     for (data_index = 0; data_index < FLASH_ROW_SIZE; data_index++)
     {
     data64 = *(__IO uint64_t *)Address;
    
     if(data64 != Data64_To_Prog[data_index])
     {
     MemoryProgramStatus++;
     }
     Address = Address + sizeof(uint64_t);
     }
     }
     /* Check the correctness of written data */
     Address = FLASH_USER_START_ADDR;
    
     while (Address < FLASH_USER_END_ADDR)
     {
     if((*(__IO uint32_t*) Address) != DATA_32)
     {
     MemoryProgramStatus = FAILED;
     }
     Address += 4;
     }

     

    CGadgAuthor
    Visitor II
    April 22, 2024

    Thanks nouirakh,

    I'll work through this and see if I can get it working

    ST Employee
    April 22, 2024

    I worked on these following examples:
    'Projects/NUCLEO-L4P5ZG/Examples/FLASH/FLASH_FastProgram'
    'Projects\NUCLEO-L4P5ZG\Examples\FLASH\FLASH_WriteProtection'
    For the 'ADDR_FLASH_PAGE_224' it is defined in the main.h 

    You can find in the attached files the main.c/.h 

    I double check this code it works for me using Cube IDE and EWARM , Maybe you can inspire from this example and make the necessary adaptation with your IC.
    Could you verify it from your end and utilize the IC you mentioned?

    CGadgAuthor
    Visitor II
    April 24, 2024

    Yes thanks,

    I've just got one error left, the line

    CGadg_0-1713954353622.png

     

    is not understood by Cube IDE.... "subscripted value is neither array nor pointer nor vector"

    Total of 3 errors within that misunderstanding

    ST Employee
    April 26, 2024

    It would be greatly appreciated if you could verify these definitions in your code in order to resolve this error?
    In the example "Projects/NUCLEO-L4P5ZG/Examples/FLASH/FLASH_FastProgram", We have:

    /* Private define ------------------------------------------------------------*/
    #define FLASH_ROW_SIZE 64
    /* Private variables ---------------------------------------------------------*/
    __IO uint64_t data64 = 0;
    /* Table used for fast programming */
    static const uint64_t Data64_To_Prog[FLASH_ROW_SIZE] = {
     0x0000000000000000, 0x1111111111111111, 0x2222222222222222, 0x3333333333333333,
     0x4444444444444444, 0x5555555555555555, 0x6666666666666666, 0x7777777777777777,
     0x8888888888888888, 0x9999999999999999, 0xAAAAAAAAAAAAAAAA, 0xBBBBBBBBBBBBBBBB,
     0xCCCCCCCCCCCCCCCC, 0xDDDDDDDDDDDDDDDD, 0xEEEEEEEEEEEEEEEE, 0xFFFFFFFFFFFFFFFF,
     0x0011001100110011, 0x2233223322332233, 0x4455445544554455, 0x6677667766776677,
     0x8899889988998899, 0xAABBAABBAABBAABB, 0xCCDDCCDDCCDDCCDD, 0xEEFFEEFFEEFFEEFF,
     0x2200220022002200, 0x3311331133113311, 0x6644664466446644, 0x7755775577557755,
     0xAA88AA88AA88AA88, 0xBB99BB99BB99BB99, 0xEECCEECCEECCEECC, 0xFFDDFFDDFFDDFFDD};
    /**
     * @brief Main program
     * @param None
     * @retval None
     */
    int main(void)
    {
     uint32_t src_addr = (uint32_t)Data64_To_Prog;
     uint8_t data_index = 0;

     

    CGadgAuthor
    Visitor II
    April 26, 2024

    I've imported it into a fresh project and there is a mismatch in definitions for 'SYSCFG_MEMRMP_FB_MODE', the compiler asks if I mean '...MEM MODE'. I guess so but I don't want to guess.

    It also needs FLASH_BANK_2 defining, though I can't see where that is.

     

    CGadgAuthor
    Visitor II
    April 26, 2024

    Thanks Kholdoun,

    I'll probably need to go through it again on Monday though,

    Cheers.

    ST Employee
    April 30, 2024

    Hello @CGadg 

    In order to give better visibility on the answered topics, please click on 'Select as Best' on my reply which solved your issue or answered your question. See also 'Best Answers

    Thanks 
    Kholdoun

    CGadgAuthor
    Visitor II
    April 30, 2024

    The STM32 Github code I found is a version of what you were working on, though just further trawling found it.

    Thank you for trying to help.