]> granicus.if.org Git - linux-firmware/blobdiff - usbdux/usbduxsigma_firmware.asm
usbdux: usbduxsigma: contact info updated
[linux-firmware] / usbdux / usbduxsigma_firmware.asm
index a2305e5a23d0f858a2c373cf5dcbf228886875b4..071d5d6b38f5d81eeca3590cae10ac8007bf527b 100644 (file)
@@ -1,5 +1,5 @@
 ;   usbdux_firmware.asm
-;   Copyright (C) 2010,2011 Bernd Porr, Bernd.Porr@f2s.com
+;   Copyright (C) 2010,2015 Bernd Porr, mail@berndporr.me.uk
 ;   For usbduxsigma.c 0.5+
 ;
 ;   This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,7 @@
 ; Description: University of Stirling USB DAQ & INCITE Technology Limited
 ; Devices: [ITL] USB-DUX-SIGMA (usbduxsigma.ko)
 ; Author: Bernd Porr <Bernd.Porr@f2s.com>
-; Updated: 24 Jul 2011
+; Updated: 19 Jul 2015
 ; Status: testing
 ;
 ;;;
        .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