where : ibrtses embedded
AVR ASM UART & Timer Interrupt
A sample application with UART and timer interrupt. Some parts of the
code may have been be removed. Note that macros are published on another page.
The main unit
; running from 4MHz Quarz
; I/O
;
; DDRA:=0x00
;
; PORTA,0 : nc
; PORTA,1 : nc
; PORTA,2 : nc
; PORTA,3 : nc
; PORTA,4 : nc
; PORTA,5 : nc
; PORTA,6 : nc
; PORTA,7 : nc
;
; DDRB :=0xFF
; PORTB:=0x10 = portb_idle
; static action
; PORTB,0 : unnamed (23)
; PORTB,1 : unnamed (22)
; PORTB,2 : unnamed (21)
; PORTB,3 : unnamed (20)
; PORTB,4 : LED on:=0, off:=1
; PORTB,5 : nc
; PORTB,6 : nc
; PORTB,7 : nc
;
; DDRC:=0xFF
;
; PORTC,0 : Bus,ALTERA lsb
; PORTC,1 : Bus,ALTERA
; PORTC,2 : Bus,ALTERA
; PORTC,3 : Bus,ALTERA
; PORTC,4 : Bus,ALTERA
; PORTC,5 : Bus,ALTERA
; PORTC,6 : Bus,ALTERA
; PORTC,7 : Bus,ALTERA msb
;
; DDRD:=0xBE ; output = 1, input = 0
;
; PORTD,0 : Rx
; PORTD,1 : Tx
; PORTD,2 : TxEnable enable:=1, disable:=0
; PORTD,3 : interlock conducting:=0, non conducting:=1;
; PORTD,4 : SelectEnable (38)
; PORTD,5 : WriteReg (37)
; PORTD,6 : freq_meas(36)
; PORTD,7 : nc
;
;
.nolist
.include "8535def.inc" ; includes '.device AT90S8535' directive
.list
.LISTMAC
;Assign the internal registers
; the lower half, no SBCI,SUBI,CPI,ORI,ANDI commands here
.def timer1loop =r1 ; timer
.def timer1save =r2 ;
.def timer1enable =r3 ; =1 enabled
.def rxlen =r4 ; counting in ISR
.def txlen =r5 ; counting in ISR
.def timer1loop2 =r6 ; timer
.def CRCLo =r7
.def CRCHi =r8
.def CData =r9
.def SRC =r10
.def DST =r11
.def Cmd =r12
.def bshadow =r13
.def myflags =r15
; the upper half, unrestricted access
.def temp =r16 ; temporay var except IRQ
.def U1 =r17
.def U2 =r18
.def U3 =r19
.def U4 =r20
.def U5 =r21
.def ErrorCode =r22
.def rxptr =r23 ; offset from buffer
.def txptr =r24 ; offset from buffer
.def comstate =r25
; r26 is the X
; r28 is the Y
; r30 is the Z
;ErrorCode : 0 = ok
;Set some constants
.equ BaudDiv =51 ; see below
.equ RxBufLen =40 ;#bytes for rx buffer
.equ TxBufLen =250 ;#bytes for tx buffer
.equ StackSize =0x60;
.equ LastRAM =0x25F ;fixed for this CPU
.equ Timer0Prescale =0x04 ; clk/256 =51.2us=19.53kHz
.equ Timer0Preset =0xff ; 1 tick to overflow
.equ Timer1Prescale =0x04 ; clk/256 =51.2us=19.53kHz
.equ Timer1Preset =0xff00 ; 1 tick to overflow
.equ SWVersion =0x01
.equ SWSubVersion =0x00
.equ CurrentConfigSize =16 ; size of configuration
.equ defaultID =0x04 ;
.equ defaultmode =0x10 ;
.equ MaxSamples =240 ;
.equ DefaultT27 =80000 ; 20ms 16777216
.equ defCaptureDiv =0x81 ; loaded into TCCR1B
.equ PortB_Idle =0xF3;
.equ HeaderCRCSize =8 ; used for tx, incl SYN
.equ settingbytes =21 ; for communication
.equ mathbytes =20 ; for communication
.equ measbytes =20 ; for communication
.equ StackTest =LastRAM-StackSize ; test this location
;
; baudrates @ 4MHz
; 1200 :207
; 2400 :103
; 4800 : 51
; 9600 : 25
;### Data segment ##########################
.DSEG
Dummy: .byte 1
; measure 8 values = measbytes bytes
ADC0: .byte 2
ADC1: .byte 2
ADC2: .byte 2
ADC3: .byte 2
ADC4: .byte 2
ADC5: .byte 2
ADC6: .byte 2
ADC7: .byte 2
LastCapture: .byte 2 ; actual capture value
CapCount: .byte 2 ; # captures
; settings : # settingbytes
BurstADC: .byte 1
BurstDepth: .byte 1
DigitalIn: .byte 1
DigitalOut: .byte 1
DAC: .byte 1
ServoT1: .byte 2 ; time Reg0,1
ServoT2: .byte 2 ; time Reg2,3
ServoT3: .byte 2 ; time Reg4,5
ServoT4: .byte 2 ; time Reg6,7
ServoT5: .byte 2 ; time Reg8,9
ServoT6: .byte 2 ; time Reg10,11
ServoT7: .byte 2 ; time Reg12,13
ServoT8: .byte 2 ; time Reg14,15
; math values : # mathbytes
; start EEPROM buffer
ConfigSize: .byte 1 ; size not including this
DeviceID: .byte 1
Mode: .byte 1
T27: .byte 4 ; loop time U11,U10,U9, blank
T15: .byte 2
SP1: .byte 1
SP2: .byte 1
SP3: .byte 1
SP4: .byte 1
Latch1: .byte 1
Latch2: .byte 1
LoopTimer: .byte 2 ; timer for report
; end EEPROM buffer
; buffers
dummy2: .byte 20
RxBuf: .byte RxBufLen
TxBuf: .byte TxBufLen
;Mode : behaviour of the ServoADC
;0x80
;0x40
;0x20 :=1 software pulse enable
;0x10 :=1 int trigger , =0 external trigger
;0x08
;0x04
;0x02
;0x01
.org Stacktest
reservestack: .byte StackSize ;
.ESEG ; little endian : low byte on low adress
.DB CurrentConfigSize,defaultID,defaultmode
.DW 0,0x0010,1,0x0101,0x0101,0,0
.ORG 0x40 ; device string <=31
.DB 14,'I','B','R','T',' ','X','X','X',' ','V','x','.','x','x'
.ORG 0x60 ; serial <=15 = yy mm number
.DB 8,'0','1','0','2','0','0','0','1'
.ORG 0x80 ; copyright msg <=31
.DB 22,'C','o','p','y','r','i','g','h','t',' ','I','B','R','T',' ','(','9','9',',','0','0',')'
.ORG 0xA0 ; reference <=31
.DB 22,'h','t','t','p',':','/','/','w','w','w','.','i','b','r','t','s','e','s','.','c','o','m'
.ORG 0xC0 ; userstring <=15
.DB 10,'u','s','e','r','s','t','r','i','n','g'
.ORG 0xE0
.CSEG
.org 0x00
; irq table
rjmp init_far ;reset
nop ;ext irq0
nop ;ext irq1
nop ;timer2 compare
nop ;timer2 overflow
rjmp Timer1Capture ;timer1 capture
nop ;timer1 compareA
nop ;timer1 compareB
rjmp Timer1Int ;timer1 overflow
nop ;timer0 overflow
nop ;SPI,STC
rjmp UART_RxInt ;uart rx
rjmp UARTTxInt ;uart tx empty
rjmp UARTendTx ;uart tx complete
nop ;adc
nop ;EEPROM
nop ;analog comp
.org 0x11
;##############################################################
.include "POINTER.ASM" ; pointer stuff
.include "MATH.ASM" ; math stuff
; stop timer
; LastCapture:= Capturecounter
; restart timer
; myflags or $01
; inc(capcount)
;
Timer1Capture:
push temp
in temp,SREG
push temp
;isr
ldi temp,0 ; stop timer1
out TCCR1B,temp
clr temp ; clear counter
out TCNT1H,temp
out TCNT1L,temp
pushY
SetYPtr LastCapture ; get capture
in temp,ICR1L
st Y+,temp
in temp,ICR1H
st Y,temp
ldi temp,defCaptureDiv ; restart timer1
out TCCR1B,temp
mov temp,myflags ; set lsb of myflags
ori temp,0x01
mov myflags,temp
SetYPtr CapCount ; inc capcount
ld temp,Y
inc temp
st Y+,temp
brne t1cend
ld temp,Y
inc temp
st Y,temp
t1cend:
; sbi PORTB,1
; cbi PORTB,1
popY
pop temp
out SREG,temp
pop temp
reti
; dec Timer1loop until zero
; then Timer1enable:=0
;
Timer1Int:
push temp
in temp,SREG
push temp
;isr
; reload
ldi temp,0xFF
out TCNT1H,temp
ldi temp,0x80 ;war 0x80
out TCNT1L,temp
; sbi PORTD,4
; cbi PORTD,4
; tst Timer1enable
; brne t1iend
mov temp,Timer1Loop
tst temp
breq t1if
dec temp
mov Timer1loop,temp
brne t1iend
t1if:
; andi ErrorCode,0xFB
ldi temp,0
mov Timer1Enable,temp
; cbi PORTD,2
;end
t1iend:
pop temp
out SREG,temp
pop temp
reti
;###########################################################
.include "CONFIG.ASM" ; EEPROM stuff
.include "8535ADC.ASM" ; ADC stuff
.MACRO SaveVar(VAR,SIZE)
push ZL
push ZH
push XL
push XH
push U1
push U2
ldi ZL,low(@0-ConfigSize)
ldi ZH,high(@0-ConfigSize)
ldi XL,low(@0)
ldi XH,high(@0)
ldi U1,@1
rcall MoveRTE
pop U2
pop U1
pop XH
pop XL
pop ZH
pop ZL
.ENDMACRO
.MACRO Ledon
mov temp,bshadow
andi temp,0xEF
mov bshadow,temp
out portb,temp
.ENDMACRO
.MACRO Ledoff
mov temp,bshadow
ori temp,0x10
mov bshadow,temp
out portb,temp
.ENDMACRO
.include "CRC.ASM" ; CRC calculation
.include "XXXX.ASM" ; Communication stuff
.include "Altera.asm" ; accessing the Altera
init_far: rjmp init
;.include "NSTECL.ASM" ; ControlLoop
moveETR_far: rjmp MoveEtr
;;wait 100us - 118us
Wait100:
push u1
push u2
ldi u1,2
w1: ldi u2,70
w2: dec u2
brne w2
dec u1
brne w1
pop u2
pop u1
ret
;.............................................
wait1s: push u1
push u2
push u3
ldi u3,100
wa1: ldi u2,200
wa2: ldi u1,70
wa3: dec u1
brne wa3
dec u2
brne wa2
dec u3
brne wa1
pop u3
pop u2
pop u1
ret
wait500ms:
push u1
push u2
push u3
ldi u3,50
wb1: ldi u2,200
wb2: ldi u1,70
wb3: dec u1
brne wb3
dec u2
brne wb2
dec u3
brne wb1
pop u3
pop u2
pop u1
ret
wait10ms:
push u1
push u2
push u3
ldi u3,2
wc1: ldi u2,100
wc2: ldi u1,70
wc3: dec u1
brne wc3
dec u2
brne wc2
dec u3
brne wc1
pop u3
pop u2
pop u1
ret
getmeasurements:
push U1
push u2
push u3
push u4
ldi U4,8
ldi u1,0
SetYPtr ADC0
gmloop:
rcall ADCChannel
st Y+,U3
st Y+,U2
inc u1
dec u4
brne gmloop
pop u4
pop u3
pop u2
pop u1
ret
;###############################################
; Main
;###############################################
init:
; init ports
clr temp
out porta,temp ;
ldi temp,PortB_Idle ;
; mov bshadow,temp
out PORTB,temp
clr temp
out portc,temp ;
ldi temp,0x08 ; open interlock
out portd,temp ;
clr temp
out DDRA,temp
ldi temp,0xFF
out DDRB,temp
ldi temp,0xFF
out DDRC,temp ; port C is output
ldi temp, 0xBE ; out:=1, in:=0
out DDRD,temp
;init stack to top of internal SRAM
ldi Temp,high(LastRAM) ; set SP
out SPH,Temp
ldi Temp,low(LastRAM)
out SPL,Temp
;init internal UART to PC
ldi temp,BaudDiv ; baud =???
out UBRR,temp
ldi temp,0x98 ; rx&tx=0x18, rx only=0x10
out UCR,temp
; clear RAM NEW !!!!
; SetZPtr Dummy
; ldi U1,0
; ldi U2,0xFF
;cv: st Z+,U1
; dec U2
; brne cv
;init vars
; set config size
ldi temp,CurrentConfigSize
setYPtr ConfigSize
st Y,temp
; set ID
ldi temp,defaultID
SetYPtr DeviceID
st Y,temp
; set mode
ldi temp,defaultmode
SetYPtr Mode
st Y,temp
; set T27
ldi temp,0
SetYPtr T27
st Y+,temp
ldi temp,0
st Y+,temp
ldi temp,0x10 ; =1e6
st Y+,temp
ldi temp,0
st Y,temp
; set T15
ldi temp,1
SetYPtr T15
st Y+,temp
ldi temp,0
st Y+,temp
; set sp1
ldi temp,2
SetYPtr SP1
st Y,temp
; set sp2
ldi temp,1
SetYPtr SP2
st Y,temp
; set sp3
ldi temp,5
SetYPtr SP3
st Y,temp
; set sp4
ldi temp,3
SetYPtr SP4
st Y,temp
; set latch1
ldi temp,0
SetYPtr Latch1
st Y,temp
; set latch2
ldi temp,0
SetYPtr Latch2
st Y,temp
; set math values
; set Settings values
SetYPtr BurstADC
ldi temp,0
st Y,temp
SetYPtr BurstDepth
ldi temp,MaxSamples
st Y,temp
SetYPtr DigitalIn
ldi temp,0
st Y,temp
SetYPtr DigitalOut
ldi temp,0
st Y,temp
SetYPtr DAC
ldi temp,0
st Y,temp
; get config
ldi ZL,0x0
ldi ZH,0x0
SetXPtr ConfigSize
ld U1,X
inc u1
rcall MoveETR_far
; disable Software_Pulse_Enable
SetYPtr Mode
ld u1,Y
andi u1,0xDF
st Y,u1
ldi temp,1
mov Timer1Loop,temp
clr temp
mov Timer1Enable,temp
; new setup
; timer1 runs on 4MHz with div1, allowing 0..16ms, or 60Hz
; timer1 ; for capture
ldi temp,0x00
out TCNT1H,temp ; clear counter
ldi temp,0x00
out TCNT1L,temp
ldi temp,0 ;no compare, no pwm
out TCCR1A,temp
ldi temp,defCaptureDiv ; 0x01
out TCCR1B,temp ;clk = clk
; ldi temp,0x24 ; enable capture & overflow
; out TIMSK,temp
; SEI
; timer1 ; @4MHz, clk/1024 :58593.75 clocks give 15s
; ldi temp,0
; out TCCR1A,temp
; ldi temp,0x05
; out TCCR1B,temp ;clk div 1024
; ldi temp,0xFF
; out TCNT1H,temp
; ldi temp,0x80
; out TCNT1L,temp
; ldi temp,0x04
; out TIMSK,temp
; SEI
; timer0
ldi temp,0 ;0:=65ms
out TCNT0,temp
ldi temp,0x05
out TCCR0,temp
; also added
ldi temp,0x24 ;0x25; enable capture & overflow
out TIMSK,temp
; SEI
ldi u1,0
clr comstate
rcall SetupRx
SEI ; interrupts from here
tst0:
rcall Wait1s
rcall Wait1s
; rjmp tst0
rcall load27bit
rcall load15bit
rcall loadSP1
rcall loadSP2
rcall loadSP3
rcall loadSP4
rcall loadLatch1
rcall loadLatch2
main:
Ledon
rcall wait10ms
rcall comloop
; snip functionality
; sbi PORTD,2 ;debug pulse
; cbi PORTD,2
Ledoff
rjmp main
the communication
; new Vx.xx : msg 0x23 - load FPGA from Memory
;
;
; single xxx communication unit
; with added CRC, and SRC & DST ID
;
; protocol :
;
; index 0 1 2 3 4 5
; [SYN] STX LEN SRC DST MSG [DATA] CRChi CRClo
; 0x16 0x02 .. .. ..
;
; LEN = lenght including STX ... CRCHi
;
; CRC:=crc(STX..data);
; CRC poly:=
;
; rx : COMState
; state 0 := wait for STX
; state 1 := get len
; state 2 := count down
; state F := got message
;
.EQU STX =0x02
.EQU SYN =0x16
; prepares for receiving
SetupRx:
ldi comstate,0
ldi rxptr,0
ret
; rx interrupt : one message only, up to rxbuflen bytes
; does NOT overwrite bytes
; if message complete of max bytes ->comstate:=0x0F
UART_RxInt:
push temp
in temp,SREG
push temp
push U1
pushZ
; isr
in U1,UDR
; out UDR,U1 ;echo
cpi rxptr,RxBufLen ; test buffer full
breq uriterm
mov temp,comstate ; rxstate
andi temp,0x0F
tst temp
brne uri1
; state 0 - wait for STX
cpi u1,STX
breq uri0
cpi u1,SYN
brne urie
; SYN came
ldi rxptr,0
rjmp urie
uri0:
ldi comstate,1
SetZPtr RxBuf
st z,u1
inc rxptr
rjmp urie
uri1:
mov temp,comstate
cpi temp,0x01
brne uri2
; state 1
mov rxlen,u1
ldi comstate,2
SetZPtr RxBuf
add zl,rxptr
clr temp
adc zh,temp
st z,u1
inc rxptr
rjmp urie
uri2:
mov temp,comstate
cpi temp,0x02
brne urie
SetZPtr RxBuf
add zl,rxptr
clr temp
adc zh,temp
st z,u1
inc rxptr
cp rxptr,rxlen
brne urie
uriterm:
ori comstate,0x0F
urie:
; return
popZ
pop U1
pop temp
out SREG,temp
pop temp
reti
;prepare for tx
; assumes txlen is set and buffer filled
; txlen = nr of bytes
SetupTx:
clr txptr
sbi PORTD,2 ; enable Tx
sbi UCR,UDRIE
ret
;immediately return rxbuffer
Ping:
pushY
pushZ
push temp
push u1
SetZPtr RxBuf
SetYPtr TxBuf
mov temp,rxptr
ping1: ld u1,Z+
st Y+,u1
dec temp
brne ping1
mov txlen,rxptr
rcall SetupTx
pop u1
pop temp
popZ
popY
ret
;tx interrupt, requires setup of buffers
; started with SetupTx
UARTTxInt:
push temp
in temp,SREG
push temp
push U1
pushZ
; isr
cp txptr,txlen ; terminate on ptr=len
breq utit
SetZPtr TxBuf
add zl,txptr
clr temp
adc zh,temp
ld u1,Z
out UDR,u1
inc txptr
rjmp utie
utit: ; terminate
cbi UCR,UDRIE ; disable TxShiftEmpty IRQ
sbi UCR,TXCIE ; enable TxRegEmpty IRQ
; cbi PORTD,2
utie:
; return
popZ
pop U1
pop temp
out SREG,temp
pop temp
reti
; end of Tx - clear TxEnable=PORTD,2
UARTendTx:
push temp
in temp,SREG
push temp
cbi PORTD,2
cbi UCR,TXCIE ; disable IRQ
sbi USR,TXC
pop temp
out SREG,temp
pop temp
reti
; SYN STX LEN SRC DST Cmd
SetupTxFrame: ; txlen is set = #bytes to tx, incl SYN
push u2
SetZPtr TxBuf
ldi U2,SYN
st Z+,U2
ldi u2,STX
st Z+,u2
mov u2,txlen
dec u2
st Z+,u2
st Z+,DST ;reverse
st Z+,SRC ;reverse
st Z+,cmd
pop u2
ret
CopyBuf: ; X^ to Z^, U2 bytes
push U1
cb1: ld U1,X+
st Z+,U1
dec u2
tst u2
brne cb1
pop U1
ret
CopyRxTx: ; copies Rx to Tx
push U1
push U2
pushY
pushZ
SetYPtr RxBuf
SetZPtr TxBuf
ldd U1,Y+1
inc U1 ; one longer for SYN
mov TxLen,U1
dec U1
ldi U2,SYN
st Z+,U2
ldi u2,STX
st Z+,U2
st Z+,U1 ; TxLen-1 (SYN)
st Z+,DST ; reverse
st Z+,SRC ; reverse
st Z+,Cmd
subi u1,7 ; without header & crc
SetYPtr RxBuf
ldi temp,5
add YL,temp
clr temp
adc YH,temp
crt:
tst u1
breq crte
ld u2,Y+
st Z+,u2
dec u1
rjmp crt
crte:
popZ
popY
pop U2
pop U1
ret
AddCRC: ; appends CRC,
; assumes msg ready, incl. TxLen
push u1
SetZPtr TxBuf
ld temp,Z+ ; skip SYN
mov u1,txlen
subi u1,3 ; not over SYN, CRC
rcall CRCMessage
SetZPtr TxBuf
mov u1,txlen
subi u1,2
add ZL,u1
ldi temp,0
adc ZH,temp
st Z+,CRCHi
st Z,CRCLo
pop u1
ret
; protocol
;
;msg :
; 0x00 : echo
; 0x01 : read measurements
; 0x02 : read config
; 0x03 : read settings
; 0x04 :
; 0x05 :
; 0x06 :
;
; 0x10 : set Div27
; 0x11 : Set Div15
; 0x12 : Set SP1
; 0x13 : //ErrorCode
; 0x14 : set DAC
; 0x15 : set SP2
; 0x16 : set SP3
; 0x17 : set SP4
; 0x18 : set Latch1
; 0x19 : set Latch2
;
; 0x20 : DeviceID (write)
; 0x21 : Mode (write)
; 0x22 : Saveall (reg to EEProm)
; 0x23 : load FPGA from Memory (new V2.1a)
; 0x24 : load Userparameter1 (newV2.5)
; 0x30 : userstring (write)
;
; 0x40 : devicestring (read)
; 0x41 : serial (read)
; 0x42 : copyright (read)
; 0x43 : reference (read)
; 0x44 : userstring (read)
;
comloop: ; master-slave
; ldi temp,0x00 ;debug
; out UDR,temp
cpi comstate,0x0F
brne clend_1
; message received - rxptr = len = 1 byte after last
; calc crc
SetZPtr RxBuf
mov u1,rxptr
subi u1,2 ; exclude CRC itself
rcall CRCMessage
mov u2,rxptr
subi u2,2 ; exclude CRC itself
SetZPtr RxBuf
add ZL,u2
clr temp
adc ZH,temp
ld u1,Z+ ;crchi
ld u2,Z ;crclo
; rjmp dskip ;*****
cp crclo,u2
brne clend_2 ; fail - discard
cp crchi,u1
brne clend_2 ; fail - discard
; test DST ID
dskip: ;*****
SetZPtr RxBuf ; DST at Rxbuf+3
ldd u1,Z+3
ldd u2,Z+4 ; cmd at RxBuf+4
SetZPtr DeviceID
ld u3,Z
cp u1,u3
breq cl0 ; match
; not equal - pass only 'change ID'=0x20 at DST=0xFF
cpi u1,0xff
brne clend_2
cpi u2,0x20
brne clend_2
rjmp cl0
clend_2:
; rcall ping
; ldi temp,1
; mov DST,temp
; ldi temp,0
; mov SRC,temp
; ldi temp,0
; mov cmd,temp
; ldi temp,10
; mov txlen,temp
; rcall SetupTxFrame
; st Z+,crchi
; st Z+,crclo
; rcall AddCRC
; rcall SetupTx
; rcall SetupRx
rjmp clnone
; test msg
cl0:
SetZPtr RxBuf
ldd U1,Z+2 ; copy SRC
mov SRC,U1
ldd U1,Z+3 ; copy DST
mov DST,U1
ldd U1,Z+4 ; get cmd
mov Cmd,u1
cpi U1,0x00
brne cl1
; msg 0x00 - Echo
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
clend_1:
rjmp clend
cl1:
cpi U1,0x01
brne cl2
; msg 0x01 - measurements
ldi temp,measbytes+8
mov txlen,temp
rcall SetupTxFrame
SetXPtr ADC0
ldi U2,measbytes ;20 bytes data
rcall Copybuf
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl2:
cpi U1,0x02
brne cl3
; msg 0x02 - config
ldi temp,CurrentConfigSize+9 ; adjustable
mov txlen,temp
rcall SetupTxFrame
SetXPtr Configsize
ldi U2,CurrentConfigSize ;# bytes data
inc U2 ; include configsize byte
rcall Copybuf
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl3:
cpi U1,0x03
brne cl4
; msg 0x03 - settings
ldi temp,settingbytes+8
mov txlen,temp
rcall SetupTxFrame
SetXPtr BurstADC
ldi U2,settingbytes ;# bytes data
rcall Copybuf
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl4:
cpi U1,0x04
brne cl5
; msg 0x04
rjmp clend
cl5:
cpi U1,0x05
brne cl6
; msg 0x05
rjmp clend
cl6:
cpi U1,0x06
brne cl7
; msg 0x06
rjmp clend
cl7:
cl10:
cpi U1,0x10
brne cl11
; msg 0x10 - set Div27 *************
SetYPtr T27
ldd temp,Z+5
st Y+,temp
ldd temp,Z+6
st Y+,temp
ldd temp,Z+7
st Y+,temp
ldd temp,Z+8
st Y,temp
rcall load27bit
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl11:
cpi U1,0x11
brne cl12
; msg 0x11 - set Div15 ************
SetYPtr T15
ldd temp,Z+5
st Y+,temp
ldd temp,Z+6
st Y,temp
rcall load15bit
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl12:
cpi U1,0x12
brne cl13
; msg 0x12 - set SP1 **************
SetYPtr SP1
ldd temp,Z+5
st Y+,temp
rcall loadsp1
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl13:
cl14:
cpi U1,0x14
brne cl15
; msg 0x14 - set DAC
; ldd temp,Z+5
; SetYPtr DAC
; st Y,temp
; rcall SetDAC
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl15:
cpi U1,0x15
brne cl16
; msg 0x15 - set SP2 **************
SetYPtr SP2
ldd temp,Z+5
st Y+,temp
rcall loadsp2
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl16:
cpi U1,0x16
brne cl17
; msg 0x16 - set SP3 **************
SetYPtr SP3
ldd temp,Z+5
st Y+,temp
rcall loadsp3
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl17:
cpi U1,0x17
brne cl18
; msg 0x17 - set SP4 ***************
SetYPtr SP4
ldd temp,Z+5
st Y+,temp
rcall loadsp4
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl18:
cpi U1,0x18
brne cl19
; msg 0x18 - set Latch1 ************
SetYPtr Latch1
ldd temp,Z+5
st Y+,temp
rcall loadlatch1
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl19:
cpi U1,0x19
brne cl1A
; msg 0x19 - set Latch2 **********
SetYPtr Latch2
ldd temp,Z+5
st Y+,temp
rcall loadlatch2
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl1a:
cpi U1,0x1a
brne cl1b
;msg 0x1a - set pulseblock
SetYPtr SP1
ldd temp,Z+5 ;sp1
st Y+,temp
ldd temp,Z+6 ;sp2
st Y+,temp
ldd temp,Z+7 ;sp3
st Y+,temp
ldd temp,Z+8 ;sp4
st Y+,temp
ldd temp,Z+9 ;latch1
st Y+,temp
ldd temp,Z+10 ;latch2
st Y,temp
rcall loadpulseblock
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl1b:
cl20:
cpi U1,0x20
brne cl21
; msg 0x20 - deviceID
ldd temp,Z+5
SetYPtr DeviceID
st Y,temp
SaveVar DeviceID,1
rcall CopyRxTx
SetZPtr TxBuf
ld temp,Y ;set new ID
std Z+3,temp
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl21:
cpi U1,0x21
brne cl22
; msg 0x21 - Mode
ldd temp,Z+5
SetYPtr Mode
st Y,temp
; SaveVar Mode,1
rcall setmode
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl22:
cpi U1,0x22
brne cl23
; msg 0x22 - Save All
SaveVar Mode,15
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl23:
cpi U1,0x23
brne cl24
; msg 0x23 - load FPGA from Memory (new V2.1a)
rcall load27bit
rcall load15bit
rcall loadsp1
rcall loadsp2
rcall loadsp3
rcall loadsp4
rcall loadlatch1
rcall loadlatch2
rcall loadUserPara1
; that was it
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl24:
cpi U1,0x24
brne cl25
; msg 0x24 - set UserPara1 (new V2.5)
SetYPtr UserPara1
ldd temp,Z+5
st Y+,temp
SaveVar UserPara1,1 ;(yes, save this parameter)
rcall loadUserPara1
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl25:
cl30:
cpi U1,0x30
brne cl31
; msg 0x30 - write userstring
ldd temp,Z+5 ; get length of string
cpi temp,28
brsh cl30s ;skip if longer than 27
ldi ZL,0xC0
ldi ZH,0
SetXPtr RxBuf
ldi u1,5
add xl,u1
ldi u1,0
adc xh,u1
inc temp ; include length byte
mov u1,temp
rcall MoveRTE
cl30s:
rcall CopyRxTx
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl31:
cl40: cpi U1,0x40
brne cl41
; msg 0x40 - devicestring
ldi ZL,0x40
ldi ZH,0
SetXPtr TxBuf
ldi temp,6 ; move string to [6]
add XL,temp
ldi temp,0
adc XH,temp
rcall EStr2RAM
SetZPtr TxBuf
ldd temp,Z+6 ; get length
subi temp,-9
mov txlen,temp
rcall SetupTxFrame
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl41:
cpi u1,0x41
brne cl42
; msg 0x41 - serial
ldi ZL,0x60
ldi ZH,0
SetXPtr TxBuf
ldi temp,6 ; move string to [6]
add XL,temp
ldi temp,0
adc XH,temp
rcall EStr2RAM
SetZPtr TxBuf
ldd temp,Z+6
subi temp,-9
mov txlen,temp
rcall SetupTxFrame
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl42: cpi u1,0x42
brne cl43
; msg 0x42 - copyright
ldi ZL,0x80
ldi ZH,0
SetXPtr TxBuf
ldi temp,6 ; move string to [6]
add XL,temp
ldi temp,0
adc XH,temp
rcall EStr2RAM
SetZPtr TxBuf
ldd temp,Z+6
subi temp,-9
mov txlen,temp
rcall SetupTxFrame
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl43:
cpi u1,0x43
brne cl44
; msg 0x43 - reference
ldi ZL,0xA0
ldi ZH,0
SetXPtr TxBuf
ldi temp,6 ; move string to [6]
add XL,temp
ldi temp,0
adc XH,temp
rcall EStr2RAM
SetZPtr TxBuf
ldd temp,Z+6
subi temp,-9
mov txlen,temp
rcall SetupTxFrame
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl44:
cpi U1,0x44
brne cl45
; msg 0x44 - read userstring
ldi ZL,0xC0
ldi ZH,0
SetXPtr TxBuf
ldi temp,6 ; move string to [6]
add XL,temp
ldi temp,0
adc XH,temp
rcall EStr2RAM
SetZPtr TxBuf
ldd temp,Z+6
subi temp,-9
mov txlen,temp
rcall SetupTxFrame
rcall AddCRC
rcall SetupTx
rcall SetupRx
rjmp clend
cl45:
clnone:
rcall setupRx
clend:
ret
the crc
; this unit calculates the crc over a message or a byte
;
;.........................................................
;PROCEDURE calcCRC(data:BYTE;VAR crc:WORD);
;VAR i:BYTE;
;BEGIN
; FOR i:=0 TO 7 DO
; BEGIN
; IF ((data and $01)XOR(crc AND $0001)<>0) THEN
; BEGIN
; crc:=crc shr 1;
; crc:= crc XOR $A001;
; END
; ELSE crc:=crc shr 1;
; data:=data shr 1;
; END;
;END;
CRCByte: ; calculates the CRC over the byte CData and
; updates the CRC
push U1
push U2
push U3
ldi U3,8 ; 8 times
_clp:
mov U1,CData ; CData AND 0x01
andi U1,0x01
mov U2,CRCLo ; CRCLo AND 0x01
andi U2,0x01
eor U2,U1 ; (CData AND 0x01)XOR(CRCLo AND 0x01)
brne _cne
; =0
clc ; clear carry
ror CRCHi ; shift high
ror CRCLo ; shift lo
rjmp _cn
_cne: ;<>0
clc ; clear carry
ror CRCHi ; shift high
ror CRCLo ; shift lo
ldi U1,0xA0 ; CRC:=CRC xor 0xA001
eor CRCHi,U1
ldi U1,0x01
eor CRCLo,U1
_cn: lsr CData ;data:=data shr 1
dec U3
brne _clp ; loop 8 times
pop U3
pop U2
pop U1
ret
;
;note : the crc is initialized as zero (0)
; the crc is calculated over the message without SYN STX
;
;
;stack : 3 push/pop + ret = 5bytes
;..................................................................
;The message is pointed to by Z, the length is in U1
;
;after the op,
; the crc is in CRCLo&CRCHi
; Z points to the next location
;
CRCMessage:
clr CRCLo
clr CRCHi
_crc1: ld Temp,Z+
mov CData,Temp
rcall CRCByte
dec U1
brne _crc1
ret
;
;stack : ret+subcall = 7bytes
;...................................................................
Questions ?
Suggestions?
Feedback ?
sponsored links
AVR index
embedded software pages
home
last updated: 17.feb.07
Copyright (99,2007) Ing.Büro R.Tschaggelar