Commit dba12691 authored by Bernd Porr's avatar Bernd Porr Committed by Kyle McMartin
Browse files

usbdux: usbduxsigma: changed firmware from ADC polling to IRQ processing



In order to prepare the firmware to work with the EHCI driver the
ADC data acquisition is now done by triggering the acquisition with
a start of frame interrupt (SOF) and then the collection of the data
is done via "data ready" interrupts until all data has been received.
Once this has happend then the whole packet is dispatched and at the
next SOF the next packet is dispatched. If there are SOF interrupts
happening during the data acquisiton it is no longer interupted and
only send out the next ISO packet once it has comleted its job.
Also now the USBDUXSIGMA has now plenty of time to deal with other
interrupts between ADC data readouts so that for example the DIO
can now be handled much quicker.
Signed-off-by: default avatarBernd Porr <mail@berndporr.me.uk>
Signed-off-by: default avatarKyle McMartin <kyle@kernel.org>
parent 8be41326
; usbdux_firmware.asm ; usbdux_firmware.asm
; Copyright (C) 2010,2011,2015 Bernd Porr, mail@berndporr.me.uk ; Copyright (C) 2010,2011 Bernd Porr, Bernd.Porr@f2s.com
; For usbduxsigma.c 0.5+ ; For usbduxsigma.c 0.5+
; ;
; This program is free software; you can redistribute it and/or modify ; This program is free software; you can redistribute it and/or modify
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
; Firmware: usbduxsigma_firmware.asm for usbduxsigma.c ; Firmware: usbduxsigma_firmware.asm for usbduxsigma.c
; Description: University of Stirling USB DAQ & INCITE Technology Limited ; Description: University of Stirling USB DAQ & INCITE Technology Limited
; Devices: [ITL] USB-DUX-SIGMA (usbduxsigma.ko) ; Devices: [ITL] USB-DUX-SIGMA (usbduxsigma.ko)
; Author: Bernd Porr <mail@berndporr.me.uk> ; Author: Bernd Porr <Bernd.Porr@f2s.com>
; Updated: 25 Jun 2015 ; Updated: 24 Jul 2011
; Status: testing ; Status: testing
; ;
;;; ;;;
...@@ -35,14 +35,21 @@ ...@@ -35,14 +35,21 @@
.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
;;; actual code ;;; actual code
.org 0000h ; after reset the processor starts here .org 0000h ; after reset the processor starts here
ljmp main ; jump to the main loop ljmp main ; jump to the main loop
.org 0003h
ljmp isr0 ; external interrupt 0: /DRY
.org 0043h ; the IRQ2-vector .org 0043h ; the IRQ2-vector
ljmp jmptbl ; irq service-routine ljmp jmptbl ; irq service-routine
.org 0100h ; start of the jump table .org 0100h ; start of the jump table
jmptbl: ljmp sudav_isr jmptbl: ljmp sudav_isr
...@@ -160,6 +167,85 @@ ep4_isr: ...@@ -160,6 +167,85 @@ ep4_isr:
reti reti
;;; this is triggered when DRY goes low
isr0:
push dps
push dpl
push dph
push dpl1
push dph1
push acc
push psw
push 00h ; R0
push 01h ; R1
push 02h ; R2
push 03h ; R3
push 04h ; R4
push 05h ; R5
push 06h ; R6
push 07h ; R7
mov r0,#ASYNC_ON
mov a,@r0
jz noepsubmit
mov DPS,#0
mov r0,#DPTRL
mov dpl,@r0
inc r0
mov dph,@r0
lcall readADCch ; read one channel
mov r0,#DPTRL
mov @r0,dpl
inc r0
mov @r0,dph
mov r0,#SMPLCTR
mov a,@r0
dec a
mov @r0,a
jnz noepsubmit
mov r0,#ASYNC_ON
mov @r0,#0
clr IOA.7 ; START = 0
;; arm the endpoint and send off the data
mov DPTR,#EP6BCH ; byte count H
mov a,#0 ; is zero
lcall syncdelaywr ; wait until we can write again
mov r0,#MAXSMPL ; number of samples to transmit
mov a,@r0 ; get them
rl a ; a=a*2
rl a ; a=a*2
add a,#4 ; four bytes for DIO
mov DPTR,#EP6BCL ; byte count L
lcall syncdelaywr ; wait until we can write again
noepsubmit:
pop 07h
pop 06h
pop 05h
pop 04h ; R4
pop 03h ; R3
pop 02h ; R2
pop 01h ; R1
pop 00h ; R0
pop psw
pop acc
pop dph1
pop dpl1
pop dph
pop dpl
pop dps
reti
;;; main program ;;; main program
;;; basically only initialises the processor and ;;; basically only initialises the processor and
...@@ -211,6 +297,9 @@ initAD: ...@@ -211,6 +297,9 @@ 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 @r0,#0 ; we don't want to accumlate samples
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
mov dptr,#IFCONFIG ; switch on clock on IFCLK pin mov dptr,#IFCONFIG ; switch on clock on IFCLK pin
...@@ -379,6 +468,10 @@ initeps: ...@@ -379,6 +468,10 @@ initeps:
mov a,#11100000b ; BULK data from here to the host mov a,#11100000b ; BULK data from here to the host
movx @DPTR,a ; movx @DPTR,a ;
mov dptr,#PORTACFG
mov a,#1 ; interrupt on pin A0
lcall syncdelaywr
;; enable interrupts ;; enable interrupts
mov dptr,#EPIE ; interrupt enable mov dptr,#EPIE ; interrupt enable
mov a,#10001000b ; enable irq for ep1out,8 mov a,#10001000b ; enable irq for ep1out,8
...@@ -392,8 +485,10 @@ initeps: ...@@ -392,8 +485,10 @@ initeps:
mov a,#2 ; enables SOF (1ms/125us interrupt) mov a,#2 ; enables SOF (1ms/125us interrupt)
movx @DPTR,a ; movx @DPTR,a ;
setb TCON.0 ; make INT0 edge triggered, falling edge
mov EIE,#00000001b ; enable INT2/USBINT in the 8051's SFR mov EIE,#00000001b ; enable INT2/USBINT in the 8051's SFR
mov IE,#80h ; IE, enable all interrupts mov IE,#81h ; IE, enable all interrupts and INT0
ret ret
...@@ -401,10 +496,6 @@ initeps: ...@@ -401,10 +496,6 @@ initeps:
;;; Reads one ADC channel from the converter and stores ;;; Reads one ADC channel from the converter and stores
;;; the result at dptr ;;; the result at dptr
readADCch: readADCch:
;; we do polling: we wait until DATA READY is zero
mov a,IOA ; get /DRDY
jb ACC.0,readADCch ; wait until data ready (DRDY=0)
;; reading data is done by just dropping /CS and start reading and ;; reading data is done by just dropping /CS and start reading and
;; while keeping the IN signal to the ADC inactive ;; while keeping the IN signal to the ADC inactive
clr IOA.5 ; /cs to 0 clr IOA.5 ; /cs to 0
...@@ -460,7 +551,8 @@ sof_isr: ...@@ -460,7 +551,8 @@ sof_isr:
anl a,#20H ; full? anl a,#20H ; full?
jnz epfull ; EP6-buffer is full jnz epfull ; EP6-buffer is full
clr IOA.7 ; stop converter, START = 0 mov a,IOA ; conversion running?
jb ACC.7,epfull
;; make sure that we are starting with the first channel ;; make sure that we are starting with the first channel
mov r0,#MUXSG0 ; mov r0,#MUXSG0 ;
...@@ -471,8 +563,6 @@ sof_isr: ...@@ -471,8 +563,6 @@ sof_isr:
setb IOA.7 ; start converter, START = 1 setb IOA.7 ; start converter, START = 1
;; get the data from the ADC as fast as possible and transfer it
;; to the EP buffer
mov dptr,#0f800h ; EP6 buffer mov dptr,#0f800h ; EP6 buffer
mov a,IOD ; get DIO D mov a,IOD ; get DIO D
movx @dptr,a ; store it movx @dptr,a ; store it
...@@ -486,30 +576,18 @@ sof_isr: ...@@ -486,30 +576,18 @@ sof_isr:
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 @r0,dpl
inc r0
mov @r0,dph
mov r0,#MAXSMPL ; number of samples to transmit mov r0,#MAXSMPL
mov a,@r0 ; get them mov a,@r0
mov r1,a ; counter mov r0,#SMPLCTR
mov @r0,a
;; main loop, get all the data
eptrans:
lcall readADCch ; get one reading
djnz r1,eptrans ; do until we have all content transf'd
clr IOA.7 ; stop converter, START = 0 mov r0,#ASYNC_ON
mov @r0,#1 ; enable data collection
;; arm the endpoint and send off the data
mov DPTR,#EP6BCH ; byte count H
mov a,#0 ; is zero
lcall syncdelaywr ; wait until we can write again
mov r0,#MAXSMPL ; number of samples to transmit
mov a,@r0 ; get them
rl a ; a=a*2
rl a ; a=a*2
add a,#4 ; four bytes for DIO
mov DPTR,#EP6BCL ; byte count L
lcall syncdelaywr ; wait until we can write again
epfull: epfull:
;; do the D/A conversion ;; do the D/A conversion
...@@ -697,6 +775,9 @@ pwm_off: ...@@ -697,6 +775,9 @@ pwm_off:
sjmp over_da sjmp over_da
initsgADchannel: initsgADchannel:
mov r0,#ASYNC_ON
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
...@@ -719,9 +800,14 @@ startadc: ...@@ -719,9 +800,14 @@ startadc:
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 @r0,a
lcall configADC ; configures all registers lcall configADC ; configures all registers
mov r0,#ASYNC_ON ; async enable
mov @r0,#1 ; enable it
lcall reset_ep6 ; reset FIFO lcall reset_ep6 ; reset FIFO
;; load new A/D data into EP6 ;; load new A/D data into EP6
...@@ -915,8 +1001,12 @@ ep8_jmp: ...@@ -915,8 +1001,12 @@ ep8_jmp:
;; read one A/D channel ;; read one A/D channel
ep8_sglchannel: ep8_sglchannel:
mov DPTR,#0fc01h ; EP8 FIFO
setb IOA.7 ; start converter, START = 1 setb IOA.7 ; start converter, START = 1
;; we do polling: we wait until DATA READY is zero
sglchwait:
mov a,IOA ; get /DRDY
jb ACC.0,sglchwait ; wait until data ready (DRDY=0)
mov DPTR,#0fc01h ; EP8 FIFO
lcall readADCch ; get one reading lcall readADCch ; get one reading
clr IOA.7 ; stop the converter, START = 0 clr IOA.7 ; stop the converter, START = 0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment