FT2000-4 下QSPI-Flash驱动总结

一. 初始化qspi

设置flash容量和片数

//初始化容量寄存器
val = chip_num << 3 | chip_size ;  //片数 和 每片容量
qspi_write(val,QSPI_FLASH_CAPACITY);

示例:
   2片flash,每片容量128MB
chip_num = 2;
chip_size = 128MB;

val = 1 << 3 | 0x5;  //片数 和 每片容量
qspi_write(val,QSPI_FLASH_CAPACITY);

二. flash读

直接拷贝即可:     

uboot下: cp.b 0x60000000 0x90000000 0x200000

拷贝 flash 6MB到内存0x90000000地址,大小为2MB。


vx下:
    memcpy(0x90000000, 0x60000000 ,0x200000);

三. flash 擦除

a. 流程:

        1. 写 CMD_PORT 寄存器,仅修改[31:24],填入对应 flash 写使能命令,并且置位 bit22。

        2. 写 LD_PORT,填入 0x1,发送命令。
        3. 写 CMD_PORT 寄存器,仅修改[31:24],填入对应 flash 擦除命令,并且置位 bit22 和 bit15。

        4. 写 ADDR_PORT 寄存器,填入需要擦除的地址。

        5. 写 LD_PORT,填入 0x1,发送命令。

 b. 示例

#define QSPI_SECTOR_SIZE             0x10000 //64KB
void qspiFlashSectorErase_4byte(UINT32 blockAddr)
{
	UINT32 cmd_id;
	semTake(Flash_Sem,WAIT_FOREVER);

	int qspi_csx = qspi_cs_get(blockAddr);  //根据地址片选

	cmd_id = CMD_WREN; // 写使能指令
	qspi_write(0x400000 | (cmd_id << 24) | (qspi_csx << 19) , (void*)QSPI_CMD_PORT);
	qspi_write(0x1, (void*)QSPI_LD_PORT);
	__asm__ volatile("isb;dsb");

    cmd_id = CMD_ERASE_4BYTE;//4字节擦除指令
	qspi_write(0x408000 | (cmd_id << 24)| (1<<12) | (qspi_csx << 19) , (void*)QSPI_CMD_PORT);
	qspi_write(blockAddr, (void*)QSPI_ADDR_PORT);
	qspi_write(0x1, (void*)QSPI_LD_PORT);
	__asm__ volatile("isb;dsb");

	semGive(Flash_Sem);
}

void qspiFlashErase_4byte(UINT32 addr, UINT32 len)
{

	setcmd(CMD_ENABLE_4BYTE);
	while(len) {

		qspiFlashSectorErase_4byte(addr);
		addr += QSPI_SECTOR_SIZE;
		len -= QSPI_SECTOR_SIZE;
	}

	setcmd(CMD_DISABLE_4BYTE);

}

四. flash写

a.流程

1、 写 CMD_PORT 寄存器,仅修改[31:24],填入对应 flash 写使能命令,并且置位 bit22。
2、 写 LD_PORT,填入 0x1,发送命令。
3、 写 WR_CFG 寄存器,仅修改[31:24],填入对应 flash 编程命令,并且置位 bit9 及 bit3。
4、 直接写 0x0 ---- 0x1FFFFFFF 的地址空间,可以连续写入,且必须保证每次写都是四字节写。
5、 写 LD_PORT,填入 0x1,发送命令。
6、 写 WR_CFG 寄存器为 0 关闭写使能。

b.示例

//一页 256个字节

void qspiPageProgramFlush_4byte(UINT32* src_addr, UINT32* page_addr, UINT32 pp_num)
{
	UINT32 i = 0;
	UINT32 temp[64] = {0};
	UINT32 cmd_id = 0;
	semTake(Flash_Sem,WAIT_FOREVER);
	for(i = 0; i < (pp_num>>2); i++) {
		temp[i] = *(src_addr + i);
	}

	int qspi_csx = qspi_cs_get(page_addr);

	cmd_id = CMD_WREN;
	qspi_write(0x400000 | (cmd_id << 24) | (qspi_csx << 19) , (void*)QSPI_CMD_PORT);
	qspi_write(0x1, (void*)QSPI_LD_PORT);
	__asm__ volatile("isb;dsb");

	cmd_id = CMD_PP_4BYTE;
	qspi_write(0x000208 | (cmd_id << 24) | (1<<4), (void*)QSPI_WR_CFG); 
	__asm__ volatile("isb;dsb");

	for(i = 0; i < (pp_num>>2); i++) {
		*(page_addr +i) = temp[i];
	}

    qspi_write(0x1, (void*)QSPI_FLUSH_REG);
    semGive(Flash_Sem);
}

void qspiPageProgram_4byte(UINT32* src_addr, UINT32* page_addr, UINT32 pp_num)
{
	UINT32 i = 0;
	UINT32 add = 0;

	if(pp_num <= 256) {
		add = 1;
	} else {
		if((pp_num % 256) > 0) {
			add = pp_num / 256 + 1;
		} else {
			add = pp_num /256;
		}
	}

	setcmd(CMD_ENABLE_4BYTE);
	for(i = 0; i < add; i++) {
        //src_addr为int型,一次操作4个字节。4 * 64 = 256
		qspiPageProgramFlush_4byte(src_addr + i*64, page_addr + i*64, 256);
	}
	setcmd(CMD_DISABLE_4BYTE);
}

五.读flash_id 

int read_flash_id()
{
    unsigned int cmd_id = ID_CMD;//0x9f
	qspi_write((cmd_id << 24) |1<<22 |1<<13 |1<<6 | (cs << 19), (void*)QSPI_CMD_PORT);  
    
	int val = qspi_read(QSPI_LD_PORT);
	printf("\r\n flash CMD:%x val=0x%x\r\n",CMD,val);

}

备注:flash命令

flash常用命令:

#define CMD_WREN                     0x06

#define CMD_PP                       0x02
#define CMD_PP_4BYTE                 0x12

#define CMD_ERASE                    0xD8
#define CMD_ERASE_4BYTE              0xDC

#define CMD_ENABLE_4BYTE             0xB7
#define CMD_DISABLE_4BYTE            0xE9

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值