usbdux: usbduxsigma: fixed timing issues between ADC and DAC
When sync ADC and the DAC was running at the same time the ADC showed spikes in the signal. This happened when just before the DRDY from the ADC was triggered a DAC interrupt was dealt with. ADC and DAC share the same SPI bus and priority is now given the ADC. The DAC values are now first stored in a buffer and are only send to the DAC once the ADC has finished converting all channels (start = 0) so that the SPI bus is definitely quiet for about 100us. Signed-off-by: Bernd Porr <mail@berndporr.me.uk> Signed-off-by: Kyle McMartin <kyle@kernel.org>
This commit is contained in:
parent
09852eab3e
commit
75cc3ef8ba
|
@ -30,17 +30,20 @@
|
||||||
|
|
||||||
.inc fx2-include.asm
|
.inc fx2-include.asm
|
||||||
|
|
||||||
;;; a couple of flags
|
;;; a couple of flags in high memory
|
||||||
.equ CMD_FLAG,80h ; flag for the next in transfer
|
.equ CMD_FLAG,80h ; flag for the next in transfer
|
||||||
.equ PWMFLAG,81h ; PWM on or off?
|
.equ PWMFLAG,81h ; PWM on or off?
|
||||||
.equ MAXSMPL,82H ; maximum number of samples, n channellist
|
.equ MAXSMPL,82H ; maximum number of samples, n channellist
|
||||||
.equ MUXSG0,83H ; content of the MUXSG0 register
|
.equ MUXSG0,83H ; content of the MUXSG0 register
|
||||||
.equ SMPLCTR,84h
|
|
||||||
.equ DPTRL,85H
|
|
||||||
.equ DPTRH,86h
|
|
||||||
.equ ASYNC_ON,87h
|
|
||||||
.equ INTERVAL,88h ; uframe/frame interval
|
.equ INTERVAL,88h ; uframe/frame interval
|
||||||
.equ INTCTR,89h ; interval counter
|
.equ INTCTR,89h ; interval counter
|
||||||
|
.equ DABUFFER,0F0h ; buffer with DA values
|
||||||
|
|
||||||
|
;;; in precious low memory but accessible within one clock cycle
|
||||||
|
.equ DPTRL,70H
|
||||||
|
.equ DPTRH,71h
|
||||||
|
.equ ASYNC_ON,72h
|
||||||
|
.equ SMPLCTR,73h
|
||||||
|
|
||||||
;;; actual code
|
;;; actual code
|
||||||
.org 0000h ; after reset the processor starts here
|
.org 0000h ; after reset the processor starts here
|
||||||
|
@ -229,31 +232,24 @@ isr0:
|
||||||
push 06h ; R6
|
push 06h ; R6
|
||||||
push 07h ; R7
|
push 07h ; R7
|
||||||
|
|
||||||
mov r0,#ASYNC_ON
|
mov a,ASYNC_ON
|
||||||
mov a,@r0
|
|
||||||
jz noepsubmit
|
jz noepsubmit
|
||||||
|
|
||||||
mov DPS,#0
|
mov DPS,#0
|
||||||
mov r0,#DPTRL
|
mov dpl,DPTRL
|
||||||
mov dpl,@r0
|
mov dph,DPTRH
|
||||||
inc r0
|
|
||||||
mov dph,@r0
|
|
||||||
|
|
||||||
lcall readADCch ; read one channel
|
lcall readADCch ; read one channel
|
||||||
|
|
||||||
mov r0,#DPTRL
|
mov DPTRL,dpl
|
||||||
mov @r0,dpl
|
mov DPTRH,dph
|
||||||
inc r0
|
|
||||||
mov @r0,dph
|
|
||||||
|
|
||||||
mov r0,#SMPLCTR
|
mov a,SMPLCTR
|
||||||
mov a,@r0
|
|
||||||
dec a
|
dec a
|
||||||
mov @r0,a
|
mov SMPLCTR,a
|
||||||
jnz noepsubmit
|
jnz noepsubmit
|
||||||
|
|
||||||
mov r0,#ASYNC_ON
|
mov ASYNC_ON,#0
|
||||||
mov @r0,#0
|
|
||||||
|
|
||||||
clr IOA.7 ; START = 0
|
clr IOA.7 ; START = 0
|
||||||
|
|
||||||
|
@ -303,9 +299,6 @@ main:
|
||||||
mov a,#00000011b ; allows skip
|
mov a,#00000011b ; allows skip
|
||||||
lcall syncdelaywr
|
lcall syncdelaywr
|
||||||
|
|
||||||
mov IP,#0 ; all std 8051 int have low priority
|
|
||||||
mov EIP,#0FFH ; all FX2 interrupts have high priority
|
|
||||||
|
|
||||||
mov dptr,#INTSETUP ; IRQ setup register
|
mov dptr,#INTSETUP ; IRQ setup register
|
||||||
mov a,#08h ; enable autovector
|
mov a,#08h ; enable autovector
|
||||||
lcall syncdelaywr
|
lcall syncdelaywr
|
||||||
|
@ -314,6 +307,9 @@ main:
|
||||||
mov a,#0
|
mov a,#0
|
||||||
lcall syncdelaywr
|
lcall syncdelaywr
|
||||||
|
|
||||||
|
mov IP,#01H ; int0 has highest interrupt priority
|
||||||
|
mov EIP,#0 ; all USB interrupts have low priority
|
||||||
|
|
||||||
lcall initAD ; init the ports to the converters
|
lcall initAD ; init the ports to the converters
|
||||||
|
|
||||||
lcall initeps ; init the isochronous data-transfer
|
lcall initeps ; init the isochronous data-transfer
|
||||||
|
@ -341,8 +337,10 @@ initAD:
|
||||||
mov r0,#MAXSMPL ; length of channellist
|
mov r0,#MAXSMPL ; length of channellist
|
||||||
mov @r0,#0 ; we don't want to accumlate samples
|
mov @r0,#0 ; we don't want to accumlate samples
|
||||||
|
|
||||||
mov r0,#ASYNC_ON ; async enable
|
mov ASYNC_ON,#0 ; async enable
|
||||||
mov @r0,#0 ; we don't want to accumlate samples
|
|
||||||
|
mov r0,#DABUFFER
|
||||||
|
mov @r0,#0
|
||||||
|
|
||||||
mov OEA,#11100000b ; PortA7,A6,A5 Outputs
|
mov OEA,#11100000b ; PortA7,A6,A5 Outputs
|
||||||
mov IOA,#01100000b ; /CS = 1 and START = 0
|
mov IOA,#01100000b ; /CS = 1 and START = 0
|
||||||
|
@ -589,8 +587,6 @@ sof_isr:
|
||||||
push 06h ; R6
|
push 06h ; R6
|
||||||
push 07h ; R7
|
push 07h ; R7
|
||||||
|
|
||||||
clr IE.7 ; make sure that no other int's disturbe us
|
|
||||||
|
|
||||||
mov r0,#INTCTR ; interval counter
|
mov r0,#INTCTR ; interval counter
|
||||||
mov a,@r0 ; get the value
|
mov a,@r0 ; get the value
|
||||||
dec a ; decrement
|
dec a ; decrement
|
||||||
|
@ -631,18 +627,14 @@ sof_adc:
|
||||||
mov a,#0 ; just zero
|
mov a,#0 ; just zero
|
||||||
movx @dptr,a ; pad it up
|
movx @dptr,a ; pad it up
|
||||||
inc dptr ; algin along a 32 bit word
|
inc dptr ; algin along a 32 bit word
|
||||||
mov r0,#DPTRL
|
mov DPTRL,dpl
|
||||||
mov @r0,dpl
|
mov DPTRH,dph
|
||||||
inc r0
|
|
||||||
mov @r0,dph
|
|
||||||
|
|
||||||
mov r0,#MAXSMPL
|
mov r0,#MAXSMPL
|
||||||
mov a,@r0
|
mov a,@r0
|
||||||
mov r0,#SMPLCTR
|
mov SMPLCTR,a
|
||||||
mov @r0,a
|
|
||||||
|
|
||||||
mov r0,#ASYNC_ON
|
mov ASYNC_ON,#1
|
||||||
mov @r0,#1 ; enable data collection
|
|
||||||
|
|
||||||
epfull:
|
epfull:
|
||||||
;; do the D/A conversion
|
;; do the D/A conversion
|
||||||
|
@ -658,7 +650,13 @@ epfull:
|
||||||
lcall syncdelaywr ; wait for the rec to sync
|
lcall syncdelaywr ; wait for the rec to sync
|
||||||
lcall syncdelaywr ; wait for the rec to sync
|
lcall syncdelaywr ; wait for the rec to sync
|
||||||
|
|
||||||
epempty:
|
epempty:
|
||||||
|
mov a,IOA ; conversion running?
|
||||||
|
jb ACC.7,sofend
|
||||||
|
|
||||||
|
lcall DAsend
|
||||||
|
|
||||||
|
sofend:
|
||||||
;; clear INT2
|
;; clear INT2
|
||||||
mov a,EXIF ; FIRST clear the USB (INT2) interrupt request
|
mov a,EXIF ; FIRST clear the USB (INT2) interrupt request
|
||||||
clr acc.4
|
clr acc.4
|
||||||
|
@ -669,8 +667,6 @@ epempty:
|
||||||
movx @DPTR,a
|
movx @DPTR,a
|
||||||
|
|
||||||
nosof:
|
nosof:
|
||||||
setb IE.7 ; re-enable global interrupts
|
|
||||||
|
|
||||||
pop 07h
|
pop 07h
|
||||||
pop 06h
|
pop 06h
|
||||||
pop 05h
|
pop 05h
|
||||||
|
@ -795,8 +791,6 @@ ep1out_isr:
|
||||||
push 06h ; R6
|
push 06h ; R6
|
||||||
push 07h ; R7
|
push 07h ; R7
|
||||||
|
|
||||||
clr IE.7 ; block other interrupts
|
|
||||||
|
|
||||||
mov dptr,#0E780h ; FIFO buffer of EP1OUT
|
mov dptr,#0E780h ; FIFO buffer of EP1OUT
|
||||||
movx a,@dptr ; get the first byte
|
movx a,@dptr ; get the first byte
|
||||||
mov r0,#CMD_FLAG ; pointer to the command byte
|
mov r0,#CMD_FLAG ; pointer to the command byte
|
||||||
|
@ -831,8 +825,7 @@ pwm_off:
|
||||||
sjmp over_da
|
sjmp over_da
|
||||||
|
|
||||||
initsgADchannel:
|
initsgADchannel:
|
||||||
mov r0,#ASYNC_ON
|
mov ASYNC_ON,#0
|
||||||
mov @r0,#0 ; make sure that no async activity is on
|
|
||||||
|
|
||||||
mov dptr,#0e781h ; FIFO buffer of EP1OUT
|
mov dptr,#0e781h ; FIFO buffer of EP1OUT
|
||||||
lcall configADC ; configures the ADC esp sel the channel
|
lcall configADC ; configures the ADC esp sel the channel
|
||||||
|
@ -869,13 +862,11 @@ startadc2:
|
||||||
inc dptr
|
inc dptr
|
||||||
mov r0,#MAXSMPL
|
mov r0,#MAXSMPL
|
||||||
mov @r0,a ; length of the channel list
|
mov @r0,a ; length of the channel list
|
||||||
mov r0,#SMPLCTR
|
mov SMPLCTR,a
|
||||||
mov @r0,a
|
|
||||||
|
|
||||||
lcall configADC ; configures all registers
|
lcall configADC ; configures all registers
|
||||||
|
|
||||||
mov r0,#ASYNC_ON ; async enable
|
mov ASYNC_ON,#1 ; async enable
|
||||||
mov @r0,#1 ; enable it
|
|
||||||
|
|
||||||
lcall reset_ep6 ; reset FIFO
|
lcall reset_ep6 ; reset FIFO
|
||||||
|
|
||||||
|
@ -958,8 +949,6 @@ over_da:
|
||||||
mov a,#00001000b ; clear the ep1outirq
|
mov a,#00001000b ; clear the ep1outirq
|
||||||
movx @DPTR,a
|
movx @DPTR,a
|
||||||
|
|
||||||
setb IE.7 ; re-enable interrupts
|
|
||||||
|
|
||||||
pop 07h
|
pop 07h
|
||||||
pop 06h
|
pop 06h
|
||||||
pop 05h
|
pop 05h
|
||||||
|
@ -979,19 +968,45 @@ over_da:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; all channels
|
;;; save all DA channels from the endpoint buffer in a local buffer
|
||||||
dalo:
|
dalo:
|
||||||
movx a,@dptr ; number of bytes to send out
|
movx a,@dptr ; number of bytes to send out
|
||||||
inc dptr ; pointer to the first byte
|
inc dptr ; pointer to the first byte
|
||||||
|
mov r1,#DABUFFER ; buffer for DA values
|
||||||
|
mov @r1,a ; save it
|
||||||
|
inc r1 ; inc pointer to local buffer
|
||||||
mov r0,a ; counter
|
mov r0,a ; counter
|
||||||
nextDA:
|
nextDAlo:
|
||||||
movx a,@dptr ; get the byte
|
movx a,@dptr ; get the byte
|
||||||
inc dptr ; point to the high byte
|
inc dptr ; point to the high byte
|
||||||
mov r3,a ; store in r3 for writeDA
|
mov @r1,a ; save it in the buffer
|
||||||
|
inc r1
|
||||||
movx a,@dptr ; get the channel number
|
movx a,@dptr ; get the channel number
|
||||||
inc dptr ; get ready for the next channel
|
inc dptr ; get ready for the next channel
|
||||||
|
mov @r1,a ; save it
|
||||||
|
inc r1
|
||||||
|
djnz r0,nextDAlo ; next channel
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;;; write to the DA converter
|
||||||
|
DAsend:
|
||||||
|
mov r1,#DABUFFER ; buffer of the DA values
|
||||||
|
mov a,@r1 ; get the channel count
|
||||||
|
jz DAret ; nothing to do
|
||||||
|
inc r1 ; pointer to the first byte
|
||||||
|
mov r0,a ; counter
|
||||||
|
nextDA:
|
||||||
|
mov a,@r1 ; get the byte
|
||||||
|
inc r1 ; point to the high byte
|
||||||
|
mov r3,a ; store in r3 for writeDA
|
||||||
|
mov a,@r1 ; get the channel number
|
||||||
|
inc r1 ; get ready for the next channel
|
||||||
|
push 1 ; is modified in the subroutine
|
||||||
lcall writeDA ; write value to the DAC
|
lcall writeDA ; write value to the DAC
|
||||||
|
pop 1 ; get the pointer back
|
||||||
djnz r0,nextDA ; next channel
|
djnz r0,nextDA ; next channel
|
||||||
|
DAret:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -1014,7 +1029,7 @@ writeDA3:
|
||||||
rr a ; shift to the upper to the lower
|
rr a ; shift to the upper to the lower
|
||||||
djnz r1,writeDA3
|
djnz r1,writeDA3
|
||||||
orl a,r2 ; merge with the channel info
|
orl a,r2 ; merge with the channel info
|
||||||
clr IOA.6 ; /SYNC of the DA to 0
|
clr IOA.6 ; /SYNC (/CS) of the DA to 0
|
||||||
lcall sendSPI ; send it out to the SPI
|
lcall sendSPI ; send it out to the SPI
|
||||||
mov a,r3 ; get data again
|
mov a,r3 ; get data again
|
||||||
anl a,#00001111b ; get the lower nibble
|
anl a,#00001111b ; get the lower nibble
|
||||||
|
@ -1024,7 +1039,7 @@ writeDA4:
|
||||||
djnz r1,writeDA4
|
djnz r1,writeDA4
|
||||||
anl a,#11110000b ; make sure that's empty
|
anl a,#11110000b ; make sure that's empty
|
||||||
lcall sendSPI
|
lcall sendSPI
|
||||||
setb IOA.6 ; /SYNC of the DA to 1
|
setb IOA.6 ; /SYNC (/CS) of the DA to 1
|
||||||
noDA: ret
|
noDA: ret
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue