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

📄 amd.c

📁 EP9315的wince下载程序。download.exe
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************
//
// AMD.c - The amd flash function definition.
//
// Copyright (c) 2006 Cirrus Logic, Inc.
//
//****************************************************************************

#include "ep93xx.h"
#include "flash.h"
#include "amd.h"
#include <string.h>

#define AMD_compatible_MAX 3
static struct sFlashManufactureId sAMD_ManufactureId[AMD_compatible_MAX]={
	{0x0001,"AMD"},
	{0x0004,"Spansion"},
	{0x0020,"ST"}
};
//****************************************************************************
// Name       : AmdFlashQuery
// Description: This routine read the flash manufactureid and deviceid.
// Return     : 0 - succuss.
//              1 - failure.
// Note(s)    :
//****************************************************************************
int AmdFlashQuery(struct FlashInfo *pInfo)
{
    volatile unsigned short *ptr16 = (volatile unsigned short *)pInfo->FlashBase;
    volatile unsigned long *ptr32 = (volatile unsigned long *)pInfo->FlashBase;
	unsigned short usByteWidth = pInfo->ByteWidth;
	int iIdx, iResult;
	int timeout = 500000;
	
	if (usByteWidth == 1){
	    
        unsigned short usWord;	    
	    usWord = *ptr16;
	    
	    // Query 16 bitwidth id.
	    *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
	    *(ptr16 + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;	    
	    *(ptr16 + AMD_SETUP_ADDR1) = AMD_READ_ID;
        pInfo->ManufactureId = *(ptr16 + AMD_VENDORID_ADDR);
        pInfo->DeviceId[0]   = *(ptr16 + AMD_DEVICEID_ADDR1);  
             	    
	    // Query 16 bitwidth flash.
	    *(ptr16 + AMD_QUERY_ADDR) = AMD_READ_QUERY;
	    pInfo->pQuery->DeviceSize = 1 << (*(ptr16 + 0x27) & 0xFF);
	    pInfo->pQuery->NumEraseBlocks = *(ptr16 + 0x2c) & 0xFFFF;
	    
        for(iIdx = 0; iIdx < pInfo->pQuery->NumEraseBlocks; iIdx++){
            pInfo->pQuery->sBlockInfo[iIdx].blocks = 
                (*(ptr16 + 0x2d + (iIdx<<2)) & 0xFFFF) + 1;
			pInfo->pQuery->sBlockInfo[iIdx].block_size = 
			    (((*(ptr16 + 0x30 + (iIdx<<2)) & 0xFFFF) << 8) + 
			    (*(ptr16 + 0x2f + (iIdx<<2)) & 0xFFFF)) << 8;
		}
        // Put the FLASH into read array mode.
        *ptr16 = AMD_RESET;
        
        // Stall, waiting for flash to return to read mode.
        while ((--timeout != 0) && (usWord != *ptr16));
        iResult = 0;		
	} else if (usByteWidth == 2){
	    
        unsigned long ulWord;	    
	    ulWord = *ptr32;
	    
	    // Query 16 bitwidth id.
	    *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1;
	    *(ptr32 + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2;	    
	    *(ptr32 + AMD_SETUP_ADDR1) = (AMD_READ_ID << 16) | AMD_READ_ID;
        pInfo->ManufactureId = (unsigned short) ((*(ptr32 + AMD_VENDORID_ADDR) >> 16)
                                & ((*(ptr32 + AMD_VENDORID_ADDR)) & 0xFFFF));
        pInfo->DeviceId[0]   = (unsigned short) (*(ptr32 + AMD_DEVICEID_ADDR1) );
         
	    // Query 32 bitwidth flash.
	    *(ptr32 + AMD_QUERY_ADDR) = (AMD_READ_QUERY << 16) | AMD_READ_QUERY;
	    pInfo->pQuery->DeviceSize = 2 << (*(ptr32 + 0x27) & 0xFF);
	    pInfo->pQuery->NumEraseBlocks = *(ptr32 + 0x2c) & 0xFFFF;
	    
        for(iIdx = 0; iIdx < pInfo->pQuery->NumEraseBlocks; iIdx++){
            pInfo->pQuery->sBlockInfo[iIdx].blocks = 
                (*(ptr32 + 0x2d + (iIdx<<2)) & 0xFFFF) + 1;
			pInfo->pQuery->sBlockInfo[iIdx].block_size = 
			    (((*(ptr32 + 0x30 + (iIdx<<2)) & 0xFFFF) << 8) + 
			    (*(ptr32 + 0x2f + (iIdx<<2)) & 0xFFFF)) << 8;
		}
        // Put the FLASH into read array mode.
        *ptr32 = (AMD_RESET << 16) | AMD_RESET;
        
        // Stall, waiting for flash to return to read mode.
        while ((--timeout != 0) && (ulWord != *ptr32));
        iResult = 0;	    
	} else{
	    // No such parameter.
        iResult = 1;
    }

    //if(pInfo->ManufactureId == 0x0001) return 0;
    //else return 1;
    for(iIdx=0;iIdx<AMD_compatible_MAX;iIdx++)
    {
    	if(pInfo->ManufactureId == sAMD_ManufactureId[iIdx].manufacture_id) 
    	{
    	    return 0;
    	}
    }
    return 1;    
}

//****************************************************************************
// Name       : AmdFlashEraseSector
// Description: This routine erase the specified sector of amd.
// Arguments  : iOffset - the offset address.
//              len  - the length.
// Return     : 0 - succuss.
//              1 - failure.
// Note(s)    :
//****************************************************************************
int AmdFlashEraseSector(struct FlashInfo *pInfo, int iSector)
{
    volatile unsigned short *ptr16 = (volatile unsigned short *)pInfo->FlashBase;
    volatile unsigned long *ptr32 = (volatile unsigned long *)pInfo->FlashBase;
	unsigned short usByteWidth = pInfo->ByteWidth;
	int iResult = FLASH_ERR_OK;
	int timeout = 50000;

	if (usByteWidth == 1){
	    // Send erase block command - six step sequence
        *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
        *(ptr16 + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
        *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_ERASE;
        *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1;
        *(ptr16 + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2;
        *(ptr16 + (iSector >> 1)) = AMD_BLOCK_ERASE;
        
        // Now poll for the completion of the sector erase timer (50us)
        timeout = 10000000;              // how many retries?
        while (1) {
            if (((*(ptr16 + (iSector >> 1))) & AMD_SECTOR_ERASE_TIMER)
                    == AMD_SECTOR_ERASE_TIMER) break;

            if (--timeout == 0) {
                iResult = FLASH_ERR_DRV_TIMEOUT;
                break;
            }
        }

        // Then wait for erase completion.
        if (FLASH_ERR_OK == iResult) {
            timeout = 10000000;
            while (1) {
                if (0xffff == (*(ptr16 + (iSector >> 1)))) {
                    break;
                }

                // Don't check for FLASH_Err here since it will fail
                // with devices in parallel because these may finish
                // at different times.

                if (--timeout == 0) {
                    iResult = FLASH_ERR_DRV_TIMEOUT;
                    break;
                }
            }
        }

        if (FLASH_ERR_OK != iResult)
            *ptr16 = AMD_RESET;
            
	} else if (usByteWidth == 2){
	    // Send erase block command - six step sequence
        *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1;
        *(ptr32 + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2;
        *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_ERASE << 16) | AMD_SETUP_ERASE;
        *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1;
        *(ptr32 + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2;
        *(ptr32 + (iSector >> 2)) = (AMD_BLOCK_ERASE << 16) | AMD_BLOCK_ERASE;
        
        // Now poll for the completion of the sector erase timer (50us)
        timeout = 10000000;              // how many retries?
        while (1) {
            if (((*(ptr32 + (iSector >> 2))) & AMD_SECTOR_ERASE_TIMER)
                    == AMD_SECTOR_ERASE_TIMER) break;

            if (--timeout == 0) {
                iResult = FLASH_ERR_DRV_TIMEOUT;
                break;
            }
        }

        // Then wait for erase completion.
        if (FLASH_ERR_OK == iResult) {
            timeout = 10000000;
            while (1) {
                if (0xffffffff == (*(ptr32 + (iSector >> 2)))) {
                    break;
                }

                // Don't check for FLASH_Err here since it will fail
                // with devices in parallel because these may finish
                // at different times.

                if (--timeout == 0) {
                    iResult = FLASH_ERR_DRV_TIMEOUT;
                    break;
                }
            }
        }

        if (FLASH_ERR_OK != iResult)
            *ptr32 = (AMD_RESET << 16) | AMD_RESET;
                
	} else{
	    // No such parameter.
        return 1;
    }
    		
	return iResult;
}


//****************************************************************************
// Name       : GetSectorIndex
// Description: This routine erase the sectors of intel.
// Arguments  : iOffset - the offset address.
//              len  - the length.
// Return     : 0 - succuss.
//              1 - failure.
// Note(s)    :
//****************************************************************************
int Amd_GetSectorIndex(struct FlashInfo *pInfo,long lStartAddress,
			unsigned long * pulSectorBase,int * piCurEraseRegion,
			int * piCurEraseBlock )
{
    unsigned short usByteWidth = pInfo->ByteWidth;
    int i, j;
    long iEraseBase = lStartAddress;
    
    *pulSectorBase = 0;
    
    if (usByteWidth == 1)
    {
        for(i = 0; i < pInfo->pQuery->NumEraseBlocks; i++) 
        {     
            for(j = 0; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) 
            {
		
		
                
                if(iEraseBase >= pInfo->pQuery->sBlockInfo[i].block_size) 
                {
                    *pulSectorBase = *pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size;
                    iEraseBase = iEraseBase - pInfo->pQuery->sBlockInfo[i].block_size;
                } 
                else 
                {
                    *piCurEraseRegion = i;
                    *piCurEraseBlock  = j;  
                    return 0;
                }

            }
        }
    }
    else if (usByteWidth == 2)
    {
        for(i = 0; i < pInfo->pQuery->NumEraseBlocks; i++) 
        {     
            for(j = 0; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) 
            {
                
                if(iEraseBase >= pInfo->pQuery->sBlockInfo[i].block_size*2) 
                {
                    *pulSectorBase = *pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size*2;
                    iEraseBase = iEraseBase - pInfo->pQuery->sBlockInfo[i].block_size*2;
                } 
                else 
                {
                    *piCurEraseRegion = i;
                    *piCurEraseBlock  = j;  
                    return 0;
                }

            }
        }    	
    } 
    else
    {
        // No such parameter.
        return 1;
    }

    return 1;        

}
//****************************************************************************
// Name       : AmdFlashErase
// Description: This routine erase the amd flash.
// Arguments  : iOffset - the offset address.
//              len  - the length.
// Return     : 0 - succuss.
//              1 - failure.
// Note(s)    :
//****************************************************************************
int AmdFlashErase(struct FlashInfo *pInfo, int iOffset, int len)
{
    volatile unsigned short *ptr16 = (volatile unsigned short *)pInfo->FlashBase;
    volatile unsigned long *ptr32 = (volatile unsigned long *)pInfo->FlashBase;	
    unsigned short usByteWidth = pInfo->ByteWidth;
    long i, j,iIdx;
    //long iEraseLen = len;
    //long iEraseBase = iOffset;
    unsigned long pulSectorBase=0,pulSectorEnd=0;
    int piCurEraseRegionStart=0,piCurEraseBlockStart=0,piCurEraseRegionEnd=0,piCurEraseBlockEnd=0;
    
    if(Amd_GetSectorIndex(pInfo,iOffset,&pulSectorBase,
    			&piCurEraseRegionStart, &piCurEraseBlockStart)==1)
	return 1;    
	
    if(Amd_GetSectorIndex(pInfo,iOffset+len,&pulSectorEnd,
    			&piCurEraseRegionEnd, &piCurEraseBlockEnd)==1)
	return 1; 
	
	
    if (usByteWidth == 1)
    {
	if(piCurEraseRegionStart!=piCurEraseRegionEnd)
	{
 	
        for(i = piCurEraseRegionStart; i <= piCurEraseRegionEnd; i++) 
        {             
             if(i==piCurEraseRegionStart)
             {
             	for(j = piCurEraseBlockStart; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) 
                {
		
 		    AmdFlashEraseSector(pInfo,pulSectorBase);
                
                    //
                    //#if 1
		    for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[i].block_size>>1); iIdx++)
             	    {
            	        if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff)
            	        {
              	    	    return 1;
            	        }
 
   	    	    }
   	    	    //#endif
   	    	     		
 		    pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size;

                }
             }
             else if(i==piCurEraseRegionEnd)
             {
              	for(j = 0; j<= piCurEraseBlockEnd; j++) 
                {
		
 		    AmdFlashEraseSector(pInfo,pulSectorBase);
                
                    //
                    //#if 1
		    for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[i].block_size>>1); iIdx++)
             	    {
            	        if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff)
            	        {
              	    	    return 1;
            	        }
 
   	    	    }
   	    	    //#endif
   	    	     		
 		    pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size;

                }            	
             }
             else
             {
             	for(j = 0; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) 
                {
		
 		    AmdFlashEraseSector(pInfo,pulSectorBase);
                
                    //
                    //#if 1
		    for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[i].block_size>>1); iIdx++)
             	    {
            	        if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff)
            	        {
              	    	    return 1;
            	        }
 
   	    	    }
   	    	    //#endif
   	    	     		
 		    pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size;

                }             
             }
            }
        }
        else
        {
      	    for(j = piCurEraseBlockStart; j<= piCurEraseBlockEnd; j++) 
            {
	
	        AmdFlashEraseSector(pInfo,pulSectorBase);
        
                //
                //#if 1
	        for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[piCurEraseRegionStart].block_size>>1); iIdx++)
     	        {
    	            if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff)
    	            {
      	    	        return 1;
    	            }

    	        }
    	        //#endif
    	     		
	        pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[piCurEraseRegionStart].block_size;

            }         	
        	
        }
        
        return 0; 
    }   
    //
    //32 bit
    //
    else if (usByteWidth == 2)
    {
	if(piCurEraseRegionStart!=piCurEraseRegionEnd)
	{
 	
            for(i = piCurEraseRegionStart; i <= piCurEraseRegionEnd; i++) 
            {             
                 if(i==piCurEraseRegionStart)
                 {
             	    for(j = piCurEraseBlockStart; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) 
                    {
		

⌨️ 快捷键说明

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