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

📄 spansion29lv320d_2x16.c

📁 Ep93XX TionProV2 BSP
💻 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_2x16.h"

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

//
//
//
static volatile PULONG  gpulCurAddr    = 0;
static volatile PULONG  gpulBaseAddr   = (PULONG)PHYSICAL_ADDR_FLASH;

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

//
//
//
extern DWORD				gdwFlashSize			;
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;

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

	gdwManufactureId = ((*(gpulBaseAddr + AMD_VENDORID_ADDR) << 16)
	                        | ((*(gpulBaseAddr + AMD_VENDORID_ADDR)) & 0xFFFF));

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

	gdwFlashSize 	= 1 << (*(gpulBaseAddr + 0x27) & 0xFF);
	gdwFlashSize	= gdwFlashSize*2;
	
	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 << 16) | AMD_RESET;

	EdbgOutputDebugString
        (
            "Flash Query: Nor Flash ID %x,size %x,base add %x\r\n",
            gdwManufactureId,gdwFlashSize,gpulBaseAddr
        );
 
	if(gdwManufactureId == 0x00010001)
	{
		return TRUE;
	}
	else
	{
		EdbgOutputDebugString
        (
            "Flash Query: Nor Flash ID %x is not AMD \r\n",gdwManufactureId
        );
//		return FALSE;
	}
	return TRUE;
}


BOOL  GotEraseFlashSectorIndex_AMD(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_AMD(void)
{
    DWORD dwBlockSize;

    dwBlockSize = sBlockInfo[gdwCurEraseRegion].block_size;

    return dwBlockSize;
}


BOOL StartEraseSpansion29LV320D_2x16(DWORD dwStartAddr, DWORD dwLength)
{
    // Check to make sure that the flash is on a Block boundary.
    //
    if(GotEraseFlashSectorIndex_AMD(dwStartAddr))
    {
        EdbgOutputDebugString
        (
            "ERROR: Address %x is not on a flash block boundary.\r\n",
            dwStartAddr
        );
        return FALSE;
    }
    
	RETAILMSG(AMDFLASH_DEBUG, (TEXT("StartEraseFlashAMD_2x16 %x %x %x %x\r\n"),
		gdwCurEraseRegion,gdwCurEraseRegion,gdwCurEraseBlock,sBlockInfo[gdwCurEraseRegion].block_size));
    
    dwStartEraseAddr           = dwStartAddr;
    dwStartEraseLength         = gdwFlashSize;//dwLength;

    return TRUE;
}

void ContinueEraseSpansion29LV320D_2x16(void)
{

}

BOOL AmdFlashEraseSector(DWORD dwEraseBase)
{
	ULONG       ulStart;
	int iResult = FLASH_ERR_OK;
	  
	// Send erase block command - six step sequence
	*(gpulBaseAddr + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1;
	*(gpulBaseAddr + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2;
	*(gpulBaseAddr + AMD_SETUP_ADDR1) = (AMD_SETUP_ERASE << 16) | AMD_SETUP_ERASE;
	*(gpulBaseAddr + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1;
	*(gpulBaseAddr + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2;

	*(gpulBaseAddr + (dwEraseBase >> 2)) = (AMD_BLOCK_ERASE << 16) | AMD_BLOCK_ERASE;

	// Now poll for the completion of the sector erase timer (50us)
	ulStart = GetSystemTimeInMsec();

    while (1) 
	{
		if (((*(gpulBaseAddr + (dwEraseBase >> 2))) & AMD_SECTOR_ERASE_TIMER)
			== AMD_SECTOR_ERASE_TIMER) 
			break;

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

			iResult = FLASH_ERR_DRV_TIMEOUT;
				return FALSE;
		}
	}
	return TRUE;
}


BOOL  FinishEraseSpansion29LV320D_2x16 (void)
{
    DWORD i, j;
    DWORD dwEraseLen = dwStartEraseLength;
    DWORD dwEraseBase = dwStartEraseAddr-FLASH_VIRTUAL_MEMORY;
	
    for(i = gdwCurEraseRegion; i < gdwNumEraseRegion; i++) 
    {
        for(j = gdwCurEraseBlock; j< sBlockInfo[i].blocks; j++) 
        {
			RETAILMSG(AMDFLASH_DEBUG,(L"FinishEraseFlashC3_2x16 1:%x %x %x %x,Current %x %x \r\n",
            i,j,sBlockInfo[i].block_size,sBlockInfo[i].blocks,dwEraseLen,dwEraseBase));
               
           if(dwEraseLen > (sBlockInfo[i].block_size << 1))
		   {
				dwEraseLen = dwEraseLen - (sBlockInfo[i].block_size << 1);
				if(AmdFlashEraseSector(dwEraseBase)==FALSE)
					return FALSE;
				else
					dwEraseBase = dwEraseBase + (sBlockInfo[i].block_size << 1);

				EdbgOutputDebugString(".");
		   } 
		  else 
		  {
			if(AmdFlashEraseSector(dwEraseBase)==FALSE)
				return FALSE;
			else
			{
				EdbgOutputDebugString("\n");
				return TRUE;
			}
		  }
		
		}
	}
	return FALSE;
}

BOOL  WriteSpansion29LV320D_2x16(DWORD dwDest, DWORD dwSource, DWORD dwLength)
{
    ULONG       ulStart;
    PULONG      pDataBuffer = (PULONG) dwSource;
	DWORD iIdx;
        int iResult = FLASH_ERR_OK;
	DWORD timeout;
	DWORD dwOffset = dwDest-FLASH_VIRTUAL_MEMORY;
	
	//
    // Save off the start address and the length.
    //
    gpulCurAddr     = (PULONG) dwDest;
    
	RETAILMSG(AMDFLASH_DEBUG,(L"WriteSpansion29LV320D_2x16 0:%x %x %x %x\r\n",
        dwOffset,gpulBaseAddr,gpulCurAddr,dwLength ));

	for(iIdx = 0; iIdx < (dwLength>>2); iIdx++)
	{
    	// Send program block command - four step sequence
        *(gpulBaseAddr + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1;
        *(gpulBaseAddr + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2;
        *(gpulBaseAddr + AMD_SETUP_ADDR1) = (AMD_PROGRAM << 16) | AMD_PROGRAM;

		
        *(gpulBaseAddr + (dwOffset >> 2) + iIdx) = *(pDataBuffer + iIdx);
        
        timeout = 10000000;
		ulStart = GetSystemTimeInMsec();
        while (1) 
		{
            if (*(pDataBuffer + iIdx) == *(gpulBaseAddr + (dwOffset >> 2) + iIdx))
                break;

            // Can't check for FLASH_Err since it'll fail in parallel
            // configurations.
            if (--timeout == 0) {
                iResult = FLASH_ERR_DRV_TIMEOUT;
                break;
            }
		}
        if (FLASH_ERR_OK != iResult)
        {
			*gpulBaseAddr =  (AMD_RESET << 16) | AMD_RESET;
			EdbgOutputDebugString("Word Write TimeOut\n");
			return FALSE;
        }
			
        if (*(gpulBaseAddr + (dwOffset >> 2) + iIdx) != *(pDataBuffer + iIdx)) 
		{
			// Only update return value if erase operation was OK
			if (FLASH_ERR_OK == iResult) 
				iResult = FLASH_ERR_DRV_VERIFY;
			break;
		}
		if( iIdx %2000 ==0 )
    		RETAILMSG(1,(L"."));

      	RETAILMSG(AMDFLASH_DEBUG,(L"WriteSpansion29LV320D_2x16 1:%x %x \r\n",
            iIdx,gpulBaseAddr ));
	}
    EdbgOutputDebugString("\n");

    return TRUE;
}

⌨️ 快捷键说明

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