📄 progflash.c
字号:
/// @ingroup AMD_BOOTLOADER/// @file progflash.c/// @brief Program functions for AMD Flash////// @li FlashWrite/// @li FlashRead/// @li FlashChipErase/// @li FlashSectorErase/// @li FlashVerify/// /// @author Louis Lai/// @bug /// @version $Version$////<<<<<Include#include "../Include/tht_memory_map_defines.h"#include "../Include/type.h"//>>>>>Include//<<<<<< Private Macro#ifndef TRUE #define TRUE (1 == 1)#endif#ifndef FALSE #define FALSE (1 == 2)#endif#define MIN(a,b) ((a) < (b) ? (a) : (b))#define MAX(a,b) ((a) > (b) ? (a) : (b))#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//>>>>>> Private Macro//<<<<<< Private Structure//>>>>>> Private Structure//<<<<<< Global Variable//>>>>>> Global Variable//<<<<<Private Function Declearationextern void EUARTputString(U8 *line);extern void EUARTputHex(U8 data);//>>>>>Private Function Declearation//<<<<<Body ///@brief This function configures the flash burst mode parameters.//////@param bBurstMode burst mode on/off///@param bRisingClock use rising CLK edge?///@param bEarlyReady RDY one CLK before data?///@param nClk wait states (2..7)///@param sAddress base Address of the Flash//////@return voidvoid FlashConfigBurst(BOOL bBurstMode, BOOL bRisingClock, BOOL bEarlyReady, U32 nClk, U32 sAddress){ volatile U32* pBase; U32 nAddr; U32 fWsc; U32 nTiacc = TIACC; int dividend; // Calculate Configuration Register address based on mode // ****************************************************** if (bBurstMode) { #if 0 fWsc = (((TIACC +10) * nClk + 999) / 1000); #else fWsc = ((TIACC +10) * nClk + 999); //fWsc = fWsc/1000; dividend = fWsc; fWsc = dividend >> 10; dividend -= fWsc * 1000; while(dividend>=1000) { dividend -= 1000; fWsc++; } #endif 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;}///@brief This function enabled or disables burst mode with the/// MX21 processor and with the memory.//////@param bOnOff burst mode on/off///@param sAddress Base Address of the Flash//////@return BOOL TRUE if successful, FALSE on errorBOOL 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); nClk = (HCLK / ((HCLK + (FCLK - 1)) / FCLK)); // 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;} ///@brief This function programs data into flash memory. It is /// assumed that the memory has been erased before calling/// this function.//////@param sAddress start address for write///@param pData data to write///@param nData number of words to write/// ///@return voidvoid 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); //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++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -