📄 flash_org.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 "tht_memory_map_defines.h"
#include "common.h"
//#define DEBUG
#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
#define TIACC 87 // Syn. Access Time#define HCLK 66 // EIM CLK
#define FCLK 54 // Flash Burst CLK
#define HCLK 66
#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
// ***************************************************************************
// ***************************************************************************
//
// 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 nWaitStates wait states (2..7)
// 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;
U32 nTiacc = TIACC;
// Calculate Configuration Register address based on mode
// ******************************************************
if (bBurstMode)
{
fWsc = (((TIACC +10) * nClk + 999) / 1000);
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
}
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
//
// Return Value: BOOL TRUE if successful, FALSE on error
//
// ***************************************************************************
BOOL BoardControlBurstMode(BOOL bOnOff, U32 sAddress)
{
//BOOL bResult;
U32 nWait;
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 Tacc
// in Tclk increments.
// ************************************************************
nWsc = (((TIACC + 10) * HCLK + 999) / 1000);
nWait = MAX(MIN(((TIACC * FCLK + 999) / 1000), 7), 2);
// 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) + 40;
nWait = 0;
}
// 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,FALSE,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 - 1) << (40 - 32)) | // WSC
(0 << (36 - 32)) | // WWS
(1 << (32 - 32)); // EDC
nCsLo = (nOea << 28) | // OEA
(0 << 24) | // OEN
(0 << 20) | // WEA
(0 << 16) | // WEN
(0 << 12) | // CSA
(1 << 11) | // EBC
(6 << 8) | // DSZ
(0 << 6) | // SP
(0 << 4) | // WP
(0 << 1) | // PA
(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
((62) << (40 - 32)) | // WSC
//((nWsc - 1) << (40 - 32)) | // WSC
(0 << (36 - 32)) | // WWS
(0 << (32 - 32)); // EDC
//(1 << (32 - 32)); // EDC
nCsLo = (0 << 28) | // OEA
(0 << 24) | // OEN
(0 << 20) | // WEA
(0 << 16) | // WEN
(0 << 12) | // CSA
(0 << 11) | // EBC
// (1 << 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;
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
//
// ***************************************************************************
/*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
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 = (((nData - 1) / sizeof(*pBase)) + 1) * sizeof(*pBase) + sAddress;
nAddress = sAddress + sizeof(*pData)*(nData - 1);
#ifdef DEBUG
printf("\nProgramming at [0x%08X - 0x%08X]...\n", sAddress, nAddress);
#endif
while (nWalk <= nAddress)
{
i++;
//i = write 32bit each time
// "P" => 0x10000 * 32bit
if( (i&0xFFFF) == 0 )
{
#ifdef DEBUG
printf("P");
#endif
}
// 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;
#ifdef DEBUG
printf("\nFlash Write Complete\n");
#endif
// return bFailTotal ? 0 : nDone;
}
// ***************************************************************************
//
// Function: FlashChipErase
//
// This function erases all flash memory sectors
//
//
// Parameters: U32 sAddress start address for erase
//
// Return Value: 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;
#ifdef DEBUG
printf("Chip Erasing...\n");
#endif
// Data polling algorithm for erase operation
// ******************************************
bDone = FALSE;
bFail = FALSE;
while ((!bDone) && (!bFail))
{
i++;
if ((i & 0xFFFF) == 0)
{
#ifdef DEBUG
printf(".");
#endif
}
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;
#ifdef DEBUG
printf("\nChip Erase Complete\n");
#endif
return bFail;
}
// ***************************************************************************
//
// Function: FlashSectorErase
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -