Skip to main content
CGadg
Associate III
April 15, 2024
Solved

Write, Read code for STM32L412 elusive

  • April 15, 2024
  • 12 replies
  • 3556 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

12 replies

nouirakh
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;
 }

 

CGadg
CGadgAuthor
Associate III
April 22, 2024

Thanks nouirakh,

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

nouirakh
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?

CGadg
CGadgAuthor
Associate III
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

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

 

CGadg
CGadgAuthor
Associate III
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.

 

CGadg
CGadgAuthor
Associate III
April 26, 2024

Thanks Kholdoun,

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

Cheers.

nouirakh
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

CGadg
CGadgAuthor
Associate III
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.