⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 progflash.c

📁 mx21 Nor flash Bootloader 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/// @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 + -