基于nxp的flash读写驱动实现

以下代码在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
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值