📄 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 "mx21.h"
#include "common.h"
#include "ARM920T.h"
#ifndef TRUE
#define TRUE (1 == 1)
#endif
#ifndef FALSE
#define FALSE (1 == 2)
#endif
// ***************************************************************************
// macros
// ***************************************************************************
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
// ***************************************************************************
// definitions
// ***************************************************************************
#define FLASH_DQ7_2X16 ((1 << (7 + 16)) | (1 << 7))
#define FLASH_DQ5_2X16 ((1 << (5 + 16)) | (1 << 5))
#define TACC 55 // Asyn. Access Time @ 54MHz
#define TIACC 87.5 // Syn. Access Time @ 54MHz
#define MX21_MEM_ADDR_CS0 0xC8000000
#define MX21_MEM_ADDR_CS1 0xCC000000
#define MX21_MEM_ADDR_CS2 0xD0000000
#define MX21_MEM_ADDR_CS3 0xD1000000
#define MX21_MEM_ADDR_CS4 0xD2000000
#define MX21_MEM_ADDR_CS5 0xD3000000
// ***************************************************************************
// types
// ***************************************************************************
// ***************************************************************************
// structures
// ***************************************************************************
// ***************************************************************************
// data
// ***************************************************************************
// ***************************************************************************
// function implementations
// ***************************************************************************
U32 LoadMultiple(void)
{
U32 i;
U32* dWalk;
U32 dStart;
U32 result = 0;
dWalk = malloc(sizeof(*dWalk * 0xFF));
dStart = (U32)dWalk;
__asm
{
MOV R0, 0xC8000000;
}
for (i = 0; i < 0xFF; i++)
{
__asm
{
LDMIA R0!, {r1-r8};
STMIA dWalk, {r1-r8};
}
dWalk += 8;
}
dWalk = (U32*)dStart;
for ( i = 0; i <= 0xFF; i++)
{
result += *dWalk;
dWalk++;
}
return result;
}
// ***************************************************************************
//
// Function: FlashConfigBurst
//
// This function configures the flash burst mode parameters.
//
// Parameters: BOOL bBurstMode burst mode on/off
// BOOL bRisingClock use rising CLK edge?
// BOOL bEarlyReady RDY one CLK before data?
// U32 nClk Burst Clock frequency (<= 54MHz)
// U32 sAddress base Address of the Flash
//
// Return Value: void
// BOOL fBurst Burst Mode Status
// (True - Sync | False - Async)
//
// ***************************************************************************
void FlashConfigBurst(BOOL bBurstMode,
BOOL bRisingClock,
BOOL bEarlyReady,
U32 nClk,
U32 sAddress)
{
volatile U32* pBase;
U32 nAddr;
U32 fWsc;
// Calculate Configuration Register address based on mode
// ******************************************************
if (bBurstMode)
{
fWsc = ((TIACC * nClk + 999) / 1000);
// fWsc = 3;
nAddr = (0 << 19) | // synchronous mode
((bEarlyReady ? 0 : 1) << 18) | // RDY one CLK before?
((bRisingClock ? 1 : 0) << 17) | // CLK edge
(0 << 15) | // continuous mode
((fWsc - 2) << 12)| // wait state bits
(0x555 << 0);
}
else
{
nAddr = (1 << 19) | // asynchronous mode
0x555; // fixed
}
// Reset flash devices before writing configuration sequence
// *********************************************************
pBase = (volatile U32*) sAddress;
*(pBase + 0x000) = 0x00f000f0;
*(pBase + 0x555) = 0x00aa00aa;
*(pBase + 0x2aa) = 0x00550055;
*(pBase + nAddr) = 0x00c000c0;
}
// ***************************************************************************
//
// Function: BoardControlBurstMode
//
// This function enabled or disables burst mode with the
// MX1 processor and with the memory.
//
// Parameters: BOOL bOnOff burst mode on/off
// U32 sAddress Base Address of the Flash
// U32 hclk system clock frequency
// U32 fclk burst clock frequency (<= 54Mhz)
//
// Return Value: BOOL TRUE if successful, FALSE on error
//
// ***************************************************************************
BOOL BoardControlBurstMode(BOOL bOnOff, U32 sAddress, U32 hClk, U32 fClk)
{
U32 nCsHi;
U32 nCsLo;
U32 nWsc;
U32 nBcd = 0;
U32 nOea;
U32 nClk = 0;
if (bOnOff)
{
// Calculate MX1 burst clock divisor based on HCLK frequency and
// input memory clock frequency parameter. Adjust used memory clock.
// *************************************************************
nBcd = (hClk + (fClk - 1)) / fClk;
nClk = (hClk / nBcd);
// Calculate number of CLK cycles required for delaying by Tiacc
// in Tclk increments.
// ************************************************************
nWsc = ((TIACC * hClk + 999) / 1000);
// Enable OE only one half-clock before sampling data (one half
// clock plus first CLK plus wait states minus one half clock)
// ************************************************************
// nOea = MIN((nWait + 1) * 2, 0x0f);
}
else
{
nWsc = ((TACC * hClk + 999) / 1000) - 10;
//nWsc = ((TACC * hClk + 999) / 1000);
}
// Configure burst mode with flash memory. Use the number of wait
// states calculated above. For this board, we use the rising CLK
// edge and configure the RDY pin to become active with the data.
// **************************************************************
FlashConfigBurst(bOnOff,TRUE,TRUE,nClk,sAddress);
// Configure burst mode with MX1 (chip select registers)
// *****************************************************
if (bOnOff)
{
// Chip select control register for synchronous mode
// *************************************************
nCsHi = (0 << (63 - 32)) | // DTACK_SEL
((nBcd - 1) << (60 - 32)) | // BCD
(0 << (56 - 32)) | // BCS
(0 << (54 - 32)) | // PSZ
(0 << (53 - 32)) | // PME
(1 << (52 - 32)) | // SYNC
(1 << (48 - 32)) | // DOL
(0 << (46 - 32)) | // CNC
(nWsc << (40 - 32)) | // WSC
(0 << (36 - 32)) | // WWS
(0 << (32 - 32)); // EDC
nCsLo = (0 << 28) | // OEA
(0 << 24) | // OEN
(0 << 20) | // WEA
(0 << 16) | // WEN
(0 << 12) | // CSA
(0 << 11) | // EBC
(6 << 8) | // DSZ
(0 << 6) | // SP
(0 << 4) | // WP
(1 << 0); // CSEN
}
else
{
// Chip select control register for asynchronous mode
// **************************************************
nCsHi = (0 << (63 - 32)) | // DTACK_SEL
(0 << (60 - 32)) | // BCD
(0 << (56 - 32)) | // BCS
(0 << (54 - 32)) | // PSZ
(0 << (53 - 32)) | // PME
(0 << (52 - 32)) | // SYNC
(0 << (48 - 32)) | // DOL
(0 << (46 - 32)) | // CNC
(nWsc << (40 - 32)) | // WSC
(0 << (36 - 32)) | // WWS
(0 << (32 - 32)); // EDC
nCsLo = (0 << 28) | // OEA
(0 << 24) | // OEN
(0 << 20) | // WEA
(0 << 16) | // WEN
(0 << 12) | // CSA
(0 << 11) | // EBC
(6 << 8) | // DSZ
(0 << 6) | // SP
(0 << 4) | // WP
(0 << 1) | // PA
(1 << 0); // CSEN
}
*(volatile U32*)WEIM_CS0U = nCsHi;
*(volatile U32*)WEIM_CS0L = nCsLo;
*(volatile U32*)WEIM_CS0U = 0x00000900;
// *(volatile U32*)WEIM_CS0L = 0x00000D01;
*(volatile U32*)WEIM_CS0L = 0x00000501;
return bOnOff;
}
// ***************************************************************************
//
// 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
//
// ***************************************************************************
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
BOOL bFailTotal;
BOOL bDone;
BOOL bFail;
U32 nWalk;
U32 nPoll;
U32 nDone;
U32 nAddress;
U32 i=0;
// Check the Flash Starting Address
pBase = (volatile U32*)(sAddress & 0xFE000000);
// 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 = sAddress + sizeof(*pData)*(nData - 1);
printf("\nProgramming at [0x%08X - 0x%08X]...\n", sAddress, nAddress);
while (nWalk <= nAddress)
{
i++;
if( (i&0xFFFF) == 0 )
{
printf("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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -