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

📄 flash.c

📁 linux flash 操作控制程序源码! l inux flash 操作控制程序源码!
💻 C
📖 第 1 页 / 共 3 页
字号:
// ***************************************************************************
//
//  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 + -