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

📄 device.c

📁 AMD公司官方版FLASH文件系统。有详细说明文档和Windows仿真测试环境。
💻 C
字号:
/**
 *    Device.c
 */

#include "Device.h"
#include "Vendor.h"

#ifndef HIBYTE
    #define HIBYTE(w)   ((BYTE) (((WORD) (w) >> 8) & 0xFF))  
#endif

#ifndef LOBYTE
    #define LOBYTE(w)   ((BYTE) (w))  
#endif

/**
 *    Private Functions
 */

void dms_lDeviceSendReset(WORD *pFlashData);


/**
 *    dms_DeviceRead
 */
DMS_STATUS dms_DeviceRead (DWORD adwAddress, WORD awByteCount, BYTE *apBuffer)
{
    WORD    wBytesRead;
    WORD    *pwFlashData;    /* Used to point at the memory  */

    //pwFlashData = dms_VendorMapPage(adwAddress);
    // dmsdbg_Printf("  Device pData = 0x%X\n",pwFlashData);
    if (pwFlashData == NULL){
      return Device_Memory_Map_Error;
    }

    dms_lDeviceSendReset(pwFlashData);

    wBytesRead = 0;
    while (wBytesRead < awByteCount) {
        /*** Word Mode ***/
        if ( ((DWORD)pwFlashData) & 0x01 ) {
            pwFlashData = (WORD*)(((BYTE*)pwFlashData) - 1);
            apBuffer[0] = HIBYTE(*pwFlashData++);
            wBytesRead++;
        } else if (wBytesRead   == awByteCount - 1 ) {
            apBuffer[wBytesRead] = LOBYTE(*pwFlashData++);
            wBytesRead++;
        } else {        
            /*** Copy both bytes into the buffer ***/
            *((WORD*)(apBuffer+wBytesRead)) = *pwFlashData++;
            wBytesRead+=2;
        }
    }
    return No_Error;
}

/**
 *    dms_DeviceWrite
 */
DMS_STATUS dms_DeviceWrite (DWORD adwAddress, WORD awByteCount, BYTE *apBuffer)
{
    WORD    wDataToWrite;
    WORD    wVerifyChar;
    WORD    wBytesWritten;
    WORD    wCount;
    WORD    *pwFlashChip;
    WORD    *pwFlashData;    /***    Used to point at the memory 
                                    mapped region on the device ***/
   // pwFlashData = dms_VendorMapPage(adwAddress);
    if (pwFlashData == NULL){
      return Device_Memory_Map_Error;
    }

  //  pwFlashChip = dms_VendorMapChip(adwAddress);
    if (pwFlashChip == NULL){
      return Device_Memory_Map_Error;
    }

    dms_lDeviceSendReset(pwFlashData);

    wBytesWritten = 0;
    while (wBytesWritten < awByteCount)
    {
        /*** Base Address for this write ***/
        if (((DWORD)pwFlashData) & 0x01) {
            pwFlashData = (WORD*)(((BYTE*)pwFlashData) - 1);
            wVerifyChar = *pwFlashData;
            wDataToWrite = (((WORD)(apBuffer[wBytesWritten])) << 8) | (wVerifyChar & 0x00FF);
            wBytesWritten++;
        } else if (wBytesWritten == awByteCount -1) {
            wVerifyChar = *pwFlashData;
            // dmsdbg_Printf("  Device verify char 0x%04X at address 0x%X\n",wVerifyChar,pwFlashData);
            wDataToWrite = ((WORD)(apBuffer[wBytesWritten])) | (wVerifyChar & 0xFF00);        
            wBytesWritten++;
        } else {                
            wVerifyChar = *pwFlashData;
            wDataToWrite = apBuffer[wBytesWritten] + (((WORD)(apBuffer[wBytesWritten+1])) << 8);
            wBytesWritten +=2;
        }                   
        /*** Verify that we aren't trying to turn a zero into a one ***/
        if ( ( (wVerifyChar ^ wDataToWrite) | wVerifyChar) != wVerifyChar) {
            return Device_Invalid_Data;
        }
            
        /*** Send the Flash Write Sequence to the device ***/
        pwFlashChip[0x5555] = AM29DL_UNLOCK1;                    
        pwFlashChip[0xAAAA] = AM29DL_UNLOCK2;            
        pwFlashChip[0x5555] = AM29DL_PROGRAM_CMD;
        *pwFlashData++ = wDataToWrite;
        // dmsdbg_Printf("Writing data 0x%X at address 0x%X\n",wDataToWrite,&(pwAddress[wOffset]));
          
        wCount = 0;
        while( dms_DeviceIsBusy(pwFlashData-1) != Device_Not_Busy ) {
            wCount++;
            if (wCount > 10000) break;
        }
        if (wCount > 9999) {
            return Device_Write_Failed;
        }
    }
    return No_Error;
}


/**
 *  dms_DeviceErase
 */
DMS_STATUS dms_DeviceErase(DWORD adwAddress)
{
    WORD *pwFlashChip;
    WORD *pwFlashSector;
  
    //pwFlashChip = dms_VendorMapChip(adwAddress);
    if (pwFlashChip == NULL) {        
      return Device_Memory_Map_Error;
    }
   // pwFlashSector = dms_VendorMapPage(adwAddress);
    if (pwFlashSector == NULL) {        
      return Device_Memory_Map_Error;
    }

    pwFlashChip[0x5555] = AM29DL_UNLOCK1;
    pwFlashChip[0xAAAA] = AM29DL_UNLOCK2;
    pwFlashChip[0x5555] = AM29DL_ERASE_CMD1;
    pwFlashChip[0x5555] = AM29DL_UNLOCK1;
    pwFlashChip[0xAAAA] = AM29DL_UNLOCK2;
    pwFlashSector[0] = AM29DL_ERASE_CMD2;
    while( dms_DeviceIsBusy(pwFlashSector) != Device_Not_Busy ) {}
    return No_Error;
}

/**
 *    dms_DeviceFinalize
 */
void dms_DeviceFinalize(void)
{
    /*** Shutdown the Vendor Layer ***/
//    dms_VendorFinalize();
}


/**
 *
 *    dms_DeviceIsBusy
 *
 *    DESCRIPTION
 *    This function is used to determine if there is an 
 *    asynchronous event in progress on the Flash Media
 *
 *    This function was taken from the DL-DEMO
 *    source code provided by AMD. 
 *
 *    RETURN CODES 
 *    Device_Not_Busy        The device is not busy 
 *                        performing another operation
 *    Device_Write_In_Progress
 *                        A write is in progress on the 
 *                        device
 *    Device_Erase_In_Progress    
 *                        An erase is in progress on the 
 *                        device
 */
DMS_STATUS dms_DeviceIsBusy(void* pAddress)
{

    BYTE d, t;
    WORD wRetry = 1;
    void *pMem;
    int iStatus;

    pMem = pAddress;
    if (pMem == NULL) {        
      return Device_Memory_Map_Error;
    }

    again:

    /*** read data from Device ***/
     d = * (BYTE *)pMem;

    /*** Read data again -- see what toggled ***/
    t = (BYTE) (d ^ * (BYTE *)pMem);


    iStatus = DS_ERROR;
    
    switch(t)
    {
    case 0:
        /*** no toggles, nothing's happening ***/
        iStatus = DS_READY;
        break;

    case 0x04:
        /*** erase-suspend ***/
        if (wRetry--)
        {
            /*** may have been write completion ***/
            goto again;    
        }
        iStatus = DS_ERSUSP;
        break;

    case 0x40:        
        iStatus = (d & 0x20) ? DS_TIMEOUT : DS_BUSY;            
        break;
    }
    
    /*** may have been write completion ***/
    if (wRetry--) goto again;

    switch(iStatus)
    {
    case DS_READY:            
    case DS_ERSUSP:
        return Device_Not_Busy;
        break;
        
    case DS_TIMEOUT:
        return Device_Confused;
        break;
            
    default:
        return Device_Erase_In_Progress;
        break;    
    }    
}


/**
 *  dms_lDeviceSendReset
 */
void dms_lDeviceSendReset(WORD *apwFlashData)
{
    apwFlashData[0] = 0xF0;   /* reset device to read mode */
}

⌨️ 快捷键说明

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