From: Frank Mori Hess Date: Sun, 30 Nov 2003 15:41:14 +0000 (+0000) Subject: comedilib support for new usbdux driver X-Git-Tag: r0_7_22~116 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=e410cfda9c898495942c45673227e9f96d24faa5;p=comedilib.git comedilib support for new usbdux driver --- diff --git a/etc/Makefile.am b/etc/Makefile.am index c4ab91a..8f862e4 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1,5 +1,5 @@ -SUBDIRS = pcmcia +SUBDIRS = pcmcia hotplug pkgdata_DATA = das1600.conf dt282x.conf modules.conf diff --git a/etc/hotplug/Makefile.am b/etc/hotplug/Makefile.am new file mode 100644 index 0000000..feb8d0a --- /dev/null +++ b/etc/hotplug/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = usb diff --git a/etc/hotplug/usb/Makefile.am b/etc/hotplug/usb/Makefile.am new file mode 100644 index 0000000..88108a4 --- /dev/null +++ b/etc/hotplug/usb/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = usbdux + diff --git a/etc/hotplug/usb/usbdux/Makefile.am b/etc/hotplug/usb/usbdux/Makefile.am new file mode 100644 index 0000000..4a79249 --- /dev/null +++ b/etc/hotplug/usb/usbdux/Makefile.am @@ -0,0 +1,6 @@ + +usbhotplug_SCRIPTS = usbdux + +usbfirmware_DATA = usbdux_firmware.hex + +EXTRA_DIST = usbdux usbdux_firmware.hex diff --git a/etc/hotplug/usb/usbdux/Makefile_asm b/etc/hotplug/usb/usbdux/Makefile_asm new file mode 100644 index 0000000..d7310f5 --- /dev/null +++ b/etc/hotplug/usb/usbdux/Makefile_asm @@ -0,0 +1,27 @@ +# (c) Bernd Porr +# GNU public license +# no warranty +# + +all: as31 usbdux_firmware.hex + +as31: + make -C as31-2.1 + +#deprecated +usbdux_firmware.bin: fx2-include.asm usbdux_firmware.asm as31 + as31-2.1/as31 -Fbin usbdux_firmware.asm + +usbdux_firmware.hex: fx2-include.asm usbdux_firmware.asm as31 + as31-2.1/as31 -l usbdux_firmware.asm + +clean: + rm -f *.bin *~ *.lst *.bin *.hex + make -C as31-2.1 clean + +install: + mkdir -p /usr/share/usb/ + install usbdux_firmware.hex /usr/share/usb/usbdux_firmware.hex + mkdir -p /etc/hotplug/usb + install hotplug/usbdux /etc/hotplug/usb/usbdux + diff --git a/etc/hotplug/usb/usbdux/README b/etc/hotplug/usb/usbdux/README new file mode 100644 index 0000000..d87cb0d --- /dev/null +++ b/etc/hotplug/usb/usbdux/README @@ -0,0 +1,33 @@ +Remarks to the hotplug script "usbdux": +--------------------------------------- + +The script /etc/hotplug/usb/usbdux uploads the +firmware into the usb device after it has been +plugged in. + +It assumes that you have installed the firmware +under /usr/share/usb (recommended by the usb hotplug team) and that +usbdux shall be connected to comedi0. + +Please modify the script if needed. + + + +To compile the firmware: +------------------------ +Download the as31 from: + +http://www.cn.stir.ac.uk/linux-daq/as31/ + +(this is a patched version of as31 which supports an +include directive). + +Install it in this directory. + +Then run "make -f Makefile_asm". + + + +Feedback: +Bernd.Porr@cn.stir.ac.uk + diff --git a/etc/hotplug/usb/usbdux/fx2-include.asm b/etc/hotplug/usb/usbdux/fx2-include.asm new file mode 100644 index 0000000..8d79025 --- /dev/null +++ b/etc/hotplug/usb/usbdux/fx2-include.asm @@ -0,0 +1,136 @@ +; 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 and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; 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 is defined +; by the as31 itself. +; +; from the TRM of the FX2: +; + ;; CPU control + .equ CPUCS,0E600H + ;; interface config + .equ IFCONFIG,0E601H + .equ FIFORESET,0E604H + ;; Endpoint configs + .equ EP1OUTCFG,0E610H + .equ EP1INCFG,0E611H + .equ EP2CFG,0E612H + .equ EP4CFG,0E613H + .equ EP6CFG,0E614H + .equ EP8CFG,0E615H + ;; packets per frame, always one for USB 1.1 + .equ EP2ISOINPKTS,0E640H + .equ EP4ISOINPKTS,0E641H + .equ EP6ISOINPKTS,0E642H + .equ EP8ISOINPKTS,0E643H + ;; endpoint byte counts + .equ EP1OUTBC,0E68DH + .equ EP2BCH,0E690H + .equ EP2BCL,0E691H + .equ EP4BCH,0E694H + .equ EP4BCL,0E695H + .equ EP6BCH,0E698H + .equ EP6BCL,0E699H + .equ EP8BCH,0E69CH + .equ EP8BCL,0E69DH + ;; + .equ EP4AUTOINLENH,0E622H + .equ EP4AUTOINLENL,0E623H + .equ EP2FIFOCFG,0E618H + .equ EP4FIFOCFG,0E619H + .equ EP6FIFOCFG,0E61AH + .equ EP8FIFOCFG,0E61BH + ;; + .equ INPKTEND,0E648H + ;; + ;; endpoint control + .equ EP2CS,0E6A3H + .equ EP4CS,0E6A4H + .equ EP6CS,0E6A5H + .equ EP8CS,0E6A6H + ;; endpoint buffers + .equ EP2FIFOBUF,0F000H + .equ EP4FIFOBUF,0F400H + .equ EP6FIFOBUF,0F800H + .equ EP8FIFOBUF,0FC00H + ;; IRQ enable for bulk NAK + .equ IBNIE,0E658H + ;; interrupt requ for NAK + .equ IBNIRQ,0E659H + ;; USB INT enables + .equ USBIE,0E65CH + ;; USB interrupt request + .equ USBIRQ,0E65DH + ;; endpoint IRQ enable + .equ EPIE,0E65EH + ;; endpoint IRQ requests + .equ EPIRQ,0E65FH + ;; USB error IRQ requests + .equ USBERRIE,0E662H + ;; USB error IRQ request + .equ USBERRIRQ,0E663H + ;; USB interrupt 2 autovector + .equ INT2IVEC,0E666H + ;; autovector enable + .equ INTSETUP,0E668H + ;; port cfg + .equ PORTACFG,0E670H + .equ PORTCCFG,0E671H + .equ PORTECFG,0E672H + ;; I2C bus + .equ I2CS,0E678H + .equ I2DAT,0E679H + .equ I2CTL,0E67AH + ;; auto pointers, read/write is directed to the pointed address + .equ XAUTODAT1,0E67BH + .equ XAUTODAT2,0E67CH + ;; USB-control + .equ USBCS,0E680H + + .equ IOA,80H + .equ DPL1,84H + .equ DPH1,85H + .equ DPS,86H + .equ CKCON,8Eh + .equ IOB,90H + .equ EXIF,91h + .equ MPAGE,92h + .equ AUTOPTRH1,9AH + .equ AUTOPTRL1,9BH + .equ AUTOPTRH2,9DH + .equ AUTOPTRL2,9EH + .equ IOC,0A0H + .equ INT2CLR,0A1H + .equ INT4CLR,0A2H + .equ EP2468STAT,0AAH + .equ EP24FIFOFLGS,0ABH + .equ EP68FIFOFLGS,0ACH + .equ AUTOPTRSETUP,0AFH + .equ IOD,0B0H + .equ IOE,0B1H + .equ OEA,0B2H + .equ OEB,0B3H + .equ OEC,0B4H + .equ OED,0B5H + .equ OEE,0B6H + .equ EIE,0E8h + + + ;;; end of file + diff --git a/etc/hotplug/usb/usbdux/usbdux b/etc/hotplug/usb/usbdux/usbdux new file mode 100755 index 0000000..fd16b84 --- /dev/null +++ b/etc/hotplug/usb/usbdux/usbdux @@ -0,0 +1,38 @@ +#!/bin/sh +# +# hotplug script for USBDUX. Mon Oct 20 10:08:09 BST 2003. +# Bernd.Porr@cn.stir.ac.uk +# +# +# +#look for comedi config +COMEDI_CONFIG= +# +if [ -e /usr/local/sbin/comedi_config ]; then + COMEDI_CONFIG=/usr/local/sbin/comedi_config +fi +if [ -e /usr/sbin/comedi_config ]; then + COMEDI_CONFIG=/usr/sbin/comedi_config +fi +if [ -e /sbin/comedi_config ]; then + COMEDI_CONFIG=/sbin/comedi_config +fi +# +# +#look for the firmware +USBDUX_FIRMWARE= +if [ -e /usr/share/usb/usbdux_firmware.hex ]; then + USBDUX_FIRMWARE=/usr/share/usb/usbdux_firmware.hex +fi +if [ -e /usr/local/share/usb/usbdux_firmware.hex ]; then + USBDUX_FIRMWARE=/usr/local/share/usb/usbdux_firmware.hex +fi +# +# +# please modify if needed +# +echo "$COMEDI_CONFIG -i $USBDUX_FIRMWARE /dev/comedi0 usbdux" +$COMEDI_CONFIG -i $USBDUX_FIRMWARE /dev/comedi0 usbdux +# +# +# diff --git a/etc/hotplug/usb/usbdux/usbdux_firmware.asm b/etc/hotplug/usb/usbdux/usbdux_firmware.asm new file mode 100644 index 0000000..ea5a896 --- /dev/null +++ b/etc/hotplug/usb/usbdux/usbdux_firmware.asm @@ -0,0 +1,981 @@ +; usbdux_firmware.asm +; Copyright (C) 2003 Bernd Porr, Bernd.Porr@cn.stir.ac.uk +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +; +; +; Firmware: usbdux_firmware.asm for usbdux.c +; Description: University of Stirling USB DAQ & INCITE Technology Limited +; Devices: [ITL] USB-DUX (usbdux.o) +; Author: Bernd Porr +; Updated: Thu Oct 16 +; Status: testing +; +;;; +;;; +;;; + + .inc fx2-include.asm + + .equ CHANNELLIST,80h ; channellist in indirect memory + + .equ DIOFLAG,90h ; flag if next IN transf is DIO + + .org 0000h ; after reset the processor starts here + ljmp main ; jump to the main loop + + .org 0043h ; the IRQ2-vector + ljmp jmptbl ; irq service-routine + + .org 0100h ; start of the jump table + +jmptbl: ljmp sudav_isr + nop + ljmp sof_isr + nop + ljmp sutok_isr + nop + ljmp suspend_isr + nop + ljmp usbreset_isr + nop + ljmp hispeed_isr + nop + ljmp ep0ack_isr + nop + ljmp spare_isr + nop + ljmp ep0in_isr + nop + ljmp ep0out_isr + nop + ljmp ep1in_isr + nop + ljmp ep1out_isr + nop + ljmp ep2_isr + nop + ljmp ep4_isr + nop + ljmp ep6_isr + nop + ljmp ep8_isr + nop + ljmp ibn_isr + nop + ljmp spare_isr + nop + ljmp ep0ping_isr + nop + ljmp ep1ping_isr + nop + ljmp ep2ping_isr + nop + ljmp ep4ping_isr + nop + ljmp ep6ping_isr + nop + ljmp ep8ping_isr + nop + ljmp errlimit_isr + nop + ljmp spare_isr + nop + ljmp spare_isr + nop + ljmp spare_isr + nop + ljmp ep2isoerr_isr + nop + ljmp ep4isoerr_isr + nop + ljmp ep6isoerr_isr + nop + 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: + + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + push psw + + ;; clear the USB2 irq bit and return + mov a,EXIF + clr acc.4 + mov EXIF,a + + pop psw + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + + reti + + +;;; main program +;;; basically only initialises the processor and +;;; then engages in an endless loop +main: + mov DPTR,#CPUCS ; CPU control register + mov a,#000010100b ; 48MHz clock + movx @DPTR,a ; do it + + mov dptr,#INTSETUP ; IRQ setup register + mov a,#08h ; enable autovector + movx @DPTR,a ; do it + + lcall initAD ; init the ports to the converters + + mov dptr,#USBCS ; USB status + movx a,@dptr ; get it + anl a,#80H ; mask out high speed + + jnz inihi ; high speed + + lcall inieplo ; init the isochronous data-transfer + sjmp mloop2 +inihi: + lcall iniephi ; init the irq transfer + +mloop2: nop + + sjmp mloop2 ; do nothing. The rest is done by the IRQs + + +;;; initialise the ports for the AD-converter +initAD: + mov OEA,#27H ;PortA0,A1,A2,A5 Outputs + mov IOA,#22H ;/CS = 1, disable transfers to the converters + 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 + anl a,#01111100b ; only the channel, gain+pol are left + orl a,#10000001b ; start bit, external clock + ;; set CS to low + clr IOA.1 ; set /CS to zero + ;; send the control byte to the AD-converter + mov R2,#8 ; bit-counter +S1: jnb ACC.7,bitzero ; jump if Bit7 = 0? + setb IOA.2 ; set the DIN bit + sjmp clock ; continue with the clock +bitzero:clr IOA.2 ; clear the DIN bit +clock: setb IOA.0 ; SCLK = 1 + clr IOA.0 ; SCLK = 0 + rl a ; next Bit + djnz R2,S1 + + ;; continue the aquisition (already started) + clr IOA.2 ; clear the DIN bit + mov R2,#5 ; five steps for the aquision +clockaq:setb IOA.0 ; SCLK = 1 + clr IOA.0 ; SCLK = 0 + djnz R2,clockaq ; loop + + ;; read highbyte from the A/D-converter + ;; and do the conversion + mov r4,#0 ; Highbyte goes into R4 + mov R2,#4 ; COUNTER 4 data bits in the MSB + mov r5,#08h ; create bit-mask +gethi: ; loop get the 8 highest bits from MSB downw + setb IOA.0 ; SCLK = 1 + clr IOA.0 ; SCLK = 0 + mov a,IOA ; from port A + jnb ACC.4,zerob ; the in-bit is zero + mov a,r4 ; get the byte + orl a,r5 ; or the bit to the result + mov r4,a ; save it again in r4 +zerob: mov a,r5 ; get r5 in order to shift the mask + rr a ; rotate right + mov r5,a ; back to r5 + djnz R2,gethi + ;; read the lowbyte from the A/D-converter + mov r3,#0 ; Lowbyte goes into R3 + mov r2,#8 ; COUNTER 8 data-bits in the LSB + mov r5,#80h ; create bit-mask +getlo: ; loop get the 8 highest bits from MSB downw + setb IOA.0 ; SCLK = 1 + clr IOA.0 ; SCLK = 0 + mov a,IOA ; from port A + jnb ACC.4,zerob2 ; the in-bit is zero + mov a,r3 ; get the result-byte + orl a,r5 ; or the bit to the result + mov r3,a ; save it again in r4 +zerob2: mov a,r5 ; get r5 in order to shift the mask + rr a ; rotate right + mov r5,a ; back to r5 + djnz R2,getlo + setb IOA.1 ; set /CS to one + ;; + ret + + + +;;; aquires data from all 8 channels and stores it in the EP6 buffer +convlo: ;; + mov AUTOPTRH1,#0F8H ; EP6 + mov AUTOPTRL1,#00H + mov AUTOPTRSETUP,#7 + mov r0,#CHANNELLIST ; points to the channellist + mov a,@r0 ;Ch0 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 ; next channel + mov a,@r0 ;Ch1 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 + mov a,@r0 ;Ch2 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 + mov a,@r0 ;Ch3 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 + mov a,@r0 ;Ch4 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 + mov a,@r0 ;Ch5 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 + mov a,@r0 ;Ch6 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + + inc r0 + mov a,@r0 ;Ch7 + lcall readAD + mov a,R3 ; + mov DPTR,#XAUTODAT1 + movx @DPTR,A + mov a,R4 ; + movx @DPTR,A + ret + + + + +;;; initilise the transfer for full speed +;;; It is assumed that the USB interface is in alternate setting 3 +inieplo: + mov dptr,#FIFORESET + mov a,#0fh + movx @dptr,a ; reset all fifos + mov a,#00h + movx @dptr,a ; normal operat + + mov DPTR,#EP2CFG + mov a,#10010010b ; valid, out, double buff, iso + movx @DPTR,a + + mov dptr,#EP2FIFOCFG + mov a,#00000000b ; manual + movx @dptr,a + + mov dptr,#EP2BCL ; "arm" it + mov a,#80h + movx @DPTR,a ; can receive data + movx @DPTR,a ; can receive data + movx @DPTR,a ; can receive data + + mov DPTR,#EP4CFG + mov a,#10100000b ; valid + movx @dptr,a + + mov dptr,#EP4FIFOCFG + mov a,#00000000b ; manual + movx @dptr,a + + mov dptr,#EP4BCL ; "arm" it + mov a,#80h + movx @DPTR,a ; can receive data + movx @dptr,a ; make shure its really empty + + mov DPTR,#EP6CFG ; ISO data from here to the host + mov a,#11010010b ; Valid + movx @DPTR,a ; ISO transfer, double buffering + + mov DPTR,#EP8CFG ; EP8 + mov a,#11100000b ; BULK data from here to the host + movx @DPTR,a ; + + mov dptr,#EPIE ; interrupt enable + mov a,#10100000b ; enable irq for ep4,8 + movx @dptr,a ; do it + + mov dptr,#EPIRQ ; clear IRQs + mov a,#10100000b + movx @dptr,a + + ;; enable interrups + mov DPTR,#USBIE ; USB int enables register + mov a,#2 ; enables SOF (1ms/125us interrupt) + movx @DPTR,a ; + + mov EIE,#00000001b ; enable INT2 in the 8051's SFR + mov IE,#80h ; IE, enable all interrupts + + lcall ep8_arm ; + + ret + + +;;; initilise the IRQ transfer +iniephi: + mov dptr,#FIFORESET + mov a,#0fh + movx @dptr,a ; reset all fifos + mov a,#00h + movx @dptr,a ; normal operat + + mov DPTR,#EP2CFG + mov a,#10110010b ; valid, out, double buff, irq + movx @DPTR,a + + mov dptr,#EP2FIFOCFG + mov a,#00000000b ; manual + movx @dptr,a + + mov dptr,#EP2BCL ; "arm" it + mov a,#80h + movx @DPTR,a ; can receive data + movx @DPTR,a ; can receive data + movx @DPTR,a ; can receive data + + mov DPTR,#EP4CFG + mov a,#10100000b ; valid + movx @dptr,a + + mov dptr,#EP4FIFOCFG + mov a,#00000000b ; manual + movx @dptr,a + + mov dptr,#EP4BCL ; "arm" it + mov a,#80h + movx @DPTR,a ; can receive data + movx @dptr,a ; make shure its really empty + + mov DPTR,#EP6CFG ; IRQ data from here to the host + mov a,#11110010b ; Valid + movx @DPTR,a ; IRQ transfer, double buffering + + mov DPTR,#EP8CFG ; EP8 + mov a,#11100000b ; BULK data from here to the host + movx @DPTR,a ; + + mov dptr,#EPIE ; interrupt enable + mov a,#11110000b ; enable irq for ep2,ep4,ep6,ep8 + movx @dptr,a ; do it + + mov dptr,#EPIRQ + mov a,#11110000b ; clear irq bits + movx @dptr,a + + ;; enable interrups + mov DPTR,#USBIE ; USB int enables register + mov a,#0 ; disables SOF (1ms/125ms interrupt) + movx @DPTR,a ; + + mov EIE,#00000001b ; enable INT2 in the 8051's SFR + mov IE,#80h ; IE, enable all interrupts + + lcall ep8_arm ; put dummy data into ep8 + lcall ep6_arm ; put dummy data into ep6 + + ret + + + +;;; interrupt-routine for SOF +;;; is for full speed +sof_isr: + 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 dptr,#USBCS ; USB status + movx a,@dptr ; get it + anl a,#80H ; mask out high speed + + jnz hispeed ; do nothing here + + mov a,EP2468STAT + anl a,#20H ; full? + jnz epfull ; EP6-buffer is full + + lcall convlo ; conversion + + mov DPTR,#EP6BCH ; byte count H + mov a,#0 ; is zero + movx @DPTR,a + + mov DPTR,#EP6BCL ; byte count L + mov a,#10H ; is 8x word = 16 bytes + movx @DPTR,a + +epfull: + ;; do the D/A conversion + mov a,EP2468STAT + anl a,#01H ; empty + jnz epempty ; nothing to get + + mov dptr,#0F000H ; EP2 fifo buffer + lcall dalo ; conversion + + mov dptr,#EP2BCL ; "arm" it + mov a,#80h + movx @DPTR,a ; can receive data + movx @dptr,a + +hispeed: +epempty: + ;; clear INT2 + mov a,EXIF ; FIRST clear the USB (INT2) interrupt request + clr acc.4 + mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable + + mov DPTR,#USBIRQ ; points to the SOF + mov a,#2 ; clear the SOF + movx @DPTR,a + +nosof: + 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 + + + + + +;;; interrupt-routine for ep4 +;;; receives the channel list and other commands +ep4_isr: + 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 dptr,#0f400h ; FIFO buffer of EP4 + movx a,@dptr ; get the first byte + + mov dptr,#ep4_jmp ; jump table for the different functions + rl a ; multiply by 2: sizeof sjmp + jmp @a+dptr ; jump to the jump table +ep4_jmp: + sjmp storechannellist; a=0 + sjmp single_da ; a=1 + sjmp config_digital_b; a=2 + sjmp write_digital_b ; a=3 + + +;;; Channellist: +;;; the first byte is zero: +;;; we've just received the channel list +;;; the channel list is stored in the addresses from 80H which +;;; are _only_ reachable by indirect addressing +storechannellist: + mov r0,#CHANNELLIST ; the conversion bytes are now stored in 80h + mov r2,#8 ; counter + mov dptr,#0f401h ; FIFO buffer of EP4 +chanlloop: + movx a,@dptr ; + mov @r0,a + inc dptr + inc r0 + djnz r2,chanlloop + clr a ; announce analogue transaction + mov r0,#DIOFLAG ; pointer to the command byte + mov @r0,a ; set the command byte + sjmp over_da + +;;; Single DA conversion. The 2 bytes are in the FIFO buffer +single_da: + mov dptr,#0f401h ; FIFO buffer of EP4 + lcall dalo ; conversion + sjmp over_da + +;;; configure the port B +config_digital_b: + mov dptr,#0f401h ; FIFO buffer of EP4 + movx a,@dptr ; get the second byte + mov OEB,a ; set the output enable bits + sjmp over_da + +;;; Write one byte to the external digital port B +;;; and prepare for digital read +write_digital_b: + mov dptr,#0f401h ; FIFO buffer of EP4 + movx a,@dptr ; get the second byte + mov OEB,a ; output enable + inc dptr ; next byte + movx a,@dptr ; bits + mov IOB,a ; send the byte to the I/O port + mov a,#0ffh ; announce DIO transaction + mov r0,#DIOFLAG ; pointer to the command byte + mov @r0,a ; set the command byte + sjmp over_da + +;;; more things here to come... + +over_da: + mov dptr,#EP4BCL + mov a,#80h + movx @DPTR,a ; arm it + movx @DPTR,a ; arm it + movx @DPTR,a ; arm it + + ;; clear INT2 + mov a,EXIF ; FIRST clear the USB (INT2) interrupt request + clr acc.4 + mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable + + mov DPTR,#EPIRQ ; + mov a,#00100000b ; clear the ep4irq + movx @DPTR,a + + 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 + + + +;;; all channels +dalo: + movx a,@dptr ; number of channels + inc dptr ; pointer to the first channel + mov r0,a ; 4 channels +nextDA: + movx a,@dptr ; get the first low byte + mov r3,a ; store in r3 (see below) + inc dptr ; point to the high byte + movx a,@dptr ; get the high byte + mov r4,a ; store in r4 (for writeDA) + inc dptr ; point to the channel number + movx a,@dptr ; get the channel number + inc dptr ; get ready for the next channel + lcall writeDA ; write value to the DAC + djnz r0,nextDA ; next channel + ret + + + +;;; D/A-conversion: +;;; control-byte in a, +;;; value in r3(low) and r4(high) +writeDA: ; mask the control byte + anl a,#11000000b ; only the channel is left + orl a,#00110000b ; internal clock, bipolar mode, +/-5V + orl a,r4 ; or the value of R4 to it + ;; set CS to low + clr IOA.5 ; set /CS to zero + ;; send the first byte to the DA-converter + mov R2,#8 ; bit-counter +DA1: jnb ACC.7,zeroda ; jump if Bit7 = 0? + setb IOA.2 ; set the DIN bit + sjmp clkda ; continue with the clock +zeroda: clr IOA.2 ; clear the DIN bit +clkda: setb IOA.0 ; SCLK = 1 + clr IOA.0 ; SCLK = 0 + rl a ; next Bit + djnz R2,DA1 + + + ;; send the second byte to the DA-converter + mov a,r3 ; low byte + mov R2,#8 ; bit-counter +DA2: jnb ACC.7,zeroda2 ; jump if Bit7 = 0? + setb IOA.2 ; set the DIN bit + sjmp clkda2 ; continue with the clock +zeroda2:clr IOA.2 ; clear the DIN bit +clkda2: setb IOA.0 ; SCLK = 1 + clr IOA.0 ; SCLK = 0 + rl a ; next Bit + djnz R2,DA2 + ;; + setb IOA.5 ; set /CS to one + ;; +noDA: ret + + + +;;; arm ep6 +ep6_arm: + lcall convlo + + mov DPTR,#EP6BCH ; byte count H + mov a,#0 ; is zero + movx @DPTR,a + + mov DPTR,#EP6BCL ; byte count L + mov a,#10H ; is one + movx @DPTR,a + ret + + + +;;; get all 8 channels in the high speed mode +ep6_isr: + 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 + + lcall convlo ; conversion + + mov DPTR,#EP6BCH ; byte count H + mov a,#0 ; is zero + movx @DPTR,a + + mov DPTR,#EP6BCL ; byte count L + mov a,#10H ; is 8x word = 16 bytes + movx @DPTR,a + + ;; clear INT2 + mov a,EXIF ; FIRST clear the USB (INT2) interrupt request + clr acc.4 + mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable + + mov DPTR,#EPIRQ ; + mov a,#01000000b ; clear the ep6irq + movx @DPTR,a + + 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 + + + +;;; converts one analog/digital channel and stores it in EP8 +;;; also gets the content of the digital ports B and D +ep8_adc: + mov r0,#DIOFLAG ; pointer to the DIO flag + mov a,@r0 ; get the flag + jnz ep8_dio ; nonzero means DIO + + mov r0,#CHANNELLIST ; points to the channellist + mov a,@r0 ; Ch0 + + lcall readAD ; start the conversion + + mov DPTR,#0fc00h ; EP8 FIFO + mov a,R3 ; get low byte + movx @DPTR,A ; store in FIFO + inc dptr ; next fifo entry + mov a,R4 ; get high byte + movx @DPTR,A ; store in FIFO + + sjmp ep8_send ; send the data + +ep8_dio: + mov DPTR,#0fc00h ; store the contents of port B + mov a,IOB ; in the next + movx @dptr,a ; entry of the buffer + + inc dptr + clr a ; high byte is zero + movx @dptr,a ; next byte of the EP + +ep8_send: + mov DPTR,#EP8BCH ; byte count H + mov a,#0 ; is zero + movx @DPTR,a + + mov DPTR,#EP8BCL ; byte count L + mov a,#10H ; 16 bytes + movx @DPTR,a ; send the data over to the host + ret + + + +;;; arms EP8 with one byte. This signals the Linux driver that +;;; 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: + mov DPTR,#EP8BCH ; byte count H + mov a,#0 ; is zero + movx @DPTR,a + + mov DPTR,#EP8BCL ; byte count L + mov a,#1 ; 1 byte + movx @DPTR,a + ret + + + +;;; EP8 interrupt: gets one measurement from the AD converter and +;;; 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: + 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 + + lcall ep8_adc + + ;; clear INT2 + mov a,EXIF ; FIRST clear the USB (INT2) interrupt request + clr acc.4 + mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable + + mov DPTR,#EPIRQ ; + mov a,#10000000b ; clear the ep8irq + movx @DPTR,a + + 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 + + + + + + +;;; high speed mode, IRQ mode. Asynchronous transmission. +ep2_isr: + 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 dptr,#0F000H ; EP2 fifo buffer + lcall dalo ; conversion + + mov dptr,#EP2BCL ; "arm" it + mov a,#80h + movx @DPTR,a ; can receive data + movx @dptr,a + + ;; clear INT2 + mov a,EXIF ; FIRST clear the USB (INT2) interrupt request + clr acc.4 + mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable + + mov DPTR,#EPIRQ ; points to the usbirq + mov a,#00010000b ; clear the usbirq of ep 2 + movx @DPTR,a + + 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 + + + + + + + + + +.End + + diff --git a/etc/hotplug/usb/usbdux/usbdux_firmware.hex b/etc/hotplug/usb/usbdux/usbdux_firmware.hex new file mode 100644 index 0000000..e1dc621 --- /dev/null +++ b/etc/hotplug/usb/usbdux/usbdux_firmware.hex @@ -0,0 +1,80 @@ +:030000000201A258 +:03004300020100B7 +:1001000002017F0002033C0002017F0002017F0028 +:1001100002017F0002017F0002017F0002017F00D7 +:1001200002017F0002017F0002017F0002017F00C7 +:10013000020577000203B50002049B0002052B00B4 +:1001400002017F0002017F0002017F0002017F00A7 +:1001500002017F0002017F0002017F0002017F0097 +:1001600002017F0002017F0002017F0002017F0087 +:1001700002017F0002017F0002017F0002017FC0B7 +:1001800086C082C083C084C085C0E0C0D0E591C273 +:10019000E4F591D0D0D0E0D085D084D083D082D087 +:1001A000863290E6007414F090E6687408F012014C +:1001B000C490E680E0548070051202898003120228 +:1001C000E10080FD75B22775802222547C4481C2F3 +:1001D000817A0830E704D2828002C282D280C28053 +:1001E00023DAF0C2827A05D280C280DAFA7C007A01 +:1001F000047D08D280C280E58030E403EC4DFCED44 +:1002000003FDDAEF7B007A087D80D280C280E58032 +:1002100030E403EB4DFBED03FDDAEFD28122759A5A +:10022000F8759B0075AF077880E61201CBEB90E67E +:100230007BF0ECF008E61201CBEB90E67BF0ECF003 +:1002400008E61201CBEB90E67BF0ECF008E6120139 +:10025000CBEB90E67BF0ECF008E61201CBEB90E6FE +:100260007BF0ECF008E61201CBEB90E67BF0ECF0D3 +:1002700008E61201CBEB90E67BF0ECF008E6120109 +:10028000CBEB90E67BF0ECF02290E604740FF07478 +:1002900000F090E6127492F090E6187400F090E688 +:1002A000917480F0F0F090E61374A0F090E6197469 +:1002B00000F090E6957480F0F090E61474D2F0901F +:1002C000E61574E0F090E65E74A0F090E65F74A02E +:1002D000F090E65C7402F075E80175A88012051EC6 +:1002E0002290E604740FF07400F090E61274B2F0FD +:1002F00090E6187400F090E6917480F0F0F090E6CB +:100300001374A0F090E6197400F090E6957480F0F4 +:10031000F090E61474F2F090E61574E0F090E65E6A +:1003200074F0F090E65F74F0F090E65C7400F075A5 +:10033000E80175A88012051E12048B22C086C082B7 +:10034000C083C084C085C0E0C0D0C000C001C0026E +:10035000C003C004C005C006C00790E680E054801A +:100360007028E5AA5420700F12021E90E6987400BF +:10037000F090E6997410F0E5AA5401700D90F00029 +:1003800012044B90E6917480F0F0E591C2E4F5918F +:1003900090E65D7402F0D007D006D005D004D003FB +:1003A000D002D001D000D0D0D0E0D085D084D0838E +:1003B000D082D08632C086C082C083C084C085C04F +:1003C000E0C0D0C000C001C002C003C004C005C06E +:1003D00006C00790F400E09003DC237380068017CA +:1003E000801D802378807A0890F401E0F6A308DA73 +:1003F000FAE47890F6802190F40112044B80199071 +:10040000F401E0F5B3801190F401E0F5B3A3E0F559 +:100410009074FF7890F6800090E6957480F0F0F08C +:10042000E591C2E4F59190E65F7420F0D007D00624 +:10043000D005D004D003D002D001D000D0D0D0E07D +:10044000D085D084D083D082D08632E0A3F8E0FB80 +:10045000A3E0FCA3E0A312045CD8F32254C0443010 +:100460004CC2857A0830E704D2828002C282D280F0 +:10047000C28023DAF0EB7A0830E704D2828002C22D +:1004800082D280C28023DAF0D2852212021E90E648 +:10049000987400F090E6997410F022C086C082C073 +:1004A00083C084C085C0E0C0D0C000C001C002C00D +:1004B00003C004C005C006C00712021E90E698746F +:1004C00000F090E6997410F0E591C2E4F59190E6A1 +:1004D0005F7440F0D007D006D005D004D003D0021E +:1004E000D001D000D0D0D0E0D085D084D083D082CD +:1004F000D086327890E670107880E61201CB90FCBE +:1005000000EBF0A3ECF0800990FC00E590F0A3E490 +:10051000F090E69C7400F090E69D7410F02290E656 +:100520009C7400F090E69D7401F022C086C082C0E9 +:1005300083C084C085C0E0C0D0C000C001C002C07C +:1005400003C004C005C006C0071204F3E591C2E46D +:10055000F59190E65F7480F0D007D006D005D00406 +:10056000D003D002D001D000D0D0D0E0D085D0844C +:10057000D083D082D08632C086C082C083C084C07F +:1005800085C0E0C0D0C000C001C002C003C004C02C +:1005900005C006C00790F00012044B90E6917480ED +:1005A000F0F0E591C2E4F59190E65F7410F0D007A9 +:1005B000D006D005D004D003D002D001D000D0D0D6 +:0D05C000D0E0D085D084D083D082D08632A8 +:00000001FF diff --git a/etc/hotplug/usb/usbdux/usbdux_firmware.lst b/etc/hotplug/usb/usbdux/usbdux_firmware.lst new file mode 100644 index 0000000..01cd32c --- /dev/null +++ b/etc/hotplug/usb/usbdux/usbdux_firmware.lst @@ -0,0 +1,1118 @@ + ; usbdux_firmware.asm + ; Copyright (C) 2003 Bernd Porr, bp1@cn.stir.ac.uk + ; + ; 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 + ; Updated: Thu Oct 16 + ; 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 + ;; 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 EP2FIFOCFG,0E618H +0000: .equ EP4FIFOCFG,0E619H +0000: .equ EP6FIFOCFG,0E61AH +0000: .equ EP8FIFOCFG,0E61BH + ;; +0000: .equ INPKTEND,0E648H + ;; + ;; 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 EIE,0E8h + + + ;;; end of file + + + +0000: .equ CHANNELLIST,80h ; channellist in in + +0000: .equ DIOFLAG,90h ; flag if next IN transf is + +0000: .org 0000h ; after reset the processor +0000: 02 01 A2 ljmp main ; jump to the main loop + +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 3C 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 05 77 ljmp ep2_isr +0133: 00 nop +0134: 02 03 B5 ljmp ep4_isr +0137: 00 nop +0138: 02 04 9B ljmp ep6_isr +013B: 00 nop +013C: 02 05 2B 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: + +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 14 mov a,#000010100b ; 48MHz clock +01A7: F0 movx @DPTR,a ; do it + +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 + +01AE: 12 01 C4 lcall initAD ; init the ports to the con + +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 + +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 + +01C1: 00 mloop2: nop + +01C2: 80 FD sjmp mloop2 ; do nothing. The rest is d + + + ;;; 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 + + + + + ;;; 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 +01CB: 54 7C anl a,#01111100b ; only the channel, gain+po +01CD: 44 81 orl a,#10000001b ; start bit, external clock + ;; set CS to low +01CF: 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 + + ;; 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 + + ;; 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 + 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 + ;; 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 + 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 + ;; +021D: 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 + +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 + +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 + +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 ; + +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 + +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 ; + +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 + +0323: 90 E6 5F mov dptr,#EPIRQ +0326: 74 F0 mov a,#11110000b ; clear irq bits +0328: 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 ; + +032F: 75 E8 01 mov EIE,#00000001b ; enable INT2 in the 8051's +0332: 75 A8 80 mov IE,#80h ; IE, enable all in + +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 + + + + ;;; 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 + +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 + +0368: 12 02 1E lcall convlo ; conversion + +036B: 90 E6 98 mov DPTR,#EP6BCH ; byte count H +036E: 74 00 mov a,#0 ; is zero +0370: F0 movx @DPTR,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 + + 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 + +037D: 90 F0 00 mov dptr,#0F000H ; EP2 fifo buffer +0380: 12 04 4B 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 + + 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 + +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 + + 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 + + + + + + ;;; 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 + +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 + 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 + + + ;;; Channellist: + ;;; the first byte is zero: + ;;; we've just received the channel list + ;;; the channel list is stored in the addresses from 80H whi + ;;; 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 + 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 + + ;;; 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 + + ;;; configure the port B + 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 + + ;;; 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... + + 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 + + ;; 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 + + + + ;;; 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 + 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 + + + + ;;; D/A-conversion: + ;;; 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 + ;; set CS to low +0461: 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 + + + ;; 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 + ;; +0488: D2 85 setb IOA.5 ; set /CS to one + ;; +048A: 22 noDA: ret + + + + ;;; arm ep6 + ep6_arm: +048B: 12 02 1E lcall convlo + +048E: 90 E6 98 mov DPTR,#EP6BCH ; byte count H +0491: 74 00 mov a,#0 ; is zero +0493: F0 movx @DPTR,a + +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 + + + + ;;; 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 + + ;; 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 + + + + ;;; 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 + +04FB: 12 01 CB 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 + +0506: 80 09 sjmp ep8_send ; send the data + + 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 + +050E: A3 inc dptr +050F: E4 clr a ; high byte is zero +0510: 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 + +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 + + + + ;;; 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 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: +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 + +0549: 12 04 F3 lcall ep8_adc + + ;; 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 + + +