
AVRASM ver. 1.11  EKEY.ASM Tue Jul 04 11:38:28 2000


         ;****************************************************************
         ;                  	E-key
         ;         a Dallas IButton (tm) based Electronic key
         ;****************************************************************
         ;
         ;Programmer :  Philippe GROS
         ;Date       :  01 Sept 1999
         ;Version    :  V1.7
         ;
          .DEVICE	AT90S1200	;set processor type
         
          .NOLIST
          .include "const.asm"
         ;****************************************************************
         ;Constant and macro definitions
          .equ	GetSN	=0x033	;IB Command Byte
          .equ	w1us	=4
         
         ;Application Constant definitions
          .def	FamCode		=r0	;family code
          .def	SN0		=r1	;Serial Num Byte 1 LSByte
          .def	SN1		=r2	;Serial Num Byte 2
          .def	SN2		=r3	;Serial Num Byte 3
          .def	SN3		=r4	;Serial Num Byte 4
          .def	SN4		=r5	;Serial Num Byte 5
          .def	SN5		=r6	;Serial Num Byte 6 MSByte
          .def	RdCRC		=r7	;Readen CRC
          .def	CalcCRC		=r8	;Computed CRC
          .def	SREGsav		=r9	;To save status reg when INT0 received
          .def	KeyProc		=r10	;Key nb processed
         ;.def			=r11
         ;.def			=r12
         ;.def			=r13
         ;.def			=r14
         ;.def			=r15
          ;------------------------------
          .def	r_cntH		=r16	;High part of counter
          .def	r_cntL		=r17	;Low part of counter
          .def	mail		=r18	;rxd has arrived
          .def	r_CD		=r19	;for Command or Data byte
          .def	r_BitCntr	=r20	;BIT Counter
          .def	r_BytCntr	=r21	;BYTE Counter
         ;.def			=r22
          .def	Pointer		=r23
          .def	hex_buf		=r24
          .def	offset		=r24	;
          .def	Scratch1	=r25	;
          .def	Scratch2	=r26	;
          .def	scnt		=r27
          .def	sbuf		=r28	;send buffer
          .def	rbuf		=r29	;receive buffer
          .def	r_Zreg		=r30 	;Z Register
          .def	rFlags		=r31	;
         ;
         ; rFlags definitions
          .equ	SCpend		=$01	;if 1, S Command is pending 
          .equ	CsumEr		=$02	;if 1, NVRAM Checksum has occured
         
         ;***********************************************************
         ;                           Macros
          .macro	WLOOP		;Long Loop (N=1,342*T)
          	ldi	r_cntH,@1
          mwl0:	ldi	r_cntL,@0
          mwl1:	dec	r_cntL
          	brne	mwl1
          	dec	r_cntH
          	brne	mwl0
          .endmacro
         
          .macro	WsLOOP		;Short Loop (N=1,3*T)
          	ldi	r_cntL,@0
          mwsl0:	dec	r_cntL
          	brne	mwsl0
          .endmacro
         
         
         ;****************************************************************
         ;*
         ;*   Program starts here
         ;*
         ;****************************************************************
          .cseg
          .org	0x0000
000000 c001      rjmp	start		;Reset Handler
         
         ;.org	INT0addr
000001 c0d7      rjmp	ext_int0	;External Interrupt Handler
         
         
         ;****************************************************************
          start:
000002 e830      	ldi	r_CD,0b10000000		;disable analog comparator
000003 b938      	out	ACSR,r_CD
         	  ;pb0,pb1=out AND high level (1)
         	  ;pb2    =out AND high level (LED OFF)
         	  ;pd0=out(TxD), pd1=input(RxD)
         	  ;pd2=in AND High level (activate internal pullup)
000004 e037      	ldi	r_CD,0b00000111		;Port B 0=input, 1=output
000005 bb37      	out	DDRB,r_CD
000006 e033      	ldi	r_CD,0b00000011		;inactive relays (0,1), led ON(2)
000007 bb38      	out	PORTB,r_CD
000008 e031      	ldi	r_CD,0b00000001		;PD0=out(txd),PD1=in(rxd)
000009 bb31      	out	DDRD,r_CD
00000a e035      	ldi	r_CD,0b00000101		;
00000b bb32      	out	PORTD,r_CD
00000c e0f0      	ldi	rFlags,0		;init rFlags to 0
          CheckNVR:       ;Check nvram consistency
00000d e070      	ldi	pointer,$00	;start from 00
00000e 2e87      	mov	CalcCRC,pointer	;init CRC to 0
00000f e450      	ldi	r_BytCntr,64	;64 bytes to check
000010 bb7e      Chk01:	out	EEAR,pointer	;place address to the register
000011 d16f      	rcall	RDeeprom
000012 b33d      	in	r_CD,EEDR	;load register to r_CD
000013 d1cb      	rcall	Do_CRC		;compute CRC
000014 9573      	inc	pointer		;next nvram location
000015 955a      	dec	r_BytCntr	;all bytes checked?
000016 f7c9      	brne	Chk01		;no, branch
000017 2088      	tst	CalcCRC		;valid result is 00
000018 f019      	breq	InitINT		;Checksum OK, continue
         		;a nvram checksum error has occured
000019 60f2      	sbr	rFlags,CsumER	;set flag CsumER (bit 1)
              ;Init WatchDog
00001a e03f      	ldi	r_CD,0b00001111	;Enable WD and set prescaler to 2048000cycles
00001b bd31      	out	WDTCR,r_CD	;To Watchdog Timer control register
              ;Interrupt initializing
          InitINT:
00001c e032              ldi	r_CD,0b00000010
00001d bf35              out	MCUCR,r_CD	;falling edge trigger on INT0
00001e e430              ldi	r_CD,$40
00001f bf3b              out	GIMSK,r_CD	;enable interrupt INT0
000020 9478      	sei			;enable interrupts
000021 c0a4      	rjmp	CRLF		;print signon and wait for command
         
          idle:	;Here we are waiting for the IB Presence detect, or receiving 
         	;character from the serial interface. 
000022 2722      	clr	mail
          iidle:
000023 95a8      	wdr			;Watchdog Reset
000024 fdf1      	sbrc	rFlags,$01	;skip if NVram Checksum OK
000025 9ac2      	sbi	PORTB,$02	;PB2 set to 1 (Turn the LED: OFF)
000026 2322      	tst	mail		;check if character received from serial line
000027 f3d9      	breq	iidle
000028 2722      	clr	mail		;YES a char has been received
000029 2fcd      	mov	sbuf,rbuf	;echo it
00002a d169      	rcall	out_char	;to txd
00002b 34d1      	cpi	rbuf,$41	;'A'
00002c f409      	brne	TstC
00002d c00d      	rjmp	Acmd
00002e 34d3      TstC:	cpi	rbuf,$43	;'C'
00002f f409      	brne	TstD
000030 c021      	rjmp	Ccmd
000031 34d4      TstD:	cpi	rbuf, $44	;'D'
000032 f409      	brne	TstS
000033 c033      	rjmp	Dcmd
000034 35d3      TstS:	cpi	rbuf,$53	;'S'
000035 f409      	brne	TstZ
000036 c047      	rjmp	Scmd
000037 35da      TstZ:	cpi	rbuf,$5A	;'Z'
000038 f409      	brne	TstErr
000039 c068      	rjmp	Zcmd
          TstErr:				;not a valid command, ignore
00003a c080      	rjmp	CmdErr		;send * with CR and LF
         
         ;****************************************************************
         ;       Command processing routines
         	;AnXXYY	n=key number, XX=action relay 1, YY=action relay 2
         	;       XX=00 no action, increment: 1 second (approx)      *
         	;Cn     Clear key number "n"                               * 
         	;D	Dump: print out all the eeprom informations
         	;	the seven serial key number, with action relays
         	;Sn	Acquire a serial number to key "n"                 *
         	;Z	Zero all counters, SN keys.                        *
                 ; * = This command update the eeprom CRC
         
         ;----------------------------------------------------------------
         	;AnXXYY	n=key number, XX=action relay 1, YY=action relay 2
         	;       XX=00 no action, increment: 1 second
00003b d169      Acmd:	rcall	fetchca		;wait for a char from input
00003c 70d7      	andi	rbuf,$07	;1 to 7 valid
00003d 23dd      	tst	rbuf
00003e f409      	brne	Acmd1
00003f c07b      	rjmp	CmdErr		;Error, drop command
000040 95da      Acmd1:	dec	rbuf		;use 0 to 6
000041 2f7d      	mov	pointer,rbuf	;key number
000042 0f77      	lsl	pointer		;compute eeprom address
000043 0f77      	lsl	pointer
000044 0f77      	lsl	pointer
000045 e086      	ldi	offset,$06	;load offset
000046 0f78      	add	pointer,offset	;location for xx relay timing
000047 e0e1      	ldi	r_Zreg,1	;SN starts at the address 1
000048 d163      	rcall	fetchhex	;get relay1 hex value 
000049 bb8d      	out	EEDR,hex_buf	;to eeprom data register
00004a bb7e      	out	EEAR,pointer	;address in eeprom
00004b d139      	rcall	WReeprom
00004c 9573      	inc	pointer
00004d d15e      	rcall	fetchhex
00004e bb8d      	out	EEDR,hex_buf	;to eeprom data register
00004f bb7e      	out	EEAR,pointer	;address in eeprom
000050 d134      	rcall	WReeprom
000051 c059      	rjmp	UpdEEcrc	;OK, update CRC and terminate
         ;----------------------------------------------------------------
         	;Cn     Clear key number "n"
000052 d152      Ccmd:	rcall	fetchca		;wait for a char from input
000053 70d7      	andi	rbuf,$07	;1 to 7 valid
000054 23dd      	tst	rbuf
000055 f409      	brne	Ccmd1
000056 c064      	rjmp	CmdErr		;Error, drop command
000057 95da      Ccmd1:	dec	rbuf		;use 0 to 6
000058 2f7d      	mov	pointer,rbuf	;key number
000059 0f77      	lsl	pointer		;compute eeprom address
00005a 0f77      	lsl	pointer
00005b 0f77      	lsl	pointer
00005c e0e1      	ldi	r_Zreg,1	;SN starts at the address 1
00005d e050      	ldi	r_BytCntr,0	;initialize counter to 00
00005e e585      Ccmd2:	ldi	hex_buf,$55	;Clear with value 55
00005f bb8d      	out	EEDR,hex_buf	;to eeprom data register
000060 bb7e      	out	EEAR,pointer	;address in eeprom
000061 d123      	rcall	WReeprom
000062 9573      	inc	pointer
000063 9553      	inc	r_BytCntr
000064 3058      	cpi	r_BytCntr,$8	;stop after 8 bytes
000065 f7c1      	brne	Ccmd2
000066 c044      	rjmp	UpdEEcrc	;OK, update CRC and terminate
         ;----------------------------------------------------------------
         	;D	Dump: print out all the eeprom informations
         	;	the seven serial key number, with action relays
         	;	all the error counters
          Dcmd:
000067 e0cd              ldi	sbuf,13		;send CRLF
000068 d12b              rcall	out_char
000069 e0ca              ldi	sbuf,10
00006a d129              rcall	out_char
00006b e050              ldi	r_BytCntr,0	;initialize pointer to 00
00006c 2f95      DCloop:	mov	Scratch1,r_BytCntr
00006d 7097              andi	Scratch1,$7	
00006e f421              brne	DCnocr
00006f e0cd              ldi	sbuf,13		;CRLF after 8 eeprom values
000070 d123              rcall	out_char
000071 e0ca              ldi	sbuf,10
000072 d121              rcall	out_char
          DCnocr:
000073 bb5e      	out	EEAR,r_BytCntr	;place address to the register
000074 d10c      	rcall	RDeeprom
000075 b38d      	in	hex_buf,EEDR	;load register to hex_buf
000076 d112      	rcall	out_hex1	;and output both nibbles
000077 d114      	rcall	out_hex0
000078 e2c0      	ldi	sbuf,$20	;space as separator
000079 d11a      	rcall	out_char
00007a 9553      	inc	r_BytCntr
00007b 3358      	cpi	r_BytCntr,56	;stop after 7*8 bytes
00007c f779      	brne	DCloop
00007d c048      	rjmp	CRLF		;Command finished, goto idle loop
         
         ;----------------------------------------------------------------
         	;Sn	Acquire a serial number to key "n"
00007e d126      Scmd:	rcall	fetchca
00007f 70d7      	andi	rbuf,$07	;1 to 7 valid
000080 23dd      	tst	rbuf
000081 f1c9      	breq	CmdErr		;Error, drop command
000082 95da      	dec	rbuf		;use 0 to 6
000083 2ead      	mov	KeyProc,rbuf	;save
000084 60f1      	sbr	rFlags,$01	;set flag (bit 0=1)
000085 95a8      Scwait:	wdr
000086 fdf0      	sbrc	rFlags,0	;wait for bit cleared (bit 0)
000087 cffd      	rjmp	Scwait		;
              ;now, the key has been read, store the SN to the eeprom location
000088 e3c1        ldi    sbuf,$31			;send 31
000089 d10a        rcall  out_char
00008a e056      	ldi	r_BytCntr,6	;6 bytes to store
00008b e0e1      	ldi	r_Zreg,1	;SN starts at the address 1
00008c 2d7a      	mov	pointer,KeyProc	;get key number
00008d 0f77      	lsl	pointer		;compute eeprom address
00008e 0f77      	lsl	pointer
00008f 0f77      	lsl	pointer
          ScStor:
000090 98c1      	cbi	PORTB,1
000091 9ac1      	sbi	PORTB,1
000092 8130      	ld	r_CD,Z		;get data from register
000093 bb3d      	out	EEDR,r_CD	;to eeprom data register
000094 bb7e      	out	EEAR,pointer	;address in eeprom
000095 d0ef      	rcall	WReeprom
000096 95e3      	inc	r_Zreg		;pointer to next byte
000097 9573      	inc	pointer
000098 955a      	dec	r_BytCntr	;byte counter all bytes stored?
000099 f7b1      	brne	ScStor		;no, branch
           ;now initialize relay timers to 5 seconds by default
00009a e035      	ldi	r_cd,$05	;default 5 seconds
00009b bb3d      	out	EEDR,r_CD	;to eeprom data register
00009c bb7e      	out	EEAR,pointer	;Relay 1
00009d d0e7      	rcall	WReeprom
00009e 9573      	inc	pointer
00009f bb7e      	out	EEAR,pointer	;Relay 2
0000a0 d0e4      	rcall	WReeprom
0000a1 c009      	rjmp	UpdEEcrc	;Go to update eeprom CRC
         
         ;----------------------------------------------------------------
         	;Z	Zero all counters, SN keys, and compute eeprom CRC
0000a2 e070      Zcmd:	ldi	pointer,$00
0000a3 e35f      	ldi	r_BytCntr,63
0000a4 bb7d      	out	EEDR,pointer	;00 to eeprom data register
          ZcLoop:
0000a5 bb7e      	out	EEAR,pointer	;address
0000a6 d0de      	rcall	WReeprom
0000a7 9573      	inc	pointer
0000a8 955a      	dec	r_BytCntr	;byte counter all bytes stored?
0000a9 f7d9      	brne	ZcLoop		;no, branch
0000aa c000      	rjmp	UpdEEcrc
         ;----------------------------------------------------------------
         	;Update eeprom CRC
          UpdEEcrc:
0000ab e070      	ldi	pointer,$00
0000ac 2e87      	mov	CalcCRC,pointer	;init CRC to 0
0000ad e35f      	ldi	r_BytCntr,63
          UpdLoop:
0000ae bb7e      	out	EEAR,pointer	;address
0000af d0d1      	rcall	RDeeprom
0000b0 b33d      	in	r_CD,EEDR	;get data
0000b1 d12d      	rcall	Do_CRC		;compute CRC
0000b2 9573      	inc	pointer
0000b3 955a      	dec	r_BytCntr	;byte counter all bytes stored?
0000b4 f7c9      	brne	UpdLoop		;no, branch
           ;Store the calculated CRC
0000b5 ba8d      	out	EEDR,CalcCRC	;place CRC to the last location
0000b6 bb7e      	out	EEAR,pointer	;address
0000b7 d0cd      	rcall	WReeprom	;Store CRC
           ;Now the NVram checksum is OK, we can turn the led ON
0000b8 7ffd      	cbr	rFlags,CsumER	;Clear flag CsumER (bit=0)
0000b9 98c2      	cbi	PORTB,$02	;PB2 set to 0 (Turn the LED: ON)
0000ba c003      	rjmp	cmdOK		;OK, terminate
         ;----------------------------------------------------------------
         	;Command Error send *,CR,LF
0000bb e2ca      CmdErr:	ldi	sbuf,$2A	;send '*'
0000bc d0d7              rcall	out_char
0000bd c008      	rjmp	CRLF
          CmdOK:	;print OK then CR and LF
0000be e0cd      	ldi	sbuf,13		;send CR and LF
0000bf d0d4              rcall	out_char
0000c0 e0ca              ldi	sbuf,10
0000c1 d0d2              rcall	out_char
0000c2 e4cf              ldi	sbuf,$4F	;send 'OK'
0000c3 d0d0              rcall	out_char
0000c4 e4cb              ldi	sbuf,$4B	;'K'
0000c5 d0ce              rcall	out_char
         	;Send CR and LF
0000c6 e0cd      CRLF:	ldi	sbuf,13		;send CR LF and signon
0000c7 d0cc              rcall	out_char
0000c8 e0ca              ldi	sbuf,10
0000c9 d0ca              rcall	out_char
0000ca e4c5              ldi	sbuf,$45	;'E-Key>'
0000cb d0c8              rcall	out_char
0000cc e2cd              ldi	sbuf,$2D	;'-'
0000cd d0c6              rcall	out_char
0000ce e4cb              ldi	sbuf,$4B	;'K'
0000cf d0c4              rcall	out_char
0000d0 e6c5              ldi	sbuf,$65	;'e'
0000d1 d0c2              rcall	out_char
0000d2 e7c9              ldi	sbuf,$79	;'y'
0000d3 d0c0              rcall	out_char
0000d4 e3ce              ldi	sbuf,$3E	;'>'
0000d5 d0be              rcall	out_char
              ;Re Init WatchDog
