;******************************** ;You will need to CHANGE this path .nolist .include "c:\avrtools\appnotes\8535def.inc" .list ;******************************** .def save =r1 .def free1 =r2 .def bcount =r3 .def sumL =r4 .def sumH =r5 .def TXbuffL =r6 .def TXbuffH =r7 .def nBytesL =r8 .def nBytesH =r9 .def nErorsL =r10 .def nErorsH =r11 .def midL =r12 .def midH =r13 .def txL =r14 .def txH =r15 .def rxL =r16 .def rxH =r17 .def timeout =r19 .def temp =r20 .def tempH =r21 .def RXbuffL =r22 .def RXbuffH =r23 .def RXbitcnt=r24 .def TXbitcnt=r25 .def TXphase =r26 .def RXphase =r27 .def RXchar =r28 .def MODREG =r29 .equ Nsamples= 8 .equ samptime= 5000 ; ie every 10 msec .equ midline = 256 .equ baud96 =25 ;9600 baud constant for 4Mhz crystal .equ MPS0 = 0 .equ MPS1 = 1 .equ TXALN = 5 .equ UARTRX = 6 .equ DEBUG = 7 .equ prescal = 1 .macro msbr push temp mov temp, @0 sbr temp, @1 mov @0, temp pop temp .endmacro .macro mcbr push temp mov temp, @0 cbr temp, @1 mov @0, temp pop temp .endmacro .macro incWord push temp ldi temp, 1 add @0L, temp clr temp adc @0H, temp pop temp .endmacro ;******************************* ; Initialization .cseg .org $0000 rjmp RESET ;reset entry vector reti ;2 reti ;3 reti ;4 reti ;5 reti ;6 rjmp compA ; timer 1 compare match A reti ;8 reti ;9 reti ;10 reti ;11 rjmp RXdone ;12 reti ;13 reti ;14 reti ;15 reti ;16 reti ;17 sigtbl: .db 0x00, 0x20, 0x40, 0x60, 0x60, 0x40, 0x20, 0x00 asctbl: .db "0123456789ABCDEF" crlf: .db 0x0d, 0x0a, 0x00 qt: .db "Quitting debug mode....", 0x00 dbgstr: .db "debug>", 0x00 clrstat:.db "Clearing stats.", 0x00 nbstr: .db "Number of bytes: ", 0x00 nestr: .db "Number of errors: ", 0x00 hello: .db "testing.....", 0x00 foo: .db "..entering ISR..", 0x00 curExp: .db "Curr exp: ", 0x00 fbyte: .db "Final byte: ", 0x00 gotaone:.db "Got a one", 0x00 gotazer:.db "Got a zero",0x00 gotasyn:.db "Gotsync", 0x00 rsetstr:.db "Clearing statistics", 0x00 dbgpmt: .db "debug>", 0x00 tunedn: .db " -> Turn Aref down", 0x00 tuneup: .db " -> Turn Aref up", 0x00 errfnd: .db "error found", 0x00 gbb: .db "**", 0x00 star: .db "*" pps: .db "+", 0x00 .macro macputF ldi ZH, HIGH(@0*2) ldi ZL, low(@0*2) rcall putFstr .endmacro ;******************************* RESET: ldi Temp, LOW(RAMEND) ;setup stack pointer out SPL, Temp ldi Temp, HIGH(RAMEND) out SPH, Temp ;set up the PORTs ldi temp, 0x7F out DDRD, temp ser temp ;set PORTB to be out DDRC,temp ;all outputs ser temp out DDRB, temp ldi temp, midline out PortC, temp out PortB, temp ;setup timer 1 for reset on compare match and disable for now ldi temp, 8 + prescal out TCCR1B, temp ldi Temp,0b00010000 out TIMSK, Temp ;setup UART -- enable RX, TX pins & RX int. ldi temp, 0b10011000 out UCR, temp ;set baud rate to 9600 ldi temp, baud96 out UBRR, temp clr MODREG ;setup ADC clr temp out ADMUX, temp ; set channel 0 ldi temp, HIGH(samptime) out OCR1AH, temp ldi temp, LOW(samptime) out OCR1AL, temp clr RXbuffL clr RXbuffH clr nBytesL clr nBytesH clr nErorsL clr nErorsH ldi temp, high(midline) out PortC, temp ldi temp, low(midline) out PortB, temp sei ;enable all interrupts clr bcount mloop: sbrs MODREG, DEBUG rjmp mnorm ; macputF gbb ; macputF crlf sbrs MODREG, UARTRX rjmp mloop cbr MODREG, exp2(UARTRX) rcall procDBG rjmp mloop mnorm: ; rcall perfTst sbrs MODREG, UARTRX rjmp mloop cbr MODREG, exp2(UARTRX) rcall procRX rjmp mloop getAna: push temp ldi temp, 0b11000101 out ADCSR, temp swait: in temp, ADCSR ;wait for A to D start andi temp, 0b01000000;by checking if ADSC bit is set breq swait ;this bit is set by t1match interrupt await: in temp, ADCSR ;wait for A to D done andi temp, 0b01000000;by checking ADSC bit brne await ;this bit is cleared by the AtoD hardware pop temp ret tunemid:clr temp clr midL clr midH _tuntst:cpi temp, 4 breq _tunend rcall getAna rcall getAna in rxL, ADCL in rxH, ADCH add midL, rxL adc midH, rxH ldi tempH, low(midline) sub midH, tempH ldi tempH, high(midline) sbc midH, tempH inc temp rjmp _tuntst _tunend:clc ror midH ror midL clc ror midH ror midL ldi temp, low(midline) ldi tempH, high(midline) add midL, temp adc midH, tempH ret procDBG:cpi RXchar, 'q' breq _bug0 cpi RXchar, 'u' breq _bug1 cpi RXchar, 'd' breq _bug2 cpi RXchar, 'r' breq _bug3 cpi RXchar, 's' breq _bug4 cpi RXchar, 't' breq _bug5 _enddbg:macputF crlf macputF dbgstr ret _bug0: macputF qt macputF crlf cbr MODREG, exp2(DEBUG) ret rjmp _enddbg _bug1: ldi temp, 1 rcall setPre rjmp _enddbg _bug2: ldi temp, 0xFF rcall setPre rjmp _enddbg _bug3: clr nBytesL clr nBytesH clr nErorsL clr nErorsH macputF crlf macputF clrstat macputF crlf rjmp _enddbg _bug4: macputF crlf macputF nbstr mov temp, nBytesH rcall putReg mov temp, nBytesL rcall putReg macputF crlf macputF nestr mov temp, nErorsH rcall putReg mov temp, nErorsL rcall putReg rjmp _enddbg _bug5: rcall tunemid macputF crlf mov temp, midH rcall putReg mov temp, midL rcall putReg rjmp _enddbg perfTst:mov TXbuffL, bcount rcall TXbyte ldi timeout, 0x14 rcall delay ldi temp, 1 add bcount, temp ret procRX: mov TXbuffL, RXchar rcall TXbyte cpi RXchar, 0x0d brne prend ldi temp, 0x0a _prx: sbis USR, UDRE rjmp _prx out UDR, temp mov TXbuffL, temp rcall TXbyte prend: ret delay: tst timeout brne delay ret TXsync: ldi temp, 0xff ldi tempH, 0x03 rcall TXalign ret genPar: mov temp, TXbuffL clr TXbuffH _ptest: tst temp breq _parend sbrc temp, 7 inc TXbuffH lsl temp rjmp _ptest _parend:sbrs TXbuffH, 0 ret msbr TXbuffH, 0b10000000 ret TXpar: push TXbuffL mov TXbuffL, TXbuffH rcall TXbit pop TXbuffL ret TXbit: clr TXphase ; macputF star ; macputF crlf ldi ZL, LOW(sigtbl*2) ldi ZH, HIGH(sigtbl*2) _bloop: cpi TXphase, Nsamples breq _bitend lpm ; r0 rcall doPre ; clr r2 ldi temp, low(midline) ldi tempH, high(midline) sbrs TXbuffL, 7 rjmp _foo add temp, r0 ; a '1' clr r0 adc tempH, r0 rjmp _bbb _foo: sub temp, r0 ; a '0' clr r0 sbc tempH, r0 _bbb: rcall TXalign inc TXphase adiw ZL, 1 rjmp _bloop _bitend:ret TXbyte: rcall TXsync rcall genPar rcall TXpar ldi TXbitcnt, 0 _byloop:cpi TXbitcnt, 8 breq _byend rcall TXbit lsl TXbuffL inc TXbitcnt rjmp _byloop _byend: ldi temp, low(midline) ldi tempH, high(midline) rcall TXalign ret setPre: mov tempH, MODREG andi tempH, 0x03 add tempH, temp andi tempH, 0x03 mov temp, MODREG andi temp, 0xFC or temp, tempH mov MODREG, temp ret doPre: sbrc MODREG, MPS0 asr r0 sbrs MODREG, MPS1 ret asr r0 asr r0 ret TXalign:cli cbr MODREG, exp2(TXALN) mov txL, temp mov txH, tempH sei _txa: sbrs MODREG, TXALN rjmp _txa ret compA: in save, SREG push temp push tempH push ZL push ZH out PortC, txH out PortB, txL sbr MODREG, exp2(TXALN) sbrc MODREG, DEBUG rjmp _aaa sbic PinD, 7 rjmp _aaa sbr MODREG, exp2(DEBUG) ldi RXphase, Nsamples macputF crlf macputF dbgstr _aaa: dec timeout sbrs MODREG, DEBUG rcall getInpt pop ZH pop ZL pop tempH pop temp out SREG, save reti getInpt2: ret getInpt:push r0 push r19 ; ie - timeout -> gets mauled by mpy8s rcall getAna in rxL, ADCL in rxH, ADCH andi rxH, 0x03 cpi rxH, 0x03 brlt _corr rcall procSyn ; found a sync pulse rjmp _getend _corr: cpi RXphase, nSamples brlt _hop rjmp _getend ; past end of bit stop correlating _hop: sub rxL, midL sbc rxH, midH ; mov temp, rxH ; rcall putReg ; mov temp, rxL ; rcall putReg ; macputF crlf ldi ZL, LOW(sigtbl*2) ldi ZH, HIGH(sigtbl*2) clr r0 add ZL, RXphase adc ZH, r0 lpm ; r0 mov r17, r0 rcall mpy8s add sumL, r17 adc sumH, r18 inc RXphase cpi RXphase, Nsamples brne _getend rcall gotBit _getend:pop r19 pop r0 ret procSyn: ; macputF gotasyn ; macputF crlf clr RXphase ; sync pulse clr sumL clr sumH clr RXbitcnt clr RXbuffL clr RXbuffH ret gotBit: clc rol RXbuffL rol RXbuffH sbrc sumH, 7 ; <<<<<-----------------switch ori RXbuffL, 0x01 inc RXbitcnt cpi RXbitcnt, 9 brne _notbyt rcall gotByte ret _notbyt:clr RXphase clr sumL clr sumH ret gotByte:rcall chkPar rcall procByt ret procByt:incWord nBytes mov temp, RXbuffL _pb: sbis USR, UDRE rjmp _pb out UDR, temp ; rcall putReg ret chkPar: andi RXbuffH, 0x01 mov temp, RXbuffL _chktst:tst temp breq _endchk sbrc temp, 7 inc RXbuffH lsl temp rjmp _chktst _endchk:sbrs RXbuffH, 0 ret ; even # of 1's macputF errfnd ; odd # of 1's found macputF crlf incWord nErors ret putFstr:push r0 _fgtchr:lpm adiw ZL, 1 tst r0 breq _flstch _bar: sbis USR, UDRE rjmp _bar out UDR, r0 rjmp _fgtchr _flstch:pop r0 ret putReg: push r0 push temp swap temp andi temp, 0x0F ldi ZL, low(asctbl*2) ldi ZH, high(asctbl*2) add ZL, temp clr temp adc ZH, temp lpm ; r0 _xa: sbis USR, UDRE rjmp _xa out UDR, r0 pop temp push temp andi temp, 0x0F ldi ZL, low(asctbl*2) ldi ZH, high(asctbl*2) add ZL, temp clr temp adc ZH, temp lpm ; r0 _xb: sbis USR, UDRE rjmp _xb out UDR, r0 pop temp pop r0 ret RXdone: in save, SREG push temp in RXchar, UDR _rxx: sbis USR, UDRE rjmp _rxx out UDR, RXchar sbr MODREG, exp2(UARTRX) pop temp out SREG, save reti ;*************************************************************************** ;* ;* "mpy8s" - 8x8 Bit Signed Multiplication ;* ;* This subroutine multiplies signed the two register variables mp8s and ;* mc8s. The result is placed in registers m8sH, m8sL ;* The routine is an implementation of Booth's algorithm. If all 16 bits ;* in the result are needed, avoid calling the routine with ;* -128 ($80) as multiplicand ;* ;* Number of words :10 + return ;* Number of cycles :73 + return ;* Low registers used :None ;* High registers used :4 (mc8s,mp8s/m8sL,m8sH,mcnt8s) ;* ;*************************************************************************** ;***** Subroutine Register Variables .def mc8s =r16 ;multiplicand .def mp8s =r17 ;multiplier .def m8sL =r17 ;result Low byte .def m8sH =r18 ;result High byte .def mcnt8s =r19 ;loop counter ;***** Code mpy8s: sub m8sH,m8sH ;clear result High byte and carry ldi mcnt8s,8 ;init loop counter m8s_1: brcc m8s_2 ;if carry (previous bit) set add m8sH,mc8s ; add multiplicand to result High byte m8s_2: sbrc mp8s,0 ;if current bit set sub m8sH,mc8s ; subtract multiplicand from result High asr m8sH ;shift right result High byte ror m8sL ;shift right result L byte and multiplier dec mcnt8s ;decrement loop counter brne m8s_1 ;if not done, loop more ret