1.讀NorFlash
我們首先來實現(xiàn)讀flash的函數(shù),我們默認每次讀取64個字節(jié),然后我們把讀取到的內(nèi)容打印出來,其中前面打印數(shù)值,后面打印字符,對于不可見字符用...代替。
void do_read_nor_flash(void)
{
unsigned int addr;
volatile unsigned char *p;
int i, j;
unsigned char c;
unsigned char str[16];
/* 獲得地址 */
printf("Enter the address to read: ");
addr = get_uint();
p = (volatile unsigned char *)addr;
printf("Data : nr");
/* 長度固定為64 */
for (i = 0; i < 4; i++)
{
/* 每行打印16個數(shù)據(jù) */
for (j = 0; j < 16; j++)
{
/* 先打印數(shù)值 */
c = *p++;
str[j] = c;
printf("%02x ", c);
}
printf(" ; ");
for (j = 0; j < 16; j++)
{
/* 后打印字符 */
if (str[j] < 0x20 || str[j] > 0x7e) /* 不可視字符 */
putchar('.');
else
putchar(str[j]);
}
printf("nr");
}
}
2.擦除Nroflash
從芯片手冊看到,要想擦除,我們首先解鎖,然后發(fā)出80命令,然后再次解鎖,然后再向某一個地址發(fā)出30命令即可。
代碼如下:
void do_erase_nor_flash(void)
{
unsigned int addr;
/* 獲得地址 */
printf("Enter the address of sector to erase: ");
addr = get_uint();
printf("erasing ...nr");
nor_cmd(0x555, 0xaa); /* 解鎖 */
nor_cmd(0x2aa, 0x55);
nor_cmd(0x555, 0x80); /* erase sector */
nor_cmd(0x555, 0xaa); /* 解鎖 */
nor_cmd(0x2aa, 0x55);
nor_cmd(addr>>1, 0x30); /* 發(fā)出扇區(qū)地址 */
wait_ready(addr);
}
我們通過讀數(shù)據(jù)bit6,如果它不變化了,說明擦除或者寫結(jié)束了。所以wait_ready()函數(shù)這樣寫。
void wait_ready(unsigned int addr)
{
unsigned int val;
unsigned int pre;
pre = nor_dat(addr>>1);
val = nor_dat(addr>>1);
while ((val & (1<<6)) != (pre & (1<<6)))
{
pre = val;
val = nor_dat(addr>>1);
}
}
3.寫NorFlash
要想寫NorFlash,我們首先解鎖,然后在地址555H寫入A0H命令,然后在某個地址寫入某個之即可,這里的數(shù)據(jù)時16位的。
代碼如下:
void do_write_nor_flash(void)
{
unsigned int addr;
unsigned char str[100];
int i, j;
unsigned int val;
/* 獲得地址 */
printf("Enter the address of sector to write: ");
addr = get_uint();
printf("Enter the string to write: ");
gets(str);
printf("writing ...nr");
/* str[0],str[1]==>16bit
* str[2],str[3]==>16bit
*/
i = 0;
j = 1;
while (str[i] && str[j])
{
val = str[i] + (str[j]<<8);
/* 燒寫 */
nor_cmd(0x555, 0xaa); /* 解鎖 */
nor_cmd(0x2aa, 0x55);
nor_cmd(0x555, 0xa0); /* program */
nor_cmd(addr>>1, val);
/* 等待燒寫完成 : 讀數(shù)據(jù), Q6無變化時表示結(jié)束 */
wait_ready(addr);
i += 2;
j += 2;
addr += 2;
}
val = str[i];
/* 燒寫 */
nor_cmd(0x555, 0xaa); /* 解鎖 */
nor_cmd(0x2aa, 0x55);
nor_cmd(0x555, 0xa0); /* program */
nor_cmd(addr>>1, val);
/* 等待燒寫完成 : 讀數(shù)據(jù), Q6無變化時表示結(jié)束 */
wait_ready(addr);
}
4.完整代碼
#include "my_printf.h"
#include "string_utils.h"
#define NOR_FLASH_BASE 0 /* jz2440, nor-->cs0, base addr = 0 */
/* 比如: 55H 98
* 本意是: 往(0 + (0x55)<<1)寫入0x98
*/
void nor_write_word(unsigned int base, unsigned int offset, unsigned int val)
{
volatile unsigned short *p = (volatile unsigned short *)(base + (offset << 1));
*p = val;
}
/* offset是基于NOR的角度看到 */
void nor_cmd(unsigned int offset, unsigned int cmd)
{
nor_write_word(NOR_FLASH_BASE, offset, cmd);
}
unsigned int nor_read_word(unsigned int base, unsigned int offset)
{
volatile unsigned short *p = (volatile unsigned short *)(base + (offset << 1));
return *p;
}
unsigned int nor_dat(unsigned int offset)
{
return nor_read_word(NOR_FLASH_BASE, offset);
}
void wait_ready(unsigned int addr)
{
unsigned int val;
unsigned int pre;
pre = nor_dat(addr>>1);
val = nor_dat(addr>>1);
while ((val & (1<<6)) != (pre & (1<<6)))
{
pre = val;
val = nor_dat(addr>>1);
}
}
/* 進入NOR FLASH的CFI模式
* 讀取各類信息
*/
void do_scan_nor_flash(void)
{
char str[4];
unsigned int size;
int regions, i;
int region_info_base;
int block_addr, blocks, block_size, j;
int cnt;
int vendor, device;
/* 打印廠家ID、設(shè)備ID */
nor_cmd(0x555, 0xaa); /* 解鎖 */
nor_cmd(0x2aa, 0x55);
nor_cmd(0x555, 0x90); /* read id */
vendor = nor_dat(0);
device = nor_dat(1);
nor_cmd(0, 0xf0); /* reset */
nor_cmd(0x55, 0x98); /* 進入cfi模式 */
str[0] = nor_dat(0x10);
str[1] = nor_dat(0x11);
str[2] = nor_dat(0x12);
str[3] = ' 主站蜘蛛池模板: 南宁市| 京山县| 彩票| 将乐县| 集安市| 德化县| 沙洋县| 松阳县| 金阳县| 怀宁县| 万山特区| 和林格尔县| 寿光市| 称多县| 荆门市| 开封市| 汉源县| 加查县| 卓资县| 赤壁市| 贞丰县| 柯坪县| 娱乐| 侯马市| 缙云县| 沂源县| 尉氏县| 锡林郭勒盟| 庆安县| 广丰县| 安福县| 南乐县| 丽水市| 读书| 彩票| 沈丘县| 海丰县| 宁国市| 襄城县| 繁昌县| 阳曲县|