0000d6 e03f      	ldi	r_CD,0b00001111	;Enable WD and set prescaler to 2048000cycles
0000d7 bd31      	out	WDTCR,r_CD	;To Watchdog Timer control register
0000d8 cf49      	rjmp	idle
         ;****************************************************************
         ;            Here from external Interrupt
         ; An interrupt has arrived because an Ibutton chip has been 
         ; applied on the E-Key interface.
         ;****************************************************************
          ext_int0:
0000d9 b69f      	in	SREGsav,SREG   ; save status
0000da 9b81      	sbis	PIND,1		;interrupt from RXD
0000db c0e9      	rjmp	in_char
0000dc 9982              sbic	PIND,2		;interrupt from IButton
0000dd c0a1      	rjmp	falseInt	;ignore pending interrups
         
0000de   +  	WLOOP	$A1,$04		;wait 480 us
          Send_Command:
0000e4 e333      	ldi	r_CD,GetSN	;Command
0000e5 e047      	ldi	r_BitCntr,07	;7 bits to send
0000e6 9a8a      	sbi	DDRD,DDD2	;place PD2 as output
0000e7 9892      scnb:	cbi	PORTD,2
0000e8   +  	WsLOOP	$0A		;10us (Tlow)
0000eb 9537      	ror	r_CD		;place lsb into C
0000ec f408      	brcc	txc		;branch if tx a 0
0000ed 9a92      	sbi	PORTD,2
          txc:	
0000ee   +  	WLOOP	9,10		;wait end of tslot
0000f4 9a92      	sbi	PORTD,2		;end of tslot
0000f5   +  	WsLOOP	$0A		;wait 10us (trec)
0000f8 954a      	dec	r_BitCntr
0000f9 f76a      	brpl	scnb		;branch to send next bit
         		;wait xxus before getting data from IB
0000fa   +  	WsLOOP	$FF		;wait some us
         
          GetDataBtyes:
0000fd e0e0      	ldi	r_Zreg,00	;get 8 data bytes and store 
0000fe e058      	ldi	r_BytCntr,$8	;them from R0 to R7
          ReadByt:
0000ff e048      	ldi	r_BitCntr,$8	;set bit counter
          ReadBit:
000100 9a12      	sbi	DDD2,PD2	;pd2 as output
000101 9892      	cbi	PORTD,PD2	;pd2 set to 0
000102   +  	WsLOOP	$03		;Wait Tlowr (3us)
000105 9812      	cbi	DDD2,PD2	;pd2 is an input
000106 9a92      	sbi	PORTD,PD2	;activate internal pullup
000107   +  	WsLOOP	$0A		;wait for sample data
00010a 9488      	clc			;clear carry	
00010b 9982      	sbic	PIND,PD2	;SAMPLE DATA BIT ,and skip if PD2=0
00010c 9408      	sec			;set carry
00010d 9537      	ror	r_CD
00010e   +  	WsLOOP	$0E		;wait 15us Trelease
000111   +  	WsLOOP	$4E		;wait until end of tslot 
000114 954a      	dec	r_BitCntr	;8 bits read ?
000115 f751      	brne	ReadBit		;no, get another bit
000116 8330      	st	Z,r_CD		;yes, store readen byte
000117 95e3      	inc	r_Zreg		;pointer to store next byte
000118 955a      	dec	r_BytCntr	;byte counter a bytes readen?
000119 f729      	brne	ReadByt		;no, branch
           ;Now, we have to control the readen datas with the CRC
00011a e0e0      	ldi	r_Zreg,00	;get 7 data bytes ... 
00011b e058      	ldi	r_BytCntr,8	;... datas from R0 to R7
00011c 2488      	eor	CalcCRC,CalcCRC	;init to 0
          IB_ckCRC:
00011d 8130      	ld	r_CD,Z		;get byte
00011e d0c0      	rcall	Do_CRC
00011f 95e3      	inc	r_Zreg		;pointer to next byte
000120 955a      	dec	r_BytCntr	;all bytes checked?
000121 f7d9      	brne	IB_ckCRC		;no, branch
            ;CRC has been calculated
000122 2088      	tst	CalcCRC
000123 f019      	breq	Action		;
000124 e2c3      	ldi	sbuf,$23	;send # as a CRC key error
000125 d06e      	rcall	out_char
000126 c058      	rjmp	falseInt	;Invalid CRC then its a false int
         
          Action:	;A key has been correctly readen, the CRC is OK
         	;then do the proper action
         ;Now we have read the IB, send 7 first registers to the console
000127 e0cd              ldi    sbuf,13		;send CRLF
000128 d06b              rcall  out_char
000129 e0ca              ldi    sbuf,10
00012a d069              rcall  out_char
00012b e0e0              ldi    ZL,0		;initialize pointer
00012c 2f8e      loop:   mov    hex_buf,ZL
00012d 708f              andi   hex_buf,15
00012e f421              brne   nocr
00012f e0cd              ldi    sbuf,13		;CRLF after 16 registers
000130 d063              rcall  out_char
000131 e0ca              ldi    sbuf,10
000132 d061              rcall  out_char
000133 8180      nocr:   ld     hex_buf,Z        ; load register to hex_buf
000134 d054              rcall  out_hex1         ; and output both nibbles
000135 d056              rcall  out_hex0
000136 e2c0              ldi    sbuf,$20
000137 d05c              rcall  out_char
000138 95e3              inc    ZL
000139 30e7              cpi    ZL,07		;7 registers processed ?
00013a f789              brne   loop		;no, loop
00013b e0cd              ldi    sbuf,13		;Yes! send CRLF and finish.
00013c d057              rcall  out_char
00013d e0ca              ldi    sbuf,10
00013e d055              rcall  out_char
         ;
00013f 95a8      	wdr			;watchdog Reset
         ;
000140 fdf0      	sbrc	rFlags,0	;skip if command S not pending (bit 0 = 0)
000141 c03c      	rjmp	endInt		;1, S command pending branch
000142 fdf1      	sbrc	rFlags,1	;Skip if NVram cksum error is not set (bit 1 = 0)
000143 c03a      	rjmp	endInt		;1, Flag NVram cksum error is set, branch
         
            ;no, look eeprom and activate proper output	
            ;search eeprom for a corresponding serial number
000144 e070      	ldi	pointer,$00	;first eeprom location
000145 e0e1      NextKL:	ldi	r_Zreg,$01	;to the first byte 
000146 e080      	ldi	offset,$00	;init byte offset
000147 e056      	ldi	r_BytCntr,$06	;6 bytes to compare
000148 0f87      	add	offset,pointer	;
000149 bb8e      NextBL:	out	EEAR,offset	;get byte from eeprom
00014a d036      	rcall	RDeeprom
00014b b33d      	in	r_CD,EEDR	;get data
00014c 8190      	ld	scratch1,Z	;data pointer to readen key bytes
00014d 1793      	cp	scratch1,r_CD	;test
00014e f559      	brne	NextKey		;no match, test next key in eeprom
00014f 95e3      	inc	r_Zreg		;match, inc pointers
000150 9583      	inc	offset
000151 955a      	dec	r_BytCntr		;byte counter
000152 f7b1      	brne	NextBL		;to next Byte Location
          ActionOK:	;OK, activate outputs needed
000153 bb8e      	out	EEAR,offset	;address
000154 d02c      	rcall	RDeeprom
000155 b39d      	in	scratch1,EEDR	;get first-output time
000156 9583      	inc	offset
000157 bb8e      	out	EEAR,offset	;address
000158 d028      	rcall	RDeeprom
000159 b3ad      	in	scratch2,EEDR	;get second-output time
00015a 2399      SetPri:	tst	scratch1
00015b f009      	breq	SetSec		;branch if timing=00
00015c 98c0      	cbi	PORTB,0		;ACTIVATE OUTPUT 0
00015d 23aa      SetSec:	tst	scratch2
00015e f009      	breq	AcLoop		;branch if timing=00
00015f 98c1      	cbi	PORTB,1		;ACTIVATE OUTPUT 1
          AcLoop:		;Action Loop, wait 1 second (approx)
         	;---- WAIT 1 SECOND ----
000160 e1b0      	ldi	scnt,$10
000161 95a8      ALl2:	wdr			;Watchdog Reset
000162 ea00      	ldi	r_cntH,$A0
000163 ef1f      ALl0:	ldi	r_cntL,$FF
000164 951a      ALl1:	dec	r_cntL
000165 0000      	nop
000166 f7e9      	brne	ALl1
000167 950a      	dec	r_cntH
000168 f7d1      	brne	ALl0
000169 95ba      	dec	scnt
00016a f7b1      	brne	ALl2
         	;-----------------------
00016b 2399      	tst	scratch1
00016c f019      	breq	out0		;already 00
00016d 959a      	dec	scratch1	;decrement counter
00016e f409      	brne	out0		;not 00, continue loop
00016f 9ac0      	sbi	PORTB,0		;DE-ACTIVATE OUTPUT 0
000170 23aa      out0:	tst	scratch2
000171 f019      	breq	out1		;already 00
000172 95aa      	dec	scratch2	;decrement counter
000173 f409      	brne	out1		;not 00, continue loop
000174 9ac1      	sbi	PORTB,1		;DE-ACTIVATE OUTPUT 1
000175 2399      out1:	tst	scratch1	;re test 0
000176 f749      	brne	AcLoop		;both counters are not 00
000177 23aa      	tst	scratch2	;re test 1
000178 f739      	brne	AcLoop		;
000179 c004      	rjmp	endInt		;here when both counters reach 00
         
          NextKey:	;go to the next key location
00017a e098      	ldi	scratch1,$08
00017b 0f79      	add	pointer,scratch1;
00017c 3378      	cpi	pointer,$38
00017d f639      	brne	NextKL
          NoValid:
          endInt:
00017e 7ffe      	cbr	rFlags,$01	;clear flag bit 0
          falseInt:
         
00017f be9f      	out	SREG,SREGsav
000180 9518      	reti			;end of Interrupt
         
         ;******************************************************************
         ;EEPROM Access Handler
         ;--------------------------------------------------------------------
          RDeeprom:	;Read eeprom address is in EEAR, data in EEDR
000181 9ae0      	sbi	EECR,EERE	;set EEReadEnable
000182 99e0      REwait:	sbic	EECR,EERE
000183 cffe      	rjmp	REwait		;wait end of read eeprom
000184 9508      	ret
         
          WReeprom:	;Write to eeprom
000185 9ae1      	sbi	EECR,EEWE	;set EEWriteEnable
000186 99e1      WEwait:	sbic	EECR,EEWE
000187 cffe      	rjmp	WEwait		;wait end of read eeprom
         
000188 9508      	ret
         
         
         ;******************************************************************
         ;Serial Handlers
         ;--------------------------------------------------------------------
         ; out_hex1 : output higher nibble from hex_buf
         ; hex_buf is not changed
         ;
          out_hex1:
000189 2fc8              mov    sbuf,hex_buf
00018a 95c2              swap   sbuf       ; msb into lower position
00018b c002              rjmp   out_hnib
         ;
         ; out_hex0 : output lower nibble from hex_buf
         ; hex_buf is not changed
         ;
          out_hex0:
00018c 2fc8              mov    sbuf,hex_buf
00018d c000              rjmp   out_hnib
         
          out_hnib:
00018e 70cf              andi   sbuf,$0F   ; mask off nibble
00018f 5fca              subi   sbuf,-6    ; add 6 ; bit 3 is set if >9
000190 fdc4              sbrc   sbuf,4     ; offset to add depends on case
000191 5fc9              subi   sbuf,-7    ; for 0 we add 48=6+42
000192 5dc6              subi   sbuf,-42   ; for A we add 55=6+7+42
000193 c000              rjmp   out_char        ; and output this character
         
         ;--------------------------------------------------------------------
         ; output the character in sbuf
         ; via RS232 at 9600 bits/sec on PORTD,0
         
          out_char:
000194 e0bb              ldi    scnt,11		;1-START 8-DATA 2-STOP bits
          bit_loop:
000195 30bb      	cpi    scnt,11		; start-bit ?
000196 f021      	breq   txmark		;start bit is mark
000197 30b3      	cpi    scnt,3		;stop bits ?
000198 f020      	brcs   txspace		;stop bits are space
000199 95c7              ror    sbuf		;transfer LSB first
00019a f010              brcs   txspace		;a 1 translates to space
00019b 9a90      txmark: sbi    PORTD,0		;mark is HIGH
00019c c001              rjmp   goon
00019d 9890      txspace:cbi    PORTD,0		;spac is LOW
          goon:
00019e e614      	ldi    r_cntL,100	;wait 100*4 cycles
00019f 951a      bl1:	dec    r_cntL
0001a0 0000              nop
0001a1 f7e9              brne	bl1		;time-loop-end
0001a2 95ba              dec    scnt		;count down bit number
0001a3 f789              brne   bit_loop		;loop of all bits
0001a4 9508              ret
         
         ;--------------------------------------------------------------------
         ;fetchca wait for a character from serial input, and echo it 
         ;        result in rbuf
