Emulated EEPROM not storing values

Post here first, or if you can't find a relevant section!
Post Reply
User avatar
Alextrical
Posts: 39
Joined: Tue Aug 02, 2022 12:59 pm
Location: Cornwall, UK

Emulated EEPROM not storing values

Post by Alextrical »

Hi all

I'm currently experiencing a issue on a STM32G0B1CBT with the ability to store and retrieve values from the emulated EEPROM.

Using the example sketch found on the projects Git repo here
I'm expecting the serial output to be

Code: Select all

 0
 254
 0
 254
 0
 254
however it rapidly outputs

Code: Select all

0
0
0
0
0
0
Using a STM32F401CC, I can confirm that the same example gives the expected results, so it looks to be an issue with the STM32G0B1CBT.

What can I do to diagnose and resolve this issue?

Edit: It looks like the range of G0B1xB/xC/xE use ECC memory, could this be causing the issue?
From the datasheet:
The whole non-volatile memory embeds the error correction code (ECC) feature supporting:
•single error detection and correction
•double error detection
•readout of the ECC fail address from the ECC register
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Emulated EEPROM not storing values

Post by ag123 »

i think the library needs to be this
https://github.com/stm32duino/Arduino_C ... ies/EEPROM
and look in
utility/stm32_eeprom.c
https://github.com/stm32duino/Arduino_C ... 2_eeprom.c
there are rather important parameters like the FLASH_BANK_NUMBER
https://github.com/stm32duino/Arduino_C ... prom.c#L30
FLASH_SECTOR_TOTAL, FLASH_DATA_SECTOR
https://github.com/stm32duino/Arduino_C ... prom.c#L40
FLASH_END
https://github.com/stm32duino/Arduino_C ... prom.c#L56
FLASH_BASE_ADDRESS
https://github.com/stm32duino/Arduino_C ... prom.c#L82
which could be different across the different mcu / series

it would likely be necessary to look up the ref manual, then review the codes and re-define those definitions as relevant to the particular mcu.
just 2 cents.
User avatar
Alextrical
Posts: 39
Joined: Tue Aug 02, 2022 12:59 pm
Location: Cornwall, UK

Re: Emulated EEPROM not storing values

Post by Alextrical »

Thank you, I think that's exactly what I'm looking for :)
I'm guessing that these would need to be adjusted per Variant?

Is the solution to set the values in the Variant file, similar to this?
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Emulated EEPROM not storing values

Post by ag123 »

There is in addition the sector that is recommended to choose on where to store the data, I'd think.
perhaps the variant is a convenient place to keep some of those, but the sector selection may vary.
it seemed for some sectors, they are "huge swatches", e.g. erase almost 1/2 of the flash. If one is not careful, it could erase part of the sketch image itself.
User avatar
Alextrical
Posts: 39
Joined: Tue Aug 02, 2022 12:59 pm
Location: Cornwall, UK

Re: Emulated EEPROM not storing values

Post by Alextrical »

I have tried setting the following with no avail so far.

#define FLASH_BANK_1
#define FLASH_PAGE_NUMBER 63
#define FLASH_PAGE_SIZE 0x800
#define FLASH_END 0x0801FFFF
#define FLASH_BANK1_END 0x0801FFFF
#define FLASH_BASE_ADDRESS 0x0801F800

the memory config for 128K is the following
2022-08-24_13-14.png
2022-08-24_13-14.png (54.35 KiB) Viewed 1489 times
I believe this MCU is page based over sector based

I'm not sure what "FLASH_BASE_ADDRESS" is, and how it differs from "FLASH_BASE"
User avatar
Alextrical
Posts: 39
Joined: Tue Aug 02, 2022 12:59 pm
Location: Cornwall, UK

Re: Emulated EEPROM not storing values

Post by Alextrical »

I have it working with your advice,
"Flash_Bank_Number" should set automatically with the following logic shouldn't it?

Code: Select all

/* Be able to change FLASH_BANK_NUMBER to use if relevant */
#if !defined(FLASH_BANK_NUMBER) && defined(FLASH_BANK_1)
#if defined(FLASH_BANK_2)
#define FLASH_BANK_NUMBER   FLASH_BANK_2
#else /* FLASH_BANK_1 */
#define FLASH_BANK_NUMBER   FLASH_BANK_1
#endif /* FLASH_BANK_2 */
#ifndef FLASH_BANK_NUMBER
#error "FLASH_BANK_NUMBER could not be defined"
#endif
#endif /* !FLASH_BANK_NUMBER */
Though that never looks to define FLASH_BANK_NUMBER, regardless of FLASH_BANK_1 or FLASH_BANK_2 being set. Is this the expected behaviour?

tests where performed with the following code, based on the BufferedEEPROM example

Code: Select all

#include <EEPROM.h>
#include "stm32yyxx_ll_utils.h"

#if defined(DATA_EEPROM_BASE)
#warning "STM32 devices have an integrated EEPROM. No buffered API available."

void setup() {
}

void loop() {
}

#else
/**
   Most STM32 devices don't have an integrated EEPROM.
   To emulate a EEPROM, the STM32 Arduino core emulated
   the operation of an EEPROM with the help of the embedded
   flash.

   Writing to a flash is very expensive operation, since a
   whole flash page needs to be written, even if you only
   want to access the flash byte-wise.

   The STM32 Arduino core provides a buffered access API
   to the emulated EEPROM. The library has allocated the
   buffer even if you don't use the buffered API, so
   it's strongly suggested to use the buffered API anyhow.
*/

#define DATA_LENGTH E2END

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }
  #if defined(DATA_LENGTH)
  Serial.print("DATA_LENGTH: ");
  Serial.print(DATA_LENGTH/1024.0);
  Serial.println("k");
  #endif
  #if defined(FLASH_PAGE_NUMBER)
  Serial.print("FLASH_PAGE_NUMBER: ");
  Serial.println(FLASH_PAGE_NUMBER);
  #endif
  #if defined(FLASH_BANK_NUMBER)
  Serial.print("FLASH_BANK_NUMBER: ");
  Serial.println(FLASH_BANK_NUMBER);
  #endif
  #if defined(FLASH_BANK_1)
  Serial.print("FLASH_BANK_1: ");
  Serial.println(FLASH_BANK_1);
  #endif
  #if defined(FLASH_BANK_2)
  Serial.print("FLASH_BANK_2: ");
  Serial.println(FLASH_BANK_2);
  #endif
  #if defined(FLASH_SECTOR_TOTAL)
  Serial.print("FLASH_SECTOR_TOTAL: ");
  Serial.println(FLASH_SECTOR_TOTAL);
  #endif
  #if defined(FLASH_DATA_SECTOR)
  Serial.print("FLASH_DATA_SECTOR: ");
  Serial.println(FLASH_DATA_SECTOR);
  #endif
  #if defined(FLASH_BASE)
  Serial.print("FLASH_BASE: 0x0");
  Serial.println(FLASH_BASE, HEX);
  #endif
  #if defined(FLASH_BASE_ADDRESS)
  Serial.print("FLASH_BASE_ADDRESS: 0x0");
  Serial.println(FLASH_BASE_ADDRESS, HEX);
  #endif
  #if defined(FLASH_PAGE_SIZE)
  Serial.print("FLASH_PAGE_SIZE: ");
  Serial.print(FLASH_PAGE_SIZE/1024.0);
  Serial.println("k");
  #endif
  #if defined(FLASH_END)
  Serial.print("FLASH_END: 0x0");
  Serial.println(FLASH_END, HEX);
  #endif
  #if defined(EEPROM_RETRAM_MODE)
  Serial.print("EEPROM_RETRAM_MODE: True ");
  Serial.println(EEPROM_RETRAM_MODE);
  #endif
  #if defined(EEPROM_RETRAM_START_ADDRESS)
  Serial.print("EEPROM_RETRAM_START_ADDRESS: 0x0");
  Serial.println(EEPROM_RETRAM_START_ADDRESS, HEX);
  #endif
  #if defined(EEPROM_RETRAM_MODE_SIZE)
  Serial.print("EEPROM_RETRAM_MODE_SIZE: ");
  Serial.println(EEPROM_RETRAM_MODE_SIZE);
  #endif
  #if defined(DATA_EEPROM_END)
  Serial.print("DATA_EEPROM_END: 0x0");
  Serial.println(DATA_EEPROM_END, HEX);
  #endif
  #if defined(FLASH_BANK2_END)
  Serial.print("FLASH_BANK2_END: 0x0");
  Serial.println(FLASH_BANK2_END, HEX);
  #endif
  #if defined(FLASH_BANK1_END)
  Serial.print("FLASH_BANK1_END: 0x0");
  Serial.println(FLASH_BANK1_END, HEX);
  #endif
  #if defined(DATA_EEPROM_BASE)
  Serial.print("DATA_EEPROM_BASE: ");
  Serial.println(DATA_EEPROM_BASE);
  #endif
//  Serial.print("FLASH_PAGE_NUMBER: ");
//  Serial.println((uint32_t)(((LL_GetFlashSize() * 1024) / FLASH_PAGE_SIZE) - 1));
  Serial.print("FlashSize: ");
  Serial.print((uint32_t)(LL_GetFlashSize()));
  Serial.println("k");
}

void loop() {
  // Fill the EEPROM buffer in memory with data
  for (uint16_t i = 0; i < DATA_LENGTH; i++) {
    eeprom_buffered_write_byte(i, i % 256);
  }

  // Copy the data from the buffer to the flash
  eeprom_buffer_flush();

  // Clear the buffer for demonstration purpose
  for (uint16_t i = 0; i < DATA_LENGTH; i++) {
    eeprom_buffered_write_byte(i, 0);
  }

  // Print the 254th byte of the current buffer (should be 0)
  Serial.println(eeprom_buffered_read_byte(254));

  // Copy the data from the flash to the buffer
  eeprom_buffer_fill();

  // Print the 254th byte of the current buffer (should be 254)
  Serial.println(eeprom_buffered_read_byte(254));

  delay(100000);
}
#endif
User avatar
Alextrical
Posts: 39
Joined: Tue Aug 02, 2022 12:59 pm
Location: Cornwall, UK

Re: Emulated EEPROM not storing values

Post by Alextrical »

In short the fix was adding

Code: Select all

#define FLASH_BANK_NUMBER       FLASH_BANK_1
to the Variant*.h file
khoih-prog
Posts: 102
Joined: Thu Feb 27, 2020 7:54 am
Location: Toronto

Re: Emulated EEPROM not storing values

Post by khoih-prog »

You can try using my https://github.com/khoih-prog/FlashStorage_STM32 library, which has been tried on many STM32 boards.
Post Reply

Return to “General discussion”