]> git.ipfire.org Git - thirdparty/linux-firmware.git/blob - usbdux/usbduxfast_firmware.asm
0d8e7f802599229452a4479bc300b5c23db2d2b0
[thirdparty/linux-firmware.git] / usbdux / usbduxfast_firmware.asm
1 ; usbduxfast_firmware.asm
2 ; Copyright (C) 2004,2009 Bernd Porr, Bernd.Porr@f2s.com
3 ;
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.
8 ;
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.
13 ;
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.
17 ;
18 ;
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
24 ; Status: stable
25 ;
26 ;;;
27 ;;;
28 ;;;
29
30 .inc fx2-include.asm
31
32 .equ WFLOADED,70H ; waveform is loaded
33
34 .org 0000h ; after reset the processor starts here
35 ljmp main ; jump to the main loop
36
37 .org 0043h ; the IRQ2-vector
38 ljmp jmptbl ; irq service-routine
39
40 .org 0100h ; start of the jump table
41
42 jmptbl: ljmp sudav_isr
43 nop
44 ljmp sof_isr
45 nop
46 ljmp sutok_isr
47 nop
48 ljmp suspend_isr
49 nop
50 ljmp usbreset_isr
51 nop
52 ljmp hispeed_isr
53 nop
54 ljmp ep0ack_isr
55 nop
56 ljmp spare_isr
57 nop
58 ljmp ep0in_isr
59 nop
60 ljmp ep0out_isr
61 nop
62 ljmp ep1in_isr
63 nop
64 ljmp ep1out_isr
65 nop
66 ljmp ep2_isr
67 nop
68 ljmp ep4_isr
69 nop
70 ljmp ep6_isr
71 nop
72 ljmp ep8_isr
73 nop
74 ljmp ibn_isr
75 nop
76 ljmp spare_isr
77 nop
78 ljmp ep0ping_isr
79 nop
80 ljmp ep1ping_isr
81 nop
82 ljmp ep2ping_isr
83 nop
84 ljmp ep4ping_isr
85 nop
86 ljmp ep6ping_isr
87 nop
88 ljmp ep8ping_isr
89 nop
90 ljmp errlimit_isr
91 nop
92 ljmp spare_isr
93 nop
94 ljmp spare_isr
95 nop
96 ljmp spare_isr
97 nop
98 ljmp ep2isoerr_isr
99 nop
100 ljmp ep4isoerr_isr
101 nop
102 ljmp ep6isoerr_isr
103 nop
104 ljmp ep8isoerr_isr
105
106
107 ;; dummy isr
108 sof_isr:
109 sudav_isr:
110 sutok_isr:
111 suspend_isr:
112 usbreset_isr:
113 hispeed_isr:
114 ep0ack_isr:
115 spare_isr:
116 ep0in_isr:
117 ep0out_isr:
118 ep1out_isr:
119 ep1in_isr:
120 ibn_isr:
121 ep0ping_isr:
122 ep1ping_isr:
123 ep2ping_isr:
124 ep4ping_isr:
125 ep6ping_isr:
126 ep8ping_isr:
127 errlimit_isr:
128 ep2isoerr_isr:
129 ep4isoerr_isr:
130 ep6isoerr_isr:
131 ep8isoerr_isr:
132 ep6_isr:
133 ep2_isr:
134 ep8_isr:
135
136 push dps
137 push dpl
138 push dph
139 push dpl1
140 push dph1
141 push acc
142 push psw
143
144 ;; clear the USB2 irq bit and return
145 mov a,EXIF
146 clr acc.4
147 mov EXIF,a
148
149 pop psw
150 pop acc
151 pop dph1
152 pop dpl1
153 pop dph
154 pop dpl
155 pop dps
156
157 reti
158
159
160 ;;; main program
161 ;;; basically only initialises the processor and
162 ;;; then engages in an endless loop
163 main:
164 mov dptr,#REVCTL
165 mov a,#00000011b ; allows skip
166 lcall syncdelaywr
167
168 mov DPTR,#CPUCS ; CPU control register
169 mov a,#00010000b ; 48Mhz
170 lcall syncdelaywr
171
172 mov dptr,#IFCONFIG ; switch on IFCLK signal
173 mov a,#10100010b ; gpif, 30MHz
174 lcall syncdelaywr
175
176 mov dptr,#FIFORESET
177 mov a,#80h
178 lcall syncdelaywr
179 mov a,#8
180 lcall syncdelaywr
181 mov a,#2
182 lcall syncdelaywr
183 mov a,#4
184 lcall syncdelaywr
185 mov a,#6
186 lcall syncdelaywr
187 mov a,#0
188 lcall syncdelaywr
189
190 mov dptr,#INTSETUP ; IRQ setup register
191 mov a,#08h ; enable autovector
192 lcall syncdelaywr
193
194 lcall initeps ; init the isochronous data-transfer
195
196 lcall initGPIF
197
198 ;;; main loop
199
200 mloop2:
201 lcall gpif_run
202 sjmp mloop2 ; do nothing. The rest is done by the IRQs
203
204
205 gpif_run:
206 mov a,WFLOADED
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
211
212 ;;; gpif has stopped
213 mov a,#06h ; RD,EP6
214 mov GPIFTRIG,a
215 no_trig:
216 ret
217
218
219
220 initGPIF:
221 mov DPTR,#EP6CFG ; BLK data from here to the host
222 mov a,#11100000b ; Valid, quad buffering
223 lcall syncdelaywr ; write
224
225 mov dptr,#EP6FIFOCFG
226 mov a,#00001001b ; autoin, wordwide
227 lcall syncdelaywr
228
229 mov dptr,#EP6AUTOINLENH
230 mov a,#00000010b ; 512 bytes
231 lcall syncdelaywr ; write
232
233 mov dptr,#EP6AUTOINLENL
234 mov a,#00000000b ; 0
235 lcall syncdelaywr ; write
236
237 mov dptr,#GPIFWFSELECT
238 mov a,#11111100b ; waveform 0 for FIFO RD
239 lcall syncdelaywr
240
241 mov dptr,#GPIFCTLCFG
242 mov a,#10000000b ; tri state for CTRL
243 lcall syncdelaywr
244
245 mov dptr,#GPIFIDLECTL
246 mov a,#11111111b ; all CTL outputs high
247 lcall syncdelaywr
248 mov a,#11111101b ; reset counter
249 lcall syncdelaywr
250 mov a,#11111111b ; reset to high again
251 lcall syncdelaywr
252
253 mov a,#00000010b ; abort when full
254 mov dptr,#EP6GPIFFLGSEL
255 lcall syncdelaywr
256
257 mov a,#00000001b ; stop when buffer overfl
258 mov dptr,#EP6GPIFPDFSTOP
259 lcall syncdelaywr
260
261 mov a,#0
262 mov dptr,#GPIFREADYCFG
263 lcall syncdelaywr
264
265 mov a,#0
266 mov dptr,#GPIFIDLECS
267 lcall syncdelaywr
268
269 ; waveform 1
270 ; this is a dummy waveform which is used
271 ; during the upload of another waveform into
272 ; wavefrom 0
273 ; it branches directly into the IDLE state
274 mov dptr,#0E420H
275 mov a,#00111111b ; branch to IDLE
276 lcall syncdelaywr
277
278 mov dptr,#0E428H ; opcode
279 mov a,#00000001b ; deceision point
280 lcall syncdelaywr
281
282 mov dptr,#0E430H
283 mov a,#0FFH ; output is high
284 lcall syncdelaywr
285
286 mov dptr,#0E438H
287 mov a,#0FFH ; logic function
288 lcall syncdelaywr
289
290 ; signals that no waveform 0 is loaded so far
291 mov WFLOADED,#0 ; waveform flag
292
293 ret
294
295
296
297 ;;; initilise the transfer
298 ;;; It is assumed that the USB interface is in alternate setting 1
299 initeps:
300 mov DPTR,#EP4CFG
301 mov a,#10100000b ; valid, bulk, out
302 lcall syncdelaywr
303
304 mov dptr,#EP4BCL ; "arm" it
305 mov a,#00h
306 lcall syncdelaywr ; wait until we can write again
307 lcall syncdelaywr ; wait
308 lcall syncdelaywr ; wait
309
310 mov DPTR,#EP8CFG
311 mov a,#0 ; disable EP8, it overlaps with EP6!!
312 lcall syncdelaywr
313
314 mov dptr,#EPIE ; interrupt enable
315 mov a,#00100000b ; enable irq for ep4
316 lcall syncdelaywr ; do it
317
318 mov dptr,#EPIRQ ; clear IRQs
319 mov a,#00100100b
320 movx @dptr,a
321
322 mov DPTR,#USBIE ; USB int enable register
323 mov a,#0 ; SOF etc
324 movx @DPTR,a ;
325
326 mov DPTR,#GPIFIE ; GPIF int enable register
327 mov a,#0 ; done IRQ
328 movx @DPTR,a ;
329
330 mov EIE,#00000001b ; enable INT2 in the 8051's SFR
331 mov IE,#80h ; IE, enable all interrupts
332
333 ret
334
335
336 ;;; interrupt-routine for ep4
337 ;;; receives the channel list and other commands
338 ep4_isr:
339 push dps
340 push dpl
341 push dph
342 push dpl1
343 push dph1
344 push acc
345 push psw
346 push 00h ; R0
347 push 01h ; R1
348 push 02h ; R2
349 push 03h ; R3
350 push 04h ; R4
351 push 05h ; R5
352 push 06h ; R6
353 push 07h ; R7
354
355 mov dptr,#0f400h ; FIFO buffer of EP4
356 movx a,@dptr ; get the first byte
357
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
361
362 ep4_jmp:
363 sjmp storewaveform ; a=0
364 sjmp init_ep6 ; a=1
365
366 init_ep6:
367 ; stop ep6
368 ; just now do nothing
369
370 ljmp over_wf
371
372
373 storewaveform:
374 mov WFLOADED,#0 ; waveform flag
375
376 mov dptr,#EP6FIFOCFG
377 mov a,#00000000b ;
378 lcall syncdelaywr
379
380 mov dptr,#GPIFABORT
381 mov a,#0ffh ; abort all transfers
382 lcall syncdelaywr
383
384 wait_f_abort:
385 mov a,GPIFTRIG ; GPIF status
386 anl a,#80h ; done bit
387 jz wait_f_abort ; GPIF busy
388
389 mov dptr,#GPIFWFSELECT
390 mov a,#11111101b ; select dummy waveform
391 movx @dptr,a
392 lcall syncdelay
393
394 mov dptr,#FIFORESET
395 mov a,#80h ; NAK
396 lcall syncdelaywr
397 mov a,#6 ; reset EP6
398 lcall syncdelaywr
399 mov a,#0 ; normal op
400 lcall syncdelaywr
401
402 ; change to dummy waveform 1
403 mov a,#06h ; RD,EP6
404 mov GPIFTRIG,a
405
406 ; wait a bit
407 mov r2,255
408 loopx:
409 djnz r2,loopx
410
411 ; abort waveform if not already so
412 mov dptr,#GPIFABORT
413 mov a,#0ffh ; abort all transfers
414 lcall syncdelaywr
415
416 ; wait again
417 mov r2,255
418 loopx2:
419 djnz r2,loopx2
420
421 ; check for DONE
422 wait_f_abort2:
423 mov a,GPIFTRIG ; GPIF status
424 anl a,#80h ; done bit
425 jz wait_f_abort2 ; GPIF busy
426
427 ; upload the new waveform into waveform 0
428 mov AUTOPTRH2,#0E4H ; XDATA0H
429 lcall syncdelay
430 mov AUTOPTRL2,#00H ; XDATA0L
431 lcall syncdelay
432
433 mov AUTOPTRH1,#0F4H ; EP4 high
434 lcall syncdelay
435 mov AUTOPTRL1,#01H ; EP4 low
436 lcall syncdelay
437
438 mov AUTOPTRSETUP,#7 ; autoinc and enable
439 lcall syncdelay
440
441 mov r2,#20H ; 32 bytes to transfer
442
443 wavetr:
444 mov dptr,#XAUTODAT1
445 movx a,@dptr
446 lcall syncdelay
447 mov dptr,#XAUTODAT2
448 movx @dptr,a
449 lcall syncdelay
450 djnz r2,wavetr
451
452 mov dptr,#EP6FIFOCFG
453 mov a,#00001001b ; autoin, wordwide
454 lcall syncdelaywr
455
456 mov dptr,#GPIFWFSELECT
457 mov a,#11111100b
458 movx @dptr,a
459 lcall syncdelay
460
461 mov dptr,#FIFORESET
462 mov a,#80h ; NAK
463 lcall syncdelaywr
464 mov a,#6 ; reset EP6
465 lcall syncdelaywr
466 mov a,#0 ; normal op
467 lcall syncdelaywr
468
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
473 lcall syncdelaywr
474
475 mov WFLOADED,#1 ; waveform flag
476
477 ; do the common things here
478 over_wf:
479 mov dptr,#EP4BCL
480 mov a,#00h
481 movx @DPTR,a ; arm it
482 lcall syncdelay ; wait
483 movx @DPTR,a ; arm it
484 lcall syncdelay ; wait
485
486 ;; clear INT2
487 mov a,EXIF ; FIRST clear the USB (INT2) interrupt request
488 clr acc.4
489 mov EXIF,a ; Note: EXIF reg is not 8051 bit-addressable
490
491 mov DPTR,#EPIRQ ;
492 mov a,#00100000b ; clear the ep4irq
493 movx @DPTR,a
494
495 pop 07h
496 pop 06h
497 pop 05h
498 pop 04h ; R4
499 pop 03h ; R3
500 pop 02h ; R2
501 pop 01h ; R1
502 pop 00h ; R0
503 pop psw
504 pop acc
505 pop dph1
506 pop dpl1
507 pop dph
508 pop dpl
509 pop dps
510 reti
511
512
513 ;; need to delay every time the byte counters
514 ;; for the EPs have been changed.
515
516 syncdelay:
517 nop
518 nop
519 nop
520 nop
521 nop
522 nop
523 nop
524 nop
525 nop
526 ret
527
528
529 syncdelaywr:
530 lcall syncdelay
531 movx @dptr,a
532 ret
533
534
535 .End
536
537
538
539
540
541
542
543
544
545
546
547