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

📄 amd.c

📁 嵌入式系统 EP93xx处理器
💻 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 3static 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 + -