📄 write_idblock.c
字号:
//////////////////////////////////////////////////
// set up the ID block fields
memset(&SysIDBlock, 0x00, sizeof(SysIDBlock));
#if (CC_VER < 0x0726)
SysIDBlock.tableVersion = 2;
#else
SysIDBlock.tableVersion = 4;
#endif
SysIDBlock.vendorID = 1;
setTimeStamp();
SysIDBlock.idBlockSize = sizeof(SysIDBlock);
for (i=0; i<3; i++) {
SysIDBlock.marker[i*2] = 0x55;
SysIDBlock.marker[i*2+1] = 0xAA;
}
//////////////////////////////////////////////////
// board-specific data
SysIDBlock.productID = MYBOARD;
SysIDBlock.flashID = getFlashID();
SysIDBlock.flashSize = _FLASH_SIZE_;
SysIDBlock.flashType = _FlashInfo.writeMode;
SysIDBlock.sectorSize = _FlashInfo.sectorSize;
SysIDBlock.numSectors = _FlashInfo.numSectors;
SysIDBlock.flashSpeed = 0x00; // special case, means "unknown"
if (Has2Flash()) {
// we assume that the 2nd flash (if installed) flash
// is identical to the first one
SysIDBlock.flash2ID = SysIDBlock.flashID;
SysIDBlock.flash2Size = _FLASH_SIZE_;
SysIDBlock.flash2Type = _FlashInfo.writeMode;
SysIDBlock.sector2Size = _FlashInfo.sectorSize;
SysIDBlock.num2Sectors = _FlashInfo.numSectors;
SysIDBlock.flash2Speed = 0x00; // special case, means "unknown"
}
SysIDBlock.ramID = 0x01;
SysIDBlock.ramSize = _RAM_SIZE_;
SysIDBlock.ramSpeed = 0x00; // special case, means "unknown"
SysIDBlock.cpuID = getCPUID(); // Rabbit 2000 CPU
#if (CC_VER < 0x0730)
div19200ptr = divider19200;
SysIDBlock.crystalFreq = (*div19200ptr) * 614400ul;
#else // functionality change with 7.30 (improved :v)
SysIDBlock.crystalFreq = (divider19200) * 614400ul;
#endif
// may fill serial number and product name here (future)
// reserve space for the user block here
if (HASUSERBLOCK) {
SysIDBlock.userBlockSize = 0x4000 - (int)SysIDBlock.idBlockSize;
SysIDBlock.userBlockLoc = 0x4000 - (int)SysIDBlock.idBlockSize;
} else {
SysIDBlock.userBlockSize = 0x0000;
SysIDBlock.userBlockLoc = 0x0000;
}
// fill MAC address
if (HasEthernet() && !HasEEPROM())
memcpy(SysIDBlock.macAddr, MAC, 6);
else
memset(SysIDBlock.macAddr, 0x00, 6);
//////////////////////////////////////////////////
// calculate the ID block's CRC sum
SysIDBlock.idBlockCRC = 0x0000;
i = (int)(&SysIDBlock.reserved) - (int)(&SysIDBlock.tableVersion);
crc = calcCRC(0x0000, &SysIDBlock, i);
crc = calcCRC(crc, &SysIDBlock.idBlockSize, 16);
SysIDBlock.idBlockCRC = crc;
//////////////////////////////////////////////////
// write the ID Block(s) to flash
i = writeIDBlock();
if (i != 0) {
printf("\nError writing ID block (%d): \n", i);
if (i == -1) printf(" attempt to write to non-flash area\n");
else if (i == -2) printf(" source not located in root\n");
else if (i == -3) printf(" timeout during flash write\n");
else printf(" unknown error type\n");
exit(1);
} else {
printf("\nID block successfully written.\n\n");
}
//////////////////////////////////////////////////
// now try and read the ID block back...
memset(&SysIDBlock, 0x00, sizeof(SysIDBlock));
i = _readIDBlock(0x01 | 0x02);
if (i != 0) {
printf("Error reading ID block (%d)\n", i);
exit(1);
} else {
printf("ID block read successfully:\n");
printf(" Version = %d\n", SysIDBlock.tableVersion);
printf(" ID block size = %d bytes\n", SysIDBlock.idBlockSize);
printf(" Product ID = 0x%04X\n", SysIDBlock.productID);
printf(" Vendor ID = %d\n", SysIDBlock.vendorID);
printf(" Timestamp = %02d/%02d/%02d%02d %02d:%02d:%02d\n",
SysIDBlock.timestamp[2], SysIDBlock.timestamp[3],
SysIDBlock.timestamp[0], SysIDBlock.timestamp[1],
SysIDBlock.timestamp[4], SysIDBlock.timestamp[5],
SysIDBlock.timestamp[6]);
printf("\n");
printf(" CPU = Rabbit ");
if (SysIDBlock.cpuID < 0x0100) printf("2000\n");
else if (SysIDBlock.cpuID == 0x0100) printf("3000\n");
else printf("????\n");
printf(" Crystal Freq = %8.4f MHz\n", SysIDBlock.crystalFreq/1.0e6);
printf(" Serial number = '%s'\n", SysIDBlock.serialNumber);
printf(" Product name = '%s'\n", SysIDBlock.productName);
printf(" MAC address = %02X:%02X:%02X:%02X:%02X:%02X\n",
SysIDBlock.macAddr[0], SysIDBlock.macAddr[1],
SysIDBlock.macAddr[2], SysIDBlock.macAddr[3],
SysIDBlock.macAddr[4], SysIDBlock.macAddr[5]);
printf("\n");
printf(" User block offset = %04x\n", SysIDBlock.userBlockLoc);
printf(" User block size = %04x\n", SysIDBlock.userBlockSize);
printf("\n");
printf(" Flash 1 information:\n");
printf(" ID = 0x%04X\n", SysIDBlock.flashID);
printf(" Type = %d\n", SysIDBlock.flashType);
printf(" Size = %ld\n", SysIDBlock.flashSize * 4096ul);
printf(" Sector size = %d bytes\n", SysIDBlock.sectorSize);
printf(" Num sectors = %d\n", SysIDBlock.numSectors);
printf("\n");
if (SysIDBlock.flash2ID == 0x0000) {
printf(" No second flash\n");
} else {
printf(" Flash 2 information:\n");
printf(" ID = 0x%04X\n", SysIDBlock.flash2ID);
printf(" Type = %d\n", SysIDBlock.flash2Type);
printf(" Size = %ld\n", SysIDBlock.flash2Size * 4096ul);
printf(" Sector size = %d bytes\n", SysIDBlock.sector2Size);
printf(" Num sectors = %d\n", SysIDBlock.num2Sectors);
}
printf("\n");
printf(" RAM Information:\n");
printf(" ID = 0x%04X\n", SysIDBlock.ramID);
printf(" Size = %ld bytes\n", SysIDBlock.ramSize * 4096ul);
}
//////////////////////////////////////////////////
// restore memory quadrant 1
WrPortI(MB1CR, &MB1CRShadow, saveMB1);
}
/********************************************************************/
int writeIDBlock()
{
static unsigned long physaddr;
static int addr, blockSize;
static char xpc;
static int err;
blockSize = sizeof(SysIDBlock);
physaddr = 0x00080000ul - blockSize;
addr = 0xE000 + (int)(physaddr & 0x0FFFul);
xpc = (int)(((physaddr - (unsigned long)addr) & 0xFF000ul) >> 12ul);
_overwrite_block_flag = 1;
err = WriteFlash(physaddr, &SysIDBlock, blockSize);
_overwrite_block_flag = 0;
return(err);
}
/********************************************************************/
int getFlashID()
{
static int id;
#asm
call _GetFlashID
ld (id), hl
#endasm
return(id);
}
/********************************************************************/
int getCPUID()
{
static int id;
#asm
ioi ld a, (GCPU)
and 0x1F
ld (id+1), a
ioi ld a, (GREV)
and 0x1F
ld (id), a
#endasm
return(id);
}
/********************************************************************/
int setTimeStamp()
{
static struct tm t;
tm_rd(&t);
SysIDBlock.timestamp[0] = (t.tm_year + 1900) / 100;
SysIDBlock.timestamp[1] = t.tm_year % 100;
SysIDBlock.timestamp[2] = t.tm_mon;
SysIDBlock.timestamp[3] = t.tm_mday;
SysIDBlock.timestamp[4] = t.tm_hour;
SysIDBlock.timestamp[5] = t.tm_min;
SysIDBlock.timestamp[6] = t.tm_sec;
}
/********************************************************************/
#define CRC_POLY 0x1021 // 16-bit CRC polynomial
// (recommended by CCITT X25 standard)
/*
* CRC calculation functions
* - can be called from C (calcCRC) or assembly (_calcCRC)
* - reference: "A painless guide to CRC error detection algorithms",
* 8/19/1993, Ross N. Williams
*/
#asm
// int calcCRC(int initCRC, void *data, int blocksize);
calcCRC::
ld hl, 2
add hl, sp
ld hl, (hl)
ex de, hl ; initial CRC value
ld hl, 6 ; the "blocksize" variable
add hl, sp
ld hl, (hl)
ld b, h
ld c, l ; get data size off stack
ld hl, 4 ; the "data" variable
add hl, sp
ld hl, (hl) ; hl now contains pointer to data
;; assembly entry point
_calcCRC::
; de contains initial CRC value
; hl contains pointer to data
; bc contains number of bytes
dataloop:
push hl
ld h, (hl) ; get next byte into hl (and shift it left 8 bits)
ld l, 0x00
push bc ; save byte counter
call _byteCRC ; call CRC function from BIOS
pop bc ; restore byte counter
pop hl
inc hl
dec bc
xor a
cp b
jr nz, dataloop
cp c
jr nz, dataloop
ex de, hl ; CRC returned in hl
ret
#endasm
//////////////////////////////////////////////////////////////////////
#asm
;;
;; Calculate the CRC value for a single byte. Can be called multiple
;; times (without resetting the CRC value passed to it) to do a CRC
;; check on a larger block of data.
;;
;; data byte passed in h (l should be 0x00)
;; crc value passed, returned in de
;;
_byteCRC::
push bc
push af
ld b, 0x08 ; bit counter
crcloop:
push bc ; save bit counter
ld a, h
xor d
scf
ccf ; clear carry bit
rl de ; roll crc left one bit
ex de, hl
scf
ccf ; clear carry bit
rl de ; roll data left one bit
ex de, hl
bit 7, a ; result from earlier XOR
jr z, bit7iszero
bit7isone:
ld bc, CRC_POLY ; recommended 16-bit polynomial (X.25)
ld a, e
xor c
ld e, a
ld a, d ; XOR crc with polynomial
xor b
ld d, a
bit7iszero:
pop bc ; restore bit counter
djnz crcloop
pop af
pop bc
ret
#endasm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -