历史上的今天
返回首页

历史上的今天

今天是:2024年10月12日(星期六)

正在发生

2021年10月12日 | S3C2440裸机------Nor Flash编程_擦写读

2021-10-12 来源:eefocus

1.读NorFlash

我们首先来实现读flash的函数,我们默认每次读取64个字节,然后我们把读取到的内容打印出来,其中前面打印数值,后面打印字符,对于不可见字符用...代替。


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个数据 */

for (j = 0; j < 16; j++)

{

/* 先打印数值 */

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

从芯片手册看到,要想擦除,我们首先解锁,然后发出80命令,然后再次解锁,然后再向某一个地址发出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); /* 发出扇区地址 */

wait_ready(addr);

}

我们通过读数据bit6,如果它不变化了,说明擦除或者写结束了。所以wait_ready()函数这样写。 


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命令,然后在某个地址写入某个之即可,这里的数据时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);

/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */

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);

/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */

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、设备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] = '';

printf("str = %snr", str);

 

/* 打印容量 */

size = 1<<(nor_dat(0x27));

printf("vendor id = 0x%x, device id = 0x%x, nor size = 0x%x, %dMnr", vendor, device, size, size/(1024*1024));

 

/* 打印各个扇区的起始地址 */

/* 名词解释:

*    erase block region : 里面含有1个或多个block, 它们的大小一样

* 一个nor flash含有1个或多个region

* 一个region含有1个或多个block(扇区)

* Erase block region information:

*    前2字节+1    : 表示该region有多少个block 

*    后2字节*256  : 表示block的大小

*/

 

regions = nor_dat(0x2c);

region_info_base = 0x2d;

block_addr = 0;

printf("Block/Sector start Address:nr");

cnt = 0;

for (i = 0; i < regions; i++)

{

blocks = 1 + nor_dat(region_info_base) + (nor_dat(region_info_base+1)<<8);

block_size = 256 * (nor_dat(region_info_base+2) + (nor_dat(region_info_base+3)<<8));

region_info_base += 4;

 

// printf("nrregion %d, blocks = %d, block_size = 0x%x, block_addr = 0x%xnr", i, blocks, block_size, block_addr);

 

for (j = 0; j < blocks; j++)

{

/* 打印每个block的起始地址 */

//printf("0x%08x ", block_addr);

printHex(block_addr);

putchar(' ');

cnt++;

block_addr += block_size;

if (cnt % 5 == 0)

printf("nr");

}

}

printf("nr");

/* 退出CFI模式 */

nor_cmd(0, 0xf0);

}

 

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); /* 发出扇区地址 */

wait_ready(addr);

}

 

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);

/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */

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);

/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */

wait_ready(addr);

}

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个数据 */

for (j = 0; j < 16; j++)

{

/* 先打印数值 */

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");

}

}

 

void nor_flash_test(void)

{

char c;

 

while (1)

{

/* 打印菜单, 供我们选择测试内容 */

printf("[s] Scan nor flashnr");

printf("[e] Erase nor flashnr");

printf("[w] Write nor flashnr");

printf("[r] Read nor flashnr");

printf("[q] quitnr");

printf("Enter selection: ");

 

c = getchar();

printf("%cnr", c);

 

/* 测试内容:

* 1. 识别nor flash

* 2. 擦除nor flash某个扇区

* 3. 编写某个地址

* 4. 读某个地址

*/

switch (c)  

{

case 'q':

case 'Q':

return;

break;

case 's':

case 'S':

do_scan_nor_flash();

break;

 

case 'e':

case 'E':

do_erase_nor_flash();

break;

 

case 'w':

case 'W':

do_write_nor_flash();

break;

 

case 'r':

case 'R':

do_read_nor_flash();

break;

default:

break;

}

}

}

推荐阅读

史海拾趣

Analog Microelectronics GmbH公司的发展小趣事

Analog Microelectronics GmbH是一家德国的半导体公司,专注于开发和生产模拟集成电路(ICs),以及为汽车、工业和医疗等领域提供解决方案。以下是Analog Microelectronics GmbH公司发展的相关故事:

  1. 创立与早期发展:Analog Microelectronics GmbH成立于1984年,总部位于德国巴伐利亚州的兰格维塔赫镇。公司的创始人致力于开发高质量的模拟集成电路,以满足市场对精密电子元件的需求。在创立初期,公司主要专注于生产模拟传感器和信号处理器件。

  2. 技术创新与产品优化:Analog Microelectronics GmbH在技术创新方面持续投入,不断改进和优化其产品线。公司注重研发和设计,致力于提供高性能、高精度和可靠性的模拟集成电路产品。公司的产品包括压力传感器、温度传感器、加速度传感器、电流传感器等,广泛应用于汽车电子、工业自动化、医疗器械等领域。

  3. 市场拓展与客户合作:Analog Microelectronics GmbH通过与全球各行业的客户建立长期稳定的合作关系,不断拓展市场份额和业务范围。公司在欧洲、亚洲和北美等地区设立了销售办事处和代表处,加强了与客户的沟通和服务能力,提高了产品的市场竞争力。

  4. 质量控制与认证:Analog Microelectronics GmbH严格遵循国际质量管理体系标准,对产品的生产过程进行严格控制和管理。公司获得了ISO 9001质量管理体系认证,确保产品质量稳定可靠。此外,公司的产品也符合汽车行业的相关认证标准,如ISO/TS 16949等,为客户提供高品质的产品和服务。

  5. 持续发展与未来展望:作为一家成熟的模拟集成电路供应商,Analog Microelectronics GmbH将继续致力于技术创新和产品研发,以满足不断变化的市场需求。公司将继续加强与客户和合作伙伴的合作关系,拓展业务领域,为全球客户提供更加优质的解决方案和服务。

