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

📄 intel_j3_2x16.c

📁 ebd9307开发板wince bsp源码,包括cs8900,lcd,nand,serial,touch,usb,gpio,wd等驱动
💻 C
字号:
//**********************************************************************
//                                                                      
// Filename: intel_j3_2x16.c
//                                                                      
// Description: Routines for programming the Intel J3 flash 2x16.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved                       
//                                                                      
//**********************************************************************
#include<windows.h>
#include<hwdefs.h>
#include<halether.h>
#include<debugtimer.h>
#include"flash.h"
#include"intel_j3_2x16.h"



//
// Flash commands.
//
#define     FLASH_BLOCK_SIZE            0x40000
#define     FLASH_BLOCK_MASK            ~(FLASH_BLOCK_SIZE - 1)
#define     FLASH_BUFFER_SIZE           64
#define     FLASH_READ_MODE             0x00FF00FF
#define     FLASH_BLOCK_ERASE           0x00200020
#define     FLASH_CLEAR_STATUS          0x00500050
#define     FLASH_BLOCK_ERASE_RESUME    0x00d000d0
#define     FLASH_BLOCK_PROGRAM_RESUME  0x00d000d0
#define     FLASH_WRITE_TO_BUFFER       0x00E800E8
#define     FLASH_READ_STATUS           0x00700070
#define     FLASH_LOCK_BIT              0x00600060
#define     FLASH_LOCK_SET              0x00010001
#define     FLASH_LOCK_CLEAR            0x00d000d0


#define     STATUS_WRITE_READY          0x00800080
#define     EXT_STATUS_WBUFFER_READY    0x00800080

static DWORD    gdwStartAddr            = 0;
static DWORD    gdwLength               = 0;
static volatile PULONG  gpulCurAddr     = 0;
static BOOL     gbFlashEraseComplete    = FALSE;
static BOOL     gbUnlocked              = TRUE;


//
// Function prototypes
//
static int  WaitForReady(volatile ULONG *pFlash, ULONG ulTimeoutInMsec, ULONG ulBitField);


//****************************************************************************
//  StartEraseFlashJ3_2x16
//****************************************************************************
//  dwStartAddr - Start address, in flash, to start erasing from. The 
//                platform loader code needs to ensure this is a flash 
//                block-aligned address or needs to handle it specially if 
//                it is not. 
//
//  dwLength    - Number of bytes of flash to be erased. 
//
//  return      TRUE indicates success. FALSE indicates failure.
//
BOOL StartEraseFlashJ3_2x16 (DWORD dwStartAddr, DWORD dwLength )
{
    //
    // Make sure that the flash addresses are valid.
    //
    if(dwStartAddr + dwLength > FLASH_VIRTUAL_MEMORY + FLASH_SIZE  || 
       dwStartAddr < FLASH_VIRTUAL_MEMORY)
    {
        EdbgOutputDebugString
        (
            "ERROR: No Flash located in the locations from %x to %xr\r\n",
            dwStartAddr,
            dwLength
        );
        return FALSE;
    }

    //
    // Check to make sure that the flash is on a Block boundary.
    //
    if(dwStartAddr  & (FLASH_BLOCK_SIZE - 1))
    {

        EdbgOutputDebugString
        (
            "ERROR: Address %x is not on a flash block boundary.\r\n",
            dwStartAddr
        );
        return FALSE;
    }

    //
    // Save off the start address and the length.
    //
    gdwStartAddr    = dwStartAddr;
    gdwLength       = dwLength;
    gpulCurAddr     = (PULONG) dwStartAddr;


    //
    // Put the flash in read mode to make sure that we are not in the middle 
    // of a command.
    //
    *gpulCurAddr = FLASH_READ_MODE;

    // DelayInuSec(500);


    //
    // Clear the lock bit.
    //
    *gpulCurAddr = FLASH_LOCK_BIT;
    *gpulCurAddr = FLASH_LOCK_CLEAR;
    *gpulCurAddr = FLASH_READ_STATUS;
    gbUnlocked  = TRUE;


    return TRUE;
}

//****************************************************************************
// ContinueEraseFlashJ3_2x16
//****************************************************************************
// Continues the flash erasing processes for J3 Flash.  See 
// OEMContinueEraseFlash for Parameter description.
// 
//
void ContinueEraseFlashJ3_2x16(void)
{
    //
    // Check to see if the flash has been completely erased. If so just
    // return.
    //
    if(gbFlashEraseComplete)
    {
        return;
    }

    //
    // Check to see if the last block has been erased.
    //
    if((*gpulCurAddr & EXT_STATUS_WBUFFER_READY) != EXT_STATUS_WBUFFER_READY)
    {
        return;
    }

    //
    // Clear Status.
    //
    *gpulCurAddr  = FLASH_CLEAR_STATUS;


    if(gbUnlocked)
    {
        //
        // Erase the flash block
        //
        *gpulCurAddr = FLASH_BLOCK_ERASE;
        *gpulCurAddr = FLASH_BLOCK_ERASE_RESUME;

        //
        // Read erase status.
        //
        *gpulCurAddr = FLASH_READ_STATUS;
        gbUnlocked   = FALSE;
    }
    else
    {
        //
        // Check to see if we have finished erasing the flash memory.
        //
        if(gdwStartAddr + gdwLength < ((DWORD)gpulCurAddr) + FLASH_BLOCK_SIZE)
        {
            gbFlashEraseComplete = TRUE;
            return;
        }

        //
        // Advance to the next block.
        //
        gpulCurAddr+= FLASH_BLOCK_SIZE>>2;

        //
        // Clear the lock bits if the flash block was locked.
        //
        *gpulCurAddr = FLASH_LOCK_BIT;
        *gpulCurAddr = FLASH_LOCK_CLEAR;
        *gpulCurAddr = FLASH_READ_STATUS;

        gbUnlocked  = TRUE;
    }
}

//****************************************************************************
// FinishEraseFlashJ3_2x16
//****************************************************************************
// Finishes the flash eraseing processes for J3 Flash.  See 
// OEMFinishEraseFlash for paramter description.
//
BOOL  FinishEraseFlashJ3_2x16 (void)
{
    BOOL    bSuccess;
    //
    // Check to see if the flash has been completely erased. If so just
    // return.
    //
    if(gbFlashEraseComplete)
    {
        return TRUE;
    }

    //
    // Wait for the Flash block command to succeed.
    //
    bSuccess = WaitForReady(gpulCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
    if(bSuccess == FALSE)
    {
        return FALSE;
    }
    *gpulCurAddr  = FLASH_CLEAR_STATUS;


    //
    // Erase the block before unlocking the next block.
    //
    if(gbUnlocked)
    {
        //
        // Erase the flash block
        //
        *gpulCurAddr = FLASH_BLOCK_ERASE;
        *gpulCurAddr = FLASH_BLOCK_ERASE_RESUME;

        //
        // Read erase status.
        //
        *gpulCurAddr = FLASH_READ_STATUS;

        //
        // Wait for the Flash block command to succeed.
        //
        bSuccess = WaitForReady(gpulCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
        if(bSuccess == FALSE)
        {
            return FALSE;
        }

        *gpulCurAddr    = FLASH_CLEAR_STATUS;
        gbUnlocked      = FALSE;

        //
        // Increment to the next block.
        //
        gpulCurAddr += FLASH_BLOCK_SIZE>>2;
    }


    //
    // Erase the Flash
    //
    while((DWORD)gpulCurAddr < (gdwStartAddr + gdwLength))
    {

        //
        // Clear the lock bits if the flash block was locked.
        //
        *gpulCurAddr = FLASH_LOCK_BIT;
        *gpulCurAddr = FLASH_LOCK_CLEAR;
        *gpulCurAddr = FLASH_READ_STATUS;

        //
        // Wait for the Flash block command to succeed.
        //
        bSuccess = WaitForReady(gpulCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
        *gpulCurAddr  = FLASH_CLEAR_STATUS;
        
        if(!bSuccess)
        {
            break;
        }


        //
        // Erase the flash block
        //
        *gpulCurAddr = FLASH_BLOCK_ERASE;
        *gpulCurAddr = FLASH_BLOCK_ERASE_RESUME;
        *gpulCurAddr = FLASH_READ_STATUS;
        
        //
        // Wait for the Flash block command to succeed.
        //
        bSuccess = WaitForReady(gpulCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
        *gpulCurAddr  = FLASH_CLEAR_STATUS;
        
        if(!bSuccess)
        {
            break;
        }

        //
        // Occasionally write out a dot so they don't think
        // the system is dead.
        //
        EdbgOutputDebugString(".");
        
        //
        // Increment to the next block.
        //
        gpulCurAddr += FLASH_BLOCK_SIZE>>2;
    }        
    return bSuccess;
}

extern volatile int bStop;
//****************************************************************************
// WriteFlashJ3_2x16
//****************************************************************************
//  Writes to J3 Flash.  Different from parameters than  OEMWriteFlash.
//
//  dwDest       -  Address in flash where the start of the downloaded image 
//                  is to be written. Note that if this is not a flash 
//                  block-aligned address, the platform code will need 
//                  to take this into account and handle it as a special
//                  case. 
//
//  dwSource     -  Location of the Flash Cache.
//
//  dwLength     -  Length of the image, in bytes, to be written to flash. 
// 
//
BOOL  WriteFlashJ3_2x16(DWORD dwDest, DWORD dwSource, DWORD dwLength)
{
    ULONG               ulCount;
    ULONG               ulEndCount;
    volatile PULONG     pulBlockAddress;
    volatile PULONG     pulDest, pulSource;
    USHORT              usWordsToWrite;
    ULONG               ulStart,ulCurrent;
    BOOL                bSuccess;
    ULONG               ulAddDelay;

    ulCount     = 0;
    pulDest     = (PULONG)dwDest;
    pulSource   = (PULONG)dwSource;
    
    while( ulCount < dwLength)
    {   
    
        //
        // Calculate the block address
        //
        pulBlockAddress = (ULONG *)(((ULONG)&pulDest[ulCount>>2]) &  FLASH_BLOCK_MASK);        
        
        //
        // Write the Flash to buffer command until the flash is ready.
        //
        ulStart = GetSystemTimeInMsec();
        ulAddDelay = 1;
        do
        {    
            *pulBlockAddress = FLASH_WRITE_TO_BUFFER;
            
            //
            // Check to make sure that we are not in a loop.
            //
            ulCurrent = GetSystemTimeInMsec();
            if(ulStart + 10000 <ulCurrent)
            {
                EdbgOutputDebugString("FLASH_WRITE_TO_BUFFER - Failed\n.");
                EdbgOutputDebugString("pulBlockAddress  = %x.\n",(ULONG)pulBlockAddress);
                EdbgOutputDebugString("*pulBlockAddress = %x.\n",(ULONG)*pulBlockAddress);
                *pulBlockAddress = FLASH_READ_STATUS;
                EdbgOutputDebugString("*FLASH_READ_STATUS pulBlockAddress = %x.\n",(ULONG)*pulBlockAddress);
                while(1);
                return FALSE;
            }                
            DelayInuSec(ulAddDelay);
            ulAddDelay =(ulAddDelay<<1);
        }            
        while((*pulBlockAddress & EXT_STATUS_WBUFFER_READY)!= EXT_STATUS_WBUFFER_READY);
        
        //
        // Program the Flash size to be written.
        //
        usWordsToWrite = (FLASH_BUFFER_SIZE - 1)>>2;
        *pulBlockAddress = (usWordsToWrite<<16) | usWordsToWrite;
        
        ulEndCount  = ulCount + FLASH_BUFFER_SIZE;
        do
        {
            pulDest[ulCount>>2] = pulSource[ulCount>>2]; 
            ulCount += sizeof(ULONG);
	        //
			// Account for timing problem.
			//
			do
			{
			} while(!(*pulBlockAddress & EXT_STATUS_WBUFFER_READY) && (ulAddDelay-- != 0));
        } while(ulCount < ulEndCount);
        
        //
        // End of programming the block.
        //
        *pulBlockAddress = FLASH_BLOCK_PROGRAM_RESUME;

        // DelayInuSec(500);
        
        //
        // Occasionally write out a dot so they don't think
        // the system is dead.
        //
        if(((ULONG)&pulDest[ulCount>>2] & (FLASH_BLOCK_SIZE - 1)) == 0)
        {
            EdbgOutputDebugString(".");
        }            
        
        //
        // Wait for the Flash block command to succeed.
        //
        bSuccess = WaitForReady(pulBlockAddress, 6000, EXT_STATUS_WBUFFER_READY);
        if(!bSuccess)
        {
            EdbgOutputDebugString("FLASH_BLOCK_PROGRAM_RESUME - Failed\n.");
            EdbgOutputDebugString("pulBlockAddress  = %x.\n",(ULONG)pulBlockAddress);
            EdbgOutputDebugString("*pulBlockAddress = %x.\n",(ULONG)*pulBlockAddress);
            *pulBlockAddress = FLASH_READ_STATUS;
            EdbgOutputDebugString("*FLASH_READ_STATUS pulBlockAddress = %x.\n",(ULONG)*pulBlockAddress);
            while(1);
            break;
        }            
    }        
    *pulBlockAddress =  FLASH_READ_MODE;
    return TRUE;
}



//****************************************************************************
// WaitForReady
//****************************************************************************
// Wait until the flash is ready.
// 
//
static int  WaitForReady
(
    volatile ULONG *pFlash, 
    ULONG ulTimeoutInMsec, 
    ULONG ulBitField
)
{
    ULONG       ulStart;
    ULONG       ulCurrent;
    BOOL        bSuccess = FALSE;
   
    ulStart = GetSystemTimeInMsec();
    do
    {
        //
        // See if there are errors.
        //
        if((*pFlash & ulBitField)== ulBitField)
        {
            bSuccess = TRUE;
            break;
        }
        
        //
        // Get the current time.
        //
        ulCurrent = GetSystemTimeInMsec();
    } while(ulCurrent<ulStart + ulTimeoutInMsec);

    if(!bSuccess)
    {
        EdbgOutputDebugString("*pFlash        = %x .\n",(ULONG)*pFlash);
    }        
    
    return bSuccess;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -