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

📄 spansion29lv320d_1x16.c

📁 EP9315的wince下载程序。download.exe
💻 C
字号:
//**********************************************************************
//                                                                      
// Filename: Spansion_1x16.c
//                                                                      
// Description: Flashing program for Spansion Flash. 
//
// 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 "spansion29lv320d_1x16.h"


//
// Definitions for Flash erasing.
//
#define     FLASH_BLOCK_SIZE            0x20000  //128KB
#define     FLASH_BLOCK_SIZE_WORD       0x10000  //64KW

//
//
//
static volatile PUSHORT  gpulCurAddr    = 0;
static volatile PUSHORT  gpulBaseAddr   = (PUSHORT)PHYSICAL_ADDR_ASYNC_CS6;

static DWORD dwStartEraseAddr           = 0;
static DWORD dwStartEraseLength         = 0;

//
//
//
static DWORD				gdwFlashSize			=0;
static DWORD                      gdwManufactureId		=0;
struct EraseBlockInfo       	sBlockInfo[4];
static DWORD				gdwNumEraseRegion		=0;
static DWORD				gdwCurEraseRegion		=0;
static DWORD				gdwCurEraseBlock		=0;
static DWORD				gdwCurEraseBlockMask	=0;
static DWORD				gdwFlashBufferSize		=64;

//
//
//
void AmdFlashSpansion29LV320D_1x16(void)
{
 	DWORD iIdx;
	// Query 16 bitwidth id.
	*(gpulBaseAddr + AMD_SETUP_ADDR1) =  AMD_SETUP_CODE1;
	*(gpulBaseAddr + AMD_SETUP_ADDR2) =  AMD_SETUP_CODE2;	    
	*(gpulBaseAddr + AMD_SETUP_ADDR1) =  AMD_READ_ID;

	    gdwManufactureId = *(gpulBaseAddr + AMD_VENDORID_ADDR);

	// Query 32 bitwidth flash.
	*(gpulBaseAddr + AMD_QUERY_ADDR) =  AMD_READ_QUERY;

	gdwFlashSize = 1 << (*(gpulBaseAddr + 0x27) & 0xFF);
	gdwNumEraseRegion = *(gpulBaseAddr + 0x2c) & 0xFFFF;


	for(iIdx = 0; iIdx <gdwNumEraseRegion; iIdx++)
	{
	    	sBlockInfo[iIdx].blocks = (*(gpulBaseAddr + 0x2d + (iIdx<<2)) & 0xFFFF) + 1;
			
		sBlockInfo[iIdx].block_size = (((*(gpulBaseAddr + 0x30 + (iIdx<<2)) & 0xFFFF) << 8) + 
		    						(*(gpulBaseAddr + 0x2f + (iIdx<<2)) & 0xFFFF)) << 8;
	}
	   // Put the FLASH into read array mode.
	  *gpulBaseAddr = AMD_RESET;

        EdbgOutputDebugString
        (
            "Flash Query: Nor Flash ID %x,size %x \r\n",
            gdwManufactureId,gdwFlashSize
        );

	if(gdwManufactureId == 0x0001)
	{
		return TRUE;
	}
	else
	{

		EdbgOutputDebugString
        (
            "Flash Query: Nor Flash ID %x is not AMD \r\n",gdwManufactureId
        );
		return FALSE;
	}
}


BOOL  GotEraseFlashSectorIndex_1X16(DWORD dwStartAddr)
{
   DWORD i,j,dwEraseLen;

   dwEraseLen = dwStartAddr-FLASH_VIRTUAL_MEMORY;
   
    for(i = 0; i <gdwNumEraseRegion; i++) 
   {
        for(j = 0; j< sBlockInfo[i].blocks; j++) 
	{

            if(dwEraseLen > sBlockInfo[i].block_size) 
	    {
                dwEraseLen = dwEraseLen - sBlockInfo[i].block_size;
               
            } 
	     else if(dwEraseLen ==sBlockInfo[i].block_size)
	     {
                gdwCurEraseRegion = i;
		  gdwCurEraseBlock    = j;
		  
                return TRUE;
            }
	     else 
	     {
                gdwCurEraseRegion = i;
		  gdwCurEraseBlock    = j;
		  
                return FALSE;
            }

         }
    }




   return FALSE;

}

DWORD GetEraseFlashBlockSize_1X16(void)
{
    DWORD dwBlockSize;

    dwBlockSize = sBlockInfo[gdwCurEraseRegion].block_size;

    return dwBlockSize;

}


BOOL StartEraseSpansion29LV320D_1x16(DWORD dwStartAddr, DWORD dwLength)
{
    //
    // Make sure that the flash addresses are valid.
    //
    if(dwStartAddr + dwLength >FLASH_VIRTUAL_MEMORY + gdwFlashSize  || 
       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(GotEraseFlashSectorIndex_1X16(dwStartAddr))
    {

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

    return TRUE;
}

void ContinueEraseSpansion29LV320D_1x16(void)
{

}

BOOL AmdFlashEraseSector_1X16(DWORD dwEraseBase,DWORD dwEraseLen)
{
	  ULONG       ulStart;
	  int iResult = FLASH_ERR_OK;
	  int timeout=0;
	  int i=0;
    // Send erase block command - six step sequence
        *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
        *(gpulBaseAddr + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
        *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_SETUP_ERASE;
        *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
        *(gpulBaseAddr + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
		
        *(gpulBaseAddr + (dwEraseBase >> 1)) = AMD_BLOCK_ERASE;
        
        // Now poll for the completion of the sector erase timer (50us)
         ulStart = GetSystemTimeInMsec();

	 //timeout = 10000000;               how many retries?
        while (1) 
	{
            if (((*(gpulBaseAddr + (dwEraseBase >> 1))) & AMD_SECTOR_ERASE_TIMER)
                    == AMD_SECTOR_ERASE_TIMER) 
                    break;

	     if( GetSystemTimeInMsec() > ulStart + 10000 )
            {
                EdbgOutputDebugString("Erase Sector TimeOut\n");
                gpulBaseAddr[0] = AMD_RESET;

		  iResult = FLASH_ERR_DRV_TIMEOUT;
                return FALSE;
            }
		 
           // if (--timeout == 0) 
	    // {
           //     iResult = FLASH_ERR_DRV_TIMEOUT;
           //     break;
           // }
           
     }
        
        // Then wait for erase completion.
        if (FLASH_ERR_OK == iResult) 
		{

            for(i=0;i<dwEraseLen/2;i++) 
			{
				if (0xffff != *(gpulBaseAddr + (dwEraseBase >> 1)+i)) 
				{
					EdbgOutputDebugString("Erase Sector error %x\n",i);
					iResult= FLASH_ERR_DRV_TIMEOUT;
    				break;
				}

   
            }
        }

        if (FLASH_ERR_OK != iResult)
		{
            gpulBaseAddr[0] = AMD_RESET;
        }

        return TRUE;
}


BOOL  FinishEraseSpansion29LV320D_1x16 (void)
{

#if 0
    ULONG       ulStart;
    int         BlockCount;

    //
    // Count the # of blocks need to erase.
    //
    BlockCount = ( dwStartEraseLength + (FLASH_BLOCK_SIZE - 1) ) / FLASH_BLOCK_SIZE;

    //
    // Save off the start address and the length.
    //
    gpusCurAddr     = (PUSHORT) dwStartEraseAddr;
    
    while(BlockCount--)
    {
    
        //
        // Issue Sector Erase Command Sequence
        //
        gpusBaseAddr[LLD_UNLOCK_ADDR1] = NOR_UNLOCK_DATA1;
        gpusBaseAddr[LLD_UNLOCK_ADDR2] = NOR_UNLOCK_DATA2;
        gpusBaseAddr[LLD_UNLOCK_ADDR1] = NOR_ERASE_SETUP_CMD;
        gpusBaseAddr[LLD_UNLOCK_ADDR1] = NOR_UNLOCK_DATA1;
        gpusBaseAddr[LLD_UNLOCK_ADDR2] = NOR_UNLOCK_DATA2;
        
        //
        // Write Sector Erase Command to Offset
        //
        gpusCurAddr[0] = NOR_SECTOR_ERASE_CMD;
        
        //
        // Wait the toggle bit.
        //
        ulStart = GetSystemTimeInMsec();
		while ((gpusBaseAddr[0] & 0x0080) != 0x0080)
		{
            if( GetSystemTimeInMsec() > ulStart + 10000 )
            {
                EdbgOutputDebugString("Erase Sector TimeOut\n");
                gpusBaseAddr[0] = NOR_RESET_CMD;
                return FALSE;
            }
		}
        EdbgOutputDebugString(".");
        gpusCurAddr += FLASH_BLOCK_SIZE_WORD;
    }    
    EdbgOutputDebugString("\n");
    return TRUE;

#else

    DWORD i, j;
    DWORD dwEraseLen =  gdwFlashSize;//dwStartEraseLength;
    DWORD dwEraseBase = dwStartEraseAddr-FLASH_VIRTUAL_MEMORY;
	
    for(i = gdwCurEraseRegion; i < gdwNumEraseRegion; i++) 
    {
            for(j = gdwCurEraseBlock; j< sBlockInfo[i].blocks; j++) 
            {
                
                if(dwEraseLen > (sBlockInfo[i].block_size))
		  {
                    dwEraseLen = dwEraseLen - (sBlockInfo[i].block_size );
                    if(AmdFlashEraseSector_1X16(dwEraseBase,sBlockInfo[i].block_size)==FALSE)
                    {
                    	EdbgOutputDebugString("error 1");
			return FALSE;
		     }
		      else
                    		dwEraseBase = dwEraseBase + (sBlockInfo[i].block_size );

		      EdbgOutputDebugString(".");
                 } 
		  else 
		  {
			if(AmdFlashEraseSector_1X16(dwEraseBase,sBlockInfo[i].block_size)==FALSE)
			{
				EdbgOutputDebugString("error 2");
				return FALSE;
			}
			else
			{
				EdbgOutputDebugString("\n");
				return TRUE;
			}
		   }
		
	     }
     }    

	return FALSE;
	
#endif

	
}

BOOL  WriteSpansion29LV320D_1x16(DWORD dwDest, DWORD dwSource, DWORD dwLength)
{
    
    ULONG       ulStart;
    PUSHORT     pDataBuffer = (PUSHORT) dwSource;
    


#if 0
    DWORD       noffset;
    //
    // Save off the start address and the length.
    //
    gpulCurAddr     = (PUSHORT) dwDest;
    
    
    
    //
    // Load Data into Buffer
    //
    for(noffset=0;noffset<(dwLength+1)/2;noffset++)
    {
        //
        // Write one word data.
        //
        gpusBaseAddr[LLD_UNLOCK_ADDR1] = NOR_UNLOCK_DATA1;
        gpusBaseAddr[LLD_UNLOCK_ADDR2] = NOR_UNLOCK_DATA2;
        gpusBaseAddr[LLD_UNLOCK_ADDR1] = NOR_PROGRAM_CMD;
        gpusCurAddr[noffset] = pDataBuffer[noffset];


        //
        // Print something to indicate still running.
        //
        if(( noffset & ( FLASH_BLOCK_SIZE_WORD -1 )) == 0 )
            EdbgOutputDebugString(".");
        
        //
        // Wait for write finish.
        //
        ulStart = GetSystemTimeInMsec();
		while ((gpusCurAddr[noffset] & 0x0080) != (pDataBuffer[noffset] & 0x0080))
		{
            if( GetSystemTimeInMsec() > ulStart + 10000 )
            {
                EdbgOutputDebugString("Word Write TimeOut\n");
                gpusBaseAddr[0] = NOR_RESET_CMD;
                return FALSE;
            }
		}
    }
    EdbgOutputDebugString("\n");

    return TRUE;
#else
	DWORD iIdx,iIdx0;
       int iResult = FLASH_ERR_OK;
	DWORD timeout;
	DWORD dwOffset = dwDest-FLASH_VIRTUAL_MEMORY;
	//
    	// Save off the start address and the length.
    	//
    	gpulCurAddr     = (PUSHORT) dwDest;
    	
    	/*
          *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
          *(gpulBaseAddr + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
    	  *(gpulBaseAddr + AMD_SETUP_ADDR1) = 0x0020;  
    	*/
    	
	for(iIdx = 0; iIdx < (dwLength+1)/2; iIdx++)
	{
    	    // Send program block command - four step sequence
            /*
            *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
            *(gpulBaseAddr + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
            *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_PROGRAM;
	    */
	      
	    *(gpulBaseAddr + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
            *(gpulBaseAddr + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
    	    *(gpulBaseAddr + AMD_SETUP_ADDR1) = 0x0020; 
    	       
	    *(gpulBaseAddr + 0) = 0x00a0;
			
            *(gpulBaseAddr + (dwOffset >> 1) + iIdx) = *(pDataBuffer + iIdx);
            
            timeout = 10000000;
	     ulStart = GetSystemTimeInMsec();
	    // for(iIdx0 = 0; iIdx0 < 100; iIdx0++){}
            while (1) 
	     {
                if (   *(pDataBuffer + iIdx) == *(gpulBaseAddr + (dwOffset >> 1) + iIdx))
                    break;

                // Can't check for FLASH_Err since it'll fail in parallel
                // configurations.
                if (--timeout == 0) {
                    iResult = FLASH_ERR_DRV_TIMEOUT;
                    break;
                }
            }

	    //for(iIdx0 = 0; iIdx0 < 50; iIdx0++){}
	    
            if (FLASH_ERR_OK != iResult)
            {
                *gpulBaseAddr =  AMD_RESET;
				EdbgOutputDebugString("word/2 Write TimeOut:addre=%x value=%x %x\n",
				(gpulBaseAddr + (dwOffset >> 1) + iIdx),*(gpulBaseAddr + (dwOffset >> 1) + iIdx),*(pDataBuffer + iIdx));
				//return FALSE;
            }
			
            if (*(gpulBaseAddr + (dwOffset >>1) + iIdx) !=  *(pDataBuffer + iIdx) ) 
	    {
                // Only update return value if erase operation was OK
                if (FLASH_ERR_OK == iResult) 
			iResult = FLASH_ERR_DRV_VERIFY;
			
		EdbgOutputDebugString("word/2 Write error:address=%x value=%x trueValue=%x\n",
		(gpulBaseAddr + (dwOffset >> 1) + iIdx),*(gpulBaseAddr + (dwOffset >> 1) + iIdx),*(pDataBuffer + iIdx));
		//break;
            }

	        //EdbgOutputDebugString(".");
	        *(gpulBaseAddr + AMD_SETUP_ADDR1) = 0x0090;
        	*(gpulBaseAddr + AMD_SETUP_ADDR2) = 0x0000;
			
        }  
	
	
	//for(iIdx0 = 0; iIdx0 < 100; iIdx0++){}
	//gpulBaseAddr[0] = AMD_RESET;
        
        *(gpulBaseAddr + AMD_SETUP_ADDR1) = 0x0090;
        *(gpulBaseAddr + AMD_SETUP_ADDR2) = 0x0000;
	

	for(iIdx = 0; iIdx < (dwLength+1)/2; iIdx++)
	{
		
		if ( *(pDataBuffer + iIdx) != *(gpulBaseAddr + (dwOffset >> 1) + iIdx))
		{
		
			EdbgOutputDebugString("word/2 Write error:addre=%x value=%x should value=%x\n",
				(gpulBaseAddr + (dwOffset >> 1) + iIdx),
				*(gpulBaseAddr + (dwOffset >> 1) + iIdx),
				*(pDataBuffer + iIdx));
		}
	
	}
	
	
	gpulBaseAddr[0] = AMD_RESET;
	
        EdbgOutputDebugString("write finished\n");

        return TRUE;

#endif

}

⌨️ 快捷键说明

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