以下代码在lpc5528上验证正常,结尾有验证函数
/** @file bsp_flash.c
* @brief nxp lpc552x's flash driver.
* @data 2023/12/19
* @author zxk.
*/
/* INCLUDES *******************************************************************/
#include "bsp_flash.h"
#include <string.h>
#include "bsp_clock.h"
#include "bsp_it.h"
#include "fsl_iap.h"
#include "fsl_iap_ffr.h"
/* CONSTANTS ******************************************************************/
#define FLASH_PAGE_SIZE_BYTES 512
#define USER_FLASH_START_ADDR 0x70000
/* PRIVATE GLOBALS ************************************************************/
static flash_config_t hflash;
/* PUBLIC FUNCTIONS ***********************************************************/
int bsp_flash_init(void)
{
return FLASH_Init(&hflash);
}
void bsp_flash_get_uuid(uint8_t *uuid)
{
FFR_Init(&hflash);
FFR_GetUUID(&hflash, uuid);
}
bool hw_drv_flash_read(uint32_t addr, uint8_t * p_rd, uint16_t length)
{
volatile uint8_t *p_src = (volatile uint8_t *)addr;
uint32_t page_offset = addr&0x1ff;
uint32_t page_start_addr = addr - page_offset;
uint16_t page_rd_length = FLASH_PAGE_SIZE_BYTES - page_offset;
if((p_rd == NULL) || (length == 0) || (addr < USER_FLASH_START_ADDR)){
return false;
}
do{
page_rd_length = (page_rd_length > length) ? length : page_rd_length;
length -= page_rd_length;
if(kStatus_Success == FLASH_VerifyErase(&hflash, page_start_addr, hflash.PFlashPageSize)){
memset(p_rd, 0xff, page_rd_length);
p_rd += page_rd_length;
p_src += page_rd_length;
}else{
do{
*p_rd++ = *p_src++;
}while(--page_rd_length);
}
page_start_addr += FLASH_PAGE_SIZE_BYTES;
page_rd_length = FLASH_PAGE_SIZE_BYTES;
}while(length);
return true;
}
bool hw_drv_flash_write(uint32_t addr, uint8_t * p_wr, uint16_t length)
{
uint32_t page_start_addr = addr - (addr & 0x1ff);
uint16_t page_wr_offset = addr & 0x1ff;
uint16_t page_wr_length = FLASH_PAGE_SIZE_BYTES - page_wr_offset; // count page remain size
uint8_t page_temp[FLASH_PAGE_SIZE_BYTES] = {0};
if((p_wr == NULL) || (length == 0) || (addr < USER_FLASH_START_ADDR)){
return false;
}
do{
// The size of the remaining space on this page is larger than the space to be written.
page_wr_length = (page_wr_length > length)?length:page_wr_length;
// Copy to temp page's buff.
hw_drv_flash_read(page_start_addr, page_temp, FLASH_PAGE_SIZE_BYTES);
// Copy the data to be written to the page cache.
memcpy(&page_temp[page_wr_offset], p_wr, page_wr_length);
// Updata flash.
FLASH_Erase(&hflash, page_start_addr, hflash.PFlashPageSize, kFLASH_ApiEraseKey);
FLASH_Program(&hflash, page_start_addr, (uint8_t *)page_temp, FLASH_PAGE_SIZE_BYTES);
p_wr += page_wr_length;
page_start_addr += FLASH_PAGE_SIZE_BYTES;
if(length >= page_wr_length){
length -= page_wr_length;
}else{
length = 0;
}
page_wr_offset = 0;
page_wr_length = FLASH_PAGE_SIZE_BYTES; // count page remain size
}while(length);
return true;
}
#if 0
void test_hw_drv_flash(void)
{
uint32_t test_addr = 0x00070000 + 512;
uint8_t test_buff_wr[1000];
uint16_t test_size = 0;
uint16_t loop = 0;
uint16_t loop2 = 0;
usb_printf("\n======= Flash test step1: =======\n");bsp_delay_ms(5);
test_size = 1000;
for(loop = 0; loop < test_size; loop ++){
test_buff_wr[loop] = loop&0XFF;
}
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
memset(test_buff_wr,0xff,sizeof(test_buff_wr));
hw_drv_flash_read(test_addr, test_buff_wr, test_size);
for(loop = 0; loop < test_size; loop++){
if((loop&0XFF) != test_buff_wr[loop]){
usb_printf("<<< Flash step1 test :%d, err. \n",loop);
return;
}
}
if(loop == test_size){
usb_printf("<<< Flash test succed\n");
}
bsp_delay_ms(5);usb_printf("\n======= Flash test step2: =======\n");bsp_delay_ms(5);
test_size = 200;
for(loop = 0; loop < test_size; loop ++){
test_buff_wr[loop] = 200 - loop;
}
test_addr = 0x00070000 + 512;
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
test_addr += test_size;
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
test_addr += test_size;
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
test_addr += test_size;
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
test_addr += test_size;
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
memset(test_buff_wr,0xff,sizeof(test_buff_wr));
test_addr = 0x00070000 + 512;
hw_drv_flash_read(test_addr, test_buff_wr, sizeof(test_buff_wr));
for(loop2 = 0; loop2 < 5; loop2++){
for(loop = 0; loop < test_size; loop++){
if((200 - loop) != test_buff_wr[test_size*loop2 + loop]){
usb_printf("<<< Flash step2 test :%d, err. \n",test_size*loop2 + loop);
return;
}
}
}
if(loop == test_size){
usb_printf("<<< Flash test succed\n");
}
bsp_delay_ms(5);usb_printf("\n======= Flash test step3: =======\n");bsp_delay_ms(5);
test_size = 1000;
test_addr = 0x00070000 + 512;
for(loop = 0; loop < test_size; loop ++){
test_buff_wr[loop] = loop&0XFF;
}
hw_drv_flash_write(test_addr, test_buff_wr, test_size);
memset(test_buff_wr,0xff,sizeof(test_buff_wr));
hw_drv_flash_read(test_addr, test_buff_wr, test_size);
for(loop = 0; loop < test_size; loop++){
if((loop&0XFF) != test_buff_wr[loop]){
usb_printf("<<< Flash step3 test :%d, err. \n",loop);
return;
}
}
if(loop == test_size){
usb_printf("<<< Flash test succed\n");
}
}
#endif