;***** Final Project - Credit card transaction system with RSA encryption ******** ; ; Tony Cuadra, Ilyas Elkin ; ;************************************************ .nolist .include "c:\avrtools\appnotes\4414def.inc" .list .def char =r0 .def savSREG =r1 ;save the status register .def reload =r2 ;timer 0 interval .def lcdstat =r3 .def val0 =r4 .def val1 =r5 .def val2 =r6 .def val3 =r7 .def val4 =r8 .def val5 =r9 .def RSAe =r11 .def RSAd =r11 ;the encrypt method uses RSAd .def RSAm =r12 .def RSAs =r13 .def bitcnt =R16 ;bit counter .def temp =R17 ;temporary storage register .def Txbyte =R18 ;Data to be transmitted .def Rxbyte =R19 ;Received data .def mode =r20 ;mode of the machine (getting #=0001, getting$=0010, processing=0100) .def state =r21 ;state of the debouncer state machine .def time1 =r22 ;keeps track of time left for 30ms interrupt .def timeout =r23 ;Timeout value in mSec passed to subroutine .def butnum =r24 ;the button pressed on the keypad .def press =r25 ;the button detected previosly (used by debouncer) .def key =r26 ;encoding for the button pressed on the keypad .equ nopress =1 ;state when no button has been pressed .equ maybe =2 ;detected a button once so far .equ press =3 ;detected a button pressed at least twice in a row .equ bounce =4 ;detected a button release once .equ lcdrs =PA6 ;LCD rs pin connected to PD6 .equ lcdrw =PA5 ;LCD r/w pin connected to PD5 .equ lcde =PA4 ;LCD e pin connected to PD4 .equ key0 =0b01111101 .equ key1 =0b11101110 .equ key2 =0b11101101 .equ key3 =0b11101011 .equ key4 =0b11011110 .equ key5 =0b11011101 .equ key6 =0b11011011 .equ key7 =0b10111110 .equ key8 =0b10111101 .equ key9 =0b10111011 .equ keyA =0b11100111 .equ keyB =0b11010111 .equ keyILL =0xff ;no button (or multiple buttons) pressed on keypad .equ getacct =0 ;bits for the mode .equ getcash =1 .equ process =2 .macro break cli rcall Monitor .endmacro ;******************************* ; Data segment .dseg acct: .byte 6 ;stores the account number cash: .byte 6 ;stores the transaction amount ;******************************* ; Initialization .cseg .org $0000 rjmp RESET ;reset entry vector reti reti reti reti reti reti rjmp t0int reti rjmp Monitor reti rjmp Monitor reti RESET: ldi Temp, LOW(RAMEND) ;setup stack pointer out SPL, Temp ldi Temp, HIGH(RAMEND) out SPH, Temp ;PORTC is used for the keypad ;PORTA is used for the LCD ;setup timer 0 for overflow once every mSec ldi temp, 3 ;prescale timer by 64 out TCCR0, temp ldi temp,256-62 ;preload timer since mov reload, temp out TCNT0, Reload ;62.5 x (64x.25) microSec = 1.0 mSec. ;turn on timer0 overflow interrupt ldi temp, exp2(TOIE0) out TIMSK, temp ;setup hardware UART -- enable RX, TX pins without ISRs ldi temp, 0b00011000 out UCR, temp ;set baud rate to 9600 ldi temp, 25 out UBRR, temp ;enable receive ISR ONLY for keyboard monitor sbi UCR, RXCIE ldi mode, EXP2(getacct) ;setup software UART cbi PORTD,RxD cbi DDRD,RxD sbi PORTD,TxD sbi DDRD,TxD ;initial conditions ldi time1, 30 ;set time1 for 30 mSec ldi state, nopress ;set initial state to nopress clr val0 clr val1 clr val2 clr val3 clr val4 clr val5 sei ldi temp, 0xff out DDRA, temp out PORTA, temp rcall lcdinit ;Initialize LCD module rcall lcdclr ;Clear LCD screen rcall getinput ;*************************** Sched: tst time1 ;test for first task ready brne Sched ;if not then loop rcall debounce tskend: rjmp Sched ;*************************** debounce: ldi time1, 30 ;reset for another 30 mSec cpi state, nopress breq _nopress cpi state, maybe breq _maybe cpi state, press breq _press cpi state, bounce breq _bounce error: rjmp error _nopress: rcall keybd cpi butnum, keyILL ;check if nothing is pressed breq _nopressY mov press, butnum ldi state, maybe _nopressY: ret _maybe: rcall keybd cp press, butnum breq _maybeY ldi state, nopress ret _maybeY:ldi state, press rcall gotkey ret _press: rcall keybd cp press, butnum breq _pressY ldi state, bounce _pressY:ret _bounce:rcall keybd cp press, butnum breq _bounceY ldi state, nopress ret _bounceY: ldi state, press ret ;*************************** getinput: ldi temp, '0' mov val0, temp mov val1, temp mov val2, temp mov val3, temp mov val4, temp mov val5, temp rcall display ret ;*************************** gotkey: sbrc mode, process ret cpi press, 'A' ;test for go command breq Mstart ;done with this input mov val5,val4 ;shift all the frequency digits left mov val4,val3 mov val3,val2 mov val2,val1 mov val1,val0 mov val0,press ;shift in the newly read digit display: rcall lcdclr sbrc mode, getacct ldi temp, '#' sbrc mode, getcash ldi temp, '$' rcall lcdput mov temp, val5 rcall lcdput mov temp, val4 rcall lcdput mov temp, val3 rcall lcdput mov temp, val2 rcall lcdput ldi temp, '.' sbrc mode, getcash rcall lcdput mov temp, val1 rcall lcdput mov temp, val0 rcall lcdput ret ;*************************** Mstart: cpi mode, EXP2(getacct) breq stacct ldi ZL, LOW(cash) ldi ZH, HIGH(cash) rjmp stcash stacct: ldi ZL, LOW(acct) ldi ZH, HIGH(acct) stcash: st Z, val5 std Z+1, val4 std Z+2, val3 std Z+3, val2 std Z+4, val1 std Z+5, val0 cpi mode, EXP2(getcash) breq proc ldi mode, EXP2(getcash) rcall getinput ret proc: ldi mode, EXP2(process) ldi timeout, 10 rcall delay ;delay 10 ms ;************************** cli ;disable interrupts so we can receive the key rcall putchar rcall getchar mov RSAm, Rxbyte rcall getchar mov RSAe, Rxbyte sei ;enable interrupts after receiving key ;************************** ldi ZL, LOW(acct) ldi ZH, HIGH(acct) encrloop: ld RSAs, Z ldi temp, '0' sub RSAs, temp rcall encrypt ldi timeout, 20 rcall delay ;delay 20 ms mov Txbyte, RSAs rcall putchar ldi timeout, 1 rcall delay ;delay 1 ms adiw ZL,1 cpi ZL, LOW(acct+12) brne encrloop ldi mode, EXP2(getacct) rcall getinput ret keypressed: ret ;ignore keys received on the hardware UART ;*************************** keybd: ldi temp, 0x0f ;set lower four lines to output out DDRC, temp ldi temp, 0xf0 ;and turn on the pullups on the inputs out PORTC, temp nop ;Need some time for the pullups to nop ;charge the port pins nop nop in temp, PINC ;read the high nibble mov key, temp ;and store it (with zeros in the low nibble) ldi temp, 0xf0 ;set upper four lines to outputs out DDRC, temp ldi temp, 0x0f ;and turn on pullups on the inputs out PORTC, temp nop ;As before wait for the pin to charge nop nop nop in temp, PINC ;read the low nibble or key, temp ;combine to make key code ;At the point the raw key code should have exactly one zero each in ;the lower and upper nibbles. Any other number of zeros indicates ;either no-button pressed or multiple-button pressed. ldi butnum, '0' cpi key, key0 breq tbldone ldi butnum, '1' cpi key, key1 breq tbldone ldi butnum, '2' cpi key, key2 breq tbldone ldi butnum, '3' cpi key, key3 breq tbldone ldi butnum, '4' cpi key, key4 breq tbldone ldi butnum, '5' cpi key, key5 breq tbldone ldi butnum, '6' cpi key, key6 breq tbldone ldi butnum, '7' cpi key, key7 breq tbldone ldi butnum, '8' cpi key, key8 breq tbldone ldi butnum, '9' cpi key, key9 breq tbldone ldi butnum, 'A' cpi key, keyA breq tbldone ldi butnum, keyILL tbldone:ret ;***************************** ;interrupt routines ;***************************** ;timer 0 ISR (timer-zero overflow) ;Enters every 1.0 mSec t0int: in savSREG, SREG out TCNT0, reload ; keeps clock ticking at 1 mSec dec timeout ;subtract another mSec tst time1 breq t0exit dec time1 t0exit: out SREG, savSREG reti ;back to backgound tasks .include ".\lcd.inc" .include ".\keymon3.inc" .include ".\uart.inc" .include ".\rsa.inc"