summaryrefslogtreecommitdiff
path: root/usbdux
diff options
context:
space:
mode:
authorBernd Porr <mail@berndporr.me.uk>2015-07-22 09:26:32 +0100
committerKyle McMartin <kyle@kernel.org>2015-07-22 13:40:19 -0400
commitdba12691ae605787b2bad5e5b0f00ac4c8da3f12 (patch)
tree527a8a88c94541e4f74854816d0b96e6750e9eff /usbdux
parent8be41326ad8e0ba3179d3ef44f873152c42c9613 (diff)
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: Bernd Porr <mail@berndporr.me.uk> Signed-off-by: Kyle McMartin <kyle@kernel.org>
Diffstat (limited to 'usbdux')
-rw-r--r--usbdux/usbduxsigma_firmware.asm160
1 files changed, 125 insertions, 35 deletions
diff --git a/usbdux/usbduxsigma_firmware.asm b/usbdux/usbduxsigma_firmware.asm
index e3639919..a8094f20 100644
--- a/usbdux/usbduxsigma_firmware.asm
+++ b/usbdux/usbduxsigma_firmware.asm
@@ -1,5 +1,5 @@
; 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+
;
; This program is free software; you can redistribute it and/or modify
@@ -20,8 +20,8 @@
; Firmware: usbduxsigma_firmware.asm for usbduxsigma.c
; Description: University of Stirling USB DAQ & INCITE Technology Limited
; Devices: [ITL] USB-DUX-SIGMA (usbduxsigma.ko)
-; Author: Bernd Porr <mail@berndporr.me.uk>
-; Updated: 25 Jun 2015
+; Author: Bernd Porr <Bernd.Porr@f2s.com>
+; Updated: 24 Jul 2011
; Status: testing
;
;;;
@@ -35,14 +35,21 @@
.equ PWMFLAG,81h ; PWM on or off?
.equ MAXSMPL,82H ; maximum number of samples, n channellist
.equ MUXSG0,83H ; content of the MUXSG0 register
+ .equ SMPLCTR,84h
+ .equ DPTRL,85H
+ .equ DPTRH,86h
+ .equ ASYNC_ON,87h
;;; actual code
.org 0000h ; after reset the processor starts here
ljmp main ; jump to the main loop
+ .org 0003h
+ ljmp isr0 ; external interrupt 0: /DRY
+
.org 0043h ; the IRQ2-vector
ljmp jmptbl ; irq service-routine
-
+
.org 0100h ; start of the jump table
jmptbl: ljmp sudav_isr
@@ -160,6 +167,85 @@ ep4_isr:
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
;;; basically only initialises the processor and
@@ -211,6 +297,9 @@ initAD:
mov r0,#MAXSMPL ; length of channellist
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 IOA,#01100000b ; /CS = 1 and START = 0
mov dptr,#IFCONFIG ; switch on clock on IFCLK pin
@@ -379,6 +468,10 @@ initeps:
mov a,#11100000b ; BULK data from here to the host
movx @DPTR,a ;
+ mov dptr,#PORTACFG
+ mov a,#1 ; interrupt on pin A0
+ lcall syncdelaywr
+
;; enable interrupts
mov dptr,#EPIE ; interrupt enable
mov a,#10001000b ; enable irq for ep1out,8
@@ -392,8 +485,10 @@ initeps:
mov a,#2 ; enables SOF (1ms/125us interrupt)
movx @DPTR,a ;
+ setb TCON.0 ; make INT0 edge triggered, falling edge
+
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
@@ -401,10 +496,6 @@ initeps:
;;; Reads one ADC channel from the converter and stores
;;; the result at dptr
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
;; while keeping the IN signal to the ADC inactive
clr IOA.5 ; /cs to 0
@@ -460,7 +551,8 @@ sof_isr:
anl a,#20H ; 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
mov r0,#MUXSG0 ;
@@ -471,8 +563,6 @@ sof_isr:
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 a,IOD ; get DIO D
movx @dptr,a ; store it
@@ -486,30 +576,18 @@ sof_isr:
mov a,#0 ; just zero
movx @dptr,a ; pad it up
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 a,@r0 ; get them
- mov r1,a ; counter
-
- ;; main loop, get all the data
-eptrans:
- lcall readADCch ; get one reading
- djnz r1,eptrans ; do until we have all content transf'd
+ mov r0,#MAXSMPL
+ mov a,@r0
+ mov r0,#SMPLCTR
+ mov @r0,a
- clr IOA.7 ; stop converter, 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
+ mov r0,#ASYNC_ON
+ mov @r0,#1 ; enable data collection
epfull:
;; do the D/A conversion
@@ -697,6 +775,9 @@ pwm_off:
sjmp over_da
initsgADchannel:
+ mov r0,#ASYNC_ON
+ mov @r0,#0 ; make sure that no async activity is on
+
mov dptr,#0e781h ; FIFO buffer of EP1OUT
lcall configADC ; configures the ADC esp sel the channel
@@ -719,9 +800,14 @@ startadc:
inc dptr
mov r0,#MAXSMPL
mov @r0,a ; length of the channel list
+ mov r0,#SMPLCTR
+ mov @r0,a
lcall configADC ; configures all registers
+ mov r0,#ASYNC_ON ; async enable
+ mov @r0,#1 ; enable it
+
lcall reset_ep6 ; reset FIFO
;; load new A/D data into EP6
@@ -915,8 +1001,12 @@ ep8_jmp:
;; read one A/D channel
ep8_sglchannel:
- mov DPTR,#0fc01h ; EP8 FIFO
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
clr IOA.7 ; stop the converter, START = 0