0001a5 95a8      fetchca:wdr			;first: watchdog reset
0001a6 2322      	tst	mail		;check if character received
0001a7 f3e9      	breq	fetchca
0001a8 2722      	clr	mail		;YES a char has been received
0001a9 2fcd      	mov	sbuf,rbuf	;echo it
0001aa dfe9      	rcall	out_char	;to txd
0001ab 9508      	ret
         
         ;fetchhex wait for an hexa character from input
         ;       no complete check done, result in hex_buf
          fetchhex:
0001ac 95a8      	wdr			;watchdog reset
0001ad 2322      	tst	mail		;check if character received
0001ae f3e9      	breq	fetchhex
0001af 2722      	clr	mail		;YES a char has been received
0001b0 2fcd      	mov	sbuf,rbuf	;echo it
0001b1 dfe2      	rcall	out_char	;to txd
0001b2 53d0      	subi	rbuf,$30	;
0001b3 30da      	cpi	rbuf,$0A
0001b4 f00a      	brmi	fhlnib
0001b5 50d7      	subi	rbuf,$07	;else result between 11h and 17h
          fhlnib:	;Fetch low Nibble
0001b6 70df      	andi	rbuf,$0F	;clear high nibble
0001b7 95d2      	swap	rbuf		;Swap nibbles
0001b8 2f8d      	mov	hex_buf,rbuf	;save high nibble to hex_buf
0001b9 95a8      fh1:	wdr
0001ba 2322      	tst	mail		;check if character received
0001bb f3e9      	breq	fh1
0001bc 2722      	clr	mail		;YES a char has been received
0001bd 2fcd      	mov	sbuf,rbuf	;echo it
0001be dfd5      	rcall	out_char	;to txd
0001bf 53d0      	subi	rbuf,$30	;
0001c0 30da      	cpi	rbuf,$0A
0001c1 f00a      	brmi	fhok
0001c2 50d7      	subi	rbuf,$07	;else result between 11h and 17h
0001c3 2b8d      fhok:	or	hex_buf,rbuf
0001c4 9508      	ret
         
         ;--------------------------------------------------------------------
         ; input a character from RS232 on portd PD1 
         ; Result to sbuf
         ; RS232 at 9600 bits/sec on PORTD,1
          in_char:
0001c5 e0b9      	ldi	scnt,9		;start bit plus 8 data bits
          RX_loop:
0001c6 e312      	ldi	r_cntL,50	;wait first half bit time
0001c7 951a      rx_t1:  dec	r_cntL		;9600 bits at 4 Mhz 1 bit = 416.66 cycles
0001c8 0000              nop
0001c9 f7e9              brne	rx_t1
0001ca 9488              clc			;sample input line and rotate into buffer
0001cb 9981              sbic	PIND,1		;test PD1 (RXD)
0001cc 9408              sec
          TEST:
0001cd 9a90      	sbi	PORTD,0
0001ce 9890      	cbi	PORTD,0
         
0001cf 95d7              ror	rbuf
0001d0 e312      	ldi	r_cntL,50	;wait second half bit time
0001d1 951a      rx_t3:  dec	r_cntL
0001d2 0000              nop
0001d3 f7e9      	brne	rx_t3
0001d4 95ba      	dec	scnt
0001d5 f781      	brne	RX_loop
0001d6 e021      	ldi	mail,1
0001d7 be9f      false1:	out	SREG,SREGsav
0001d8   +  	WLOOP	30,30		;TEST
0001de 9518              reti
         
         
         ;******************************************************************
         ;CRC Handler
         ;--------------------------------------------------------------------
0001df 2fa3      Do_CRC:	mov	Scratch2,r_CD	;save byte to compute
0001e0 e048      	ldi	r_BitCntr,8	;8 bits to compute
          CRC_Loop:
0001e1 2f3a      	mov	r_CD,Scratch2
0001e2 2538      	eor	r_CD,CalcCRC
0001e3 9537      	ror	r_CD		;Data (lsb) into Carry
0001e4 2d38      	mov	r_CD,CalcCRC
0001e5 f410      	brcc	CRCZ		;if carry =0 branch
0001e6 e198      	ldi	Scratch1,$18	;if carry=1 do eor with 18H
0001e7 2739      	eor	r_CD,Scratch1
0001e8 9537      CRCZ:	ror	r_CD
0001e9 2e83      	mov	CalcCRC,r_CD
0001ea 2f3a      	mov	r_CD,Scratch2
0001eb 9536      	lsr	r_CD		;position to next data bit
0001ec 2fa3      	mov	Scratch2,r_CD	;save 
0001ed 954a      	dec	r_BitCntr
0001ee f791      	brne	CRC_Loop
0001ef 9508      	ret
         
         ;******************************************************************
         

Assembly complete with no errors.
