1 ; usbduxfast_firmware.asm
2 ; Copyright (C) 2004,2009 Bernd Porr, Bernd.Porr@f2s.com
4 ; This program is free software; you can redistribute it and/or modify
5 ; it under the terms of the GNU General Public License as published by
6 ; the Free Software Foundation; either version 2 of the License, or
7 ; (at your option) any later version.
9 ; This program is distributed in the hope that it will be useful,
10 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ; GNU General Public License for more details.
14 ; You should have received a copy of the GNU General Public License
15 ; along with this program; if not, write to the Free Software
16 ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ; Firmware: usbduxfast_firmware.asm for usbdux.c
20 ; Description: Firmware for usbduxfast
21 ; Devices: [ITL] USB-DUX (usbdux.o)
22 ; Author: Bernd Porr <Bernd.Porr@f2s.com>
23 ; Updated: 17 Apr 2009
32 .equ WFLOADED,70H ; waveform is loaded
34 .org 0000h ; after reset the processor starts here
35 ljmp main ; jump to the main loop
37 .org 0043h ; the IRQ2-vector
38 ljmp jmptbl ; irq service-routine
40 .org 0100h ; start of the jump table
42 jmptbl: ljmp sudav_isr
144 ;; clear the USB2 irq bit and return
161 ;;; basically only initialises the processor and
162 ;;; then engages in an endless loop
165 mov a,#00000011b ; allows skip
168 mov DPTR,#CPUCS ; CPU control register
169 mov a,#00010000b ; 48Mhz
172 mov dptr,#IFCONFIG ; switch on IFCLK signal
173 mov a,#10100010b ; gpif, 30MHz
190 mov dptr,#INTSETUP ; IRQ setup register
191 mov a,#08h ; enable autovector
194 lcall initeps ; init the isochronous data-transfer
202 sjmp mloop2 ; do nothing. The rest is done by the IRQs
207 jz no_trig ; do not trigger
208 mov a,GPIFTRIG ; GPIF status
209 anl a,#80h ; done bit
210 jz no_trig ; GPIF busy
221 mov DPTR,#EP6CFG ; BLK data from here to the host
222 mov a,#11100000b ; Valid, quad buffering
223 lcall syncdelaywr ; write
226 mov a,#00001001b ; autoin, wordwide
229 mov dptr,#EP6AUTOINLENH
230 mov a,#00000010b ; 512 bytes
231 lcall syncdelaywr ; write
233 mov dptr,#EP6AUTOINLENL
235 lcall syncdelaywr ; write
237 mov dptr,#GPIFWFSELECT
238 mov a,#11111100b ; waveform 0 for FIFO RD
242 mov a,#10000000b ; tri state for CTRL
245 mov dptr,#GPIFIDLECTL
246 mov a,#11111111b ; all CTL outputs high
248 mov a,#11111101b ; reset counter
250 mov a,#11111111b ; reset to high again
253 mov a,#00000010b ; abort when full
254 mov dptr,#EP6GPIFFLGSEL
257 mov a,#00000001b ; stop when buffer overfl
258 mov dptr,#EP6GPIFPDFSTOP
262 mov dptr,#GPIFREADYCFG
270 ; this is a dummy waveform which is used
271 ; during the upload of another waveform into
273 ; it branches directly into the IDLE state
275 mov a,#00111111b ; branch to IDLE
278 mov dptr,#0E428H ; opcode
279 mov a,#00000001b ; deceision point
283 mov a,#0FFH ; output is high
287 mov a,#0FFH ; logic function
290 ; signals that no waveform 0 is loaded so far
291 mov WFLOADED,#0 ; waveform flag
297 ;;; initilise the transfer
298 ;;; It is assumed that the USB interface is in alternate setting 1
301 mov a,#10100000b ; valid, bulk, out
304 mov dptr,#EP4BCL ; "arm" it
306 lcall syncdelaywr ; wait until we can write again
307 lcall syncdelaywr ; wait
308 lcall syncdelaywr ; wait
311 mov a,#0 ; disable EP8, it overlaps with EP6!!
314 mov dptr,#EPIE ; interrupt enable
315 mov a,#00100000b ; enable irq for ep4
316 lcall syncdelaywr ; do it
318 mov dptr,#EPIRQ ; clear IRQs
322 mov DPTR,#USBIE ; USB int enable register
326 mov DPTR,#GPIFIE ; GPIF int enable register
330 mov EIE,#00000001b ; enable INT2 in the 8051's SFR
331 mov IE,#80h ; IE, enable all interrupts
336 ;;; interrupt-routine for ep4
337 ;;; receives the channel list and other commands
355 mov dptr,#0f400h ; FIFO buffer of EP4
356 movx a,@dptr ; get the first byte
358 mov dptr,#ep4_jmp ; jump table for the different functions
359 rl a ; multiply by 2: sizeof sjmp
360 jmp @a+dptr ; jump to the jump table
363 sjmp storewaveform ; a=0
368 ; just now do nothing
374 mov WFLOADED,#0 ; waveform flag
381 mov a,#0ffh ; abort all transfers
385 mov a,GPIFTRIG ; GPIF status
386 anl a,#80h ; done bit
387 jz wait_f_abort ; GPIF busy
389 mov dptr,#GPIFWFSELECT
390 mov a,#11111101b ; select dummy waveform
402 ; change to dummy waveform 1
411 ; abort waveform if not already so
413 mov a,#0ffh ; abort all transfers
423 mov a,GPIFTRIG ; GPIF status
424 anl a,#80h ; done bit
425 jz wait_f_abort2 ; GPIF busy
427 ; upload the new waveform into waveform 0
428 mov AUTOPTRH2,#0E4H ; XDATA0H
430 mov AUTOPTRL2,#00H ; XDATA0L
433 mov AUTOPTRH1,#0F4H ; EP4 high
435 mov AUTOPTRL1,#01H ; EP4 low
438 mov AUTOPTRSETUP,#7 ; autoinc and enable
441 mov r2,#20H ; 32 bytes to transfer
453 mov a,#00001001b ; autoin, wordwide
456 mov dptr,#GPIFWFSELECT
469 mov dptr,#0E400H+10H; waveform 0: first CTL byte
470 movx a,@dptr ; get it
471 orl a,#11111011b ; force all bits to one except the range bit
472 mov dptr,#GPIFIDLECTL
475 mov WFLOADED,#1 ; waveform flag
477 ; do the common things here
481 movx @DPTR,a ; arm it
482 lcall syncdelay ; wait
483 movx @DPTR,a ; arm it
484 lcall syncdelay ; wait
487 mov a,EXIF ; FIRST clear the USB (INT2) interrupt request
489 mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable
492 mov a,#00100000b ; clear the ep4irq
513 ;; need to delay every time the byte counters
514 ;; for the EPs have been changed.