第一次提交
This commit is contained in:
172
app_cail/port/bsp_fmc_flash.c
Normal file
172
app_cail/port/bsp_fmc_flash.c
Normal file
@@ -0,0 +1,172 @@
|
||||
#include "bsp_fmc_flash.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 这个文件默认是根据GD32F303 实现的flash 操作接口函数,所以移植的时候,需要根据项目自行实现芯片平台相关的fmc 外设操作函数,只需要替换实现以下函数的函数体:
|
||||
bsp_flash_read
|
||||
bsp_flash_write
|
||||
bsp_flash_is_erased
|
||||
bsp_flash_erased
|
||||
其他不需要动
|
||||
*/
|
||||
|
||||
#include "at32a423.h" // Device header
|
||||
|
||||
|
||||
#define BSP_FLASH_BANK_FLAGS ((fmc_flag_enum)(FMC_FLAG_PGAERR | FMC_FLAG_WPERR | \
|
||||
FMC_FLAG_END | FMC_FLAG_PGERR ))
|
||||
#define BSP_FLASH_SN_SIZE 16U
|
||||
|
||||
static const bsp_flash_info_t s_bsp_flash_info =
|
||||
{
|
||||
BSP_FLASH_PAGE_SIZE,
|
||||
BSP_FLASH_PROGRAM_UNIT,
|
||||
BSP_FLASH_ERASE_VALUE,
|
||||
};
|
||||
|
||||
static uint32_t bsp_flash_align_down(uint32_t value, uint32_t align)
|
||||
{
|
||||
return value & ~(align - 1U);
|
||||
}
|
||||
|
||||
static uint32_t bsp_flash_align_up(uint32_t value, uint32_t align)
|
||||
{
|
||||
return (value + align - 1U) & ~(align - 1U);
|
||||
}
|
||||
|
||||
static void bsp_flash_clear_flags(void)
|
||||
{
|
||||
fmc_flag_clear(BSP_FLASH_BANK_FLAGS);
|
||||
}
|
||||
|
||||
static uint8_t bsp_flash_pack_word(const uint8_t *src, uint32_t size, uint32_t *word_out)
|
||||
{
|
||||
uint8_t bytes[BSP_FLASH_PROGRAM_UNIT] = { BSP_FLASH_ERASE_VALUE, BSP_FLASH_ERASE_VALUE,
|
||||
BSP_FLASH_ERASE_VALUE, BSP_FLASH_ERASE_VALUE };
|
||||
|
||||
if ((word_out == 0) || ((src == 0) && (size > 0U))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > BSP_FLASH_PROGRAM_UNIT) {
|
||||
size = BSP_FLASH_PROGRAM_UNIT;
|
||||
}
|
||||
|
||||
if (size > 0U) {
|
||||
memcpy(bytes, src, size);
|
||||
}
|
||||
|
||||
*word_out = ((uint32_t)bytes[0]) |
|
||||
((uint32_t)bytes[1] << 8) |
|
||||
((uint32_t)bytes[2] << 16) |
|
||||
((uint32_t)bytes[3] << 24);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const bsp_flash_info_t *bsp_flash_get_info(void)
|
||||
{
|
||||
return &s_bsp_flash_info;
|
||||
}
|
||||
|
||||
uint8_t bsp_flash_read(uint32_t addr, void *buffer, uint32_t size)
|
||||
{
|
||||
if ((buffer == 0) && (size > 0U)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size > 0U) {
|
||||
memcpy(buffer, (const void *)addr, size);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t bsp_flash_is_erased(uint32_t addr, uint32_t size)
|
||||
{
|
||||
const uint8_t *flash_ptr = (const uint8_t *)addr;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0U; i < size; i++) {
|
||||
if (flash_ptr[i] != BSP_FLASH_ERASE_VALUE) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t bsp_flash_erased(uint32_t addr, uint32_t size)
|
||||
{
|
||||
uint32_t erase_addr;
|
||||
uint32_t erase_end;
|
||||
|
||||
if (size == 0U) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
erase_addr = bsp_flash_align_down(addr, BSP_FLASH_PAGE_SIZE);
|
||||
erase_end = bsp_flash_align_up(addr + size, BSP_FLASH_PAGE_SIZE);
|
||||
|
||||
fmc_unlock();
|
||||
bsp_flash_clear_flags();
|
||||
|
||||
while (erase_addr < erase_end) {
|
||||
if (fmc_page_erase(erase_addr) != FMC_READY) {
|
||||
fmc_lock();
|
||||
return 0;
|
||||
}
|
||||
erase_addr += BSP_FLASH_PAGE_SIZE;
|
||||
bsp_flash_clear_flags();
|
||||
}
|
||||
|
||||
fmc_lock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t bsp_flash_write(uint32_t addr, const void *data, uint32_t size)
|
||||
{
|
||||
const uint8_t *src = (const uint8_t *)data;
|
||||
uint32_t offset = 0U;
|
||||
uint32_t word = 0U;
|
||||
uint32_t chunk_size;
|
||||
|
||||
if ((addr % BSP_FLASH_PROGRAM_UNIT) != 0U) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((data == 0) && (size > 0U)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size == 0U) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
fmc_unlock();
|
||||
bsp_flash_clear_flags();
|
||||
|
||||
while (offset < size)
|
||||
{
|
||||
chunk_size = size - offset;
|
||||
if (chunk_size > BSP_FLASH_PROGRAM_UNIT) {
|
||||
chunk_size = BSP_FLASH_PROGRAM_UNIT;
|
||||
}
|
||||
|
||||
if (!bsp_flash_pack_word(src + offset, chunk_size, &word)) {
|
||||
fmc_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fmc_word_program(addr + offset, word) != FMC_READY) {
|
||||
fmc_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset += BSP_FLASH_PROGRAM_UNIT;
|
||||
bsp_flash_clear_flags();
|
||||
}
|
||||
|
||||
fmc_lock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
28
app_cail/port/bsp_fmc_flash.h
Normal file
28
app_cail/port/bsp_fmc_flash.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef BSP_FMC_FLASH_H
|
||||
#define BSP_FMC_FLASH_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define BSP_FLASH_PAGE_SIZE ((uint32_t)0x400U) // 1KB per page
|
||||
#define BSP_FLASH_PROGRAM_UNIT ((uint32_t)4U) // 4 bytes per program unit (word)
|
||||
#define BSP_FLASH_ERASE_VALUE ((uint8_t)0xFFU) // Value of erased flash bytes
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t page_size;
|
||||
uint32_t program_unit;
|
||||
uint8_t erased_value;
|
||||
} bsp_flash_info_t;
|
||||
|
||||
const bsp_flash_info_t *bsp_flash_get_info(void);
|
||||
uint8_t bsp_flash_read(uint32_t addr, void *buffer, uint32_t size);
|
||||
uint8_t bsp_flash_erased(uint32_t addr, uint32_t size);
|
||||
uint8_t bsp_flash_write(uint32_t addr, const void *data, uint32_t size);
|
||||
uint8_t bsp_flash_is_erased(uint32_t addr, uint32_t size);
|
||||
|
||||
|
||||
|
||||
#endif /* BSP_FMC_FLASH_H */
|
||||
393
app_cail/port/flash_port.c
Normal file
393
app_cail/port/flash_port.c
Normal file
@@ -0,0 +1,393 @@
|
||||
#include "flash_port.h"
|
||||
#include <string.h>
|
||||
#include "mx_log.h"
|
||||
|
||||
#undef MX_LOGD
|
||||
#undef MX_LOGI
|
||||
#undef MX_LOGW
|
||||
#undef MX_LOGE
|
||||
#define MX_LOGD FLASH_PORT_LOGD
|
||||
#define MX_LOGI FLASH_PORT_LOGI
|
||||
#define MX_LOGW FLASH_PORT_LOGW
|
||||
#define MX_LOGE FLASH_PORT_LOGE
|
||||
|
||||
#define FLASH_PORT_TAG FLASH_PORT_LOG_TAG
|
||||
|
||||
#define FLASH_PORT_ERASE_PROBE_BYTES 8U
|
||||
#define FLASH_PORT_VERIFY_CHUNK_BYTES 64U
|
||||
|
||||
static flash_port_ops_t s_flash_ops = {0};
|
||||
|
||||
void flash_port_init(const flash_port_ops_t *ops)
|
||||
{
|
||||
if (ops != NULL) {
|
||||
s_flash_ops = *ops;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t hal_read(uint32_t addr, void *buf, uint32_t len)
|
||||
{
|
||||
if (s_flash_ops.read) {
|
||||
return s_flash_ops.read(addr, buf, len/2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t hal_write(uint32_t addr, const void *buf, uint32_t len)
|
||||
{
|
||||
if (s_flash_ops.write) {
|
||||
return s_flash_ops.write(addr, buf, len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t hal_erase(uint32_t addr, uint32_t len)
|
||||
{
|
||||
if (s_flash_ops.erase) {
|
||||
return s_flash_ops.erase(addr, len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t hal_is_erased(uint32_t addr, uint32_t len)
|
||||
{
|
||||
if (s_flash_ops.is_erased) {
|
||||
return s_flash_ops.is_erased(addr, len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t flash_port_min_u32(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
static uint8_t flash_port_addr_is_erased(uint32_t addr, uint32_t bytes)
|
||||
{
|
||||
uint32_t probe_bytes = flash_port_min_u32(bytes, FLASH_PORT_ERASE_PROBE_BYTES);
|
||||
|
||||
if (probe_bytes == 0U)
|
||||
{
|
||||
probe_bytes = FLASH_PORT_ERASE_PROBE_BYTES;
|
||||
}
|
||||
|
||||
return hal_is_erased(addr, probe_bytes);
|
||||
}
|
||||
|
||||
static uint8_t flash_port_erase_range(uint32_t start_addr, uint32_t bytes)
|
||||
{
|
||||
if (!hal_erase(start_addr, bytes))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flash_port_addr_is_erased(start_addr, bytes);
|
||||
}
|
||||
|
||||
static uint8_t flash_port_verify_bytes(uint32_t addr, const void *expect, uint32_t bytes)
|
||||
{
|
||||
uint8_t verify_buf[FLASH_PORT_VERIFY_CHUNK_BYTES];
|
||||
const uint8_t *expect_bytes = (const uint8_t *)expect;
|
||||
uint32_t offset = 0U;
|
||||
|
||||
if ((expect == NULL) && (bytes > 0U))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (offset < bytes)
|
||||
{
|
||||
uint32_t chunk = flash_port_min_u32(bytes - offset, FLASH_PORT_VERIFY_CHUNK_BYTES);
|
||||
|
||||
if (!hal_read(addr + offset, verify_buf, chunk)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "verify read failed addr=0x%08X offset=%u",
|
||||
(unsigned int)addr, (unsigned int)offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(verify_buf, expect_bytes + offset, chunk) != 0) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "verify failed addr=0x%08X offset=%u",
|
||||
(unsigned int)addr, (unsigned int)offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset += chunk;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t flash_port_load_cali_raw(app_math_cali_t *params)
|
||||
{
|
||||
if (params == NULL) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "load cali raw null params");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sizeof(app_math_cali_t) > FLASH_PORT_CALI_REGION_SIZE) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "cali region too small: need=%u size=%u",
|
||||
(unsigned int)sizeof(app_math_cali_t), (unsigned int)FLASH_PORT_CALI_REGION_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hal_read(FLASH_PORT_CALI_REGION_ADDR, params, sizeof(app_math_cali_t));
|
||||
}
|
||||
|
||||
static uint8_t flash_port_store_cali_raw(const app_math_cali_t *params)
|
||||
{
|
||||
if (params == NULL)
|
||||
{
|
||||
MX_LOGE(FLASH_PORT_TAG, "store cali raw null params");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sizeof(app_math_cali_t) > FLASH_PORT_CALI_REGION_SIZE) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "cali region too small: need=%u size=%u",
|
||||
(unsigned int)sizeof(app_math_cali_t), (unsigned int)FLASH_PORT_CALI_REGION_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!flash_port_erase_range(FLASH_PORT_CALI_REGION_ADDR, FLASH_PORT_CALI_REGION_SIZE)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "erase cali region failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hal_write(FLASH_PORT_CALI_REGION_ADDR, params, sizeof(app_math_cali_t))) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "write cali raw failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flash_port_verify_bytes(FLASH_PORT_CALI_REGION_ADDR, params, sizeof(app_math_cali_t));
|
||||
}
|
||||
|
||||
uint8_t flash_port_math_load(app_math_cali_t *params)
|
||||
{
|
||||
if (!flash_port_load_cali_raw(params))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params->min_trigger_res_value == 0xFFFFU) &&
|
||||
(params->max_trigger_res_value == 0xFFFFU) &&
|
||||
(params->div_trigger_res_value == 0xFFFFU) &&
|
||||
(params->max_display_value == 0xFFFFU)) {
|
||||
MX_LOGW(FLASH_PORT_TAG, "math area is empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t flash_port_math_save(const app_math_cali_t *params)
|
||||
{
|
||||
app_math_cali_t merged = {0};
|
||||
|
||||
if (params == NULL)
|
||||
{
|
||||
MX_LOGE(FLASH_PORT_TAG, "math save null params");
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)flash_port_load_cali_raw(&merged);
|
||||
merged.check_cail = params->check_cail;
|
||||
merged.min_trigger_res_value = params->min_trigger_res_value;
|
||||
merged.max_trigger_res_value = params->max_trigger_res_value;
|
||||
merged.div_trigger_res_value = params->div_trigger_res_value;
|
||||
merged.max_display_value = params->max_display_value;
|
||||
merged.sensor_data_type = params->sensor_data_type;
|
||||
return flash_port_store_cali_raw(&merged);
|
||||
}
|
||||
|
||||
uint8_t flash_port_math_clear(void)
|
||||
{
|
||||
if (!flash_port_erase_range(FLASH_PORT_CALI_REGION_ADDR, FLASH_PORT_CALI_REGION_SIZE)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "math clear erase failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t flash_port_pressure_load(app_math_cali_t *params)
|
||||
{
|
||||
if (!flash_port_load_cali_raw(params)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params->num_points == 0xFFFFU) || (params->num_points > MAX_PRESSURE_POINTS)) {
|
||||
MX_LOGW(FLASH_PORT_TAG, "invalid pressure points=%u", (unsigned int)params->num_points);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t flash_port_pressure_save(const app_math_cali_t *params)
|
||||
{
|
||||
app_math_cali_t merged = {0};
|
||||
|
||||
if ((params == NULL) || (params->num_points > MAX_PRESSURE_POINTS)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "pressure save invalid params, num_points=%u",
|
||||
(unsigned int)(params ? params->num_points : 0U));
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)flash_port_load_cali_raw(&merged);
|
||||
merged.num_points = params->num_points;
|
||||
memcpy(merged.pressure_points, params->pressure_points, sizeof(merged.pressure_points));
|
||||
|
||||
return flash_port_store_cali_raw(&merged);
|
||||
}
|
||||
|
||||
uint8_t flash_port_pressure_clear(void)
|
||||
{
|
||||
app_math_cali_t merged = {0};
|
||||
|
||||
(void)flash_port_load_cali_raw(&merged);
|
||||
merged.num_points = 0U;
|
||||
memset(merged.pressure_points, 0, sizeof(merged.pressure_points));
|
||||
|
||||
return flash_port_store_cali_raw(&merged);
|
||||
}
|
||||
|
||||
uint8_t flash_port_map_load(uint16_t *map_matrix, uint32_t map_words)
|
||||
{
|
||||
uint32_t map_bytes = map_words * sizeof(uint16_t);
|
||||
|
||||
if ((map_matrix == NULL) || (map_words != FLASH_PORT_MAP_WORDS)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map load bad arg, words=%u", (unsigned int)map_words);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (map_bytes > FLASH_PORT_MAP_REGION_SIZE) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map region too small: need=%u size=%u",
|
||||
(unsigned int)map_bytes, (unsigned int)FLASH_PORT_MAP_REGION_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flash_port_addr_is_erased(FLASH_PORT_MAP_REGION_ADDR, map_bytes)) {
|
||||
MX_LOGW(FLASH_PORT_TAG, "map area is empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hal_read(FLASH_PORT_MAP_REGION_ADDR, map_matrix, map_bytes);
|
||||
}
|
||||
|
||||
uint8_t flash_port_map_save(const uint16_t *map_matrix, uint32_t map_words)
|
||||
{
|
||||
uint32_t map_bytes = map_words * sizeof(uint16_t);
|
||||
|
||||
if ((map_matrix == NULL) || (map_words != FLASH_PORT_MAP_WORDS)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map save bad arg, words=%u", (unsigned int)map_words);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (map_bytes > FLASH_PORT_MAP_REGION_SIZE) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map region too small: need=%u size=%u",
|
||||
(unsigned int)map_bytes, (unsigned int)FLASH_PORT_MAP_REGION_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!flash_port_erase_range(FLASH_PORT_MAP_REGION_ADDR, FLASH_PORT_MAP_REGION_SIZE)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map erase failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hal_write(FLASH_PORT_MAP_REGION_ADDR, map_matrix, map_bytes)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map write failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flash_port_verify_bytes(FLASH_PORT_MAP_REGION_ADDR, map_matrix, map_bytes);
|
||||
}
|
||||
|
||||
uint8_t flash_port_map_clear(void)
|
||||
{
|
||||
if (!flash_port_erase_range(FLASH_PORT_MAP_REGION_ADDR, FLASH_PORT_MAP_REGION_SIZE)) {
|
||||
MX_LOGE(FLASH_PORT_TAG, "map clear erase failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t flash_port_creep_load(app_creep_params *params)
|
||||
{
|
||||
uint32_t raw_data[2];
|
||||
|
||||
if (params == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hal_read(FLASH_PORT_CREEP_REGION_ADDR, raw_data, sizeof(raw_data))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((raw_data[0] == 0xFFFFFFFFUL) && (raw_data[1] == 0xFFFFFFFFUL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
params->creep_strength = (uint8_t)raw_data[0];
|
||||
params->creep_level = (uint8_t)raw_data[1];
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t flash_port_creep_save(const app_creep_params *params)
|
||||
{
|
||||
uint32_t raw_data[2];
|
||||
|
||||
if (params == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
raw_data[0] = (uint32_t)params->creep_strength;
|
||||
raw_data[1] = (uint32_t)params->creep_level;
|
||||
|
||||
if (!flash_port_erase_range(FLASH_PORT_CREEP_REGION_ADDR, FLASH_PORT_CREEP_REGION_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hal_write(FLASH_PORT_CREEP_REGION_ADDR, raw_data, sizeof(raw_data))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flash_port_verify_bytes(FLASH_PORT_CREEP_REGION_ADDR, raw_data, sizeof(raw_data));
|
||||
}
|
||||
|
||||
uint8_t flash_port_creep_clear(void)
|
||||
{
|
||||
if (!flash_port_erase_range(FLASH_PORT_CREEP_REGION_ADDR, FLASH_PORT_CREEP_REGION_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t flash_port_device_info_load(app_dev_info *info)
|
||||
{
|
||||
if (info == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flash_port_addr_is_erased(FLASH_PORT_DEVICE_INFO_REGION_ADDR, sizeof(*info))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hal_read(FLASH_PORT_DEVICE_INFO_REGION_ADDR, info, sizeof(*info));
|
||||
}
|
||||
|
||||
uint8_t flash_port_device_info_save(const app_dev_info *info)
|
||||
{
|
||||
if (info == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!flash_port_erase_range(FLASH_PORT_DEVICE_INFO_REGION_ADDR, FLASH_PORT_DEVICE_INFO_REGION_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hal_write(FLASH_PORT_DEVICE_INFO_REGION_ADDR, info, sizeof(*info))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flash_port_verify_bytes(FLASH_PORT_DEVICE_INFO_REGION_ADDR, info, sizeof(*info));
|
||||
}
|
||||
82
app_cail/port/flash_port.h
Normal file
82
app_cail/port/flash_port.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef __FLASH_PORT_H
|
||||
#define __FLASH_PORT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "app_calibration.h"
|
||||
|
||||
#ifndef FLASH_PORT_LOG_TAG
|
||||
#define FLASH_PORT_LOG_TAG "FLASH_PORT"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flash Region Configuration
|
||||
* Adjust Sector Size and Base Addresses for your specific MCU.
|
||||
*/
|
||||
#ifndef PORT_SECTOR_SIZE
|
||||
#define PORT_SECTOR_SIZE (2048U) // Target MCU Sector Size
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_PORT_CREEP_REGION
|
||||
#define FLASH_PORT_CREEP_REGION_ADDR (0x08000000 + 1024 * 58)
|
||||
#define FLASH_PORT_CREEP_REGION_SIZE PORT_SECTOR_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_PORT_DEVICE_INFO_REGION
|
||||
#define FLASH_PORT_DEVICE_INFO_REGION_ADDR (0x08000000 + 1024 * 60)
|
||||
#define FLASH_PORT_DEVICE_INFO_REGION_SIZE PORT_SECTOR_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_PORT_CALI_REGION
|
||||
#define FLASH_PORT_CALI_REGION_ADDR (0x08000000 + 1024 * 62) // FMC_WRITE_MAP_ADDR in old code
|
||||
#define FLASH_PORT_CALI_REGION_SIZE PORT_SECTOR_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_PORT_MAP_REGION
|
||||
#define FLASH_PORT_MAP_REGION_ADDR (FLASH_PORT_CALI_REGION_ADDR + PORT_SECTOR_SIZE)
|
||||
#define FLASH_PORT_MAP_REGION_SIZE APP_MAP_MATRIX_BYTES
|
||||
#define FLASH_PORT_MAP_WORDS APP_MAP_MATRIX_WORDS
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
* HAL Interface (Function pointer injection)
|
||||
* ============================================================================ */
|
||||
typedef struct flash_port_ops_t
|
||||
{
|
||||
uint8_t (*read)(uint32_t addr, void *buf, uint32_t len);
|
||||
uint8_t (*write)(uint32_t addr, const void *buf, uint32_t len);
|
||||
uint8_t (*erase)(uint32_t addr, uint32_t len);
|
||||
uint8_t (*is_erased)(uint32_t addr, uint32_t len);
|
||||
} flash_port_ops_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the flash port layer with hardware specific operations.
|
||||
* @param ops Pointer to hardware operations structure.
|
||||
*/
|
||||
void flash_port_init(const flash_port_ops_t *ops);
|
||||
|
||||
/* ============================================================================
|
||||
* Application APIs
|
||||
* ============================================================================ */
|
||||
uint8_t flash_port_math_load(app_math_cali_t *params);
|
||||
uint8_t flash_port_math_save(const app_math_cali_t *params);
|
||||
uint8_t flash_port_math_clear(void);
|
||||
|
||||
uint8_t flash_port_pressure_load(app_math_cali_t *params);
|
||||
uint8_t flash_port_pressure_save(const app_math_cali_t *params);
|
||||
uint8_t flash_port_pressure_clear(void);
|
||||
|
||||
uint8_t flash_port_map_load(uint16_t *map_matrix, uint32_t map_words);
|
||||
uint8_t flash_port_map_save(const uint16_t *map_matrix, uint32_t map_words);
|
||||
uint8_t flash_port_map_clear(void);
|
||||
|
||||
uint8_t flash_port_creep_load(app_creep_params *params);
|
||||
uint8_t flash_port_creep_save(const app_creep_params *params);
|
||||
uint8_t flash_port_creep_clear(void);
|
||||
|
||||
uint8_t flash_port_device_info_load(app_dev_info *info);
|
||||
uint8_t flash_port_device_info_save(const app_dev_info *info);
|
||||
|
||||
#endif /* __FLASH_PORT_H */
|
||||
Reference in New Issue
Block a user