📄 flash.c
字号:
/************************************************************************
flash.c
Copyright 1999 by cdma all right reserved
Author: chenhong
Date: 1999.9.13
Description: the source file of flash driver for CHM
Note:
*************************************************************************/
#include "flash.h"
/*************************<< variables declaration >>********************/
/* the two array is too big to fit the stack,so we define
them to static global variable */
/*************************<< Functions Prototype >>**********************/
/* static int FlashEraseChip(void); */ /* screen by zoutl 2003-3-14 10:21*/ /*Note! 28f640 not support it*/
int FlashEraseSector(ULONG Offset);
static int Write_Flash(ULONG Offset, ULONG DataLen, UCHAR *BufAddr);
int FlashWrite(ULONG Offset, ULONG DataLen, UCHAR *BufAddr);
int FlashRead(ULONG Offset, ULONG DataLen, UCHAR *BufAddr);
/************************************************************************
description: Read a value from an 8-bit memory-mapped register
input:
Addr: ULONG, Address of register to read from
output:
return value:
register value: ULONG
************************************************************************/
static USHORT ReadReg(UCHAR *Addr)
{
return (*Addr);
}
/************************************************************************
description: Write a value to an 8-bit register
input:
Addr : ULONG, Address of register to write to
value: ULONG, Value to write
output:
return value:
************************************************************************/
static void WriteReg(UCHAR *Addr, UCHAR Value)
{
*Addr = Value;
return;
}
/************************************************************************
description: Erases FLASH
input:
output:
return value:
1: int, FLASH_OK means operate is success
0: int, FLASH_FAIL means operate is fail
************************************************************************/
/* screen by zoutl 2003/2/21 */
/*
static int FlashEraseChip(void)
{
ULONG Loop;
ULONG BaseAddr;
UCHAR TempReg;
BaseAddr = FLASH_BASE;
WriteReg((UCHAR *)(BaseAddr), 0x30);
WriteReg((UCHAR *)(BaseAddr), 0xD0);
for(Loop = 0; Loop < FLASH_ERASE_CHIP_LOOP; Loop ++)
{
TempReg = ReadReg((UCHAR *)(BaseAddr));
TempReg &= 0x80;
if(TempReg == 0x80)
break;
}
if(Loop == FLASH_ERASE_CHIP_LOOP)
return FLASH_FAIL;
if((ReadReg((UCHAR *)BaseAddr) & 0x38) != 0)
return FLASH_FAIL;
WriteReg((UCHAR *)(BaseAddr),0xff);
return FLASH_OK;
}
*/
/************************************************************************
description: Erases FLASH's one sector
input:
Offset: ULONG, Offset from base to start read
output:
return value:
1: int, FLASH_OK means operate is success
0: int, FLASH_FAIL means operate is fail
************************************************************************/
int FlashEraseSector(ULONG Offset)
{
ULONG Loop;
ULONG BaseAddr;
UCHAR TempReg;
BaseAddr = FLASH_BASE;
WriteReg((UCHAR *)(BaseAddr+Offset), 0x20);
WriteReg((UCHAR *)(BaseAddr+Offset), 0xD0);
for(Loop = 0; Loop < FLASH_ERASE_SECTOR_LOOP; Loop ++)
{
TempReg = ReadReg((UCHAR *)(BaseAddr));
TempReg &= 0x80;
if(TempReg==0x80)
break;
}
if(Loop == FLASH_ERASE_SECTOR_LOOP)
return FLASH_FAIL;
if((ReadReg((UCHAR *)BaseAddr) & 0x38) != 0) /* modified by zoutl 2003/2/21 */
return FLASH_FAIL;
WriteReg((UCHAR *)(BaseAddr), 0xff); /*return read array mode*/
return FLASH_OK;
}
/************************************************************************
description: delay function.
input:
NuSecs: ULONG, the number of microsecond delay.
output:
return value:
************************************************************************/
void Delay(ULONG NuSecs) /*not used*/
{
ULONG Loop;
ULONG Count;
ULONG Seed;
Seed = 0x1234;
while(NuSecs--)
{
for (Loop=0; Loop<30; Loop++)
Count = Loop * Seed;
}
}
/************************************************************************
description: This function is used to read data in the FLASH.
input:
Offset : Offset from base to start read
BufAddr : Pointer to buffer which will store data
DataLen : Number of USHORT(2 bytes) to be read
output:
return value:
1: int, FLASH_OK means operate is success
************************************************************************/
int FlashRead(ULONG Offset, ULONG DataLen, UCHAR *BufAddr)
{
ULONG Loop;
UCHAR *Addr;
/*check the input parameter*/
if (Offset < 0)
return FLASH_FAIL;
if ((Offset + DataLen) > FLASH_DRV_SIZE)
return FLASH_FAIL;
if(BufAddr == NULL)
return FLASH_FAIL;
Addr = (UCHAR *)(FLASH_BASE + Offset);
for(Loop = 0; Loop < DataLen; Loop ++)
BufAddr[Loop] = Addr[Loop];
return FLASH_OK;
}
/************************************************************************
description: This function is used to store data in the FLASH.
it require the flash is already erase ,and we use
buffer program mode.
input:
Offset : Offset from base to start programming
BufAddr : Pointer to buffer which contains data
DataLen : Number of USHORT(2 bytes) to be written
output:
return value:
1: int, FLASH_OK means operate is success
0: int, FLASH_FAIL means operate is fail
************************************************************************/
static int Write_Flash(ULONG Offset, ULONG DataLen, UCHAR *BufAddr)
{
ULONG Count;
ULONG CurrentDataLen;
ULONG Loop;
ULONG BlockRemainWord;
ULONG WriteWordCount =0; /* modified by zoutl 2003/2/21 */
ULONG BaseAddr;
UCHAR *Start;
Count = 0;
CurrentDataLen = 0;
BaseAddr = FLASH_BASE;
Start = (UCHAR *)(BaseAddr + Offset);
BlockRemainWord = FLASH_UNIT_UBYTE - ((Offset & ~FLASH_MASK));
do
{
WriteReg((UCHAR *)(Start),0xe8); /*write to buffer program mode*/
for(Loop = 0; Loop < FLASH_WRITE_LOOP; Loop ++) /* set time out circle*/
{
if((ReadReg((UCHAR *)(BaseAddr)) & 0x80) == 0x80)
break;
}
if(Loop == FLASH_WRITE_LOOP)
{
printf("Start is 0x%x",(unsigned int)Start); /* modified by zoutl 2003/2/21 */
printf("Write_Flash overrun WRITE_LOOP 1.\n");
return FLASH_FAIL;
}
/*******************<<judge>>********************************/
/*judge whether next write will beyond the end of program? or whether next write will beyond the block*/
if(((CurrentDataLen + BUFFER_UBYTE_NUM) >= DataLen)||(BlockRemainWord <= BUFFER_UBYTE_NUM))
{
if((CurrentDataLen + BUFFER_UBYTE_NUM) >= DataLen)
{
WriteWordCount = (DataLen-CurrentDataLen) - 1;
}
if (BlockRemainWord <= (DataLen-CurrentDataLen))
{
WriteWordCount = BlockRemainWord - 1;
BlockRemainWord = FLASH_UNIT_UBYTE; /*for next blank*/
}
}
else
{
WriteWordCount = BUFFER_UBYTE_NUM - 1; /*write USHORT(2 byte) count*/
/* buffer size is 16 word,correspond write 0x00f*/
BlockRemainWord -= BUFFER_UBYTE_NUM;
}
/******************<<end of judge>>**************************/
WriteReg((UCHAR *)(Start), WriteWordCount);
/*issue the count of write to buffer*/
for (Count = 0; Count <= WriteWordCount; Count ++)
{
*Start = BufAddr[CurrentDataLen];
Start++;
CurrentDataLen++;
}
Start--; /*(Start-1) is in block,Start maybe beyond*/
WriteReg((UCHAR *)Start, 0xd0); /*issue the confirm of program buffer to flash*/
Start++;
/*read status rigister*/
for(Loop = 0; Loop < FLASH_WRITE_LOOP; Loop ++)
{
if((ReadReg((UCHAR *)(BaseAddr)) & 0x80) == 0x80)
break;
}
if(Loop == FLASH_WRITE_LOOP)
{
printf("Write_Flash overrun WRITE_LOOP 2.\n");
return FLASH_FAIL;
}
} while(CurrentDataLen < DataLen);
/*read status rigister*/
for(Loop = 0; Loop < FLASH_WRITE_LOOP; Loop ++)
{
if((ReadReg((UCHAR *)(BaseAddr)) & 0x80) == 0x80)
break;
}
if(Loop == FLASH_WRITE_LOOP)
{
printf("Write_Flash overrun WRITE_LOOP 3.\n");
return FLASH_FAIL;
}
if(ReadReg((UCHAR *)(BaseAddr)) & 0x38)
{
printf("Write_Flash comand error\n");
return FLASH_FAIL;
}
/*check the writted data*/
WriteReg((UCHAR *)(BaseAddr), 0xff); /*return read array mode*/
Start = (UCHAR *)(BaseAddr + Offset);
for(Count = 0; Count < DataLen; Count ++)
{
if(Start[Count] != BufAddr[Count])
{
printf("Write_Flash read != write error.\n");
return FLASH_FAIL;
}
}
return FLASH_OK;
}
/************************************************************************
description: This function is used to store data in the FLASH.
input:
Offset : Offset from base to start programming
BufAddr : Pointer to buffer which contains data
DataLen : Number of USHORT(2 bytes) to be written
output:
return value:
1: int, FLASH_OK means operate is success
0: int, FLASH_FAIL means operate is fail
************************************************************************/
int FlashWrite(ULONG Offset, ULONG DataLen, UCHAR *BufAddr)
{
int RetVal;
ULONG OffsetStart;
ULONG DataLenStart;
UCHAR *Start;
ULONG Loop;
/*check the input parameter*/
if (Offset < 0)
{
printf("Offset less than zero\n");
return FLASH_FAIL;
}
if ((Offset + DataLen) > FLASH_DRV_SIZE)
{
printf("Offset add Datalen large than FLASH_DRV_SIZE\n");
return FLASH_FAIL;
}
if(BufAddr == NULL)
{
printf("BufAddr is Null\n");
return FLASH_FAIL;
}
/* 2000/2/26 adding by chenhong to increase init file system speed.
because it should call flashwrite() 128 times to write some
bytes in different address in same bank of flash, so we can
write flash directly and not erase the bank.*/
Start = (UCHAR *)(FLASH_BASE + Offset);
for(Loop = 0; Loop < DataLen; Loop++)
{
if(Start[Loop] != BufAddr[Loop])
break;
}
if(Loop == DataLen)
return FLASH_OK;
for(Loop = 0; Loop < DataLen; Loop++)
{
if(Start[Loop] != 0xff)
break;
}
if(Loop == DataLen)
{
RetVal = Write_Flash(Offset, DataLen, BufAddr);
if (RetVal == -1)
return FLASH_FAIL;
else
return FLASH_OK;
}
/*end of 2000/2/26 adding */
/*store front part of the first sector we'll erase*/
OffsetStart = Offset & FLASH_MASK;
DataLenStart = (Offset & ~FLASH_MASK) ; /* USHORT(2 byte) number */
/*if (DataLenStart != 0)
{
FlashRead(OffsetStart, DataLenStart, BufferStart);
}
*/
/* store back part of the end sector we'll erase */
/* OffsetEnd = Offset + DataLen ;
DataLenEnd = FLASH_UNIT_UBYTE - ((OffsetEnd & ~FLASH_MASK));
if (DataLenEnd != FLASH_UNIT_UBYTE)
{
FlashRead(OffsetEnd, DataLenEnd, BufferEnd);
} */
/* erase all the sector we'll write to */
/* for (Temp = Offset; (Temp & FLASH_MASK) < OffsetEnd; Temp += FLASH_UNIT_BYTE)
{
RetVal = FlashEraseSector(Temp);
if (RetVal == 0)
return FLASH_FAIL;
} */
/* write the flash */
/* if (DataLenStart != 0)
{
RetVal = Write_Flash(OffsetStart, DataLenStart, BufferStart);
if (RetVal == 0)
return FLASH_FAIL;
} */
RetVal = Write_Flash(Offset, DataLen, BufAddr);
if (RetVal == -1)
return FLASH_FAIL;
else
return FLASH_OK;
/* if (DataLenEnd != FLASH_UNIT_UBYTE)
{
RetVal = Write_Flash(OffsetEnd, DataLenEnd, BufferEnd);
if (RetVal == 0)
return FLASH_FAIL;
} */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -