Files
Frame-rate-optimization/Bsp/bsp_flash.c
2026-04-09 10:14:20 +08:00

250 lines
7.0 KiB
C
Raw 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.
/**
**************************************************************************
* @file flash.c
* @brief flash program
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "bsp_flash.h"
#include "string.h"
/** @addtogroup AT32A423_periph_examples
* @{
*/
#if defined (AT32A423xC)
#define SECTOR_SIZE 2048 /* this parameter depends on the specific model of the chip */
#else
#define SECTOR_SIZE 1024 /* this parameter depends on the specific model of the chip */
#endif
#define FLASH_HEAD 0XA55AA55A
#define FLASH_TAIL 0X5AA55AA5
uint16_t flash_buf[SECTOR_SIZE / 2];
/**
* @brief read data using halfword mode
* @param read_addr: the address of reading
* @param p_buffer: the buffer of reading data
* @param num_read: the number of reading data
* @retval 0 = success, 1 = fail
*/
uint8_t flash_read(uint32_t read_addr, void *p_buffer, uint32_t num_read)
{
uint16_t *buf = (uint16_t *)p_buffer;
uint32_t i;
for(i = 0; i < num_read; i++)
{
buf[i] = *(uint16_t*)(read_addr);
read_addr += 2;
}
return 0;
}
/**
* @brief write data using halfword mode without checking
* @param write_addr: the address of writing
* @param p_buffer: the buffer of writing data
* @param num_write: the number of writing data
* @retval 0 = success, 1 = fail
*/
uint8_t flash_write_nocheck(uint32_t write_addr, const void *p_buffer, uint32_t num_write)
{
uint16_t *buf = (uint16_t *)p_buffer;
uint32_t i;
flash_status_type status = FLASH_OPERATE_DONE;
for(i = 0; i < num_write; i++)
{
status = flash_halfword_program(write_addr, buf[i]);
if(status != FLASH_OPERATE_DONE)
return 1;
write_addr += 2;
}
return 0;
}
/**
* @brief write data using halfword mode with checking
* @param write_addr: the address of writing
* @param p_buffer: the buffer of writing data
* @param num_write: the number of writing data
* @retval 0 = success, 1 = fail
*/
uint8_t flash_write(uint32_t write_addr, const void *p_buffer, uint32_t num_write)
{
uint16_t *buf = (uint16_t *)p_buffer;
uint32_t offset_addr;
uint32_t sector_position;
uint32_t sector_offset;
uint32_t sector_remain;
uint32_t i;
flash_status_type status = FLASH_OPERATE_DONE;
flash_unlock();
offset_addr = write_addr - FLASH_BASE;
sector_position = offset_addr / SECTOR_SIZE;
sector_offset = (offset_addr % SECTOR_SIZE) / 2;
sector_remain = (SECTOR_SIZE / 2) - sector_offset;
if(num_write <= sector_remain)
sector_remain = num_write;
while(1)
{
flash_read(sector_position * SECTOR_SIZE + FLASH_BASE, flash_buf, SECTOR_SIZE / 2);
for(i = 0; i < sector_remain; i++)
{
if(flash_buf[sector_offset + i] != 0xFFFF)
break;
}
if(i < sector_remain)
{
status = flash_operation_wait_for(ERASE_TIMEOUT);
if((status == FLASH_PROGRAM_ERROR) || (status == FLASH_EPP_ERROR))
flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
else if(status == FLASH_OPERATE_TIMEOUT)
{
flash_lock();
return 1;
}
status = flash_sector_erase(sector_position * SECTOR_SIZE + FLASH_BASE);
if(status != FLASH_OPERATE_DONE)
{
flash_lock();
return 1;
}
for(i = 0; i < sector_remain; i++)
{
flash_buf[i + sector_offset] = buf[i];
}
if(flash_write_nocheck(sector_position * SECTOR_SIZE + FLASH_BASE, flash_buf, SECTOR_SIZE / 2) != 0)
{
flash_lock();
return 1;
}
}
else
{
if(flash_write_nocheck(write_addr, buf, sector_remain) != 0)
{
flash_lock();
return 1;
}
}
if(num_write == sector_remain)
break;
else
{
sector_position++;
sector_offset = 0;
buf += sector_remain;
write_addr += (sector_remain * 2);
num_write -= sector_remain;
if(num_write > (SECTOR_SIZE / 2))
sector_remain = SECTOR_SIZE / 2;
else
sector_remain = num_write;
}
}
flash_lock();
return 0;
}
int load_config_params(flash_para_struct *params)
{
uint32_t *head = (uint32_t*)FMC_WRITE_START_ADDR;
uint32_t *tail = (uint32_t*)(FMC_WRITE_START_ADDR + sizeof(flash_para_struct) - 4);
if(*head == FLASH_HEAD && *tail == FLASH_TAIL)
{
memcpy((uint32_t *)params, head, sizeof(flash_para_struct));
return 1;
}
else
{
return -1;
}
}
int save_config_params(flash_para_struct *params)
{
params->flash_head = FLASH_HEAD;
params->flash_tail = FLASH_TAIL;
flash_write(FMC_WRITE_START_ADDR, params, sizeof(flash_para_struct)/sizeof(uint16_t));
return 0;
}
/**
* @brief <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param sector_addr <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
* @param len <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD>δʹ<CEB4>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ֽӿڼ<D3BF><DABC>ݣ<EFBFBD>
* @return 0 = success, 1 = fail
*/
uint8_t flash_erase(uint32_t sector_addr, uint32_t len)
{
flash_status_type status;
flash_unlock();
status = flash_operation_wait_for(ERASE_TIMEOUT);
if(status == FLASH_OPERATE_TIMEOUT)
{
flash_lock();
return 1;
}
if((status == FLASH_PROGRAM_ERROR) || (status == FLASH_EPP_ERROR))
{
flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
}
status = flash_sector_erase(sector_addr);
flash_lock();
return (status == FLASH_OPERATE_DONE) ? 0 : 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] != 0xFF)
{
return 0;
}
}
return 1;
}