📄 comemadm.cpp
字号:
// This ComemAdm.cpp. It contains the EEPROM, timeout, and report error
// routines located in comemlit and used by Test3042.
//
#include "afxwin.h"
#include <sys\timeb.h>
#include <stdio.h>
#include "comemDevice.h"
int serial_device_addr = 0x50;
DWORD fakedata[0x100];
// Write data from the host to the co-mem
errcodeE writeComemL(DWORD addr, DWORD data, DWORD comemID)
{
if(PCIDPMemory[comemID])
PCIDPMemory[comemID][addr/4] = data;
// TBD -- fakedata is still used to save our state to the cfg file. Keep writing it.
fakedata[addr] = data;
return(NO_MAPPER_ERROR);
}
// Read data from the co-mem to the host
DWORD readComemL(DWORD addr, DWORD comemID)
{
if(PCIDPMemory[comemID])
return PCIDPMemory[comemID][addr/4];
else
return fakedata[addr];
}
int timeout(unsigned long time, unsigned timer)
{
#define DIVISOR 18L
static struct timeb oldtimebuff[10];
struct timeb timebuff;
/* get the time B4 we let them have control, so we get at least one*/
/* good one before a timeout occurs */
ftime(&timebuff);
if (time)
{
/* save current time */
memmove(&(oldtimebuff[timer]), &timebuff, sizeof(struct timeb));
if ((oldtimebuff[timer].millitm += (unsigned short)((time % DIVISOR) * 1000L/DIVISOR)) >= 1000)
{
oldtimebuff[timer].millitm -= 1000;
time += DIVISOR;
}
oldtimebuff[timer].time += time / DIVISOR;
return(0);
}
if (timebuff.time > oldtimebuff[timer].time)
return(1);
if (timebuff.time == oldtimebuff[timer].time)
if (timebuff.millitm > oldtimebuff[timer].millitm)
return(1);
return(0);
}
errcodeE wait_eeprom(int type, DWORD comemID)
{
int readdata;
for (timeout(2, FOREGROUND_TIMER);
!timeout(0, FOREGROUND_TIMER);)
;
for (readdata = 0, timeout(ONE_SECOND, FOREGROUND_TIMER);
(!(readdata & SERIAL_REG2_DONE_BIT));
readdata = readComemL(ADDR_NVSTAT, comemID))
if (timeout(0, FOREGROUND_TIMER))
{
// timed out -- try to read one more time, then report failure.
readdata = readComemL(ADDR_NVSTAT, comemID);
if (!(readdata & SERIAL_REG2_DONE_BIT))
{
return(ERROR_EEPROM_TIMEOUT);
}
}
// Now check to see if we received three ACKs -- one for device address, one for device data, one for value
int mask;
if (type == EEPROM_READ)
mask = SERIAL_WRITE_ACK_MASK;
else
mask = SERIAL_READ_ACK_MASK;
if (readdata & mask)
{
report_error("Missed ACK -- Could be caused by an address beyond the eeprom boundaries or by more than one master device on the EEPROM bus. If there is more than one master device, add retry code on missing ACKs.");
return(ERROR_EEPROM_MISSED_ACK);
}
return(NO_MAPPER_ERROR);
}
void reportErrorCode(DWORD status, char * whereAmI)
{
char buf[0x1000];
switch(status)
{
case ERROR_INVALID_REGION:
strcpy(buf, "Invalid region detected");
break;
case ERROR_INVALID_ADDIN_ADDR:
strcpy(buf, "Invalid Local processor address detected");
break;
case ERROR_OVERLAID_REGION:
strcpy(buf, "Region was totally obscured by another");
break;
case ERROR_BAD_PAGE_TABLE:
strcpy(buf, "Bad page table detected");
break;
case ERROR_MEMORY_ALLOC:
strcpy(buf, "Memory allocation error");
break;
case ERROR_ALLOC_EXISTS:
strcpy(buf, "Memory alread allocated. Must deallocate before allocating.");
break;
case ERROR_NO_DRIVER:
strcpy(buf, "Driver is not resident");
break;
case ERROR_INVALID_COMEM_ID:
strcpy(buf, "Invalid comem ID");
break;
case ERROR_DEVICE_NOT_FOUND:
strcpy(buf, "Device not found");
break;
case ERROR_UNKNOWN:
strcpy(buf, "Unknown error code detected");
break;
default:
sprintf(buf, "Encountered error code (%d)", status);
//strcpy(buf, "An error was reported that is not in our table");
break;
}
if (whereAmI)
{
strcat(buf, " while ");
strcat(buf, whereAmI);
}
else
strcat(buf, ".");
AfxMessageBox(buf, MB_OK | MB_ICONEXCLAMATION);
}
void report_error(const char *fmt, ...)
{
char buf[0x1000];
va_list va;
va_start( va, fmt );
vsprintf( buf, fmt, va );
va_end( va );
AfxMessageBox(buf, MB_OK | MB_ICONEXCLAMATION);
}
// Write a block of memory to the eeprom
errcodeE writeEepromL(DWORD addr, unsigned char *blockptr, DWORD size, DWORD comemID)
{
errcodeE error;
if (addr + size > MAX_EEPROM_ADDR)
report_error("writeEeprom() passed bad address. Start = 0x%x, size = 0x%x", addr, size);
while (size--)
{
int readdata = 0;
writeComemL(ADDR_NVCMD,
(serial_device_addr << (24)) |
((addr & (EEPROM_ADDR_MASK-1)) << 16) | // This may overlap the device address in large devices
(*blockptr) << 8 |
EEPROM_WRITE_ENABLE, comemID);
// Wait for the device to be done
error = wait_eeprom(EEPROM_READ, comemID);
if (error == ERROR_EEPROM_TIMEOUT)
report_error("Timed out writing address 0x%x in EEPROM.", addr);
if (error != NO_MAPPER_ERROR)
return error;
blockptr++;
addr++;
}
return(NO_MAPPER_ERROR);
}
// Read a block of memory from the eeprom
// The user is responsible for determining if the address is within the EEPROM, since this software
// must support very large devices.
errcodeE readEepromL(DWORD addr, unsigned char *blockptr, DWORD size, DWORD comemID)
{
errcodeE error;
char *byteptr;
DWORD inData;
while (size)
{
writeComemL(ADDR_NVCMD,
(serial_device_addr << (24)) |
((addr & (EEPROM_ADDR_MASK-1)) << 16) | // This may overlap the device address in large devices
EEPROM_4READ_ENABLE, comemID);
// Wait for the device to be done
error = wait_eeprom(EEPROM_READ, comemID);
if (error == ERROR_EEPROM_TIMEOUT)
report_error("Timed out reading address 0x%x in EEPROM.", addr);
if (error != NO_MAPPER_ERROR)
return error;
// TBD -- processing blocks that span multiple EEPROMs.
// Save the data that was requested. Be careful to only store the requested data.
// The EEPROM address may be misalined. The EEPROM doesn't care.
inData = readComemL(ADDR_NVREAD, comemID);
byteptr = (char *) &inData;
for (int i = 0; i < 4 && size; i++, size--)
{
*blockptr++ = *byteptr++;
}
addr += 4;
}
return(NO_MAPPER_ERROR);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -