All pastes #1748306 Raw Edit

Stuff

public text v1 · immutable
#1748306 ·published 2010-01-12 14:45 UTC
rendered paste body
	// プログラムのチェック
#define CHECKSUM_ENABLED 0x7f /* ここのEEPROMアドレスにかかれているバイトが0ならばチェックサムのチェックをする */
#define CHECKSUM_H 0x7e /* チェックサム(h)のかかれているEEPROMアドレス */
#define CHECKSUM_L 0x7d /* チェックサム(l)のかかれているEEPROMアドレス */
#define PROGRAM_SIZE 2048 /* プログラムメモリのサイズ */
	if(eeprom_read_byte((const uint8_t*)CHECKSUM_ENABLED) == 0)
	{
		unsigned char sum_l = 0, sum_h = 0;
		unsigned short addr = PROGRAM_SIZE;
		while(--addr)
		{
			unsigned char b = pgm_read_byte(addr);
			sum_l += b;
			sum_h += sum_l;
		}
		if(sum_l != eeprom_read_byte((const uint8_t*)CHECKSUM_L) ||
			eeprom_read_byte((const uint8_t*)CHECKSUM_H))
		{
			for(;;) ; /* エラー */
		}
	}


/*------ 上と等価 ------*/


	asm volatile(
"ldi		r21,	%4"				"\n"
"rcall .pgmcheck_read_eeprom"		"\n"
"and		r16, r16"				"\n"
"brne		.pgmcheck_end"			"\n" /* eeprom(CHECKSUM_ENABLED) != 0 then end */ 
"ldi		r16,	0"				"\n" /* r17 and r16 : checksums */
"ldi		r17,	0"				"\n"
"movw		r30,	r16"			"\n" /* r30 : program addr */
"ldi		r24,	%7"				"\n" /* r25:r24 : loop counter */
"ldi		r25,	%8"				"\n"
".pgmcheck_loop:"					"\n"
"lpm		r20,	Z+"				"\n" /* read from program memory */
"add		r16,	r20"			"\n" /* checksumming */
"add		r17,	r16"			"\n" /* checksumming */
"sbiw		r24,	1"				"\n" /* loop counter -- */
"brne		.pgmcheck_loop"			"\n" /* loop not end ? then loop */
"ldi		r21,	%5"				"\n"
"rcall .pgmcheck_read_eeprom"		"\n"
"sub		r16, r21"				"\n" /* check sum l correct ? */
"brne		.-2"					"\n" /* not then, inifinite loop */
"ldi		r21,	%6"				"\n"
"rcall .pgmcheck_read_eeprom"		"\n"
"sub		r17, r21"				"\n" /* check sum h correct ? */
"brne		.-2"					"\n" /* not then, infinite loop */
"rjmp		.pgmcheck_end"			"\n"
".pgmcheck_read_eeprom:"			"\n" /* sub routine to read eeprom */
"out		%2, r21"				"\n"
"sbi		%0, %1"					"\n"
"in			r21, %3"				"\n"
"ret"								"\n"
".pgmcheck_end:"					"\n"
:
:
	/*%0*/"M"(_SFR_IO_ADDR(EECR)),
	/*%1*/"M"(EERE),
	/*%2*/"M"(_SFR_IO_ADDR(EEARL)),
	/*%3*/"M"(_SFR_IO_ADDR(EEDR)),
	/*%4*/"M"(CHECKSUM_ENABLED),
	/*%5*/"M"(CHECKSUM_H),
	/*%6*/"M"(CHECKSUM_L),
	/*%7*/"M"(PROGRAM_SIZE>>8),
	/*%8*/"M"(PROGRAM_SIZE&0xff)
:"r16", "r17", "r18", "r19", "r20", "r21", "r24", "r25", "r30", "r31" 
	);