哪位朋友用过EN29LV160AB,即TQ2440开发板配套Nor Flash。最近想学习一下Flash操作,用ADS1.2写了一个简单的测试程序,将bin文件通过Hjtag烧写到Nor flash中,发现写入失败。
主要程序如下:
- void Test_NorFlash(void)
- {
- U32 EonID, FlashAddr, RdStartAddr,WrStartAddr=0xf0000; //32K
- U16 i,WrLen=0x20, WrErrNum=0;
- U16 dat=0, RdLen=32, Rddata;
- U8 j=0;
-
- RdStartAddr = WrStartAddr;
- FlashAddr = WrStartAddr;
-
- EonID = EN29LV160AB_GetID();
-
- Uart_Printf("芯片ID:%x\n", EonID);
-
- EN29LV160AB_Reset(); //must write the reset
- Delay(100);
- /*if(!EN29LV160AB_ChipErase()) //Erase fail
- {
- Uart_Printf("Chip Erase fail!\n");
- }*/
-
- Uart_Printf("Start test Word Program...\n");
- for(i=0; i<WrLen; i++) //Write data
- {
- if((FlashAddr % 0x8000) == 0x0) //32K
- {
- if(!EN29LV160AB_SectorErase(FlashAddr))//擦除貌似没什么问题
- {
- Uart_Printf("Erase Sector %x Fail!\n", FlashAddr);
- return;
- }
- }
-
- if(!EN29LV160AB_WordProg(FlashAddr, dat))
- {
- WrErrNum++;
- }
- FlashAddr++;
- dat++;
- for(j=0; j<100; j++);
- }
-
- Uart_Printf("Start test Read Chip...\n"); //Read data
- FlashAddr = RdStartAddr;
- for(i=0; i<RdLen; i++)
- {
- Rddata = EN29LV160AB_Read(FlashAddr);
- FlashAddr++;
- Uart_Printf("%-10x", Rddata);
- }
-
- Uart_Printf("\nEN29LV160AB test finish! WrERR = %-10x\n", WrErrNum);
- return;
- }
复制代码 我写的一些基础操作
- /*
- Vendor: EON
- PartNo: EN29LV160AB
- Type: Nor FLASH
- Sector: 35
- BYTE: 1 2 1 31
- 16K 8K 32K 64K
- Word: 1 2 1 31
- 8K 4K 16K 32K
- Size: 2M
- ID: 0x2249001C
- Width: byte/word
- */
- #define __EN29LV160_H
- #include "../inc/EN29LV160AB.h"
- #undef __EN29LV160_H
- /**********
- 功能:读取存储器
- 参数:
- *************/
- U16 EN29LV160AB_Read(U32 addr)
- {
- return *((volatile U16 *)(addr));
- }
- /**********
- 功能:软件复位存储器
- 参数:
- *************/
- void EN29LV160AB_Reset(void)
- {
- *((volatile U16 *)0x00) = 0xf0;
- }
- /**********
- 功能:写入存储器
- 参数:addr:地址
- dat:数据
- *************/
- void Writeflash( U32 addr,U16 dat )
- {
- addr = addr << 1;
- *((volatile U16 *)addr) = dat;
- }
- /**********
- 功能:等待结束
- 参数:
- 返回:1-正常结束 0-失败
- *************/
- U8 Waitfor_endofprg(void)
- {
- volatile U16 waitno=0;
- volatile U32 Old_status, New_status;
- Old_status = *((volatile U16 *)0x00); //read first
- while(1)
- {
- New_status = *((volatile U16 *)0x00); //read second
- if((Old_status & 0x40) == (New_status & 0x40)) //DQ6=Toggle?
- {
- break; //pass
- }
- //waitno++;
- if(New_status & 0x20) //DQ5 = 1
- {
- Old_status = *((volatile U16 *)0x00); //read first
- New_status = *((volatile U16 *)0x00); //read second
- if((Old_status & 0x40) == (New_status & 0x40)) //DQ6=Toggle?
- {
- break; //pass
- }
- else
- return 0; //fail
- }
- Old_status = New_status;
- }
- //Uart_Printf("%x", waitno);
- return 1;
- }
- /**********
- 功能:芯片擦除
- 参数:
- 返回:1-正常结束 0-失败
- *************/
- U8 EN29LV160AB_ChipErase(void)
- {
- Writeflash(0x555, 0xAA);
- Writeflash(0x2AA, 0x55);
- Writeflash(0x555, 0x80);
- Writeflash(0x555, 0xAA);
- Writeflash(0x2AA, 0x55);
- Writeflash(0x555, 0x10);
-
- return Waitfor_endofprg();
- }
- /**********
- 功能:扇区擦除
- 参数:SAaddr:地址(对应扇区)
- *************/
- U8 EN29LV160AB_SectorErase(U32 SAaddr)
- {
- Writeflash(0x555, 0xAA);
- Writeflash(0x2AA, 0x55);
- Writeflash(0x555, 0x80);
- Writeflash(0x555, 0xAA);
- Writeflash(0x2AA, 0x55);
- *((volatile U16 *)SAaddr)=0x30;
- return Waitfor_endofprg();
- }
- /**********
- 功能:写入双字
- 参数:addr:地址
- dat:数据
- *************/
- U8 EN29LV160AB_WordProg(U32 addr,U16 dat)
- {
- Writeflash(0x555, 0xAA);
- Writeflash(0x2AA, 0x55);
- Writeflash(0x555, 0xA0);
- Writeflash(addr, dat);
-
- return Waitfor_endofprg();
-
- }
- /**********
- 功能:读取存储器ID
- 参数:
- 返回:ID
- 备注:AutoSelect Command程序执行结束,必须复位才能进行读写操作
- *************/
- U32 EN29LV160AB_GetID(void)
- {
- U32 temp;
-
- Writeflash(0x555, 0xAA);
- Writeflash(0x2AA, 0x55);
- Writeflash(0x555, 0x90);
-
- temp = (*(volatile unsigned short *)(0x1<<1))<<16; //A1->A0. Left shift
- temp |= *(volatile unsigned short *)(0x100<<1);
-
- return temp;
- }
复制代码 串口调试信息及技术手册相关部分,如图
|