📄 drv_flash.c
字号:
// ***************************************************************************
//
// Filename: flash.c
//
// Created: Louis Lai (6/20/2003)
//
// Modified: $Author: $ $Date: $
//
// ***************************************************************************
// ***************************************************************************
// pragmas
// ***************************************************************************
// ***************************************************************************
// includes
// ***************************************************************************
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "drv_defs.h"#include "flash.h"
#if 1
void FlashSearchSector(u32 sAddress, u32 *Sec_start, u32 *Sec_size)
{
u32 SA;
u32 base, nSize;
base = FLASH_BASE;
for (SA = 0; SA <= 133; SA++)
{
if ((SA >= 0 && SA <= 3) || (SA >= 130 && SA <= 133))
{
nSize = 0x4000*4;
}
else
{
nSize = 0x10000*4;
}
if ((sAddress >= base)&&(sAddress < (base+nSize))){
*Sec_start = base;
*Sec_size = nSize/4;
break;
}
base += nSize;
}
}
#else
void FlashSearchSector(u32 sAddress, u32 *Sec_start, u32 *Sec_size)
{
u32 SA;
u32 base, nSize;
base = FLASH_BASE;
for (SA = 1; SA <= 270; SA++)
{
if ((SA >= 1 && SA <= 8) || (SA >= 263 && SA <= 270))
{
nSize = 0x1000*4;
}
else
{
nSize = 0x8000*4;
}
if ((sAddress >= base)&&(sAddress < (base+nSize))){
*Sec_start = base;
*Sec_size = nSize/4;
break;
}
base += nSize;
}
}
#endif
int FlashEraseSector(u32 sAddress)
{
volatile u32* pBase;
volatile u32* pWalk;
int bFailTotal;
int bDone;
int bFail;
u32 nPoll;
u32 nDone;
// This sector overlaps the address range. Erase it
// ************************************************
pWalk = (volatile u32*) sAddress;
pBase = (u32*)FLASH_BASE;
// Execute "normal" sector erase algorithm
// ***************************************
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pBase + 0x555) = 0x00800080;
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pWalk) = 0x00300030;
// Data polling algorithm for erase operation
// ******************************************
bDone = FALSE;
bFail = FALSE;
while ((!bDone) && (!bFail))
{
nPoll = *(pWalk);
if (((~nPoll) & FLASH_DQ7_2X16) == 0)
{
bDone = TRUE;
}
else if ((nPoll & FLASH_DQ5_2X16) == FLASH_DQ5_2X16)
{
nPoll = *(pWalk);
if (((~nPoll) & FLASH_DQ7_2X16) == 0)
{
bDone = TRUE;
}
else
{
bFail = TRUE;
bFailTotal = TRUE;
}
}
}
return (bDone?0:1);
}
// ***************************************************************************
//
// Function: FlashWrite
//
// This function programs data into flash memory. It is
// assumed that the memory has been erased before calling
// this function.
//
//
// Parameters: U32 sAddress start address for write
// U32* pData data to write
// U32 nData number of words to write
//
// Return Value: U32 number of bytes written or zero on error
//
// ***************************************************************************
/*U32 FlashWrite(U32 sAddress,
void* pData,
U32 nData)*/
void FlashWrite(u32 sAddress, u32* pData, u32 nData)
{
volatile u32* pBase; // base address of the selected memory bank
volatile u32* pWalk; // flash programming pointer
u32* pWalkSrc; // ram source pointer
int bFailTotal;
int bDone;
int bFail;
u32 nWalk;
u32 nPoll;
u32 nDone;
u32 nAddress;
u32 i=0;
u32 Flash_Write = 0x27272727;
// Check the Flash Starting Address
pBase = (volatile u32*)FLASH_BASE;
// Reset flash devices before starting programming sequence
// ********************************************************
*(pBase + 0x000) = 0x00f000f0;
// execute unlock bypass sequence
// ******************************************
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pBase + 0x555) = 0x00200020;
// start the flash programming algorithm
// **********************************************
nWalk = sAddress;
pWalk = (u32*) sAddress;
pWalkSrc = (u32*) pData;
// nAddress = (((nData - 1) / sizeof(*pBase)) + 1) * sizeof(*pBase) + sAddress;
nAddress = sAddress + sizeof(*pData)*(nData - 1);
while (nWalk <= nAddress){
i++;
if( (i&0xFFFF) == 0 ){
printf("P");
//CheckFlashComplete(Flash_Write);
}
// Execute unlock bypass program algorithm
// ***************************************
*(pBase + 0x555) = 0x00a000a0;
*(pWalk) = *(pWalkSrc);
// Data polling algorithm for program operation
// ********************************************
bDone = FALSE;
bFail = FALSE;
bFailTotal = FALSE;
while ((!bDone) && (!bFail))
{
nPoll = *(pWalk);
if (((nPoll ^ *(pWalkSrc)) & FLASH_DQ7_2X16) == 0){
bDone = TRUE;
}
else if ((nPoll & FLASH_DQ5_2X16) == FLASH_DQ5_2X16){
nPoll = *(pWalk);
if (((nPoll ^ *(pWalkSrc)) & FLASH_DQ7_2X16) == 0){
bDone = TRUE;
}
else{
bFail = TRUE;
bFailTotal = TRUE;
}
}
}
if (bDone == TRUE){
nDone += sizeof(*pWalk);
}
nWalk += sizeof(*pWalk);
pWalk++;
pWalkSrc++;
}
// Cancel unlock bypass mode
// ************************************************
*(pBase + 0x000) = 0x00900090;
*(pBase + 0x000) = 0x00000000;
// Reset flash devices
// *******************
*(pBase + 0x000) = 0x00f000f0;
}
u32 FlashVerify(u32 fAddress, u32 rAddress, u32 nWords)
{
u32 i;
u32 Errors = 0;
u32* fWalk;
u32* rWalk;
u32 nAddress;
u32 Flash_Verify = 0x37373737;
fWalk = (u32*)fAddress;
rWalk = (u32*)rAddress;
nAddress = fAddress + (nWords - 1) * sizeof(*fWalk);
// printf("Flash Verifing at [0x%08X - 0x%08X]...\n", fAddress, nAddress);
for (i = 0; i < nWords;i++)
{
if (*fWalk != *rWalk)
{
Errors++;
}
fWalk++;
rWalk++;
}
return Errors;
}
// ***************************************************************************
//
// Function: FlashChipErase
//
// This function erases all flash memory sectors
//
//
// Parameters: U32 sAddress start address for erase
//
// Return Value: BOOL chip erase success?
//
//
// ***************************************************************************
int FlashChipErase(u32 sAddress)
{
volatile u32* pBase;
int bDone;
int bFail;
u32 nPoll;
u32 i = 0;
// Check the Flash Starting Address
pBase = (volatile u32*)FLASH_BASE;
// Reset flash devices before chip erase
// ***************************************
*(pBase + 0x000) = 0x00f000f0;
// Execute "normal" chip erase algorithm
// ***************************************
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pBase + 0x555) = 0x00800080;
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pBase + 0x555) = 0x00100010;
printf("Chip Erasing...\n");
// Data polling algorithm for erase operation
// ******************************************
bDone = FALSE;
bFail = FALSE;
while ((!bDone) && (!bFail)){
i++;
if ((i & 0xFFFF) == 0){
printf(".");
}
nPoll = *(pBase);
if (((~nPoll) & FLASH_DQ7_2X16) == 0){
bDone = TRUE;
}
else if ((nPoll & FLASH_DQ5_2X16) == FLASH_DQ5_2X16){
nPoll = *(pBase);
if (((~nPoll) & FLASH_DQ7_2X16) == 0){
bDone = TRUE;
}
else{
bFail = TRUE;
}
}
}
// Reset flash evices
// *******************
*(pBase + 0x000) = 0x00f000f0;
printf("\nChip Erase Complete\n");
return bFail;
}
// ***************************************************************************
//
// Function: FlashSectorErase
//
// This function erases all flash memory sectors overlapping
// the address range specified in the parameters.
//
//
// Parameters: U32 sAddress start address for erase
// U32 nAddress end address for erase
//
// Return Value: U32 number of bytes erased (rounded up to
// next sector limit), or zero on error
//
// ***************************************************************************
u32 FlashSectorErase(u32 sAddress, u32 nAddress)
{
volatile u32* pBase;
volatile u32* pWalk;
int bFailTotal;
int bDone;
int bFail;
u32 nWalk;
u32 nSize;
u32 nPoll;
u32 nDone;
u32 nSec;
u32 SA;
u32 i = 0;
u32 Flash_Erase = 0x17171717;
// Check the Flash Starting Address
pBase = (volatile u32*)FLASH_BASE;
// Reset flash devices before starting erase sequences
// ***************************************************
*(pBase + 0x000) = 0x00f000f0;
nSec = (u32)pBase;
nDone = 0;
nWalk = sAddress;
printf("Sector Erase at [0x%08X - 0x%08X]...\n",sAddress, nAddress);
for (SA = 1; SA <= 270; SA++)
{
if ((SA >= 1 && SA <= 8) || (SA >= 263 && SA <= 270))
{
nSize = 0x1000*4;
}
else
{
nSize = 0x8000*4;
}
if ((nSec <= nWalk) && (nSec + nSize > nWalk) && (nSec <= nAddress))
{
// This sector overlaps the address range. Erase it
// ************************************************
pWalk = (volatile u32*) nWalk;
// Execute "normal" sector erase algorithm
// ***************************************
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pBase + 0x555) = 0x00800080;
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pWalk) = 0x00300030;
// Data polling algorithm for erase operation
// ******************************************
bDone = FALSE;
bFail = FALSE;
while ((!bDone) && (!bFail))
{
nPoll = *(pWalk);
if (((~nPoll) & FLASH_DQ7_2X16) == 0)
{
bDone = TRUE;
}
else if ((nPoll & FLASH_DQ5_2X16) == FLASH_DQ5_2X16)
{
nPoll = *(pWalk);
if (((~nPoll) & FLASH_DQ7_2X16) == 0)
{
bDone = TRUE;
}
else
{
bFail = TRUE;
bFailTotal = TRUE;
}
}
if ( (i &= 0xFFFF) ==0)
{
printf(".");
//CheckFlashComplete(Flash_Erase);
}
i++;
}
nDone += nSize;
nWalk += nSize;
}
nSec += nSize;
}
// Reset flash devices
// *******************
*(pBase + 0x000) = 0x00f000f0;
return bFailTotal ? 0 : nDone;
}
int FlashProgram(u32 sAddress, u32* pData, u32 nData)
{
static char sector[0x10000*4];
u32 Sec_start, Sec_size, AvailableBytes;
u32 offset;
int repeat;
char *src;
int error;
error = 0;
repeat = nData * 4;
while(repeat > 0){
FlashSearchSector(sAddress, &Sec_start, &Sec_size);
offset = sAddress - Sec_start;
AvailableBytes = Sec_size*4 - offset;
if (offset == 0){
if (repeat >= AvailableBytes){
// src = (char *)pData;
src = §or[0];
memcpy(src, (char *)pData, Sec_size*4);
}
else{
src = §or[0];
memcpy(src, (char *)Sec_start, Sec_size*4);
memcpy(src, (char *)pData, repeat);
}
}
else{
if (repeat >= AvailableBytes){
src = §or[0];
memcpy(src, (char *)Sec_start, Sec_size*4);
memcpy((src+offset), pData, AvailableBytes);
}
else{
src = §or[0];
memcpy(src, (char *)Sec_start, Sec_size*4);
memcpy((src+offset), pData, repeat);
}
}
FlashEraseSector(Sec_start);
FlashWrite(Sec_start, (u32 *)src, Sec_size);
error += FlashVerify(Sec_start, (u32)src, Sec_size);
repeat -= AvailableBytes;
sAddress += AvailableBytes;
pData += (AvailableBytes/4);
}
return error;
}
// ***************************************************************************
//
// Function: FlashRead
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -