;*********************************************************************
; LaserPro.asm
;
; For the ATmega88
;
; Laserprojector steering software
;
; Program settings:
; BOOTSZ = 11, BODLEVEL = 100, CKSEL = 0111, SUT = 11
; (brownout VCC = 4,3V, ext. full swing XTal)
;
;*********************************************************************
.include "m88def.inc"
;*********************************************************************
; Definitions
;*********************************************************************
.def T0 = r13 ;servo response time x 100 uS
.def Td = r14 ;extra response time (Tr = T0 + Td x dS/dSmax)
.def px = r22 ;projection x coordinate
.def py = r23 ;projection y coordinate
.def prevX = r4 ;previous X
.def prevY = r5 ;previous Y
.def prSize = r24 ;image proj. size
.def TimeH = r20 ;Timer H x 1 mS
.def TimeL = r19 ;Timer L x 1 mS
.def RxBufPtr = r7 ;Rx buffer index
.def Key = r8 ;Last KEY from terminal
.def ScrollWidth = r12 ;Scrollwidth (letters)
.def RevXY = r15 ;Reverse X/Y (b1,b0)
.def Mode = r9 ;Mode 1-4
;*********************************************************************
;*********************************************************************
; Constants
;*********************************************************************
.equ on = 1
.equ off = 0
.equ end = 2
;modes
.equ TxScr = 1
.equ TxWd = 2
.equ Yt = 3
.equ XYZ = 4
;default settings
.equ T0def = 15
.equ Tddef = 100
.equ TimeHdef = high(300)
.equ TimeLdef = low(300)
.equ prSizedef = 30
.equ ScrollWidthdef = 5
.equ RevXYdef = 0b00000001 ;b0 Y, b1 X
.equ ModeDef = TxScr
;misc
.equ StrBufSize = 35
.equ ScrollBufSize = 256
.equ TextBufSize = 238
.equ RxBufSize = 241
.equ CMDsize = 2
.equ ScrollY = 0 ;text start Y
.equ CTCrun = 0b00001001
.equ CTChalt = 0b00001000
.equ ADCmux = 0b01100000 ;ref=Vcc, ADLAR (8bits)
.equ ADCpre = 0b00000111 ;prescaler 128
.equ UBRR = 129 ;9600 Baud
;ASCII control
.equ CR = 13
.equ LF = 10
.equ BS = 8
.equ Prompt = '>'
.equ EWr = 0x5a ;flag EEPROM settings written
;*********************************************************************
;*********************************************************************
; Variables
;*********************************************************************
.dseg
;buffers
strbuf: .byte StrBufSize
ScrollBuf: .byte ScrollBufSize
RxBuf: .byte RxBufSize
TextBuf: .byte TextBufSize
;*********************************************************************
;*********************************************************************
; Macro's
;*********************************************************************
.macro LASER
.if @0 == on
sbi PortD,4
.endif
.if @0 == off
cbi PortD,4
.endif
.endm
.macro MoveTo
sbrc RevXY,1
com @0
out OCR0B,@0 ;X
sbrc RevXY,1
com @0
sbrc RevXY,0
com @1
sts OCR2B,@1 ;Y
sbrc RevXY,0
com @1
sub PrevX,@0
brcc mt00
neg PrevX
mt00:
sub PrevY,@1
brcc mt01
neg PrevY
mt01:
cp PrevX,PrevY
brcc mt02
mov PrevX,prevY
mt02:
mov r16,Td
mul r16,PrevX
mov r16,T0
mov PrevX,@0
mov PrevY,@1
add r16,r1
rcall Delay100uS
.endm
.macro LoadScrollBuf
ldi Zl,low(@0*2)
ldi Zh,high(@0*2)
rcall msg2scrollbuf
.endm
.macro LoadTextBuf
ldi Zl,low(@0*2)
ldi Zh,high(@0*2)
rcall msg2Textbuf
.endm
.macro DrawPattern
ldi r17,@1
Dp:
ldi Zl,low(@0*2)
ldi Zh,high(@0*2)
rcall Draw
dec r17
brne Dp
.endm
.macro StartTimer
clt
mov r11,@0
mov r10,@1
;reset prescaler
ldi r16, 1<<PSRSYNC
out GTCCR,r16
;set timer to zero
clr r16
sts TCNT1H,r16
sts TCNT1L,r16
;run timer
ldi r16,CTCrun ;CTC mode,presc=1
sts TCCR1B,r16
.endm
.macro IfTime
brts @0
.endm
.macro IfnTime
brtc @0
.endm
.macro StartADC
;select channel
ori @0,ADCmux
sts ADMUX,@0
;start conversion
ldi @0,ADCpre | (1<<ADEN) | (1<<ADSC) | (1<<ADIF)
sts ADCSRA,@0
.endm
.macro IfADCbusy
lds r16,ADCSRA
andi r16,1<<ADIF
breq @0
.endm
.macro TxByte
;Wait for Tx rdy
txb0:
lds r6,UCSR0A
sbrs r6,UDRE0
rjmp Txb0
;transmit
sts UDR0,@0
.endm
.macro LoadTxBuf
ldi Zl,low(@0*2)
ldi Zh,high(@0*2)
rcall Txmsg2buf
.endm
;*********************************************************************
.cseg
;*********************************************************************
; Interrupt adresses
;*********************************************************************
.org 0x0000 rjmp Reset
.org 0x000B rjmp T1_COMPA ;T1 OC int
.org 0x0012 rjmp RxRdy ;USART Rx complete
.org 0x0020
;*********************************************************************
;*********************************************************************
; Tables
;*********************************************************************
;default settings
defSet:
.db T0def,Tddef,TimeHdef,TimeLdef,prSizedef,ScrollWidthdef,RevXYdef,Modedef
defTxt:
.db "Laser-projector 2008",0
;ASCII table:
;space to /
a32: .db 0,0,end
a33: .db 127,0,on,127,32,off,127,127,on,127,255,end
a34: .db 127-32,255,on,127-32,255-32,off,127+32,255,on,127+32,255-32,end
a35: .db 0,0,end
a36: .db 0,0,end
a37: .db 0,0,end
a38: .db 0,0,end
a39: .db 127,255,on,127-32,255-32,end
a40: .db 0,0,end
a41: .db 0,0,end
a42: .db 64,255-64,on,255-64,64,off,255-64,255-64,on,64,64,off,127,255-64,on,127,64,end
a43: .db 0,127,on,255,127,off,127,255,on,127,0,end
a44: .db 127,48,on,127-48,0,end
a45: .db 0+64,127,on,255-64,127,end
a46: .db 127,0,on,127,16,end
a47: .db 0,0,on,255,255,end
;0-9
a48: .db 0,0,on,0,255,on,255,255,on,255,0,on,0,0,end
a49: .db 127,0,on,127,255,end
a50: .db 0,255,on,255,255,on,255,127,on,0,127,on,0,0,on,255,0,end
a51: .db 0,255,on,255,255,on,255,0,on,0,0,off,255,127,on,0,127,end
a52: .db 0,255,on,0,127,on,255,127,off,255,255,on,255,0,end
a53: .db 255,255,on,0,255,on,0,127,on,255,127,on,255,0,on,0,0,end
a54: .db 255,255,on,0,255,on,0,0,on,255,0,on,255,127,on,0,127,end
a55: .db 0,255,on,255,255,on,0,0,end
a56: .db 0,0,on,0,255,on,255,255,on,255,0,on,0,0,off,0,127,on,255,127,end
a57: .db 0,0,on,255,0,on,255,255,on,0,255,on,0,127,on,255,127,end
;symbols :,;,<,=,>,?,@
a58: .db 127,0,on,127,10,off,127,255-10,on,127,255,end
a59: .db 127-10,0,on,127,10,off,127,255-10,on,127,255,end
a60: .db 255,255,on,0,127,on,255,0,end
a61: .db 0,127+64,on,255,127+64,off,0,127-64,on,255,127-64,end
a62: .db 0,255,on,255,127,on,0,0,end
a63: .db 0,255,on,255,255,on,255,127,on,127,127,on,127,64,off,127,32,on,127,0,end
a64: .db 0,0,end;255,127+20,on,255-20,127+20,on,255-20,127,on,255,127,on,255,255,on,0,255,on,0,0,on,255,0,end
;A-Z
a65: .db 0,0,on,0,255,on,255,255,on,255,0,off,255,127,on,0,127,end
a66: .db 0,127,on,0,0,on,255,0,on,255,127,on,0,127,on,0,255,on,255-30,255,on,255-30,127,end
a67: .db 255,0,on,0,0,on,0,255,on,255,255,end
a68: .db 0,0,on,0,255,on,255,255-50,on,255,50,on,0,0,end
a69: .db 255,0,on,0,0,on,0,255,on,255,255,off,0,127,on,255,127,end
a70: .db 0,0,on,0,255,on,255,255,off,0,127,on,255,127,end
a71: .db 255,255,on,0,255,on,0,0,on,255,0,on,255,127,on,127,127,end
a72: .db 0,0,on,0,255,off,255,255,on,255,0,off,255,127,on,0,127,end
a73: .db 127-32,255,on,127+32,255,off,127,0,on,127,255,off,127-32,0,on,127+32,0,end
a74: .db 0,0,on,255,0,on,255,255,end
a75: .db 0,0,on,0,255,off,255,255,on,0,127,on,255,0,end
a76: .db 0,255,on,0,0,on,255,0,end
a77: .db 0,0,on,0,255,on,127,127,on,255,255,on,255,0,end
a78: .db 0,0,on,0,255,on,255,0,on,255,255,end
a79: .db 0,0,on,0,255,on,255,255,on,255,0,on,0,0,end
a80: .db 0,0,on,0,255,on,255,255,on,255,127,on,0,127,end
a81: .db 255,0,on,0,0,on,0,255,on,255,255,on,255,0,on,255-75,75,end
a82: .db 0,0,on,0,255,on,255,255,on,255,127,on,0,127,on,255,0,end
a83: .db 255,255,on,0,255,on,0,127,on,255,127,on,255,0,on,0,0,end
a84: .db 0,255,on,255,255,off,127,255,on,127,0,end
a85: .db 0,255,on,0,0,on,255,0,on,255,255,end
a86: .db 0,255,on,127,0,on,255,255,end
a87: .db 0,255,on,0,0,on,127,127,on,255,0,on,255,255,end
a88: .db 0,0,on,255,255,off,0,255,on,255,0,end
a89: .db 0,255,on,0,127,on,255,127,off,255,255,on,255,0,on,0,0,end
a90: .db 0,255,on,255,255,on,0,0,on,255,0,end
;symbols [,\,],^,_,'
a91: .db 127,0,on,0,0,on,0,255,on,127,255,end
a92: .db 0,255,on,255,0,end
a93: .db 127,255,on,255,255,on,255,0,on,127,0,end
a94: .db 127-64,255-64,on,127,255,on,127+64,255-64,end
a95: .db 0,0,on,255,0,end
a96: .db 127-30,255,on,127,255-30,end
;a to z
a97: .db 0,255-64,on,255,255-64,on,255,0,on,0,0,on,0,127,on,255,127,end
a98: .db 0,255,on,0,0,on,255,0,on,255,127,on,0,127,end
a99: .db 255,127+64,on,0,127+64,on,0,0,on,255,0,end
a100: .db 255,127,on,0,127,on,0,0,on,255,0,on,255,255,end
a101: .db 0,(127+64)/2,on,255,(127+64)/2,on,255,127+64,on,0,127+64,on,0,0,on,255,0,end
a102: .db 0,0,on,0,255-32,on,255,255-32,off,255,127,on,0,127,end
a103: .db 0,0,on,255,0,on,255,127+64,on,0,127+64,on,0,(127+64)/2,on,255,(127+64)/2,end
a104: .db 0,255,on,0,0,on,0,127,on,255,127,on,255,0,end
a105: .db 127,255,on,127,255-32,off,127,127,on,127,0,end
a106: .db 127,255,on,127,255-32,off,127,127,on,127,0,on,0,0,end
a107: .db 0,0,on,0,127+64,off,255,127+64,on,0,(127+64)/2,on,255,0,end
a108: .db 127,0,on,127,255,end
a109: .db 0,0,on,0,127+64,on,255,127+64,on,255,0,off,127,0,on,127,127+64,end
a110: .db 0,127+64,on,0,0,off,0,127+64,on,255,127+64,on,255,0,end
a111: .db 0,0,on,0,127+64,on,255,127+64,on,255,0,on,0,0,end
a112: .db 0,0,on,0,127+64,on,255,127+64,on,255,(127+64)/2,on,0,(127+64)/2,end
a113: .db 255,0,on,255,127+64,on,0,127+64,on,0,(127+64)/2,on,255,(127+64)/2,end
a114: .db 0,0,on,0,127+64,off,0,127,on,255,127+64,end
a115: .db 0,0,on,255,0,on,255,(127+64)/2,on,0,(127+64)/2,on,0,127+64,on,255,127+64,end
a116: .db 0,255-32,on,0,0,on,255,0,off,255,(255-32)/2,on,0,(255-32)/2,end
a117: .db 0,127+64,on,0,0,on,255,0,on,255,127+64,end
a118: .db 0,127+64,on,127,0,on,255,127+64,end
a119: .db 0,127+64,on,0,0,on,255,0,on,255,127+64,off,127,127+64,on,127,0,end
a120: .db 0,0,on,255,127+64,off,0,127+64,on,255,0,end
a121: .db 255,127+64,on,0,0,off,0,127+64,on,127,(127+64)/2,end
a122: .db 0,127+64,on,255,127+74,on,0,0,on,255,0,end
;symbols {,|,},~
a123: .db 0,0,end
a124: .db 0,0,end
a125: .db 0,0,end
a126: .db 0,0,end
a127: .db 0,0,end
;ASCII reference table
Char: .dw a32,a33,a34,a35,a36,a37,a38,a39,a40,a41
.dw a42,a43,a44,a45,a46,a47,a48,a49,a50,a51
.dw a52,a53,a54,a55,a56,a57,a58,a59,a60,a61
.dw a62,a63,a64,a65,a66,a67,a68,a69,a70,a71
.dw a72,a73,a74,a75,a76,a77,a78,a79,a80,a81
.dw a82,a83,a84,a85,a86,a87,a88,a89,a90,a91
.dw a92,a93,a94,a95,a96,a97,a98,a99,a100,a101
.dw a102,a103,a104,a105,a106,a107,a108,a109,a110,a111
.dw a112,a113,a114,a115,a116,a117,a118,a119,a120,a121
.dw a122,a123,a124,a125,a126,a127
;Test patterns
TP1: .db 0,0,on,0,255,on,255,255,on,255,0,on,0,0,end
TP2: .db 0,127,on,127,255,on,255,127,on,127,0,on,0,127,end
TP3: .db 127,0,on,127,255,off,0,127,on,255,127,off,0,0,on,0,255,on,255,255,on,255,0,on,0,0,end
TP4: .db 0,127,on,127,255,on,255,127,on,127,0,on,0,127,off,0,127,on,255,127,off,127,255,on,127,0,end
XYadj: .db 127,255,on,255,255,on,255,127,off,255,255,on,0,0,end
;Star
US: .db 0,0,on,255,160,on,0,160,on,255,0,on,127,255,on,0,0,end
;Square face
Face1: .db 0,0,on,0,255,on,255,255,on,255,0,on,0,0,off,(127-32),255-64,on,(127-32),255-64-32,off,127+64,255-64,on,127+64,255-64-32,off,64,64,on,255-64,64,end
;Flying bird
Bird0: .db 0,127,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127,end
Bird1: .db 0,127-16,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127-16,end
Bird2: .db 0,127-32,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127-32,end
Bird3: .db 0,127-32-16,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127-32-16,end
Bird10: .db 0,127+16,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127+16,end
Bird20: .db 0,127+32,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127+32,end
Bird30: .db 0,127+32+16,on,127-32,127,on,127,127-32,on,127+32,127,on,255,127+32+16,end
;Text constants
Headr: .db cr,lf," *** LASER-projector 2008 ***",CR,LF,LF,0
LCMsg: .db "LC<enter> for help",CR,LF,LF,0
CRLF: .db CR,LF,0
;---------------------------------------------------------------------------------
;commands CMD addr Syntax
;---------------------------------------------------------------------------------
CMDs: .db "TS" .dw TextSetUp ;TS <projsize 0-9> <width 0-9> <delay 0-9>
.db "TX" .dw Text ;TX <scroll text>
.db "TM" .dw Timing ;TM <T0 0-9> <Td 0-9>
.db "RE" .dw Reverse ;RE <X 0/1> <Y 0/1>
.db "XY" .dw adjXY
.db "AX" .dw AdjX
.db "AY" .dw AdjY
.db "S1" .dw XYsc
.db "S2" .dw YTsc
.db "D1" .dw Demo1
.db "T1" .dw Test1
.db "T2" .dw Test2
.db "T3" .dw Test3
.db "T4" .dw Test4
.db "LD" .dw LoadDefaults
.db "LS" .dw LoadSettings
.db "SS" .dw SaveSettings
.db "MS" .dw GetMode
.db "LC" .dw ListCommands
.equ nrCMD = (PC-CMDs) / 2 ;nrCMD := #CMD's
;---------------------------------------------------------------------------------
CommandList:
.db "Command-list:",Cr,LF,LF
.db "TS <size 0-9> <width 0-9> <delay 0-9> Text-Setup",Cr,Lf
.db "TX <Text max 240 char> ScrollText input",Cr,Lf
.db "TM <T0 0-9> <Td 0-9> Servo-timing",Cr,Lf
.db "RE <X 0/1> <Y 0/1> Reverse X Y 1=Yes",Cr,Lf
.db "XY Arrow to right-up",Cr,Lf
.db "AX Adjust X step",Cr,Lf
.db "AY Adjust Y step",Cr,Lf
.db "T1-T4 <proj.size> Testpattern 1-4",Cr,Lf
.db "D1 <proj.size> Demo1",Cr,Lf
.db "LD Load defaults",Cr,Lf
.db "LS Load (saved) settings",Cr,Lf
.db "SS Save (current) settings",Cr,Lf
.db "MS <mode 1-4> Mode-set 1=Scroll,2=Words,3=Yt,4=XYZ",Cr,Lf
.db "LC List commands (this screen)",Cr,Lf
.db Cr,Lf,"(Commands in capitals)",Cr,Lf
.db Lf,">",0xFF
;*********************************************************************
;*********************************************************************
; Reset
;*********************************************************************
Reset:
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
;init I/O
;Pull-up on Z input (of XYX)
sbi PortC,2
;Laser control
sbi DDRD,4
cbi PortD,4 ;laser off
;TXD output
sbi DDRD,1
;X DAC (Timer0 PWM, OC0B)
ldi r16,0b00100011 ;Fast PWM
out TCCR0A,r16
ldi r16,0b00000001 ;No prescaler
out TCCR0B,r16
;center X
ldi r16,127
out OCR0B,r16
;connect
sbi DDRD,5 ;OC0B = output
;Y DAC (Timer2 PWM, OC2B)
ldi r16,0b00100011 ;Fast PWM
sts TCCR2A,r16
ldi r16,0b00000001 ;No prescaler
sts TCCR2B,r16
;center X
ldi r16,127
sts OCR2B,r16
;connect
sbi DDRD,3 ;OC2B = output
;Timer1, int timer
ldi r16,0b00000000 ;normal operation
sts TCCR1A,r16
ldi r16,CTCrun ;CTC mode,presc=1
; ldi r16,CTChalt ;CTC mode,no clk
sts TCCR1B,r16
;compare match value (int-rate = 20E6 / value)
ldi r16,high(20000-1)
sts OCR1AH,r16
ldi r16,low(20000-1)
sts OCR1AL,r16
;enable compare-match-A interrupt
ldi r16,1<<OCIE1A
sts TIMSK1,r16
;enable the ADC
ldi r16,ADCpre | (1<<ADEN)
sts ADCSRA,r16
;USART setup
ldi r16,0b10011000 ;Rx int en, Rx en, Tx en
sts UCSR0B,r16
ldi r16,0b00001110 ;async,no par,8 bits,1 stb
sts UCSR0C,r16
;Baudrate
ldi r16,high(UBRR)
sts UBRR0H,r16
ldi r16,low(UBRR)
sts UBRR0L,r16
;Vdd rise delay
Vddr:
dec r16
brne Vddr
dec r17
brne Vddr
rjmp Main
;*********************************************************************
;*********************************************************************
; Interrupt: T1 compare-match-A (CTC mode)
;
; Usage: Timer 1mS
; r11:r10 = Time x 1 mS
;
;
;*********************************************************************
T1_COMPA:
;count down timer r11:r10
brts T100
dec r10
brne T100
tst r11
breq T101
dec r11
rjmp T100
T101:
set ;T-bit is time-out
;stop timer
push r16
ldi r16,CTChalt ;CTC mode,halt
sts TCCR1B,r16
pop r16
T100:
reti
;*********************************************************************
;*********************************************************************
; Rx complete interrupt (UART buffer contains a char to read)
;
;
;*********************************************************************
RxRdy:
push Xl
push Xh
push r16
lds Key,UDR0
mov r16,Key
;test for control chars
cpi r16,CR
breq rxr00
cpi r16,BS
breq rxr01
;handle data
mov r16,RxBufPtr
cpi r16,RxBufSize ;ignore if buffer full
brne rxr02
rjmp endRx
rxr02:
txbyte Key ;echo
ldi Xl,low(RxBuf)
ldi Xh,high(RxBuf)
add Xl,RxBufPtr
clr r16
adc Xh,r16
st X,Key
inc RxBufPtr
rjmp endRx
;Handle enter
rxr00:
ldi r16,CR
TxByte r16
ldi r16,LF
TxByte r16 ;send crlf
ldi r16,'>'
TxByte r16 ;send command prompt
rjmp endRx
;Handle backspace
rxr01:
tst RxBufPtr
breq endrx
dec RxBufPtr
ldi r16,BS
TxByte r16
ldi r16,' '
TxByte r16
ldi r16,BS
TxByte r16
endRx:
pop r16
pop Xh
pop Xl
reti
;*********************************************************************
;*********************************************************************
; Delay100uS
;
; delays r16 x 100uS
; uses r25
; affects r16
;*********************************************************************
Delay100uS:
ldi r25,200
Dl1m0:
nop
nop
nop
nop
nop
nop
nop
dec r25
brne Dl1m0
dec r16
brne Delay100uS
ret
;*********************************************************************
;*********************************************************************
; Draw
; Draws a pattern of lines
;
; entry: Z -> pattern
; pattern: .db x1,y1,laser,x2,y2,laser,....,xn,yn,end ;laser=on/off
;
; uses r2,r3,r21
;*********************************************************************
|