;-------------------------------------------------------- ; Roll Your Own Electronic Lock ; Dhananjay V. Gadre ;-------------------------------------------------------- ;ser-dong.asm ;Clock Frequency 3.58 MHz ;-------------------------------------------------------- .include "2323def.inc" .def start_t=r2 .def stop-t=r3 .def timer-reload=r4 .def exor=r5 .def temp=rl6 .def temp2=rl8 .def templ=rl9 .def low_del=rl7 .def high-del=r22 .def count=r2O .def data=r2l .def lfsr-preset=r23 .def lfsr_shift=r24 .def lfsr_result=r25 .equ half-step= -23 .equ full-step= -46 .equ stop-timer= 0 .equ start_timer= 2 .cseg .org 0 rjmp RESET ;Reset Handle RESET: ldi temp, low(RAMEND) out SPL, temp ;Init the Stack Pointer ldi temp, ObOO000110 ;configure PORT B for all outputs out DDRB, temp ;except PBO ldi temp, ObOO000001 ;PBO is input with pullup ;PB1 is o/p at 101 out PORTB, temp ldi temp, $04 mov exor, temp ldi temp, stop-timer ;stop the timer out TCCRO, temp out TCNTO, temp mov stop-t, temp ldi temp, start-timer mov start-t, temp ;register to start the timer ;with CK/8 as the clock source ;Main Program Loop ;This part receives 2 bytes from the PC as seed and ;the shift value. calculates the result and transmits ;the result to the PC main-loop: rcall get-byte ;get seed from the PC ;data is received in Itempl com temp ;account for the RS-232 inversion mov lfsr-preset, temp rcall send-byte ;echo the received byte rcall get-byte ;get the shift count com temp mov lfsr shift, temp rcall send-byte ;echo it rcall calc-result ;using the seed and the shift value ;calculate the result. result is in ;Ilfsr-result' register mov data, lfsr-result com data rcall send-byte ;transmit the result rjmp main-loop ;function: GET-BYTE ;This function gets assembles a byte out of serial ;bits on the PORTB.0 pin, uses the TimerO to time ;the duration between bits. TimerO is programmed ;for 104 us which corresponds to bit rate of 9600. ;The byte format is: 1 stop bit, no parity bit and 6 ;8 data bits Assembled byte is saved in ;register: 'data' get-byte: ldi count, 9 ldi data, 0 wait-foro: sbic PINB, 0 rjmp wait-foro wait-forl: sbis PINB, 0 rjmp wait-forl ldi temp, half-step out TCNTO, temp out TCCRO, start-t still-time: in temp, TIFR cpi temp, 2 brne still-time out TIFR, temp out TCCRO, stop-t in temp, PORTB eor temp, exor out PORTB, temp sec sbis PINB, 0 clc ror data ldi temp, full-step out TCNTO, temp out TCCRO, start-t dec count cpi count, 0 brne still-time ldi temp, half-step out TCNTO, temp s-time: in temp, TIFR cpi temp, 2 brne s-time out TIFR, temp out TCCRO, stop-t mov temp, data ret ;set carry 7 ;function: SEND-BYTE ;This function sends out bits serially on ;bits on the PORTB.1 pin from the register 'data'. ;Function uses the TimerO to time the duration ;between bits. TimerO is programmed for 104 us ;which corresponds to bit rate of 9600. ;The byte format is: 1 stop bit, no parity bit and ;8 data bits. send-byte: ldi count, 10 in temp, PORTB eor temp, exor out PORTB, temp sbi PORTB, 1 ldi temp, full-step out TCNTO, temp out TCCRO, start-t till-time: in temp, TIFR cpi temp, 2 brne till-time out TIFR, temp out TCCRO, stop-t in temp, PORTB eor temp, exor out PORTB, temp clc ror data brcs its-1 cbi PORTB, 1 rjmp loop-over its-1: sbi PORTB, 1 loop-over: ldi temp, full-step out TCNTO, temp out TCCRO, start-t dec count cpi count, 0 brne till time out TCCRO, stop-t ldi temp, 2 out TIFR, temp ret 8 ;function: LFSR ;A routine to generate a sequence using an 8-bit ;LFSR. Register Itempl is used as the 8- bit LFSR ;The Taps for an 8-bit LFSR are at: 1, 2, 3 and 7 for ;maximal length. lfsr: mov templ, temp andi templ, OblOO01110 ror templ mov temp2, templ andi temp2, ObOO000001 ror templ mov low-del, templ andi low-del, ObOO000001 ror templ mov high-del, templ andi high-del, ObOO000001 ror templ ror templ ror templ ror templ eor templ, temp2 eor low-del, high-del eor templ, low-del andi templ, ObOO000001 breq shift sec rjmp no-shift shift: clc no-shift: rol temp ret ;temp has the shifted number ;function: CALC-RESULT ;cycles the LFSR for a count equal to the content ;of Ilfsr-shift' register. The seed is taken from ;the register Ilfsr-preset'. ;The result is stored in register Ilfsr-result' calc-result: cpi lfsr-preset, 0 9 breq its-over cpi lfsr-shift, 0 breq its-over get-lfsr: mov temp, lfsr-preset rcall lfsr mov lfsr-preset, temp dec lfsr-shift cpi lfsr-shift, 0 brne get-lfsr its-over: mov lfsr-result, lfsr-preset ret