; usbdux_firmware.asm
- ; Copyright (C) 2003 Bernd Porr, bp1@cn.stir.ac.uk
+ ; Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com
+ ; For usbdux.c 1.00pre2
;
; This program is free software; you can redistribute it a
; it under the terms of the GNU General Public License as
; Firmware: usbdux_firmware.asm for usbdux.c
; Description: University of Stirling USB DAQ & INCITE Techn
; Devices: [ITL] USB-DUX (usbdux.o)
- ; Author: Bernd Porr <Bernd.Porr@cn.stir.ac.uk>
- ; Updated: Thu Oct 16
+ ; Author: Bernd Porr <Bernd.Porr@f2s.com>
+ ; Updated: 18 Aug 2004
; Status: testing
;
;;;
;
;; CPU control
0000: .equ CPUCS,0E600H
+0000: .equ REVCTL,0E60BH
;; interface config
0000: .equ IFCONFIG,0E601H
0000: .equ FIFORESET,0E604H
;;
0000: .equ EP4AUTOINLENH,0E622H
0000: .equ EP4AUTOINLENL,0E623H
+0000: .equ EP6AUTOINLENH,0E624H
+0000: .equ EP6AUTOINLENL,0E625H
0000: .equ EP2FIFOCFG,0E618H
0000: .equ EP4FIFOCFG,0E619H
0000: .equ EP6FIFOCFG,0E61AH
0000: .equ EP8FIFOCFG,0E61BH
;;
0000: .equ INPKTEND,0E648H
+0000: .equ GPIFCTLCFG,0E6C3H
+0000: .equ GPIFABORT,0E6F5H
+0000: .equ GPIFIDLECTL,0E6C2H
+0000: .equ GPIFWFSELECT,0E6C0H
+0000: .equ GPIFREADYCFG,0E6F3H
+0000: .equ GPIFIDLECS,0E6C1H
+0000: .equ EP6GPIFFLGSEL,0E6E2H
+0000: .equ EP6GPIFPDFSTOP,0E6E3H
+0000: .equ EP6GPIFTRIG,0E6E4H
;;
;; endpoint control
0000: .equ EP2CS,0E6A3H
0000: .equ OEC,0B4H
0000: .equ OED,0B5H
0000: .equ OEE,0B6H
+0000: .equ GPIFTRIG,0BBH
0000: .equ EIE,0E8h
+0000: .equ EIP,0F8h
;;; end of file
-
+
+
0000: .equ CHANNELLIST,80h ; channellist in in
-0000: .equ DIOFLAG,90h ; flag if next IN transf is
-
+0000: .equ CMD_FLAG,90h ; flag if next IN transf is
+0000: .equ SGLCHANNEL,91h ; channel for INSN
+
+0000: .equ DIOSTAT0,98h ; last status of the digita
+0000: .equ DIOSTAT1,99h ; same for the second count
+
+0000: .equ CTR0,0A0H ; counter 0
+0000: .equ CTR1,0A2H ; counter 1
+
0000: .org 0000h ; after reset the processor
0000: 02 01 A2 ljmp main ; jump to the main loop
+000B: .org 000bh ; timer 0 irq
+000B: 02 02 F8 ljmp timer0_isr
+
0043: .org 0043h ; the IRQ2-vector
0043: 02 01 00 ljmp jmptbl ; irq service-routine
0100: 02 01 7F jmptbl: ljmp sudav_isr
0103: 00 nop
-0104: 02 03 3C ljmp sof_isr
+0104: 02 03 39 ljmp sof_isr
0107: 00 nop
0108: 02 01 7F ljmp sutok_isr
010B: 00 nop
012B: 00 nop
012C: 02 01 7F ljmp ep1out_isr
012F: 00 nop
-0130: 02 05 77 ljmp ep2_isr
+0130: 02 01 7F ljmp ep2_isr
0133: 00 nop
-0134: 02 03 B5 ljmp ep4_isr
+0134: 02 03 E4 ljmp ep4_isr
0137: 00 nop
-0138: 02 04 9B ljmp ep6_isr
+0138: 02 01 7F ljmp ep6_isr
013B: 00 nop
-013C: 02 05 2B ljmp ep8_isr
+013C: 02 05 63 ljmp ep8_isr
013F: 00 nop
0140: 02 01 7F ljmp ibn_isr
0143: 00 nop
ep4isoerr_isr:
ep6isoerr_isr:
ep8isoerr_isr:
+ ep6_isr:
+ ep2_isr:
+
017F: C0 86 push dps
0181: C0 82 push dpl
;;; then engages in an endless loop
main:
01A2: 90 E6 00 mov DPTR,#CPUCS ; CPU control register
-01A5: 74 14 mov a,#000010100b ; 48MHz clock
-01A7: F0 movx @DPTR,a ; do it
+01A5: 74 10 mov a,#00010000b ; 48Mhz
+01A7: 12 05 B9 lcall syncdelaywr
-01A8: 90 E6 68 mov dptr,#INTSETUP ; IRQ setup register
-01AB: 74 08 mov a,#08h ; enable autovector
-01AD: F0 movx @DPTR,a ; do it
+01AA: 90 E6 0B mov dptr,#REVCTL
+01AD: 74 03 mov a,#00000011b ; allows skip
+01AF: 12 05 B9 lcall syncdelaywr
-01AE: 12 01 C4 lcall initAD ; init the ports to the con
+01B2: 75 B8 00 mov IP,#0 ; all std 8051 int have low
+01B5: 75 F8 FF mov EIP,#0FFH ; all FX2 interrupts have h
+
+01B8: 90 E6 68 mov dptr,#INTSETUP ; IRQ setup register
+01BB: 74 08 mov a,#08h ; enable autovector
+01BD: 12 05 B9 lcall syncdelaywr
-01B1: 90 E6 80 mov dptr,#USBCS ; USB status
-01B4: E0 movx a,@dptr ; get it
-01B5: 54 80 anl a,#80H ; mask out high speed
+01C0: 12 01 D2 lcall initAD ; init the ports to the con
-01B7: 70 05 jnz inihi ; high speed
-
-01B9: 12 02 89 lcall inieplo ; init the isochron
-01BC: 80 03 sjmp mloop2
- inihi:
-01BE: 12 02 E1 lcall iniephi ; init the irq tran
+01C3: 12 02 5A lcall initeps ; init the isochron
-01C1: 00 mloop2: nop
+01C6: 12 01 D9 lcall init_timer
+
+01C9: 00 mloop2: nop
+01CA: 00 nop
+01CB: 00 nop
+01CC: 00 nop
+01CD: 00 nop
+01CE: 00 nop
+01CF: 00 nop
-01C2: 80 FD sjmp mloop2 ; do nothing. The rest is d
+01D0: 80 F7 sjmp mloop2 ; loop for ever
;;; initialise the ports for the AD-converter
initAD:
-01C4: 75 B2 27 mov OEA,#27H ;PortA0,A1,A2,A5 Outputs
-01C7: 75 80 22 mov IOA,#22H ;/CS = 1, disable transfers
-01CA: 22 ret
+01D2: 75 B2 27 mov OEA,#27H ;PortA0,A1,A2,A5 Outputs
+01D5: 75 80 22 mov IOA,#22H ;/CS = 1, disable transfers
+01D8: 22 ret
+ ;;; init the timer for the soft counters
+ init_timer:
+ ;; init the timer for 2ms sampling rate
+01D9: 75 8E 01 mov CKCON,#00000001b; CLKOUT/12 for timer
+01DC: 75 8A 10 mov TL0,#010H ; 16
+01DF: 75 8C 00 mov TH0,#0H ; 256
+01E2: 75 A8 82 mov IE,#82H ; switch on timer i
+01E5: 75 89 00 mov TMOD,#00000000b ; 13 bit counters
+01E8: D2 8C setb TCON.4 ; enable timer 0
+01EA: 22 ret
;;; from here it's only IRQ handling...
;;; result in r3(low) and r4(high)
;;; this routine is optimised for speed
readAD: ; mask the control byte
-01CB: 54 7C anl a,#01111100b ; only the channel, gain+po
-01CD: 44 81 orl a,#10000001b ; start bit, external clock
+01EB: 54 7C anl a,#01111100b ; only the channel, gain+po
+01ED: 44 81 orl a,#10000001b ; start bit, external clock
;; set CS to low
-01CF: C2 81 clr IOA.1 ; set /CS to zero
+01EF: C2 81 clr IOA.1 ; set /CS to zero
;; send the control byte to the AD-converter
-01D1: 7A 08 mov R2,#8 ; bit-counter
-01D3: 30 E7 04 S1: jnb ACC.7,bitzero ; jump if Bit7 = 0?
-01D6: D2 82 setb IOA.2 ; set the DIN bit
-01D8: 80 02 sjmp clock ; continue with the clock
-01DA: C2 82 bitzero:clr IOA.2 ; clear the DIN bit
-01DC: D2 80 clock: setb IOA.0 ; SCLK = 1
-01DE: C2 80 clr IOA.0 ; SCLK = 0
-01E0: 23 rl a ; next Bit
-01E1: DA F0 djnz R2,S1
+01F1: 7A 08 mov R2,#8 ; bit-counter
+01F3: 30 E7 04 bitlp: jnb ACC.7,bitzero ; jump if Bit7 = 0?
+01F6: D2 82 setb IOA.2 ; set the DIN bit
+01F8: 80 02 sjmp clock ; continue with the clock
+01FA: C2 82 bitzero:clr IOA.2 ; clear the DIN bit
+01FC: D2 80 clock: setb IOA.0 ; SCLK = 1
+01FE: C2 80 clr IOA.0 ; SCLK = 0
+0200: 23 rl a ; next Bit
+0201: DA F0 djnz R2,bitlp
;; continue the aquisition (already started)
-01E3: C2 82 clr IOA.2 ; clear the DIN bit
-01E5: 7A 05 mov R2,#5 ; five steps for the aquisi
-01E7: D2 80 clockaq:setb IOA.0 ; SCLK = 1
-01E9: C2 80 clr IOA.0 ; SCLK = 0
-01EB: DA FA djnz R2,clockaq ; loop
+0203: C2 82 clr IOA.2 ; clear the DIN bit
+0205: 7A 05 mov R2,#5 ; five steps for the aquisi
+0207: D2 80 clockaq:setb IOA.0 ; SCLK = 1
+0209: C2 80 clr IOA.0 ; SCLK = 0
+020B: DA FA djnz R2,clockaq ; loop
;; read highbyte from the A/D-converter
;; and do the conversion
-01ED: 7C 00 mov r4,#0 ; Highbyte goes into R4
-01EF: 7A 04 mov R2,#4 ; COUNTER 4 data bits in th
-01F1: 7D 08 mov r5,#08h ; create bit-mask
+020D: 7C 00 mov r4,#0 ; Highbyte goes into R4
+020F: 7A 04 mov R2,#4 ; COUNTER 4 data bits in th
+0211: 7D 08 mov r5,#08h ; create bit-mask
gethi: ; loop get the 8 highest bi
-01F3: D2 80 setb IOA.0 ; SCLK = 1
-01F5: C2 80 clr IOA.0 ; SCLK = 0
-01F7: E5 80 mov a,IOA ; from port A
-01F9: 30 E4 03 jnb ACC.4,zerob ; the in-bit is zero
-01FC: EC mov a,r4 ; get the byte
-01FD: 4D orl a,r5 ; or the bit to the result
-01FE: FC mov r4,a ; save it again in r4
-01FF: ED zerob: mov a,r5 ; get r5 in order to shift
-0200: 03 rr a ; rotate right
-0201: FD mov r5,a ; back to r5
-0202: DA EF djnz R2,gethi
+0213: D2 80 setb IOA.0 ; SCLK = 1
+0215: C2 80 clr IOA.0 ; SCLK = 0
+0217: E5 80 mov a,IOA ; from port A
+0219: 30 E4 03 jnb ACC.4,zerob ; the in-bit is zero
+021C: EC mov a,r4 ; get the byte
+021D: 4D orl a,r5 ; or the bit to the result
+021E: FC mov r4,a ; save it again in r4
+021F: ED zerob: mov a,r5 ; get r5 in order to shift
+0220: 03 rr a ; rotate right
+0221: FD mov r5,a ; back to r5
+0222: DA EF djnz R2,gethi
;; read the lowbyte from the A/D-converter
-0204: 7B 00 mov r3,#0 ; Lowbyte goes into R3
-0206: 7A 08 mov r2,#8 ; COUNTER 8 data-bits in th
-0208: 7D 80 mov r5,#80h ; create bit-mask
+0224: 7B 00 mov r3,#0 ; Lowbyte goes into R3
+0226: 7A 08 mov r2,#8 ; COUNTER 8 data-bits in th
+0228: 7D 80 mov r5,#80h ; create bit-mask
getlo: ; loop get the 8 highest bi
-020A: D2 80 setb IOA.0 ; SCLK = 1
-020C: C2 80 clr IOA.0 ; SCLK = 0
-020E: E5 80 mov a,IOA ; from port A
-0210: 30 E4 03 jnb ACC.4,zerob2 ; the in-bit is zero
-0213: EB mov a,r3 ; get the result-byte
-0214: 4D orl a,r5 ; or the bit to the result
-0215: FB mov r3,a ; save it again in r4
-0216: ED zerob2: mov a,r5 ; get r5 in order to shift
-0217: 03 rr a ; rotate right
-0218: FD mov r5,a ; back to r5
-0219: DA EF djnz R2,getlo
-021B: D2 81 setb IOA.1 ; set /CS to one
+022A: D2 80 setb IOA.0 ; SCLK = 1
+022C: C2 80 clr IOA.0 ; SCLK = 0
+022E: E5 80 mov a,IOA ; from port A
+0230: 30 E4 03 jnb ACC.4,zerob2 ; the in-bit is zero
+0233: EB mov a,r3 ; get the result-byte
+0234: 4D orl a,r5 ; or the bit to the result
+0235: FB mov r3,a ; save it again in r4
+0236: ED zerob2: mov a,r5 ; get r5 in order to shift
+0237: 03 rr a ; rotate right
+0238: FD mov r5,a ; back to r5
+0239: DA EF djnz R2,getlo
+023B: D2 81 setb IOA.1 ; set /CS to one
;;
-021D: 22 ret
+023D: 22 ret
- ;;; aquires data from all 8 channels and stores it in the EP
- convlo: ;;
-021E: 75 9A F8 mov AUTOPTRH1,#0F8H ; EP6
-0221: 75 9B 00 mov AUTOPTRL1,#00H
-0224: 75 AF 07 mov AUTOPTRSETUP,#7
-0227: 78 80 mov r0,#CHANNELLIST ; points to the cha
-0229: E6 mov a,@r0 ;Ch0
-022A: 12 01 CB lcall readAD
-022D: EB mov a,R3 ;
-022E: 90 E6 7B mov DPTR,#XAUTODAT1
-0231: F0 movx @DPTR,A
-0232: EC mov a,R4 ;
-0233: F0 movx @DPTR,A
-
-0234: 08 inc r0 ; next channel
-0235: E6 mov a,@r0 ;Ch1
-0236: 12 01 CB lcall readAD
-0239: EB mov a,R3 ;
-023A: 90 E6 7B mov DPTR,#XAUTODAT1
-023D: F0 movx @DPTR,A
-023E: EC mov a,R4 ;
-023F: F0 movx @DPTR,A
-
-0240: 08 inc r0
-0241: E6 mov a,@r0 ;Ch2
-0242: 12 01 CB lcall readAD
-0245: EB mov a,R3 ;
-0246: 90 E6 7B mov DPTR,#XAUTODAT1
-0249: F0 movx @DPTR,A
-024A: EC mov a,R4 ;
-024B: F0 movx @DPTR,A
-
-024C: 08 inc r0
-024D: E6 mov a,@r0 ;Ch3
-024E: 12 01 CB lcall readAD
-0251: EB mov a,R3 ;
-0252: 90 E6 7B mov DPTR,#XAUTODAT1
-0255: F0 movx @DPTR,A
-0256: EC mov a,R4 ;
-0257: F0 movx @DPTR,A
-
-0258: 08 inc r0
-0259: E6 mov a,@r0 ;Ch4
-025A: 12 01 CB lcall readAD
-025D: EB mov a,R3 ;
-025E: 90 E6 7B mov DPTR,#XAUTODAT1
-0261: F0 movx @DPTR,A
-0262: EC mov a,R4 ;
-0263: F0 movx @DPTR,A
-
-0264: 08 inc r0
-0265: E6 mov a,@r0 ;Ch5
-0266: 12 01 CB lcall readAD
-0269: EB mov a,R3 ;
-026A: 90 E6 7B mov DPTR,#XAUTODAT1
-026D: F0 movx @DPTR,A
-026E: EC mov a,R4 ;
-026F: F0 movx @DPTR,A
-
-0270: 08 inc r0
-0271: E6 mov a,@r0 ;Ch6
-0272: 12 01 CB lcall readAD
-0275: EB mov a,R3 ;
-0276: 90 E6 7B mov DPTR,#XAUTODAT1
-0279: F0 movx @DPTR,A
-027A: EC mov a,R4 ;
-027B: F0 movx @DPTR,A
-
-027C: 08 inc r0
-027D: E6 mov a,@r0 ;Ch7
-027E: 12 01 CB lcall readAD
-0281: EB mov a,R3 ;
-0282: 90 E6 7B mov DPTR,#XAUTODAT1
-0285: F0 movx @DPTR,A
-0286: EC mov a,R4 ;
-0287: F0 movx @DPTR,A
-0288: 22 ret
-
-
-
-
- ;;; initilise the transfer for full speed
- ;;; It is assumed that the USB interface is in alternate set
- inieplo:
-0289: 90 E6 04 mov dptr,#FIFORESET
-028C: 74 0F mov a,#0fh
-028E: F0 movx @dptr,a ; reset all fifos
-028F: 74 00 mov a,#00h
-0291: F0 movx @dptr,a ; normal operat
-
-0292: 90 E6 12 mov DPTR,#EP2CFG
-0295: 74 92 mov a,#10010010b ; valid, out, double buff,
-0297: F0 movx @DPTR,a
-
-0298: 90 E6 18 mov dptr,#EP2FIFOCFG
-029B: 74 00 mov a,#00000000b ; manual
-029D: F0 movx @dptr,a
-
-029E: 90 E6 91 mov dptr,#EP2BCL ; "arm" it
-02A1: 74 80 mov a,#80h
-02A3: F0 movx @DPTR,a ; can receive data
-02A4: F0 movx @DPTR,a ; can receive data
-02A5: F0 movx @DPTR,a ; can receive data
-
-02A6: 90 E6 13 mov DPTR,#EP4CFG
-02A9: 74 A0 mov a,#10100000b ; valid
-02AB: F0 movx @dptr,a
-
-02AC: 90 E6 19 mov dptr,#EP4FIFOCFG
-02AF: 74 00 mov a,#00000000b ; manual
-02B1: F0 movx @dptr,a
+ ;;; aquires data from A/D channels and stores them in the EP
+ conv_ad:
+023E: 75 9A F8 mov AUTOPTRH1,#0F8H ; auto pointer on E
+0241: 75 9B 00 mov AUTOPTRL1,#00H
+0244: 75 AF 07 mov AUTOPTRSETUP,#7
+0247: 78 80 mov r0,#CHANNELLIST ; points to the cha
-02B2: 90 E6 95 mov dptr,#EP4BCL ; "arm" it
-02B5: 74 80 mov a,#80h
-02B7: F0 movx @DPTR,a ; can receive data
-02B8: F0 movx @dptr,a ; make shure its re
+0249: E6 mov a,@r0 ; number of channels
+024A: F9 mov r1,a ; counter
-02B9: 90 E6 14 mov DPTR,#EP6CFG ; ISO data from here to the
-02BC: 74 D2 mov a,#11010010b ; Valid
-02BE: F0 movx @DPTR,a ; ISO transfer, dou
+024B: 90 E6 7B mov DPTR,#XAUTODAT1 ; auto pointer
+ convloop:
+024E: 08 inc r0
+024F: E6 mov a,@r0 ; Channel
+0250: 12 01 EB lcall readAD
+0253: EB mov a,R3 ;
+0254: F0 movx @DPTR,A
+0255: EC mov a,R4 ;
+0256: F0 movx @DPTR,A
+0257: D9 F5 djnz r1,convloop
-02BF: 90 E6 15 mov DPTR,#EP8CFG ; EP8
-02C2: 74 E0 mov a,#11100000b ; BULK data from here to th
-02C4: F0 movx @DPTR,a ;
+0259: 22 ret
-02C5: 90 E6 5E mov dptr,#EPIE ; interrupt enable
-02C8: 74 A0 mov a,#10100000b ; enable irq for ep4,8
-02CA: F0 movx @dptr,a ; do it
-02CB: 90 E6 5F mov dptr,#EPIRQ ; clear IRQs
-02CE: 74 A0 mov a,#10100000b
-02D0: F0 movx @dptr,a
-
- ;; enable interrups
-02D1: 90 E6 5C mov DPTR,#USBIE ; USB int enables register
-02D4: 74 02 mov a,#2 ; enables SOF (1ms/125us int
-02D6: F0 movx @DPTR,a ;
-
-02D7: 75 E8 01 mov EIE,#00000001b ; enable INT2 in the 8051's
-02DA: 75 A8 80 mov IE,#80h ; IE, enable all in
-
-02DD: 12 05 1E lcall ep8_arm ;
-
-02E0: 22 ret
- ;;; initilise the IRQ transfer
- iniephi:
-02E1: 90 E6 04 mov dptr,#FIFORESET
-02E4: 74 0F mov a,#0fh
-02E6: F0 movx @dptr,a ; reset all fifos
-02E7: 74 00 mov a,#00h
-02E9: F0 movx @dptr,a ; normal operat
-
-02EA: 90 E6 12 mov DPTR,#EP2CFG
-02ED: 74 B2 mov a,#10110010b ; valid, out, double buff,
-02EF: F0 movx @DPTR,a
-
-02F0: 90 E6 18 mov dptr,#EP2FIFOCFG
-02F3: 74 00 mov a,#00000000b ; manual
-02F5: F0 movx @dptr,a
-
-02F6: 90 E6 91 mov dptr,#EP2BCL ; "arm" it
-02F9: 74 80 mov a,#80h
-02FB: F0 movx @DPTR,a ; can receive data
-02FC: F0 movx @DPTR,a ; can receive data
-02FD: F0 movx @DPTR,a ; can receive data
+ ;;; initilise the transfer
+ ;;; It is assumed that the USB interface is in alternate set
+ initeps:
+025A: 90 E6 04 mov dptr,#FIFORESET
+025D: 74 80 mov a,#80H
+025F: F0 movx @dptr,a ; reset all fifos
+0260: 74 02 mov a,#2
+0262: F0 movx @dptr,a ;
+0263: 74 04 mov a,#4
+0265: F0 movx @dptr,a ;
+0266: 74 06 mov a,#6
+0268: F0 movx @dptr,a ;
+0269: 74 08 mov a,#8
+026B: F0 movx @dptr,a ;
+026C: 74 00 mov a,#0
+026E: F0 movx @dptr,a ; normal operat
-02FE: 90 E6 13 mov DPTR,#EP4CFG
-0301: 74 A0 mov a,#10100000b ; valid
-0303: F0 movx @dptr,a
-
-0304: 90 E6 19 mov dptr,#EP4FIFOCFG
-0307: 74 00 mov a,#00000000b ; manual
-0309: F0 movx @dptr,a
-
-030A: 90 E6 95 mov dptr,#EP4BCL ; "arm" it
-030D: 74 80 mov a,#80h
-030F: F0 movx @DPTR,a ; can receive data
-0310: F0 movx @dptr,a ; make shure its re
-
-0311: 90 E6 14 mov DPTR,#EP6CFG ; IRQ data from here to the
-0314: 74 F2 mov a,#11110010b ; Valid
-0316: F0 movx @DPTR,a ; IRQ transfer, dou
-
-0317: 90 E6 15 mov DPTR,#EP8CFG ; EP8
-031A: 74 E0 mov a,#11100000b ; BULK data from here to th
-031C: F0 movx @DPTR,a ;
+026F: 90 E6 12 mov DPTR,#EP2CFG
+0272: 74 92 mov a,#10010010b ; valid, out, double buff,
+0274: F0 movx @DPTR,a
+
+0275: 90 E6 18 mov dptr,#EP2FIFOCFG
+0278: 74 00 mov a,#00000000b ; manual
+027A: F0 movx @dptr,a
+
+027B: 90 E6 91 mov dptr,#EP2BCL ; "arm" it
+027E: 74 00 mov a,#00h
+0280: F0 movx @DPTR,a ; can receive data
+0281: 12 05 AF lcall syncdelay ; wait to sync
+0284: F0 movx @DPTR,a ; can receive data
+0285: 12 05 AF lcall syncdelay ; wait to sync
+0288: F0 movx @DPTR,a ; can receive data
+0289: 12 05 AF lcall syncdelay ; wait to sync
-031D: 90 E6 5E mov dptr,#EPIE ; interrupt enable
-0320: 74 F0 mov a,#11110000b ; enable irq for ep2,ep4,ep
-0322: F0 movx @dptr,a ; do it
+028C: 90 E6 13 mov DPTR,#EP4CFG
+028F: 74 A0 mov a,#10100000b ; valid
+0291: F0 movx @dptr,a
-0323: 90 E6 5F mov dptr,#EPIRQ
-0326: 74 F0 mov a,#11110000b ; clear irq bits
-0328: F0 movx @dptr,a
+0292: 90 E6 19 mov dptr,#EP4FIFOCFG
+0295: 74 00 mov a,#00000000b ; manual
+0297: F0 movx @dptr,a
- ;; enable interrups
-0329: 90 E6 5C mov DPTR,#USBIE ; USB int enables register
-032C: 74 00 mov a,#0 ; disables SOF (1ms/125ms in
-032E: F0 movx @DPTR,a ;
+0298: 90 E6 95 mov dptr,#EP4BCL ; "arm" it
+029B: 74 00 mov a,#00h
+029D: F0 movx @DPTR,a ; can receive data
+029E: 12 05 AF lcall syncdelay ; wait until we can write a
+02A1: F0 movx @dptr,a ; make shure its re
+02A2: 12 05 AF lcall syncdelay ; wait
-032F: 75 E8 01 mov EIE,#00000001b ; enable INT2 in the 8051's
-0332: 75 A8 80 mov IE,#80h ; IE, enable all in
+02A5: 90 E6 14 mov DPTR,#EP6CFG ; ISO data from here to the
+02A8: 74 D2 mov a,#11010010b ; Valid
+02AA: F0 movx @DPTR,a ; ISO transfer, dou
-0335: 12 05 1E lcall ep8_arm ; put dummy data in
-0338: 12 04 8B lcall ep6_arm ; put dummy data in
-
-033B: 22 ret
+02AB: 90 E6 15 mov DPTR,#EP8CFG ; EP8
+02AE: 74 E0 mov a,#11100000b ; BULK data from here to th
+02B0: F0 movx @DPTR,a ;
+
+02B1: 90 E6 5E mov dptr,#EPIE ; interrupt enable
+02B4: 74 A0 mov a,#10100000b ; enable irq for ep4,8
+02B6: F0 movx @dptr,a ; do it
+02B7: 90 E6 5F mov dptr,#EPIRQ ; clear IRQs
+02BA: 74 A0 mov a,#10100000b
+02BC: F0 movx @dptr,a
+ ;; enable interrups
+02BD: 90 E6 5C mov DPTR,#USBIE ; USB int enables register
+02C0: 74 02 mov a,#2 ; enables SOF (1ms/125us int
+02C2: F0 movx @DPTR,a ;
+
+02C3: 75 E8 01 mov EIE,#00000001b ; enable INT2 in the 8051's
+02C6: 75 A8 80 mov IE,#80h ; IE, enable all in
+
+02C9: 22 ret
+
+
+ ;;; counter
+ ;;; r0: DIOSTAT
+ ;;; r1: counter address
+ ;;; r2: up/down-mask
+ ;;; r3: reset-mask
+ ;;; r4: clock-mask
+ counter:
+02CA: E5 90 mov a,IOB ; actual IOB input state
+02CC: FD mov r5,a ; save in r5
+02CD: 5B anl a,r3 ; bit mask for reset
+02CE: 60 06 jz no_reset ; reset if one
+02D0: E4 clr a ; set counter to zero
+02D1: F7 mov @r1,a
+02D2: 0C inc r4
+02D3: F7 mov @r1,a
+02D4: 80 1F sjmp ctr_end
+ no_reset:
+02D6: E6 mov a,@r0 ; get last state
+02D7: 6D xrl a,r5 ; has it changed?
+02D8: 5D anl a,r5 ; is it now on?
+02D9: 5C anl a,r4 ; mask out the port
+02DA: 60 19 jz ctr_end ; no rising edge
+02DC: ED mov a,r5 ; get port B again
+02DD: 5A anl a,r2 ; test if up or down
+02DE: 70 0C jnz ctr_up ; count up
+02E0: E7 mov a,@r1
+02E1: 14 dec a
+02E2: F7 mov @r1,a
+02E3: B4 FF 0F cjne a,#0ffh,ctr_end ; underflow?
+02E6: 09 inc r1 ; high byte
+02E7: E7 mov a,@r1
+02E8: 14 dec a
+02E9: F7 mov @r1,a
+02EA: 80 09 sjmp ctr_end
+ ctr_up: ; count up
+02EC: E7 mov a,@r1
+02ED: 04 inc a
+02EE: F7 mov @r1,a
+02EF: 70 04 jnz ctr_end
+02F1: 09 inc r1 ; high byte
+02F2: E7 mov a,@r1
+02F3: 04 inc a
+02F4: F7 mov @r1,a
+ ctr_end:
+02F5: ED mov a,r5
+02F6: F6 mov @r0,a
+02F7: 22 ret
+
+ ;;; implements two soft counters with up/down and reset
+ timer0_isr:
+02F8: C0 86 push dps
+02FA: C0 E0 push acc
+02FC: C0 D0 push psw
+02FE: C0 00 push 00h ; R0
+0300: C0 01 push 01h ; R1
+0302: C0 02 push 02h ; R2
+0304: C0 03 push 03h ; R3
+0306: C0 04 push 04h ; R4
+0308: C0 05 push 05h ; R5
+
+030A: 78 98 mov r0,#DIOSTAT0 ; status of port
+030C: 79 A0 mov r1,#CTR0 ; address of counter0
+030E: 74 01 mov a,#00000001b ; bit 0
+0310: FC mov r4,a ; clock
+0311: 23 rl a ; bit 1
+0312: FA mov r2,a ; up/down
+0313: 23 rl a ; bit 2
+0314: FB mov r3,a ; reset mask
+0315: 12 02 CA lcall counter
+0318: 08 inc r0 ; to DISTAT1
+0319: 09 inc r1 ; to CTR1
+031A: 09 inc r1
+031B: EB mov a,r3
+031C: 23 rl a ; bit 3
+031D: 23 rl a ; bit 4
+031E: FC mov r4,a ; clock
+031F: 23 rl a ; bit 5
+0320: FA mov r2,a ; up/down
+0321: 23 rl a ; bit 6
+0322: FB mov r3,a ; reset
+0323: 12 02 CA lcall counter
+0326: D0 05 pop 05h ; R5
+0328: D0 04 pop 04h ; R4
+032A: D0 03 pop 03h ; R3
+032C: D0 02 pop 02h ; R2
+032E: D0 01 pop 01h ; R1
+0330: D0 00 pop 00h ; R0
+0332: D0 D0 pop psw
+0334: D0 E0 pop acc
+0336: D0 86 pop dps
+
+0338: 32 reti
+
;;; interrupt-routine for SOF
;;; is for full speed
sof_isr:
-033C: C0 86 push dps
-033E: C0 82 push dpl
-0340: C0 83 push dph
-0342: C0 84 push dpl1
-0344: C0 85 push dph1
-0346: C0 E0 push acc
-0348: C0 D0 push psw
-034A: C0 00 push 00h ; R0
-034C: C0 01 push 01h ; R1
-034E: C0 02 push 02h ; R2
-0350: C0 03 push 03h ; R3
-0352: C0 04 push 04h ; R4
-0354: C0 05 push 05h ; R5
-0356: C0 06 push 06h ; R6
-0358: C0 07 push 07h ; R7
+0339: C0 86 push dps
+033B: C0 82 push dpl
+033D: C0 83 push dph
+033F: C0 84 push dpl1
+0341: C0 85 push dph1
+0343: C0 E0 push acc
+0345: C0 D0 push psw
+0347: C0 00 push 00h ; R0
+0349: C0 01 push 01h ; R1
+034B: C0 02 push 02h ; R2
+034D: C0 03 push 03h ; R3
+034F: C0 04 push 04h ; R4
+0351: C0 05 push 05h ; R5
+0353: C0 06 push 06h ; R6
+0355: C0 07 push 07h ; R7
-035A: 90 E6 80 mov dptr,#USBCS ; USB status
-035D: E0 movx a,@dptr ; get it
-035E: 54 80 anl a,#80H ; mask out high speed
-
-0360: 70 28 jnz hispeed ; do nothing here
-
-0362: E5 AA mov a,EP2468STAT
-0364: 54 20 anl a,#20H ; full?
-0366: 70 0F jnz epfull ; EP6-buffer is full
+0357: E5 AA mov a,EP2468STAT
+0359: 54 20 anl a,#20H ; full?
+035B: 70 13 jnz epfull ; EP6-buffer is full
-0368: 12 02 1E lcall convlo ; conversion
+035D: 12 02 3E lcall conv_ad ; conversion
-036B: 90 E6 98 mov DPTR,#EP6BCH ; byte count H
-036E: 74 00 mov a,#0 ; is zero
-0370: F0 movx @DPTR,a
+0360: 90 E6 98 mov DPTR,#EP6BCH ; byte count H
+0363: 74 00 mov a,#0 ; is zero
+0365: 12 05 B9 lcall syncdelaywr ; wait until we can write a
-0371: 90 E6 99 mov DPTR,#EP6BCL ; byte count L
-0374: 74 10 mov a,#10H ; is 8x word = 16 bytes
-0376: F0 movx @DPTR,a
+0368: 90 E6 99 mov DPTR,#EP6BCL ; byte count L
+036B: 74 10 mov a,#10H ; is 8x word = 16 bytes
+036D: 12 05 B9 lcall syncdelaywr ; wait until we can write a
epfull:
;; do the D/A conversion
-0377: E5 AA mov a,EP2468STAT
-0379: 54 01 anl a,#01H ; empty
-037B: 70 0D jnz epempty ; nothing to get
+0370: E5 AA mov a,EP2468STAT
+0372: 54 01 anl a,#01H ; empty
+0374: 70 11 jnz epempty ; nothing to get
-037D: 90 F0 00 mov dptr,#0F000H ; EP2 fifo buffer
-0380: 12 04 4B lcall dalo ; conversion
+0376: 90 F0 00 mov dptr,#0F000H ; EP2 fifo buffer
+0379: 12 04 B7 lcall dalo ; conversion
-0383: 90 E6 91 mov dptr,#EP2BCL ; "arm" it
-0386: 74 80 mov a,#80h
-0388: F0 movx @DPTR,a ; can receive data
-0389: F0 movx @dptr,a
+037C: 90 E6 91 mov dptr,#EP2BCL ; "arm" it
+037F: 74 00 mov a,#00h
+0381: 12 05 B9 lcall syncdelaywr ; wait for the rec to sync
+0384: 12 05 B9 lcall syncdelaywr ; wait for the rec to sync
- hispeed:
epempty:
;; clear INT2
-038A: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
-038C: C2 E4 clr acc.4
-038E: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
+0387: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
+0389: C2 E4 clr acc.4
+038B: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
-0390: 90 E6 5D mov DPTR,#USBIRQ ; points to the SOF
-0393: 74 02 mov a,#2 ; clear the SOF
-0395: F0 movx @DPTR,a
+038D: 90 E6 5D mov DPTR,#USBIRQ ; points to the SOF
+0390: 74 02 mov a,#2 ; clear the SOF
+0392: F0 movx @DPTR,a
nosof:
-0396: D0 07 pop 07h
-0398: D0 06 pop 06h
-039A: D0 05 pop 05h
-039C: D0 04 pop 04h ; R4
-039E: D0 03 pop 03h ; R3
-03A0: D0 02 pop 02h ; R2
-03A2: D0 01 pop 01h ; R1
-03A4: D0 00 pop 00h ; R0
-03A6: D0 D0 pop psw
-03A8: D0 E0 pop acc
-03AA: D0 85 pop dph1
-03AC: D0 84 pop dpl1
-03AE: D0 83 pop dph
-03B0: D0 82 pop dpl
-03B2: D0 86 pop dps
-03B4: 32 reti
-
-
-
-
+0393: D0 07 pop 07h
+0395: D0 06 pop 06h
+0397: D0 05 pop 05h
+0399: D0 04 pop 04h ; R4
+039B: D0 03 pop 03h ; R3
+039D: D0 02 pop 02h ; R2
+039F: D0 01 pop 01h ; R1
+03A1: D0 00 pop 00h ; R0
+03A3: D0 D0 pop psw
+03A5: D0 E0 pop acc
+03A7: D0 85 pop dph1
+03A9: D0 84 pop dpl1
+03AB: D0 83 pop dph
+03AD: D0 82 pop dpl
+03AF: D0 86 pop dps
+03B1: 32 reti
+
+
+ reset_ep8:
+ ;; erase all data in ep8
+03B2: 90 E6 04 mov dptr,#FIFORESET
+03B5: 74 80 mov a,#80H ; NAK
+03B7: 12 05 B9 lcall syncdelaywr
+03BA: 90 E6 04 mov dptr,#FIFORESET
+03BD: 74 08 mov a,#8 ; reset EP8
+03BF: 12 05 B9 lcall syncdelaywr
+03C2: 90 E6 04 mov dptr,#FIFORESET
+03C5: 74 00 mov a,#0 ; normal operation
+03C7: 12 05 B9 lcall syncdelaywr
+03CA: 22 ret
+
+
+ reset_ep6:
+ ;; throw out old data
+03CB: 90 E6 04 mov dptr,#FIFORESET
+03CE: 74 80 mov a,#80H ; NAK
+03D0: 12 05 B9 lcall syncdelaywr
+03D3: 90 E6 04 mov dptr,#FIFORESET
+03D6: 74 06 mov a,#6 ; reset EP6
+03D8: 12 05 B9 lcall syncdelaywr
+03DB: 90 E6 04 mov dptr,#FIFORESET
+03DE: 74 00 mov a,#0 ; normal operation
+03E0: 12 05 B9 lcall syncdelaywr
+03E3: 22 ret
+
;;; interrupt-routine for ep4
;;; receives the channel list and other commands
ep4_isr:
-03B5: C0 86 push dps
-03B7: C0 82 push dpl
-03B9: C0 83 push dph
-03BB: C0 84 push dpl1
-03BD: C0 85 push dph1
-03BF: C0 E0 push acc
-03C1: C0 D0 push psw
-03C3: C0 00 push 00h ; R0
-03C5: C0 01 push 01h ; R1
-03C7: C0 02 push 02h ; R2
-03C9: C0 03 push 03h ; R3
-03CB: C0 04 push 04h ; R4
-03CD: C0 05 push 05h ; R5
-03CF: C0 06 push 06h ; R6
-03D1: C0 07 push 07h ; R7
+03E4: C0 86 push dps
+03E6: C0 82 push dpl
+03E8: C0 83 push dph
+03EA: C0 84 push dpl1
+03EC: C0 85 push dph1
+03EE: C0 E0 push acc
+03F0: C0 D0 push psw
+03F2: C0 00 push 00h ; R0
+03F4: C0 01 push 01h ; R1
+03F6: C0 02 push 02h ; R2
+03F8: C0 03 push 03h ; R3
+03FA: C0 04 push 04h ; R4
+03FC: C0 05 push 05h ; R5
+03FE: C0 06 push 06h ; R6
+0400: C0 07 push 07h ; R7
-03D3: 90 F4 00 mov dptr,#0f400h ; FIFO buffer of EP4
-03D6: E0 movx a,@dptr ; get the first byt
-
-03D7: 90 03 DC mov dptr,#ep4_jmp ; jump table for the differ
-03DA: 23 rl a ; multiply by 2: sizeof sjm
-03DB: 73 jmp @a+dptr ; jump to the jump
+0402: 90 F4 00 mov dptr,#0f400h ; FIFO buffer of EP4
+0405: E0 movx a,@dptr ; get the first byt
+0406: 78 90 mov r0,#CMD_FLAG ; pointer to the command by
+0408: F6 mov @r0,a ; store the command byte fo
+
+0409: 90 04 0E mov dptr,#ep4_jmp ; jump table for the differ
+040C: 23 rl a ; multiply by 2: sizeof sjm
+040D: 73 jmp @a+dptr ; jump to the jump
+ ;; jump table, corresponds to the command bytes def
+ ;; in usbdux.c
ep4_jmp:
-03DC: 80 06 sjmp storechannellist; a=0
-03DE: 80 17 sjmp single_da ; a=1
-03E0: 80 1D sjmp config_digital_b; a=2
-03E2: 80 23 sjmp write_digital_b ; a=3
-
+040E: 80 39 sjmp storechannellist; a=0
+0410: 80 4C sjmp single_da ; a=1
+0412: 80 52 sjmp config_digital_b; a=2
+0414: 80 58 sjmp write_digital_b ; a=3
+0416: 80 22 sjmp storesglchannel ; a=4
+0418: 80 02 sjmp readcounter ; a=5
+041A: 80 08 sjmp writecounter ; a=6
+
+ ;; read the counter
+ readcounter:
+041C: 12 03 B2 lcall reset_ep8 ; reset ep8
+041F: 12 05 0B lcall ep8_ops ; fill the counter
+0422: 80 5A sjmp over_da ; jump to the end
+
+ ;; write zeroes to the counters
+ writecounter:
+0424: 90 F4 01 mov dptr,#0f401h ; buffer
+0427: 78 A0 mov r0,#CTR0 ; r0 points to counter 0
+0429: E0 movx a,@dptr ; channel number
+042A: 60 05 jz wrctr0 ; first channel
+042C: F9 mov r1,a ; counter
+ wrctrl:
+042D: 08 inc r0 ; next counter
+042E: 08 inc r0 ; next counter
+042F: D9 FC djnz r1,wrctrl ; advance to the right coun
+ wrctr0:
+0431: A3 inc dptr ; get to the value
+0432: E0 movx a,@dptr ; get value
+0433: F6 mov @r0,a ; save in ctr
+0434: 08 inc r0 ; next byte
+0435: A3 inc dptr
+0436: E0 movx a,@dptr ; get value
+0437: F6 mov @r0,a ; save in ctr
+0438: 80 44 sjmp over_da ; jump to the end
+
+ storesglchannel:
+043A: 78 91 mov r0,#SGLCHANNEL ; the conversion bytes are
+043C: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
+043F: E0 movx a,@dptr ;
+0440: F6 mov @r0,a
+
+0441: 12 03 B2 lcall reset_ep8 ; reset FIFO
+ ;; Save new A/D data in EP8. This is the first byte
+ ;; the host will read during an INSN. If there are
+ ;; more to come they will be handled by the ISR of
+ ;; ep8.
+0444: 12 05 0B lcall ep8_ops ; get A/D data
+
+0447: 80 35 sjmp over_da
- ;;; Channellist:
+
+ ;;; Channellist:
;;; the first byte is zero:
;;; we've just received the channel list
- ;;; the channel list is stored in the addresses from 80H whi
+ ;;; the channel list is stored in the addresses from CHANNEL
;;; are _only_ reachable by indirect addressing
storechannellist:
-03E4: 78 80 mov r0,#CHANNELLIST ; the conversion by
-03E6: 7A 08 mov r2,#8 ; counter
-03E8: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
+0449: 78 80 mov r0,#CHANNELLIST ; the conversion by
+044B: 7A 09 mov r2,#9 ; counter
+044D: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
chanlloop:
-03EB: E0 movx a,@dptr ;
-03EC: F6 mov @r0,a
-03ED: A3 inc dptr
-03EE: 08 inc r0
-03EF: DA FA djnz r2,chanlloop
-03F1: E4 clr a ; announce analogue transac
-03F2: 78 90 mov r0,#DIOFLAG ; pointer to the command by
-03F4: F6 mov @r0,a ; set the command byte
-03F5: 80 21 sjmp over_da
+0450: E0 movx a,@dptr ;
+0451: F6 mov @r0,a
+0452: A3 inc dptr
+0453: 08 inc r0
+0454: DA FA djnz r2,chanlloop
+
+0456: 12 03 CB lcall reset_ep6 ; reset FIFO
+
+ ;; load new A/D data into EP6
+ ;; This must be done. Otherwise the ISR is never ca
+ ;; The ISR is only called when data has _left_ the
+ ;; ep buffer here it has to be refilled.
+0459: 12 04 F7 lcall ep6_arm ; fill with the fir
+
+045C: 80 20 sjmp over_da
;;; Single DA conversion. The 2 bytes are in the FIFO buffer
single_da:
-03F7: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
-03FA: 12 04 4B lcall dalo ; conversion
-03FD: 80 19 sjmp over_da
+045E: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
+0461: 12 04 B7 lcall dalo ; conversion
+0464: 80 18 sjmp over_da
- ;;; configure the port B
+ ;;; configure the port B as input or output (bitwise)
config_digital_b:
-03FF: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
-0402: E0 movx a,@dptr ; get the second by
-0403: F5 B3 mov OEB,a ; set the output enable bit
-0405: 80 11 sjmp over_da
+0466: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
+0469: E0 movx a,@dptr ; get the second by
+046A: F5 B3 mov OEB,a ; set the output enable bit
+046C: 80 10 sjmp over_da
;;; Write one byte to the external digital port B
;;; and prepare for digital read
write_digital_b:
-0407: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
-040A: E0 movx a,@dptr ; get the second by
-040B: F5 B3 mov OEB,a ; output enable
-040D: A3 inc dptr ; next byte
-040E: E0 movx a,@dptr ; bits
-040F: F5 90 mov IOB,a ; send the byte to the I/O
-0411: 74 FF mov a,#0ffh ; announce DIO tran
-0413: 78 90 mov r0,#DIOFLAG ; pointer to the command by
-0415: F6 mov @r0,a ; set the command byte
-0416: 80 00 sjmp over_da
-
- ;;; more things here to come...
-
+046E: 90 F4 01 mov dptr,#0f401h ; FIFO buffer of EP4
+0471: E0 movx a,@dptr ; get the second by
+0472: F5 B3 mov OEB,a ; output enable
+0474: A3 inc dptr ; next byte
+0475: E0 movx a,@dptr ; bits
+0476: F5 90 mov IOB,a ; send the byte to the I/O
+
+0478: 12 03 B2 lcall reset_ep8 ; reset FIFO of ep 8
+
+ ;; fill ep8 with new data from port B
+ ;; When the host requests the data it's already the
+ ;; This must be so. Otherwise the ISR is not called
+ ;; The ISR is only called when a packet has been de
+ ;; to the host. Thus, we need a packet here in the
+ ;; first instance.
+047B: 12 05 0B lcall ep8_ops ; get digital data
+
+ ;;
+ ;; for all commands the same
over_da:
-0418: 90 E6 95 mov dptr,#EP4BCL
-041B: 74 80 mov a,#80h
-041D: F0 movx @DPTR,a ; arm it
-041E: F0 movx @DPTR,a ; arm it
-041F: F0 movx @DPTR,a ; arm it
+047E: 90 E6 95 mov dptr,#EP4BCL
+0481: 74 00 mov a,#00h
+0483: 12 05 B9 lcall syncdelaywr ; arm
+0486: 12 05 B9 lcall syncdelaywr ; arm
+0489: 12 05 B9 lcall syncdelaywr ; arm
;; clear INT2
-0420: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
-0422: C2 E4 clr acc.4
-0424: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
-
-0426: 90 E6 5F mov DPTR,#EPIRQ ;
-0429: 74 20 mov a,#00100000b ; clear the ep4irq
-042B: F0 movx @DPTR,a
-
-042C: D0 07 pop 07h
-042E: D0 06 pop 06h
-0430: D0 05 pop 05h
-0432: D0 04 pop 04h ; R4
-0434: D0 03 pop 03h ; R3
-0436: D0 02 pop 02h ; R2
-0438: D0 01 pop 01h ; R1
-043A: D0 00 pop 00h ; R0
-043C: D0 D0 pop psw
-043E: D0 E0 pop acc
-0440: D0 85 pop dph1
-0442: D0 84 pop dpl1
-0444: D0 83 pop dph
-0446: D0 82 pop dpl
-0448: D0 86 pop dps
-044A: 32 reti
+048C: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
+048E: C2 E4 clr acc.4
+0490: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
+
+0492: 90 E6 5F mov DPTR,#EPIRQ ;
+0495: 74 20 mov a,#00100000b ; clear the ep4irq
+0497: F0 movx @DPTR,a
+
+0498: D0 07 pop 07h
+049A: D0 06 pop 06h
+049C: D0 05 pop 05h
+049E: D0 04 pop 04h ; R4
+04A0: D0 03 pop 03h ; R3
+04A2: D0 02 pop 02h ; R2
+04A4: D0 01 pop 01h ; R1
+04A6: D0 00 pop 00h ; R0
+04A8: D0 D0 pop psw
+04AA: D0 E0 pop acc
+04AC: D0 85 pop dph1
+04AE: D0 84 pop dpl1
+04B0: D0 83 pop dph
+04B2: D0 82 pop dpl
+04B4: D0 86 pop dps
+04B6: 32 reti
;;; all channels
dalo:
-044B: E0 movx a,@dptr ; number of channel
-044C: A3 inc dptr ; pointer to the first chan
-044D: F8 mov r0,a ; 4 channels
+04B7: E0 movx a,@dptr ; number of channel
+04B8: A3 inc dptr ; pointer to the first chan
+04B9: F8 mov r0,a ; 4 channels
nextDA:
-044E: E0 movx a,@dptr ; get the first low
-044F: FB mov r3,a ; store in r3 (see below)
-0450: A3 inc dptr ; point to the high byte
-0451: E0 movx a,@dptr ; get the high byte
-0452: FC mov r4,a ; store in r4 (for writeDA)
-0453: A3 inc dptr ; point to the channel numb
-0454: E0 movx a,@dptr ; get the channel n
-0455: A3 inc dptr ; get ready for the next ch
-0456: 12 04 5C lcall writeDA ; write value to th
-0459: D8 F3 djnz r0,nextDA ; next channel
-045B: 22 ret
+04BA: E0 movx a,@dptr ; get the first low
+04BB: FB mov r3,a ; store in r3 (see below)
+04BC: A3 inc dptr ; point to the high byte
+04BD: E0 movx a,@dptr ; get the high byte
+04BE: FC mov r4,a ; store in r4 (for writeDA)
+04BF: A3 inc dptr ; point to the channel numb
+04C0: E0 movx a,@dptr ; get the channel n
+04C1: A3 inc dptr ; get ready for the next ch
+04C2: 12 04 C8 lcall writeDA ; write value to th
+04C5: D8 F3 djnz r0,nextDA ; next channel
+04C7: 22 ret
;;; control-byte in a,
;;; value in r3(low) and r4(high)
writeDA: ; mask the control byte
-045C: 54 C0 anl a,#11000000b ; only the channel is left
-045E: 44 30 orl a,#00110000b ; internal clock, bipolar m
-0460: 4C orl a,r4 ; or the value of R4 to it
+04C8: 54 C0 anl a,#11000000b ; only the channel is left
+04CA: 44 30 orl a,#00110000b ; internal clock, bipolar m
+04CC: 4C orl a,r4 ; or the value of R4 to it
;; set CS to low
-0461: C2 85 clr IOA.5 ; set /CS to zero
+04CD: C2 85 clr IOA.5 ; set /CS to zero
;; send the first byte to the DA-converter
-0463: 7A 08 mov R2,#8 ; bit-counter
-0465: 30 E7 04 DA1: jnb ACC.7,zeroda ; jump if Bit7 = 0?
-0468: D2 82 setb IOA.2 ; set the DIN bit
-046A: 80 02 sjmp clkda ; continue with the clock
-046C: C2 82 zeroda: clr IOA.2 ; clear the DIN bit
-046E: D2 80 clkda: setb IOA.0 ; SCLK = 1
-0470: C2 80 clr IOA.0 ; SCLK = 0
-0472: 23 rl a ; next Bit
-0473: DA F0 djnz R2,DA1
+04CF: 7A 08 mov R2,#8 ; bit-counter
+04D1: 30 E7 04 DA1: jnb ACC.7,zeroda ; jump if Bit7 = 0?
+04D4: D2 82 setb IOA.2 ; set the DIN bit
+04D6: 80 02 sjmp clkda ; continue with the clock
+04D8: C2 82 zeroda: clr IOA.2 ; clear the DIN bit
+04DA: D2 80 clkda: setb IOA.0 ; SCLK = 1
+04DC: C2 80 clr IOA.0 ; SCLK = 0
+04DE: 23 rl a ; next Bit
+04DF: DA F0 djnz R2,DA1
;; send the second byte to the DA-converter
-0475: EB mov a,r3 ; low byte
-0476: 7A 08 mov R2,#8 ; bit-counter
-0478: 30 E7 04 DA2: jnb ACC.7,zeroda2 ; jump if Bit7 = 0?
-047B: D2 82 setb IOA.2 ; set the DIN bit
-047D: 80 02 sjmp clkda2 ; continue with the clock
-047F: C2 82 zeroda2:clr IOA.2 ; clear the DIN bit
-0481: D2 80 clkda2: setb IOA.0 ; SCLK = 1
-0483: C2 80 clr IOA.0 ; SCLK = 0
-0485: 23 rl a ; next Bit
-0486: DA F0 djnz R2,DA2
+04E1: EB mov a,r3 ; low byte
+04E2: 7A 08 mov R2,#8 ; bit-counter
+04E4: 30 E7 04 DA2: jnb ACC.7,zeroda2 ; jump if Bit7 = 0?
+04E7: D2 82 setb IOA.2 ; set the DIN bit
+04E9: 80 02 sjmp clkda2 ; continue with the clock
+04EB: C2 82 zeroda2:clr IOA.2 ; clear the DIN bit
+04ED: D2 80 clkda2: setb IOA.0 ; SCLK = 1
+04EF: C2 80 clr IOA.0 ; SCLK = 0
+04F1: 23 rl a ; next Bit
+04F2: DA F0 djnz R2,DA2
;;
-0488: D2 85 setb IOA.5 ; set /CS to one
+04F4: D2 85 setb IOA.5 ; set /CS to one
;;
-048A: 22 noDA: ret
+04F6: 22 noDA: ret
;;; arm ep6
ep6_arm:
-048B: 12 02 1E lcall convlo
+04F7: 12 02 3E lcall conv_ad
-048E: 90 E6 98 mov DPTR,#EP6BCH ; byte count H
-0491: 74 00 mov a,#0 ; is zero
-0493: F0 movx @DPTR,a
+04FA: 90 E6 98 mov DPTR,#EP6BCH ; byte count H
+04FD: 74 00 mov a,#0 ; is zero
+04FF: 12 05 B9 lcall syncdelaywr ; wait until the length has
-0494: 90 E6 99 mov DPTR,#EP6BCL ; byte count L
-0497: 74 10 mov a,#10H ; is one
-0499: F0 movx @DPTR,a
-049A: 22 ret
+0502: 90 E6 99 mov DPTR,#EP6BCL ; byte count L
+0505: 74 10 mov a,#10H ; is one
+0507: 12 05 B9 lcall syncdelaywr ; wait until the length has
+050A: 22 ret
-
- ;;; get all 8 channels in the high speed mode
- ep6_isr:
-049B: C0 86 push dps
-049D: C0 82 push dpl
-049F: C0 83 push dph
-04A1: C0 84 push dpl1
-04A3: C0 85 push dph1
-04A5: C0 E0 push acc
-04A7: C0 D0 push psw
-04A9: C0 00 push 00h ; R0
-04AB: C0 01 push 01h ; R1
-04AD: C0 02 push 02h ; R2
-04AF: C0 03 push 03h ; R3
-04B1: C0 04 push 04h ; R4
-04B3: C0 05 push 05h ; R5
-04B5: C0 06 push 06h ; R6
-04B7: C0 07 push 07h ; R7
-
-04B9: 12 02 1E lcall convlo ; conversion
-04BC: 90 E6 98 mov DPTR,#EP6BCH ; byte count H
-04BF: 74 00 mov a,#0 ; is zero
-04C1: F0 movx @DPTR,a
-
-04C2: 90 E6 99 mov DPTR,#EP6BCL ; byte count L
-04C5: 74 10 mov a,#10H ; is 8x word = 16 bytes
-04C7: F0 movx @DPTR,a
+ ;;; converts one analog/digital channel and stores it in EP8
+ ;;; also gets the content of the digital ports B and D depen
+ ;;; the COMMAND flag
+ ep8_ops:
+050B: 90 FC 01 mov dptr,#0fc01h ; ep8 fifo buffer
+050E: E4 clr a ; high byte
+050F: F0 movx @dptr,a ; set H=0
+0510: 90 FC 00 mov dptr,#0fc00h ; low byte
+0513: 78 90 mov r0,#CMD_FLAG
+0515: E6 mov a,@r0
+0516: F0 movx @dptr,a ; save command byte
+
+0517: 90 05 1C mov dptr,#ep8_jmp ; jump table for the differ
+051A: 23 rl a ; multiply by 2: sizeof sjm
+051B: 73 jmp @a+dptr ; jump to the jump
+ ;; jump table, corresponds to the command bytes def
+ ;; in usbdux.c
+ ep8_jmp:
+051C: 80 44 sjmp ep8_err ; a=0, err
+051E: 80 42 sjmp ep8_err ; a=1, err
+0520: 80 40 sjmp ep8_err ; a=2, err
+0522: 80 25 sjmp ep8_dio ; a=3, digital read
+0524: 80 13 sjmp ep8_sglchannel ; a=4, analog A/D
+0526: 80 02 sjmp ep8_readctr ; a=5, read counter
+0528: 80 38 sjmp ep8_err ; a=6, write counte
+
+ ;; reads all counters
+ ep8_readctr:
+052A: 78 A0 mov r0,#CTR0 ; points to counter0
+052C: 90 FC 02 mov dptr,#0fc02h ; ep8 fifo buffer
+052F: 79 08 mov r1,#8 ; transfer 4 16bit counters
+ ep8_ctrlp:
+0531: E6 mov a,@r0 ; get the counter
+0532: F0 movx @dptr,a ; save in the fifo
+0533: 08 inc r0 ; inc pointer to the counte
+0534: A3 inc dptr ; inc pointer to the fifo b
+0535: D9 FA djnz r1,ep8_ctrlp ; loop until ready
- ;; clear INT2
-04C8: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
-04CA: C2 E4 clr acc.4
-04CC: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
-
-04CE: 90 E6 5F mov DPTR,#EPIRQ ;
-04D1: 74 40 mov a,#01000000b ; clear the ep6irq
-04D3: F0 movx @DPTR,a
-
-04D4: D0 07 pop 07h
-04D6: D0 06 pop 06h
-04D8: D0 05 pop 05h
-04DA: D0 04 pop 04h ; R4
-04DC: D0 03 pop 03h ; R3
-04DE: D0 02 pop 02h ; R2
-04E0: D0 01 pop 01h ; R1
-04E2: D0 00 pop 00h ; R0
-04E4: D0 D0 pop psw
-04E6: D0 E0 pop acc
-04E8: D0 85 pop dph1
-04EA: D0 84 pop dpl1
-04EC: D0 83 pop dph
-04EE: D0 82 pop dpl
-04F0: D0 86 pop dps
-04F2: 32 reti
-
-
+0537: 80 19 sjmp ep8_send ; send the data
- ;;; converts one analog/digital channel and stores it in EP8
- ;;; also gets the content of the digital ports B and D
- ep8_adc:
-04F3: 78 90 mov r0,#DIOFLAG ; pointer to the DIO flag
-04F5: E6 mov a,@r0 ; get the flag
-04F6: 70 10 jnz ep8_dio ; nonzero means DIO
-
-04F8: 78 80 mov r0,#CHANNELLIST ; points to the cha
-04FA: E6 mov a,@r0 ; Ch0
+ ;; read one A/D channel
+ ep8_sglchannel:
+0539: 78 91 mov r0,#SGLCHANNEL ; points to the channel
+053B: E6 mov a,@r0 ; Ch0
-04FB: 12 01 CB lcall readAD ; start the conversion
+053C: 12 01 EB lcall readAD ; start the conversion
-04FE: 90 FC 00 mov DPTR,#0fc00h ; EP8 FIFO
-0501: EB mov a,R3 ; get low byte
-0502: F0 movx @DPTR,A ; store in FIFO
-0503: A3 inc dptr ; next fifo entry
-0504: EC mov a,R4 ; get high byte
-0505: F0 movx @DPTR,A ; store in FIFO
+053F: 90 FC 02 mov DPTR,#0fc02h ; EP8 FIFO
+0542: EB mov a,R3 ; get low byte
+0543: F0 movx @DPTR,A ; store in FIFO
+0544: A3 inc dptr ; next fifo entry
+0545: EC mov a,R4 ; get high byte
+0546: F0 movx @DPTR,A ; store in FIFO
-0506: 80 09 sjmp ep8_send ; send the data
+0547: 80 09 sjmp ep8_send ; send the data
+ ;; read the digital lines
ep8_dio:
-0508: 90 FC 00 mov DPTR,#0fc00h ; store the contents of por
-050B: E5 90 mov a,IOB ; in the next
-050D: F0 movx @dptr,a ; entry of the buff
+0549: 90 FC 02 mov DPTR,#0fc02h ; store the contents of por
+054C: E5 90 mov a,IOB ; in the next
+054E: F0 movx @dptr,a ; entry of the buff
-050E: A3 inc dptr
-050F: E4 clr a ; high byte is zero
-0510: F0 movx @dptr,a ; next byte of the
+054F: A3 inc dptr
+0550: E4 clr a ; high byte is zero
+0551: F0 movx @dptr,a ; next byte of the
ep8_send:
-0511: 90 E6 9C mov DPTR,#EP8BCH ; byte count H
-0514: 74 00 mov a,#0 ; is zero
-0516: F0 movx @DPTR,a
+0552: 90 E6 9C mov DPTR,#EP8BCH ; byte count H
+0555: 74 00 mov a,#0 ; is zero
+0557: 12 05 B9 lcall syncdelaywr
-0517: 90 E6 9D mov DPTR,#EP8BCL ; byte count L
-051A: 74 10 mov a,#10H ; 16 bytes
-051C: F0 movx @DPTR,a ; send the data ove
-051D: 22 ret
+055A: 90 E6 9D mov DPTR,#EP8BCL ; byte count L
+055D: 74 10 mov a,#10H ; 16 bytes
+055F: 12 05 B9 lcall syncdelaywr ; send the data over to the
-
-
- ;;; arms EP8 with one byte. This signals the Linux driver th
- ;;; the EP has been armed only with a dummy byte to make the
- ;;; IRQ work. The byte is not processed by the driver.
- ep8_arm:
-051E: 90 E6 9C mov DPTR,#EP8BCH ; byte count H
-0521: 74 00 mov a,#0 ; is zero
-0523: F0 movx @DPTR,a
-
-0524: 90 E6 9D mov DPTR,#EP8BCL ; byte count L
-0527: 74 01 mov a,#1 ; 1 byte
-0529: F0 movx @DPTR,a
-052A: 22 ret
+ ep8_err:
+0562: 22 ret
;;; sends it via EP8. The channel # is stored in address 80H
;;; It also gets the state of the digital registers B and D.
ep8_isr:
-052B: C0 86 push dps
-052D: C0 82 push dpl
-052F: C0 83 push dph
-0531: C0 84 push dpl1
-0533: C0 85 push dph1
-0535: C0 E0 push acc
-0537: C0 D0 push psw
-0539: C0 00 push 00h ; R0
-053B: C0 01 push 01h ; R1
-053D: C0 02 push 02h ; R2
-053F: C0 03 push 03h ; R3
-0541: C0 04 push 04h ; R4
-0543: C0 05 push 05h ; R5
-0545: C0 06 push 06h ; R6
-0547: C0 07 push 07h ; R7
+0563: C0 86 push dps
+0565: C0 82 push dpl
+0567: C0 83 push dph
+0569: C0 84 push dpl1
+056B: C0 85 push dph1
+056D: C0 E0 push acc
+056F: C0 D0 push psw
+0571: C0 00 push 00h ; R0
+0573: C0 01 push 01h ; R1
+0575: C0 02 push 02h ; R2
+0577: C0 03 push 03h ; R3
+0579: C0 04 push 04h ; R4
+057B: C0 05 push 05h ; R5
+057D: C0 06 push 06h ; R6
+057F: C0 07 push 07h ; R7
-0549: 12 04 F3 lcall ep8_adc
+0581: 12 05 0B lcall ep8_ops
;; clear INT2
-054C: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
-054E: C2 E4 clr acc.4
-0550: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
-
-0552: 90 E6 5F mov DPTR,#EPIRQ ;
-0555: 74 80 mov a,#10000000b ; clear the ep8irq
-0557: F0 movx @DPTR,a
-
-0558: D0 07 pop 07h
-055A: D0 06 pop 06h
-055C: D0 05 pop 05h
-055E: D0 04 pop 04h ; R4
-0560: D0 03 pop 03h ; R3
-0562: D0 02 pop 02h ; R2
-0564: D0 01 pop 01h ; R1
-0566: D0 00 pop 00h ; R0
-0568: D0 D0 pop psw
-056A: D0 E0 pop acc
-056C: D0 85 pop dph1
-056E: D0 84 pop dpl1
-0570: D0 83 pop dph
-0572: D0 82 pop dpl
-0574: D0 86 pop dps
-0576: 32 reti
-
-
-
-
-
-
- ;;; high speed mode, IRQ mode. Asynchronous transmission.
- ep2_isr:
-0577: C0 86 push dps
-0579: C0 82 push dpl
-057B: C0 83 push dph
-057D: C0 84 push dpl1
-057F: C0 85 push dph1
-0581: C0 E0 push acc
-0583: C0 D0 push psw
-0585: C0 00 push 00h ; R0
-0587: C0 01 push 01h ; R1
-0589: C0 02 push 02h ; R2
-058B: C0 03 push 03h ; R3
-058D: C0 04 push 04h ; R4
-058F: C0 05 push 05h ; R5
-0591: C0 06 push 06h ; R6
-0593: C0 07 push 07h ; R7
-
-0595: 90 F0 00 mov dptr,#0F000H ; EP2 fifo buffer
-0598: 12 04 4B lcall dalo ; conversion
-
-059B: 90 E6 91 mov dptr,#EP2BCL ; "arm" it
-059E: 74 80 mov a,#80h
-05A0: F0 movx @DPTR,a ; can receive data
-05A1: F0 movx @dptr,a
-
- ;; clear INT2
-05A2: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
-05A4: C2 E4 clr acc.4
-05A6: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
-
-05A8: 90 E6 5F mov DPTR,#EPIRQ ; points to the usbirq
-05AB: 74 10 mov a,#00010000b ; clear the usbirq of ep 2
-05AD: F0 movx @DPTR,a
-
-05AE: D0 07 pop 07h
-05B0: D0 06 pop 06h
-05B2: D0 05 pop 05h
-05B4: D0 04 pop 04h ; R4
-05B6: D0 03 pop 03h ; R3
-05B8: D0 02 pop 02h ; R2
-05BA: D0 01 pop 01h ; R1
-05BC: D0 00 pop 00h ; R0
-05BE: D0 D0 pop psw
-05C0: D0 E0 pop acc
-05C2: D0 85 pop dph1
-05C4: D0 84 pop dpl1
-05C6: D0 83 pop dph
-05C8: D0 82 pop dpl
-05CA: D0 86 pop dps
-05CC: 32 reti
-
-
-
-
-
-
-
-
-
-05CD: .End
+0584: E5 91 mov a,EXIF ; FIRST clear the USB (INT2
+0586: C2 E4 clr acc.4
+0588: F5 91 mov EXIF,a ; Note: EXIF reg is not 805
+
+058A: 90 E6 5F mov DPTR,#EPIRQ ;
+058D: 74 80 mov a,#10000000b ; clear the ep8irq
+058F: F0 movx @DPTR,a
+
+0590: D0 07 pop 07h
+0592: D0 06 pop 06h
+0594: D0 05 pop 05h
+0596: D0 04 pop 04h ; R4
+0598: D0 03 pop 03h ; R3
+059A: D0 02 pop 02h ; R2
+059C: D0 01 pop 01h ; R1
+059E: D0 00 pop 00h ; R0
+05A0: D0 D0 pop psw
+05A2: D0 E0 pop acc
+05A4: D0 85 pop dph1
+05A6: D0 84 pop dpl1
+05A8: D0 83 pop dph
+05AA: D0 82 pop dpl
+05AC: D0 86 pop dps
+05AE: 32 reti
+
+
+ ;; need to delay every time the byte counters
+ ;; for the EPs have been changed.
+
+ syncdelay:
+05AF: 00 nop
+05B0: 00 nop
+05B1: 00 nop
+05B2: 00 nop
+05B3: 00 nop
+05B4: 00 nop
+05B5: 00 nop
+05B6: 00 nop
+05B7: 00 nop
+05B8: 22 ret
+
+ syncdelaywr:
+05B9: F0 movx @dptr,a
+05BA: 12 05 AF lcall syncdelay
+05BD: 22 ret
+
+
+05BE: .End