📄 s29gl064a90.c
字号:
*
* Arguments : start_addr is the start byte address.
* data is the data pointer.
* number is the data of number to be read. It is counted by half-words.
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void NorFlashRdData(int start_addr, unsigned short *data, int number)
{
int i;
#if 1
/* The read array command */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_RD_ARRAY;
PifWaitTillDone(); // Wait till the first cycle complete
#endif
NorFlashRd(start_addr, data, number);
}
/*
*********************************************************************************************
* NorFlashRdDataBurst
*
* Description: read the data from the specified address.
*
* Arguments : start_addr is the start byte address.
* data is the data pointer.
* number is the data of number to be read. It is counted by half-words.
* Maximum is 2047.
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void NorFlashRdDataBurst(int start_addr, unsigned short *data, int number)
{
int i;
#if 0
/* The read array command */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_RD_ARRAY;
PifWaitTillDone(); // Wait till the first cycle complete
#endif
NorFlashRd1(start_addr, data, number);
}
/*
*********************************************************************************************
* NorFlashRd1
*
* Description: read the data from the specified address.
*
* Arguments : start_addr is the start byte address.
* data is the data pointer.
* number is the data of number to be read. Counted by unsigned short integers.
*
* Return : none.
*
* Note(s) : number should be less than 2047.
*********************************************************************************************
*/
void NorFlashRd1(int start_addr, unsigned short *data, int number)
{
unsigned int i, tmp, iN, word_number;
start_addr = start_addr * 1;
//number &= 0x7ff; // Maxium of byte length of the transfer is 4096 bytes
if(number & 0x1) {
word_number = number/2 + 1;
} else
word_number = number/2;
iN = 0;
PIF_READ_SET();
rPIF_PCI_LEN = number * 2; // rPIF_PCI_LEN is counted by bytes.
rPIF_PCI_DEV_A = start_addr; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
for(i = 0; i < word_number; i++) {
tmp = rPIF_PCMCIA_DATA;
*data++ = tmp & 0xffff;
iN++;
if (iN == number)
break;
*data++ = (tmp >> 16);
iN++;
}
}
/*
*********************************************************************************************
* NorFlashRd
*
* Description: read the data from the specified address.
*
* Arguments : start_addr is the start byte address.
* data is the data pointer.
* number is the data of number to be read. It is counted by half-words.
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void NorFlashRd(int start_addr, unsigned short *data, int number)
{
unsigned int i, tmp;
//printf("NoFlashRd: start_addr = 0x%x, data_add = 0x%x, number = %d \n",start_addr,data,number);
start_addr = start_addr * 1;
PIF_READ_SET();
rPIF_PCI_LEN = 2; // rPIF_PCI_LEN is counted by bytes.
for(i = 0; i < number; i++) {
rPIF_PCI_DEV_A = start_addr; // the byte address
start_addr += 2;
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
*data++ = rPIF_PCMCIA_DATA;
}
}
/* S29GL064A90_16x1_erase():
* Erase sector 'snum'.
* Return 0 if success, else negative.
*/
int
S29GL064A90_16x1_erase(struct flashinfo *fdev,int snum)
{
unsigned int status;
int i;
//printf("S29GL064A90_16x1_erase erase block %d \n",snum);
/* the first cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
rPIF_PCI_DEV_A = 0xaaa; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
rPIF_PCMCIA_DATA = 0xaa;
PifWaitTillDone(); // Wait till the first cycle complete
/* the second cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
rPIF_PCI_DEV_A = 0x554; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
rPIF_PCMCIA_DATA = 0x55;
PifWaitTillDone(); // Wait till the first cycle complete
/* the third cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
rPIF_PCI_DEV_A = 0xaaa; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
rPIF_PCMCIA_DATA = 0x80;
PifWaitTillDone(); // Wait till the first cycle complete
/* the fourth cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
rPIF_PCI_DEV_A = 0xaaa; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
rPIF_PCMCIA_DATA = 0xaa;
PifWaitTillDone(); // Wait till the first cycle complete
/* the fifth cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
rPIF_PCI_DEV_A = 0x554; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
rPIF_PCMCIA_DATA = 0x55;
PifWaitTillDone(); // Wait till the first cycle complete
/* the sixth cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
//rPIF_PCI_DEV_A = block_no * NOR_FLASH_BYTES_PER_SECTOR ; // the byte address
rPIF_PCI_DEV_A = fdev->sectors[snum].begin; // the byte address
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PIF_START();
rPIF_PCMCIA_DATA = 0x30; //30 -> 50
PifWaitTillDone(); // Wait till the first cycle complete
status = 0x0;
while(!(status & 0x80)) { // Flash is busy?
NorFlashRd(rPIF_PCI_DEV_A, &status, 1);
}
// printf("Erase OK Status %d !\r\n", status);
/*
status = 0x0;
for(i=0; i< 40; i++)
{
NorFlashRd(fdev->sectors[snum].begin+i, &status, 1);
printf("%x ",status);
if(i&0xf == 0)
printf("\n");
status = 0x0;
}
*/
//if(status & 0x20) // Whether the SR4 or SR5 is set
// return FAILED;
return SUCCESSFUL;
}
/* EndS29GL064A90_16x1_erase():
* Function place holder to determine the end of the above function.
*/
void
EndS29GL064A90_16x1_erase(void)
{}
int
S29GL064A90_16x1_write(struct flashinfo *fdev,uchar *dest,uchar *src,
long bytecnt)
{
int i,addr,step,process;
unsigned short *data;
uchar temp;
addr = dest;
data = (unsigned short *)src;
step = bytecnt/100;
process = 0;
for(i = 0; i < bytecnt/2 + 1; i ++) {
NorFlashProg(addr, *data);
//printf("After program\r\n");
/* Flash program setup command */
addr +=2;
data++;
if(i>=process)
{
putchar('*');
process += step;
}
}
printf("Write %d byte OK!\r\n",bytecnt);
}
int
S29GL064A90_16x1_read(struct flashinfo *fdev,uchar *dest,uchar *src,
long bytecnt)
{
int i,addr;
unsigned short *data;
addr = src;
//printf("flash read srcaddr == %x \n",addr);
NorFlashRdData(addr ,(unsigned short *)dest, bytecnt/2 +1);
}
/* S29GL064A90_16x1_ewrite():
* Erase all sectors that are part of the address space to be written,
* then write the data to that address space. This is basically a
* concatenation of the above erase & write done in one step. This is
* necessary primarily for re-writing the bootcode; because after the boot
* code is erased, there is nowhere to return so the re-write must be done
* while executing out of ram also. It is only needed in systems that are
* executing the monitor out of the same device that is being updated.
*/
int
S29GL064A90_16x1_ewrite(struct flashinfo *fdev,uchar *destA,uchar *srcA,
long bytecnt)
{
int sector, i;
void (*reset)();
uchar *src, *dest;
return 0;//stone debug
}
/* EndS29GL064A90_16x1_ewrite():
* Function place holder to determine the end of the above function.
*/
void
EndS29GL064A90_16x1_ewrite(void)
{}
/* S29GL064A90_16x1_lock():
*/
int
S29GL064A90_16x1_lock(struct flashinfo *fdev,int snum,int operation)
{
return 0;//stone debug
}
/* EndS29GL064A90_16x1_lock():
* Function place holder to determine the end of the above function.
*/
void
EndS29GL064A90_16x1_lock(void)
{
}
/* S29GL064A90_16x1_type():
* Run the AUTOSELECT algorithm to retrieve the manufacturer and
* device id of the flash.
*/
int
S29GL064A90_16x1_type(struct flashinfo *fdev)
{
WORD man, dev,block_lock_cfg;
//stone add
NorFlashPifInit();
fdev->id = NorFlashRdID();
return((int)(fdev->id));
}
/* EndS29GL064A90_16x1_type():
* Function place holder to determine the end of the above function.
*/
void
EndS29GL064A90_16x1_type(void)
{}
/**************************************************************************
**************************************************************************
*
* The remainder of the code in this file can be included if the
* target configuration is such that this 28F640 device is the only
* real flash device in the system that is to be visible to the monitor.
*
**************************************************************************
**************************************************************************
*/
#ifdef SINGLE_FLASH_DEVICE
/* FlashNamId[]:
* Used to correlate between the ID and a string representing the name
* of the flash device.
* Note that this table (and the case statement in FlashBankInit())
* allow a 28F128 flash ID to sneak by... This is to allow a 28F128
* device to be put in the footprint of a 28F640, but with the upper
* half of the device inaccessible (some CSB360 boards).
*/
struct flashdesc FlashNamId[] = {
{ INTEL_28F640, "INTEL-28F640" },
{ ST_M58LW064D, "SGS_THOMPSON-M58LW064D" },
{ INTEL_DT28F640J5, "INTEL-DT28F640J5" },
{ INTEL_DT28F128J5, "INTEL-28F128 (half)" },
{ S29GL128M90, "SPANSION S29GL128M90"},
{ SST39VF3201, "SST39VF3201"},
{ S29GL064A90, "S29GL064A90"},
{ 0, 0 },
};
int
FlashBankInit(struct flashinfo *fbnk,int snum)
{
uchar *saddr,*tmp;
int i, msize;
struct sectorinfo *sinfotbl;
unsigned short *data = 0xa0300000;
/* Based on the flash bank ID returned, load a sector count and a
* sector size-information table...
*/
flashtype(fbnk);
switch(fbnk->id) {
case ST_M58LW064D:
case INTEL_28F640:
case INTEL_DT28F640J5:
fbnk->sectorcnt = 64;
break;
case INTEL_DT28F128J5:
case ST_M25P64:
fbnk->sectorcnt = 128;
break;
// case S29GL128M90:
// fbnk->sectorcnt = 256;
// break;
case SST39VF3201: //jason add
fbnk->sectorcnt = 64;
// printf("SST39VF3201 flash program: flashid is %08lx\n", fbnk->id);
break;
case S29GL064A90: //jason add
fbnk->sectorcnt = 128;
// printf("S29GL064A90 flash program: flashid is %08lx\n", fbnk->id);
break;
default:
printf("Unrecognized flashid: 0x%08lx\n",fbnk->id);
return(-1);
break;
}
/* Create the per-sector information table. The size of the table
* depends on the number of sectors in the device...
*/
if (fbnk->sectors)
free((char *)fbnk->sectors);
msize = fbnk->sectorcnt * (sizeof(struct sectorinfo));
sinfotbl = (struct sectorinfo *)malloc(msize);
if (!sinfotbl) {
printf("Can't allocate space for flash sector information\n");
return(-1);
}
fbnk->sectors = sinfotbl;
/* Using the above-determined sector count, build the sector
* information table as part of the flash-bank structure. For
* this set of devices, all sectors are the same size (0x20000).
*/
saddr = fbnk->base;
for(i=0;i<fbnk->sectorcnt;i++) {
fbnk->sectors[i].snum = snum+i;
fbnk->sectors[i].size = NOR_FLASH_BYTES_PER_SECTOR;
fbnk->sectors[i].begin = saddr;
fbnk->sectors[i].end =
fbnk->sectors[i].begin + fbnk->sectors[i].size - 1;
if(i ==fbnk->sectorcnt )
{
fbnk->sectors[i].protected = 1;
}
else{
fbnk->sectors[i].protected = 0;
}
saddr += NOR_FLASH_BYTES_PER_SECTOR;
}
fbnk->end = saddr-1;
return(fbnk->sectorcnt);
}
/* FlashInit():
* Initialize data structures for each bank of flash...
*/
int
FlashInit(void)
{
int snum;
struct flashinfo *fbnk;
snum = 0;
FlashCurrentBank = 0;
fbnk = &FlashBank[0];
//printf("flash init \n");
fbnk->device_name = malloc(20);
//printf("get device name\n");
strcpy(fbnk->device_name, "nor");
boot_device_name = fbnk->device_name;
//printf("boot device name = %s\n",boot_device_name);
fbnk->base = (unsigned char *)FLASH_BANK0_BASE_ADDR;
fbnk->width = FLASH_BANK0_WIDTH;
fbnk->fltype = S29GL064A90_16x1_type;
fbnk->flerase = S29GL064A90_16x1_erase;
fbnk->flwrite = S29GL064A90_16x1_write;
fbnk->flread = S29GL064A90_16x1_read;
fbnk->flewrite = S29GL064A90_16x1_ewrite;
fbnk->fllock = S29GL064A90_16x1_lock;
snum += FlashBankInit(fbnk,snum);
sectorProtect(FLASH_PROTECT_RANGE,1);
return(0);
}
#endif /* SINGLE_FLASH_DEVICE */
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -