From 324c5ba9098c1010d0aa8c1e26b95509878ce9f2 Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Tue, 11 Oct 2011 21:50:49 +0200 Subject: Mini-Octopus build from r@171 --- firmware/93c46.c | 359 ++++++++++++++ firmware/93c46.h | 113 +++++ firmware/Makefile | 458 +++++++++++++++++ firmware/adc.c | 200 ++++++++ firmware/adc.h | 56 +++ firmware/common.c | 107 ++++ firmware/common.h | 93 ++++ firmware/debug.c | 72 +++ firmware/debug.h | 5 + firmware/fifo.c | 27 + firmware/fifo.h | 75 +++ firmware/i2c.c | 216 ++++++++ firmware/i2c.h | 68 +++ firmware/io.c | 512 +++++++++++++++++++ firmware/io.h | 269 ++++++++++ firmware/main.c | 287 +++++++++++ firmware/main.hex | 844 ++++++++++++++++++++++++++++++++ firmware/octopus.hex | 830 +++++++++++++++++++++++++++++++ firmware/octopus_can.hex | 842 +++++++++++++++++++++++++++++++ firmware/protocol.h | 94 ++++ firmware/pwm.c | 270 ++++++++++ firmware/pwm.h | 56 +++ firmware/spi.c | 188 +++++++ firmware/spi.h | 64 +++ firmware/uart.c | 381 ++++++++++++++ firmware/uart.h | 19 + firmware/usbn2mc.c | 153 ++++++ firmware/usbn2mc.h | 73 +++ firmware/wait.c | 45 ++ firmware/wait.h | 39 ++ liboctopus/.gitignore | 2 + liboctopus/Makefile | 10 + liboctopus/octopus.c | 815 ++++++++++++++++++++++++++++++ liboctopus/octopus.h | 141 ++++++ liboctopus/python/.gitignore | 2 + liboctopus/python/Makefile | 19 + liboctopus/python/demos/adc.py | 19 + liboctopus/python/demos/blink.py | 22 + liboctopus/python/demos/blink_all.py | 58 +++ liboctopus/python/demos/blink_i2c.py | 29 ++ liboctopus/python/demos/blink_lauf.py | 67 +++ liboctopus/python/demos/blink_status.py | 26 + liboctopus/python/demos/eeprom_i2c.py | 36 ++ liboctopus/python/octopus.i | 5 + 44 files changed, 8066 insertions(+) create mode 100644 firmware/93c46.c create mode 100644 firmware/93c46.h create mode 100644 firmware/Makefile create mode 100644 firmware/adc.c create mode 100644 firmware/adc.h create mode 100644 firmware/common.c create mode 100644 firmware/common.h create mode 100644 firmware/debug.c create mode 100644 firmware/debug.h create mode 100644 firmware/fifo.c create mode 100644 firmware/fifo.h create mode 100644 firmware/i2c.c create mode 100644 firmware/i2c.h create mode 100644 firmware/io.c create mode 100644 firmware/io.h create mode 100644 firmware/main.c create mode 100644 firmware/main.hex create mode 100644 firmware/octopus.hex create mode 100644 firmware/octopus_can.hex create mode 100644 firmware/protocol.h create mode 100644 firmware/pwm.c create mode 100644 firmware/pwm.h create mode 100644 firmware/spi.c create mode 100644 firmware/spi.h create mode 100644 firmware/uart.c create mode 100644 firmware/uart.h create mode 100644 firmware/usbn2mc.c create mode 100644 firmware/usbn2mc.h create mode 100644 firmware/wait.c create mode 100644 firmware/wait.h create mode 100644 liboctopus/.gitignore create mode 100644 liboctopus/Makefile create mode 100644 liboctopus/octopus.c create mode 100644 liboctopus/octopus.h create mode 100644 liboctopus/python/.gitignore create mode 100644 liboctopus/python/Makefile create mode 100644 liboctopus/python/demos/adc.py create mode 100644 liboctopus/python/demos/blink.py create mode 100644 liboctopus/python/demos/blink_all.py create mode 100644 liboctopus/python/demos/blink_i2c.py create mode 100644 liboctopus/python/demos/blink_lauf.py create mode 100644 liboctopus/python/demos/blink_status.py create mode 100644 liboctopus/python/demos/eeprom_i2c.py create mode 100644 liboctopus/python/octopus.i diff --git a/firmware/93c46.c b/firmware/93c46.c new file mode 100644 index 0000000..4af0f45 --- /dev/null +++ b/firmware/93c46.c @@ -0,0 +1,359 @@ +/* + * Author: Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "common.h" +#include "protocol.h" + +#include + + +#include "93c46.h" + +void flash_93c46_parser(char *buf) +{ + //UARTWrite("flash parser\r\n"); + switch(buf[3]) + { + case CMD_93C46_INIT: + flash_93c46_init_usb(); + break; + case CMD_93C46_DEINIT: + flash_93c46_deinit_usb(); + break; + case CMD_93C46_READ: + // read addr, length, buffer + flash_93c46_read_usb((unsigned char)buf[4], (int)buf[5], &buf[6]); + break; + case CMD_93C46_WRITE: + flash_93c46_write_usb((unsigned char)buf[4], (int)buf[5], &buf[6]); + break; + default: + //UARTWrite("default\r\n"); + answer[0] = buf[0]; + answer[1] = RSP_UNKOWN_CMD; + answer[2] = 0; + CommandAnswer(3); + } +} + +void flash_93c46_init_usb(void) +{ + answer[0] = CMD_93C46_INIT; + answer[1] = (unsigned char) flash_93c46_init(); + answer[2] = 0; + CommandAnswer(3); +} + + +int flash_93c46_init(void) +{ + //UARTWrite("init\r\n"); + SET_DDR_OUT(CS); + SET_DDR_OUT(SK); + + SET_DDR_OUT(DI); + SET_DDR_IN(DO); + + SET_DDR_OUT(DIN0); + SET_DDR_OUT(DIN1); + + CLRPIN(DIN0); + CLRPIN(DIN1); + + //SETPIN(DIN0) = D4 = low + //SETPIN(DIN1) = D4 = low + + octopus.ports[19]=PIN_OUT; + octopus.ports[18]=PIN_OUT; + octopus.ports[17]=PIN_OUT; + octopus.ports[16]=PIN_IN; + + return RSP_OK; +} + +void flash_93c46_deinit_usb(void) +{ + answer[0]=CMD_93C46_DEINIT; + answer[1]=(unsigned char)flash_93c46_deinit(); + answer[2]=0; + CommandAnswer(3); +} + +int flash_93c46_deinit(void) +{ + octopus.ports[5]=PIN_OUT; // this is wrong! + octopus.ports[6]=PIN_OUT; // this is wrong! + octopus.ports[7]=PIN_OUT; // this is wrong! + + return RSP_OK; +} + +void flash_93c46_read_usb(unsigned char address, unsigned int length, char * buf) +{ + answer[0]=CMD_93C46_READ; + answer[1]=(unsigned char)flash_93c46_read(address,length,(char*)&answer[2]); + CommandAnswer(length+2); +} + +int flash_93c46_read(unsigned char address, unsigned int length, char * buf) +{ + //UARTWrite("read\r\n"); + //SendHex((uint8_t)address); + //SendHex(flash_93c46_read_word((uint8_t)address)); + unsigned int i; + for(i = 0; i < length; i++) + buf[i] = (char)flash_93c46_read_word((uint8_t)address+i); + + return RSP_OK; +} + + +void flash_93c46_write_usb(unsigned char address, unsigned int length, char * buf) +{ + answer[0]=CMD_93C46_WRITE; + answer[1]=(unsigned char)flash_93c46_write(address,length, buf); + answer[2]=0x00; + CommandAnswer(3); +} + +int flash_93c46_write(unsigned char address, unsigned int length, char * buf) +{ + unsigned int i; + //UARTWrite("write\r\n"); + //SendHex((uint8_t)address); + //SendHex(length); + //SendHex(buf[0]); + + for(i=0;i 0) return 0; + SETPIN(SK); + _delay_us(2); + CLRPIN(SK); + _delay_us(2); + } while (GETPIN(DO)); + + return 1; +} + +void end_of_erase_write_disable(void) +{ + CLRPIN(SK); + CLRPIN(CS); + CLRPIN(DI); + SETPIN(DO); +} + +void erase_write_enable(void) +{ + start_of_ins(); + send_sb_opcode(CMD_EWEN); + send_address(0x60); +} + +void erase_write_disable(void) +{ + start_of_ins(); + send_sb_opcode(CMD_EWDS); + send_address(0x00); + end_of_erase_write_disable(); +} + + +uint8_t write_word_step(uint8_t add,uint8_t wd) +{ + start_of_ins(); + send_sb_opcode(CMD_WRITE); + send_address(add); + send_data_byte(wd); + return 1; + //return( end_of_erase_write() ); +} + +uint8_t erase_word(uint8_t add) +{ + start_of_ins(); + send_sb_opcode(CMD_ERASE); + send_address(add); + return( end_of_erase_write() ); +} + +uint8_t recv_data_word(void) +{ + uint8_t i; + uint8_t da=0; + CLRPIN(SK); + _delay_us(2); + CLRPIN(DI); + + for( i =0; i <8; i ++) + { + da *= 2; + SETPIN(SK); + _delay_us(2); + CLRPIN(SK); + if (GETPIN(DO)) da++; + _delay_us(2); + } + + CLRPIN(CS); + SETPIN(SK); + _delay_us(2); + SETPIN(CS); + CLRPIN(SK); + _delay_us(2); + return da; +} + +uint8_t flash_93c46_read_word(uint8_t add) +{ + //if(add < 0 && add > 127 ) + // return 0; + + start_of_ins(); + send_sb_opcode(CMD_READ); + send_address(add); + return( recv_data_word() ); +} + + +uint8_t flash_93c46_write_word(uint8_t add,uint8_t wd) +{ + +// if(add < 0 && add > 127 ) +// return 0; + + erase_write_enable(); + write_word_step(add,wd); + //_delay_ms(1); + + return 1; + do + { + //write_word_step(add,wd); + _delay_us(10); + } while (flash_93c46_read_word(add)!=wd); + return 1; +} + diff --git a/firmware/93c46.h b/firmware/93c46.h new file mode 100644 index 0000000..817eade --- /dev/null +++ b/firmware/93c46.h @@ -0,0 +1,113 @@ +/* + * Author: Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SPI_H +#define SPI_H + +#include +#include + + +#include "io.h" + + +#define CS (B, 0) +#define SK (B, 1) +#define DI (B, 2) +#define DO (B, 3) + + + + + + +#define DIN0 (B, 4) +#define DIN1 (B, 5) + +#define CMD_READ 0x80 +#define CMD_EWEN 0x30 +#define CMD_ERASE 0xc0 +#define CMD_WRITE 0x40 +#define CMD_ERAL 0x20 +#define CMD_WRAL 0x10 +#define CMD_EWDS 0x00 + + +#define PIN_S PB0 +#define PIN_C PB1 +#define PIN_D PB2 +#define PIN_Q PB3 + +void flash_93c46_parser(char *buf); + +int flash_93c46_init(void); +int flash_93c46_deinit(void); + +int flash_93c46_read(unsigned char address, unsigned int length, char * buf); +int flash_93c46_write(unsigned char address, unsigned int length, char* buf); + +void flash_93c46_init_usb(void); +void flash_93c46_deinit_usb(void); + +void flash_93c46_read_usb(unsigned char address, unsigned int length, char* buf); +void flash_93c46_write_usb(unsigned char address, unsigned int length, char* buf); + + +void start_of_ins(void); +void send_sb_opcode(uint8_t ins); +void send_data_byte(uint8_t da); +uint8_t end_of_erase_write(void); +void end_of_erase_write_disable(void); +void erase_write_enable(void); +void send_address(uint8_t da); +uint8_t write_word_step(uint8_t add,uint8_t wd); +uint8_t recv_data_word(void); +uint8_t erase_word(uint8_t add); +void erase_write_disable(void); + + + +uint8_t flash_93c46_read_word(uint8_t add); +uint8_t flash_93c46_write_word(uint8_t add,uint8_t wd); + + + + + + + + + + + +#endif /* SPI_H */ diff --git a/firmware/Makefile b/firmware/Makefile new file mode 100644 index 0000000..f3553b5 --- /dev/null +++ b/firmware/Makefile @@ -0,0 +1,458 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# Released to the Public Domain +# Please read the make user manual! +# +# Additional material for this makefile was submitted by: +# Tim Henigan +# Peter Fleury +# Reiner Patommel +# Sander Pool +# Frederik Rouleau +# Markus Pfaff +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + +# mth 2004/09 +# Differences from WinAVR 20040720 sample: +# - DEPFLAGS according to Eric Weddingtion's fix (avrfreaks/gcc-forum) +# - F_OSC Define in CFLAGS and AFLAGS + + +# MCU name +#MCU = atmega128 +MCU = at90can128 + +# Main Oscillator Frequency +# This is only used to define F_OSC in all assembler and c-sources. +F_OSC = 16000000 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Target file name (without extension). +TARGET = main + + +# List C source files here. (C dependencies are automatically generated.) +#SRC = $(TARGET).c uart.c usbn2mc/main/usbn960x.c usbn2mc.c usbn2mc/main/usbnapi.c + +SRC = $(TARGET).c wait.c uart.c ../usbn2mc/main/usbn960x.c usbn2mc.c ../usbn2mc/main/usbnapi.c common.c fifo.c io.c adc.c i2c.c spi.c 93c46.c pwm.c debug.c + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs +#DEBUG = dwarf-2 + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +# Place -D or -U options here +CDEFS = + +# Place -I options here +CINCS = + + +# Compiler flags. +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g$(DEBUG) +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes +#CFLAGS += -Wall +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) +CFLAGS += -DF_OSC=$(F_OSC) + + + +# Assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +ASFLAGS += -DF_OSC=$(F_OSC) + + +#Additional libraries. + +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +PRINTF_LIB = + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +SCANF_LIB = + +MATH_LIB = -lm + +# External memory options + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +# Linker flags. +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + + + +# Programming support using avrdude. Settings and variables. + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = stk500 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = com1 # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp + + + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + + +# Compiler flags to generate dependency files. +### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d +GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build sizeafter finished end + +build: elf hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) .dep/* + + + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program + +download: + avrdude -p m128 -c avrispv2 -P usb -U flash:w:main.hex + +download_can: + avrdude -p c128 -c avrispv2 -P usb -U flash:w:main.hex + +fuse: + avrdude -p m128 -c avrispv2 -P usb -U lfuse:w:0xe0:m + avrdude -p m128 -c avrispv2 -P usb -U efuse:w:0xff:m + avrdude -p m128 -c avrispv2 -P usb -U hfuse:w:0xdd:m + +fuse_can: + avrdude -p c128 -c avrispv2 -B 10 -P usb -U lfuse:w:0xe0:m + avrdude -p c128 -c avrispv2 -B 10 -P usb -U efuse:w:0xff:m + avrdude -p c128 -c avrispv2 -B 10 -P usb -U hfuse:w:0xdd:m + +usbprog: + avrdude -p c128 -c avrispv2 -P usb -U flash:w:main.hex diff --git a/firmware/adc.c b/firmware/adc.c new file mode 100644 index 0000000..a9449b7 --- /dev/null +++ b/firmware/adc.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2007 empronix (http://www.empronix.com) + * Author: Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES{} LOSS OF USE, + * DATA, OR PROFITS{} OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "common.h" +#include "protocol.h" +#include "adc.h" + +void adc_parser(char *buf) +{ + switch(buf[0]) + { + case CMD_ADC_INIT_PIN: + adc_init_usb((int)buf[2]); + break; + case CMD_ADC_GET: + adc_get_usb((int)buf[2]); + break; + case CMD_ADC_REF: + adc_ref_usb((int)buf[2]); + break; + + default: + answer[0]=buf[0]; + answer[1]=RSP_UNKOWN_CMD; + answer[2]=0; + CommandAnswer(3); + } +} + +int adc_init(int pin) +{ + if (pin >= 33 && pin <= 40) + { + octopus.ports[pin] = PIN_AD; + + switch(pin) + { + case 40: break; + case 39: break; + case 38: break; + case 37: break; + case 36: break; + case 35: break; + case 34: break; + case 33: break; + default: + return RSP_IMPOSSIBLE_PIN_CONFIG; + } + return RSP_OK; + } + return RSP_UNKOWN_PIN; +} + +void adc_init_usb(int pin) +{ + answer[0]=CMD_ADC_INIT_PIN; + answer[1]= (unsigned char)adc_init(pin); + answer[2]=0; + + CommandAnswer(3); +} + +void adc_get_usb(int pin) +{ + + uint16_t result; + //uint8_t result[2]; + + answer[0]=CMD_ADC_GET; + answer[1]=adc_get(pin,&result); + //result[0] = 0x77; + //result[1] = 0x88; + //answer[2]=(char)result[1]; //high + //answer[3]=(char)result[0]; //low + answer[2]=(char)(result>>8); //high + answer[3]=(char)(result); //low + CommandAnswer(4); +} + + +int adc_get(int pin, uint16_t *value) +{ + *value = 0; + + if (octopus.ports[pin] == PIN_AD) + { + switch (pin) + { + case 40: *value =_adc_read_channel(0); break; + case 39: *value =_adc_read_channel(1); break; + case 38: *value =_adc_read_channel(2); break; + case 37: *value =_adc_read_channel(3); break; + case 36: *value =_adc_read_channel(4); break; + case 35: *value =_adc_read_channel(5); break; + case 34: *value =_adc_read_channel(6); break; + case 33: *value =_adc_read_channel(7); break; + default: + return RSP_IMPOSSIBLE_PIN_CONFIG; + } + return RSP_OK; + } + else + { + return RSP_WRONG_PIN_CONFIG; + } +} + +void adc_ref_usb(int ref) +{ + answer[0]=CMD_ADC_REF; + answer[1]=adc_ref(ref); + CommandAnswer(2); +} + +int adc_ref(int ref) +{ + ADMUX = 0x00; + + switch(ref){ + case PARAM_ADC_AREF: break; + case PARAM_ADC_AVCC: ADMUX |= (1< + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef ADC_H +#define ADC_H + +#include +#include + + +void adc_parser(char *buf); + +int adc_init(int pin); +void adc_init_usb(int pin); + +void adc_ref_usb(int ref); +int adc_ref(int ref); + + + +int adc_get(int pin, uint16_t *value); +void adc_get_usb(int pin); +uint16_t _adc_read_channel(int mux); + +#endif /* ADC_H */ diff --git a/firmware/common.c b/firmware/common.c new file mode 100644 index 0000000..9947c59 --- /dev/null +++ b/firmware/common.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2006, Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "common.h" +#include "protocol.h" +#include "io.h" +#include "93c46.h" + + + +void common_latency_timer_init(void) +{ + // us = 256 - x/2 + octopus.latency_timer = 206; // 255 = 2us, 254 = 4us ... + + #ifdef OCTOPUS_CAN + TIMSK0 = (1< + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +enum signals {PIN_NONE,PIN_IN,PIN_OUT,PIN_TRI, + PIN_AD,PIN_RX,PIN_TX, + PIN_SS,PIN_SCK,PIN_MISO,PIN_MOSI, + PIN_SCL,PIN_SDA,PIN_PWM, + PIN_UART}; + + +#define OCTOPUS_CAN + +//#define DEBUG + +#define F_CPU 16000000UL +#define STATUS_LED_PIN PB7 +#define STATUS_LED_PORT PORTB + +/* red status led */ +#define STATUS_LED_on (STATUS_LED_PORT |= (1 << STATUS_LED_PIN)) +#define STATUS_LED_off (STATUS_LED_PORT &= ~(1 << STATUS_LED_PIN)) + + +volatile struct octopus_t +{ + volatile unsigned char latency_timer; + int ports[45]; + volatile char * msg[20]; + volatile int datatogl; + volatile unsigned int long_rx_cmd; + volatile unsigned int long_rx_index; + volatile unsigned int long_rx_bytes; + + volatile unsigned int long_index; + volatile unsigned int long_bytes; + volatile unsigned int long_running; +} octopus; + + + +void CommandAnswer(unsigned int length); +void CommandAnswerRest(void); +void USBCommandRX(char *buf); +void USBMessageIn(char *buf); + + +volatile unsigned char answer[320]; +volatile unsigned char request[320]; + +void common_latency_timer_init(void); + +void common_scheduler(void); + +void common_scheduler_add(int id,void(*userFunc)(void)); + +void common_parser(char *buf); + +void common_init(void); + +void common_hwdesc(void); + diff --git a/firmware/debug.c b/firmware/debug.c new file mode 100644 index 0000000..539a3e2 --- /dev/null +++ b/firmware/debug.c @@ -0,0 +1,72 @@ +#include +#include + +#include "uart.h" +#include "debug.h" +#include "common.h" +#include "protocol.h" + +#define UART_PORT 0 + +void debug_init(void) { + uart_init(UART_PORT); + uart_baudrate(UART_PORT, 25, 0, 0, 0); + uart_stopbits(UART_PORT, 1); + uart_databits(UART_PORT, 8); + uart_parity(UART_PORT, 'N'); +} + +void debug_deinit(void) { + uart_deinit(UART_PORT); +} + +void debug_write(char *buf) { + while(*buf) + uart_putchar(UART_PORT, *buf++); +} + +unsigned char debug_AsciiToHex(unsigned char high, unsigned char low) +{ + unsigned char new; + + // check if lower equal 9 ( ascii 57 ) + if(high <= 57) // high is a number + high = high -48; + else // high is a letter + high = high -87; + + high = high << 4; + high = high & 0xF0; + + // check if lower equal 9 ( ascii 57 ) + if(low <= 57) // high is a number + low = low -48; + else // high is a letter + low = low -87; + low = low & 0x0F; + + new = high | low; + + return new; +} + +void debug_SendHex(unsigned char hex) +{ + unsigned char high,low; + // get highnibble + high = hex & 0xF0; + high = high >> 4; + + // get lownibble + low = hex & 0x0F; + + if(high<=9) + uart_putchar(UART_PORT, high+48); + else + uart_putchar(UART_PORT, high+87); + + if(low<=9) + uart_putchar(UART_PORT, low+48); + else + uart_putchar(UART_PORT, low+87); +} diff --git a/firmware/debug.h b/firmware/debug.h new file mode 100644 index 0000000..8aa15d9 --- /dev/null +++ b/firmware/debug.h @@ -0,0 +1,5 @@ +void debug_init(void); +void debug_deinit(void); +void debug_write(char *buf); +unsigned char debug_AsciiToHex(unsigned char high, unsigned char low); +void debug_SendHex(unsigned char hex); diff --git a/firmware/fifo.c b/firmware/fifo.c new file mode 100644 index 0000000..a1e0f87 --- /dev/null +++ b/firmware/fifo.c @@ -0,0 +1,27 @@ +#include "fifo.h" + +void fifo_init (fifo_t *f, uint8_t *buffer, const uint8_t size) +{ + f->count = 0; + f->pread = f->pwrite = buffer; + f->read2end = f->write2end = f->size = size; +} + +uint8_t fifo_put (fifo_t *f, const uint8_t data) +{ + return _inline_fifo_put (f, data); +} + +uint8_t fifo_get_wait (fifo_t *f) +{ + while (!f->count); + + return _inline_fifo_get (f); +} + +int fifo_get_nowait (fifo_t *f) +{ + if (!f->count) return -1; + + return (int) _inline_fifo_get (f); +} diff --git a/firmware/fifo.h b/firmware/fifo.h new file mode 100644 index 0000000..32c3264 --- /dev/null +++ b/firmware/fifo.h @@ -0,0 +1,75 @@ +#ifndef _FIFO_H_ +#define _FIFO_H_ + +#include +#include + +typedef struct +{ + uint8_t volatile count; // # Zeichen im Puffer + uint8_t size; // Puffer-Größe + uint8_t *pread; // Lesezeiger + uint8_t *pwrite; // Schreibzeiger + uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger +} fifo_t; + +extern void fifo_init (fifo_t*, uint8_t* buf, const uint8_t size); +extern uint8_t fifo_put (fifo_t*, const uint8_t data); +extern uint8_t fifo_get_wait (fifo_t*); +extern int fifo_get_nowait (fifo_t*); + +static inline uint8_t +_inline_fifo_put (fifo_t *f, const uint8_t data) +{ + if (f->count >= f->size) + return 0; + + uint8_t * pwrite = f->pwrite; + + *(pwrite++) = data; + + uint8_t write2end = f->write2end; + + if (--write2end == 0) + { + write2end = f->size; + pwrite -= write2end; + } + + f->write2end = write2end; + f->pwrite = pwrite; + + uint8_t sreg = SREG; + cli(); + f->count++; + SREG = sreg; + + return 1; +} + +static inline uint8_t +_inline_fifo_get (fifo_t *f) +{ + uint8_t *pread = f->pread; + uint8_t data = *(pread++); + uint8_t read2end = f->read2end; + + if (--read2end == 0) + { + read2end = f->size; + pread -= read2end; + } + + f->pread = pread; + f->read2end = read2end; + + uint8_t sreg = SREG; + cli(); + f->count--; + SREG = sreg; + + return data; +} + +#endif /* _FIFO_H_ */ + diff --git a/firmware/i2c.c b/firmware/i2c.c new file mode 100644 index 0000000..b7d55fe --- /dev/null +++ b/firmware/i2c.c @@ -0,0 +1,216 @@ +/* + * Author: Benedikt Sauter + * Author: Peter Huewe, Hubert Hogel + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "common.h" +#include "protocol.h" +#include "i2c.h" + +void i2c_parser(char *buf) { +answer[0] = buf[0]; + switch(buf[0]){ + case CMD_I2C_INIT: + i2c_init_usb(); + break; + case CMD_I2C_DEINIT: + i2c_deinit_usb(); + break; + case CMD_I2C_SET_BITRATE: + i2c_set_bitrate_usb((char)buf[2]); + break; + case CMD_I2C_SEND_BYTE: + i2c_send_byte_usb((int)buf[2]); + break; + case CMD_I2C_RECV_BYTES: + i2c_reveice_bytes_usb((int)buf[3],(int)buf[1]-4, (int)buf[2]); + break; + case CMD_I2C_SEND_START: + i2c_send_start_usb(); + break; + case CMD_I2C_SEND_STOP: + i2c_send_stop_usb(); + break; + default: + answer[0]=buf[0]; + answer[1]=RSP_UNKOWN_CMD; + answer[2]=0; + CommandAnswer(3); + } +} + + +unsigned char i2c_get_twsr(void) +{ + return (TWSR & 0xF8); +} + + +void i2c_wait_for_complete(void) +{ + while (!(TWCR & (1< +#include + + +void i2c_parser(char *buf); + +int i2c_init(void); +int i2c_deinit(void); + +int i2c_set_bitrate(char); +int i2c_send_start(void); +int i2c_send_stop(void); +void i2c_send_byte(char data); +unsigned char i2c_receive_byte(void); + + +unsigned char i2c_get_twsr(void); +void i2c_wait_for_complete(void); + +void i2c_init_usb(void); +void i2c_deinit_usb(void); + +void i2c_set_bitrate_usb(char); +void i2c_send_start_usb(void); +void i2c_send_stop_usb(void); +void i2c_send_byte_usb(char data); + +void i2c_reveice_bytes_usb(int address,int len, int timeout); + + +#endif /* I2C_H */ diff --git a/firmware/io.c b/firmware/io.c new file mode 100644 index 0000000..280f892 --- /dev/null +++ b/firmware/io.c @@ -0,0 +1,512 @@ +/* + * Copyright (c) 2007 Embedded Projects (http://www.embedded-projects.net) + * Author: Benedikt Sauter = 1 && pin <= 19) || (pin >= 26 && pin <= 44)) + { + io_set_pin_direction_out(pin); + return RSP_OK; + } + return RSP_UNKOWN_PIN; +} + +void io_init_usb(uint8_t pin) +{ + answer[0] = CMD_IO_INIT_PIN; + answer[1] = (unsigned char)io_init(pin); + answer[2] = 0; + CommandAnswer(3); +} + +uint8_t io_init_port(uint8_t port) +{ + /* TODO implement this function */ + return RSP_OK; +} + +void io_init_port_usb(uint8_t port) +{ + answer[0] = CMD_IO_INIT_PORT; + answer[1] = (unsigned char)io_init_port(port); + answer[2] = 0; + CommandAnswer(3); +} + +uint8_t io_set_port_direction_out(uint8_t port,uint8_t mask) +{ + /* TODO + switch (port) + { + case 1: DDRB = mask; break; + case 2: DDRC = mask; break; // PC7 = /CS (output) - do we need to mask this ? + case 3: DDRD = mask; break; + case 4: DDRE = mask; break; // PE4 = INT4 (input) - do we need to mask this ? + case 5: DDRF = mask; break; + default: return RSP_UNKOWN_PIN; + } + */ + return RSP_OK; +} + +uint8_t io_set_port_direction_in(uint8_t port,uint8_t mask) +{ + /* TODO implement */ + return RSP_OK; +} + +uint8_t io_set_port_direction_tri(uint8_t port,uint8_t mask) +{ + /* TODO implement */ + return RSP_OK; +} + +void io_set_port_direction_out_usb (uint8_t port, uint8_t mask) +{ + answer[0] = CMD_IO_PORT_DIRECTION_OUT; + answer[1] = (unsigned char)io_set_port_direction_out (port, mask); + answer[2] = 0; + CommandAnswer(3); +} + +void io_set_port_direction_in_usb(uint8_t port, uint8_t mask) +{ + answer[0] = CMD_IO_PORT_DIRECTION_IN; + answer[1] = (unsigned char)io_set_port_direction_in (port, mask); + answer[2] = 0; + CommandAnswer(3); +} +void io_set_port_direction_tri_usb(uint8_t port, uint8_t mask) +{ + answer[0] = CMD_IO_PORT_DIRECTION_TRI; + answer[1] = (unsigned char)io_set_port_direction_tri (port, mask); + answer[2] = 0; + CommandAnswer(3); +} + + +uint8_t io_set_pin_direction_out(uint8_t pin) +{ + if((pin >= 1 && pin <= 19) || (pin >=26 && pin <=44) ) + { + octopus.ports[pin] = PIN_OUT; + + switch(pin) + { + case 1: OX_DDR1 |=(1<= 1 && pin <= 19) || (pin >=26 && pin <=44) ) + { + octopus.ports[pin] = PIN_IN; + switch (pin) + { + case 1: OX_DDR1 &=~(1<= 1 && pin <= 19) || (pin >=26 && pin <=44) ) + { + octopus.ports[pin] = PIN_TRI; + io_set_pin_direction_out(pin); + io_set_pin(pin,1); + return RSP_OK; + } + else + { + return RSP_UNKOWN_PIN; + } +} + + +void io_set_pin_direction_out_usb(uint8_t pin) +{ + answer[0] = CMD_IO_PIN_DIRECTION_OUT; + answer[1] = (unsigned char)io_set_pin_direction_out(pin); + answer[2] = 0; + CommandAnswer(3); +} + +void io_set_pin_direction_in_usb(uint8_t pin) +{ + answer[0] = CMD_IO_PIN_DIRECTION_IN; + answer[1] = (unsigned char)io_set_pin_direction_in(pin); + answer[2] = 0; + CommandAnswer(3); +} + +void io_set_pin_direction_tri_usb(uint8_t pin) +{ + answer[0] = CMD_IO_PIN_DIRECTION_TRI; + answer[1] = (unsigned char)io_set_pin_direction_tri(pin); + answer[2] = 0; + CommandAnswer(3); +} + + + +uint8_t io_get_port (uint8_t port, uint8_t *pvalue) +{ + uint8_t value; + + *pvalue = 0; + switch (port) + { + case 1: value = PINB; break; + case 2: value = PINC; break; /* PC7 = /CS */ + case 3: value = PIND; break; + case 4: value = PINE; break; /* PE4 = INTR */ + case 5: value = PINF; break; + default: return RSP_UNKOWN_PORT; + } + *pvalue = value; + return RSP_OK; +} + +void io_get_port_usb (uint8_t port) +{ + uint8_t value; + + answer[0] = CMD_IO_PORT_GET; + answer[1] = (unsigned char)io_get_port (port, &value); + answer[2] = (unsigned char)value; + CommandAnswer(3); +} + +uint8_t io_set_port(uint8_t port, uint8_t value) +{ + switch (port) + { + case 1: PORTB = value; break; + case 2: PORTC = value; break; // PC7 = /CS + case 3: PORTD = value; break; + case 4: PORTE = value; break; // PE4 = INTR + case 5: PORTF = value; break; + default: return RSP_UNKOWN_PIN; + } + return RSP_OK; +} + +void io_set_port_usb (uint8_t port, uint8_t value) +{ + answer[0] = CMD_IO_PORT_SET; + answer[1] = (unsigned char)io_set_port (port, value); + answer[2] = 0; + CommandAnswer(3); +} + + +void io_set_pin_usb(uint8_t pin, uint8_t value) +{ + answer[0] = CMD_IO_PIN_SET; + answer[1] = (unsigned char)io_set_pin(pin,value); + answer[2] = 0; + CommandAnswer(3); +} + + +uint8_t io_set_pin(uint8_t pin, uint8_t value) +{ + if(octopus.ports[pin] == PIN_OUT) + { + switch(pin) + { + case 1: if(value) OX_PORT1 |=(1< +#include + + +#define OX_PIN1 PINE +#define OX_PIN2 PINE +#define OX_PIN3 PINE +#define OX_PIN4 PINB +#define OX_PIN5 PINB +#define OX_PIN6 PINB +#define OX_PIN7 PINB +#define OX_PIN8 PINB +#define OX_PIN9 PINB +#define OX_PIN10 PINB +#define OX_PIN11 PINB +#define OX_PIN12 PIND +#define OX_PIN13 PIND +#define OX_PIN14 PIND +#define OX_PIN15 PIND +#define OX_PIN16 PIND +#define OX_PIN17 PIND +#define OX_PIN18 PIND +#define OX_PIN19 PIND + +#define OX_PIN26 PINC +#define OX_PIN27 PINC +#define OX_PIN28 PINC +#define OX_PIN29 PINC +#define OX_PIN30 PINC +#define OX_PIN31 PINC +#define OX_PIN32 PINC +#define OX_PIN33 PINF +#define OX_PIN34 PINF +#define OX_PIN35 PINF +#define OX_PIN36 PINF +#define OX_PIN37 PINF +#define OX_PIN38 PINF +#define OX_PIN39 PINF +#define OX_PIN40 PINF +#define OX_PIN41 PINE +#define OX_PIN42 PINE +#define OX_PIN43 PINE +#define OX_PIN44 PINE + +#define OX_PORT1 PORTE +#define OX_PORT2 PORTE +#define OX_PORT3 PORTE +#define OX_PORT4 PORTB +#define OX_PORT5 PORTB +#define OX_PORT6 PORTB +#define OX_PORT7 PORTB +#define OX_PORT8 PORTB +#define OX_PORT9 PORTB +#define OX_PORT10 PORTB +#define OX_PORT11 PORTB +#define OX_PORT12 PORTD +#define OX_PORT13 PORTD +#define OX_PORT14 PORTD +#define OX_PORT15 PORTD +#define OX_PORT16 PORTD +#define OX_PORT17 PORTD +#define OX_PORT18 PORTD +#define OX_PORT19 PORTD + +#define OX_PORT26 PORTC +#define OX_PORT27 PORTC +#define OX_PORT28 PORTC +#define OX_PORT29 PORTC +#define OX_PORT30 PORTC +#define OX_PORT31 PORTC +#define OX_PORT32 PORTC +#define OX_PORT33 PORTF +#define OX_PORT34 PORTF +#define OX_PORT35 PORTF +#define OX_PORT36 PORTF +#define OX_PORT37 PORTF +#define OX_PORT38 PORTF +#define OX_PORT39 PORTF +#define OX_PORT40 PORTF +#define OX_PORT41 PORTE +#define OX_PORT42 PORTE +#define OX_PORT43 PORTE +#define OX_PORT44 PORTE + +#define OX_DDR1 DDRE +#define OX_DDR2 DDRE +#define OX_DDR3 DDRE +#define OX_DDR4 DDRB +#define OX_DDR5 DDRB +#define OX_DDR6 DDRB +#define OX_DDR7 DDRB +#define OX_DDR8 DDRB +#define OX_DDR9 DDRB +#define OX_DDR10 DDRB +#define OX_DDR11 DDRB +#define OX_DDR12 DDRD +#define OX_DDR13 DDRD +#define OX_DDR14 DDRD +#define OX_DDR15 DDRD +#define OX_DDR16 DDRD +#define OX_DDR17 DDRD +#define OX_DDR18 DDRD +#define OX_DDR19 DDRD + +#define OX_DDR26 DDRC +#define OX_DDR27 DDRC +#define OX_DDR28 DDRC +#define OX_DDR29 DDRC +#define OX_DDR30 DDRC +#define OX_DDR31 DDRC +#define OX_DDR32 DDRC +#define OX_DDR33 DDRF +#define OX_DDR34 DDRF +#define OX_DDR35 DDRF +#define OX_DDR36 DDRF +#define OX_DDR37 DDRF +#define OX_DDR38 DDRF +#define OX_DDR39 DDRF +#define OX_DDR40 DDRF +#define OX_DDR41 DDRE +#define OX_DDR42 DDRE +#define OX_DDR43 DDRE +#define OX_DDR44 DDRE + + +#define OX_P1 PE5 +#define OX_P2 PE6 +#define OX_P3 PE7 +#define OX_P4 PB0 +#define OX_P5 PB1 +#define OX_P6 PB2 +#define OX_P7 PB3 +#define OX_P8 PB4 +#define OX_P9 PB5 +#define OX_P10 PB6 +#define OX_P11 PB7 +#define OX_P12 PD0 +#define OX_P13 PD1 +#define OX_P14 PD2 +#define OX_P15 PD3 +#define OX_P16 PD4 +#define OX_P17 PD5 +#define OX_P18 PD6 +#define OX_P19 PD7 + +#define OX_P26 PC0 +#define OX_P27 PC1 +#define OX_P28 PC2 +#define OX_P29 PC3 +#define OX_P30 PC4 +#define OX_P31 PC5 +#define OX_P32 PC6 +#define OX_P33 PF7 +#define OX_P34 PF6 +#define OX_P35 PF5 +#define OX_P36 PF4 +#define OX_P37 PF3 +#define OX_P38 PF2 +#define OX_P39 PF1 +#define OX_P40 PF0 +#define OX_P41 PE0 +#define OX_P42 PE1 +#define OX_P43 PE2 +#define OX_P44 PE3 + + + +void io_parser(char *buf); + +uint8_t io_init(uint8_t pin); +void io_init_usb(uint8_t pin); + +uint8_t io_init_port(uint8_t port); +void io_init_port_usb(uint8_t port); + +uint8_t io_set_port_direction_out(uint8_t port,uint8_t mask); +uint8_t io_set_port_direction_in(uint8_t port, uint8_t mask); +uint8_t io_set_port_direction_tri(uint8_t port, uint8_t mask); + + +void io_set_port_direction_out_usb (uint8_t port, uint8_t mask); +void io_set_port_direction_in_usb(uint8_t port, uint8_t mask); +void io_set_port_direction_tri_usb(uint8_t port, uint8_t mask); + +uint8_t io_set_pin_direction_out(uint8_t pin); +uint8_t io_set_pin_direction_in(uint8_t pin); +uint8_t io_set_pin_direction_tri(uint8_t pin); + +void io_set_pin_direction_out_usb(uint8_t pin); +void io_set_pin_direction_in_usb(uint8_t pin); +void io_set_pin_direction_tri_usb(uint8_t pin); + +uint8_t io_get_port (uint8_t port, uint8_t *pvalue); +void io_get_port_usb (uint8_t port); + + +uint8_t io_set_port(uint8_t port, uint8_t value); +void io_set_port_usb (uint8_t port, uint8_t value); + +uint8_t io_set_pin(uint8_t pin, uint8_t value); +void io_set_pin_usb(uint8_t pin, uint8_t value); + +uint8_t io_get_pin(uint8_t pin, uint8_t *value); +void io_get_pin_usb(uint8_t pin); + + +#define PORT(port,pin) (PORT##port) +#define DDR(port,pin) (DDR##port) +#define PIN(port,pin) (PIN##port) +#define PIN_MASK(port,pin) (1<<(pin)) + +/* Set a pin */ +#define SETPIN(pindef) PORT pindef |= PIN_MASK pindef + +/* Clear a pin */ +#define CLRPIN(pindef) PORT pindef &= ~PIN_MASK pindef + +/* Get pin value */ +#define GETPIN(pindef) (PIN pindef & PIN_MASK pindef) + +/* Toggle a pin */ +#define TOGGLEPIN(pindef) PIN pindef |= PIN_MASK pindef + +/* Set a IO to output */ +#define SET_DDR_OUT(pindef) DDR pindef |= PIN_MASK pindef + +/* Set a IO to input */ +#define SET_DDR_IN(pindef) DDR pindef &= ~PIN_MASK pindef + + + +#endif /* IO_H */ diff --git a/firmware/main.c b/firmware/main.c new file mode 100644 index 0000000..ef802a2 --- /dev/null +++ b/firmware/main.c @@ -0,0 +1,287 @@ +#include +#include +#include +#include +#include +#include + +#include "usbn2mc.h" +#define F_CPU 16000000UL +#include + +#include "../usbn2mc/main/usbnapi.h" +#include "usbn2mc.h" + +#include "common.h" +#include "protocol.h" +#include "wait.h" + +#include "io.h" +#include "adc.h" +#include "i2c.h" +#include "spi.h" +#include "pwm.h" +#include "uart.h" + +#include "93c46.h" +#include "debug.h" + +//#define DEBUG 1 + + + +SIGNAL (SIG_INTERRUPT4) +{ + USBNInterrupt (); +} + +SIGNAL (SIG_UART0_RECV) +{ + +} + +/* internal timer */ +SIGNAL (SIG_OVERFLOW0) +{ + common_scheduler (); + TCNT0 = octopus.latency_timer; +} + + +void +USBCommandRX (char *buf) +{ + int i; + +#ifdef DEBUG + debug_write("get \0"); + debug_SendHex(buf[1]); + debug_write("\r\n"); +#endif + + /* a paket can be max 255 bytes */ + if (octopus.long_rx_cmd == 1) + { +#ifdef DEBUG + debug_write("get next\r\n"); +#endif + for (i = 0; i < 64; i++) + request[octopus.long_rx_index + i] = buf[i]; + + octopus.long_rx_index = octopus.long_rx_index + i; + + if (octopus.long_rx_index >= octopus.long_rx_bytes) + { + octopus.long_rx_cmd = 0; + USBMessageIn (request); + } + } + else + { +#ifdef DEBUG + debug_write("get and execute\r\n\0"); +#endif + octopus.long_rx_index = 0; + for (i = 0; i < 64; i++) + request[octopus.long_rx_index + i] = buf[i]; + + octopus.long_rx_index = i; + + if ((unsigned int) buf[1] < 64) + { + octopus.long_rx_cmd = 0; + USBMessageIn (request); + } + else + { + octopus.long_rx_cmd = 1; + octopus.long_rx_bytes = (unsigned int) buf[1]; + } + } +} + +/* is called when received data from pc */ +void +USBMessageIn (char *buf) +{ + octopus.long_index = 0; + octopus.long_running = 0; + + STATUS_LED_on; +#ifdef DEBUG + debug_write("parser\r\n\0"); +#endif + int check = ((int) buf[0] >> 4) & 0x0F; + + switch (check) + { + case 0: + if (buf[0] == CMD_EXTERNAL_DEVICE) + { + switch (buf[2]) + { + case CMD_EXTERNAL_93C46: + flash_93c46_parser (buf); + break; + default: + ; + } + } + else + common_parser (buf); + break; + case 1: + io_parser (buf); + break; + case 2: + adc_parser (buf); + break; + case 3: + i2c_parser (buf); + break; + case 4: + spi_parser (buf); + break; + case 5: + pwm_parser (buf); + break; + case 6: + uart_parser (buf); + break; + default: + answer[0] = buf[0]; + answer[1] = RSP_UNKOWN_CMD; + answer[2] = 0; + CommandAnswer (3); + } + + STATUS_LED_off; +} + + +void +CommandAnswer (unsigned int length) +{ + int i; + + // if first packet of a lang message + if (length > 64 && octopus.long_running == 0) + { + octopus.long_index = 0; + octopus.long_bytes = length; + octopus.long_running = 1; + length = 64; + } + + USBNWrite (FIFOTXC1, FLUSH); + + for (i = 0; i < length; i++) + USBNWrite (TXD1, answer[octopus.long_index + i]); + + /* control togl bit */ + if (octopus.datatogl == 1) + { + USBNWrite (FIFOTXC1, TX_LAST + TX_EN + TX_TOGL); + octopus.datatogl = 0; + } + else + { + USBNWrite (FIFOTXC1, TX_LAST + TX_EN); + octopus.datatogl = 1; + } +} + + +void +CommandAnswerRest (void) +{ + if (octopus.long_running == 1) + { + if (octopus.long_index < octopus.long_bytes) + { + int dif = octopus.long_bytes - octopus.long_index; + octopus.long_index = octopus.long_index + 64; + + if (dif > 64) + CommandAnswer (64); + + else + { + /* last packet */ + CommandAnswer (dif); + octopus.long_running = 0; + } + } + } +} + + +int +main (void) +{ + DDRB = 0xFF; + PORTB = 0xFF; + + + int interf; + int conf; + + + STATUS_LED_off; + + USBNInit (); + + // setup your device + USBNDeviceVendorID (0x1781); // 0x0400 is the number from national + USBNDeviceProductID (0x0c65); // add your product id + USBNDeviceBCDDevice (0x0001); // you can use it as version e.g. version 1.02 + + char lang[] = { 0x09, 0x04, 0x00 }; + _USBNAddStringDescriptor (lang); // language descriptor + + + /* Attention!!! Descriptors must be a factor of 8 (error in the stack) */ + USBNDeviceManufacture ("EmbeddedProjects"); + USBNDeviceProduct ("OctopusUSB Interface Converter and I/O Extension"); + USBNDeviceSerialNumber ("20081108"); + + conf = USBNAddConfiguration (); + + USBNConfigurationPower (conf, 100); + + interf = USBNAddInterface (conf, 0); + USBNAlternateSetting (conf, interf, 0); + + /* communication */ + USBNAddInEndpoint (conf, interf, 1, 0x01, BULK, 64, 0, &CommandAnswerRest); + USBNAddOutEndpoint (conf, interf, 1, 0x01, BULK, 64, 0, &USBCommandRX); + + USBNInitMC (); + + octopus.datatogl = 0; + octopus.long_rx_cmd = 0; + + /* start usb chip */ + USBNStart (); + + /* UARTInit2(38400,8,'N',1); */ + #ifdef DEBUG + debug_init(); + #endif + + /* hello world led pattern */ + DDRC = 0xFF; + PORTC = 0xAA; + delay_250ms (); + PORTC = 0xD5; + delay_250ms (); + PORTC = 0x80; + + // testpin + //PORTB = 0xFF; + //PORTB = 0x00; + + while (1); + + return 0; +} diff --git a/firmware/main.hex b/firmware/main.hex new file mode 100644 index 0000000..3d38158 --- /dev/null +++ b/firmware/main.hex @@ -0,0 +1,844 @@ +:100000000C94FA000C9417010C9417010C9417012E +:100010000C9417010C9408030C9417010C9417010D +:100020000C9417010C9417010C9417010C941701F0 +:100030000C9475170C9417010C9417010C9417016C +:100040000C9417010C94E1020C9417010C94170105 +:100050000C9417010C9419010C9417010C941701BE +:100060000C9417010C9417010C9417010C941701B0 +:100070000C9417010C9417010C9417010C941701A0 +:100080000C9417010C9417010C9417010C94170190 +:100090000C941701AA0DAC0DAE0DB00DB20DB40D40 +:1000A000B60DB80DBA0DBC0DBE0DC00DC20DC40D00 +:1000B000C60DC80DCA0DCC0DCE0DFC0DFC0DFC0DF2 +:1000C000FC0DFC0DFC0DD00DD20DD40DD60DD80DB0 +:1000D000DA0DDC0DDE0DE00DE20DE40DE60DE80DB0 +:1000E000EA0DEC0DEE0DF00DF20DF60D490E4B0E76 +:1000F0004D0E4F0E510E530E550E570E590E5B0EF0 +:100100005D0E5F0E610E630E650E670E690E6B0E5F +:100110006D0E9B0E9B0E9B0E9B0E9B0E9B0E6F0EF1 +:10012000710E730E750E770E790E7B0E7D0E7F0E9F +:10013000810E830E850E870E890E8B0E8D0E8F0E0F +:10014000910E950E090F0F0F150F1B0F210F270F83 +:100150002D0F330F390F3F0F450F4B0F510F570F17 +:100160005D0F630F690F6F0F750F060F060F060FF8 +:10017000060F060F060F7B0F810F870F8D0F930F52 +:10018000990F9F0FA50FAB0FB10FB70FBD0FC30F87 +:10019000C90FCF0FD50FDB0FE10FE70F37103A1064 +:1001A0003D1040104310461049104C104F10521093 +:1001B000551058105B105E106110641067106A10C3 +:1001C0006D1034103410341034103410341070109A +:1001D0007310761079107C107F10821085108810B3 +:1001E0008B108E109110941097109A109D10A010E3 +:1001F000A310A61011241FBECFEFD0E1DEBFCDBFEC +:1002000011E0A0E0B1E0E2E4F4E300E00BBF02C0E3 +:1002100007900D92A435B107D9F714E0A4E5B1E039 +:1002200001C01D92A93BB107E1F70C9423010C9486 +:1002300000001F920F920FB60F9211240F900FBE65 +:100240000F901F901895CCEFD0E1DEBFCDBF8FEFA0 +:1002500084B985B92F980E94650781E897E10E94CB +:10026000B00785E69CE00E94B50781E090E00E941F +:10027000BA07DE011196EBE4F1E083E001900D9204 +:100280008150E1F7CE0101960E94AF0B80E091E032 +:100290000E944B0C81E191E00E94430C82E491E0CA +:1002A0000E943B0C0E94850B4C0164E670E00E94AA +:1002B000C80760E070E0C4010E94F10A3C0140E020 +:1002C00050E0BC01C4010E94E90720EFA22E21E00A +:1002D000B22ECC24DD2490E4E92EF12C02E021E0C2 +:1002E00030E041E050E0B301C4010E94860A87E794 +:1002F000A82E82E0B82E21E030E041E050E0B301CA +:10030000C4010E94BE0A0E940A071092E1011092E5 +:10031000E0011092E3011092E2010E94790C8FEF4C +:1003200087B98AEA88B90E942C0385ED88B90E94B2 +:100330002C0380E888B9FFCF0F931F93CF93DF93EF +:10034000EC0181349105B0F08091EC019091ED01C8 +:10035000892B81F41092E9011092E801D093EB010E +:10036000C093EA0181E090E09093ED018093EC016D +:10037000C0E4D0E068E08BE20E94500700E010E0AB +:100380000EC0E091E801F091E901E00FF11FEE5C91 +:10039000FC4F608189E20E9450070F5F1F4F0C17CE +:1003A0001D0779F78091E0019091E101019749F4EF +:1003B00067E08BE20E9450071092E1011092E00189 +:1003C0000AC063E08BE20E94500781E090E09093C6 +:1003D000E1018093E001DF91CF911F910F9108958A +:1003E0008091EC019091ED01019771F52091E80168 +:1003F0003091E9018091EA019091EB0128173907CA +:1004000018F52091EA013091EB018091E80190917B +:10041000E901281B390B8091E8019091E901805C8A +:100420009F4F9093E9018093E801213431052CF02E +:1004300080E490E00E949C010895C9010E949C0103 +:100440001092ED011092EC010895FC011092E90167 +:100450001092E8011092ED011092EC0100002F9A29 +:100460002081822F82958F7099278230910511F11A +:10047000833091052CF4009761F0019759F516C06F +:1004800084309105F9F084309105C4F0059711F599 +:100490001DC0263039F48281813039F5CF010E94A8 +:1004A000421723C0CF010E94F30C1FC0CF010E944E +:1004B00084111BC0CF010E94E71217C0CF010E9418 +:1004C0002A1413C0CF010E945C150FC0CF010E94F7 +:1004D00092180BC02093320383E080933303109271 +:1004E000340383E090E00E949C012F980895CF93FD +:1004F000DF93EC018091E2019091E301019751F5C6 +:1005000020E030E0E091E401F091E501E20FF31F1B +:10051000DE01A20FB31F8C91EE50FE4F80832F5F40 +:100520003F4F2034310571F78091E4019091E5014E +:10053000805C9F4F9093E5018093E4012091E4015A +:100540003091E5018091E6019091E7012817390784 +:10055000A8F11FC01092E5011092E40120E030E004 +:10056000E091E401F091E501E20FF31FDE01A20F3B +:10057000B31F8C91EE50FE4F80832F5F3F4F20348E +:10058000310571F73093E5012093E401A981A0348E +:1005900048F41092E3011092E20182EF91E00E9490 +:1005A00025020CC081E090E09093E3018093E2018A +:1005B0008A2F99279093E7018093E601DF91CF91ED +:1005C00008951F920F920FB60F9211242F933F930D +:1005D0004F935F936F937F938F939F93AF93BF934B +:1005E000EF93FF930E94C50C80915D0186BDFF9142 +:1005F000EF91BF91AF919F918F917F916F915F919B +:100600004F913F912F910F900FBE0F901F90189513 +:100610001F920F920FB60F9211242F933F934F9377 +:100620005F936F937F938F939F93AF93BF93EF935A +:10063000FF930E94530CFF91EF91BF91AF919F9157 +:100640008F917F916F915F914F913F912F910F907B +:100650000FBE0F901F90189520E080E49CE9019751 +:10066000F1F72F5F2931C9F70895FF920F931F9378 +:10067000162F042FF22E9C01442737FD4095542F4E +:1006800060E472E48FE090E00E94D0192150304085 +:10069000163061F0173019F0153019F404C0E1E09C +:1006A00003C0E1E004C0E0E070E002C0E0E071E01F +:1006B000053439F00F3419F451E041E004C050E042 +:1006C00001C051E040E082E0F81611F462E001C0A0 +:1006D00060E0832F992787FD9A958093C50020932A +:1006E000C40088E18093C100770FEE0FEE0FE72B77 +:1006F0005295550F507E5E2B4295407F452B660FDD +:10070000660F660F642B6093C2001F910F91FF90DC +:1007100008951092C50089E18093C40088E1809318 +:10072000C10086E08093C20008950895982F8091BB +:10073000C00085FFFCCF9093C60008958091C00053 +:1007400087FFFCCF8091C600992708958A3310F463 +:10075000805301C087556A3310F4605301C0675558 +:100760006F708295807F682B862F99270895FC01F2 +:1007700007C08091C00085FFFCCF31969093C600E2 +:1007800090819923B1F70895982F92959F70282F03 +:100790002F709A3030F48091C00085FFFCCF905DBF +:1007A00005C08091C00085FFFCCF995A9093C60088 +:1007B0002A3030F48091C00085FFFCCF205D05C059 +:1007C0008091C00085FFFCCF295A2093C600089570 +:1007D00087E280939A0485E28093990490E2909353 +:1007E0009B0410929C0428E030E030939E042093F8 +:1007F0009D0483E28093A60481E28093A5049093F4 +:10080000A7041092A8043093AA042093A904089581 +:1008100008956091B20481E20E945007089568E053 +:100820008BE20E94500761E188E20E94500768E075 +:100830008FE20E94500761E18CE20E94500761E064 +:100840008FE20E9450071092E1011092E00165E0F2 +:1008500083E20E94500708950F931F938C0160E478 +:1008600080E20E945007F8016281605884E00E9493 +:100870005007F80182818093B1041F910F91089570 +:100880000F931F93CF93DF93EC01288539851216C0 +:100890001306DCF58E819F81821793071CF568E0B3 +:1008A00083E20E94500700E010E00FC08A859B851C +:1008B000E80FF91F608181E20E9450078E819F81BD +:1008C00001969F838E830F5F1F4FEE81FF81888586 +:1008D0009985083011051CF4E817F9073CF3E8176F +:1008E000F90724F061E087E20E9450078B81813094 +:1008F00031F465E089810E9450071B8206C061E0E7 +:1009000089810E94500781E08B83DF91CF911F91F5 +:100910000F910895CF93DF93CDB7DEB724970FB62D +:10092000F894DEBF0FBECDBFDC01FC012281338114 +:100930001092AC041092AB0481E08093A804832F42 +:1009400099278230D9F0833069F1813009F057C09E +:100950008091850499279093AE048093AD0485E837 +:1009600094E09093B0048093AF04868197818034A3 +:10097000910509F044C088E090E029C0FD0186811E +:1009800097819093AE048093AD04E22FFF27EE0F82 +:10099000FF1F8091970490919804E80FF91F8081C0 +:1009A000918129C02223C1F0E22FFF27EE0FFF1F04 +:1009B0008091F0019091F101E80FF91F0190F08111 +:1009C000E02DF093B004E093AF04808199279093D9 +:1009D000AE048093AD0413C094E0998383E08A83CE +:1009E00089E08B839C8384E090E09093AE048093B5 +:1009F000AD04CE0101969093B0048093AF0485EAD4 +:100A000094E00E94400424960FB6F894DEBF0FBE17 +:100A1000CDBFDF91CF910895CF93DF9382E20E9403 +:100A20002B07C82FDD27C5FF1AC068E083E20E94AC +:100A30005007C6FF10C02091AB043091AC048091E8 +:100A4000AD049091AE04281739072CF485EA94E0A0 +:100A50000E94400404C061E087E20E945007DF91D9 +:100A6000CF9108951F93CF93DF9388E00E942B07C7 +:100A7000182FC82FDD27C6FF18C060E085E00E9450 +:100A8000500760E884E00E94500760E080E20E9426 +:100A9000500768E083E20E94500761E087E20E940D +:100AA000500762E085E00E945007C4FF04C060EC7C +:100AB00089E00E94500717FF04C060ED89E00E94A2 +:100AC0005007DF91CF911F9108958AE00E942B0774 +:100AD000992780FF03C00E940C05089581FF0DC077 +:100AE0008AE20E942B0780917204813061F4E091C8 +:100AF0007504F09176040995089582E30E942B070E +:100B00008AE30E942B0708958EE00E942B0768E07D +:100B10008FE20E94500761E08FE20E94500720910F +:100B2000AD043091AE048091A9049091AA0482177B +:100B300093075CF468E083E20E94500761E087E27B +:100B40000E94500781E08093A8040895AF92BF925D +:100B5000CF92DF92EF92FF920F931F93CF93DF9389 +:100B6000CDB7DEB728970FB6F894DEBF0FBECDBF66 +:100B700086E20E942B0786FF7EC08E010F5F1F4F0B +:100B8000580169E0C62ED12CCC0EDD1E809199044F +:100B90000E942B07F80181938F017501EC15FD056B +:100BA000A9F768E087E20E94500768E083E20E94AC +:100BB000500780E20E942B078F77682F80E20E9407 +:100BC000500789819927807690708032910509F4C9 +:100BD00040C080349105D1F1892BF1F5F501818177 +:100BE0008630D9F0873048F48130F1F18130C8F097 +:100BF0008330D1F1853081F521C0893019F18A30F7 +:100C000018F4883049F505C08A3071F18B3021F530 +:100C100020C0C5010E94090427C0C5010E948A04A2 +:100C200023C068E083E20E94500761E081E20E94F5 +:100C3000500760E081E20E9450070BC0C5010E948E +:100C40002C0412C0C5010E940F040EC0C5010E94F1 +:100C5000080765E083E206C080E20E942B07805807 +:100C6000682F80E20E945007F70180818823D1F429 +:100C700065E083E215C02091AD043091AE0480910F +:100C8000A9049091AA048217930764F41092AE0409 +:100C90001092AD0468E083E20E94500761E087E2B1 +:100CA0000E94500728960FB6F894DEBF0FBECDBF46 +:100CB000DF91CF911F910F91FF90EF90DF90CF9038 +:100CC000BF90AF900895CF92DF92EF92FF920F9373 +:100CD0001F93CF93DF93CDB7DEB7C054D0400FB68C +:100CE000F894DEBF0FBECDBF8CE00E942B07992782 +:100CF00080FF03C00E94A6057BC081FF2AC08EE250 +:100D00000E942B078DE20E942B0789838E010F5FC3 +:100D10001F4F6801FFE3EF2EF12CE00EF11E0F5F75 +:100D20001F4F0E941907F80180830E151F05B9F7A0 +:100D300080915401813031F4E0915701F0915801D4 +:100D4000C601099568E08FE20E94500761E08FE2DA +:100D50002BC082FF2CC086E30E942B0785E30E94F4 +:100D60002B0789838E010F5F1F4F6801EFE3EE2E83 +:100D7000F12CE00EF11E0F5F1F4F0E941907F801C2 +:100D800080830E151F05B9F780915501813031F42C +:100D9000E0915901F0915A01C601099568E087E395 +:100DA0000E94500761E087E30E94500721C083FF43 +:100DB0001FC08EE30E942B078E010F5F1F4F68013B +:100DC00071E4E72EF12CEC0EFD1E8DE30E942B0743 +:100DD000F80181938F01EE15FF05B9F78091560157 +:100DE000813031F4E0915701F0915801C601099525 +:100DF000C05CDF4F0FB6F894DEBF0FBECDBFDF91F2 +:100E0000CF911F910F91FF90EF90DF90CF900895B9 +:100E10000895089581E080936A0080E18DBB83B3DB +:100E2000876083BB84B3836084BB3F9A479A78947E +:100E3000089588B1805888B984B322E0822784BBA2 +:100E40000000000080B198B1905898B994B39227EF +:100E500094BB992708959FEF91B982B988B18058C2 +:100E600088B984B395E0892784BB88B1805888B954 +:100E700084B3892784BB000011B80E941907992701 +:100E8000089582B988B1805888B984B391E08927E0 +:100E900084BB88B1805888B984B3892784BB0895FE +:100EA00082B98FEF81B988B1805888B984B395E051 +:100EB000892784BB88B1805888B984B3892784BBCB +:100EC000862F0E9441070895089582E1809385044A +:100ED00081E08093860480E191E090938804809380 +:100EE00087041092890410928A0410928B0488E07F +:100EF00080938C0410928E0410928D0410929004B2 +:100F000010928F0410929204109291041092930404 +:100F10001092940410929504109296041092540129 +:100F2000109255011092560110927204109273049F +:100F30001092740410927C0410927B041092EF01C2 +:100F40001092EE01089590938E0480938D04709317 +:100F5000900460938F0450939204409391040895F9 +:100F600090938E0480938D040895909390048093C1 +:100F70008F04089590939204809391040895809330 +:100F80008904089580938A04089580938B040895BA +:100F9000CF93DF939C01CB01E0917B04F0917C0423 +:100FA00062E070E00E94BD190FC0A081B181828112 +:100FB000823039F4ED018D8199278217930709F466 +:100FC00068870780F085E02D309779F7DF91CF9122 +:100FD0000895CF93DF939C01E0917B04F0917C0412 +:100FE00014C0A081B1818281843061F48481992709 +:100FF0008217930739F4868199278617970711F48A +:10100000ED014B830780F085E02D309751F7DF919C +:10101000CF910895BF92CF92DF92EF92FF920F93FC +:101020001F93CF93DF936C01162FF42EB22EC09135 +:101030007B04D0917C042097A1F489E090E00E9489 +:10104000C418FC0190937C0480937B04D182C082FD +:10105000138310861782F282B4820583E68215C05C +:10106000EC018F8198850097D9F789E090E00E9484 +:10107000C418FC0198878F83D182C0821383F282C7 +:10108000B4820583E68210861782DF91CF911F918B +:101090000F91FF90EF90DF90CF90BF900895EF9267 +:1010A000FF921F93CF93DF937C01C091EE01D0910B +:1010B000EF01209711F011E012C085E090E00E944E +:1010C000C418FC019093EF018093EE01F182E0825D +:1010D00012821482138210E012C01F5FEC018B8118 +:1010E0009C810097D1F785E090E00E94C418FC0134 +:1010F0009C838B83F182E082128314821382812F7E +:101100009927DF91CF911F91FF90EF900895EF9273 +:10111000FF920F931F93CF93DF93E091EE01F09135 +:10112000EF0180E090E00380F481E02D019630979C +:10113000D1F7880F991F0E94C4189093F1018093F2 +:10114000F0010091EE011091EF01E801E880F980D3 +:101150008A81C82FDD27CC0FDD1F8091F00190918F +:10116000F101C80FD91FF701808199270E94C41887 +:101170009983888320E030E017C0E801EA81FF27E7 +:10118000EE0FFF1F8091F0019091F101E80FF91F20 +:101190000190F081E02DE20FF31FD701A20FB31FE2 +:1011A0008C9180832F5F3F4FF7018081992728170B +:1011B00039071CF3E8018B819C81009711F08C01A9 +:1011C000C4CFDF91CF911F910F91FF90EF900895C1 +:1011D0004F925F926F927F928F929F92AF92BF9247 +:1011E000CF92DF92EF92FF920F931F93CF93DF93F3 +:1011F000E0917B04F0917C046624772409C082810D +:10120000823019F40894611C711C0780F085E02D70 +:101210003097A9F74301880C991CC4010E94C41897 +:101220009093980480939704E1E0EE2EF12CAA2489 +:10123000BB2455C0E0917B04F0917C0479E0C72E7B +:10124000D12C15C0A081B181848199278E159F056D +:1012500019F48381C80ED11CED018D818E1521F406 +:101260008281823009F45D010780F085E02D30979E +:1012700049F7009197041091980402501040080D0E +:10128000191DC6010E94C418F8019183808320E0D3 +:1012900030E0E0919704F0919804E80DF91D329741 +:1012A0000190F081E02DE20FF31FD501A20FB31FD3 +:1012B0008C9180832F5F3F4F2930310551F7E091AA +:1012C0009704F0919804E80DF91D32970190F08190 +:1012D000E02D8C2D875F82830894E11CF11C6E1435 +:1012E0007F040CF0A7CF61E0C62ED12C59E0A52ECB +:1012F000B12C4424552442E0842E912CA1C0A0910D +:101300007B04B0917C0412C0ED91FC911197818116 +:10131000823049F4858199278C159D0521F48481BB +:10132000482E552405C0ED01AF81B885109761F7AF +:1013300031E0E32EF12C79C060917B0470917C0444 +:101340006DC0FB01C081D1818981843009F063C007 +:10135000868199278E159F0509F05DC084819927A4 +:101360008C159D0509F057C0950140E050E0E091D3 +:101370009704F0919804E80DF91D32970190F081DF +:10138000E02DE20FF31FDE01A40FB51F8C918083C7 +:101390002F5F3F4F4F5F5F4F4930510541F789E065 +:1013A00090E0A80EB91EC0917B04D0917C0431C09E +:1013B0008A81853059F58C8199278C159D0531F5E9 +:1013C0008D8199278E159F0509F508811981950151 +:1013D00040E050E0E0919704F0919804E80DF91D89 +:1013E00032970190F081E02DE20FF31FD801A40F96 +:1013F000B51F8C9180832F5F3F4F4F5F5F4F47300A +:10140000510541F7E7E0F0E0AE0EBF1E0F80D88532 +:10141000C02D209769F6EB016F8178856115710504 +:1014200009F08FCF0894E11CF11C4E145F040CF0FE +:1014300083CF0894C11CD11CE2E0F0E08E0E9F1E09 +:101440006C147D040CF05BCFDF91CF911F910F9155 +:10145000FF90EF90DF90CF90BF90AF909F908F90D4 +:101460007F906F905F904F9008956F927F928F92D0 +:101470009F92AF92BF92CF92DF92EF92FF920F9323 +:10148000CF93DF935C013B014901E0917B04F09134 +:101490007C0416C0A081B18184819927A816B90661 +:1014A00061F4868199278615970539F48281843005 +:1014B00021F4ED018C818F5F8C830780F085E02D16 +:1014C000309741F787E090E00E94C418FC0187E064 +:1014D000808385E0818382820383F582E482C682F1 +:1014E000EE24062D2A2D45E067E0CF010E940A0870 +:1014F000DF91CF910F91FF90EF90DF90CF90BF9051 +:10150000AF909F908F907F906F900895AF92BF9211 +:10151000CF92DF92EF92FF920F93FC01A114B104DE +:1015200001F14230510571F04330510599F04130DD +:101530005105B9F481E080937204B0927604A092D0 +:1015400075040FC081E080937304B0927804A09278 +:10155000770407C081E080937404B0927A04A0926B +:10156000790420583F4FCF010E94350A0F91FF9018 +:10157000EF90DF90CF90BF90AF900895AF92BF9261 +:10158000CF92DF92EF92FF920F93FC014230510510 +:1015900071F04330510599F041305105B9F481E0C3 +:1015A00080935401B0925801A09257010FC081E07E +:1015B00080935501B0925A01A092590107C081E071 +:1015C00080935601B0925C01A0925B01CF010E9412 +:1015D000350A0F91FF90EF90DF90CF90BF90AF90C2 +:1015E0000895CF92DF92EF920F931F93CF93DF93E3 +:1015F0006C018B01A0917B04B0917C04C0E0D0E031 +:1016000014C02D913C911197F90185818C1551F4ED +:10161000FD018281823031F4F90184818F5F8483FE +:10162000C82FDD27FD01A781B085109751F789E00C +:1016300090E00E94C418FC0189E0808384E08183EB +:101640000283138214821582168217821086EC2E72 +:1016500000E02C2D44E069E0CF010E940A08CE0191 +:10166000DF91CF911F910F91EF90DF90CF90089570 +:10167000BF92CF92DF92EF92FF920F931F93CF937F +:10168000DF936C017B01142FB22EA0917B04B091EB +:101690007C04C0E0D0E014C02D913C911197F90179 +:1016A00085818C1551F4FD018281823031F4F9017C +:1016B00084818F5F8483C82FDD27FD01A781B085DA +:1016C000109751F789E090E00E94C418FC0189E06E +:1016D000808384E08183E282138214821583B68240 +:1016E00007831086EC2E00E02C2D44E069E0CF014A +:1016F0000E940A08CE01DF91CF911F910F91FF90B8 +:10170000EF90DF90CF90BF900895EF920F931F93CB +:10171000109196041F5F1093960489E090E00E9458 +:10172000C418FC0189E0808389E090E09383828380 +:1017300082E0818314821583168280EA87838AE19E +:101740008087EE2400E020E042E069E0CF010E94C3 +:101750000A08812F99271F910F91EF900895CF9339 +:10176000DF93EC01FC0101900020E9F7E81BF90B85 +:10177000CF01880F991F0E94C4189C01FE0101909F +:101780000020E9F7EC1BFD0BEE0FFF1FDC01EC93D3 +:1017900083E0F901818340E050E009C0FE01E40FDD +:1017A000F51F80818C93FD0111824F5F5F4F129670 +:1017B000FE0101900020E9F73197EC1BFD0B4E175D +:1017C0005F0760F3C9010E944F089927DF91CF910D +:1017D0000895EF92FF920F931F93CF93DF938C01A5 +:1017E0007B01CA010E94AF0B9C01E0917B04F09148 +:1017F0007C0414C0A081B1818281843061F4848131 +:1018000099278017910739F4868199278E159F05AE +:1018100011F4ED0128870780F085E02D309751F70E +:10182000DF91CF911F910F91FF90EF9008950F934B +:101830001F93CF93DF938C01CB010E94AF0B9C01D0 +:10184000E0917B04F0917C040FC0A081B181828182 +:10185000823039F4ED018D8199278017910709F4C1 +:101860002E830780F085E02D309779F7DF91CF91B7 +:101870001F910F9108950E94AF0B1816190614F4CA +:101880008093950408950E94AF0B1816190614F45E +:101890008093940408950E94AF0B1816190614F44F +:1018A0008093930408951F9386E00E942B07992745 +:1018B00086FF03C00E9463060EC082FF03C00E9421 +:1018C000650509C081FF03C00E94320504C084FF82 +:1018D00002C00E94840587E00E942B07182F60E059 +:1018E00087E00E945007612F87E00E9450071F91F8 +:1018F00008950E94E8080E9487080E94E80361E0BA +:1019000080E00E94500780E00E942B0780FDFBCF03 +:1019100062E081E00E94500760E884E00E94500786 +:1019200060E480E20E94500768E083E20E94500772 +:1019300069E087E20E9450076FE08DE00E94500747 +:101940006FE08BE00E94500768ED89E00E9450072D +:1019500063E38FE00E94500766ED87E00E94500726 +:1019600062E085E00E9450076CEC80E00E94500726 +:1019700008958EEC80935D0181E080936E008091EC +:101980005D0186BD83E084BD08950895089583E0D8 +:101990008093320381E0809333038BE080933403A0 +:1019A0002FE62093350393E69093360384E78093E4 +:1019B0003703209338039093390381E680933A03E9 +:1019C0008EE680933B038FE580933C0380E3809316 +:1019D0003D0381E380933E0310923F038EE090E04D +:1019E0000E949C010895FC018081833011F40E94C3 +:1019F000C70C0895CF93DF93C1E0D0E08C2F0E94F5 +:101A00000B0E2196C431D105C9F7CAE1D0E08C2F65 +:101A10000E940B0E2196CD32D105C9F7DF91CF91EF +:101A20000895CF93DF93DC01EC01EA81FB812191E2 +:101A30008E81815019F48981E81BF109ED01FB8346 +:101A4000EA838E839FB7F8948C9181508C939FBFCB +:101A5000822F9927DF91CF910895FC011082758321 +:101A60006483738362834183478346830895CF935E +:101A7000DF93DC019C91ED018981981718F080E0DB +:101A800090E016C0ED01EC81FD8161938F81815062 +:101A900019F48981E81BF109ED018F83FD83EC8343 +:101AA0009FB7F8948C918F5F8C939FBF81E090E0FB +:101AB000DF91CF910895FC0180818823E9F3CF0164 +:101AC0000E94110D99270895FC018081882319F443 +:101AD0008FEF9FEF0895CF010E94110D9927089570 +:101AE00081E090E0089581E090E0089581E090E049 +:101AF000089581E090E00895CF93DF93CDB7DEB7EE +:101B000022970FB6F894DEBF0FBECDBF282F8150AD +:101B1000833120F08951833108F06EC0E22FFF2716 +:101B2000EE0FFF1FE35AFE4F82E090E09283818325 +:101B3000822F9927AA27BB27FC013197EC32F105A8 +:101B400008F05AC0E65BFF4FEE0FFF1F0590F491BF +:101B5000E02D09946D9A47C06E9A49C06F9A43C0B0 +:101B6000209A45C0219A3FC0229A41C0239A3BC087 +:101B7000249A3DC0259A37C0269A39C0279A33C087 +:101B8000509A35C0519A2FC0529A31C0539A2BC0E7 +:101B9000549A2DC0559A27C0569A29C0579A23C0E7 +:101BA000389A25C0399A1FC03A9A21C03B9A1BC067 +:101BB0003C9A1DC03D9A17C03E9A19C0879A13C01F +:101BC000869A15C0859A0FC0849A11C0839A0BC05B +:101BD000829A0DC0819A07C0809A09C0689A03C092 +:101BE000699A05C06A9A81E090E008C06B9AE1E0CA +:101BF000F0E0FA83E98304C084E090E09A8389836B +:101C000089819A8122960FB6F894DEBF0FBECDBFB0 +:101C1000DF91CF910895982F8150833130F0895111 +:101C2000833118F084E090E00895892F0E947C0DA4 +:101C300081E090E00895CF93DF93CDB7DEB7229790 +:101C40000FB6F894DEBF0FBECDBF282F8150833171 +:101C500020F08951833108F06EC0E22FFF27EE0F8C +:101C6000FF1FE35AFE4F81E090E092838183822F31 +:101C70009927AA27BB27FC013197EC32F10508F020 +:101C80005AC0EA58FF4FEE0FFF1F0590F491E02D68 +:101C900009946D9847C06E9849C06F9843C02098CA +:101CA00045C021983FC0229841C023983BC024984A +:101CB0003DC0259837C0269839C0279833C0509822 +:101CC00035C051982FC0529831C053982BC05498AA +:101CD0002DC0559827C0569829C0579823C03898CA +:101CE00025C039981FC03A9821C03B981BC03C982A +:101CF0001DC03D9817C03E9819C0879813C086989C +:101D000015C085980FC0849811C083980BC0829825 +:101D10000DC0819807C0809809C0689803C0699871 +:101D200005C06A9881E090E008C06B98E1E0F0E0BF +:101D3000FA83E98304C084E090E09A8389838981EF +:101D40009A8122960FB6F894DEBF0FBECDBFDF9109 +:101D5000CF910895FB011082833091F0843028F4F4 +:101D6000813051F0823029F409C0843059F0853037 +:101D700059F085E090E0089583B107C086B105C0B1 +:101D800089B103C08CB101C08FB1808381E090E044 +:101D90000895833091F0843028F4813051F08230FE +:101DA00029F409C0843059F0853069F084E090E06E +:101DB000089565B905C068B903C06BB901C06EB9B3 +:101DC00081E090E0089561BB81E090E00895282FC4 +:101DD000E82FFF27EE0FFF1FE35AFE4F818192810C +:101DE000029719F086E090E00895822F9927AA279C +:101DF000BB27FC013197EC32F10540F4EE55FF4F63 +:101E0000EE0FFF1F0590F491E02D099484E090E01F +:101E10000895662311F0759ADDC07598DBC06623BE +:101E200011F0769AD7C07698D5C0662311F0779ACC +:101E3000D1C07798CFC0662311F0289ACBC02898DC +:101E4000C9C0662311F0299AC5C02998C3C066236A +:101E500011F02A9ABFC02A98BDC0662311F02B9AB0 +:101E6000B9C02B98B7C0662311F02C9AB3C02C9838 +:101E7000B1C0662311F02D9AADC02D98ABC066237A +:101E800011F02E9AA7C02E98A5C0662311F02F9AA4 +:101E9000A1C02F989FC0662311F0589A9BC05898F4 +:101EA00099C0662311F0599A95C0599893C066233A +:101EB00011F05A9A8FC05A988DC0662311F05B9A20 +:101EC00089C05B9887C0662311F05C9A83C05C98D8 +:101ED00081C0662311F05D9A7DC05D987BC066234A +:101EE00011F05E9A77C05E9875C0662311F05F9A14 +:101EF00071C05F986FC0662311F0409A6BC0409824 +:101F000069C0662311F0419A65C0419863C0662399 +:101F100011F0429A5FC042985DC0662311F0439A67 +:101F200059C0439857C0662311F0449A53C044984F +:101F300051C0662311F0459A4DC045984BC06623A9 +:101F400011F0469A47C0469845C0662311F08F9A13 +:101F500041C08F983FC0662311F08E9A3BC08E9887 +:101F600039C0662311F08D9A35C08D9833C0662331 +:101F700011F08C9A2FC08C982DC0662311F08B9A8B +:101F800029C08B9827C0662311F08A9A23C08A98AB +:101F900021C0662311F0899A1DC089981BC0662351 +:101FA00011F0889A17C0889815C0662311F0709AAE +:101FB00011C070980FC0662311F0719A0BC0719810 +:101FC00009C0662311F0729A05C0729803C0662397 +:101FD00021F0739A81E090E00895739881E090E099 +:101FE00008951F93182F8150833130F08951833128 +:101FF00018F084E090E013C0E12FFF27EE0FFF1FE1 +:10200000E35AFE4F83E090E092838183812F0E9408 +:102010007C0D61E0812F0E94E70E81E090E01F912E +:102020000895CF93DF93282FEB011882E82FFF2725 +:10203000EE0FFF1FE35AFE4F81819281019719F045 +:1020400086E090E089C0822F9927AA27BB27FC0150 +:102050003197EC32F10540F4E253FF4FEE0FFF1FD2 +:102060000590F491E02D099484E090E075C0659BA3 +:1020700071C06EC0669B6EC06BC0679B6BC068C052 +:10208000189B68C065C0199B65C062C01A9B62C07E +:102090005FC01B9B5FC05CC01C9B5CC059C01D9B8C +:1020A00059C056C01E9B56C053C01F9B53C050C042 +:1020B000489B50C04DC0499B4DC04AC04A9B4AC036 +:1020C00047C04B9B47C044C04C9B44C041C04D9B44 +:1020D00041C03EC04E9B3EC03BC04F9B3BC038C042 +:1020E000309B38C035C0319B35C032C0329B32C0C6 +:1020F0002FC0339B2FC02CC0349B2CC029C0359BD4 +:1021000029C026C0369B26C023C07F9B23C020C089 +:102110007E9B20C01DC07D9B1DC01AC07C9B1AC029 +:1021200017C07B9B17C014C07A9B14C011C0799B49 +:1021300011C00EC0789B0EC00BC0609B0BC008C0C6 +:10214000619B08C005C0629B05C002C0639B02C0C2 +:1021500081E0888381E090E0DF91CF910895CF9373 +:10216000DF93CDB7DEB721970FB6F894DEBF0FBE71 +:10217000CDBF9BE190933203BE016F5F7F4F0E9402 +:1021800011108093330389818093340383E090E0BE +:102190000E949C0121960FB6F894DEBF0FBECDBF02 +:1021A000DF91CF9108959AE1909332030E94E70E58 +:1021B000809333031092340383E090E00E949C01EB +:1021C000089598E1909332030E94C90E80933303DF +:1021D0001092340383E090E00E949C010895982FB0 +:1021E00089E180933203933099F0943028F4913050 +:1021F00059F0923029F40AC0943061F0953061F0C2 +:1022000085E090E020E00BC023B107C026B105C0F7 +:1022100029B103C02CB101C02FB181E090E08093BF +:1022200033032093340383E090E00E949C010895DF +:1022300097E1909332030E94F10F80933303109241 +:10224000340383E090E00E949C01089595E190930F +:1022500032030E941B0E809333031092340383E0F9 +:1022600090E00E949C01089596E1909332030E94B1 +:102270007C0D809333031092340383E090E00E943E +:102280009C01089584E18093320381E080933303BD +:102290001092340383E090E00E949C01089582E153 +:1022A0008093320381E0809333031092340383E000 +:1022B00090E00E949C01089583E18093320381E0C5 +:1022C000809333031092340383E090E00E949C01DA +:1022D000089580E18093320381E08093330310926C +:1022E000340383E090E00E949C01089591E1909373 +:1022F00032030E940B0E809333031092340383E069 +:1023000090E00E949C010895FC0180818531C9F113 +:10231000863180F4823131F1833130F48031D1F073 +:10232000813109F04CC01AC0833109F1843109F0C0 +:1023300046C022C0883189F1893128F4863129F1DB +:102340008731E9F526C08A3189F18A3158F18B311C +:10235000B1F531C082810E946911089582810E9485 +:1023600076110895638182810E944F1108956381DF +:1023700082810E945C110895638182810E944211D2 +:10238000089582810E942611089582810E9434114D +:10239000089582810E9418110895638182810E94AC +:1023A000E110089582810E94EF1008956381828177 +:1023B0000E94D310089582810E94AF1008958093E7 +:1023C000320383E0809333031092340383E090E080 +:1023D0000E949C010895FC018197089718F084E001 +:1023E00090E00895EE0FFF1FE35AFE4F84E090E067 +:1023F0009283818381E090E0089510927C00823086 +:10240000910541F08330910569F0019741F082E038 +:1024100090E0089580917C00806480937C0081E04E +:1024200090E0089580917C00806C80937C0081E036 +:1024300090E0089593E890937A0090917C00907FCB +:10244000982B90937C0080917A00806480937A002E +:1024500080917A0086FDFCCF809178009091790080 +:1024600020E030E040E050E080917A00806480938A +:102470007A0080917A0086FDFCCF8091780090915F +:102480007900480F591F2F5F3F4F2430310561F706 +:1024900080917A008F7780937A00CA01969587950C +:1024A000969587950895CF93DF939C01EB01198250 +:1024B0001882FC01EE0FFF1FE35AFE4F81819281CB +:1024C000049719F086E090E03CC02432310541F1D8 +:1024D0002532310554F42232310541F123323105E0 +:1024E00014F52132310569F424C02632310591F00A +:1024F0002632310594F02732310549F02832310572 +:1025000019F087E090E01DC080E090E014C081E009 +:1025100090E011C082E090E00EC083E090E00BC03C +:1025200084E090E008C085E090E005C086E090E09F +:1025300002C087E090E00E941A129983888381E0AC +:1025400090E0DF91CF91089522E2209332030E9420 +:10255000FD118093330382E090E00E949C01089576 +:10256000CF93DF93CDB7DEB722970FB6F894DEBFD7 +:102570000FBECDBF21E220933203BE016F5F7F4FBC +:102580000E9453128093330329813A81832F992724 +:10259000809334032093350384E090E00E949C01F3 +:1025A00022960FB6F894DEBF0FBECDBFDF91CF915C +:1025B000089520E2209332030E94EB1180933303AD +:1025C0001092340383E090E00E949C010895FC0186 +:1025D0008081813249F0823261F0803279F48281E7 +:1025E00099270E94D9120895828199270E94B012DA +:1025F0000895828199270E94A4120895809332033E +:1026000083E0809333031092340383E090E00E94D0 +:102610009C0108958091B9009927887F9070089552 +:102620008091BC0087FFFCCF0895ECEBF0E0808147 +:10263000846080838BE090E09093770180937601B3 +:102640008CE090E0909379018093780181E090E0B4 +:102650000895ECEBF0E080818B7F808382E090E056 +:10266000909377018093760190937901809378011C +:1026700081E090E008958130910511F48CE00BC069 +:102680008230910511F488E106C0039719F082E0C9 +:1026900090E0089588E48093B8008091B9008C7F21 +:1026A0008093B9008091B9008093B90081E090E0F7 +:1026B00008958091B90084EA8093BC008091BC00A9 +:1026C00087FFFCCF81E090E0089584E98093BC000F +:1026D00081E090E008958093BB0084E88093BC0083 +:1026E0008091BC0087FFFCCF80E090E0089584E8F3 +:1026F0008093BC008091BC0087FFFCCF8091BB0021 +:102700009927089585E38093320381E08093330312 +:102710008093340384E88093BC008091BC0087FFE1 +:10272000FCCF8091BB008093350385E090E00E9450 +:102730009C01089540E050E00FC0F901E40FF51F3F +:1027400080818093BB0084E88093BC008091BC00B2 +:1027500087FFFCCF4F5F5F4F4617570774F384E343 +:102760008093320381E0809333031092340383E03B +:1027700090E00E949C01089587E38093320384E9EE +:102780008093BC0081E0809333031092340383E094 +:1027900090E00E949C01089586E38093320380912B +:1027A000B90084EA8093BC008091BC0087FFFCCF15 +:1027B00081E0809333031092340383E090E00E9421 +:1027C0009C01089522E3209332030E943B138093DF +:1027D00033031092340383E090E00E949C0108953B +:1027E00081E380933203ECEBF0E080818B7F808388 +:1027F00082E090E090937701809376019093790145 +:102800008093780181E0809333031092340383E056 +:1028100090E00E949C01089580E380933203ECEBEA +:10282000F0E08081846080838BE090E0909377017A +:10283000809376018CE090E0909379018093780109 +:1028400081E0809333031092340383E090E00E9490 +:102850009C010895FC0180818433D9F0853338F4DC +:10286000813379F0823381F0803389F507C0863374 +:1028700041F18633D8F0873351F526C00E940C14FD +:1028800008950E94F0130895828199270E94E2130F +:102890000895428155276181772764507040838174 +:1028A00034969F0199270E949A13089542815527D3 +:1028B0006181772764507040838199270E94821339 +:1028C00008950E94CC1308950E94BC13089580932C +:1028D000320383E0809333031092340383E090E06B +:1028E0000E949C01089585B1817F85B9239886E077 +:1028F00084B91CBC1DBC83E58CBD88E090E090933E +:102900006901809368018AE090E090936B01809365 +:102910006A0189E090E090936D0180936C0181E001 +:1029200090E008951CBC1DBC82E090E0909369018A +:102930008093680190936B0180936A0190936D017D +:1029400080936C0181E090E00895089581E090E02B +:102950000895AC0120E030E00AC0FA01E20FF31F55 +:1029600080818EBD0DB407FEFDCF2F5F3F4F261730 +:1029700037079CF381E090E00895DC0120E030E02F +:1029800040E050E015C01EBC09C04F5F5F4F83E0C0 +:10299000493E58071CF088E090E008950DB407FE0A +:1029A000F4CFFD01E20FF31F8EB580832F5F3F4F01 +:1029B0002617370744F381E090E00895CF93DF9323 +:1029C000EC0120E030E0A0E0B0E018C0FE01E20F32 +:1029D000F31F80818EBD08C0119683E0A93EB80721 +:1029E0001CF088E090E00FC00DB407FEF5CFFB01AE +:1029F000E20FF31F8EB580832F5F3F4F24173507FB +:102A00002CF381E090E0DF91CF9108950F931F9315 +:102A10008B0123E420933203AB0164E373E00E9453 +:102A2000DE148093330310923403C80102960E948F +:102A30009C011F910F9108950F931F938C0184E4C3 +:102A400080933203B80184E393E00E94BD14809325 +:102A5000330310923403C80102960E949C011F9117 +:102A60000F91089523E4209332030E94A9148093C8 +:102A700033031092340383E090E00E949C01089598 +:102A800081E4809332030E94921480933303109266 +:102A9000340383E090E00E949C01089580E48093D9 +:102AA00032030E947314809333031092350383E042 +:102AB00090E00E949C010895CF93DF93EC01888100 +:102AC0008334A1F0843438F4813469F0823458F5C9 +:102AD0008034F1F405C0843481F08534C9F411C028 +:102AE0000E944E1520C00E9440151DC069817727A5 +:102AF000CE0102960E94321516C0898199270E9444 +:102B00001C1569817727CE0102960E9406150BC01D +:102B10008093320383E0809333031092340383E085 +:102B200090E00E949C01DF91CF910895209A219A14 +:102B3000229A2398249A259A2C982D9882E090E046 +:102B40009093850180938401909383018093820107 +:102B5000909381018093800181E090E090937F01C8 +:102B600080937E01089582E090E0909369018093C4 +:102B7000680190936B0180936A0190936D0180933B +:102B80006C0181E090E00895289829982A9880E2C5 +:102B90009EE40197F1F7289A8AE0982F9A95F1F729 +:102BA0002A9A299A8A95F1F70895282F299887FD5E +:102BB00002C02A9801C02A9A8AE0982F9A95F1F7C4 +:102BC000299A8A95F1F7299826FF02C02A9A01C00E +:102BD0002A988AE0982F9A95F1F7299A8A95F1F721 +:102BE0000895282F220F30E0299827FF02C02A9A43 +:102BF00001C02A988AE0982F9A95F1F7299A8A9528 +:102C0000F1F73F5F373011F0220FEECF0895282FF4 +:102C100030E0299827FF02C02A9A01C02A988AE04A +:102C2000982F9A95F1F7299A8A95F1F73F5F3830F6 +:102C300011F0220FEECF089529982A988AE0982F54 +:102C40009A95F1F7299A982F9A95F1F7299828984B +:102C5000982F9A95F1F7299A982F9A95F1F7299834 +:102C60008A95F1F7289A80E090E0089529982898AD +:102C70002A982B9A08950E94C41580E30E94D515C6 +:102C800080E60E94F11508950E94C41580E00E941C +:102C9000D51580E00E94F1150E94361608950F9315 +:102CA0001F93182F062F0E94C41580E40E94D5158B +:102CB000812F0E94F115802F0E94071681E090E07D +:102CC0001F910F9108951F93182F0E94C41580EC37 +:102CD0000E94D515812F0E94F1150E941C1699277C +:102CE0001F91089529988AE08A95F1F72A9830E093 +:102CF00090E0990F299A2AE0822F8A95F1F7299876 +:102D00001B999F5F822F8A95F1F73F5F383089F7D3 +:102D10002898299A822F8A95F1F7289A29982A9536 +:102D2000F1F7892F992708951F93182F0E94C41532 +:102D300080E80E94D515812F0E94F1150E9472161D +:102D400099271F910895DF92EF92FF920F931F939F +:102D5000CF93DF93D82E7B018A01C0E0D0E009C079 +:102D60008D2D8C0F0E949416F801EC0FFD1F8083AF +:102D70002196CE15DF05A1F781E090E0DF91CF919C +:102D80001F910F91FF90EF90DF9008950F931F9385 +:102D9000082F162F0E943B16612F802F0E944F167E +:102DA00081E090E01F910F910895DF92EF92FF92E2 +:102DB0000F931F93CF93DF93D82E7B018A01C0E03E +:102DC000D0E009C0F801EC0FFD1F60818D2D8C0F44 +:102DD0000E94C6162196CE15DF05A1F781E090E08E +:102DE000DF91CF911F910F91FF90EF90DF900895A9 +:102DF00094E0909332030E94D5168093330310928F +:102E0000340383E090E00E949C0108950F931F9388 +:102E10008B0193E09093320344E353E00E94A316A6 +:102E200080933303C80102960E949C011F910F9169 +:102E3000089582E08093320382E090E090936901EC +:102E40008093680190936B0180936A0190936D0168 +:102E500080936C0181E0809333031092340383E00C +:102E600090E00E949C01089581E0809332030E94CB +:102E70009615809333031092340383E090E00E9410 +:102E80009C010895FC018381823069F0833018F43D +:102E90008130F1F405C0833049F08430C9F40FC0AB +:102EA0000E94341708950E9419170895AF014A5FD0 +:102EB0005F4F6581772784810E9406170895AF01CF +:102EC0004A5F5F4F6581772784810E94F8160895D5 +:102ED00080818093320383E0809333031092340324 +:102EE00083E090E00E949C0108951F920F920FB61C +:102EF0000F9211240F900FBE0F901F9018959C01F8 +:102F00000897029718F084E090E00895F901EE0F19 +:102F1000FF1FE35AFE4F8DE090E0928381832830BB +:102F20003105B1F02930310519F087E090E00895BE +:102F3000259A81E090E0909389008093880081E851 +:102F40008093800089E08093810081E090E0089583 +:102F5000249A81E08093B30089E68093B00081E0F9 +:102F600090E008959C01FC01EE0FFF1FE35AFE4F15 +:102F7000818192810D9719F086E090E008952830C4 +:102F8000310539F12930310519F087E090E00895D5 +:102F900063307105B1F06430710544F4613071053E +:102FA00061F06230710509F040C009C064307105FC +:102FB00051F065307105C9F508C081E007C082E0B5 +:102FC00005C083E003C084E001C085E080938100F8 +:102FD00029C064307105E9F06530710554F4623040 +:102FE000710599F06330710594F461307105E9F46D +:102FF0000AC06630710589F06630710564F067308B +:10300000710599F40CC089E60BC08AE609C08BE60D +:1030100007C08CE605C08DE603C08EE601C08FE6D2 +:103020008093B00081E090E0089581E090E0089501 +:103030009C01FC01EE0FFF1FE35AFE4F818192813C +:103040000D9719F086E090E008952830310569F079 +:103050002930310519F087E090E0089570938900D8 +:103060006093880081E090E008956093B30081E070 +:1030700090E0089523E5209332030E94181880936E +:1030800033031092340383E090E00E949C01089582 +:1030900022E5209332030E94B217809333031092EB +:1030A000340383E090E00E949C01089520E5209382 +:1030B00032030E947F17809333031092340383E01E +:1030C00090E00E949C0108959C01FC01EE0FFF1FFF +:1030D000E35AFE4F82E090E09283818328303105ED +:1030E00031F02930310531F086E090E008951092FA +:1030F000B00004C01092810010928000822F0E94C4 +:103100007C0D81E090E0089521E5209332030E9438 +:103110006418809333031092340383E090E00E949C +:103120009C010895FC018081813579F0823518F485 +:103130008035F1F405C0823569F08335C9F411C0DA +:10314000828199270E9456180895828199270E94AA +:103150008418089563817727828199270E944818EF +:10316000089563817727828199270E943A180895EC +:103170008093320383E0809333031092340383E01F +:1031800090E00E949C010895CF93DF93AC010297D9 +:1031900010F442E050E0A091B704B091B804FD01F2 +:1031A000C0E0D0E020E030E020C080819181841731 +:1031B000950769F482819381209719F09B838A8314 +:1031C00004C09093B8048093B704CF0132C048176D +:1031D000590738F42115310519F08217930708F4BF +:1031E0009C01EF010280F381E02D3097F1F621156B +:1031F000310589F1C901841B950B049708F4A901D5 +:10320000E0E0F0E026C08D919C9111978217930722 +:10321000E9F44817590779F4ED018A819B813097C9 +:1032200019F09383828304C09093B8048093B70409 +:10323000CD01029649C0841B950BFD01E80FF91FD3 +:103240004193519302978D939C933AC0FD01A281C3 +:10325000B3811097C1F68091B5049091B604892B83 +:1032600041F480915001909151019093B604809364 +:10327000B50420915201309153012115310541F4DB +:103280002DB73EB780914E0190914F01281B390B0D +:10329000E091B504F091B6042E1B3F0B24173507BF +:1032A00088F0CA0102962817390760F0CF01840F11 +:1032B000951F02969093B6048093B5044193519361 +:1032C000CF0102C080E090E0DF91CF910895CF93CD +:1032D000DF93009709F44EC0EC0122971B821A82FB +:1032E000A091B704B091B804109711F140E050E0FC +:1032F00001C0DC01AC17BD0700F1BB83AA83FE014E +:1033000021913191E20FF31FEA17FB0771F42E5F51 +:103310003F4F8D919C911197820F931F99838883C2 +:10332000FD01828193819B838A834115510559F464 +:10333000D093B804C093B7041DC0FD01828193816E +:10334000AD010097B1F6FA01D383C2832191319187 +:10335000E20FF31FEC17FD0769F42E5F3F4F8881E2 +:103360009981820F931FFA01918380838A819B81C7 +:1033700093838283DF91CF91089597FB092E0726CF +:103380000AD077FD04D027D006D000201AF470951B +:1033900061957F4F0895F6F7909581959F4F089519 +:1033A00097FB092E05260ED057FD04D028D00AD051 +:1033B000001C38F450954095309521953F4F4F4F64 +:1033C0005F4F0895F6F790958095709561957F4FC2 +:1033D0008F4F9F4F0895AA1BBB1B51E107C0AA1F27 +:1033E000BB1FA617B70710F0A61BB70B881F991FA6 +:1033F0005A95A9F780959095BC01CD010895A1E259 +:103400001A2EAA1BBB1BFD010DC0AA1FBB1FEE1F5E +:10341000FF1FA217B307E407F50720F0A21BB30BA9 +:10342000E40BF50B661F771F881F991F1A9469F725 +:1034300060957095809590959B01AC01BD01CF0181 +:023440000895ED +:10344200456D62656464656450726F6A6563747326 +:10345200004F63746F70757355534220496E7465E3 +:10346200726661636520436F6E7665727465722061 +:10347200616E6420492F4F20457874656E73696FC1 +:103482006E0032303038313130380009040020000B +:04349200B904000079 +:00000001FF diff --git a/firmware/octopus.hex b/firmware/octopus.hex new file mode 100644 index 0000000..1dde146 --- /dev/null +++ b/firmware/octopus.hex @@ -0,0 +1,830 @@ +:100000000C94CA000C94E7000C94E7000C94E700F1 +:100010000C94E7000C94D8020C94E7000C94E700D1 +:100020000C94E7000C94E7000C94E7000C94E700B4 +:100030000C9483170C94E7000C94E7000C94E700F1 +:100040000C94B1020C94E7000C94E9000C94E700C6 +:100050000C94E7000C94E7000C94E7000C94E70084 +:100060000C94E7000C94E7000C94E7000C94E70074 +:100070000C94E7000C94E7000C94E7000C94E70064 +:100080000C94E7000C94E7000C94E7005D0D5F0D05 +:10009000610D630D650D670D690D6B0D6D0D6F0DB8 +:1000A000710D730D750D770D790D7B0D7D0D7F0D28 +:1000B000810DC30DC30DC30DC30DC30DC30D830D42 +:1000C000850D870D890D8B0D8D0D8F0D910D950D66 +:1000D000990D9F0DA30DA70DAB0DAF0DB50DB70D70 +:1000E000B90DBD0D0D0E0F0E110E130E150E170EC0 +:1000F000190E1B0E1D0E1F0E210E230E250E270E90 +:10010000290E2B0E2D0E2F0E310E730E730E730E45 +:10011000730E730E730E330E350E370E390E3B0E03 +:100120003D0E3F0E410E450E490E4F0E530E570E1B +:100130005B0E5F0E650E670E690E6D0EAF0EB50E8F +:10014000BB0EC10EC70ECD0ED30ED90EDF0EE50EBF +:10015000EB0EF10EF70EFD0E030F090F0F0F150F2B +:100160001B0FAC0EAC0EAC0EAC0EAC0EAC0E210FD9 +:10017000270F2D0F330F390F3F0F450F4B0F550F23 +:10018000610F6B0F750F7F0F890F930F9D0FA30FDB +:10019000A90FAF0F11241FBECFEFD0E1DEBFCDBF3F +:1001A00011E0A0E0B1E0E4E6F3E300E00BBF02C041 +:1001B00007900D92A435B107D9F714E0A4E5B1E09A +:1001C00001C01D92A93BB107E1F70C94F3000C9418 +:1001D00000001F920F920FB60F9211240F900FBEC6 +:1001E0000F901F901895CCEFD0E1DEBFCDBF8FEF01 +:1001F00087BB88BBC7980E94270781E897E10E94C8 +:10020000720785E69CE00E94770781E090E00E94FB +:100210007C07DE011196EBE4F1E083E001900D92A2 +:100220008150E1F7CE0101960E94710B80E091E0D0 +:100230000E940D0C81E191E00E94050C82E491E0A6 +:100240000E94FD0B0E94470B4C0164E670E00E9487 +:100250008A0760E070E0C4010E94B30A3C0140E0FC +:1002600050E0BC01C4010E94AB0720ECA22E21E0AB +:10027000B22ECC24DD2490E4E92EF12C02E021E022 +:1002800030E041E050E0B301C4010E94480A87E435 +:10029000A82E82E0B82E21E030E041E050E0B3012A +:1002A000C4010E94800A0E94C1061092E1011092CE +:1002B000E0011092E3011092E2010E943B0C8FEFEB +:1002C00084BB8AEA85BB0E94FC0285ED85BB0E9447 +:1002D000FC0280E885BBFFCF0F931F93CF93DF9382 +:1002E000EC0181349105B0F08091EC019091ED0129 +:1002F000892B81F41092E9011092E801D093EB016F +:10030000C093EA0181E090E09093ED018093EC01CD +:10031000C0E4D0E068E08BE20E94100700E010E04B +:100320000EC0E091E801F091E901E00FF11FEE5CF1 +:10033000FC4F608189E20E9410070F5F1F4F0C176E +:100340001D0779F78091E0019091E101019749F44F +:1003500067E08BE20E9410071092E1011092E00129 +:100360000AC063E08BE20E94100781E090E0909366 +:10037000E1018093E001DF91CF911F910F910895EA +:100380008091EC019091ED01019771F52091E801C8 +:100390003091E9018091EA019091EB01281739072A +:1003A00018F52091EA013091EB018091E8019091DC +:1003B000E901281B390B8091E8019091E901805CEB +:1003C0009F4F9093E9018093E801213431052CF08F +:1003D00080E490E00E946C010895C9010E946C01C4 +:1003E0001092ED011092EC010895FC011092E901C8 +:1003F0001092E8011092ED011092EC010000C79AF2 +:100400002081822F82958F7099278230910511F17A +:10041000833091052CF4009761F0019759F516C0CF +:1004200084309105F9F084309105C4F0059711F5F9 +:100430001DC0263039F48281813039F5CF010E9408 +:10044000501723C0CF010E94B50C1FC0CF010E94DE +:10045000DD111BC0CF010E94FB1217C0CF010E940B +:100460003B1413C0CF010E946A150FC0CF010E9438 +:100470002E180BC02093320383E080933303109235 +:10048000340383E090E00E946C01C7980895CF93F5 +:10049000DF93EC018091E2019091E301019751F526 +:1004A00020E030E0E091E401F091E501E20FF31F7C +:1004B000DE01A20FB31F8C91EE50FE4F80832F5FA1 +:1004C0003F4F2034310571F78091E4019091E501AF +:1004D000805C9F4F9093E5018093E4012091E401BB +:1004E0003091E5018091E6019091E70128173907E5 +:1004F000A8F11FC01092E5011092E40120E030E065 +:10050000E091E401F091E501E20FF31FDE01A20F9B +:10051000B31F8C91EE50FE4F80832F5F3F4F2034EE +:10052000310571F73093E5012093E401A981A034EE +:1005300048F41092E3011092E20182EF91E00E94F0 +:10054000F5010CC081E090E09093E3018093E2011B +:100550008A2F99279093E7018093E601DF91CF914D +:1005600008951F920F920FB60F9211242F933F936D +:100570004F935F936F937F938F939F93AF93BF93AB +:10058000EF93FF930E94860C80915D0182BFFF91E3 +:10059000EF91BF91AF919F918F917F916F915F91FB +:1005A0004F913F912F910F900FBE0F901F90189574 +:1005B0001F920F920FB60F9211242F933F934F93D8 +:1005C0005F936F937F938F939F93AF93BF93EF93BB +:1005D000FF930E94150CFF91EF91BF91AF919F91F6 +:1005E0008F917F916F915F914F913F912F910F90DC +:1005F0000FBE0F901F90189520E080E49CE90197B2 +:10060000F1F72F5F2931C9F70895FF920F931F93D8 +:10061000162F042FF22E9C01442737FD4095542FAE +:1006200060E472E48FE090E00E9461192150304054 +:10063000163061F0173019F0153019F404C0E1E0FC +:1006400003C0E1E004C0E0E070E002C0E0E071E07F +:10065000053439F00F3419F451E041E004C050E0A2 +:1006600001C051E040E082E0F81611F462E001C000 +:1006700060E0832F992787FD9A958093900029B990 +:1006800088E18AB9770FEE0FEE0FE72B5295550FE1 +:10069000507E5E2B4295407F452B660F660F660F9E +:1006A000642B609395001F910F91FF900895109215 +:1006B000900089E189B988E18AB986E08093950044 +:1006C000089508955D9BFECF8CB908955F9BFECF82 +:1006D0008CB1992708958A3310F4805301C087554F +:1006E0006A3310F4605301C067556F708295807F44 +:1006F000682B862F99270895FC0104C05D9BFECFCF +:1007000031968CB980818823C9F70895982F9295E6 +:100710009F708F709A3020F45D9BFECF905D03C078 +:100720005D9BFECF995A9CB98A3020F45D9BFECF29 +:10073000805D03C05D9BFECF895A8CB9089587E226 +:1007400080939A0485E28093990490E290939B04AD +:1007500010929C0428E030E030939E0420939D0486 +:1007600083E28093A60481E28093A5049093A7047A +:100770001092A8043093AA042093A9040895089520 +:100780006091B20481E20E941007089568E08BE254 +:100790000E94100761E188E20E94100768E08FE282 +:1007A0000E94100761E18CE20E94100761E08FE275 +:1007B0000E9410071092E1011092E00165E083E2CF +:1007C0000E94100708950F931F938C0160E480E24C +:1007D0000E941007F8016281605884E00E941007AF +:1007E000F80182818093B1041F910F9108950F93B6 +:1007F0001F93CF93DF93EC012885398512161306DA +:10080000DCF58E819F81821793071CF568E083E2F7 +:100810000E94100700E010E00FC08A859B85E80F5A +:10082000F91F608181E20E9410078E819F810196ED +:100830009F838E830F5F1F4FEE81FF81888599858F +:10084000083011051CF4E817F9073CF3E817F9071D +:1008500024F061E087E20E9410078B81813031F43F +:1008600065E089810E9410071B8206C061E08981D2 +:100870000E94100781E08B83DF91CF911F910F9130 +:100880000895CF93DF93CDB7DEB724970FB6F894D2 +:10089000DEBF0FBECDBFDC01FC012281338110928F +:1008A000AC041092AB0481E08093A804832F9927B5 +:1008B0008230D9F0833069F1813009F057C08091DE +:1008C000850499279093AE048093AD0485E894E065 +:1008D0009093B0048093AF04868197818034910512 +:1008E00009F044C088E090E029C0FD01868197812D +:1008F0009093AE048093AD04E22FFF27EE0FFF1F0D +:100900008091970490919804E80FF91F808191815C +:1009100029C02223C1F0E22FFF27EE0FFF1F809195 +:10092000F0019091F101E80FF91F0190F081E02DA5 +:10093000F093B004E093AF04808199279093AE04C4 +:100940008093AD0413C094E0998383E08A8389E0A7 +:100950008B839C8384E090E09093AE048093AD04FD +:10096000CE0101969093B0048093AF0485EA94E0A1 +:100970000E94F70324960FB6F894DEBF0FBECDBFDA +:10098000DF91CF910895CF93DF9382E20E94E70633 +:10099000C82FDD27C5FF1AC068E083E20E94100758 +:1009A000C6FF10C02091AB043091AC048091AD041F +:1009B0009091AE04281739072CF485EA94E00E9440 +:1009C000F70304C061E087E20E941007DF91CF9136 +:1009D00008951F93CF93DF9388E00E94E706182FB6 +:1009E000C82FDD27C6FF18C060E085E00E94100711 +:1009F00060E884E00E94100760E080E20E94100737 +:100A000068E083E20E94100761E087E20E9410071D +:100A100062E085E00E941007C4FF04C060EC89E03A +:100A20000E94100717FF04C060ED89E00E941007C4 +:100A3000DF91CF911F9108958AE00E94E7069927E0 +:100A400080FF03C00E94C304089581FF0DC08AE2A5 +:100A50000E94E70680917204813061F4E091750490 +:100A6000F09176040995089582E30E94E7068AE3EF +:100A70000E94E70608958EE00E94E70668E08FE294 +:100A80000E94100761E08FE20E9410072091AD04E0 +:100A90003091AE048091A9049091AA048217930723 +:100AA0005CF468E083E20E94100761E087E20E9444 +:100AB000100781E08093A8040895AF92BF92CF926F +:100AC000DF92EF92FF920F931F93CF93DF93CDB7F7 +:100AD000DEB728970FB6F894DEBF0FBECDBF86E213 +:100AE0000E94E70686FF7EC08E010F5F1F4F5801F0 +:100AF00069E0C62ED12CCC0EDD1E809199040E9497 +:100B0000E706F80181938F017501EC15FD05A9F742 +:100B100068E087E20E94100768E083E20E94100705 +:100B200080E20E94E7068F77682F80E20E9410071C +:100B300089819927807690708032910509F440C0B0 +:100B400080349105D1F1892BF1F5F5018181863051 +:100B5000D9F0873048F48130F1F18130C8F083302A +:100B6000D1F1853081F521C0893019F18A3018F42E +:100B7000883049F505C08A3071F18B3021F520C0ED +:100B8000C5010E94C00327C0C5010E94410423C0C3 +:100B900068E083E20E94100761E081E20E94100792 +:100BA00060E081E20E9410070BC0C5010E94E303D0 +:100BB00012C0C5010E94C6030EC0C5010E94BF0637 +:100BC00065E083E206C080E20E94E7068058682F55 +:100BD00080E20E941007F70180818823D1F465E04C +:100BE00083E215C02091AD043091AE048091A90438 +:100BF0009091AA048217930764F41092AE041092A5 +:100C0000AD0468E083E20E94100761E087E20E9481 +:100C1000100728960FB6F894DEBF0FBECDBFDF9148 +:100C2000CF911F910F91FF90EF90DF90CF90BF90E9 +:100C3000AF900895CF92DF92EF92FF920F931F93A0 +:100C4000CF93DF93CDB7DEB7C054D0400FB6F89442 +:100C5000DEBF0FBECDBF8CE00E94E706992780FF64 +:100C600003C00E945D057BC081FF2AC08EE20E9406 +:100C7000E7068DE20E94E70689838E010F5F1F4F12 +:100C80006801FFE3EF2EF12CE00EF11E0F5F1F4F06 +:100C90000E94D306F80180830E151F05B9F78091D5 +:100CA0005401813031F4E0915701F0915801C601AF +:100CB000099568E08FE20E94100761E08FE22BC087 +:100CC00082FF2CC086E30E94E70685E30E94E706C8 +:100CD00089838E010F5F1F4F6801EFE3EE2EF12C29 +:100CE000E00EF11E0F5F1F4F0E94D306F8018083B4 +:100CF0000E151F05B9F780915501813031F4E0914F +:100D00005901F0915A01C601099568E087E30E94F4 +:100D1000100761E087E30E94100721C083FF1FC016 +:100D20008EE30E94E7068E010F5F1F4F680171E49A +:100D3000E72EF12CEC0EFD1E8DE30E94E706F80174 +:100D400081938F01EE15FF05B9F78091560181302F +:100D500031F4E0915701F0915801C6010995C05C4A +:100D6000DF4F0FB6F894DEBF0FBECDBFDF91CF913E +:100D70001F910F91FF90EF90DF90CF90089508950D +:100D8000089581E08ABF80E189BFE4E6F0E08081D8 +:100D900087608083E5E6F0E0808183608083A79AA6 +:100DA000AF9A7894089585B3805885BBE5E6F0E066 +:100DB000808122E0822780830000000089B395B300 +:100DC000905895BB908192279083992708959FEF23 +:100DD0009ABB8BBB85B3805885BBE5E6F0E080818C +:100DE00095E08927808385B3805885BB80818927DA +:100DF000808300001ABA0E94D306992708958BBBFE +:100E000085B3805885BBE5E6F0E0808191E08927D5 +:100E1000808385B3805885BB80818927808308952E +:100E20008BBB8FEF8ABB85B3805885BBE5E6F0E0CE +:100E3000808195E08927808385B3805885BB808138 +:100E400089278083862F0E94FF060895089582E1F6 +:100E50008093850481E08093860480E191E0909303 +:100E60008804809387041092890410928A04109257 +:100E70008B0488E080938C0410928E0410928D0471 +:100E80001092900410928F04109292041092910488 +:100E90001092930410929404109295041092960468 +:100EA0001092540110925501109256011092720442 +:100EB000109273041092740410927C0410927B04BC +:100EC0001092EF011092EE01089590938E0480939A +:100ED0008D047093900460938F0450939204409318 +:100EE0009104089590938E0480938D0408959093B7 +:100EF000900480938F0408959093920480939104BA +:100F0000089580938904089580938A0408958093B6 +:100F10008B040895CF93DF939C01CB01E0917B0478 +:100F2000F0917C0462E070E00E944E190FC0A08135 +:100F3000B1818281823039F4ED018D819927821748 +:100F4000930709F468870780F085E02D309779F7DB +:100F5000DF91CF910895CF93DF939C01E0917B04C3 +:100F6000F0917C0414C0A081B1818281843061F44D +:100F7000848199278217930739F4868199278617E8 +:100F8000970711F4ED014B830780F085E02D309732 +:100F900051F7DF91CF910895BF92CF92DF92EF92F8 +:100FA000FF920F931F93CF93DF936C01162FF42EB4 +:100FB000B22EC0917B04D0917C042097A1F489E0EB +:100FC00090E00E945518FC0190937C0480937B0470 +:100FD000D182C082138310861782F282B482058385 +:100FE000E68215C0EC018F8198850097D9F789E0DA +:100FF00090E00E945518FC0198878F83D182C082AF +:101000001383F282B4820583E68210861782DF9111 +:10101000CF911F910F91FF90EF90DF90CF90BF90F5 +:101020000895EF92FF921F93CF93DF937C01C091BD +:10103000EE01D091EF01209711F011E012C085E090 +:1010400090E00E945518FC019093EF018093EE010F +:10105000F182E08212821482138210E012C01F5FBC +:10106000EC018B819C810097D1F785E090E00E9494 +:101070005518FC019C838B83F182E08212831482D9 +:101080001382812F9927DF91CF911F91FF90EF90CD +:101090000895EF92FF920F931F93CF93DF93E09108 +:1010A000EE01F091EF0180E090E00380F481E02D0B +:1010B00001963097D1F7880F991F0E945518909389 +:1010C000F1018093F0010091EE011091EF01E80130 +:1010D000E880F9808A81C82FDD27CC0FDD1F809141 +:1010E000F0019091F101C80FD91FF7018081992774 +:1010F0000E9455189983888320E030E017C0E801EA +:10110000EA81FF27EE0FFF1F8091F0019091F1011E +:10111000E80FF91F0190F081E02DE20FF31FD701D6 +:10112000A20FB31F8C9180832F5F3F4FF701808107 +:101130009927281739071CF3E8018B819C810097B8 +:1011400011F08C01C4CFDF91CF911F910F91FF90CF +:10115000EF9008954F925F926F927F928F929F923D +:10116000AF92BF92CF92DF92EF92FF920F931F93B5 +:10117000CF93DF93E0917B04F0917C046624772485 +:1011800009C08281823019F40894611C711C0780A7 +:10119000F085E02D3097A9F74301880C991CC40114 +:1011A0000E9455189093980480939704E1E0EE2EE6 +:1011B000F12CAA24BB2455C0E0917B04F0917C045F +:1011C00079E0C72ED12C15C0A081B18184819927E7 +:1011D0008E159F0519F48381C80ED11CED018D81F8 +:1011E0008E1521F48281823009F45D010780F0853B +:1011F000E02D309749F70091970410919804025020 +:101200001040080D191DC6010E945518F801918360 +:10121000808320E030E0E0919704F0919804E80D9D +:10122000F91D32970190F081E02DE20FF31FD501F7 +:10123000A20FB31F8C9180832F5F3F4F2930310560 +:1012400051F7E0919704F0919804E80DF91D329759 +:101250000190F081E02D8C2D875F82830894E11C42 +:10126000F11C6E147F040CF0A7CF61E0C62ED12CC8 +:1012700059E0A52EB12C4424552442E0842E912C13 +:10128000A1C0A0917B04B0917C0412C0ED91FC91AF +:1012900011978181823049F4858199278C159D05AC +:1012A00021F48481482E552405C0ED01AF81B88515 +:1012B000109761F731E0E32EF12C79C060917B0447 +:1012C00070917C046DC0FB01C081D1818981843023 +:1012D00009F063C0868199278E159F0509F05DC0CE +:1012E000848199278C159D0509F057C0950140E030 +:1012F00050E0E0919704F0919804E80DF91D3297C1 +:101300000190F081E02DE20FF31FDE01A40FB51F65 +:101310008C9180832F5F3F4F4F5F5F4F4930510566 +:1013200041F789E090E0A80EB91EC0917B04D091EE +:101330007C0431C08A81853059F58C8199278C15C0 +:101340009D0531F58D8199278E159F0509F5088139 +:101350001981950140E050E0E0919704F0919804E4 +:10136000E80DF91D32970190F081E02DE20FF31F97 +:10137000D801A40FB51F8C9180832F5F3F4F4F5F23 +:101380005F4F4730510541F7E7E0F0E0AE0EBF1E7A +:101390000F80D885C02D209769F6EB016F81788585 +:1013A0006115710509F08FCF0894E11CF11C4E14F2 +:1013B0005F040CF083CF0894C11CD11CE2E0F0E084 +:1013C0008E0E9F1E6C147D040CF05BCFDF91CF91CD +:1013D0001F910F91FF90EF90DF90CF90BF90AF9053 +:1013E0009F908F907F906F905F904F9008956F9235 +:1013F0007F928F929F92AF92BF92CF92DF92EF92A5 +:10140000FF920F93CF93DF935C013B014901E09181 +:101410007B04F0917C0416C0A081B181848199275E +:10142000A816B90661F4868199278615970539F4BF +:101430008281843021F4ED018C818F5F8C83078061 +:10144000F085E02D309741F787E090E00E94551835 +:10145000FC0187E0808385E0818382820383F582BB +:10146000E482C682EE24062D2A2D45E067E0CF01F6 +:101470000E94CC07DF91CF910F91FF90EF90DF900A +:10148000CF90BF90AF909F908F907F906F90089576 +:10149000AF92BF92CF92DF92EF92FF920F93FC0137 +:1014A000A114B10401F14230510571F043305105EE +:1014B00099F041305105B9F481E080937204B09203 +:1014C0007604A09275040FC081E080937304B092FB +:1014D0007804A092770407C081E080937404B092EE +:1014E0007A04A092790420583F4FCF010E94F70957 +:1014F0000F91FF90EF90DF90CF90BF90AF90089545 +:10150000AF92BF92CF92DF92EF92FF920F93FC01C6 +:101510004230510571F04330510599F04130510589 +:10152000B9F481E080935401B0925801A092570120 +:101530000FC081E080935501B0925A01A0925901E9 +:1015400007C081E080935601B0925C01A0925B01DC +:10155000CF010E94F7090F91FF90EF90DF90CF909D +:10156000BF90AF900895CF92DF92EF920F931F93A9 +:10157000CF93DF936C018B01A0917B04B0917C042D +:10158000C0E0D0E014C02D913C911197F901858104 +:101590008C1551F4FD018281823031F4F90184818E +:1015A0008F5F8483C82FDD27FD01A781B085109749 +:1015B00051F789E090E00E945518FC0189E0808392 +:1015C00084E081830283138214821582168217823B +:1015D0001086EC2E00E02C2D44E069E0CF010E9443 +:1015E000CC07CE01DF91CF911F910F91EF90DF904B +:1015F000CF900895BF92CF92DF92EF92FF920F9318 +:101600001F93CF93DF936C017B01142FB22EA09117 +:101610007B04B0917C04C0E0D0E014C02D913C91DB +:101620001197F90185818C1551F4FD018281823079 +:1016300031F4F90184818F5F8483C82FDD27FD0198 +:10164000A781B085109751F789E090E00E94551866 +:10165000FC0189E0808384E08183E282138214822A +:101660001583B68207831086EC2E00E02C2D44E013 +:1016700069E0CF010E94CC07CE01DF91CF911F918D +:101680000F91FF90EF90DF90CF90BF900895EF9271 +:101690000F931F93109196041F5F1093960489E097 +:1016A00090E00E945518FC0189E0808389E090E079 +:1016B0009383828382E0818314821583168280EA79 +:1016C00087838AE18087EE2400E020E042E069E041 +:1016D000CF010E94CC07812F99271F910F91EF9086 +:1016E0000895CF93DF93EC01FC0101900020E9F70E +:1016F000E81BF90BCF01880F991F0E9455189C0118 +:10170000FE0101900020E9F7EC1BFD0BEE0FFF1F1F +:10171000DC01EC9383E0F901818340E050E009C0F3 +:10172000FE01E40FF51F80818C93FD0111824F5F54 +:101730005F4F1296FE0101900020E9F73197EC1BF4 +:10174000FD0B4E175F0760F3C9010E94110899272E +:10175000DF91CF910895EF92FF920F931F93CF9354 +:10176000DF938C017B01CA010E94710B9C01E09107 +:101770007B04F0917C0414C0A081B181828184300B +:1017800061F4848199278017910739F4868199271C +:101790008E159F0511F4ED0128870780F085E02D57 +:1017A000309751F7DF91CF911F910F91FF90EF90FC +:1017B00008950F931F93CF93DF938C01CB010E9469 +:1017C000710B9C01E0917B04F0917C040FC0A0811F +:1017D000B1818281823039F4ED018D8199278017A2 +:1017E000910709F42E830780F085E02D309779F773 +:1017F000DF91CF911F910F9108950E94710B1816E0 +:10180000190614F48093950408950E94710B18161C +:10181000190614F48093940408950E94710B18160D +:10182000190614F48093930408951F9386E00E9490 +:10183000E706992786FF03C00E941A060EC082FFA2 +:1018400003C00E941C0509C081FF03C00E94E90477 +:1018500004C084FF02C00E943B0587E00E94E706A7 +:10186000182F60E087E00E941007612F87E00E9438 +:1018700010071F9108950E94AA080E9449080E941B +:101880009F0361E080E00E94100780E00E94E7066D +:1018900080FDFBCF62E081E00E94100760E884E0F9 +:1018A0000E94100760E480E20E94100768E083E273 +:1018B0000E94100769E087E20E9410076FE08DE048 +:1018C0000E9410076FE08BE00E94100768ED89E02E +:1018D0000E94100763E38FE00E94100766ED87E027 +:1018E0000E94100762E085E00E9410076CEC80E027 +:1018F0000E94100708958EEC80935D0181E087BF00 +:1019000080915D0182BF83E083BF089508950895AB +:1019100083E08093320381E0809333038BE08093F4 +:1019200034039FE69093350383E68093360384E780 +:10193000809337039093380380E78093390385E7DA +:1019400080933A0383E780933B038FE580933C03C6 +:1019500080E380933D0381E380933E0310923F0335 +:101960008EE090E00E946C010895FC01808183303C +:1019700011F40E94880C0895CF93DF93C1E0D0E06A +:10198000CE010E94D20D2196C431D105C9F7CAE11A +:10199000D0E0CE010E94D20D2196CD32D105C9F7FB +:1019A000DF91CF910895CF93DF93DC01EC01EA81C1 +:1019B000FB8121918E81815019F48981E81BF10905 +:1019C000ED01FB83EA838E839FB7F8948C9181505D +:1019D0008C939FBF822F9927DF91CF910895FC01AF +:1019E0001082758364837383628341834783468354 +:1019F0000895CF93DF93DC019C91ED0189819817C5 +:101A000018F080E090E016C0ED01EC81FD8161935B +:101A10008F81815019F48981E81BF109ED018F83D1 +:101A2000FD83EC839FB7F8948C918F5F8C939FBF5D +:101A300081E090E0DF91CF910895FC0180818823BF +:101A4000E9F3CF010E94D30C99270895FC0180810E +:101A5000882319F48FEF9FEF0895CF010E94D30CD4 +:101A6000992708950895CF93DF93CDB7DEB72297D6 +:101A70000FB6F894DEBF0FBECDBF9C010197439710 +:101A800028F0C9014A97439708F07DC0F901EE0F8D +:101A9000FF1FE35AFE4F82E090E092838183F901B9 +:101AA0003197EC32F10508F06EC0EA5BFF4FEE0FA4 +:101AB000FF1F0590F491E02D0994159A5BC0169ACA +:101AC0005DC0179A57C0B89A59C0B99A53C0BA9A0C +:101AD00055C0BB9A4FC0BC9A51C0BD9A4BC0BE9A6C +:101AE0004DC0BF9A47C0889A49C0899A43C08A9A14 +:101AF00045C08B9A3FC08C9A41C08D9A3BC08E9A4C +:101B00003DC08F9A37C0A09A39C0A19A33C0A29A1B +:101B100035C0A39A2FC0A49A31C0A59A2BC0A69A0B +:101B20002DC080916100806807C080916100806451 +:101B300019C0809161008062809361001BC0809118 +:101B4000610080610FC0809161008860F5CF809155 +:101B50006100846007C0809161008260EDCF809158 +:101B6000610081608093610009C0109A03C0119ADE +:101B700005C0129A81E090E008C0139AE1E0F0E01D +:101B8000FA83E98304C084E090E09A8389838981A1 +:101B90009A8122960FB6F894DEBF0FBECDBFDF91BB +:101BA000CF9108959C010197439738F0C9014A9756 +:101BB000439718F084E090E00895C9010E94330D26 +:101BC00081E090E00895CF93DF93CDB7DEB7229701 +:101BD0000FB6F894DEBF0FBECDBF9C0101974397AF +:101BE00028F0C9014A97439708F07DC0F901EE0F2C +:101BF000FF1FE35AFE4F81E090E092838183F90159 +:101C00003197EC32F10508F06EC0EE58FF4FEE0F41 +:101C1000FF1F0590F491E02D099415985BC016986C +:101C20005DC0179857C0B89859C0B99853C0BA98B2 +:101C300055C0BB984FC0BC9851C0BD984BC0BE9812 +:101C40004DC0BF9847C0889849C0899843C08A98BA +:101C500045C08B983FC08C9841C08D983BC08E98F2 +:101C60003DC08F9837C0A09839C0A19833C0A298C2 +:101C700035C0A3982FC0A49831C0A5982BC0A698B2 +:101C80002DC0809161008F7707C0809161008F7BAC +:101C900019C0809161008F7D809361001BC080918D +:101CA00061008F7E0FC080916100877FF5CF8091AA +:101CB00061008B7F07C0809161008D7FEDCF8091A7 +:101CC00061008E7F8093610009C0109803C0119855 +:101CD00005C0129881E090E008C01398E1E0F0E0C0 +:101CE000FA83E98304C084E090E09A838983898140 +:101CF0009A8122960FB6F894DEBF0FBECDBFDF915A +:101D0000CF91089580E090E0089580E090E00895FC +:101D100080E090E008950895089508950895089545 +:101D2000089508959C01FC01EE0FFF1FE35AFE4F3A +:101D300081819281029719F085E090E00895F90180 +:101D40003197EC32F10540F4E256FF4FEE0FFF1FE2 +:101D50000590F491E02D099484E090E00895672BBC +:101D600011F01D9AFFC01D98FDC0672B11F01E9A3F +:101D7000F9C01E98F7C0672B11F01F9AF3C01F9887 +:101D8000F1C0672B11F0C09AEDC0C098EBC0672B73 +:101D900011F0C19AE7C0C198E5C0672B11F0C29A53 +:101DA000E1C0C298DFC0672B11F0C39ADBC0C398B3 +:101DB000D9C0672B11F0C49AD5C0C498D3C0672B83 +:101DC00011F0C59ACFC0C598CDC0672B11F0C69A47 +:101DD000C9C0C698C7C0672B11F0C79AC3C0C798BF +:101DE000C1C0672B11F0909ABDC09098BBC0672B03 +:101DF00011F0919AB7C09198B5C0672B11F0929AE3 +:101E0000B1C09298AFC0672B11F0939AABC0939872 +:101E1000A9C0672B11F0949AA5C09498A3C0672B12 +:101E200011F0959A9FC095989DC0672B11F0969AD6 +:101E300099C0969897C0672B11F0979A93C097987E +:101E400091C0672B11F0A89A8DC0A8988BC0672B02 +:101E500011F0A99A87C0A99885C0672B11F0AA9A9A +:101E600081C0AA987FC0672B11F0AB9A7BC0AB985A +:101E700079C0672B11F0AC9A75C0AC9873C0672B12 +:101E800011F0AD9A6FC0AD986DC0672B11F0AE9A8E +:101E900069C0AE9867C0672B21F0809162008068AE +:101EA0000DC0809162008F7709C0672B21F080916F +:101EB0006200806403C0809162008F7B8093620027 +:101EC00051C0672B21F0809162008062F7CF809132 +:101ED00062008F7DF3CF672B21F0809162008061DB +:101EE000EDCF809162008F7EE9CF672B21F080914A +:101EF00062008860E3CF80916200877FDFCF672B2D +:101F000021F0809162008460D9CF809162008B7F44 +:101F1000D5CF672B21F0809162008260CFCF809176 +:101F200062008D7FCBCF672B21F0809162008160B2 +:101F3000C5CF809162008E7FC1CF672B11F0189AB8 +:101F400011C018980FC0672B11F0199A0BC019987F +:101F500009C0672B11F01A9A05C01A9803C0672BA5 +:101F600021F01B9A81E090E008951B9881E090E0B9 +:101F70000895CF93DF93EC010197439738F0CE019A +:101F80004A97439718F084E090E013C0FE01EE0FEB +:101F9000FF1FE35AFE4F83E090E092838183CE01DE +:101FA0000E94330D61E070E0CE010E94920E81E04C +:101FB00090E0DF91CF91089508959C01DB01119687 +:101FC0001C921E92FC01EE0FFF1FE35AFE4F81810F +:101FD00092818130910519F085E090E008952130DB +:101FE000310531F4859B28C011963C932E9324C073 +:101FF0002230310531F4869B2AC011969C938E9332 +:1020000026C02330310531F40F9B2CC011969C93D0 +:102010008E9328C02430310531F4B09B2EC0119628 +:102020009C938E932AC02530310531F4B19B30C08A +:1020300011969C938E932CC02630310541F4B29BAF +:1020400032C081E090E011969C938E932CC0273093 +:10205000310541F4B39B32C081E090E011969C932E +:102060008E932CC02830310541F4B49B32C081E0FE +:1020700090E011969C938E932CC02930310541F449 +:10208000B59B32C081E090E011969C938E932CC05A +:102090002A30310541F4B69B32C081E090E01196C0 +:1020A0009C938E932CC02B30310541F4B79B32C0EA +:1020B00081E090E011969C938E932CC02C303105DA +:1020C00041F4809B32C081E090E011969C938E9306 +:1020D0002CC02D30310541F4819B32C081E090E06D +:1020E00011969C938E932CC02E30310541F4829B27 +:1020F00032C081E090E011969C938E932CC02F30DB +:10210000310541F4839B32C081E090E011969C93AD +:102110008E932CC02031310541F4849B32C081E084 +:1021200090E011969C938E932CC02131310541F49F +:10213000859B32C081E090E011969C938E932CC0D9 +:102140002231310541F4869B32C081E090E0119646 +:102150009C938E932CC02331310541F4879B32C070 +:1021600081E090E011969C938E932CC02A3131052A +:1021700041F4809B32C081E090E011969C938E9355 +:102180002CC02B31310541F4999B32C081E090E0A5 +:1021900011969C938E932CC02C31310541F49A9B5F +:1021A00032C081E090E011969C938E932CC02D312B +:1021B000310541F49B9B32C081E090E011969C93E5 +:1021C0008E932CC02E31310541F49C9B32C081E0AE +:1021D00090E011969C938E932CC02F31310541F4E1 +:1021E0009D9B32C081E090E011969C938E932CC011 +:1021F0002032310541F49E9B32C081E090E011967F +:102200009C938E932CC02132310541F4079B32C040 +:1022100081E090E011969C938E932CC02232310580 +:1022200041F4069B32C081E090E011969C938E931E +:102230002CC02332310541F4059B32C081E090E08F +:1022400011969C938E932CC02432310541F4049B4B +:102250002AC081E090E011969C938E9324C0253291 +:10226000310541F4039B25C081E090E011969C93D9 +:102270008E931FC02632310541F4029B20C081E0BD +:1022800090E011969C938E931AC02732310541F449 +:10229000019B1BC081E090E011969C938E9315C02A +:1022A0002832310519F02932310519F4809B17C005 +:1022B00011C02A32310519F4099B11C00BC02B3211 +:1022C000310519F40A9B0BC005C02C32310539F4D5 +:1022D0000B9B05C081E090E08D939C93089581E075 +:1022E00090E008950895CF93DF93CDB7DEB722979E +:1022F0000FB6F894DEBF0FBECDBF2BE120933203A3 +:10230000BE016F5F7F4F0E94DD0F80933303898191 +:102310008093340383E090E00E946C0122960FB614 +:10232000F894DEBF0FBECDBFDF91CF9108952AE1B3 +:10233000209332030E94920E809333031092340351 +:1023400083E090E00E946C01089527E1209332031E +:102350000E94B90F809333031092340383E090E01E +:102360000E946C01089525E1209332030E94E30D41 +:10237000809333031092340383E090E00E946C0159 +:10238000089526E1209332030E94330D8093330396 +:102390001092340383E090E00E946C01089521E1E3 +:1023A000209332030E94D20D8093330310923403A2 +:1023B00083E090E00E946C010895FC0180818631E9 +:1023C000E9F0873138F48531A0F48231C0F58031ED +:1023D00058F10AC08A3118F4883188F514C08A315E +:1023E000B9F08B3109F51BC0828199270E94CF116A +:1023F0000895828199270E94B311089582819927B7 +:102400000E94C1110895828199270E94B90F0895F1 +:1024100063817727828199270E949711089582818D +:1024200099270E94731108958093320383E080936B +:1024300033031092340383E090E00E946C0108950E +:10244000FC018197089718F084E090E00895EE0F62 +:10245000FF1FE35AFE4F84E090E09283818381E086 +:1024600090E0089517B88230910541F083309105CE +:1024700049F0019721F082E090E008953E9A81E0D2 +:1024800090E0089587B1806C87B981E090E008956D +:1024900093E896B997B1907F982B97B9369A369969 +:1024A000FECF84B195B120E030E040E050E0369AB4 +:1024B0003699FECF84B195B1480F591F2F5F3F4F1A +:1024C00024303105A1F73798CA01969587959695DE +:1024D00087950895CF93DF939C01EB0119821882B1 +:1024E000FC01EE0FFF1FE35AFE4F8181928104979A +:1024F000D1F52432310559F12532310554F4223217 +:10250000310559F1233231052CF52132310559F5C8 +:1025100027C026323105A9F026323105ACF027322A +:10252000310531F028323105F1F480E090E002C04D +:1025300081E090E00E9448129983888381E090E0D6 +:1025400014C082E090E0F6CF83E090E0F3CF84E027 +:1025500090E0F0CF85E090E0EDCF86E090E0EACF2C +:1025600087E090E0E7CF85E090E0DF91CF9108959C +:1025700022E2209332030E9432128093330382E0DE +:1025800090E00E946C010895CF93DF93CDB7DEB742 +:1025900022970FB6F894DEBF0FBECDBF21E2209385 +:1025A0003203BE016F5F7F4F0E946A128093330334 +:1025B00029813A81832F992780933403209335030F +:1025C00084E090E00E946C0122960FB6F894DEBF82 +:1025D0000FBECDBFDF91CF91089520E2209332034B +:1025E0000E942012809333031092340383E090E022 +:1025F0000E946C010895FC018081813249F0823291 +:1026000061F0803279F4828199270E94ED12089559 +:10261000828199270E94C4120895828199270E947D +:10262000B81208958093320383E0809333031092AD +:10263000340383E090E00E946C0108958091710062 +:102640009927887F907008958091740087FFFCCF50 +:102650000895E4E7F0E08081846080838BE090E07F +:1026600090937701809376018CE090E090937901CC +:102670008093780181E090E00895E4E7F0E08081C4 +:102680008B7F808382E090E0909377018093760146 +:10269000909379018093780108958130910511F428 +:1026A0008CE00BC08230910511F488E106C00397DD +:1026B00019F082E090E0089588E4809370008091A2 +:1026C00071008C7F80937100809171008093710004 +:1026D00081E090E008958091710084EA8093740015 +:1026E0008091740087FFFCCF81E090E0089584E939 +:1026F0008093740081E090E008958093730084E8F3 +:10270000809374008091740087FFFCCF80E090E09C +:10271000089584E8809374008091740087FFFCCF53 +:10272000809173009927089585E38093320381E0B7 +:10273000809333038093340384E880937400809102 +:10274000740087FFFCCF809173008093350385E090 +:1027500090E00E946C01089540E050E00FC0F90144 +:10276000E40FF51F80818093730084E880937400E8 +:102770008091740087FFFCCF4F5F5F4F461757076C +:1027800074F384E38093320381E0809333031092E7 +:10279000340383E090E00E946C01089587E3809306 +:1027A000320384E98093740081E0809333031092B4 +:1027B000340383E090E00E946C01089586E38093E7 +:1027C00032038091710084EA8093740080917400D8 +:1027D00087FFFCCF81E0809333031092340383E0C2 +:1027E00090E00E946C01089522E3209332030E943E +:1027F0004D13809333031092340383E090E00E94E2 +:102800006C01089581E380933203E4E7F0E0808176 +:102810008B7F808382E090E09093770180937601B4 +:1028200090937901809378011092330310923403CE +:1028300083E090E00E946C01089580E3809332036E +:10284000E4E7F0E08081846080838BE090E0909307 +:102850007701809376018CE090E0909379018093EA +:10286000780181E0809333031092340383E090E099 +:102870000E946C010895FC0180818433D9F0853376 +:1028800038F4813379F0823381F0803389F507C0E1 +:10289000863341F18633D8F0873351F526C00E9444 +:1028A0001D1408950E9402140895828199270E94A0 +:1028B000F413089542815527618177276450704051 +:1028C000838134969F0199270E94AC130895428119 +:1028D00055276181772764507040838199270E9432 +:1028E000941308950E94DE1308950E94CE13089554 +:1028F0008093320383E0809333031092340383E0A8 +:1029000090E00E946C01089588B3817F88BBBB98DA +:1029100086E087BB1DB81EB883E58DB988E090E0DE +:1029200090936901809368018AE090E090936B0135 +:1029300080936A0189E090E090936D0180936C012F +:1029400081E090E008951DB81EB882E090E0909379 +:1029500069018093680190936B0180936A01909361 +:102960006D0180936C0181E090E00895089581E00D +:1029700090E00895AC0120E030E009C0FA01E20FD8 +:10298000F31F80818FB9779BFECF2F5F3F4F2617B4 +:102990003707A4F381E090E00895DC0120E030E007 +:1029A00040E050E014C01FB809C04F5F5F4F83E0A4 +:1029B000493E58071CF086E090E00895779BF5CFDC +:1029C000FD01E20FF31F8FB180832F5F3F4F26176A +:1029D00037074CF381E090E00895CF93DF93EC014B +:1029E00020E030E0A0E0B0E017C0FE01E20FF31FEE +:1029F00080818FB908C0119683E0A93EB8071CF00A +:102A000086E090E00EC0779BF6CFFB01E20FF31F4C +:102A10008FB180832F5F3F4F2417350734F381E058 +:102A200090E0DF91CF9108950F931F938B0123E4E2 +:102A300020933203AB0164E373E00E94ED148093B2 +:102A4000330310923403C80102960E946C011F9157 +:102A50000F9108950F931F938C0184E480933203A8 +:102A6000B80184E393E00E94CD1480933303109265 +:102A70003403C80102960E946C011F910F910895C2 +:102A800023E4209332030E94BA14809333031092FC +:102A9000340383E090E00E946C01089581E4809308 +:102AA00032030E94A314809333031092340383E013 +:102AB00090E00E946C01089580E4809332030E94AC +:102AC0008414809333031092350383E090E00E94D6 +:102AD0006C010895CF93DF93EC0188818334A1F0DA +:102AE000843438F4813469F0823458F58034F1F458 +:102AF00005C0843481F08534C9F411C00E945C158E +:102B000020C00E944E151DC069817727CE01029614 +:102B10000E94401516C0898199270E942A15698153 +:102B20007727CE0102960E9414150BC080933203C2 +:102B300083E0809333031092340383E090E00E949B +:102B40006C01DF91CF910895B89AB99ABA9ABB985F +:102B5000BC9ABD9AC498C59882E090E09093850194 +:102B600080938401909383018093820190938101EB +:102B70008093800181E090E090937F0180937E01BB +:102B8000089582E090E090936901809368019093AA +:102B90006B0180936A0190936D0180936C0181E0D9 +:102BA00090E00895C098C198C29880E29EE4019791 +:102BB000F1F7C09A8AE0982F9A95F1F7C29AC19AD4 +:102BC0008A95F1F70895282FC19887FD02C0C29811 +:102BD00001C0C29A8AE0982F9A95F1F7C19A8A9516 +:102BE000F1F7C19826FF02C0C29A01C0C2988AE0DC +:102BF000982F9A95F1F7C19A8A95F1F70895282FA1 +:102C0000220F30E0C19827FF02C0C29A01C0C298CB +:102C10008AE0982F9A95F1F7C19A8A95F1F73F5F6C +:102C2000373011F0220FEECF0895282F30E0C198F1 +:102C300027FF02C0C29A01C0C2988AE0982F9A95D5 +:102C4000F1F7C19A8A95F1F73F5F383011F0220F02 +:102C5000EECF0895C198C2988AE0982F9A95F1F71F +:102C6000C19A982F9A95F1F7C198C098982F9A9584 +:102C7000F1F7C19A982F9A95F1F7C1988A95F1F7D3 +:102C8000C09A80E090E00895C198C098C298C39A15 +:102C900008950E94D21580E30E94E31580E60E9409 +:102CA000FF1508950E94D21580E00E94E31580E090 +:102CB0000E94FF150E94441608950F931F93182F2A +:102CC000062F0E94D21580E40E94E315812F0E94F6 +:102CD000FF15802F0E94151681E090E01F910F9143 +:102CE00008951F93182F0E94D21580EC0E94E315BF +:102CF000812F0E94FF150E942A1699271F9108957F +:102D0000C1988AE08A95F1F7C29830E090E0990F77 +:102D1000C19A2AE0822F8A95F1F7C198B3999F5FF3 +:102D2000822F8A95F1F73F5F383089F7C098C19AB2 +:102D3000822F8A95F1F7C09AC1982A95F1F7892FC9 +:102D4000992708951F93182F0E94D21580E80E949A +:102D5000E315812F0E94FF150E94801699271F916D +:102D60000895DF92EF92FF920F931F93CF93DF931B +:102D7000D82E7B018A01C0E0D0E009C08D2D8C0FD8 +:102D80000E94A216F801EC0FFD1F80832196CE153C +:102D9000DF05A1F781E090E0DF91CF911F910F91C6 +:102DA000FF90EF90DF9008950F931F93082F162F39 +:102DB0000E944916612F802F0E945D1681E090E0ED +:102DC0001F910F910895DF92EF92FF920F931F933F +:102DD000CF93DF93D82E7B018A01C0E0D0E009C0F9 +:102DE000F801EC0FFD1F60818D2D8C0F0E94D41611 +:102DF0002196CE15DF05A1F781E090E0DF91CF911C +:102E00001F910F91FF90EF90DF90089594E09093C1 +:102E100032030E94E316809333031092340383E05D +:102E200090E00E946C0108950F931F938B0193E033 +:102E30009093320344E353E00E94B116809333032E +:102E4000C80102960E946C011F910F91089582E0C3 +:102E50008093320382E090E090936901809368014F +:102E600090936B0180936A0190936D0180936C0144 +:102E700081E0809333031092340383E090E00E945A +:102E80006C01089581E0809332030E94A415809321 +:102E900033031092340383E090E00E946C010895A4 +:102EA000FC018381823069F0833018F48130F1F4C1 +:102EB00005C0833049F08430C9F40FC00E94421726 +:102EC00008950E9427170895AF014A5F5F4F6581FB +:102ED000772784810E9414170895AF014A5F5F4FDE +:102EE0006581772784810E940617089580818093E9 +:102EF000320383E0809333031092340383E090E045 +:102F00000E946C0108951F920F920FB60F92112428 +:102F10008F939F938091B3049091B4049BBD8ABD1D +:102F20009F918F910F900FBE0F901F901895FC01ED +:102F30000897029718F084E090E00895EE0FFF1FC5 +:102F4000E35AFE4F8DE090E09283818381E090E030 +:102F500008959C01FC01EE0FFF1FE35AFE4F818193 +:102F600092810D97F1F428303105F1F029303105C7 +:102F7000C1F48091B3049091B404892B31F480E8BA +:102F800090E09093B4048093B3046130710561F4D0 +:102F90008FB5816A8FBD8EB581608EBD81E090E076 +:102FA000089585E090E0089581E090E008959C0107 +:102FB000FC01EE0FFF1FE35AFE4F818192810D97B6 +:102FC00059F42830310529F02930310529F47BBD29 +:102FD0006ABD81E090E0089585E090E008959C014D +:102FE00082E580933203F901EE0FFF1FE35AFE4F93 +:102FF000818192810D9759F42830310529F02930CB +:10300000310529F47BBD6ABD81E090E002C085E016 +:1030100090E0809333031092340383E090E00E94A9 +:103020006C01089521E5209332030E94A917809333 +:1030300033031092340383E090E00E946C01089502 +:1030400020E5209332030E94971780933303109258 +:10305000340383E090E00E946C010895FC018081BC +:10306000813549F0823571F0803599F48281992754 +:103070000E942018089563817727828199270E94F2 +:103080001218089563817727828199270E94EF178C +:1030900008958093320383E08093330310923403C6 +:1030A00083E090E00E946C010895CF93DF93AC0120 +:1030B000029710F442E050E0A091B704B091B80438 +:1030C000FD01C0E0D0E020E030E020C080819181AF +:1030D0008417950769F482819381209719F09B8367 +:1030E0008A8304C09093B8048093B704CF0132C0A0 +:1030F0004817590738F42115310519F0821793073D +:1031000008F49C01EF010280F381E02D3097F1F685 +:103110002115310589F1C901841B950B049708F429 +:10312000A901E0E0F0E026C08D919C9111978217F3 +:103130009307E9F44817590779F4ED018A819B81D7 +:10314000309719F09383828304C09093B8048093DE +:10315000B704CD01029649C0841B950BFD01E80F11 +:10316000F91F4193519302978D939C933AC0FD01AF +:10317000A281B3811097C1F68091B5049091B604F5 +:10318000892B41F480915001909151019093B604A4 +:103190008093B504209152013091530121153105DE +:1031A00041F42DB73EB780914E0190914F01281BFD +:1031B000390BE091B504F091B6042E1B3F0B241798 +:1031C000350788F0CA0102962817390760F0CF0149 +:1031D000840F951F02969093B6048093B504419393 +:1031E0005193CF0102C080E090E0DF91CF9108952C +:1031F000CF93DF93009709F44EC0EC0122971B8216 +:103200001A82A091B704B091B804109711F140E070 +:1032100050E001C0DC01AC17BD0700F1BB83AA83FD +:10322000FE0121913191E20FF31FEA17FB0771F4C0 +:103230002E5F3F4F8D919C911197820F931F998321 +:103240008883FD01828193819B838A834115510587 +:1032500059F4D093B804C093B7041DC0FD01828116 +:103260009381AD010097B1F6FA01D383C283219116 +:103270003191E20FF31FEC17FD0769F42E5F3F4F0A +:1032800088819981820F931FFA01918380838A81BB +:103290009B8193838283DF91CF91089597FB092EC1 +:1032A00007260AD077FD04D027D006D000201AF4D4 +:1032B000709561957F4F0895F6F7909581959F4F92 +:1032C000089597FB092E05260ED057FD04D028D06F +:1032D0000AD0001C38F450954095309521953F4F09 +:1032E0004F4F5F4F0895F6F79095809570956195D3 +:1032F0007F4F8F4F9F4F0895AA1BBB1B51E107C003 +:10330000AA1FBB1FA617B70710F0A61BB70B881F75 +:10331000991F5A95A9F780959095BC01CD01089504 +:10332000A1E21A2EAA1BBB1BFD010DC0AA1FBB1FC9 +:10333000EE1FFF1FA217B307E407F50720F0A21B3B +:10334000B30BE40BF50B661F771F881F991F1A94A8 +:1033500069F760957095809590959B01AC01BD01D2 +:04336000CF010895FC +:10336400456D62656464656450726F6A6563747305 +:10337400004F63746F70757355534220496E7465C2 +:10338400726661636520436F6E7665727465722040 +:10339400616E6420492F4F20457874656E73696FA0 +:1033A4006E003230303831313038000904002000EA +:0433B400B904000058 +:00000001FF diff --git a/firmware/octopus_can.hex b/firmware/octopus_can.hex new file mode 100644 index 0000000..aa546f0 --- /dev/null +++ b/firmware/octopus_can.hex @@ -0,0 +1,842 @@ +:100000000C94FA000C9417010C9417010C9417012E +:100010000C9417010C9408030C9417010C9417010D +:100020000C9417010C9417010C9417010C941701F0 +:100030000C9475170C9417010C9417010C9417016C +:100040000C9417010C94E1020C9417010C94170105 +:100050000C9417010C9419010C9417010C941701BE +:100060000C9417010C9417010C9417010C941701B0 +:100070000C9417010C9417010C9417010C941701A0 +:100080000C9417010C9417010C9417010C94170190 +:100090000C941701AA0DAC0DAE0DB00DB20DB40D40 +:1000A000B60DB80DBA0DBC0DBE0DC00DC20DC40D00 +:1000B000C60DC80DCA0DCC0DCE0DFC0DFC0DFC0DF2 +:1000C000FC0DFC0DFC0DD00DD20DD40DD60DD80DB0 +:1000D000DA0DDC0DDE0DE00DE20DE40DE60DE80DB0 +:1000E000EA0DEC0DEE0DF00DF20DF60D490E4B0E76 +:1000F0004D0E4F0E510E530E550E570E590E5B0EF0 +:100100005D0E5F0E610E630E650E670E690E6B0E5F +:100110006D0E9B0E9B0E9B0E9B0E9B0E9B0E6F0EF1 +:10012000710E730E750E770E790E7B0E7D0E7F0E9F +:10013000810E830E850E870E890E8B0E8D0E8F0E0F +:10014000910E950E090F0F0F150F1B0F210F270F83 +:100150002D0F330F390F3F0F450F4B0F510F570F17 +:100160005D0F630F690F6F0F750F060F060F060FF8 +:10017000060F060F060F7B0F810F870F8D0F930F52 +:10018000990F9F0FA50FAB0FB10FB70FBD0FC30F87 +:10019000C90FCF0FD50FDB0FE10FE70F37103A1064 +:1001A0003D1040104310461049104C104F10521093 +:1001B000551058105B105E106110641067106A10C3 +:1001C0006D1034103410341034103410341070109A +:1001D0007310761079107C107F10821085108810B3 +:1001E0008B108E109110941097109A109D10A010E3 +:1001F000A310A61011241FBECFEFD0E1DEBFCDBFEC +:1002000011E0A0E0B1E0E0E3F4E300E00BBF02C0E6 +:1002100007900D92A435B107D9F714E0A4E5B1E039 +:1002200001C01D92A93BB107E1F70C9423010C9486 +:1002300000001F920F920FB60F9211240F900FBE65 +:100240000F901F901895CCEFD0E1DEBFCDBF8FEFA0 +:1002500084B985B92F980E94650781E897E10E94CB +:10026000B00785E69CE00E94B50781E090E00E941F +:10027000BA07DE011196EBE4F1E083E001900D9204 +:100280008150E1F7CE0101960E94AF0B80E091E032 +:100290000E944B0C81E191E00E94430C82E491E0CA +:1002A0000E943B0C0E94850B4C0164E670E00E94AA +:1002B000C80760E070E0C4010E94F10A3C0140E020 +:1002C00050E0BC01C4010E94E90720EFA22E21E00A +:1002D000B22ECC24DD2490E4E92EF12C02E021E0C2 +:1002E00030E041E050E0B301C4010E94860A87E794 +:1002F000A82E82E0B82E21E030E041E050E0B301CA +:10030000C4010E94BE0A0E940A071092E1011092E5 +:10031000E0011092E3011092E2010E94790C8FEF4C +:1003200087B98AEA88B90E942C0385ED88B90E94B2 +:100330002C0380E888B9FFCF0F931F93CF93DF93EF +:10034000EC0181349105B0F08091EC019091ED01C8 +:10035000892B81F41092E9011092E801D093EB010E +:10036000C093EA0181E090E09093ED018093EC016D +:10037000C0E4D0E068E08BE20E94500700E010E0AB +:100380000EC0E091E801F091E901E00FF11FEE5C91 +:10039000FC4F608189E20E9450070F5F1F4F0C17CE +:1003A0001D0779F78091E0019091E101019749F4EF +:1003B00067E08BE20E9450071092E1011092E00189 +:1003C0000AC063E08BE20E94500781E090E09093C6 +:1003D000E1018093E001DF91CF911F910F9108958A +:1003E0008091EC019091ED01019771F52091E80168 +:1003F0003091E9018091EA019091EB0128173907CA +:1004000018F52091EA013091EB018091E80190917B +:10041000E901281B390B8091E8019091E901805C8A +:100420009F4F9093E9018093E801213431052CF02E +:1004300080E490E00E949C010895C9010E949C0103 +:100440001092ED011092EC010895FC011092E90167 +:100450001092E8011092ED011092EC0100002F9A29 +:100460002081822F82958F7099278230910511F11A +:10047000833091052CF4009761F0019759F516C06F +:1004800084309105F9F084309105C4F0059711F599 +:100490001DC0263039F48281813039F5CF010E94A8 +:1004A000421723C0CF010E94F30C1FC0CF010E944E +:1004B00084111BC0CF010E94E71217C0CF010E9418 +:1004C0002A1413C0CF010E945C150FC0CF010E94F7 +:1004D00089180BC02093320383E08093330310927A +:1004E000340383E090E00E949C012F980895CF93FD +:1004F000DF93EC018091E2019091E301019751F5C6 +:1005000020E030E0E091E401F091E501E20FF31F1B +:10051000DE01A20FB31F8C91EE50FE4F80832F5F40 +:100520003F4F2034310571F78091E4019091E5014E +:10053000805C9F4F9093E5018093E4012091E4015A +:100540003091E5018091E6019091E7012817390784 +:10055000A8F11FC01092E5011092E40120E030E004 +:10056000E091E401F091E501E20FF31FDE01A20F3B +:10057000B31F8C91EE50FE4F80832F5F3F4F20348E +:10058000310571F73093E5012093E401A981A0348E +:1005900048F41092E3011092E20182EF91E00E9490 +:1005A00025020CC081E090E09093E3018093E2018A +:1005B0008A2F99279093E7018093E601DF91CF91ED +:1005C00008951F920F920FB60F9211242F933F930D +:1005D0004F935F936F937F938F939F93AF93BF934B +:1005E000EF93FF930E94C50C80915D0186BDFF9142 +:1005F000EF91BF91AF919F918F917F916F915F919B +:100600004F913F912F910F900FBE0F901F90189513 +:100610001F920F920FB60F9211242F933F934F9377 +:100620005F936F937F938F939F93AF93BF93EF935A +:10063000FF930E94530CFF91EF91BF91AF919F9157 +:100640008F917F916F915F914F913F912F910F907B +:100650000FBE0F901F90189520E080E49CE9019751 +:10066000F1F72F5F2931C9F70895FF920F931F9378 +:10067000162F042FF22E9C01442737FD4095542F4E +:1006800060E472E48FE090E00E94C719215030408E +:10069000163061F0173019F0153019F404C0E1E09C +:1006A00003C0E1E004C0E0E070E002C0E0E071E01F +:1006B000053439F00F3419F451E041E004C050E042 +:1006C00001C051E040E082E0F81611F462E001C0A0 +:1006D00060E0832F992787FD9A958093C50020932A +:1006E000C40088E18093C100770FEE0FEE0FE72B77 +:1006F0005295550F507E5E2B4295407F452B660FDD +:10070000660F660F642B6093C2001F910F91FF90DC +:1007100008951092C50089E18093C40088E1809318 +:10072000C10086E08093C20008950895982F8091BB +:10073000C00085FFFCCF9093C60008958091C00053 +:1007400087FFFCCF8091C600992708958A3310F463 +:10075000805301C087556A3310F4605301C0675558 +:100760006F708295807F682B862F99270895FC01F2 +:1007700007C08091C00085FFFCCF31969093C600E2 +:1007800090819923B1F70895982F92959F70282F03 +:100790002F709A3030F48091C00085FFFCCF905DBF +:1007A00005C08091C00085FFFCCF995A9093C60088 +:1007B0002A3030F48091C00085FFFCCF205D05C059 +:1007C0008091C00085FFFCCF295A2093C600089570 +:1007D00087E280939A0485E28093990490E2909353 +:1007E0009B0410929C0428E030E030939E042093F8 +:1007F0009D0483E28093A60481E28093A5049093F4 +:10080000A7041092A8043093AA042093A904089581 +:1008100008956091B20481E20E945007089568E053 +:100820008BE20E94500761E188E20E94500768E075 +:100830008FE20E94500761E18CE20E94500761E064 +:100840008FE20E9450071092E1011092E00165E0F2 +:1008500083E20E94500708950F931F938C0160E478 +:1008600080E20E945007F8016281605884E00E9493 +:100870005007F80182818093B1041F910F91089570 +:100880000F931F93CF93DF93EC01288539851216C0 +:100890001306DCF58E819F81821793071CF568E0B3 +:1008A00083E20E94500700E010E00FC08A859B851C +:1008B000E80FF91F608181E20E9450078E819F81BD +:1008C00001969F838E830F5F1F4FEE81FF81888586 +:1008D0009985083011051CF4E817F9073CF3E8176F +:1008E000F90724F061E087E20E9450078B81813094 +:1008F00031F465E089810E9450071B8206C061E0E7 +:1009000089810E94500781E08B83DF91CF911F91F5 +:100910000F910895CF93DF93CDB7DEB724970FB62D +:10092000F894DEBF0FBECDBFDC01FC012281338114 +:100930001092AC041092AB0481E08093A804832F42 +:1009400099278230D9F0833069F1813009F057C09E +:100950008091850499279093AE048093AD0485E837 +:1009600094E09093B0048093AF04868197818034A3 +:10097000910509F044C088E090E029C0FD0186811E +:1009800097819093AE048093AD04E22FFF27EE0F82 +:10099000FF1F8091970490919804E80FF91F8081C0 +:1009A000918129C02223C1F0E22FFF27EE0FFF1F04 +:1009B0008091F0019091F101E80FF91F0190F08111 +:1009C000E02DF093B004E093AF04808199279093D9 +:1009D000AE048093AD0413C094E0998383E08A83CE +:1009E00089E08B839C8384E090E09093AE048093B5 +:1009F000AD04CE0101969093B0048093AF0485EAD4 +:100A000094E00E94400424960FB6F894DEBF0FBE17 +:100A1000CDBFDF91CF910895CF93DF9382E20E9403 +:100A20002B07C82FDD27C5FF1AC068E083E20E94AC +:100A30005007C6FF10C02091AB043091AC048091E8 +:100A4000AD049091AE04281739072CF485EA94E0A0 +:100A50000E94400404C061E087E20E945007DF91D9 +:100A6000CF9108951F93CF93DF9388E00E942B07C7 +:100A7000182FC82FDD27C6FF18C060E085E00E9450 +:100A8000500760E884E00E94500760E080E20E9426 +:100A9000500768E083E20E94500761E087E20E940D +:100AA000500762E085E00E945007C4FF04C060EC7C +:100AB00089E00E94500717FF04C060ED89E00E94A2 +:100AC0005007DF91CF911F9108958AE00E942B0774 +:100AD000992780FF03C00E940C05089581FF0DC077 +:100AE0008AE20E942B0780917204813061F4E091C8 +:100AF0007504F09176040995089582E30E942B070E +:100B00008AE30E942B0708958EE00E942B0768E07D +:100B10008FE20E94500761E08FE20E94500720910F +:100B2000AD043091AE048091A9049091AA0482177B +:100B300093075CF468E083E20E94500761E087E27B +:100B40000E94500781E08093A8040895AF92BF925D +:100B5000CF92DF92EF92FF920F931F93CF93DF9389 +:100B6000CDB7DEB728970FB6F894DEBF0FBECDBF66 +:100B700086E20E942B0786FF7EC08E010F5F1F4F0B +:100B8000580169E0C62ED12CCC0EDD1E809199044F +:100B90000E942B07F80181938F017501EC15FD056B +:100BA000A9F768E087E20E94500768E083E20E94AC +:100BB000500780E20E942B078F77682F80E20E9407 +:100BC000500789819927807690708032910509F4C9 +:100BD00040C080349105D1F1892BF1F5F501818177 +:100BE0008630D9F0873048F48130F1F18130C8F097 +:100BF0008330D1F1853081F521C0893019F18A30F7 +:100C000018F4883049F505C08A3071F18B3021F530 +:100C100020C0C5010E94090427C0C5010E948A04A2 +:100C200023C068E083E20E94500761E081E20E94F5 +:100C3000500760E081E20E9450070BC0C5010E948E +:100C40002C0412C0C5010E940F040EC0C5010E94F1 +:100C5000080765E083E206C080E20E942B07805807 +:100C6000682F80E20E945007F70180818823D1F429 +:100C700065E083E215C02091AD043091AE0480910F +:100C8000A9049091AA048217930764F41092AE0409 +:100C90001092AD0468E083E20E94500761E087E2B1 +:100CA0000E94500728960FB6F894DEBF0FBECDBF46 +:100CB000DF91CF911F910F91FF90EF90DF90CF9038 +:100CC000BF90AF900895CF92DF92EF92FF920F9373 +:100CD0001F93CF93DF93CDB7DEB7C054D0400FB68C +:100CE000F894DEBF0FBECDBF8CE00E942B07992782 +:100CF00080FF03C00E94A6057BC081FF2AC08EE250 +:100D00000E942B078DE20E942B0789838E010F5FC3 +:100D10001F4F6801FFE3EF2EF12CE00EF11E0F5F75 +:100D20001F4F0E941907F80180830E151F05B9F7A0 +:100D300080915401813031F4E0915701F0915801D4 +:100D4000C601099568E08FE20E94500761E08FE2DA +:100D50002BC082FF2CC086E30E942B0785E30E94F4 +:100D60002B0789838E010F5F1F4F6801EFE3EE2E83 +:100D7000F12CE00EF11E0F5F1F4F0E941907F801C2 +:100D800080830E151F05B9F780915501813031F42C +:100D9000E0915901F0915A01C601099568E087E395 +:100DA0000E94500761E087E30E94500721C083FF43 +:100DB0001FC08EE30E942B078E010F5F1F4F68013B +:100DC00071E4E72EF12CEC0EFD1E8DE30E942B0743 +:100DD000F80181938F01EE15FF05B9F78091560157 +:100DE000813031F4E0915701F0915801C601099525 +:100DF000C05CDF4F0FB6F894DEBF0FBECDBFDF91F2 +:100E0000CF911F910F91FF90EF90DF90CF900895B9 +:100E10000895089581E080936A0080E18DBB83B3DB +:100E2000876083BB84B3836084BB3F9A479A78947E +:100E3000089588B1805888B984B322E0822784BBA2 +:100E40000000000080B198B1905898B994B39227EF +:100E500094BB992708959FEF91B982B988B18058C2 +:100E600088B984B395E0892784BB88B1805888B954 +:100E700084B3892784BB000011B80E941907992701 +:100E8000089582B988B1805888B984B391E08927E0 +:100E900084BB88B1805888B984B3892784BB0895FE +:100EA00082B98FEF81B988B1805888B984B395E051 +:100EB000892784BB88B1805888B984B3892784BBCB +:100EC000862F0E9441070895089582E1809385044A +:100ED00081E08093860480E191E090938804809380 +:100EE00087041092890410928A0410928B0488E07F +:100EF00080938C0410928E0410928D0410929004B2 +:100F000010928F0410929204109291041092930404 +:100F10001092940410929504109296041092540129 +:100F2000109255011092560110927204109273049F +:100F30001092740410927C0410927B041092EF01C2 +:100F40001092EE01089590938E0480938D04709317 +:100F5000900460938F0450939204409391040895F9 +:100F600090938E0480938D040895909390048093C1 +:100F70008F04089590939204809391040895809330 +:100F80008904089580938A04089580938B040895BA +:100F9000CF93DF939C01CB01E0917B04F0917C0423 +:100FA00062E070E00E94B4190FC0A081B18182811B +:100FB000823039F4ED018D8199278217930709F466 +:100FC00068870780F085E02D309779F7DF91CF9122 +:100FD0000895CF93DF939C01E0917B04F0917C0412 +:100FE00014C0A081B1818281843061F48481992709 +:100FF0008217930739F4868199278617970711F48A +:10100000ED014B830780F085E02D309751F7DF919C +:10101000CF910895BF92CF92DF92EF92FF920F93FC +:101020001F93CF93DF936C01162FF42EB22EC09135 +:101030007B04D0917C042097A1F489E090E00E9489 +:10104000BB18FC0190937C0480937B04D182C08206 +:10105000138310861782F282B4820583E68215C05C +:10106000EC018F8198850097D9F789E090E00E9484 +:10107000BB18FC0198878F83D182C0821383F282D0 +:10108000B4820583E68210861782DF91CF911F918B +:101090000F91FF90EF90DF90CF90BF900895EF9267 +:1010A000FF921F93CF93DF937C01C091EE01D0910B +:1010B000EF01209711F011E012C085E090E00E944E +:1010C000BB18FC019093EF018093EE01F182E08266 +:1010D00012821482138210E012C01F5FEC018B8118 +:1010E0009C810097D1F785E090E00E94BB18FC013D +:1010F0009C838B83F182E082128314821382812F7E +:101100009927DF91CF911F91FF90EF900895EF9273 +:10111000FF920F931F93CF93DF93E091EE01F09135 +:10112000EF0180E090E00380F481E02D019630979C +:10113000D1F7880F991F0E94BB189093F1018093FB +:10114000F0010091EE011091EF01E801E880F980D3 +:101150008A81C82FDD27CC0FDD1F8091F00190918F +:10116000F101C80FD91FF701808199270E94BB1890 +:101170009983888320E030E017C0E801EA81FF27E7 +:10118000EE0FFF1F8091F0019091F101E80FF91F20 +:101190000190F081E02DE20FF31FD701A20FB31FE2 +:1011A0008C9180832F5F3F4FF7018081992728170B +:1011B00039071CF3E8018B819C81009711F08C01A9 +:1011C000C4CFDF91CF911F910F91FF90EF900895C1 +:1011D0004F925F926F927F928F929F92AF92BF9247 +:1011E000CF92DF92EF92FF920F931F93CF93DF93F3 +:1011F000E0917B04F0917C046624772409C082810D +:10120000823019F40894611C711C0780F085E02D70 +:101210003097A9F74301880C991CC4010E94BB18A0 +:101220009093980480939704E1E0EE2EF12CAA2489 +:10123000BB2455C0E0917B04F0917C0479E0C72E7B +:10124000D12C15C0A081B181848199278E159F056D +:1012500019F48381C80ED11CED018D818E1521F406 +:101260008281823009F45D010780F085E02D30979E +:1012700049F7009197041091980402501040080D0E +:10128000191DC6010E94BB18F8019183808320E0DC +:1012900030E0E0919704F0919804E80DF91D329741 +:1012A0000190F081E02DE20FF31FD501A20FB31FD3 +:1012B0008C9180832F5F3F4F2930310551F7E091AA +:1012C0009704F0919804E80DF91D32970190F08190 +:1012D000E02D8C2D875F82830894E11CF11C6E1435 +:1012E0007F040CF0A7CF61E0C62ED12C59E0A52ECB +:1012F000B12C4424552442E0842E912CA1C0A0910D +:101300007B04B0917C0412C0ED91FC911197818116 +:10131000823049F4858199278C159D0521F48481BB +:10132000482E552405C0ED01AF81B885109761F7AF +:1013300031E0E32EF12C79C060917B0470917C0444 +:101340006DC0FB01C081D1818981843009F063C007 +:10135000868199278E159F0509F05DC084819927A4 +:101360008C159D0509F057C0950140E050E0E091D3 +:101370009704F0919804E80DF91D32970190F081DF +:10138000E02DE20FF31FDE01A40FB51F8C918083C7 +:101390002F5F3F4F4F5F5F4F4930510541F789E065 +:1013A00090E0A80EB91EC0917B04D0917C0431C09E +:1013B0008A81853059F58C8199278C159D0531F5E9 +:1013C0008D8199278E159F0509F508811981950151 +:1013D00040E050E0E0919704F0919804E80DF91D89 +:1013E00032970190F081E02DE20FF31FD801A40F96 +:1013F000B51F8C9180832F5F3F4F4F5F5F4F47300A +:10140000510541F7E7E0F0E0AE0EBF1E0F80D88532 +:10141000C02D209769F6EB016F8178856115710504 +:1014200009F08FCF0894E11CF11C4E145F040CF0FE +:1014300083CF0894C11CD11CE2E0F0E08E0E9F1E09 +:101440006C147D040CF05BCFDF91CF911F910F9155 +:10145000FF90EF90DF90CF90BF90AF909F908F90D4 +:101460007F906F905F904F9008956F927F928F92D0 +:101470009F92AF92BF92CF92DF92EF92FF920F9323 +:10148000CF93DF935C013B014901E0917B04F09134 +:101490007C0416C0A081B18184819927A816B90661 +:1014A00061F4868199278615970539F48281843005 +:1014B00021F4ED018C818F5F8C830780F085E02D16 +:1014C000309741F787E090E00E94BB18FC0187E06D +:1014D000808385E0818382820383F582E482C682F1 +:1014E000EE24062D2A2D45E067E0CF010E940A0870 +:1014F000DF91CF910F91FF90EF90DF90CF90BF9051 +:10150000AF909F908F907F906F900895AF92BF9211 +:10151000CF92DF92EF92FF920F93FC01A114B104DE +:1015200001F14230510571F04330510599F04130DD +:101530005105B9F481E080937204B0927604A092D0 +:1015400075040FC081E080937304B0927804A09278 +:10155000770407C081E080937404B0927A04A0926B +:10156000790420583F4FCF010E94350A0F91FF9018 +:10157000EF90DF90CF90BF90AF900895AF92BF9261 +:10158000CF92DF92EF92FF920F93FC014230510510 +:1015900071F04330510599F041305105B9F481E0C3 +:1015A00080935401B0925801A09257010FC081E07E +:1015B00080935501B0925A01A092590107C081E071 +:1015C00080935601B0925C01A0925B01CF010E9412 +:1015D000350A0F91FF90EF90DF90CF90BF90AF90C2 +:1015E0000895CF92DF92EF920F931F93CF93DF93E3 +:1015F0006C018B01A0917B04B0917C04C0E0D0E031 +:1016000014C02D913C911197F90185818C1551F4ED +:10161000FD018281823031F4F90184818F5F8483FE +:10162000C82FDD27FD01A781B085109751F789E00C +:1016300090E00E94BB18FC0189E0808384E08183F4 +:101640000283138214821582168217821086EC2E72 +:1016500000E02C2D44E069E0CF010E940A08CE0191 +:10166000DF91CF911F910F91EF90DF90CF90089570 +:10167000BF92CF92DF92EF92FF920F931F93CF937F +:10168000DF936C017B01142FB22EA0917B04B091EB +:101690007C04C0E0D0E014C02D913C911197F90179 +:1016A00085818C1551F4FD018281823031F4F9017C +:1016B00084818F5F8483C82FDD27FD01A781B085DA +:1016C000109751F789E090E00E94BB18FC0189E077 +:1016D000808384E08183E282138214821583B68240 +:1016E00007831086EC2E00E02C2D44E069E0CF014A +:1016F0000E940A08CE01DF91CF911F910F91FF90B8 +:10170000EF90DF90CF90BF900895EF920F931F93CB +:10171000109196041F5F1093960489E090E00E9458 +:10172000BB18FC0189E0808389E090E09383828389 +:1017300082E0818314821583168280EA87838AE19E +:101740008087EE2400E020E042E069E0CF010E94C3 +:101750000A08812F99271F910F91EF900895CF9339 +:10176000DF93EC01FC0101900020E9F7E81BF90B85 +:10177000CF01880F991F0E94BB189C01FE010190A8 +:101780000020E9F7EC1BFD0BEE0FFF1FDC01EC93D3 +:1017900083E0F901818340E050E009C0FE01E40FDD +:1017A000F51F80818C93FD0111824F5F5F4F129670 +:1017B000FE0101900020E9F73197EC1BFD0B4E175D +:1017C0005F0760F3C9010E944F089927DF91CF910D +:1017D0000895EF92FF920F931F93CF93DF938C01A5 +:1017E0007B01CA010E94AF0B9C01E0917B04F09148 +:1017F0007C0414C0A081B1818281843061F4848131 +:1018000099278017910739F4868199278E159F05AE +:1018100011F4ED0128870780F085E02D309751F70E +:10182000DF91CF911F910F91FF90EF9008950F934B +:101830001F93CF93DF938C01CB010E94AF0B9C01D0 +:10184000E0917B04F0917C040FC0A081B181828182 +:10185000823039F4ED018D8199278017910709F4C1 +:101860002E830780F085E02D309779F7DF91CF91B7 +:101870001F910F9108950E94AF0B1816190614F4CA +:101880008093950408950E94AF0B1816190614F45E +:101890008093940408950E94AF0B1816190614F44F +:1018A0008093930408951F9386E00E942B07992745 +:1018B00086FF03C00E9463060EC082FF03C00E9421 +:1018C000650509C081FF03C00E94320504C084FF82 +:1018D00002C00E94840587E00E942B07182F60E059 +:1018E00087E00E945007612F87E00E9450071F91F8 +:1018F00008950E94E8080E9487080E94E80361E0BA +:1019000080E00E94500780E00E942B0780FDFBCF03 +:1019100062E081E00E94500760E884E00E94500786 +:1019200060E480E20E94500768E083E20E94500772 +:1019300069E087E20E9450076FE08DE00E94500747 +:101940006FE08BE00E94500768ED89E00E9450072D +:1019500063E38FE00E94500766ED87E00E94500726 +:1019600062E085E00E9450076CEC80E00E94500726 +:1019700008958EEC80935D0181E080936E008091EC +:101980005D0186BD83E084BD08950895089583E0D8 +:101990008093320381E0809333038BE080933403A0 +:1019A0002FE62093350393E69093360384E78093E4 +:1019B0003703209338039093390381E680933A03E9 +:1019C0008EE680933B038FE580933C0380E3809316 +:1019D0003D0381E380933E0310923F038EE090E04D +:1019E0000E949C010895FC018081833011F40E94C3 +:1019F000C70C0895CF93DF93C1E0D0E08C2F0E94F5 +:101A00000B0E2196C431D105C9F7CAE1D0E08C2F65 +:101A10000E940B0E2196CD32D105C9F7DF91CF91EF +:101A20000895CF93DF93DC01EC01EA81FB812191E2 +:101A30008E81815019F48981E81BF109ED01FB8346 +:101A4000EA838E839FB7F8948C9181508C939FBFCB +:101A5000822F9927DF91CF910895FC011082758321 +:101A60006483738362834183478346830895CF935E +:101A7000DF93DC019C91ED018981981718F080E0DB +:101A800090E016C0ED01EC81FD8161938F81815062 +:101A900019F48981E81BF109ED018F83FD83EC8343 +:101AA0009FB7F8948C918F5F8C939FBF81E090E0FB +:101AB000DF91CF910895FC0180818823E9F3CF0164 +:101AC0000E94110D99270895FC018081882319F443 +:101AD0008FEF9FEF0895CF010E94110D9927089570 +:101AE00081E090E0089581E090E0089581E090E049 +:101AF000089581E090E00895CF93DF93CDB7DEB7EE +:101B000022970FB6F894DEBF0FBECDBF282F8150AD +:101B1000833120F08951833108F06EC0E22FFF2716 +:101B2000EE0FFF1FE35AFE4F82E090E09283818325 +:101B3000822F9927AA27BB27FC013197EC32F105A8 +:101B400008F05AC0E65BFF4FEE0FFF1F0590F491BF +:101B5000E02D09946D9A47C06E9A49C06F9A43C0B0 +:101B6000209A45C0219A3FC0229A41C0239A3BC087 +:101B7000249A3DC0259A37C0269A39C0279A33C087 +:101B8000509A35C0519A2FC0529A31C0539A2BC0E7 +:101B9000549A2DC0559A27C0569A29C0579A23C0E7 +:101BA000389A25C0399A1FC03A9A21C03B9A1BC067 +:101BB0003C9A1DC03D9A17C03E9A19C0879A13C01F +:101BC000869A15C0859A0FC0849A11C0839A0BC05B +:101BD000829A0DC0819A07C0809A09C0689A03C092 +:101BE000699A05C06A9A81E090E008C06B9AE1E0CA +:101BF000F0E0FA83E98304C084E090E09A8389836B +:101C000089819A8122960FB6F894DEBF0FBECDBFB0 +:101C1000DF91CF910895982F8150833130F0895111 +:101C2000833118F084E090E00895892F0E947C0DA4 +:101C300081E090E00895CF93DF93CDB7DEB7229790 +:101C40000FB6F894DEBF0FBECDBF282F8150833171 +:101C500020F08951833108F06EC0E22FFF27EE0F8C +:101C6000FF1FE35AFE4F81E090E092838183822F31 +:101C70009927AA27BB27FC013197EC32F10508F020 +:101C80005AC0EA58FF4FEE0FFF1F0590F491E02D68 +:101C900009946D9847C06E9849C06F9843C02098CA +:101CA00045C021983FC0229841C023983BC024984A +:101CB0003DC0259837C0269839C0279833C0509822 +:101CC00035C051982FC0529831C053982BC05498AA +:101CD0002DC0559827C0569829C0579823C03898CA +:101CE00025C039981FC03A9821C03B981BC03C982A +:101CF0001DC03D9817C03E9819C0879813C086989C +:101D000015C085980FC0849811C083980BC0829825 +:101D10000DC0819807C0809809C0689803C0699871 +:101D200005C06A9881E090E008C06B98E1E0F0E0BF +:101D3000FA83E98304C084E090E09A8389838981EF +:101D40009A8122960FB6F894DEBF0FBECDBFDF9109 +:101D5000CF910895FB011082833091F0843028F4F4 +:101D6000813051F0823029F409C0843059F0853037 +:101D700059F085E090E0089583B107C086B105C0B1 +:101D800089B103C08CB101C08FB1808381E090E044 +:101D90000895833091F0843028F4813051F08230FE +:101DA00029F409C0843059F0853069F084E090E06E +:101DB000089565B905C068B903C06BB901C06EB9B3 +:101DC00081E090E0089561BB81E090E00895282FC4 +:101DD000E82FFF27EE0FFF1FE35AFE4F818192810C +:101DE000029719F086E090E00895822F9927AA279C +:101DF000BB27FC013197EC32F10540F4EE55FF4F63 +:101E0000EE0FFF1F0590F491E02D099484E090E01F +:101E10000895662311F0759ADDC07598DBC06623BE +:101E200011F0769AD7C07698D5C0662311F0779ACC +:101E3000D1C07798CFC0662311F0289ACBC02898DC +:101E4000C9C0662311F0299AC5C02998C3C066236A +:101E500011F02A9ABFC02A98BDC0662311F02B9AB0 +:101E6000B9C02B98B7C0662311F02C9AB3C02C9838 +:101E7000B1C0662311F02D9AADC02D98ABC066237A +:101E800011F02E9AA7C02E98A5C0662311F02F9AA4 +:101E9000A1C02F989FC0662311F0589A9BC05898F4 +:101EA00099C0662311F0599A95C0599893C066233A +:101EB00011F05A9A8FC05A988DC0662311F05B9A20 +:101EC00089C05B9887C0662311F05C9A83C05C98D8 +:101ED00081C0662311F05D9A7DC05D987BC066234A +:101EE00011F05E9A77C05E9875C0662311F05F9A14 +:101EF00071C05F986FC0662311F0409A6BC0409824 +:101F000069C0662311F0419A65C0419863C0662399 +:101F100011F0429A5FC042985DC0662311F0439A67 +:101F200059C0439857C0662311F0449A53C044984F +:101F300051C0662311F0459A4DC045984BC06623A9 +:101F400011F0469A47C0469845C0662311F08F9A13 +:101F500041C08F983FC0662311F08E9A3BC08E9887 +:101F600039C0662311F08D9A35C08D9833C0662331 +:101F700011F08C9A2FC08C982DC0662311F08B9A8B +:101F800029C08B9827C0662311F08A9A23C08A98AB +:101F900021C0662311F0899A1DC089981BC0662351 +:101FA00011F0889A17C0889815C0662311F0709AAE +:101FB00011C070980FC0662311F0719A0BC0719810 +:101FC00009C0662311F0729A05C0729803C0662397 +:101FD00021F0739A81E090E00895739881E090E099 +:101FE00008951F93182F8150833130F08951833128 +:101FF00018F084E090E013C0E12FFF27EE0FFF1FE1 +:10200000E35AFE4F83E090E092838183812F0E9408 +:102010007C0D61E0812F0E94E70E81E090E01F912E +:102020000895CF93DF93282FEB011882E82FFF2725 +:10203000EE0FFF1FE35AFE4F81819281019719F045 +:1020400086E090E089C0822F9927AA27BB27FC0150 +:102050003197EC32F10540F4E253FF4FEE0FFF1FD2 +:102060000590F491E02D099484E090E075C0659BA3 +:1020700071C06EC0669B6EC06BC0679B6BC068C052 +:10208000189B68C065C0199B65C062C01A9B62C07E +:102090005FC01B9B5FC05CC01C9B5CC059C01D9B8C +:1020A00059C056C01E9B56C053C01F9B53C050C042 +:1020B000489B50C04DC0499B4DC04AC04A9B4AC036 +:1020C00047C04B9B47C044C04C9B44C041C04D9B44 +:1020D00041C03EC04E9B3EC03BC04F9B3BC038C042 +:1020E000309B38C035C0319B35C032C0329B32C0C6 +:1020F0002FC0339B2FC02CC0349B2CC029C0359BD4 +:1021000029C026C0369B26C023C07F9B23C020C089 +:102110007E9B20C01DC07D9B1DC01AC07C9B1AC029 +:1021200017C07B9B17C014C07A9B14C011C0799B49 +:1021300011C00EC0789B0EC00BC0609B0BC008C0C6 +:10214000619B08C005C0629B05C002C0639B02C0C2 +:1021500081E0888381E090E0DF91CF910895CF9373 +:10216000DF93CDB7DEB721970FB6F894DEBF0FBE71 +:10217000CDBF9BE190933203BE016F5F7F4F0E9402 +:1021800011108093330389818093340383E090E0BE +:102190000E949C0121960FB6F894DEBF0FBECDBF02 +:1021A000DF91CF9108959AE1909332030E94E70E58 +:1021B000809333031092340383E090E00E949C01EB +:1021C000089598E1909332030E94C90E80933303DF +:1021D0001092340383E090E00E949C010895982FB0 +:1021E00089E180933203933099F0943028F4913050 +:1021F00059F0923029F40AC0943061F0953061F0C2 +:1022000085E090E020E00BC023B107C026B105C0F7 +:1022100029B103C02CB101C02FB181E090E08093BF +:1022200033032093340383E090E00E949C010895DF +:1022300097E1909332030E94F10F80933303109241 +:10224000340383E090E00E949C01089595E190930F +:1022500032030E941B0E809333031092340383E0F9 +:1022600090E00E949C01089596E1909332030E94B1 +:102270007C0D809333031092340383E090E00E943E +:102280009C01089584E18093320381E080933303BD +:102290001092340383E090E00E949C01089582E153 +:1022A0008093320381E0809333031092340383E000 +:1022B00090E00E949C01089583E18093320381E0C5 +:1022C000809333031092340383E090E00E949C01DA +:1022D000089580E18093320381E08093330310926C +:1022E000340383E090E00E949C01089591E1909373 +:1022F00032030E940B0E809333031092340383E069 +:1023000090E00E949C010895FC0180818531C9F113 +:10231000863180F4823131F1833130F48031D1F073 +:10232000813109F04CC01AC0833109F1843109F0C0 +:1023300046C022C0883189F1893128F4863129F1DB +:102340008731E9F526C08A3189F18A3158F18B311C +:10235000B1F531C082810E946911089582810E9485 +:1023600076110895638182810E944F1108956381DF +:1023700082810E945C110895638182810E944211D2 +:10238000089582810E942611089582810E9434114D +:10239000089582810E9418110895638182810E94AC +:1023A000E110089582810E94EF1008956381828177 +:1023B0000E94D310089582810E94AF1008958093E7 +:1023C000320383E0809333031092340383E090E080 +:1023D0000E949C010895FC018197089718F084E001 +:1023E00090E00895EE0FFF1FE35AFE4F84E090E067 +:1023F0009283818381E090E0089510927C00823086 +:10240000910541F08330910569F0019741F082E038 +:1024100090E0089580917C00806480937C0081E04E +:1024200090E0089580917C00806C80937C0081E036 +:1024300090E0089593E890937A0090917C00907FCB +:10244000982B90937C0080917A00806480937A002E +:1024500080917A0086FDFCCF809178009091790080 +:1024600020E030E040E050E080917A00806480938A +:102470007A0080917A0086FDFCCF8091780090915F +:102480007900480F591F2F5F3F4F2430310561F706 +:1024900080917A008F7780937A00CA01969587950C +:1024A000969587950895CF93DF939C01EB01198250 +:1024B0001882FC01EE0FFF1FE35AFE4F81819281CB +:1024C000049719F086E090E03CC02432310541F1D8 +:1024D0002532310554F42232310541F123323105E0 +:1024E00014F52132310569F424C02632310591F00A +:1024F0002632310594F02732310549F02832310572 +:1025000019F087E090E01DC080E090E014C081E009 +:1025100090E011C082E090E00EC083E090E00BC03C +:1025200084E090E008C085E090E005C086E090E09F +:1025300002C087E090E00E941A129983888381E0AC +:1025400090E0DF91CF91089522E2209332030E9420 +:10255000FD118093330382E090E00E949C01089576 +:10256000CF93DF93CDB7DEB722970FB6F894DEBFD7 +:102570000FBECDBF21E220933203BE016F5F7F4FBC +:102580000E9453128093330329813A81832F992724 +:10259000809334032093350384E090E00E949C01F3 +:1025A00022960FB6F894DEBF0FBECDBFDF91CF915C +:1025B000089520E2209332030E94EB1180933303AD +:1025C0001092340383E090E00E949C010895FC0186 +:1025D0008081813249F0823261F0803279F48281E7 +:1025E00099270E94D9120895828199270E94B012DA +:1025F0000895828199270E94A4120895809332033E +:1026000083E0809333031092340383E090E00E94D0 +:102610009C0108958091B9009927887F9070089552 +:102620008091BC0087FFFCCF0895ECEBF0E0808147 +:10263000846080838BE090E09093770180937601B3 +:102640008CE090E0909379018093780181E090E0B4 +:102650000895ECEBF0E080818B7F808382E090E056 +:10266000909377018093760190937901809378011C +:1026700081E090E008958130910511F48CE00BC069 +:102680008230910511F488E106C0039719F082E0C9 +:1026900090E0089588E48093B8008091B9008C7F21 +:1026A0008093B9008091B9008093B90081E090E0F7 +:1026B00008958091B90084EA8093BC008091BC00A9 +:1026C00087FFFCCF81E090E0089584E98093BC000F +:1026D00081E090E008958093BB0084E88093BC0083 +:1026E0008091BC0087FFFCCF80E090E0089584E8F3 +:1026F0008093BC008091BC0087FFFCCF8091BB0021 +:102700009927089585E38093320381E08093330312 +:102710008093340384E88093BC008091BC0087FFE1 +:10272000FCCF8091BB008093350385E090E00E9450 +:102730009C01089540E050E00FC0F901E40FF51F3F +:1027400080818093BB0084E88093BC008091BC00B2 +:1027500087FFFCCF4F5F5F4F4617570774F384E343 +:102760008093320381E0809333031092340383E03B +:1027700090E00E949C01089587E38093320384E9EE +:102780008093BC0081E0809333031092340383E094 +:1027900090E00E949C01089586E38093320380912B +:1027A000B90084EA8093BC008091BC0087FFFCCF15 +:1027B00081E0809333031092340383E090E00E9421 +:1027C0009C01089522E3209332030E943B138093DF +:1027D00033031092340383E090E00E949C0108953B +:1027E00081E380933203ECEBF0E080818B7F808388 +:1027F00082E090E090937701809376019093790145 +:102800008093780181E0809333031092340383E056 +:1028100090E00E949C01089580E380933203ECEBEA +:10282000F0E08081846080838BE090E0909377017A +:10283000809376018CE090E0909379018093780109 +:1028400081E0809333031092340383E090E00E9490 +:102850009C010895FC0180818433D9F0853338F4DC +:10286000813379F0823381F0803389F507C0863374 +:1028700041F18633D8F0873351F526C00E940C14FD +:1028800008950E94F0130895828199270E94E2130F +:102890000895428155276181772764507040838174 +:1028A00034969F0199270E949A13089542815527D3 +:1028B0006181772764507040838199270E94821339 +:1028C00008950E94CC1308950E94BC13089580932C +:1028D000320383E0809333031092340383E090E06B +:1028E0000E949C01089585B1817F85B9239886E077 +:1028F00084B91CBC1DBC83E58CBD88E090E090933E +:102900006901809368018AE090E090936B01809365 +:102910006A0189E090E090936D0180936C0181E001 +:1029200090E008951CBC1DBC82E090E0909369018A +:102930008093680190936B0180936A0190936D017D +:1029400080936C0181E090E00895089581E090E02B +:102950000895AC0120E030E00AC0FA01E20FF31F55 +:1029600080818EBD0DB407FEFDCF2F5F3F4F261730 +:1029700037079CF381E090E00895DC0120E030E02F +:1029800040E050E015C01EBC09C04F5F5F4F83E0C0 +:10299000493E58071CF088E090E008950DB407FE0A +:1029A000F4CFFD01E20FF31F8EB580832F5F3F4F01 +:1029B0002617370744F381E090E00895CF93DF9323 +:1029C000EC0120E030E0A0E0B0E018C0FE01E20F32 +:1029D000F31F80818EBD08C0119683E0A93EB80721 +:1029E0001CF088E090E00FC00DB407FEF5CFFB01AE +:1029F000E20FF31F8EB580832F5F3F4F24173507FB +:102A00002CF381E090E0DF91CF9108950F931F9315 +:102A10008B0123E420933203AB0164E373E00E9453 +:102A2000DE148093330310923403C80102960E948F +:102A30009C011F910F9108950F931F938C0184E4C3 +:102A400080933203B80184E393E00E94BD14809325 +:102A5000330310923403C80102960E949C011F9117 +:102A60000F91089523E4209332030E94A9148093C8 +:102A700033031092340383E090E00E949C01089598 +:102A800081E4809332030E94921480933303109266 +:102A9000340383E090E00E949C01089580E48093D9 +:102AA00032030E947314809333031092350383E042 +:102AB00090E00E949C010895CF93DF93EC01888100 +:102AC0008334A1F0843438F4813469F0823458F5C9 +:102AD0008034F1F405C0843481F08534C9F411C028 +:102AE0000E944E1520C00E9440151DC069817727A5 +:102AF000CE0102960E94321516C0898199270E9444 +:102B00001C1569817727CE0102960E9406150BC01D +:102B10008093320383E0809333031092340383E085 +:102B200090E00E949C01DF91CF910895209A219A14 +:102B3000229A2398249A259A2C982D9882E090E046 +:102B40009093850180938401909383018093820107 +:102B5000909381018093800181E090E090937F01C8 +:102B600080937E01089582E090E0909369018093C4 +:102B7000680190936B0180936A0190936D0180933B +:102B80006C0181E090E00895289829982A9880E2C5 +:102B90009EE40197F1F7289A8AE0982F9A95F1F729 +:102BA0002A9A299A8A95F1F70895282F299887FD5E +:102BB00002C02A9801C02A9A8AE0982F9A95F1F7C4 +:102BC000299A8A95F1F7299826FF02C02A9A01C00E +:102BD0002A988AE0982F9A95F1F7299A8A95F1F721 +:102BE0000895282F220F30E0299827FF02C02A9A43 +:102BF00001C02A988AE0982F9A95F1F7299A8A9528 +:102C0000F1F73F5F373011F0220FEECF0895282FF4 +:102C100030E0299827FF02C02A9A01C02A988AE04A +:102C2000982F9A95F1F7299A8A95F1F73F5F3830F6 +:102C300011F0220FEECF089529982A988AE0982F54 +:102C40009A95F1F7299A982F9A95F1F7299828984B +:102C5000982F9A95F1F7299A982F9A95F1F7299834 +:102C60008A95F1F7289A80E090E0089529982898AD +:102C70002A982B9A08950E94C41580E30E94D515C6 +:102C800080E60E94F11508950E94C41580E00E941C +:102C9000D51580E00E94F1150E94361608950F9315 +:102CA0001F93182F062F0E94C41580E40E94D5158B +:102CB000812F0E94F115802F0E94071681E090E07D +:102CC0001F910F9108951F93182F0E94C41580EC37 +:102CD0000E94D515812F0E94F1150E941C1699277C +:102CE0001F91089529988AE08A95F1F72A9830E093 +:102CF00090E0990F299A2AE0822F8A95F1F7299876 +:102D00001B999F5F822F8A95F1F73F5F383089F7D3 +:102D10002898299A822F8A95F1F7289A29982A9536 +:102D2000F1F7892F992708951F93182F0E94C41532 +:102D300080E80E94D515812F0E94F1150E9472161D +:102D400099271F910895DF92EF92FF920F931F939F +:102D5000CF93DF93D82E7B018A01C0E0D0E009C079 +:102D60008D2D8C0F0E949416F801EC0FFD1F8083AF +:102D70002196CE15DF05A1F781E090E0DF91CF919C +:102D80001F910F91FF90EF90DF9008950F931F9385 +:102D9000082F162F0E943B16612F802F0E944F167E +:102DA00081E090E01F910F910895DF92EF92FF92E2 +:102DB0000F931F93CF93DF93D82E7B018A01C0E03E +:102DC000D0E009C0F801EC0FFD1F60818D2D8C0F44 +:102DD0000E94C6162196CE15DF05A1F781E090E08E +:102DE000DF91CF911F910F91FF90EF90DF900895A9 +:102DF00094E0909332030E94D5168093330310928F +:102E0000340383E090E00E949C0108950F931F9388 +:102E10008B0193E09093320344E353E00E94A316A6 +:102E200080933303C80102960E949C011F910F9169 +:102E3000089582E08093320382E090E090936901EC +:102E40008093680190936B0180936A0190936D0168 +:102E500080936C0181E0809333031092340383E00C +:102E600090E00E949C01089581E0809332030E94CB +:102E70009615809333031092340383E090E00E9410 +:102E80009C010895FC018381823069F0833018F43D +:102E90008130F1F405C0833049F08430C9F40FC0AB +:102EA0000E94341708950E9419170895AF014A5FD0 +:102EB0005F4F6581772784810E9406170895AF01CF +:102EC0004A5F5F4F6581772784810E94F8160895D5 +:102ED00080818093320383E0809333031092340324 +:102EE00083E090E00E949C0108951F920F920FB61C +:102EF0000F9211240F900FBE0F901F9018959C01F8 +:102F00000897029718F084E090E00895F901EE0F19 +:102F1000FF1FE35AFE4F8DE090E0928381832830BB +:102F2000310531F02930310531F087E090E0089526 +:102F300081E090E00895259A81E090E090938900E7 +:102F40008093880081E88093800089E080938100ED +:102F500081E090E008959C01FC01EE0FFF1FE35A11 +:102F6000FE4F818192810D9719F086E090E00895DF +:102F70002830310539F12930310519F087E090E02A +:102F8000089563307105B1F06430710544F4613027 +:102F9000710561F06230710509F040C009C064300C +:102FA000710551F065307105C9F508C081E007C0B1 +:102FB00082E005C083E003C084E001C085E0809327 +:102FC000810029C064307105E9F06530710554F461 +:102FD0006230710599F06330710594F461307105C8 +:102FE000E9F40AC06630710589F06630710564F055 +:102FF0006730710599F40CC089E60BC08AE609C0F8 +:103000008BE607C08CE605C08DE603C08EE601C0E6 +:103010008FE68093B00081E090E0089581E090E039 +:1030200008959C01FC01EE0FFF1FE35AFE4F8181C2 +:1030300092810D9719F086E090E0089528303105CF +:1030400069F02930310519F087E090E00895709318 +:1030500089006093880081E090E008956093B30058 +:1030600081E090E0089523E5209332030E94111837 +:10307000809333031092340383E090E00E949C011C +:10308000089522E5209332030E94AB178093330307 +:103090001092340383E090E00E949C01089520E5A3 +:1030A000209332030E947F178093330310923403DE +:1030B00083E090E00E949C0108959C01FC01EE0FCA +:1030C000FF1FE35AFE4F82E090E092838183283015 +:1030D000310531F02930310531F086E090E0089576 +:1030E0001092B00002C010928100822F0E947C0DCD +:1030F00081E090E0089521E5209332030E945D185D +:10310000809333031092340383E090E00E949C018B +:103110000895FC018081813579F0823518F480357D +:10312000F1F405C0823569F08335C9F411C082819C +:1031300099270E944F180895828199270E947B1831 +:10314000089563817727828199270E944118089505 +:1031500063817727828199270E943318089580938D +:10316000320383E0809333031092340383E090E0D2 +:103170000E949C010895CF93DF93AC01029710F455 +:1031800042E050E0A091B704B091B804FD01C0E066 +:10319000D0E020E030E020C0808191818417950745 +:1031A00069F482819381209719F09B838A8304C0FC +:1031B0009093B8048093B704CF0132C048175907E1 +:1031C00038F42115310519F08217930708F49C0192 +:1031D000EF010280F381E02D3097F1F621153105E2 +:1031E00089F1C901841B950B049708F4A901E0E05B +:1031F000F0E026C08D919C91119782179307E9F416 +:103200004817590779F4ED018A819B81309719F0AD +:103210009383828304C09093B8048093B704CD0154 +:10322000029649C0841B950BFD01E80FF91F4193DD +:10323000519302978D939C933AC0FD01A281B38173 +:103240001097C1F68091B5049091B604892B41F492 +:1032500080915001909151019093B6048093B504F0 +:1032600020915201309153012115310541F42DB7C0 +:103270003EB780914E0190914F01281B390BE09190 +:10328000B504F091B6042E1B3F0B2417350788F0C8 +:10329000CA0102962817390760F0CF01840F951FE5 +:1032A00002969093B6048093B50441935193CF0155 +:1032B00002C080E090E0DF91CF910895CF93DF933B +:1032C000009709F44EC0EC0122971B821A82A0914C +:1032D000B704B091B804109711F140E050E001C07C +:1032E000DC01AC17BD0700F1BB83AA83FE0121916D +:1032F0003191E20FF31FEA17FB0771F42E5F3F4F86 +:103300008D919C911197820F931F99838883FD0162 +:10331000828193819B838A834115510559F4D0930F +:10332000B804C093B7041DC0FD0182819381AD0133 +:103330000097B1F6FA01D383C28321913191E20F54 +:10334000F31FEC17FD0769F42E5F3F4F88819981C9 +:10335000820F931FFA01918380838A819B819383DB +:103360008283DF91CF91089597FB092E07260AD01B +:1033700077FD04D027D006D000201AF4709561950F +:103380007F4F0895F6F7909581959F4F089597FB8D +:10339000092E05260ED057FD04D028D00AD0001CD7 +:1033A00038F450954095309521953F4F4F4F5F4FE2 +:1033B0000895F6F790958095709561957F4F8F4FA2 +:1033C0009F4F0895AA1BBB1B51E107C0AA1FBB1F3B +:1033D000A617B70710F0A61BB70B881F991F5A95A1 +:1033E000A9F780959095BC01CD010895A1E21A2E10 +:1033F000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F99 +:10340000A217B307E407F50720F0A21BB30BE40BE8 +:10341000F50B661F771F881F991F1A9469F760952F +:103420007095809590959B01AC01BD01CF010895E9 +:10343000456D62656464656450726F6A6563747338 +:10344000004F63746F70757355534220496E7465F5 +:10345000726661636520436F6E7665727465722073 +:10346000616E6420492F4F20457874656E73696FD3 +:103470006E0032303038313130380009040020001D +:04348000B90400008B +:00000001FF diff --git a/firmware/protocol.h b/firmware/protocol.h new file mode 100644 index 0000000..fce8eda --- /dev/null +++ b/firmware/protocol.h @@ -0,0 +1,94 @@ +/** + * Protocol is under GNU/GPL2! + * Author: Benedikt Sauter sauter@empronix.com, 2007-09-02 + * + * BYTE command + * BYTE parameter + * BYTE length body + * BYTES body + * + * max body length = 60 bytes + */ + +/** + * The first byte in the body of an response packet + * is always a value from the next table. + */ + +#define RSP_OK 0x01 +#define RSP_ERROR 0x02 +#define RSP_UNKOWN_CMD 0x03 +#define RSP_UNKOWN_PIN 0x04 +#define RSP_UNKOWN_PORT 0x05 +#define RSP_WRONG_PIN_CONFIG 0x06 +#define RSP_IMPOSSIBLE_PIN_CONFIG 0x07 +#define RSP_TIMEOUT 0x08 + + +#define CMD_LATENCY_TIMER_SET 0x01 +#define CMD_LATENCY_TIMER_GET 0x02 +#define CMD_GET_HW_ID 0x03 +#define CMD_EXTERNAL_DEVICE 0x06 + +#define CMD_IO_INIT_PORT 0x10 +#define CMD_IO_INIT_PIN 0x11 +#define CMD_IO_PORT_DIRECTION_IN 0x12 +#define CMD_IO_PORT_DIRECTION_OUT 0x13 +#define CMD_IO_PORT_DIRECTION_TRI 0x14 +#define CMD_IO_PIN_DIRECTION_IN 0x15 +#define CMD_IO_PIN_DIRECTION_OUT 0x16 +#define CMD_IO_PIN_DIRECTION_TRI 0x17 +#define CMD_IO_PORT_SET 0x18 +#define CMD_IO_PORT_GET 0x19 +#define CMD_IO_PIN_SET 0x1A +#define CMD_IO_PIN_GET 0x1B + +#define CMD_ADC_INIT_PIN 0x20 +#define CMD_ADC_GET 0x21 +#define CMD_ADC_REF 0x22 + +#define CMD_I2C_INIT 0x30 +#define CMD_I2C_DEINIT 0x31 +#define CMD_I2C_SET_BITRATE 0x32 +#define CMD_I2C_SEND_BYTE 0x34 +#define CMD_I2C_RECV_BYTES 0x35 +#define CMD_I2C_SEND_START 0x36 +#define CMD_I2C_SEND_STOP 0x37 + +#define CMD_SPI_INIT 0x40 +#define CMD_SPI_DEINIT 0x41 +#define CMD_SPI_SPEED 0x42 +#define CMD_SPI_SEND 0x43 +#define CMD_SPI_RECV 0x44 +#define CMD_SPI_SEND_AND_RECV 0x45 + + +#define CMD_PWM_INIT_PIN 0x50 +#define CMD_PWM_DEINIT_PIN 0x51 +#define CMD_PWM_SPEED 0x52 +#define CMD_PWM_VALUE 0x53 + + +#define CMD_UART_INIT 0x60 +#define CMD_UART_DEINIT 0x61 +#define CMD_UART_BAUDRATE 0x62 +#define CMD_UART_STOPBITS 0x63 +#define CMD_UART_DATABITS 0x64 +#define CMD_UART_PARITY 0x65 +#define CMD_UART_RECV 0x67 +#define CMD_UART_SEND 0x68 + + +#define PARAM_ADC_AREF 0x01 +#define PARAM_ADC_AVCC 0x02 +#define PARAM_ADC_INTERNAL 0x03 + + +/* microwire eeprom */ +#define CMD_EXTERNAL_93C46 0x01 + + +#define CMD_93C46_INIT 0x01 +#define CMD_93C46_DEINIT 0x02 +#define CMD_93C46_READ 0x03 +#define CMD_93C46_WRITE 0x04 diff --git a/firmware/pwm.c b/firmware/pwm.c new file mode 100644 index 0000000..9e3666d --- /dev/null +++ b/firmware/pwm.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2007 empronix (http://www.empronix.com) + * Author: Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES{} LOSS OF USE, + * DATA, OR PROFITS{} OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "common.h" +#include "protocol.h" +#include "adc.h" +#include "io.h" +#include "pwm.h" + +#include + +volatile unsigned int counter; + + SIGNAL(SIG_OUTPUT_COMPARE1A){ + //OCR1A = counter; + } + + + +void pwm_parser(char *buf) +{ + switch(buf[0]) + { + case CMD_PWM_INIT_PIN: + pwm_init_usb((int)buf[2]); + break; + case CMD_PWM_DEINIT_PIN: + pwm_deinit_usb((int)buf[2]); + break; + case CMD_PWM_SPEED: + pwm_speed_usb((int)buf[2],(int)buf[3]); + break; + case CMD_PWM_VALUE: + pwm_value_usb((int)buf[2],(int)buf[3]); + break; + + default: + answer[0]=buf[0]; + answer[1]=RSP_UNKOWN_CMD; + answer[2]=0; + CommandAnswer(3); + } +} + +int pwm_init(int pin) +{ + if (pin >= 8 && pin <= 9) + { + octopus.ports[pin] = PIN_PWM; + + switch(pin) + { + case 9: + /* set pin as output */ + OX_DDR9 |=(1< + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef PWM_H +#define PWM_H + +#include +#include + + +void pwm_parser(char *buf); + +int pwm_init(int pin); +void pwm_init_usb(int pin); + +int pwm_deinit(int pin); +void pwm_deinit_usb(int pin); + +void pwm_speed_usb(int pin, int speed); +int pwm_speed(int pin, int speed); + +void pwm_value_usb(int pin, unsigned int value); +int pwm_value(int pin, unsigned int value); + +#endif /* PWM_H */ diff --git a/firmware/spi.c b/firmware/spi.c new file mode 100644 index 0000000..2b8abb1 --- /dev/null +++ b/firmware/spi.c @@ -0,0 +1,188 @@ +/* + * Author: Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "common.h" +#include "protocol.h" + +#include "spi.h" + +void spi_parser(char *buf) +{ + switch(buf[0]) { + case CMD_SPI_INIT: + spi_init_usb(); + break; + case CMD_SPI_DEINIT: + spi_deinit_usb(); + break; + case CMD_SPI_SPEED: + spi_set_speed_usb((int)buf[2]); + break; + case CMD_SPI_SEND: + spi_send_usb(&buf[2], (int)buf[1]); + break; + case CMD_SPI_RECV: + spi_receive_usb((int)buf[1]); + case CMD_SPI_SEND_AND_RECV: + spi_send_and_receive_usb(&buf[2], (int)buf[1]); + break; + default: + answer[0] = buf[0]; + answer[1] = RSP_UNKOWN_CMD; + answer[2] = 0; + CommandAnswer(3); + } +} + +void spi_init_usb(void) +{ + answer[0] = CMD_SPI_INIT; + answer[1] = (unsigned char) spi_init(); + answer[3] = 0; + CommandAnswer(3); +} + + +int spi_init(void) +{ + PORTB &= ~((1 << SCK)|(1< 1000) return RSP_TIMEOUT; } + buf[i]=SPDR; + } + return RSP_OK; +} + +void spi_send_and_receive_usb(char * txbuf, int length) +{ + answer[0]=CMD_SPI_SEND; + answer[1]=(unsigned char)spi_send_and_receive(txbuf,(char *)&answer[2],length); + answer[2]=0; + CommandAnswer(2+length); + +} + +int spi_send_and_receive(char * txbuf, char * rxbuf, int length){ + + int i, timeout=0; + for(i=0;i 1000) return RSP_TIMEOUT; } + rxbuf[i]=SPDR; + } + return RSP_OK; +} + + + + + + diff --git a/firmware/spi.h b/firmware/spi.h new file mode 100644 index 0000000..d7cfbf1 --- /dev/null +++ b/firmware/spi.h @@ -0,0 +1,64 @@ +/* + * Author: Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SPI_H +#define SPI_H + +#include +#include + +#define MOSI PB2 +#define MISO PB3 +#define SCK PB1 + +void spi_parser(char *buf); + +int spi_init(void); +int spi_deinit(void); + +int spi_set_speed(int speed); +int spi_send(char * buf, int length); +unsigned char spi_receive( char * buf, int length); +int spi_send_and_receive(char * txbuf, char * rxbuf, int length); + + +void spi_init_usb(void); +void spi_deinit_usb(void); + +void spi_set_speed_usb(int speed); +void spi_send_usb(char * buf, int length); +void spi_receive_usb(int length); +void spi_send_and_receive_usb(char * txbuf, int length); + + +#endif /* SPI_H */ diff --git a/firmware/uart.c b/firmware/uart.c new file mode 100644 index 0000000..02b4a87 --- /dev/null +++ b/firmware/uart.c @@ -0,0 +1,381 @@ +#include +#include + +#include "uart.h" +#include "common.h" +#include "protocol.h" + +void uart_parser(char *buf) +{ + answer[0] = buf[0]; + + switch(buf[0]) + { + case CMD_UART_INIT: + uart_init_usb((char)buf[2]); + break; + case CMD_UART_DEINIT: + uart_deinit_usb((char)buf[2]); + break; + + case CMD_UART_BAUDRATE: + uart_baudrate_usb((char)buf[2], (char)buf[3], (char)buf[4], (char)buf[5], (char)buf[6]); + break; + case CMD_UART_STOPBITS: + uart_stopbits_usb((char)buf[2], (char)buf[3]); + break; + case CMD_UART_DATABITS: + uart_stopbits_usb((char)buf[2], (char)buf[3]); + break; + case CMD_UART_PARITY: + uart_parity_usb((char)buf[2], (char)buf[3]); + break; + + case CMD_UART_SEND: + uart_send_usb((char)buf[2], (char)buf[3], &buf[4]); + break; + case CMD_UART_RECV: + uart_recv_usb((char)buf[2], (char)buf[3]); + break; + default: + answer[1] = RSP_UNKOWN_CMD; + answer[2] = '\0'; + CommandAnswer(3); + } +} + +void uart_init_usb(char uartport) +{ + answer[1] = (unsigned char)uart_init(uartport); + answer[2] = '\0'; + + CommandAnswer(3); +} + +char uart_init(char uartport) +{ + switch(uartport) + { + case 0: + octopus.ports[41] = PIN_UART; + octopus.ports[42] = PIN_UART; + /* enable transmitter receiver */ + UCSR0B = (1 << RXEN0) | (1 << TXEN0); + break; + case 1: + octopus.ports[14] = PIN_UART; + octopus.ports[15] = PIN_UART; + /* enable transmitter receiver */ + UCSR1B = (1 << RXEN1) | (1 << TXEN1); + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_deinit_usb(char uartport) +{ + answer[1] = (unsigned char)uart_deinit(uartport); + answer[2] = '\0'; + + CommandAnswer(3); +} + +char uart_deinit(char uartport) +{ + switch(uartport) + { + case 0: + octopus.ports[41] = PIN_NONE; + octopus.ports[42] = PIN_NONE; + UBRR0H = 0; + UBRR0L = 0; + UCSR0B = 0; + UCSR0C = 0; + break; + case 1: + octopus.ports[14] = PIN_NONE; + octopus.ports[15] = PIN_NONE; + UBRR1H = 0; + UBRR1L = 0; + UCSR1B = 0; + UCSR1C = 0; + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_baudrate_usb(char uartport, char ubrrll, char ubrrlh, char ubrrhl, char ubrrhh) +{ + answer[1] = (unsigned char)uart_baudrate(uartport, ubrrll, ubrrlh, ubrrhl, ubrrhh); + answer[2] = '\0'; + + CommandAnswer(3); +} + +char uart_baudrate(char uartport, char ubrrll, char ubrrlh, char ubrrhl, char ubrrhh) +{ + switch(uartport) + { + case 0: + UBRR0H = (ubrrhh << 8) | ubrrhl; + UBRR0L = (ubrrhl << 8) | ubrrll; + break; + case 1: + UBRR1H = (ubrrhh << 8) | ubrrhl; + UBRR1L = (ubrrhl << 8) | ubrrll; + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_stopbits_usb(char uartport, char stopbits) +{ + answer[1] = (unsigned char)uart_stopbits(uartport, stopbits); + answer[2] = '\0'; + + CommandAnswer(3); +} + +char uart_stopbits(char uartport, char stopbits) +{ + char usbs; + + switch(stopbits) + { + case 1: usbs = 0; break; + case 2: usbs = 2; break; + default: usbs = 0; break; + } + + switch(uartport) + { + case 0: + UCSR0C |= (usbs << USBS0); + break; + case 1: + UCSR1C |= (usbs << USBS1); + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_databits_usb(char uartport, char databits) +{ + answer[1] = (unsigned char)uart_databits(uartport, databits); + answer[2] = '\0'; + + CommandAnswer(3); +} + +char uart_databits(char uartport, char databits) +{ + char ucsz1,ucsz0; + + switch(databits) { + case 5: ucsz1 = 0; ucsz0 = 0; break; + case 6: ucsz1 = 0; ucsz0 = 1; break; + case 7: ucsz1 = 1; ucsz0 = 0; break; + case 8: ucsz1 = 1; ucsz0 = 1; break; + default: ucsz1 = 1; ucsz0 = 1; break; + } + + switch(uartport) + { + case 0: + UCSR0C |= (ucsz1 << UCSZ01) | (ucsz0 << UCSZ00); + break; + case 1: + UCSR1C |= (ucsz1 << UCSZ11) | (ucsz0 << UCSZ10); + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_parity_usb(char uartport, char parity) +{ + answer[1] = (unsigned char)uart_databits(uartport, parity); + answer[2] = '\0'; + + CommandAnswer(3); +} + +char uart_parity(char uartport, char parity) +{ + char upm1, upm0; + switch(parity) + { + case 'N': upm1 = 0; upm0 = 0; break; + case 'E': upm1 = 1; upm0 = 0; break; + case 'O': upm1 = 1; upm0 = 1; break; + default: upm1 = 0; upm0 = 0; break; + } + + switch(uartport) + { + case 0: + UCSR0C |= (upm1 << UPM01) | (upm0 << UPM00); + break; + case 1: + UCSR1C |= (upm1 << UPM11) | (upm0 << UPM10); + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_send_usb(char uartport, char length, char *buf) +{ + answer[1] = (unsigned char)uart_send(uartport, length, buf); + answer[2] = '\0'; + + CommandAnswer(3); +} + + +char uart_send(char uartport, unsigned int length, char *buf) +{ + if(uartport != 0 && uartport != 1) + return RSP_UNKOWN_PIN; + + while(length--) + { + uart_putchar(uartport, *buf++); + } + + return RSP_OK; +} + +char uart_putchar(char uartport, char data) +{ + switch(uartport) + { + case 0: + /* Wait for empty transmit buffer */ + while (!(UCSR0A & (1 << UDRE0))); + /* Put data into buffer, sends the data */ + UDR0 = data; + break; + case 1: + /* Wait for empty transmit buffer */ + while (!(UCSR1A & (1 << UDRE1))); + /* Put data into buffer, sends the data */ + UDR1 = data; + break; + default: + return RSP_UNKOWN_PIN; + } + + return RSP_OK; +} + +void uart_recv_usb(char uartport, int length) +{ + char data[length]; + int i; + + answer[1] = (char)uart_recv(uartport, data, length); + + for(i = 0; i < length; i++) + answer[2+i] = data[i]; + + CommandAnswer(3+length); +} + +char uart_recv(char uartport, char * buf, int length) +{ + if(uartport != 0 && uartport != 1) + return RSP_UNKOWN_PIN; + + while(length-- > 0) + *buf++ = uart_getchar(uartport); + + return RSP_OK; +} + +char uart_getchar(char uartport) +{ + char c; + + switch(uartport) + { + case 0: + while (!(UCSR0A & (1 << RXC0))); + c = UDR0; + break; + case 1: + while (!(UCSR1A & (1 << RXC1))); + c = UDR1; + break; + default: + return RSP_UNKOWN_PIN; + } + + return c; +} + +/* +unsigned char AsciiToHex(unsigned char high,unsigned char low) +{ + unsigned char new; + + // check if lower equal 9 ( ascii 57 ) + if(high <= 57) // high is a number + high = high -48; + else // high is a letter + high = high -87; + + high = high << 4; + high = high & 0xF0; + + // check if lower equal 9 ( ascii 57 ) + if(low <= 57) // high is a number + low = low -48; + else // high is a letter + low = low -87; + low = low & 0x0F; + + new = high | low; + + return new; +} + +void SendHex(unsigned char hex) +{ + unsigned char high,low; + // get highnibble + high = hex & 0xF0; + high = high >> 4; + + // get lownibble + low = hex & 0x0F; + + if(high<=9) + UARTPutChar(high+48); + else + UARTPutChar(high+87); + + + if(low<=9) + UARTPutChar(low+48); + else + UARTPutChar(low+87); + +} +*/ diff --git a/firmware/uart.h b/firmware/uart.h new file mode 100644 index 0000000..fc89a0a --- /dev/null +++ b/firmware/uart.h @@ -0,0 +1,19 @@ +void uart_parser(char *); +char uart_init(char); +void uart_init_usb(char); +char uart_deinit(char); +void uart_deinit_usb(char); +char uart_baudrate(char uartport, char, char, char, char); +void uart_baudrate_usb(char uartport, char, char, char, char); +char uart_stopbits(char, char); +void uart_stopbits_usb(char, char); +char uart_databits(char, char); +void uart_databits_usb(char, char); +char uart_parity(char, char); +void uart_parity_usb(char, char); +char uart_putchar(char, char); +char uart_getchar(char uartport); +char uart_send(char uartport, unsigned int length, char *buf); +void uart_send_usb(char uartport, char length, char *buf); +void uart_recv_usb(char uartport, int length); +char uart_recv(char uartport, char * buf, int length); diff --git a/firmware/usbn2mc.c b/firmware/usbn2mc.c new file mode 100644 index 0000000..d9b0fdd --- /dev/null +++ b/firmware/usbn2mc.c @@ -0,0 +1,153 @@ +/* usbn960x.c +* Copyright (C) 2005 Benedikt Sauter +* +* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "usbn2mc.h" +#include "uart.h" + +//******************************************************************* +// add own vendor requests +// ******************************************************************** + +// decode your own vendor requests + +void +USBNDecodeVendorRequest (DeviceRequest * req) +{ +#if 0 + //SendHex(req->bRequest); // decode request code + SendHex (req->wLength); // decode request code + USBNWrite (RXC0, RX_EN); + USBNRead (RXD0); + USBNRead (RXD0); + + //USBNWrite(TXC0,FLUSH); + //USBNWrite(TXD0,0x24); + //USBNWrite(TXD0,0x25); +#endif +} + + +void +USBNDecodeClassRequest (DeviceRequest * req) +{ +#if 0 + //SendHex(req->bRequest); // decode request code + SendHex (req->wLength); // decode request code + USBNWrite (RXC0, RX_EN); + USBNRead (RXD0); + USBNRead (RXD0); +#endif +} + + + +// ******************************************************************** +// This subroutine handles the communication with usbn9604 +// ******************************************************************** + + +// Read data from usbn96x register + +void +USBNInitMC (void) +{ + // interrupt on INT4 pin falling edge (atmega128) + //EICRB = (0 << ISC41) | (1 << ISC40); + EICRB = (1 << ISC40); + // interrupts on! + //EIMSK = (1 << INT4); // allow extern irq4 + EIMSK = (1 << INT4); + + USB_CTRL_DDR |= (1 << PF_A0) | (1 << PF_RD) | (1 << PF_WR); // output (a0,rd,wr) + //USB_CTRL_PORT |= ((1 << PF_RD) | (1 << PF_WR) & ~(PF_A0)); + USB_CTRL_PORT |= ((1 << PF_RD) | (1 << PF_WR)); + USB_CS_DDR |= (1 << PF_CS); + USB_CS_PORT |= (1 << PF_CS); + + sei (); +} + + +unsigned char +USBNRead (unsigned char Adr) +{ + USB_DATA_DDR = 0xff; // set for output + USB_DATA_OUT = Adr; // load address + + USB_CS_PORT ^= (1 << PF_CS); + USB_CTRL_PORT ^= (1 << PF_WR) | (1 << PF_A0); // strobe the CS, WR, and A0 pins + USB_CS_PORT ^= (1 << PF_CS); + USB_CTRL_PORT ^= (1 << PF_WR) | (1 << PF_A0); // strobe the CS, WR, and A0 pins +// USB_CS_PORT ^=(1< +#include +#include + + +#include "../usbn2mc/main/usbnapi.h" + +unsigned char USBNRead(unsigned char Adr); +unsigned char USBNBurstRead(void); +void USBNWrite(unsigned char Adr,unsigned char Data); +void USBNBurstWrite(unsigned char Data); + +void USBNInitMC(void); + +// print debug messages +void USBNDebug(char *msg); + +void USBNDecodeVendorRequest(DeviceRequest *req); +void USBNDecodeClassRequest(DeviceRequest *req); + + +/// The Atmega register used to send data/address to the USBN9604 +#define USB_DATA_OUT PORTA + +/// The Atmega register used to receive data from the USBN9604 +#define USB_DATA_IN PINA + +/// The Atmega register that controls the i/o direction of the USB_DATA_OUT +#define USB_DATA_DDR DDRA + +/// The Atmega port used to send control signals to the USBN9604 +#define USB_CTRL_PORT PORTG + +/// The Atmega register that controls the i/o direction of USB_CTRL_PORT +#define USB_CTRL_DDR DDRG + + +#define USB_CS_DDR DDRC +#define USB_CS_PORT PORTC + +/// The pin address of the chip select signal +#define PF_CS PC7 + +/// The pin address of the Address enable signal +#define PF_A0 PG2 + +/// The pin address of the write strobe signal +#define PF_WR PG0 + +/// The pin address of the read strobe signal +#define PF_RD PG1 + +#endif /* _MCIFACE_H_ */ diff --git a/firmware/wait.c b/firmware/wait.c new file mode 100644 index 0000000..91ef62a --- /dev/null +++ b/firmware/wait.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006, Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "wait.h" +#define F_CPU 16000000U +#include + +void delay_250ms (void) +{ + uint8_t i; + + for (i = 0; i < 25; i++) + _delay_ms (10); +} diff --git a/firmware/wait.h b/firmware/wait.h new file mode 100644 index 0000000..f1b56f8 --- /dev/null +++ b/firmware/wait.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2006, Benedikt Sauter + * All rights reserved. + * + * Short descripton of file: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the FH Augsburg nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef WAIT_H +#define WAIT_H + + +void delay_250ms (void); +#endif /* WAIT_H */ diff --git a/liboctopus/.gitignore b/liboctopus/.gitignore new file mode 100644 index 0000000..cc78368 --- /dev/null +++ b/liboctopus/.gitignore @@ -0,0 +1,2 @@ +*.so +*.o diff --git a/liboctopus/Makefile b/liboctopus/Makefile new file mode 100644 index 0000000..70d2625 --- /dev/null +++ b/liboctopus/Makefile @@ -0,0 +1,10 @@ +CC=gcc +CFLAGS= -fPIC +LDFLAGS=`pkg-config --libs libusb` + +all: octopus.o + gcc -fPIC -shared octopus.o $(LDFLAGS) -o liboctopus.so + +.PHONY: clean +clean: + rm -vf octopus.o liboctopus.so diff --git a/liboctopus/octopus.c b/liboctopus/octopus.c new file mode 100644 index 0000000..5471d7b --- /dev/null +++ b/liboctopus/octopus.c @@ -0,0 +1,815 @@ +/*************************************************************************** + octopus.c - description + ------------------- + begin : Aug 2007 + author : Benedikt Sauter, sauter@embedded-projects.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software, you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License * + * version 2.1 as published by the Free Software Foundation. * + * * + ***************************************************************************/ + +/** + \mainpage liboctopus API documentation + + Library to talk to octopus devices. You find the latest versions of liboctopus at + http://www.embedded-projects.net/octopus + + The library is easy to use. Have a look at this short example: + \include simple.c + + More examples can be found in the "examples" directory. +*/ +/** \addtogroup liboctopus */ +/* @{ */ + +#include +#include +#include + +#include "octopus.h" +#include "../firmware/protocol.h" + +#define F_CPU 16000000UL + +#define octopus_error_return(code, str) do { \ + octopus->error_str = str; \ + return code; \ + } while(0); + + +/* + * initial octopus handle before use octopus_open + */ +int octopus_init(struct octopus_context *octopus) +{ + if (octopus == NULL) + octopus_error_return(-1,"octopus not valid"); + + octopus->error_str = NULL; + octopus->usb_handle = NULL; + + return 1; +} + +/* + * open first octopus on usb + */ +int octopus_open(struct octopus_context *octopus) +{ + if (octopus_open_id(octopus,VID,PID) < 0) + octopus_error_return(-1,"could not found octopus device with pid and vid"); + + return 1; +} + +/* + * open octopus with a given usb vendor and product id + */ +int octopus_open_id(struct octopus_context *octopus, int vendor, int product) +{ + struct usb_bus *busses; + struct usb_bus *bus; + struct usb_device *dev; + + usb_init(); + + if (usb_find_busses() < 0) + octopus_error_return(-1, "usb_find_busses() failed"); + + if (usb_find_devices() < 0) + octopus_error_return(-2, "usb_find_devices() failed"); + + busses = usb_get_busses(); + + if (busses == NULL) + octopus_error_return(-3, "usb_get_busses() failed"); + + for (bus = busses; bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) + { + octopus_open_dev(octopus,dev); + return 1; + } + } + } + octopus_error_return(-4,"could not found octopus device with pid and vid"); + return -1; +} + +/* + * open octopus with a given usb name description (not tested!) + */ +int octopus_open_serial(struct octopus_context *octopus, char * serial) +{ + struct usb_bus *busses; + struct usb_dev_handle* usb_handle; + struct usb_bus *bus; + struct usb_device *dev; + char usbserial[64]; + int length=0; + + usb_init(); + + if (usb_find_busses() < 0) + octopus_error_return(-1, "usb_find_busses() failed"); + if (usb_find_devices() < 0) + octopus_error_return(-2, "usb_find_devices() failed"); + + busses = usb_get_busses(); + if(busses==NULL) + octopus_error_return(-3, "usb_get_busses() failed"); + + for (bus = busses; bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + usb_handle = usb_open(dev); + usb_set_configuration(usb_handle,0); + length = usb_get_string_simple(usb_handle,3,usbserial,64); + usb_close(usb_handle); + + if (strncmp(serial,usbserial,length) == 0) + { + octopus_open_dev(octopus,dev); + return 1; + } + } + } + + octopus_error_return(-4,"could not found octopus device with serial number"); + return -1; +} + +/* + * open octopus with a libusb dev handle + */ +int octopus_open_dev(struct octopus_context *octopus, struct usb_device *dev) +{ + if (octopus == NULL) + octopus_error_return(-1,"octopus handle is wrong or missing"); + + if (dev == NULL) + octopus_error_return(-2,"device handle is wrong or missing"); + + if (!(octopus->usb_handle = usb_open(dev))) + octopus_error_return(-3,"can't open usb device"); + + if (usb_set_configuration (octopus->usb_handle,dev->config[0].bConfigurationValue) < 0) + octopus_error_return(-4,"can't set configuration for given usb device"); + + if (usb_claim_interface(octopus->usb_handle, 0) < 0) + octopus_error_return(-5,"can't claim interface for given usb device"); + + if (usb_set_altinterface(octopus->usb_handle,0) < 0) + octopus_error_return(-6,"can't set altinterface for given usb device"); + + return 1; +} + +/* + * close a open octopus handle + */ +int octopus_close(struct octopus_context *octopus) +{ + if (octopus == NULL) + octopus_error_return(-1,"octopus is not a valid handle"); + + if (usb_close(octopus->usb_handle) < 0) + octopus_error_return(-2,usb_strerror()); + + return 1; +} + +/* + * send message to octopus + */ +int octopus_message(struct octopus_context *octopus, char *msg, + int msglen, char *answer, int answerlen) +{ + int timeout=0; + + if (usb_bulk_write(octopus->usb_handle,1,msg,msglen,100) < msglen) + octopus_error_return(-1,"transfer error occurred"); + + if (answerlen>0){ + while(1) + { + if(usb_bulk_read(octopus->usb_handle,0x81,(char*)answer,answerlen,100)>0) + break; + + if(timeout++ >= 1000) + octopus_error_return(-2,"receive error occurred"); + } + + if(answer[1]==RSP_OK) + { + return 1; + } + else if (answer[1]==RSP_UNKOWN_CMD) + { + octopus_error_return(-1,"unkown command"); + } + else if (answer[1]==RSP_UNKOWN_PIN) + { + octopus_error_return(-2,"unkown pin"); + } + else if (answer[1]==RSP_WRONG_PIN_CONFIG) + { + octopus_error_return(-3,"pin is in wrong configuration"); + } + else if (answer[1]==RSP_ERROR) + { + octopus_error_return(-4,"error in usb device"); + } + else if (answer[1]==RSP_TIMEOUT) + { + octopus_error_return(-4,"timeout error in usb device"); + } + else + { + octopus_error_return(-5,"unknown error"); + } + } + return 1; +} + +/* + * get internal device description of octopus (octopus_1, octocan_01) + */ +char * octopus_get_hwdesc(struct octopus_context *octopus, char *desc) +{ + + char msg[] = {CMD_GET_HW_ID,0x00,0x00}; + int i; + char answer[64]; + + for (i=0;i<64;i++) + answer[i]=0; + + if (octopus_message(octopus,msg,3,answer,14) == RSP_OK) + { + if ((int)answer[2] > 0) + memcpy(desc,answer+3,(int)answer[2]); + return desc; + } + else + { + octopus_error_return(NULL,octopus->error_str); + } + return desc; +} + +/* + * use pin as gpio + */ +int octopus_io_init(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_IO_INIT_PIN,0x01,0x00}; + msg[2] = (char)pin; + if (octopus_message(octopus,msg,3,answer,3) > 0) + return 1; + else return -1; +} + + +int octopus_io_init_port(struct octopus_context *octopus, int port) +{ + char msg[] = {CMD_IO_INIT_PORT,0x01,0x00}; + char answer[3]; + msg[2] = (char)port; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + +int octopus_io_set_port_direction_out(struct octopus_context *octopus, int port,unsigned char mask) +{ + char answer[3]; + char msg[] = {CMD_IO_PORT_DIRECTION_OUT,0x02,0x00,0x00}; + msg[2] = (char)port; + msg[3] = mask; + if(octopus_message(octopus,msg,4,answer,3)) + return 1; + else return -1; +} + +int octopus_io_set_port_direction_in(struct octopus_context *octopus, int port, unsigned char mask) +{ + char answer[3]; + char msg[] = {CMD_IO_PORT_DIRECTION_IN,0x02,0x00,0x00}; + msg[2] = (char)port; + msg[3] = mask; + if(octopus_message(octopus,msg,4,answer,3)) + return 1; + else return -1; +} + + +int octopus_io_set_port_direction_tri(struct octopus_context *octopus, int port, unsigned char mask) +{ + char answer[3]; + char msg[] = {CMD_IO_PORT_DIRECTION_TRI,0x02,0x00,0x00}; + msg[2] = (char)port; + msg[3] = mask; + if(octopus_message(octopus,msg,4,answer,3)) + return 1; + else return -1; +} + +/* + * use pin as output + */ +int octopus_io_set_pin_direction_out(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_IO_PIN_DIRECTION_OUT,0x01,0x00}; + msg[2] = (char)pin; + if (octopus_message(octopus,msg,3,answer,3) == RSP_OK) + return 1; + else + octopus_error_return(-1,octopus->error_str); +} + + +int octopus_io_set_pin_direction_in(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_IO_PIN_DIRECTION_IN,0x01,0x00}; + msg[2] = (char)pin; + if(octopus_message(octopus,msg,3,answer,3)==RSP_OK) + return 1; + else + octopus_error_return(-1,octopus->error_str); +} + + + +int octopus_io_set_pin_direction_tri(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_IO_PIN_DIRECTION_TRI,0x01,0x00}; + msg[2] = (char)pin; + if(octopus_message(octopus,msg,3,answer,3)==RSP_OK) + return 1; + else + octopus_error_return(-1,octopus->error_str); +} + +unsigned char octopus_io_get_port(struct octopus_context *octopus, int port) +{ + char answer[3]; + char msg[] = {CMD_IO_PORT_GET,0x01,0x00}; + msg[2] = (char)port; + if(octopus_message(octopus,msg,3,answer,3)==RSP_OK) + return (unsigned char) answer[2]; + else + return 0; + //octopus_error_return((unsigned char)NULL,octopus->error_str); +} + + +int octopus_io_set_port(struct octopus_context *octopus, int port, unsigned char value) +{ + char answer[3]; + char msg[] = {CMD_IO_PORT_SET,0x01,0x00,0x00}; + msg[2] = (char)port; + msg[3] = (char)value; + if(octopus_message(octopus,msg,4,answer,3)) + return 1; + else return -1; +} + + +int octopus_io_set_pin(struct octopus_context *octopus, int pin, int value) +{ + char answer[3]; + char msg[] = {CMD_IO_PIN_SET,0x01,0x00,0x00}; + msg[2] = (char)pin; + msg[3] = (char)value; + if(octopus_message(octopus,msg,4,answer,3)==RSP_OK) + return 1; + else + octopus_error_return(-1,octopus->error_str); +} + + +int octopus_io_get_pin(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_IO_PIN_GET,0x01,0x00}; + msg[2] = (char)pin; + //msg[3] = 0x00; + if(octopus_message(octopus,msg,3,answer,3)==RSP_OK) + return (int)answer[2]; + else + octopus_error_return(-1,octopus->error_str); +} + + + +/// part: adc +int octopus_adc_init(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_ADC_INIT_PIN,0x01,0x00}; + msg[2] = (char)pin; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + + + +int octopus_adc_get(struct octopus_context *octopus, int pin) +{ + unsigned char answer[4]; + char msg[] = { CMD_ADC_GET, 0x01, 0x00 }; + msg[2] = (char) pin; + + //XXX ???? + if (octopus_message (octopus, msg, 3, (char *)answer, sizeof (answer)) >0) + { + unsigned int low = (unsigned int)answer[3]; + unsigned int high = (unsigned int)answer[2]; + + return((int)((unsigned int)(low | (high << 8)))); + } + else + return -1; +} + +int octopus_adc_ref(struct octopus_context *octopus, int ref) +{ + char answer[3]; + char msg[] = {CMD_ADC_REF,0x01,0x00}; + msg[2] = (char)ref; + if(octopus_message(octopus,msg,3,answer,3)>0) + return (int)answer[1]; + else + octopus_error_return(-1,octopus->error_str); +} + + + +int octopus_adc_get_bulk(struct octopus_context *octopus, + int pin, int number, int * buf) +{ + return 1; +} + +int octopus_i2c_init(struct octopus_context *octopus) +{ + char answer[3]; + char msg[] = {CMD_I2C_INIT,0x01,0x00}; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + +int octopus_i2c_deinit(struct octopus_context *octopus) +{ + char answer[3]; + char msg[] = {CMD_I2C_DEINIT,0x01,0x00}; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + +int octopus_i2c_set_bitrate(struct octopus_context *octopus, int scl_freq) { + char answer[3]; + char msg[] = {CMD_I2C_SET_BITRATE, 0x01, 0x00}; + + //XXX rounding XXX + int bitrate = ((F_CPU/scl_freq)-16) / 2; + msg[2] = bitrate; + + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + + +int octopus_i2c_send_byte(struct octopus_context *octopus, char data) +{ + char answer[3]; + + // cmd = cmd,len,timeout,address,data1,data2,..) + char msg[] = {CMD_I2C_SEND_BYTE,0x01,0x00}; + msg[2] = (char)data; + + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else + octopus_error_return(-1,octopus->error_str); +} + + +int octopus_i2c_send_bytes(struct octopus_context *octopus, char *buf, int len) +{ + while(len > 0) { + if(octopus_i2c_send_byte(octopus,buf[len--]) <= 0) + return 0; + } + + return 1; +} + + +unsigned char octopus_i2c_receive_byte(struct octopus_context *octopus, + int address,int timeout) +{ + char tmp[1]; + + if(octopus_i2c_receive_bytes(octopus,address,tmp,1,1)>0) + return tmp[1]; + else + return -1; +} + + +int octopus_i2c_receive_bytes(struct octopus_context *octopus, + int address,char *buf, int len, int timeout) +{ + if(len>60){ + return -1; // max 60 bytes + } + + char msg[64] = {CMD_I2C_RECV_BYTES,0x01,0x00}; + msg[1] = (char)(len+4); + msg[2] = (char)timeout; + msg[3] = (char)address; + + char answer[64]; + int i; + + if(octopus_message(octopus,msg,4,answer,len+3)>0){ + for(i=0;ierror_str); + + return 1; +} + +int octopus_i2c_send_start(struct octopus_context *octopus) +{ + char answer[3]; + char msg[] = {CMD_I2C_SEND_START,0x01,0x00}; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; + + return 1; +} + +int octopus_i2c_send_stop(struct octopus_context *octopus) +{ + char answer[3]; + char msg[] = {CMD_I2C_SEND_STOP,0x00,0x00}; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; + + return 1; +} + +/// part: SPI +int octopus_spi_init(struct octopus_context *octopus) +{ + char answer[2]; + char msg[] = {CMD_SPI_INIT,0x00,0x00}; + if(octopus_message(octopus,msg,3,answer,2)>0) + return 1; + else return -1; + +} + +int octopus_spi_deinit(struct octopus_context *octopus) +{ + char answer[2]; + char msg[] = {CMD_SPI_DEINIT,0x00,0x00}; + if(octopus_message(octopus,msg,3,answer,2)>0) + return 1; + else return -1; + +} + +int octopus_spi_speed(struct octopus_context *octopus, int speed) +{ + return 0; +} + + +int octopus_spi_send(struct octopus_context *octopus, unsigned char * buf, int length) +{ + if(length>60){ + return -1; // max 60 bytes + } + + char answer[2]; + + // cmd = cmd,len,timeout,address,data1,data2,..) + char msg[64] = {CMD_SPI_SEND,0x01,0x00}; + msg[1] = (char)(length); + + // build send array + int i; + for(i=0;i0) + return 1; + else + octopus_error_return(-1,octopus->error_str); + + return 1; +} + +int octopus_spi_recv(struct octopus_context *octopus, unsigned char * buf, int length) +{ + if(length>60){ + return -1; // max 60 bytes + } + + char answer[64]; + + char msg[64] = {CMD_SPI_RECV,0x01,0x00}; + msg[1] = (char)(length); + + int i; + + if(octopus_message(octopus,msg,2,answer,2+length)>0) { + for(i=0;ierror_str); +} + +int octopus_spi_send_and_recv(struct octopus_context *octopus, unsigned char * buf, int length) +{ + if(length>60){ + return -1; // max 60 bytes + } + + char answer[2]; + + // cmd = cmd,len,timeout,address,data1,data2,..) + char msg[64] = {CMD_SPI_SEND_AND_RECV,0x01,0x00}; + msg[1] = (char)(length); + + // build send array + int i; + for(i=0;i0) { + + for(i=0;ierror_str); + + return 1; + +} + +/// part: Flash 93c46 +int octopus_93c46_init(struct octopus_context *octopus) +{ + char answer[3]; + char msg[] = {CMD_EXTERNAL_DEVICE,0x00,CMD_EXTERNAL_93C46,CMD_93C46_INIT}; + msg[1] = 4; + if(octopus_message(octopus,msg,4,answer,3)>0) + return 1; + else return -1; +} + +int octopus_93c46_deinit(struct octopus_context *octopus) +{ + char answer[3]; + char msg[] = {CMD_EXTERNAL_DEVICE,CMD_EXTERNAL_93C46,CMD_93C46_DEINIT}; + if (octopus_message(octopus,msg,3,answer,3) > 0) + return 1; + else return -1; +} + +int octopus_93c46_write(struct octopus_context *octopus, unsigned char address, int length, unsigned char * buf) +{ + /* + if(length>59){ + return -1; // max 60 bytes + } + */ + + char answer[3]; + + // cmd = cmd,len,timeout,address,data1,data2,..) + char msg[150] = {CMD_EXTERNAL_DEVICE,0x00,CMD_EXTERNAL_93C46,CMD_93C46_WRITE}; + msg[1] = (unsigned char)(6 + length); + msg[4] = (unsigned char)(address); + msg[5] = (unsigned char)(length); + + // build send array + int i; + for(i=0;i0) + return 1; + else + octopus_error_return(-1,octopus->error_str); + + return 1; +} + +int octopus_93c46_read(struct octopus_context *octopus, unsigned char address, int length, unsigned char * buf) +{ + /* + if(length>59) + { + return -1; // max 60 bytes + }*/ + + char answer[150]; + + char msg[6] = {CMD_EXTERNAL_DEVICE,0x00,CMD_EXTERNAL_93C46,CMD_93C46_READ}; + + msg[1] = 6; + msg[4] = (unsigned char)(address); + msg[5] = (unsigned char)(length); + + int i; + + if (octopus_message(octopus, msg, 6, answer, 2 + length) > 0) + { + for(i=0;ierror_str); +} + + +/// part: PWM +int octopus_pwm_init(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_PWM_INIT_PIN,0x01,0x00}; + msg[2] = (char)pin; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + +int octopus_pwm_deinit(struct octopus_context *octopus, int pin) +{ + char answer[3]; + char msg[] = {CMD_PWM_DEINIT_PIN,0x01,0x00}; + msg[2] = (char)pin; + if(octopus_message(octopus,msg,3,answer,3)>0) + return 1; + else return -1; +} + +int octopus_pwm_speed(struct octopus_context *octopus, int pin, int speed) +{ + char answer[3]; + char msg[] = {CMD_PWM_SPEED,0x02,0x00,0x00}; + msg[2] = (char)pin; + msg[3] = (char)speed; + if(octopus_message(octopus,msg,4,answer,3)>0) + return 1; + else return -1; +} + +int octopus_pwm_value(struct octopus_context *octopus, int pin, unsigned char value) +{ + char answer[3]; + char msg[] = {CMD_PWM_VALUE,0x02,0x00,0x00}; + msg[2] = (char)pin; + msg[3] = (char)value; + if(octopus_message(octopus,msg,4,answer,3)>0) + return 1; + else return -1; +} + +; diff --git a/liboctopus/octopus.h b/liboctopus/octopus.h new file mode 100644 index 0000000..b123335 --- /dev/null +++ b/liboctopus/octopus.h @@ -0,0 +1,141 @@ +/*************************************************************************** + octopus.h - description + ------------------- + begin : Fri Apr 1 2007 + copyright : (C) 2007 by Embedded Projects + email : sauter@embedded-projects.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License * + * version 2.1 as published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef __liboctopus_h__ +#define __liboctopus_h__ + +#include + + +#define VID 0x1781 +#define PID 0x0c65 + +/** + \brief Main context structure for all liboctopus functions. + + Do not access directly if possible. +*/ +struct octopus_context { + // USB specific + /// libusb's usb_dev_handle + struct usb_dev_handle *usb_handle; + + /// String representation of last error + char *error_str; +}; + +/** + \brief list of usb devices created by octopus_usb_find_all() +*/ +struct octopus_device_list { + /// pointer to next entry + struct octopus_device_list *next; + /// pointer to libusb's usb_device + struct usb_device *dev; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + int octopus_init(struct octopus_context *octopus); + + int octopus_open(struct octopus_context *octopus); + int octopus_open_id(struct octopus_context *octopus, int vendor, int product); + int octopus_open_serial(struct octopus_context *octopus, char * serial); + + int octopus_open_dev(struct octopus_context *octopus, struct usb_device *dev); + + int octopus_close(struct octopus_context *octopus); + + int octopus_message(struct octopus_context *octopus, char *msg, + int msglen, char *answer, int answerlen); + + char * octopus_get_hwdesc(struct octopus_context *octopus, char *desc); + + /// part: IO + + int octopus_io_init(struct octopus_context *octopus, int pin); + int octopus_io_init_port(struct octopus_context *octopus, int port); + + int octopus_io_set_port_direction_out(struct octopus_context *octopus, + int port,unsigned char mask); + int octopus_io_set_port_direction_in(struct octopus_context *octopus, + int port, unsigned char mask); + int octopus_io_set_port_direction_tri(struct octopus_context *octopus, + int port, unsigned char mask); + + int octopus_io_set_pin_direction_out(struct octopus_context *octopus, int pin); + int octopus_io_set_pin_direction_in(struct octopus_context *octopus, int pin); + //int octopus_io_set_pin_direction_in_pullup(struct octopus_context *octopus, int pin); + int octopus_io_set_pin_direction_tri(struct octopus_context *octopus, int pin); + + unsigned char octopus_io_get_port(struct octopus_context *octopus, int port); + + int octopus_io_set_port(struct octopus_context *octopus, int port, unsigned char value); + + int octopus_io_set_pin(struct octopus_context *octopus, int pin, int value); //buffered + + int octopus_io_get_pin(struct octopus_context *octopus, int pin); + + /// part: adc + + int octopus_adc_init(struct octopus_context *octopus, int pin); + int octopus_adc_get(struct octopus_context *octopus, int pin); + int octopus_adc_ref(struct octopus_context *octopus, int ref); + // 1= extern AREF, 2 = AVCC as reference, 3=intern voltage + + + /// part: I2C + int octopus_i2c_init(struct octopus_context *octopus); + int octopus_i2c_deinit(struct octopus_context *octopus); + + int octopus_i2c_set_bitrate(struct octopus_context *octopus, int bitrate); + int octopus_i2c_send_byte(struct octopus_context *octopus, char data); + int octopus_i2c_send_bytes(struct octopus_context *octopus, char *buf, int len); + unsigned char octopus_i2c_receive_byte(struct octopus_context *octopus, int address,int timeout); + int octopus_i2c_receive_bytes(struct octopus_context *octopus, int address,char *buf, int len, int timeout); + + int octopus_i2c_send_start(struct octopus_context *octopus); + int octopus_i2c_send_stop(struct octopus_context *octopus); + + /// part: SPI + int octopus_spi_init(struct octopus_context *octopus); + int octopus_spi_deinit(struct octopus_context *octopus); + + int octopus_spi_speed(struct octopus_context *octopus, int speed); + int octopus_spi_send(struct octopus_context *octopus, unsigned char * buf, int length); + int octopus_spi_recv(struct octopus_context *octopus, unsigned char * buf, int length); + int octopus_spi_send_and_recv(struct octopus_context *octopus, unsigned char * buf, int length); + + /// part: Flash 93c46 + int octopus_93c46_init(struct octopus_context *octopus); + int octopus_93c46_deinit(struct octopus_context *octopus); + + int octopus_93c46_read(struct octopus_context *octopus, unsigned char address, int length, unsigned char * buf); + int octopus_93c46_write(struct octopus_context *octopus, unsigned char address, int length, unsigned char * buf); + + /// part: PWM + int octopus_pwm_init(struct octopus_context *octopus, int pin); + int octopus_pwm_deinit(struct octopus_context *octopus, int pin); + int octopus_pwm_speed(struct octopus_context *octopus, int pin, int speed); + int octopus_pwm_value(struct octopus_context *octopus, int pin, unsigned char value); + +#ifdef __cplusplus +} +#endif + +#endif /* __liboctopus_h__ */ diff --git a/liboctopus/python/.gitignore b/liboctopus/python/.gitignore new file mode 100644 index 0000000..5b2c896 --- /dev/null +++ b/liboctopus/python/.gitignore @@ -0,0 +1,2 @@ +octopus.py +octopus_wrap.c diff --git a/liboctopus/python/Makefile b/liboctopus/python/Makefile new file mode 100644 index 0000000..e0e6f29 --- /dev/null +++ b/liboctopus/python/Makefile @@ -0,0 +1,19 @@ +CC=gcc +CFLAGS= -fPIC +CFLAGS+=-I.. +CFLAGS+=`python-config --cflags` +LDFLAGS=`pkg-config --libs libusb` + +all: octopus.o octopus_wrap.o + gcc -fPIC -shared octopus_wrap.o octopus.o $(LDFLAGS) -o _octopus.so + +octopus_wrap.o: + swig -python octopus.i + $(CC) -c -o octopus_wrap.o octopus_wrap.c $(CFLAGS) + +octopus.o: + $(CC) -c -o octopus.o ../octopus.c $(CFLAGS) + +.PHONY: clean +clean: + rm -vf octopus.o octopus.py _octopus.so octopus_wrap.o octopus.pyc octopus_wrap.c diff --git a/liboctopus/python/demos/adc.py b/liboctopus/python/demos/adc.py new file mode 100644 index 0000000..5e55ab7 --- /dev/null +++ b/liboctopus/python/demos/adc.py @@ -0,0 +1,19 @@ + + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_adc_init(op, 33) +octopus_adc_ref(op, 2) + +while 1: + value = octopus_adc_get(op, 33) + callin = "Value %i" % value + print callin + time.sleep(1) + + diff --git a/liboctopus/python/demos/blink.py b/liboctopus/python/demos/blink.py new file mode 100644 index 0000000..3e454af --- /dev/null +++ b/liboctopus/python/demos/blink.py @@ -0,0 +1,22 @@ +#blink.py +#laesst die led1 (26) blinken + + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_io_init(op,26) + +octopus_io_set_pin_direction_out(op,26) + +while 1: + octopus_io_set_pin(op,26,1) + time.sleep(1) + octopus_io_set_pin(op,26,0) + time.sleep(1) + + diff --git a/liboctopus/python/demos/blink_all.py b/liboctopus/python/demos/blink_all.py new file mode 100644 index 0000000..32c963b --- /dev/null +++ b/liboctopus/python/demos/blink_all.py @@ -0,0 +1,58 @@ +#blink_all.py +#laesst die led1 - led6 auf einmal blinken + +import sys + +sys.path.append("../../libs/python") + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_io_init(op,26) +octopus_io_init(op,27) +octopus_io_init(op,28) +octopus_io_init(op,29) +octopus_io_init(op,30) +octopus_io_init(op,31) +octopus_io_init(op,32) + +octopus_io_set_pin_direction_out(op,26) +octopus_io_set_pin_direction_out(op,27) +octopus_io_set_pin_direction_out(op,28) +octopus_io_set_pin_direction_out(op,29) +octopus_io_set_pin_direction_out(op,30) +octopus_io_set_pin_direction_out(op,31) +octopus_io_set_pin_direction_out(op,32) + +octopus_io_set_pin(op,26,0) +octopus_io_set_pin(op,27,0) +octopus_io_set_pin(op,28,0) +octopus_io_set_pin(op,29,0) +octopus_io_set_pin(op,30,0) +octopus_io_set_pin(op,31,0) +octopus_io_set_pin(op,32,0) + + + + +while 1: + octopus_io_set_pin(op,26,1) + octopus_io_set_pin(op,27,1) + octopus_io_set_pin(op,28,1) + octopus_io_set_pin(op,29,1) + octopus_io_set_pin(op,30,1) + octopus_io_set_pin(op,31,1) + octopus_io_set_pin(op,32,1) + time.sleep(1) + octopus_io_set_pin(op,26,0) + octopus_io_set_pin(op,27,0) + octopus_io_set_pin(op,28,0) + octopus_io_set_pin(op,29,0) + octopus_io_set_pin(op,30,0) + octopus_io_set_pin(op,31,0) + octopus_io_set_pin(op,32,0) + time.sleep(1) diff --git a/liboctopus/python/demos/blink_i2c.py b/liboctopus/python/demos/blink_i2c.py new file mode 100644 index 0000000..5fd4cb9 --- /dev/null +++ b/liboctopus/python/demos/blink_i2c.py @@ -0,0 +1,29 @@ +# blink_i2c.py +# laesst die led des i2c (0x10) blinken + +import sys +sys.path.append("..\\..\\libs\\python") + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_i2c_init(op) +octopus_i2c_set_bitrate(op,3) # 100khz + + +octopus_i2c_send_start(op) + +while 1: + #octopus_i2c_receive_byte(op,0x10,1) + octopus_i2c_send_byte(op,0x20,1) + octopus_i2c_send_byte(op,1,1) + time.sleep(1) + octopus_i2c_send_byte(op,0x20,1) + octopus_i2c_send_byte(op,0,1) + time.sleep(1) + + diff --git a/liboctopus/python/demos/blink_lauf.py b/liboctopus/python/demos/blink_lauf.py new file mode 100644 index 0000000..00f73e7 --- /dev/null +++ b/liboctopus/python/demos/blink_lauf.py @@ -0,0 +1,67 @@ +#blink_lauf.py +#laesst alle leds nacheinander blinken + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_io_init(op,26) +octopus_io_init(op,27) +octopus_io_init(op,28) +octopus_io_init(op,29) +octopus_io_init(op,30) +octopus_io_init(op,31) +octopus_io_init(op,32) + +octopus_io_set_pin_direction_out(op,26) +octopus_io_set_pin_direction_out(op,27) +octopus_io_set_pin_direction_out(op,28) +octopus_io_set_pin_direction_out(op,29) +octopus_io_set_pin_direction_out(op,30) +octopus_io_set_pin_direction_out(op,31) +octopus_io_set_pin_direction_out(op,32) + +octopus_io_set_pin(op,26,0) +octopus_io_set_pin(op,27,0) +octopus_io_set_pin(op,28,0) +octopus_io_set_pin(op,29,0) +octopus_io_set_pin(op,30,0) +octopus_io_set_pin(op,31,0) +octopus_io_set_pin(op,32,0) + + + + +while 1: + octopus_io_set_pin(op,26,1) + time.sleep(1) + octopus_io_set_pin(op,26,0) + time.sleep(0.5) + octopus_io_set_pin(op,27,1) + time.sleep(1) + octopus_io_set_pin(op,27,0) + time.sleep(0.5) + octopus_io_set_pin(op,28,1) + time.sleep(1) + octopus_io_set_pin(op,28,0) + time.sleep(0.5) + octopus_io_set_pin(op,29,1) + time.sleep(1) + octopus_io_set_pin(op,29,0) + time.sleep(0.5) + octopus_io_set_pin(op,30,1) + time.sleep(1) + octopus_io_set_pin(op,30,0) + time.sleep(0.5) + octopus_io_set_pin(op,31,1) + time.sleep(1) + octopus_io_set_pin(op,31,0) + time.sleep(0.5) + octopus_io_set_pin(op,32,1) + time.sleep(1) + octopus_io_set_pin(op,32,0) + time.sleep(0.5) + diff --git a/liboctopus/python/demos/blink_status.py b/liboctopus/python/demos/blink_status.py new file mode 100644 index 0000000..c4b0945 --- /dev/null +++ b/liboctopus/python/demos/blink_status.py @@ -0,0 +1,26 @@ +# blink_status.py +# laesst die status led (11) blinken + +import sys +sys.path.append("..\\..\\libs\\python") + + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_io_init(op,11) + +octopus_io_set_pin_direction_out(op,11) + +octopus_io_set_pin(op,11,0) + + +while 1: + octopus_io_set_pin(op,11,1) + time.sleep(1) + octopus_io_set_pin(op,11,0) + time.sleep(1) diff --git a/liboctopus/python/demos/eeprom_i2c.py b/liboctopus/python/demos/eeprom_i2c.py new file mode 100644 index 0000000..17707a4 --- /dev/null +++ b/liboctopus/python/demos/eeprom_i2c.py @@ -0,0 +1,36 @@ +# blink_i2c.py +# laesst die led des i2c (0x10) blinken + +from octopus import * +import time + + +op=octopus_context() +octopus_init(op) +octopus_open(op) +octopus_i2c_init(op) +octopus_i2c_set_bitrate(op,3) # 100khz + + +octopus_i2c_send_start(op) +octopus_i2c_send_byte(op,0xae,1) +octopus_i2c_send_byte(op,1,1) +octopus_i2c_send_byte(op,0,1) +octopus_i2c_send_byte(op,0x77,1) +octopus_i2c_send_stop(op) + + + +octopus_i2c_send_start(op) +octopus_i2c_send_byte(op,0xae,1) +octopus_i2c_send_byte(op,1,1) +octopus_i2c_send_byte(op,0,1) +octopus_i2c_send_start(op) + +octopus_i2c_send_byte(op,0xaf,1) + +print octopus_i2c_receive_byte(op,1,1) + +octopus_i2c_send_stop(op) + + diff --git a/liboctopus/python/octopus.i b/liboctopus/python/octopus.i new file mode 100644 index 0000000..4999a19 --- /dev/null +++ b/liboctopus/python/octopus.i @@ -0,0 +1,5 @@ +%module octopus +%{ +#include "../octopus.h" +%} +%include "../octopus.h" -- cgit v1.2.1