📄 nor_lib.c
字号:
/*********************************************************************************************
* File name : nor_lib.c
* Author : lixf
* Descript : s3c2410 function library
* History
* lixf, Programming modify, Sep 20, 2007
*********************************************************************************************/
#include "nor_lib.h"
#include "2410lib.h"
int Strata_CheckID(int targetAddr) //返回Manufacture Code
{
_WR(targetAddr, 0x0090);
return _RD(targetAddr); //_WR和_RD都是半字操作
}
int Strata_CheckDevice(int targetAddr) //返回Device Code
{
_WR(targetAddr, 0x0090);
return _RD(targetAddr+0x2);
}
void cfi_probe(int targetAddr)
{
int i[3];
_WR(targetAddr, 0x00f0);
_WR(targetAddr, 0x0098);
i[0]=_RD(2*0x10);
i[1]=_RD(2*0x11);
i[2]=_RD(2*0x12);
if(i[0]=='Q'&&i[1]=='R'&&i[2]=='Y')
uprintf("flash(%d) is the CFI device\n",targetAddr);
else
uprintf("flash(%d) is not the CFI device\n",targetAddr);
}
void nor_test(int targetAddr)
{
int i;
i=Strata_CheckID(targetAddr);
uprintf (" flash check id=%x\n",i);
i=Strata_CheckDevice(targetAddr);
uprintf (" flash check device=%x\n",i);
cfi_probe(targetAddr);
}
void Strata_EraseSector(int targetAddress)
{
unsigned long ReadStatus;
unsigned long bSR5;
unsigned long bSR7;
_WR(targetAddress, 0x0020); //擦除命令first cycle
_WR(targetAddress, 0x00d0); //擦除命令second cycle
_WR(targetAddress, 0x0070); //读状态寄存器命令
ReadStatus=_RD(targetAddress); //读状态寄存器
bSR7=ReadStatus & (1<<7);
while(!bSR7 ) //需要判断状态寄存器的第7位
{
_WR(targetAddress, 0x0070);
ReadStatus=_RD(targetAddress);
bSR7=ReadStatus & (1<<7);
}
_WR(targetAddress, 0x0070);
ReadStatus=_RD(targetAddress);
bSR5=ReadStatus & (1<<5);
if (bSR5==0)
{
uprintf("Block @%xh Erase O.K. \n",targetAddress);
}
else
{
_WR(targetAddress, 0x0050); //// Clear Status Register
}
_WR(targetAddress, 0x00ff); //就相当于_WR(targetAddress, 0x00ff),回到Read Array的状态。
}
int Strata_ProgFlash(int realAddr, int data)
{
unsigned long ReadStatus;
unsigned long bSR4;
unsigned long bSR7;
_WR(realAddr, 0x0040);
_WR(realAddr, data);
_WR(realAddr+2, data);
_WR(realAddr+2, data);
_WR(realAddr+2, data);
_WR(realAddr, 0x0070);
ReadStatus=_RD(realAddr);
bSR7=ReadStatus & (1<<7);
while(!bSR7)
{
_WR(realAddr, 0x0070);
ReadStatus=_RD(realAddr);
bSR7=ReadStatus & (1<<7);
}
_WR(realAddr, 0x0070);
ReadStatus=_RD(realAddr);
bSR4=ReadStatus & (1<<4);
if (bSR4==0)
{
uprintf("Successful Program!!\n");
}
else
{
_WR(realAddr, 0x0050); // Clear Status Register
}
_WR(realAddr, 0x00ff);
return 0;
}
int Strata_unprotect_sector(int targetAddr) //去除sector的写保护
{
int SR7,SR3,SR4,SR5,ReadStatus;
int res=0;
_WR(targetAddr,0x0050); //Clear Status Register
_WR(targetAddr,0x0060); //First bus cycle
_WR(targetAddr,0x00D0); //Second bus cycle
_WR(targetAddr,0x0070);
ReadStatus=_RD(targetAddr);
SR7=ReadStatus & (1<<7);
while(!SR7)
{
_WR(targetAddr,0x0070);
ReadStatus=_RD(targetAddr);
SR7=ReadStatus & (1<<7);
}
_WR(targetAddr,0x0070);
ReadStatus=_RD(targetAddr);
SR3=ReadStatus & (1<<3);
SR4=ReadStatus & (1<<4);
SR5=ReadStatus & (1<<5);
if(SR3) {printf("Voltage Range Error"); res=-1;}
if(SR4 && SR5) {printf("Command Sequence Error"); res=-2;}
if(SR5) {printf("Clear Block Lock-Bits Error"); res=-3;}
_WR(targetAddr, 0x00ff);
return res;
}
int do_write_buffer( unsigned long adr, unsigned short int *buf, int len)
{
unsigned short int status, status_OK;
unsigned long cmd_adr, timeo;
int wbufsize, z;
wbufsize = 1 << 5;
adr += 0x00;
cmd_adr = adr & ~(wbufsize - 1);
/* Let's determinc this according to the interleave only once */
status_OK = CMD(0x80);
timeo = 5 * 1000;
cfi_write(CMD(0xe8), cmd_adr);
for (;;) {
status = cfi_read(cmd_adr);
if ((status & status_OK) == status_OK)
break;
if (timeo < 0) {
/* Argh. Not ready for write to buffer */
cfi_write( CMD(0x70), cmd_adr);
uprintf("Chip not ready for buffer write. Xstatus = 0x%llx, status = %llx\n", status, cfi_read( cmd_adr));
/* Odd. Clear status bits */
cfi_write( CMD(0x50), cmd_adr);
cfi_write( CMD(0x70), cmd_adr);
cfi_write( CMD(0xff), adr);
return -1;
}
}
/* Write length of data to come */
cfi_write( CMD(len), cmd_adr);
/* Write data */
for (z = 0; z <=2*len; z += 2) {
cfi_write(*buf++, adr+z);
}
/* GO GO GO */
cfi_write(CMD(0xd0), cmd_adr);
timeo = 5 * 1000;
for (;;) {
status = cfi_read( cmd_adr);
if ((status & status_OK) == status_OK)
break;
if (timeo-- < 0) {
uprintf("Waiting for chip to be ready timed out in bufwrite\n");
cfi_write( CMD(0xff), adr);
return -1;
}
}
/* Done and happy. */
// DISABLE_VPP(map);
/* check for lock bit */
if (status & CMD(0x02)) {
/* clear status */
cfi_write( CMD(0x50), cmd_adr);
/* put back into read status register mode */
cfi_write( CMD(0x70), adr);
cfi_write( CMD(0xff), adr);
return -1;
}
cfi_write( CMD(0xff), adr);
return 0;
}
/*********************************************************************************************
* name: do_write_buffers
* func: write the data from memory to nor flash with buffer
* para: flash_addr -- nor flash address
* len -- the length of the data,must be the times of 128K
* ret: the data must be download to 0x31000000 of the ram
* modify:
* comment:
*********************************************************************************************/
void do_write_buffers(unsigned int flash_addr,int len)
{
int i,a;
int erase_size = len >> 17 ;
int copy_size = len >> 5 ;
for(i=0;i<erase_size;i++)
Strata_EraseSector(flash_addr+i*sector_size);
uprintf("erase ok\n");
for(a=0;a<copy_size;a++)
do_write_buffer( flash_addr+2*a*0x10, 0x31000000+2*a*0x10, 0x0f);
// do_write_buffer( 0x500000+2*a*0x10, p+0x10, 0x0f);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -