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

📄 write_idblock.c

📁 CBUF.LIB OVERVIEW: The circular buffers here are standard rotating FIFO buffers. THey are c
💻 C
📖 第 1 页 / 共 2 页
字号:

	//////////////////////////////////////////////////
	// 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 + -