cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with flash saving on STM32L4P5CGUX

kiwiosek2007
Associate II

I have a problem with saving settings to flash memory on STM32L4P5CGUX.

I made a settings menu for my project, and the settings should be stored in flash so they stay after power off. The problem is that only one setting gets saved — always the first one, no matter which setting I change.

After restarting the device, the other settings are lost or not loaded correctly.

What could cause this issue?

/**
 * @file  SettingsManager.c
 * @brief Persistent settings - stable version based on eeprom_emul.c
 */

#include "SettingsManager.h"
#include "stm32l4xx_hal.h"
#include <string.h>

/* Flash record (8 bytes) */
typedef struct __attribute__((packed)) {
    uint16_t magic;
    uint8_t  tempUnit;
    uint8_t  showEnv;
    uint8_t  colorScheme;
    uint8_t  language;
    uint8_t  saveCounter;
    uint8_t  reserved;
} Settings_FlashRecord_t;

_Static_assert(sizeof(Settings_FlashRecord_t) == 8, "Settings_FlashRecord_t must be 8 bytes!");

static Settings_t settings;

static const Settings_t defaults = {
    .tempUnit    = 0,
    .showEnv     = 0,
    .colorScheme = 0,
    .language    = 0
};

static void flash_load(void)
{
    const Settings_FlashRecord_t* rec = (const Settings_FlashRecord_t*)SETTINGS_FLASH_ADDRESS;

    if (rec->magic == SETTINGS_MAGIC)
    {
        settings.tempUnit    = rec->tempUnit;
        settings.showEnv     = rec->showEnv;
        settings.colorScheme = rec->colorScheme;
        settings.language    = rec->language;
    }
    else
    {
        settings = defaults;
    }
}

void Settings_Init(void)
{
    flash_load();
}

/* ================================================ */
/*  Save - modeled exactly after eeprom_emul.c     */
/* ================================================ */
static bool flash_save(void)
{
    Settings_FlashRecord_t rec;
    memset(&rec, 0xFF, sizeof(rec));

    rec.magic       = SETTINGS_MAGIC;
    rec.tempUnit    = settings.tempUnit;
    rec.showEnv     = settings.showEnv;
    rec.colorScheme = settings.colorScheme;
    rec.language    = settings.language;
    rec.saveCounter = 0x55;        // diagnostic marker

    if (HAL_FLASH_Unlock() != HAL_OK) {
        return false;
    }

    /* Erase page */
    FLASH_EraseInitTypeDef erase_init = {
        .TypeErase = FLASH_TYPEERASE_PAGES,
        .Banks     = SETTINGS_FLASH_BANK,
        .Page      = SETTINGS_FLASH_PAGE,
        .NbPages   = 1
    };

    uint32_t page_error = 0;
    HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase_init, &page_error);

    if (status != HAL_OK || page_error != 0xFFFFFFFF) {
        HAL_FLASH_Lock();
        return false;
    }

    /* Write one doubleword */
    status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,
                               SETTINGS_FLASH_ADDRESS,
                               *(uint64_t*)&rec);

    HAL_FLASH_Lock();
    return (status == HAL_OK);
}

void Settings_Save(void)
{
    flash_save();
}

/* ==================== Getters / Setters ==================== */

uint8_t Settings_GetTempUnit(void)         { return settings.tempUnit;    }
void    Settings_SetTempUnit(uint8_t v)    { settings.tempUnit = v;    Settings_Save(); }

uint8_t Settings_GetShowEnv(void)          { return settings.showEnv;     }
void    Settings_SetShowEnv(uint8_t v)     { settings.showEnv = v;     Settings_Save(); }

uint8_t Settings_GetColorScheme(void)      { return settings.colorScheme; }
void    Settings_SetColorScheme(uint8_t v) { settings.colorScheme = v; Settings_Save(); }

uint8_t Settings_GetLanguage(void)         { return settings.language;    }
void    Settings_SetLanguage(uint8_t v)    { settings.language = v;    Settings_Save(); }

kiwiosek2007_0-1780051357982.png

 

0 REPLIES 0