📄 device.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 + -