; Rhett Dillingham, Brian Morgan EE476 Spring 99 ; Code to control handheld prototype for final project .nolist ;Suppress listing of include file .include "8535def.inc" ;Define chip particulars .list ;***** Global register variables .def savSREG =r1 ;save the status register .def timetemp=r2 ;save old time or temp value .def tempsave=r3 ;save old temp value in cdb loop .def flag =r4 ;flag for debounce success or fail .def cdbcount=r5 ;keep track of where in contacts database we are .def mdbcount=r6 ;keep track of where in memos database we are .def temp2 =r7 ;extra temp storage for comparisons .def linelimit=r8 .def wreg =R16 ;General use working register .def timeout =R17 ;Timeout value passed to subroutine .def lcdstat =R18 ;LCD busy/wait status .def longtime=R19 ;Long timer for powerup .def char =r20 ;a variable character to print .def temp =r21 .def cursorow=r22 ;Char position on the display .def TXbusy =r23 ;transmit busy flag .def RXchar =r24 ;a received character .def TXflash =r25 ;text to be sent is in flash if <>0 ;***** Other equates .equ lcdrs =PC6 ;LCD rs pin connected to PD6 .equ lcdrw =PC5 ;LCD r/w pin connected to PD5 .equ lcde =PC4 ;LCD enable pin connected to PD4 ; Timer/Counter prescaler values .equ TSTOP =0 ;Stop Timer/Counter .equ TCK1 =1 ;Timer/Counter runs from CK .equ TCK8 =2 ;Timer/Counter runs from CK / 8 .equ TCK64 =3 ;Timer/Counter runs from CK / 64 .equ TCK256 =4 ;Timer/Counter runs from CK / 256 .equ TCK1024 =5 ;Timer/Counter runs from CK / 1024 .equ TEXF =6 ;Timer/Counter runs from external falling edge .equ TEXR =7 ;Timer/Counter runs from external rising edge .equ baud96 =25 ;9600 baud constant for 4Mhz crystal .equ baud24 =103 ;2400 baud constant for 4Mhz crystal .equ contactlimit=2 ;limit of contacts that can be used .equ memolimit=3 ;limit of memos that can be used and still fit in 8535 SRAM .dseg ;define variable strings to be transmitted from RAM ;total space taken for 2 contacts and 2 memos ; with display RAM rows = (2*76+1) + (3*73+1) + 84 = 457 contacts: .byte 165;153 ;contact storage ; organized as 20 for first and last names ; 40 in 2 lines for address fields ; 10 for phone number ; 1 field terminator per field (5), ; 1 terminator per contact = 76 ; and 1 whole string terminator memos: .byte 230;165 ;memo storage ; organized as 8 for date ; 20 in 3 lines for memo => total 68 + 4 terminators + 0x03 term = 73 row1: .byte 21 ;display character storage row2: .byte 21 row3: .byte 21 row4: .byte 21 tempchar: .byte 5 .cseg ; Interrupt vectors .org $0000 rjmp RESET ;reset entry vector reti reti reti reti reti reti reti reti rjmp t0int reti rjmp RXdone ;UART receive done rjmp TXempty ;UART buffer empty reti ;rjmp TXdone ;UART transmit done reti reti reti ;============================================= ; menu headings mainmenu: .db "MAIN MENU", 0x00 contmemo: .db "CONTACTS & MEMOS", 0x00 syncset: .db "SYNC SETUP", 0x00 messagec: .db "MESSAGE CENTER", 0x00 contact: .db "CONTACT DATABASE", 0x00 contactlist: .db "CONTACTS", 0x00 memo: .db "MEMOS DATABASE", 0x00 memolist: .db "MEMOS", 0x00 ; menu options for Main Menu a_contact: .db "1.Contacts,Memos", 0x00 b_message: .db "2.Message Center", 0x00 c_syncmode: .db "3.Sync Mode", 0x00 ; menu options for Contacts and Memos a_condb: .db "1.Contacts Database", 0x00 b_memodb: .db "2.Memos List", 0x00 c_return: .db "3.Back to Main Menu", 0x00 ; menu options for Contacts Database and Notes Database a_add: .db "1.Add Entry", 0x00 b_edit: .db "2.View Entry", 0x00 c_del: .db "3.Delete Entry", 0x00 ; menu options for Message Center a_rec: .db "1.Receive Mode", 0x00 b_send: .db "2.Send Message", 0x00 ; menu options for Sync Setup a_sendinfo: .db "2.Send Info",0x00 b_recinfo: .db "1.Receive Info",0x00 ; special messages recdone: .db "Receive Done",0x00 recready: .db "Receive Ready",0x00 datasent: .db "Data Sent",0x00 initString: .db 0x01,0x04,0x05,0x00 ; Main program entry point on Reset reset: ldi wreg, LOW(RAMEND) ;setup stack pointer out SPL, wreg ldi wreg, HIGH(RAMEND) out SPH, wreg ldi wreg,TSTOP ;Timer 0 off (just in case) out TCCR0,wreg ;Stop timer ldi wreg,0b00000001 ;Enable Timer 0 interrupt out TIMSK,wreg ldi wreg,0xFF ;Make port B pin all outputs out DDRB,wreg ;initial conditions clr TXbusy ;start out not busy on TX ldi RXchar, 0 ;set UART baud rate to 2400 ldi temp, baud96 out UBRR, temp clr cdbcount ;initialize counters to 0 clr mdbcount clr RXchar ldi temp, 0b10111000 ;enable transmission and receive out UCR,temp ; using RX done and TX empty ints ldi ZL,low(contacts) ldi ZH,high(contacts) ldi wreg,1 st Z,wreg ldi ZL,low(memos) ldi ZH,high(memos) ldi wreg,1 st Z,wreg sei ;Enable interrupts ;////////////INITIALIZE LCD DISPLAY\\\\\\\\\\\\\\\\\\\\\\\ ;power down the LCD ldi wreg, 0xff ;LCD power connection out DDRA, wreg ;power it down after reset ldi wreg, 0x00 out PORTA,wreg ldi longtime,100 ; then Wait 1.5 second with LCD power off ldi timeout,0 ;Delay 15 mS offwait:rcall delay dec longtime brne offwait ;now power up LCD ldi wreg, 0xff out PORTA, wreg ldi longtime,100 ;Wait 1.5 second for LCD power up ldi timeout,0 ;Delay 15 mS puwait: rcall delay dec longtime brne puwait ldi wreg,0xFF ;Turn off all LEDs out PORTB,wreg ;hopefully by now the LCD has rebooted main: rcall lcdinit ;Initialize LCD module rcall lcdclr ;Clear LCD screen ;------------------Beginning of Main Program------------------- ;/////////////BEGINNING OF MENUING SECTION\\\\\\\\\\\\\\ ;Begin with the Main Menu here mmenu: ldi wreg,0b00001100 rcall lcdcmd rcall lcdclr clr flag ;reset flag for use in debounce ldi ZL,low(mainmenu*2) ;load menu title ldi ZH,high(mainmenu*2) rcall printfl ;print menu title ldi wreg,0xC0 ;set 2nd line addr rcall lcdcmd ldi ZL,low(a_contact*2) ;load 1st option line ldi ZH,high(a_contact*2) rcall printfl ;print 1st option line ldi wreg,0x94 ;set 3rd line addr rcall lcdcmd ldi ZL,low(b_message*2) ;load 2nd option line ldi ZH,high(b_message*2) rcall printfl ;print 2nd option line ldi wreg,0xD4 ;set 4th line addr rcall lcdcmd ldi ZL,low(c_syncmode*2) ;load 3rd option line ldi ZH,high(c_syncmode*2) rcall printfl ;print 3rd option line ser temp out DDRD,temp out PORTD,temp ldi temp,0xFE ;check the option switches for main menu control mmloop: sbic PINB,1 ;check 1st button rjmp mmbut2 ;if not pushed check 2nd button out PORTD,temp ldi wreg,0x02 rcall debounce ;if pushed debounce it tst flag breq mmloop ;if not proper push, continue looping mmwlp1: sbis PINB,1 ;wait for button release rjmp mmwlp1 rjmp cmmenu ;if proper push jump to button function mmbut2: sbic PINB,2 ;check 2nd button rjmp mmbut3 ;if not pushed check 3rd button ldi wreg,0x04 rcall debounce ;if pushed debounce it tst flag breq mmloop ;if not proper push, continue looping mmwlp2: sbis PINB,2 ;wait for button release rjmp mmwlp2 rjmp mcmenu ;if proper push jump to button function mmbut3: sbic PINB,3 ;check 3rd button rjmp mmloop ;if not pushed loop again ldi wreg,0x08 rcall debounce ;if pushed debounce it tst flag breq mmloop ;if not proper push, continue looping mmwlp3: sbis PINB,3 ;wait for button release rjmp mmwlp3 rjmp smmenu ;if proper push jump to button function ;option1 of main menu selected contacts and memos menu cmmenu: ldi wreg,0b00001100 rcall lcdcmd rcall lcdclr clr flag ;reset flag for use in debounce ldi ZL,low(contmemo*2) ;load menu title ldi ZH,high(contmemo*2) rcall printfl ;print menu title ldi wreg,0xC0 ;set 2nd line addr rcall lcdcmd ldi ZL,low(a_condb*2) ;load 1st option line ldi ZH,high(a_condb*2) rcall printfl ;print 1st option line ldi wreg,0x94 ;set 3rd line addr rcall lcdcmd ldi ZL,low(b_memodb*2) ;load 2nd option line ldi ZH,high(b_memodb*2) rcall printfl ;print 2nd option line ldi wreg,0xD4 ;set 4th line addr rcall lcdcmd ldi ZL,low(c_return*2) ;load 3rd option line ldi ZH,high(c_return*2) rcall printfl ;print 3rd option line ;contacts and memos menu set up so check buttons cmloop: sbic PINB,1 ;check 1st button rjmp cmbut2 ;if not pushed check 2nd button ldi wreg,0x02 rcall debounce ;if pushed debounce it tst flag breq cmloop ;if not proper push, continue looping cmwlp1: sbis PINB,1 ;wait for button release rjmp cmwlp1 tst cdbcount ;check to make sure there are contacts to display brne cdbnoadd ;if there are no contacts left make a new one inc cdbcount ldi ZL,low(contacts) ldi ZH,high(contacts) rcall cdbadd cdbnoadd:rjmp cdbmenu ;if proper push jump to button function cmbut2: sbic PINB,2 ;check 2nd button rjmp cmbut3 ;if not pushed check 3rd button ldi wreg,0x04 rcall debounce ;if pushed debounce it tst flag breq cmloop ;if not proper push, continue looping cmwlp2: sbis PINB,2 ;wait for button release rjmp cmwlp2 tst mdbcount ;check to make sure there are contacts to display brne mdbnoadd ;if there are no memos left make a new one inc mdbcount ldi ZL,low(memos) ldi ZH,high(memos) rcall mdbadd mdbnoadd:rjmp mdbmenu ;if proper push jump to button function cmbut3: sbic PINB,3 ;check 3rd button rjmp cmloop ;if not pushed loop again ldi wreg,0x08 rcall debounce ;if pushed debounce it tst flag breq cmloop ;if not proper push, continue looping cmwlp3: sbis PINB,3 ;wait for button release rjmp cmwlp3 rjmp mmenu ;if proper push jump to button function ;option2 of main menu selected message center menu mcmenu: rcall lcdclr clr flag ;reset flag for use in debounce ldi ZL,low(messagec*2) ;load menu title ldi ZH,high(messagec*2) rcall printfl ;print menu title ldi wreg,0xC0 ;set 2nd line addr rcall lcdcmd ldi ZL,low(a_rec*2) ;load 1st option line ldi ZH,high(a_rec*2) rcall printfl ;print 1st option line ldi wreg,0x94 ;set 3rd line addr rcall lcdcmd ldi ZL,low(b_send*2) ;load 2nd option line ldi ZH,high(b_send*2) rcall printfl ;print 2nd option line ldi wreg,0xD4 ;set 4th line addr rcall lcdcmd ldi ZL,low(c_return*2) ;load 3rd option line ldi ZH,high(c_return*2) rcall printfl ;print 3rd option line ;message center menu set up so check buttons mcloop: sbic PINB,1 ;check 1st button rjmp mcbut2 ;if not pushed check 2nd button ldi wreg,0x02 rcall debounce ;if pushed debounce it tst flag breq mcloop ;if not proper push, continue looping mcwlp1: sbis PINB,1 ;wait for button release rjmp mcwlp1 rjmp recmode ;if proper push jump to button function mcbut2: sbic PINB,2 ;check 2nd button rjmp mcbut3 ;if not pushed check 3rd button ldi wreg,0x04 rcall debounce ;if pushed debounce it tst flag breq mcloop ;if not proper push, continue looping mcwlp2: sbis PINB,2 ;wait for button release rjmp mcwlp2 rjmp sendmsg ;if proper push jump to button function mcbut3: sbic PINB,3 ;check 3rd button rjmp mcloop ;if not pushed loop again ldi wreg,0x08 rcall debounce ;if pushed debounce it tst flag breq mcloop ;if not proper push, continue looping mcwlp3: sbis PINB,3 ;wait for button release rjmp mcwlp3 rjmp mmenu ;if proper push jump to button function ;option3 of main menu selected synchronization mode menu smmenu: rcall lcdclr clr flag ;reset flag for use in debounce ldi ZL,low(syncset*2) ;load menu title ldi ZH,high(syncset*2) rcall printfl ;print menu title ldi wreg,0xC0 ;set 2nd line addr rcall lcdcmd ldi ZL,low(b_recinfo*2) ;load 1st option line ldi ZH,high(b_recinfo*2) rcall printfl ;print 1st option line ldi wreg,0x94 ;set 3rd line addr rcall lcdcmd ldi ZL,low(a_sendinfo*2) ;load 2nd option line ldi ZH,high(a_sendinfo*2) rcall printfl ;print 2nd option line ldi wreg,0xD4 ;set 4th line addr rcall lcdcmd ldi ZL,low(c_return*2) ;load 3rd option line ldi ZH,high(c_return*2) rcall printfl ;print 3rd option line ;sync mode menu set up so check buttons smloop: sbic PINB,1 ;check 1st button rjmp smbut2 ;if not pushed check 2nd button ldi wreg,0x02 rcall debounce ;if pushed debounce it tst flag breq smloop ;if not proper push, continue looping smwlp1: sbis PINB,1 ;wait for button release rjmp smwlp1 rjmp recinfo ;if proper push jump to button function smbut2: sbic PINB,2 ;check 2nd button rjmp smbut3 ;if not pushed check 3rd button ldi wreg,0x04 rcall debounce ;if pushed debounce it tst flag breq smloop ;if not proper push, continue looping smwlp2: sbis PINB,2 ;wait for button release rjmp smwlp2 rjmp sendinfo ;if proper push jump to button function smbut3: sbic PINB,3 ;check 3rd button rjmp smloop ;if not pushed loop again ldi wreg,0x08 rcall debounce ;if pushed debounce it tst flag breq smloop ;if not proper push, continue looping smwlp3: sbis PINB,3 ;wait for button release rjmp smwlp3 rjmp mmenu ;if proper push jump to button function ;/////////////END OF MENUING SECTION\\\\\\\\\\\\\\ ;Setup handheld to receive from PC recinfo: rcall lcdclr ldi RXchar,0x00 RX1: cpi RXchar,0x00 ;wait for the 1st initialization string of ASCII 0 breq RX1 cpi RXchar,0x01 ;compare input character brne RX1 ;check fails so continue waiting RXt2: cpi RXchar,0x00 ;wait for the 1st initialization string of ASCII 0 breq RXt2 cpi RXchar,0x04 ;compare input character brne RXt2 ;check fails so continue waiting RXt3: cpi RXchar,0x00 ;wait for the 1st initialization string of ASCII 0 breq RXt3 cpi RXchar,0x05 ;compare input character brne RXt3 ;check fails so continue waiting ;string initialize checks out from PC so begin loading contacts database into SRAM ldi ZH,high(contacts) ;setup write to contacts SRAM addr ldi ZL,low(contacts) clr temp mov cdbcount,temp ;contacts counter ldi RXchar,0x00 ldi temp,contactlimit ;limit contacts list to 2 to fit in 8535 SRAM RXcon: cpi RXchar,0x00 breq RXcon ;wait to receive next character cpi RXchar,0x03 ;check for end of one contact brne skipc1 inc cdbcount ;if end of contact inc counter cp cdbcount,temp ;check to see if we've reached contacts list limit breq RXcon1a ;if so move on to memos skipc1: st Z,RXchar ;else store the character in SRAM adiw ZL,1 clr RXchar rjmp RXcon ;receive more contacts data RXcon1a:st Z,RXchar ;store the last 0x03 character adiw ZL,1 clr RXchar RXcon1: cpi RXchar,0x00 ;we've hit the contacts limit so just let the chars go breq RXcon1 ;wait to receive next character cpi RXchar,0x01 ;check for end of contacts transmission breq RX2 ;contacts done so end RX clr RXchar rjmp RXcon1 ;receive more contact data ;contacts are done so add terminator to contact string and load all memo data RX2: ldi temp,0x01 ;store terminating 0x01 on contacts string st Z,temp clr RXchar ;reset RXchar ldi ZH,high(memos) ;setup write to memos SRAM addr ldi ZL,low(memos) clr temp mov mdbcount,temp ;memos counter ldi temp,memolimit ;limit memos list to 2 to fit in 8535 SRAM RXmem: cpi RXchar,0x00 breq RXmem ;wait to receive next character cpi RXchar,0x03 ;check for end of one memo brne skipc2 inc mdbcount ;if end of memo inc counter cp mdbcount,temp ;check to see if we've reached contacts list limit breq RXmem1a ;if so move on to memos skipc2: st Z,RXchar ;else store the character in SRAM adiw ZL,1 clr RXchar rjmp RXmem ;receive more memo data RXmem1a:st Z,RXchar ;store the last 0x03 character adiw ZL,1 clr RXchar RXmem1: cpi RXchar,0x00 ;we've hit the memos limit so just let the chars go breq RXmem1 ;wait to receive next character cpi RXchar,0x01 ;check for end of memos transmission breq RXfin ;memos done so end RX clr RXchar rjmp RXmem1 ;receive more memo data ;RX done so display msg indicating done and turn off RX interrupt RXfin: ldi temp,0x01 ;store terminating 0x01 on contacts string st Z,temp rcall lcdclr ;reset display ldi ZL,low(recdone*2) ;load done msg ldi ZH,high(recdone*2) rcall printfl ;print done msg ldi timeout,0 ;set t0 reload to 0 ldi longtime,100 ;loop counter for getting longtime * 16ms delay displp: rcall delay ;run t0 longtime times w/prescal = 256 dec longtime brne displp rjmp smmenu ;prints 4 lines from RAM when browsing contact or memo info print4lines: rcall lcdclr ;initializes pointer to first line mov XL,ZL ;copy Z location so it can be restored mov XH,ZH ldi ZL,low(row1) ;print row1 from SRAM ldi ZH,high(row1) rcall printRAM ldi wreg,0xC0 ;move to display line2 rcall lcdcmd ldi ZL,low(row2) ;print row2 from SRAM ldi ZH,high(row2) rcall printRAM ldi wreg,0x94 ;move to display line3 rcall lcdcmd ldi ZL,low(row3) ;print row3 from SRAM ldi ZH,high(row3) rcall printRAM ldi wreg,0xD4 ;move to display line4 rcall lcdcmd ldi ZL,low(row4) ;print row4 from SRAM ldi ZH,high(row4) rcall printRAM mov ZL,XL ;restore prior Z location mov ZH,XH ret ;Button push debounce routine which returns flag set when button is pushed properly ; after two 33ms checks debounce: mov timetemp,temp ldi timeout,0 ;set t0 reload value to 0 ldi longtime,2 ;loop counter delaylp: rcall delay ;run t0 2 times w/prescal = 256 => 33ms dec longtime brne delaylp in temp,PINB ;check buttons com temp ;make button push = 1 not 0 tst temp ;check for button push brne flagset clr flag ;if no push, notify of no push and return mov temp,timetemp ret flagset: ldi longtime,2 ;loop counter delaylp2: rcall delay ;run t0 2 times w/prescal = 256 => 33ms dec longtime brne delaylp2 in temp,PINB ;check buttons com temp ;make button push = 1 not 0 tst temp ;check for button push brne flagset1 clr temp mov flag,temp ;if no push, notify of no push and return mov temp,timetemp ret flagset1:ser temp mov flag,temp ;otherwise button press okayed mov temp,timetemp ret .include "hheldin1.asm" .include "hheldin2.asm" .include "contacts.asm" .include "memos.asm" sendmsg: clr RXchar clr cursorow ldi ZL,low(row1) ;load row 1 ldi ZH,high(row1) ldi wreg,0x20 ;set wreg to space ldi temp,20 ;set limit to 20 clearlp1: st Z+,wreg ;clear all characters on first row dec temp brne clearlp1 clr wreg st Z+,wreg ldi ZL,low(row2) ;load row 2 ldi ZH,high(row2) ldi wreg,0x20 ;set to space ldi temp,20 ;set limit to 20 characters clearlp2: st Z+,wreg ;set all characters to spaces on 2nd row dec temp brne clearlp2 clr wreg st Z+,wreg ldi ZL,low(row3) ;load row 3 ldi ZH,high(row3) ldi wreg,0x20 ;set to space ldi temp,20 ;set limit to 20 clearlp3: st Z+,wreg ;set all characters to spaces on 3rd row dec temp brne clearlp3 clr wreg st Z+,wreg ldi ZL,low(row4) ;load row 4 ldi ZH,high(row4) ldi wreg,0x20 ;set to space ldi temp,20 ;set limit to 20 clearlp4: st Z+,wreg ;set all characters to spaces on the 4th row dec temp brne clearlp4 clr wreg st Z+,wreg rcall lcdclr rcall print4lines ;print 4 blank lines ldi wreg,0b00001110 ;display cursor rcall lcdcmd ldi wreg,0x80 ;set cursor position to the beginning rcall lcdcmd sndlp: sbic PINB,1 ;check send button rjmp sndbut3 ;if not pushed loop again ldi wreg,2 rcall debounce ;if pushed debounce it tst flag breq sndlp ;if not proper push, continue looping sndbut1:sbis PINB,1 ;wait for button release rjmp sndbut1 rcall sendnow rjmp sndlp sndbut3:sbic PINB,3 ;check if the user wants to edit the curent row rjmp sndbut4 ldi wreg,16 rcall debounce ;debounce tst flag breq sndbret sndwbut3:sbis PINB,3 ;wait for button to be released rjmp sndwbut3 cpi cursorow,3 ;determine the currrent row that we are on breq sndnextrow4 cpi cursorow,2 breq sndnextrow3 cpi cursorow,1 breq sndnextrow2 ldi XL,low(row1) ;if on row 1 load row1 ldi XH,high(row1) ldi wreg,19 ; set line limit to 20 characters rjmp sndcontrow sndnextrow2: ldi XL,low(row2) ;if on row 2 load row 2 ldi XH,high(row2) ldi wreg,19 ;set line limit to 20 characters rjmp sndcontrow sndnextrow3: ldi XL,low(row3) ;if on row 3 load row 3 ldi XH,high(row3) ldi wreg,19 ;set line limit to 20 characters rjmp sndcontrow sndnextrow4: ldi XL,low(row4) ;if on row 4 load row 4 ldi XH,high(row4) ldi wreg,19 ;set line limit to 20 characters rjmp sndcontrow sndcontrow: mov YL,XL ;load pointer for Editchar mov YH,XH rcall Editchar ldi wreg,0b00001110 ;display cursor rcall lcdcmd ldi wreg,0x80 ;move cursor back to the beginning rcall lcdcmd clr cursorow sndbret:rjmp sndlp sndbut4:sbic PINB,4 ;check to see if the user wants to move up rjmp snddbbut5 ;one row ldi wreg,32 rcall debounce ;debounce tst flag breq snddblp1 sndwbut4:sbis PINB,4 ;wait for button to be released rjmp sndwbut4 cpi cursorow,0 ;determine the row that we are currently on breq sndrow41 cpi cursorow,1 breq sndrow42 cpi cursorow,2 breq sndrow43 ldi wreg,0x94 ;if on row 4 move to row 3 rcall lcdcmd dec cursorow snddblp1:rjmp sndlp sndrow41:rjmp sndlp ;if one row 1 do nothing sndrow42:dec cursorow ;if on row 2 move to row 1 ldi wreg,0x80 rcall lcdcmd rjmp sndlp sndrow43:dec cursorow ;if on row 3 move to row 2 ldi wreg,0xC0 rcall lcdcmd rjmp sndlp snddbbut5:sbic PINB,5 ;chekc to see if the user wants to move down rjmp sndbut0 ldi wreg,64 rcall debounce ;debounce tst flag breq sndlp1 sndwbut5:sbis PINB,5 ;wait for button to be released rjmp sndwbut5 cpi cursorow,0 ;determine current row breq sndrow51 cpi cursorow,1 breq sndrow52 cpi cursorow,2 breq sndrow53 rjmp sndlp ;if on row 4 do nothing sndrow51:inc cursorow ;if on row 1 move to row 2 ldi wreg,0xC0 rcall lcdcmd rjmp sndlp sndrow52:inc cursorow ;if on row 2 move to row 3 ldi wreg,0x94 rcall lcdcmd rjmp sndlp sndrow53:inc cursorow ;if on row 3 move to row 4 ldi wreg,0xD4 rcall lcdcmd sndlp1: rjmp sndlp sndbut0:sbic PINB,0 ;check to see if the user is ready to exit rjmp sndlp ldi wreg,1 rcall debounce ;debounce tst flag breq sndlp1 sndwbut0:sbis PINB,0 ;wait for button to be released rjmp sndwbut0 clr RXchar rjmp mcmenu ;return to previous menu ; sends messages sendnow: ;now the pointer to the variable message in RAM ldi ZL, LOW(row1) ;ptr to RAM row1 ldi ZH, HIGH(row1) ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ldi ZL, LOW(row2) ;ptr to RAM row2 ldi ZH, HIGH(row2) ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ldi ZL, LOW(row3) ;ptr to RAM row3 ldi ZH, HIGH(row3) ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ldi ZL, LOW(row4) ;ptr to RAM row4 ldi ZH, HIGH(row4) ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ret ;Receive messages from another unit recmode: ldi RXchar,0x00 ldi ZL,low(recready*2) ldi ZH,high(recready*2) rcall lcdclr rcall printfl ;display message to let the user know that ;we are in receive mode ldi ZL,low(row1) ;load pointer to row1 ldi ZH,high(row1) ldi temp,20 reclp1: cpi RXchar,0x00 ;wait for a non-zero character breq reclp1 st Z+,RXchar ;store character clr RXchar dec temp ;make sure we are not at the end of the line brne reclp1 st Z+,RXchar ;if we are store a terminating 0 ldi ZL,low(row2) ;load pointer to row2 ldi ZH,high(row2) ldi temp,20 ;set limit reclp2: cpi RXchar,0x00 ;wait for non-zero characters breq reclp2 st Z+,RXchar ;store character clr RXchar dec temp ;make sure we are not at the end of the line brne reclp2 st Z+,RXchar ;store a terminating 0 ldi ZL,low(row3) ;load pointer to row 3 ldi ZH,high(row3) ldi temp,20 ;set row limit reclp3: cpi RXchar,0x00 ;wait for non-zero characters breq reclp3 st Z+,RXchar ;store character clr RXchar dec temp ;make sure we are not at the end of the line brne reclp3 st Z+,RXchar ;store a terminating 0 ldi ZL,low(row4) ;load a pointer to row 4 ldi ZH,high(row4) ldi temp,20 reclp4: cpi RXchar,0x00 ;wait for non-zero characters breq reclp4 st Z+,RXchar ;store chracter clr RXchar dec temp ;make sure we are not at the end of the line brne reclp4 st Z+,RXchar ;store a terminating character rcall lcdclr rcall print4lines ;print all data received recwait:sbis PINB,0 ;check to see if the user if ready to exit rjmp mcmenu rjmp recwait ;This will send the handheld's contacts and memos database ; information to the Java program running on the PC sendinfo: ;send transfer initialization characters ldi ZL,low(initString*2) ldi ZH,high(initString*2) lpm out UDR, r0 ser TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ;initialization sent so now send contacts database ldi XL,low(contacts) ;initialize Z to beginning of contacts list ldi XH,high(contacts) ldi ZL,low(tempchar) ldi ZH,high(tempchar) sndcdb: ld wreg,X+ ;send each character until a 1 is reahed cpi wreg,0x01 breq send1 st Z,wreg ldi wreg,0x00 std Z+1,wreg ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ldi ZL,low(tempchar) ldi ZH,high(tempchar) rjmp sndcdb ; send a one send1: ldi ZL,low(tempchar) ldi ZH,high(tempchar) ldi wreg,0x01 st Z,wreg ldi wreg,0x00 std Z+1,wreg ld r0,Z out UDR, r0 clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ldi XL,low(memos) ;initialize Z to beginning of memos list ldi XH,high(memos) ldi ZL,low(tempchar) ldi ZH,high(tempchar) sndmdb: ld wreg,X+ ;send each character individually until a 1 is reached cpi wreg,0x01 breq send1a st Z,wreg ldi wreg,0x00 std Z+1,wreg ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ldi ZL,low(tempchar) ldi ZH,high(tempchar) rjmp sndmdb ; send a 1 send1a: ldi ZL,low(tempchar) ldi ZH,high(tempchar) ldi wreg,0x01 st Z,wreg ldi wreg,0x00 std Z+1,wreg ld r0,Z out UDR, r0 clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait snddone:rcall lcdclr ;reset display ldi ZL,low(datasent*2) ;load done msg ldi ZH,high(datasent*2) rcall printfl ;print done msg ldi timeout,0 ;set t0 reload to 0 ldi longtime,100 ;loop counter for getting longtime * 16ms delay snddisp:rcall delay ;run t0 longtime times w/prescal = 256 dec longtime brne snddisp ;leave done message on screen for a few (~1.6) seconds rjmp smmenu ;return to synchronization menu