Files
Frame-rate-optimization/app_cail/port/bsp_fmc_flash.c
2026-04-09 10:14:20 +08:00

173 lines
3.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}