本文是基于韦东山视频的学习笔记
总汇
Nor flash 相关指令集
都说 Nor flash “只读”不可写的,事实上,要写的话用特殊指令集写即可。由于Nor flash是16位的,所以都是对应 word 指令。
每次我们在烧写bin文件的时候总看见命令行上面有这些信息,这次我们就来实现一下自己实现打印这些信息。
[Main Menu]
0:Nand Flash prog 1:Nor Flash prog 2:Memory Rd/Wr 3:Exit
Select the function to test:1
Detect Nor Flash ...
MXIC MX29LV160B
Size: 2 MB
Image Size: 0xe80
Available Target Offset:
Bank # 1: MXIC MX29LV160B FLASH (16 x 16) Size: 2 MB in 35 Sectors
AMD Standard command set, Manufacturer ID: 0xC2, Device ID: 0x2249
Erase timeout: 30000 ms, write timeout: 100 ms
Sector Start Addresses:
00000000 00004000 00006000 00008000 00010000
00020000 00030000 00040000 00050000 00060000
00070000 00080000 00090000 000A0000 000B0000
000C0000 000D0000 000E0000 000F0000 00100000
00110000 00120000 00130000 00140000 00150000
00160000 00170000 00180000 00190000 001A0000
001B0000 001C0000 001D0000 001E0000 001F0000
Input target offset:0
Erasing . done
write ...
100%done
其中包括
- 设备信息
- Nor flash 大小
- 扇区数量
- 扇区信息
读取设备信息
要读取设备信息,首先需要进入CFI 模式
进入CFI 的指令是 [55H] = 0x98
设备信息
Nor flash 大小
参考CFI publication 100基准,可知扇区信息怎么解读:
- 前两字节+1代表扇区个数
- 后两字节*256代表扇区大小
在data(h) 只是取低8位的数据
void do_scan_nor_flash()
{
unsigned int i = 0, j = 0, cnt = 0;
unsigned int region = 0, sectors = 0, sector_size = 0, sector_addr = 0;
unsigned int region_info_base = 0x2D;
unlock_cmd(); //解锁
nor_cmd(0x555, 0x90);
puts("\n\r");
puts("vendor id: "); print_hex(nor_read(0)); puts("\n\r"); //0xC2
puts("device id: "); print_hex(nor_read(1)); puts("\n\r"); //0x2249
/* 要读取设备信息,首先需要进入CFI 模式
* 进入CFI 的指令是 [55H] = 0x98
*/
nor_cmd(0x55, 0x98);
#if 0
str[1] = nor_read(0x10); putchar(str[1]);
str[2] = nor_read(0x11); putchar(str[2]);
str[3] = nor_read(0x12); putchar(str[3]);
str[4] = '\0';
#endif
putchar(nor_read(0x10)); //Q
putchar(nor_read(0x12)); //R
putchar(nor_read(0x11)); //Y
puts(" CFI mode... \n\r");
puts("nor size: "); print_hex((1<<(nor_read(0x27))) / 1024 / 1024);puts("M\n\r");
region = nor_read(0x2C);
puts("region : "); print_hex(region);puts("\n\r");
/*
> 参考CFI publication 100基准,可知扇区信息怎么解读:
> - 前两字节+1 = 该region的扇区个数
> - 后两字节*256 = 该region的扇区大小
在data(h) 只是取低8位的数据
*/
for (i=0; i<region; i++)
{
sectors = 1 + (nor_read(region_info_base + 0) + (nor_read(region_info_base + 1) << 8));
sector_size = 256 * (nor_read(region_info_base + 2) + (nor_read(region_info_base + 3) << 8));
region_info_base += 4;
for(j=0; j<sectors; j++)
{
print_hex_with0(sector_addr);putchar(' ');
sector_addr += sector_size;
cnt++;
if (cnt % 5 == 0)
puts("\n\r");
}
}
}