Concurrent Logic公司的发展小趣事

随着技术的不断进步,Concurrent Logic成功开发出了一款具有革命性的并行计算芯片。这款芯片在市场上引起了巨大的反响,因其出色的并行处理能力和高效的逻辑运算,很快得到了众多电子设备和数据中心的青睐。这一技术的突破不仅为公司带来了可观的收入,更让Concurrent Logic在电子行业中崭露头角。

辉芒微(FMD)公司的发展小趣事

在快速发展的过程中,辉芒微积极寻求外部合作与资本支持。2017年,公司与芯天下达成重要交易,通过股权转让的方式,将SPI NOR Flash产品线转让给芯天下,并获得了丰厚的现金回报和股权收益。这一战略举措不仅为公司带来了短期的财务收益,更为后续的发展提供了更多的资本支持和战略灵活性。此后,辉芒微还成功吸引了多家知名投资机构的关注和支持,为其未来的发展注入了强劲的动力。

Connector City公司的发展小趣事

随着国内市场的饱和,Connector City公司开始寻求海外市场的发展机遇。公司制定了详细的国际化战略,积极开拓海外市场,加强与国外客户的合作与交流。同时,公司还注重本土化运营,根据不同国家和地区的市场需求和文化差异,灵活调整产品设计和营销策略。通过不断拓展海外市场,公司的销售业绩实现了快速增长。

First Silicon Co., Ltd公司的发展小趣事

面对日益激烈的市场竞争,First Silicon公司深知供应链管理的重要性。公司投入大量资源,对供应链进行了全面整合和优化。通过建立长期稳定的供应商关系、引入先进的供应链管理软件和提高库存周转率等措施,First Silicon有效降低了原材料成本和库存风险。同时,公司还加强了与下游客户的沟通和合作,确保产品能够及时、准确地送达客户手中。这一系列举措不仅提升了公司的运营效率,还增强了其市场竞争力。

Elpida Memory公司的发展小趣事

尽管有政府的支持,但Elpida Memory的经营状况并未得到根本性的改善。在经历了多年的亏损和重组后,Elpida Memory最终于2012年被美国的美光科技(Micron Technology)收购。这一收购标志着Elpida Memory正式退出了日本半导体产业的舞台,但也为其未来的发展提供了新的机遇。

问答坊 | AI 解惑

器件搜索

本帖最后由 paulhyde 于 2014-9-15 09:17 编辑 器件搜索  …

查看全部问答>

请教高手电路图中的难点

D13,D41,D42三个二极管再电路中是什么用处? 如果LM324的1脚输出增加,那么D13,D41,D42三个二极管输出全部拉低,这对电路整体有什么影响呢? [ 本帖最后由 simonprince 于 2009-9-10 08:46 编辑 ]…

查看全部问答>

做Wince和Mobile方面的底层和上层的软件开发的QQ 3号群68387065

提供一个大家交流的平台,现还有部分名额,欢迎相关人员加入,长期有效…

查看全部问答>

求救,藍牙模塊出錯(Bluetooth hardware error 10050(controller not present))!

我在Catalog Items中添加了Bluetooth下的UART Driver 和 Universal Loadable Driver,然後 編譯. (是不是在這步之後需要修改哪個.reg嗎?請指教!)之後,在Bluetooth Manager中點擊Scan Device出現 Bluetooth hardware error 10050(controller not pre ...…

查看全部问答>

求助:f2812如何将片内FLASH中的程序加载到片内RAM中运行?

由于程序在片内flash中的运行速度较慢,希望能将片内flash中的程序全部加载到片内ram中运行,请问有什么好办法? 我的邮箱:gziyong2004@126.com,希望大家有空多沟通交流!…

查看全部问答>

智能小车

本帖最后由 dontium 于 2015-1-23 13:24 编辑 智能小车 …

查看全部问答>

一种新颖的D类音频功率放大器驱动电路

本帖最后由 dontium 于 2015-1-23 12:40 编辑 一种新颖的D类音频功率放大器驱动电路一种高效率+PWM+CMOS+D类音频功率放大器 …

查看全部问答>

用C8051F系列编写的ADXL345角速度测试程序

我用C8051F410编写的程序通过I2C通信,显示屏无任何显示,怎么办?谁有正确的代码,能不能分享下…

查看全部问答>