arm_joint_sensor_bootloader/Drivers/OpenBLT/flash_config.c

92 lines
2.2 KiB
C
Raw Permalink Normal View History

#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(&currentCfg);
return &currentCfg;
}
Flash_UnpackConfig(rawData, &currentCfg);
if ((currentCfg.can_id > 0x7FFU) || (currentCfg.crc != Flash_CalcCrc(&currentCfg)))
{
Flash_LoadDefaultConfig(&currentCfg);
}
return &currentCfg;
}
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();
}