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

📄 flash_org.c

📁 FreeScale imx21开发板Nand flash烧写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
// ***************************************************************************
//
//  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 + -