From e7f8fe430101fff0e6d819d943a3272990b7bda9 Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Tue, 2 Nov 2004 00:17:58 +0000 Subject: [PATCH] usbduxfast hotplug scripts and firmware. --- etc/hotplug/usb/usbduxfast/Makefile_asm | 26 + etc/hotplug/usb/usbduxfast/README | 32 ++ etc/hotplug/usb/usbduxfast/fx2-include.asm | 153 +++++ etc/hotplug/usb/usbduxfast/usbduxfast | 44 ++ .../usb/usbduxfast/usbduxfast_firmware.asm | 540 ++++++++++++++++++ .../usb/usbduxfast/usbduxfast_firmware.hex | 50 ++ 6 files changed, 845 insertions(+) create mode 100644 etc/hotplug/usb/usbduxfast/Makefile_asm create mode 100644 etc/hotplug/usb/usbduxfast/README create mode 100644 etc/hotplug/usb/usbduxfast/fx2-include.asm create mode 100755 etc/hotplug/usb/usbduxfast/usbduxfast create mode 100644 etc/hotplug/usb/usbduxfast/usbduxfast_firmware.asm create mode 100644 etc/hotplug/usb/usbduxfast/usbduxfast_firmware.hex diff --git a/etc/hotplug/usb/usbduxfast/Makefile_asm b/etc/hotplug/usb/usbduxfast/Makefile_asm new file mode 100644 index 0000000..def57b8 --- /dev/null +++ b/etc/hotplug/usb/usbduxfast/Makefile_asm @@ -0,0 +1,26 @@ +# (c) Bernd Porr +# GNU public license +# no warranty +# + +all: as31 usbduxfast_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 + +usbduxfast_firmware.hex: fx2-include.asm usbduxfast_firmware.asm as31 + as31-2.1/as31 -l usbduxfast_firmware.asm + +clean: + rm -f *.bin *~ *.lst *.bin *.hex + make -C as31-2.1 clean + +install: usbduxfast_firmware.hex + mkdir -p /usr/share/usb/ + install usbduxfast_firmware.hex /usr/share/usb/usbduxfast_firmware.hex + mkdir -p /etc/hotplug/usb + install usbduxfast /etc/hotplug/usb/usbduxfast diff --git a/etc/hotplug/usb/usbduxfast/README b/etc/hotplug/usb/usbduxfast/README new file mode 100644 index 0000000..ab1c5f3 --- /dev/null +++ b/etc/hotplug/usb/usbduxfast/README @@ -0,0 +1,32 @@ +Remarks to the hotplug script "usbduxfast": +--------------------------------------- + +The script /etc/hotplug/usb/usbduxfast 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.berndporr.me.uk/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: +BerndPorr@f2s.com diff --git a/etc/hotplug/usb/usbduxfast/fx2-include.asm b/etc/hotplug/usb/usbduxfast/fx2-include.asm new file mode 100644 index 0000000..4318294 --- /dev/null +++ b/etc/hotplug/usb/usbduxfast/fx2-include.asm @@ -0,0 +1,153 @@ +; 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 + .equ REVCTL,0E60BH + ;; 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 EP1INBC,0E68FH + .equ EP1INCS,0E6A2H + .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 EP6AUTOINLENH,0E624H + .equ EP6AUTOINLENL,0E625H + .equ EP2FIFOCFG,0E618H + .equ EP4FIFOCFG,0E619H + .equ EP6FIFOCFG,0E61AH + .equ EP8FIFOCFG,0E61BH + ;; + .equ INPKTEND,0E648H + .equ GPIFCTLCFG,0E6C3H + .equ GPIFABORT,0E6F5H + .equ GPIFIDLECTL,0E6C2H + .equ GPIFWFSELECT,0E6C0H + .equ GPIFREADYCFG,0E6F3H + .equ GPIFIDLECS,0E6C1H + .equ EP6GPIFFLGSEL,0E6E2H + .equ EP6GPIFPDFSTOP,0E6E3H + .equ EP6GPIFTRIG,0E6E4H + .equ GPIFIE,0E660H + .equ GPIFIRQ,0E661H + ;; + ;; 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 GPIFTRIG,0BBH + .equ EIE,0E8h + + + ;;; end of file + diff --git a/etc/hotplug/usb/usbduxfast/usbduxfast b/etc/hotplug/usb/usbduxfast/usbduxfast new file mode 100755 index 0000000..226161b --- /dev/null +++ b/etc/hotplug/usb/usbduxfast/usbduxfast @@ -0,0 +1,44 @@ +#!/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/usbduxfast_firmware.hex ]; then + USBDUX_FIRMWARE=/usr/share/usb/usbduxfast_firmware.hex +fi +if [ -e /usr/local/share/usb/usbduxfast_firmware.hex ]; then + USBDUX_FIRMWARE=/usr/local/share/usb/usbduxfast_firmware.hex +fi +# +# +# +# +# If you have more than one device please add/uncomment +# +# just to make sure we remove the comedi device +$COMEDI_CONFIG -r /dev/comedi0 +# $COMEDI_CONFIG -r /dev/comedi1 +# +# connecting the comedi device comedi0 with the module usbdux +$COMEDI_CONFIG -i $USBDUX_FIRMWARE /dev/comedi0 usbduxfast +# $COMEDI_CONFIG /dev/comedi1 usbduxfast +# +# diff --git a/etc/hotplug/usb/usbduxfast/usbduxfast_firmware.asm b/etc/hotplug/usb/usbduxfast/usbduxfast_firmware.asm new file mode 100644 index 0000000..e6aab02 --- /dev/null +++ b/etc/hotplug/usb/usbduxfast/usbduxfast_firmware.asm @@ -0,0 +1,540 @@ +; usbdux_firmware.asm +; Copyright (C) 2004 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: xxx +; Devices: [ITL] USB-DUX (usbdux.o) +; Author: Bernd Porr +; Updated: +; Status: testing +; +;;; +;;; +;;; + + .inc fx2-include.asm + + .equ WFLOADED,70H ; waveform is loaded + + .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 +sof_isr: +sudav_isr: +sutok_isr: +suspend_isr: +usbreset_isr: +hispeed_isr: +ep0ack_isr: +spare_isr: +ep0in_isr: +ep0out_isr: +ep1out_isr: +ep1in_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: +ep8_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,#REVCTL + mov a,#00000011b ; allows skip + lcall syncdelaywr + + mov DPTR,#CPUCS ; CPU control register + mov a,#00010000b ; 48Mhz + lcall syncdelaywr + + mov dptr,#IFCONFIG ; switch on IFCLK signal + mov a,#10110010b ; gpif, 30MHz, + lcall syncdelaywr + + mov dptr,#FIFORESET + mov a,#80h + lcall syncdelaywr + mov a,#8 + lcall syncdelaywr + mov a,#2 + lcall syncdelaywr + mov a,#4 + lcall syncdelaywr + mov a,#6 + lcall syncdelaywr + mov a,#0 + lcall syncdelaywr + + mov dptr,#INTSETUP ; IRQ setup register + mov a,#08h ; enable autovector + lcall syncdelaywr + + lcall initeps ; init the isochronous data-transfer + + lcall initGPIF + +;;; main loop + +mloop2: + lcall gpif_run + sjmp mloop2 ; do nothing. The rest is done by the IRQs + + +gpif_run: + mov a,WFLOADED + jz no_trig ; do not trigger + mov a,GPIFTRIG ; GPIF status + anl a,#80h ; done bit + jz no_trig ; GPIF busy + + mov a,#06h ; RD,EP6 + mov GPIFTRIG,a +no_trig: + ret + + + +initGPIF: + mov DPTR,#EP6CFG ; ISO data from here to the host + mov a,#11010000b ; Valid, quad buffering + lcall syncdelaywr + + mov dptr,#EP6FIFOCFG + mov a,#00001001b ; autoin, wordwide + lcall syncdelaywr + + mov dptr,#EP6AUTOINLENH + mov a,#00000010b ; 512 bytes + lcall syncdelaywr + + mov dptr,#EP6AUTOINLENL + mov a,#00000000b ; 0 + lcall syncdelaywr + + mov dptr,#EP6ISOINPKTS + mov a,#1 ; 1 packets + lcall syncdelaywr + + mov dptr,#GPIFWFSELECT + mov a,#11111100b ; waveform 0 for FIFO RD + lcall syncdelaywr + + mov dptr,#GPIFCTLCFG + mov a,#10000000b ; tri state for CTRL + lcall syncdelaywr + + mov dptr,#GPIFIDLECTL + mov a,#11111111b ; all CTL outputs high + lcall syncdelaywr + mov a,#11111101b ; reset counter + lcall syncdelaywr + mov a,#11111111b ; reset to high again + lcall syncdelaywr + + mov a,#00000010b ; abort when full + mov dptr,#EP6GPIFFLGSEL + lcall syncdelaywr + + mov a,#00000001b ; stop when buffer overfl + mov dptr,#EP6GPIFPDFSTOP + lcall syncdelaywr + + mov a,#0 + mov dptr,#GPIFREADYCFG + lcall syncdelaywr + + mov a,#0 + mov dptr,#GPIFIDLECS + lcall syncdelaywr + +; waveform 1 +; this is a dummy waveform which is used +; during the upload of another waveform into +; wavefrom 0 +; it branches directly into the IDLE state + mov dptr,#0E420H + mov a,#00111111b ; branch to IDLE + lcall syncdelaywr + + mov dptr,#0E428H ; opcode + mov a,#00000001b ; deceision point + lcall syncdelaywr + + mov dptr,#0E430H + mov a,#0FFH ; output is high + lcall syncdelaywr + + mov dptr,#0E438H + mov a,#0FFH ; logic function + lcall syncdelaywr + +; signals that no waveform 0 is loaded so far + mov WFLOADED,#0 ; waveform flag + + ret + + + +;;; initilise the transfer +;;; It is assumed that the USB interface is in alternate setting 3 +initeps: + mov DPTR,#EP4CFG + mov a,#10100000b ; valid, bulk, out + movx @dptr,a + + mov dptr,#EP4BCL ; "arm" it + mov a,#00h + lcall syncdelaywr ; wait until we can write again + lcall syncdelaywr ; wait + lcall syncdelaywr ; wait + + mov DPTR,#EP8CFG + mov a,#0 ; disable EP8, it overlaps with EP6!! + movx @dptr,a + + mov dptr,#EPIE ; interrupt enable + mov a,#00100000b ; enable irq for ep4 + movx @dptr,a ; do it + + mov dptr,#EPIRQ ; clear IRQs + mov a,#00100100b + movx @dptr,a + + mov DPTR,#USBIE ; USB int enable register + mov a,#0 ; SOF etc + movx @DPTR,a ; + + mov DPTR,#GPIFIE ; GPIF int enable register + mov a,#0 ; done IRQ + movx @DPTR,a ; + + mov EIE,#00000001b ; enable INT2 in the 8051's SFR + mov IE,#80h ; IE, enable all interrupts + + ret + + +;;; 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 storewaveform ; a=0 + sjmp init_ep6 ; a=1 + +init_ep6: + ; stop ep6 + ; just now do nothing + + ljmp over_wf + + +storewaveform: + mov WFLOADED,#0 ; waveform flag + + mov dptr,#EP6FIFOCFG + mov a,#00000000b ; + lcall syncdelaywr + + mov dptr,#GPIFABORT + mov a,#0ffh ; abort all transfers + lcall syncdelaywr + +wait_f_abort: + mov a,GPIFTRIG ; GPIF status + anl a,#80h ; done bit + jz wait_f_abort ; GPIF busy + + mov dptr,#GPIFWFSELECT + mov a,#11111101b ; select dummy waveform + movx @dptr,a + lcall syncdelay + + mov dptr,#FIFORESET + mov a,#80h ; NAK + lcall syncdelaywr + mov a,#6 ; reset EP6 + lcall syncdelaywr + mov a,#0 ; normal op + lcall syncdelaywr + +; change to dummy waveform 1 + mov a,#06h ; RD,EP6 + mov GPIFTRIG,a + +; wait a bit + mov r2,255 +loopx: + djnz r2,loopx + +; abort waveform if not already so + mov dptr,#GPIFABORT + mov a,#0ffh ; abort all transfers + lcall syncdelaywr + +; wait again + mov r2,255 +loopx2: + djnz r2,loopx2 + +; check for DONE +wait_f_abort2: + mov a,GPIFTRIG ; GPIF status + anl a,#80h ; done bit + jz wait_f_abort2 ; GPIF busy + +; upload the new waveform into waveform 0 + mov AUTOPTRH2,#0E4H ; XDATA0H + lcall syncdelay + mov AUTOPTRL2,#00H ; XDATA0L + lcall syncdelay + + mov AUTOPTRH1,#0F4H ; EP4 high + lcall syncdelay + mov AUTOPTRL1,#01H ; EP4 low + lcall syncdelay + + mov AUTOPTRSETUP,#7 ; autoinc and enable + lcall syncdelay + + mov r2,#20H ; 32 bytes to transfer + +wavetr: + mov dptr,#XAUTODAT1 + movx a,@dptr + lcall syncdelay + mov dptr,#XAUTODAT2 + movx @dptr,a + lcall syncdelay + djnz r2,wavetr + + mov dptr,#EP6FIFOCFG + mov a,#00001001b ; autoin, wordwide + lcall syncdelaywr + + mov dptr,#GPIFWFSELECT + mov a,#11111100b + movx @dptr,a + lcall syncdelay + + mov dptr,#FIFORESET + mov a,#80h ; NAK + lcall syncdelaywr + mov a,#6 ; reset EP6 + lcall syncdelaywr + mov a,#0 ; normal op + lcall syncdelaywr + + mov dptr,#0E400H+10H; waveform 0: first CTL byte + movx a,@dptr ; get it + orl a,#11111011b ; force all bits to one except the range bit + mov dptr,#GPIFIDLECTL + lcall syncdelaywr + + mov WFLOADED,#1 ; waveform flag + +; do the common things here +over_wf: + mov dptr,#EP4BCL + mov a,#00h + movx @DPTR,a ; arm it + lcall syncdelay ; wait + movx @DPTR,a ; arm it + lcall syncdelay ; wait + + ;; 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 + + +;; need to delay every time the byte counters +;; for the EPs have been changed. + +syncdelay: + nop + nop + nop + nop + nop + nop + nop + nop + nop + ret + + +syncdelaywr: + lcall syncdelay + movx @dptr,a + ret + + +.End + + diff --git a/etc/hotplug/usb/usbduxfast/usbduxfast_firmware.hex b/etc/hotplug/usb/usbduxfast/usbduxfast_firmware.hex new file mode 100644 index 0000000..05ed226 --- /dev/null +++ b/etc/hotplug/usb/usbduxfast/usbduxfast_firmware.hex @@ -0,0 +1,50 @@ +:030000000201A258 +:03004300020100B7 +:1001000002017F0002017F0002017F0002017F00E7 +:1001100002017F0002017F0002017F0002017F00D7 +:1001200002017F0002017F0002017F0002017F00C7 +:1001300002017F000202C40002017F0002017F0071 +:1001400002017F0002017F0002017F0002017F00A7 +:1001500002017F0002017F0002017F0002017F0097 +:1001600002017F0002017F0002017F0002017F0087 +:1001700002017F0002017F0002017F0002017FC0B7 +:1001800086C082C083C084C085C0E0C0D0E591C273 +:10019000E4F591D0D0D0E0D085D084D083D082D087 +:1001A000863290E60B74031203E490E6007410129A +:1001B00003E490E60174B21203E490E60474801242 +:1001C00003E474081203E474021203E474041203D7 +:1001D000E474061203E474001203E490E668740801 +:1001E0001203E412028B1201FD1201EE80FBE57096 +:1001F000600AE5BB548060047406F5BB2290E614E7 +:1002000074D01203E490E61A74091203E490E62411 +:1002100074021203E490E62574001203E490E642AF +:1002200074011203E490E6C074FC1203E490E6C388 +:1002300074801203E490E6C274FF1203E474FD12AA +:1002400003E474FF1203E4740290E6E21203E47420 +:100250000190E6E31203E4740090E6F31203E47401 +:100260000090E6C11203E490E420743F1203E4908E +:10027000E42874011203E490E43074FF1203E49064 +:10028000E43874FF1203E47570002290E61374A042 +:10029000F090E69574001203E41203E41203E49074 +:1002A000E6157400F090E65E7420F090E65F74242A +:1002B000F090E65C7400F090E6607400F075E80180 +:1002C00075A88022C086C082C083C084C085C0E07B +:1002D000C0D0C000C001C002C003C004C005C00639 +:1002E000C00790F400E09002EB23738005800002C9 +:1002F00003A275700090E61A74001203E490E6F50C +:1003000074FF1203E4E5BB548060FA90E6C074FD0C +:10031000F01203DA90E60474801203E47406120308 +:10032000E474001203E47406F5BBAAFFDAFE90E65B +:10033000F574FF1203E4AAFFDAFEE5BB548060FA0D +:10034000759DE41203DA759E001203DA759AF412B1 +:1003500003DA759B011203DA75AF071203DA7A200C +:1003600090E67BE01203DA90E67CF01203DADAF032 +:1003700090E61A74091203E490E6C074FCF01203CC +:10038000DA90E60474801203E474061203E4740045 +:100390001203E490E410E044FB90E6C21203E4751B +:1003A000700190E6957400F01203DAF01203DAE5BA +:1003B00091C2E4F59190E65F7420F0D007D006D0AA +:1003C00005D004D003D002D001D000D0D0D0E0D0EE +:1003D00085D084D083D082D0863200000000000017 +:0903E000000000221203DAF022F1 +:00000001FF -- 2.26.2