+++ /dev/null
- ; usbdux_firmware.asm
- ; 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
- ; the Free Software Foundation; either version 2 of the Li
- ; (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be
- ; but WITHOUT ANY WARRANTY; without even the implied warra
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Publi
- ; along with this program; if not, write to the Free Softw
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
- ;
- ;
- ; 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@f2s.com>
- ; Updated: 18 Aug 2004
- ; Status: testing
- ;
- ;;;
- ;;;
- ;;;
-
- ; rev 0.9
- ; (c) Bernd Porr, Bernd.Porr@cn.stir.ac.uk
- ; GPL, GNU public license
- ;
- ; This program is free software; you can redistribute it a
- ; it under the terms of the GNU General Public License as
- ; the Free Software Foundation; either version 2 of the Li
- ; (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be
- ; but WITHOUT ANY WARRANTY; without even the implied warra
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Publi
- ; along with this program; if not, write to the Free Softw
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
- ;
- ; In conjunction with the as31.
- ; Include-file for the FX2 by Cypress. The rest of the regs
- ; by the as31 itself.
- ;
- ; from the TRM of the FX2:
- ;
- ;; CPU control
-0000: .equ CPUCS,0E600H
-0000: .equ REVCTL,0E60BH
- ;; interface config
-0000: .equ IFCONFIG,0E601H
-0000: .equ FIFORESET,0E604H
- ;; Endpoint configs
-0000: .equ EP1OUTCFG,0E610H
-0000: .equ EP1INCFG,0E611H
-0000: .equ EP2CFG,0E612H
-0000: .equ EP4CFG,0E613H
-0000: .equ EP6CFG,0E614H
-0000: .equ EP8CFG,0E615H
- ;; packets per frame, always one for USB 1.1
-0000: .equ EP2ISOINPKTS,0E640H
-0000: .equ EP4ISOINPKTS,0E641H
-0000: .equ EP6ISOINPKTS,0E642H
-0000: .equ EP8ISOINPKTS,0E643H
- ;; endpoint byte counts
-0000: .equ EP1OUTBC,0E68DH
-0000: .equ EP2BCH,0E690H
-0000: .equ EP2BCL,0E691H
-0000: .equ EP4BCH,0E694H
-0000: .equ EP4BCL,0E695H
-0000: .equ EP6BCH,0E698H
-0000: .equ EP6BCL,0E699H
-0000: .equ EP8BCH,0E69CH
-0000: .equ EP8BCL,0E69DH
- ;;
-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 EP4CS,0E6A4H
-0000: .equ EP6CS,0E6A5H
-0000: .equ EP8CS,0E6A6H
- ;; endpoint buffers
-0000: .equ EP2FIFOBUF,0F000H
-0000: .equ EP4FIFOBUF,0F400H
-0000: .equ EP6FIFOBUF,0F800H
-0000: .equ EP8FIFOBUF,0FC00H
- ;; IRQ enable for bulk NAK
-0000: .equ IBNIE,0E658H
- ;; interrupt requ for NAK
-0000: .equ IBNIRQ,0E659H
- ;; USB INT enables
-0000: .equ USBIE,0E65CH
- ;; USB interrupt request
-0000: .equ USBIRQ,0E65DH
- ;; endpoint IRQ enable
-0000: .equ EPIE,0E65EH
- ;; endpoint IRQ requests
-0000: .equ EPIRQ,0E65FH
- ;; USB error IRQ requests
-0000: .equ USBERRIE,0E662H
- ;; USB error IRQ request
-0000: .equ USBERRIRQ,0E663H
- ;; USB interrupt 2 autovector
-0000: .equ INT2IVEC,0E666H
- ;; autovector enable
-0000: .equ INTSETUP,0E668H
- ;; port cfg
-0000: .equ PORTACFG,0E670H
-0000: .equ PORTCCFG,0E671H
-0000: .equ PORTECFG,0E672H
- ;; I2C bus
-0000: .equ I2CS,0E678H
-0000: .equ I2DAT,0E679H
-0000: .equ I2CTL,0E67AH
- ;; auto pointers, read/write is directed to the poi
-0000: .equ XAUTODAT1,0E67BH
-0000: .equ XAUTODAT2,0E67CH
- ;; USB-control
-0000: .equ USBCS,0E680H
-
-0000: .equ IOA,80H
-0000: .equ DPL1,84H
-0000: .equ DPH1,85H
-0000: .equ DPS,86H
-0000: .equ CKCON,8Eh
-0000: .equ IOB,90H
-0000: .equ EXIF,91h
-0000: .equ MPAGE,92h
-0000: .equ AUTOPTRH1,9AH
-0000: .equ AUTOPTRL1,9BH
-0000: .equ AUTOPTRH2,9DH
-0000: .equ AUTOPTRL2,9EH
-0000: .equ IOC,0A0H
-0000: .equ INT2CLR,0A1H
-0000: .equ INT4CLR,0A2H
-0000: .equ EP2468STAT,0AAH
-0000: .equ EP24FIFOFLGS,0ABH
-0000: .equ EP68FIFOFLGS,0ACH
-0000: .equ AUTOPTRSETUP,0AFH
-0000: .equ IOD,0B0H
-0000: .equ IOE,0B1H
-0000: .equ OEA,0B2H
-0000: .equ OEB,0B3H
-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 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: .org 0100h ; start of the jump table
-
-0100: 02 01 7F jmptbl: ljmp sudav_isr
-0103: 00 nop
-0104: 02 03 39 ljmp sof_isr
-0107: 00 nop
-0108: 02 01 7F ljmp sutok_isr
-010B: 00 nop
-010C: 02 01 7F ljmp suspend_isr
-010F: 00 nop
-0110: 02 01 7F ljmp usbreset_isr
-0113: 00 nop
-0114: 02 01 7F ljmp hispeed_isr
-0117: 00 nop
-0118: 02 01 7F ljmp ep0ack_isr
-011B: 00 nop
-011C: 02 01 7F ljmp spare_isr
-011F: 00 nop
-0120: 02 01 7F ljmp ep0in_isr
-0123: 00 nop
-0124: 02 01 7F ljmp ep0out_isr
-0127: 00 nop
-0128: 02 01 7F ljmp ep1in_isr
-012B: 00 nop
-012C: 02 01 7F ljmp ep1out_isr
-012F: 00 nop
-0130: 02 01 7F ljmp ep2_isr
-0133: 00 nop
-0134: 02 03 E4 ljmp ep4_isr
-0137: 00 nop
-0138: 02 01 7F ljmp ep6_isr
-013B: 00 nop
-013C: 02 05 63 ljmp ep8_isr
-013F: 00 nop
-0140: 02 01 7F ljmp ibn_isr
-0143: 00 nop
-0144: 02 01 7F ljmp spare_isr
-0147: 00 nop
-0148: 02 01 7F ljmp ep0ping_isr
-014B: 00 nop
-014C: 02 01 7F ljmp ep1ping_isr
-014F: 00 nop
-0150: 02 01 7F ljmp ep2ping_isr
-0153: 00 nop
-0154: 02 01 7F ljmp ep4ping_isr
-0157: 00 nop
-0158: 02 01 7F ljmp ep6ping_isr
-015B: 00 nop
-015C: 02 01 7F ljmp ep8ping_isr
-015F: 00 nop
-0160: 02 01 7F ljmp errlimit_isr
-0163: 00 nop
-0164: 02 01 7F ljmp spare_isr
-0167: 00 nop
-0168: 02 01 7F ljmp spare_isr
-016B: 00 nop
-016C: 02 01 7F ljmp spare_isr
-016F: 00 nop
-0170: 02 01 7F ljmp ep2isoerr_isr
-0173: 00 nop
-0174: 02 01 7F ljmp ep4isoerr_isr
-0177: 00 nop
-0178: 02 01 7F ljmp ep6isoerr_isr
-017B: 00 nop
-017C: 02 01 7F ljmp ep8isoerr_isr
-
-
- ;; dummy isr
- sudav_isr:
- sutok_isr:
- suspend_isr:
- usbreset_isr:
- hispeed_isr:
- ep0ack_isr:
- spare_isr:
- ep0in_isr:
- ep0out_isr:
- ep1in_isr:
- ep1out_isr:
- ibn_isr:
- ep0ping_isr:
- ep1ping_isr:
- ep2ping_isr:
- ep4ping_isr:
- ep6ping_isr:
- ep8ping_isr:
- errlimit_isr:
- ep2isoerr_isr:
- ep4isoerr_isr:
- ep6isoerr_isr:
- ep8isoerr_isr:
- ep6_isr:
- ep2_isr:
-
-
-017F: C0 86 push dps
-0181: C0 82 push dpl
-0183: C0 83 push dph
-0185: C0 84 push dpl1
-0187: C0 85 push dph1
-0189: C0 E0 push acc
-018B: C0 D0 push psw
-
- ;; clear the USB2 irq bit and return
-018D: E5 91 mov a,EXIF
-018F: C2 E4 clr acc.4
-0191: F5 91 mov EXIF,a
-
-0193: D0 D0 pop psw
-0195: D0 E0 pop acc
-0197: D0 85 pop dph1
-0199: D0 84 pop dpl1
-019B: D0 83 pop dph
-019D: D0 82 pop dpl
-019F: D0 86 pop dps
-
-01A1: 32 reti
-
-
- ;;; main program
- ;;; basically only initialises the processor and
- ;;; then engages in an endless loop
- main:
-01A2: 90 E6 00 mov DPTR,#CPUCS ; CPU control register
-01A5: 74 10 mov a,#00010000b ; 48Mhz
-01A7: 12 05 B9 lcall syncdelaywr
-
-01AA: 90 E6 0B mov dptr,#REVCTL
-01AD: 74 03 mov a,#00000011b ; allows skip
-01AF: 12 05 B9 lcall syncdelaywr
-
-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
-
-01C0: 12 01 D2 lcall initAD ; init the ports to the con
-
-01C3: 12 02 5A lcall initeps ; init the isochron
-
-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
-
-01D0: 80 F7 sjmp mloop2 ; loop for ever
-
-
- ;;; initialise the ports for the AD-converter
- initAD:
-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...
-
- ;;; A/D-conversion:
- ;;; control-byte in a,
- ;;; result in r3(low) and r4(high)
- ;;; this routine is optimised for speed
- readAD: ; mask the control byte
-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
-01EF: C2 81 clr IOA.1 ; set /CS to zero
- ;; send the control byte to the AD-converter
-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)
-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
-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
-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
-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
-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
- ;;
-023D: 22 ret
-
-
-
- ;;; 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
-
-0249: E6 mov a,@r0 ; number of channels
-024A: F9 mov r1,a ; counter
-
-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
-
-0259: 22 ret
-
-
-
-
- ;;; 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
-
-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
-
-028C: 90 E6 13 mov DPTR,#EP4CFG
-028F: 74 A0 mov a,#10100000b ; valid
-0291: F0 movx @dptr,a
-
-0292: 90 E6 19 mov dptr,#EP4FIFOCFG
-0295: 74 00 mov a,#00000000b ; manual
-0297: 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
-
-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
-
-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:
-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
-
-0357: E5 AA mov a,EP2468STAT
-0359: 54 20 anl a,#20H ; full?
-035B: 70 13 jnz epfull ; EP6-buffer is full
-
-035D: 12 02 3E lcall conv_ad ; conversion
-
-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
-
-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
-0370: E5 AA mov a,EP2468STAT
-0372: 54 01 anl a,#01H ; empty
-0374: 70 11 jnz epempty ; nothing to get
-
-0376: 90 F0 00 mov dptr,#0F000H ; EP2 fifo buffer
-0379: 12 04 B7 lcall dalo ; conversion
-
-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
-
- epempty:
- ;; clear INT2
-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
-
-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:
-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:
-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
-
-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:
-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:
- ;;; the first byte is zero:
- ;;; we've just received the channel list
- ;;; the channel list is stored in the addresses from CHANNEL
- ;;; are _only_ reachable by indirect addressing
- storechannellist:
-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:
-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:
-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 as input or output (bitwise)
- config_digital_b:
-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:
-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:
-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
-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:
-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:
-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
-
-
-
- ;;; D/A-conversion:
- ;;; control-byte in a,
- ;;; value in r3(low) and r4(high)
- writeDA: ; mask the control byte
-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
-04CD: C2 85 clr IOA.5 ; set /CS to zero
- ;; send the first byte to the DA-converter
-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
-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
- ;;
-04F4: D2 85 setb IOA.5 ; set /CS to one
- ;;
-04F6: 22 noDA: ret
-
-
-
- ;;; arm ep6
- ep6_arm:
-04F7: 12 02 3E lcall conv_ad
-
-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
-
-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
-
-
-
- ;;; 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
-
-0537: 80 19 sjmp ep8_send ; send the data
-
- ;; read one A/D channel
- ep8_sglchannel:
-0539: 78 91 mov r0,#SGLCHANNEL ; points to the channel
-053B: E6 mov a,@r0 ; Ch0
-
-053C: 12 01 EB lcall readAD ; start the conversion
-
-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
-
-0547: 80 09 sjmp ep8_send ; send the data
-
- ;; read the digital lines
- ep8_dio:
-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
-
-054F: A3 inc dptr
-0550: E4 clr a ; high byte is zero
-0551: F0 movx @dptr,a ; next byte of the
-
- ep8_send:
-0552: 90 E6 9C mov DPTR,#EP8BCH ; byte count H
-0555: 74 00 mov a,#0 ; is zero
-0557: 12 05 B9 lcall syncdelaywr
-
-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
-
- ep8_err:
-0562: 22 ret
-
-
-
- ;;; EP8 interrupt: gets one measurement from the AD converte
- ;;; 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:
-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
-
-0581: 12 05 0B lcall ep8_ops
-
- ;; clear INT2
-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
-
-
-