📄 norflash_rw.txt
字号:
pWalk = (U32*) sAddress;
pWalkSrc = (U32*) pData;
// nAddress = (((nData - 1) / sizeof(*pBase)) + 1) * sizeof(*pBase) + sAddress;
nAddress = sAddress + sizeof(*pData)*(nData - 1);
//printf("\nProgramming at [0x%08X - 0x%08X]...\n", sAddress, nAddress);
EUARTputString("\nProgramming at [0x");
EUARTputHex((sAddress>>24)&0xff);
EUARTputHex((sAddress>>16)&0xff);
EUARTputHex((sAddress>>8)&0xff);
EUARTputHex(sAddress&0xff);
EUARTputString(" - 0x");
EUARTputHex((nAddress>>24)&0xff);
EUARTputHex((nAddress>>16)&0xff);
EUARTputHex((nAddress>>8)&0xff);
EUARTputHex(nAddress&0xff);
EUARTputString("]\n");
while (nWalk <= nAddress)
{
i++;
if( (i&0xFFFF) == 0 )
{
//printf("P");
EUARTputString("P");
}
// 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;
//printf("\nFlash Write Complete\n");
EUARTputString("\nFlash Write Complete\n");
// return bFailTotal ? 0 : nDone;
}
///@brief This function erases all flash memory sectors
///
///@param sAddress start address for erase
///@return BOOL chip erase success?
BOOL FlashChipErase(U32 sAddress)
{
volatile U32* pBase;
BOOL bDone;
BOOL bFail;
U32 nPoll;
U32 i = 0;
// Check the Flash Starting Address
pBase = (volatile U32*)(sAddress & 0xFE000000);
// 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");
EUARTputString("Chip Erasing...\n");
// Data polling algorithm for erase operation
// ******************************************
bDone = FALSE;
bFail = FALSE;
while ((!bDone) && (!bFail))
{
i++;
if ((i & 0xFFFF) == 0)
{
//printf(".");
EUARTputString(".\n");
}
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");
EUARTputString("\nChip Erase Complete\n");
return bFail;
}
///@brief This function erases all flash memory sectors overlapping
/// the address range specified in the parameters.
///
///@param sAddress start address for erase
///@param nAddress end address for erase
///
///@return 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;
BOOL bFailTotal;
BOOL bDone;
BOOL bFail;
U32 nWalk;
U32 nSize;
U32 nPoll;
U32 nDone;
U32 nSec;
U32 SA;
U32 i = 0;
// Check the Flash Starting Address
pBase = (volatile U32*)(sAddress & 0xFE000000);
// 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);
EUARTputString("\nFlash Sector Erase at [0x");
EUARTputHex((sAddress>>24)&0xff);
EUARTputHex((sAddress>>16)&0xff);
EUARTputHex((sAddress>>8)&0xff);
EUARTputHex(sAddress&0xff);
EUARTputString(" - 0x");
EUARTputHex((nAddress>>24)&0xff);
EUARTputHex((nAddress>>16)&0xff);
EUARTputHex((nAddress>>8)&0xff);
EUARTputHex(nAddress&0xff);
EUARTputString("]\n");
for (SA = 1; SA <= 270; SA++)
{
if ((SA >= 1 && SA <= 8) || (SA >= 262 && 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(".");
EUARTputString(".");
}
i++;
}
nDone += nSize;
nWalk += nSize;
}
nSec += nSize;
}
// Reset flash devices
// *******************
*(pBase + 0x000) = 0x00f000f0;
EUARTputString("\n");
return bFailTotal ? 0 : nDone;
}
///@brief This function read data from flash memory
///
///@param sAddress start address for read
///@param pData data to read
///@param nData number of bytes to read
///
///@return U32 start address for read
U32* FlashRead(U32 sAddress, U32* pData, U32 nData)
{
U32 nWalk;
U32 nAddress;
U32* dWalk;
U32* sWalk;
U32 i;
nWalk = sAddress;
nAddress = sAddress + nData;
dWalk = (U32*)sAddress;
sWalk = pData;
//printf("Flash Reading at [0x%08X - 0x%08X]...\n", sAddress, nAddress);
// Data Read
// *******************
//pData=memcpy(pData, (U32*) nAddress, nData);
//nDone = nData;
while (nWalk < nAddress)
{
i++;
if ((i & 0xFFFF) == 0)
{
//printf("R");
EUARTputString("R\n");
}
*dWalk = *sWalk;
dWalk++;
sWalk++;
nWalk +=sizeof(*dWalk);
}
//printf("\nFlash Read Complete\n");
EUARTputString("\nFlash Read Complete\n");
return (U32*)sAddress;
}
///@brief Verify after programming
///
///@param fAddress RAM starting address
///@param rAddress Flash starting address to be verified
///@param nWords number of words to check
///
///@return U32 number of programming errors in word
U32 FlashVerify(U32 fAddress, U32 rAddress, U32 nWords)
{
U32 i;
U32 Errors = 0;
U32* fWalk;
U32* rWalk;
U32 nAddress;
fWalk = (U32*)fAddress;
rWalk = (U32*)rAddress;
nAddress = fAddress + (nWords - 1) * sizeof(*fWalk);
//printf("Flash Verifing at [0x%08X - 0x%08X]...\n", fAddress, nAddress);
EUARTputString("\nFlash Verifying at [0x");
EUARTputHex((fAddress>>24)&0xff);
EUARTputHex((fAddress>>16)&0xff);
EUARTputHex((fAddress>>8)&0xff);
EUARTputHex(fAddress&0xff);
EUARTputString(" - 0x");
EUARTputHex((nAddress>>24)&0xff);
EUARTputHex((nAddress>>16)&0xff);
EUARTputHex((nAddress>>8)&0xff);
EUARTputHex(nAddress&0xff);
EUARTputString("]\n");
for (i = 0; i < nWords;i++)
{
if (*fWalk != *rWalk)
{
//printf("Programming Error at 0x%08X\n", (U32)fWalk);
Errors++;
}
else
{
if ((i & 0xFFFF) == 0)
{
//printf("S");
EUARTputString("S");
}
}
fWalk++;
rWalk++;
}
EUARTputString("\nVerify Done.\n");
return Errors;
}
// ***************************************************************************
//
// Function: FlashLoader
//
//
//
// Parameters: U32 rAddress RAM starting address
// U32 fAddress Flash starting address to be programmmed
// U32 nWords number of words to write
//
// Return Value: void
//
// ***************************************************************************
void FlashLoader(U32 fAddress, U32 rAddress, U32 nWords)
{
U32 nAddress;
U32 Errors;
EUARTputString("\nStarting Flash Programming\n");
nAddress = fAddress + (nWords - 1) * sizeof(U32);
if (fAddress == 0xc8300000) {
nAddress = 0xc9ffffff;
FlashSectorErase(fAddress, nAddress);
}
else
FlashSectorErase(fAddress,nAddress);
FlashWrite(fAddress, (U32*)rAddress, nWords);
Errors = FlashVerify(fAddress,rAddress,nWords);
if (Errors)
{
EUARTputString("\nFlash Programming Error:\n Total no. of Errors:");
EUARTputHex((Errors>>24)&0xff);
EUARTputHex((Errors>>16)&0xff);
EUARTputHex((Errors>>8)&0xff);
EUARTputHex(Errors&0xff);
EUARTputString("words(4 bytes)\n");
}
else
{
EUARTputString("\nFlash Programming Complete\n");
}
return;
}
void progFlash(U32 sourceAddr, U32 destinAddr, U32 byteCount)
{
return FlashLoader(destinAddr, sourceAddr, (byteCount+4)/4);
}
/*******************************************************************************
*
* Copyright (C) 2004, FREESCALE INC. All Rights Reserved
*
* FILE NAME : flash_test.c
* DATE CREATED : 09-15-04
*
* DESCRIPTION: Function and Test code for Spansion S29WS256N Flash
* This code will query the burst flash on the Jazz Rev2 board for its manufacturer ID
* AND device ID. If device ID is incorrect, the code will report this failure.
* If manufacturer ID not correct, the code will also report this.
*
*
*
* ****************************
* IMPORTANT NOTE ON FUNCTIONS:
* ****************************
*
* When passing an address to a function, the function assumes that the address
* passed to it is the Flash address as a standard integer, not the System address.
* E.g., regardless of where in the system memory the Flash resides, the functions
* should be passed address values between 0x000000 and 0x7FFFFF. The functions will
* automatically adjust to write or read to the correct system address based off of
* the value of CS_BASE. Address values between 0x000000 and 0x7FFFFF represent the
* entire FLASH (x16) address range. This test code assumes a system with a x32
* FLASH configuration. Thus the functions will convert the x16 FLASH address to the
* appropriate and desired SYSTEM (x32) address.
*
* If a function needs to be passed a sector value, it will accept either the
* NEGATIVE number of the sector or any Flash address within the sector.
*
* Ex: Sector 2 starts at Flash address 0x002000 and ends at 0x002FFF
* Passing -2, 0x002000, 0x002FFF or 0x0023F9 would all work correctly
* Passing 2 would be interpreted as an address in sector 0
*
* The sector value functions will actually also operate correctly when passed
* a system address that points to the sector.
*
* In general though, the intent is that as long as CS_BASE is defined, the function
* user does not need to bother with where the Flash resides in system memory.
*
* Revision history:
* rev 0.0 - original release
* rev 0.1 - updated for i.mx21
*
********************************************************************************
* I N C L U D E F I L E S
*******************************************************************************/
#include "common.h"
#include "tht_memory_map_defines.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Modify SysInit() for different system initialization settings */
extern int SysInit(void);
extern int MemInit(void);
/******************************************************************************
* DEFINES
******************************************************************************/
/* i.MX21 specific defines */
//#define HCLK133MHZ
/***** Critical *****/
// CS_BASE informs the program of the base system address of the Flash
#define CS_BASE (volatile unsigned int *)CS0_BASE_ADDR // Chip select 0, i.mx21
/*************************************************************
********* Spansion S29WS256N Flash Constant Defines **********
*************************************************************/
// Read adjusting for CS_BASE
#define read(x) *(CS_BASE+x)
//reset & unlock writes
#define reset() *CS_BASE=0x00F000F0
#define unlock() *(CS_BASE + 0x555)=0x00AA00AA; *(CS_BASE + 0x2AA)=0x00550055
//manufacturer and device ID values
#define MANU_ID 0x00010001
#define MANU_ID_AD (CS_BASE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -