92 lines
2.2 KiB
C
92 lines
2.2 KiB
C
|
|
#include "flash_config.h"
|
||
|
|
#include <stdint.h>
|
||
|
|
#include "stm32l4xx.h"
|
||
|
|
|
||
|
|
#define FLASH_BASE_ADDR 0x08000000UL
|
||
|
|
// #define FLASH_PAGE_SIZE 0x800 // 2KB
|
||
|
|
#define FLASH_PAGE_NUM 128
|
||
|
|
#define FLASH_USER_PAGE (FLASH_PAGE_NUM - 1)
|
||
|
|
#define FLASH_USER_ADDR (FLASH_BASE_ADDR + FLASH_USER_PAGE * FLASH_PAGE_SIZE)
|
||
|
|
#define FLASH_EMPTY_DWORD 0xFFFFFFFFFFFFFFFFULL
|
||
|
|
|
||
|
|
static uint16_t Flash_CalcCrc(const FlashConfig_t *cfg)
|
||
|
|
{
|
||
|
|
uint16_t crc = 0xA55A;
|
||
|
|
crc ^= cfg->can_id;
|
||
|
|
crc ^= ((uint16_t)cfg->sensorDir << 8) | cfg->debugFlag;
|
||
|
|
return crc;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void Flash_LoadDefaultConfig(FlashConfig_t *cfg)
|
||
|
|
{
|
||
|
|
cfg->can_id = 0x01;
|
||
|
|
cfg->sensorDir = 0;
|
||
|
|
cfg->debugFlag = 0;
|
||
|
|
cfg->crc = Flash_CalcCrc(cfg);
|
||
|
|
}
|
||
|
|
|
||
|
|
static uint64_t Flash_PackConfig(const FlashConfig_t *cfg)
|
||
|
|
{
|
||
|
|
uint64_t data = 0;
|
||
|
|
|
||
|
|
data |= (uint64_t)(cfg->can_id & 0xFFFFU);
|
||
|
|
data |= ((uint64_t)cfg->sensorDir << 16);
|
||
|
|
data |= ((uint64_t)cfg->debugFlag << 24);
|
||
|
|
data |= ((uint64_t)cfg->crc << 32);
|
||
|
|
|
||
|
|
return data;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void Flash_UnpackConfig(uint64_t data, FlashConfig_t *cfg)
|
||
|
|
{
|
||
|
|
cfg->can_id = (uint16_t)(data & 0xFFFFU);
|
||
|
|
cfg->sensorDir = (uint8_t)((data >> 16) & 0xFFU);
|
||
|
|
cfg->debugFlag = (uint8_t)((data >> 24) & 0xFFU);
|
||
|
|
cfg->crc = (uint16_t)((data >> 32) & 0xFFFFU);
|
||
|
|
}
|
||
|
|
|
||
|
|
FlashConfig_t currentCfg;
|
||
|
|
FlashConfig_t *Flash_ReadConfig(void)
|
||
|
|
{
|
||
|
|
uint64_t rawData = *(volatile uint64_t *)FLASH_USER_ADDR;
|
||
|
|
|
||
|
|
if (rawData == FLASH_EMPTY_DWORD)
|
||
|
|
{
|
||
|
|
Flash_LoadDefaultConfig(¤tCfg);
|
||
|
|
return ¤tCfg;
|
||
|
|
}
|
||
|
|
|
||
|
|
Flash_UnpackConfig(rawData, ¤tCfg);
|
||
|
|
|
||
|
|
if ((currentCfg.can_id > 0x7FFU) || (currentCfg.crc != Flash_CalcCrc(¤tCfg)))
|
||
|
|
{
|
||
|
|
Flash_LoadDefaultConfig(¤tCfg);
|
||
|
|
}
|
||
|
|
|
||
|
|
return ¤tCfg;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Flash_WriteConfig(FlashConfig_t *cfg)
|
||
|
|
{
|
||
|
|
uint64_t data;
|
||
|
|
|
||
|
|
cfg->crc = Flash_CalcCrc(cfg);
|
||
|
|
data = Flash_PackConfig(cfg);
|
||
|
|
|
||
|
|
HAL_FLASH_Unlock();
|
||
|
|
|
||
|
|
FLASH_EraseInitTypeDef erase;
|
||
|
|
uint32_t page_error;
|
||
|
|
|
||
|
|
erase.TypeErase = FLASH_TYPEERASE_PAGES;
|
||
|
|
erase.Page = FLASH_USER_PAGE;
|
||
|
|
erase.NbPages = 1;
|
||
|
|
|
||
|
|
HAL_FLASHEx_Erase(&erase, &page_error);
|
||
|
|
|
||
|
|
uint32_t addr = FLASH_USER_ADDR;
|
||
|
|
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, data);
|
||
|
|
|
||
|
|
HAL_FLASH_Lock();
|
||
|
|
}
|