From afc8f9ff30b9c026bd8b5b678748e6b23913d867 Mon Sep 17 00:00:00 2001 From: Andreas Auras Date: Wed, 10 Feb 2010 12:55:37 +0100 Subject: More modifications for public use of project --- .cproject | 772 +++++ .project | 2 +- Makefile | 43 + README | 1 + df10ch_common.h | 108 +- df10ch_usb_proto.h | 232 +- "kicad/10ch_pwm_ctrl-L\303\266tseite.ps" | 4881 ------------------------------ kicad/10ch_pwm_ctrl-solder-side.ps | 4881 ++++++++++++++++++++++++++++++ pwm_appl/10ch_pwm_appl.c | 1000 ------ pwm_appl/Makefile | 212 +- pwm_appl/df10ch_pwm_appl.c | 1000 ++++++ pwm_boot/10ch_pwm_boot.c | 475 --- pwm_boot/Makefile | 204 +- pwm_boot/df10ch_pwm_boot.c | 475 +++ usb_appl/10ch_usb_appl.c | 838 ----- usb_appl/Makefile | 218 +- usb_appl/df10ch_usb_appl.c | 838 +++++ usb_appl/usbconfig.h | 58 +- usb_boot/10ch_usb_boot.c | 323 -- usb_boot/Makefile | 212 +- usb_boot/df10ch_usb_boot.c | 323 ++ usb_boot/usbconfig.h | 60 +- 22 files changed, 8986 insertions(+), 8170 deletions(-) create mode 100644 Makefile delete mode 100644 "kicad/10ch_pwm_ctrl-L\303\266tseite.ps" create mode 100644 kicad/10ch_pwm_ctrl-solder-side.ps delete mode 100644 pwm_appl/10ch_pwm_appl.c create mode 100644 pwm_appl/df10ch_pwm_appl.c delete mode 100644 pwm_boot/10ch_pwm_boot.c create mode 100644 pwm_boot/df10ch_pwm_boot.c delete mode 100644 usb_appl/10ch_usb_appl.c create mode 100644 usb_appl/df10ch_usb_appl.c delete mode 100644 usb_boot/10ch_usb_boot.c create mode 100644 usb_boot/df10ch_usb_boot.c diff --git a/.cproject b/.cproject index 927156a..846b2b0 100644 --- a/.cproject +++ b/.cproject @@ -3091,6 +3091,778 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project index ac8d1ad..2ae3639 100644 --- a/.project +++ b/.project @@ -36,7 +36,7 @@ org.eclipse.cdt.make.core.buildLocation - ${workspace_loc:/df10ch/pwm_appl} + ${workspace_loc:/df10ch} org.eclipse.cdt.make.core.cleanBuildTarget diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..77cc950 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2010 Andreas Auras +# +# This file is part of the DF10CH Atmolight controller project. +# +# DF10CH Atmolight controller 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. +# +# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +# +# ################################ +# Build all distribution tar files +# ################################ + +all: clean + mkdir -p dist + mkdir -p build/firmware + python setup.py sdist + (cd usb_boot && make) + (cd usb_appl && make) + (cd pwm_boot && make) + (cd pwm_appl && make) + cp usb_appl/df10ch_usb_appl.dff build/firmware/df10ch_usb_appl.dff + cp pwm_appl/df10ch_pwm_appl.dff build/firmware/df10ch_pwm_appl.dff + (cd build && tar cvzf ../dist/df10ch_firmware.tar.gz firmware) + +## Clean target +.PHONY: clean +clean: + (cd usb_boot && make clean) + (cd usb_appl && make clean) + (cd pwm_boot && make clean) + (cd pwm_appl && make clean) + rm -rf build MANIFEST diff --git a/README b/README index 963cb90..63a5f5f 100644 --- a/README +++ b/README @@ -19,6 +19,7 @@ http://www.obdev.at/vusb/ This directory contains the firmware, DF10CH setup program and KiCad files of hardware design: README The file you are currently reading +Makfile Makefile for generating everything df10ch_setup_pkg/ Python modules needed by the DF10CH setup program pwm_appl/ Application firmware for PWM-Prozessor pwm_boot/ Bootloader firmware for PWM-Prozessor diff --git a/df10ch_common.h b/df10ch_common.h index a723cd3..dfd04c3 100644 --- a/df10ch_common.h +++ b/df10ch_common.h @@ -1,54 +1,54 @@ -/* - * Copyright (C) 2010 Andreas Auras - * - * This file is part of the DF10CH Atmolight controller project. - * - * DF10CH Atmolight controller 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. - * - * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - */ - -// --- -// Useful utility defines. -// -#define NOMEMINIT __attribute__((section(".noinit"))) -#define NORETURN __attribute__((noreturn)) -#define NOINLINE __attribute__((noinline)) -#define INLINE __attribute__((inline)) -#define nop() __asm__ __volatile__ ("nop" ::) -#define FIX_POINTER(_ptr) __asm__ __volatile__("" : "=b" (_ptr) : "0" (_ptr)) -#define SIGNATURE_DATA uint8_t __signature[3] __attribute__((section(".signature"))) - -#define set_bit(var, bit) var |= _BV(bit) -#define clear_bit(var, bit) var &= ~_BV(bit) - -typedef union -{ - uint16_t word; - uint8_t bytes[2]; -} bytes_word_t; - - -// Definitions for usb <--> pwm controller communication -#define BAUD 125000UL - -#define REQ_HEADER_SIZE 8 - -#define PWMRQ_DEVICE_TO_HOST 0x80 -#define PWMRQ_ID_MASK 0x3F -#define PWMRP_KEEP_ALIVE 0x80 -#define PWMRP_HAS_PAYLOAD 0x40 - - - +/* + * Copyright (C) 2010 Andreas Auras + * + * This file is part of the DF10CH Atmolight controller project. + * + * DF10CH Atmolight controller 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. + * + * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +// --- +// Useful utility defines. +// +#define NOMEMINIT __attribute__((section(".noinit"))) +#define NORETURN __attribute__((noreturn)) +#define NOINLINE __attribute__((noinline)) +#define INLINE __attribute__((inline)) +#define nop() __asm__ __volatile__ ("nop" ::) +#define FIX_POINTER(_ptr) __asm__ __volatile__("" : "=b" (_ptr) : "0" (_ptr)) +#define SIGNATURE_DATA uint8_t __signature[3] __attribute__((section(".signature"))) + +#define set_bit(var, bit) var |= _BV(bit) +#define clear_bit(var, bit) var &= ~_BV(bit) + +typedef union +{ + uint16_t word; + uint8_t bytes[2]; +} bytes_word_t; + + +// Definitions for usb <--> pwm controller communication +#define BAUD 125000UL + +#define REQ_HEADER_SIZE 8 + +#define PWMRQ_DEVICE_TO_HOST 0x80 +#define PWMRQ_ID_MASK 0x3F +#define PWMRP_KEEP_ALIVE 0x80 +#define PWMRP_HAS_PAYLOAD 0x40 + + + diff --git a/df10ch_usb_proto.h b/df10ch_usb_proto.h index cb10912..bbda480 100644 --- a/df10ch_usb_proto.h +++ b/df10ch_usb_proto.h @@ -1,116 +1,116 @@ -/* - * Copyright (C) 2010 Andreas Auras - * - * This file is part of the DF10CH Atmolight controller project. - * - * DF10CH Atmolight controller 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. - * - * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - */ - -/* --- - * Communication protocol related defines for DF10CH Atmolight Controller. - */ - -#define REQ_USB_START 0 // Start of usb controller requests -#define REQ_USB_BL_START 64 // Start of usb controller boot loader requests -#define REQ_PWM_START 128 // Start of pwm controller requests -#define REQ_PWM_BL_START 192 // Start of pwm controller boot loader requests - -enum -{ - // usb controller requests - REQ_START_BOOTLOADER = REQ_USB_START, // start boot loader of usb controller - REQ_READ_EE_DATA, // read eeprom data (wLength: number of bytes, wIndex: eeprom start address) - REQ_WRITE_EE_DATA, // write eeprom data (wLength: number of bytes, wIndex: eeprom start address) - - REQ_STOP_PWM_CTRL, // stop PWM controller - REQ_RESET_PWM_CTRL, // reset PWM controller - REQ_BOOTLOADER_RESET_PWM_CTRL, // reset PWM controller and signal bootloader start - - REQ_SET_REPLY_TIMEOUT, // set reply timeout values (wValue: start timeout [ms], wIndex: timeout [ms]) - - REQ_GET_REPLY_ERR_STATUS, // get reply error status (COMM_ERR_...) - - // usb controller boot loader requests - BL_REQ_WRITE_PAGE = REQ_USB_BL_START, // write flash page - BL_REQ_LEAVE_BOOT, // leave boot loader and start application - BL_REQ_GET_PAGE_SIZE, // return flash page size of device - BL_REQ_READ_FLASH, // return flash contents - - // pwm controller requests - PWM_REQ_GET_VERSION = REQ_PWM_START, // Get firmware version (returns 1 byte) - PWM_REQ_SET_BRIGHTNESS, // Set channel brightness values (wLenght: number of bytes, wIndex: start channel) - PWM_REQ_SET_BRIGHTNESS_SYNCED, // Same as above but wait until buffer flip - PWM_REQ_GET_BRIGHTNESS, - - PWM_REQ_SET_CHANNEL_MAP, // Set channel to port mapping (wLength: number of bytes, wIndex: start channel) - PWM_REQ_GET_CHANNEL_MAP, - - PWM_REQ_SET_COMMON_PWM, // Set common pwm value (wValue.low: pwm value) - PWM_REQ_GET_COMMON_PWM, - - PWM_REQ_STORE_SETUP, // Store actual calibration values - PWM_REQ_RESET_SETUP, // Reset calibration values to default - - PWM_REQ_GET_REQUEST_ERR_STATUS, // Get request error status (COMM_ERR_...) - - PWM_REQ_GET_MAX_PWM, // Get maximum internal PWM value - - PWM_REQ_SET_PWM_FREQ, // Set pwm frequency (wValue: frequency [hz]) - PWM_REQ_GET_PWM_FREQ, // Get pwm frequency (returns word) - - PWM_REQ_ECHO_TEST, // Reply 8 byte header - - // pwm controller boot loader requests - BL_PWM_REQ_WRITE_PAGE = REQ_PWM_BL_START, // write flash page - BL_PWM_REQ_GET_PAGE_SIZE, // return flash page size of device - BL_PWM_REQ_READ_FLASH, // return flash contents - BL_PWM_REQ_GET_REQUEST_ERR_STATUS // Get request error status (COMM_ERR_...) -}; - -// Data payload related -#define MAX_REQ_PAYLOAD_SIZE 128 -#define MAX_REPLY_PAYLOAD_SIZE 128 - -// Error flag definition for communication error's of usb and pwm controller -#define COMM_ERR_OVERRUN 0 -#define COMM_ERR_FRAME 1 -#define COMM_ERR_TIMEOUT 2 -#define COMM_ERR_START 3 -#define COMM_ERR_OVERFLOW 4 -#define COMM_ERR_CRC 5 -#define COMM_ERR_DUPLICATE 6 -#define COMM_ERR_DEBUG 7 - -// Port channel mapping related -#define NCHANNELS 30 // Number of supported Channels - -#define NPORTS 4 -#define PA_IDX 0 -#define PB_IDX 1 -#define PC_IDX 2 -#define PD_IDX 3 - -#define CM_CODE(port, channel) (((channel) << 2) | (port)) -#define CM_CHANNEL(code) ((code) >> 2) -#define CM_PORT(code) ((code) & 0x03) - -// PWM frequency related -#define MIN_PWM_FREQ 50 -#define MAX_PWM_FREQ 400 - -// PWM controller version request related -#define PWM_VERS_APPL 0 // Is application firmware -#define PWM_VERS_BOOT 1 // Is bootloader firmware +/* + * Copyright (C) 2010 Andreas Auras + * + * This file is part of the DF10CH Atmolight controller project. + * + * DF10CH Atmolight controller 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. + * + * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +/* --- + * Communication protocol related defines for DF10CH Atmolight Controller. + */ + +#define REQ_USB_START 0 // Start of usb controller requests +#define REQ_USB_BL_START 64 // Start of usb controller boot loader requests +#define REQ_PWM_START 128 // Start of pwm controller requests +#define REQ_PWM_BL_START 192 // Start of pwm controller boot loader requests + +enum +{ + // usb controller requests + REQ_START_BOOTLOADER = REQ_USB_START, // start boot loader of usb controller + REQ_READ_EE_DATA, // read eeprom data (wLength: number of bytes, wIndex: eeprom start address) + REQ_WRITE_EE_DATA, // write eeprom data (wLength: number of bytes, wIndex: eeprom start address) + + REQ_STOP_PWM_CTRL, // stop PWM controller + REQ_RESET_PWM_CTRL, // reset PWM controller + REQ_BOOTLOADER_RESET_PWM_CTRL, // reset PWM controller and signal bootloader start + + REQ_SET_REPLY_TIMEOUT, // set reply timeout values (wValue: start timeout [ms], wIndex: timeout [ms]) + + REQ_GET_REPLY_ERR_STATUS, // get reply error status (COMM_ERR_...) + + // usb controller boot loader requests + BL_REQ_WRITE_PAGE = REQ_USB_BL_START, // write flash page + BL_REQ_LEAVE_BOOT, // leave boot loader and start application + BL_REQ_GET_PAGE_SIZE, // return flash page size of device + BL_REQ_READ_FLASH, // return flash contents + + // pwm controller requests + PWM_REQ_GET_VERSION = REQ_PWM_START, // Get firmware version (returns 1 byte) + PWM_REQ_SET_BRIGHTNESS, // Set channel brightness values (wLenght: number of bytes, wIndex: start channel) + PWM_REQ_SET_BRIGHTNESS_SYNCED, // Same as above but wait until buffer flip + PWM_REQ_GET_BRIGHTNESS, + + PWM_REQ_SET_CHANNEL_MAP, // Set channel to port mapping (wLength: number of bytes, wIndex: start channel) + PWM_REQ_GET_CHANNEL_MAP, + + PWM_REQ_SET_COMMON_PWM, // Set common pwm value (wValue.low: pwm value) + PWM_REQ_GET_COMMON_PWM, + + PWM_REQ_STORE_SETUP, // Store actual calibration values + PWM_REQ_RESET_SETUP, // Reset calibration values to default + + PWM_REQ_GET_REQUEST_ERR_STATUS, // Get request error status (COMM_ERR_...) + + PWM_REQ_GET_MAX_PWM, // Get maximum internal PWM value + + PWM_REQ_SET_PWM_FREQ, // Set pwm frequency (wValue: frequency [hz]) + PWM_REQ_GET_PWM_FREQ, // Get pwm frequency (returns word) + + PWM_REQ_ECHO_TEST, // Reply 8 byte header + + // pwm controller boot loader requests + BL_PWM_REQ_WRITE_PAGE = REQ_PWM_BL_START, // write flash page + BL_PWM_REQ_GET_PAGE_SIZE, // return flash page size of device + BL_PWM_REQ_READ_FLASH, // return flash contents + BL_PWM_REQ_GET_REQUEST_ERR_STATUS // Get request error status (COMM_ERR_...) +}; + +// Data payload related +#define MAX_REQ_PAYLOAD_SIZE 128 +#define MAX_REPLY_PAYLOAD_SIZE 128 + +// Error flag definition for communication error's of usb and pwm controller +#define COMM_ERR_OVERRUN 0 +#define COMM_ERR_FRAME 1 +#define COMM_ERR_TIMEOUT 2 +#define COMM_ERR_START 3 +#define COMM_ERR_OVERFLOW 4 +#define COMM_ERR_CRC 5 +#define COMM_ERR_DUPLICATE 6 +#define COMM_ERR_DEBUG 7 + +// Port channel mapping related +#define NCHANNELS 30 // Number of supported Channels + +#define NPORTS 4 +#define PA_IDX 0 +#define PB_IDX 1 +#define PC_IDX 2 +#define PD_IDX 3 + +#define CM_CODE(port, channel) (((channel) << 2) | (port)) +#define CM_CHANNEL(code) ((code) >> 2) +#define CM_PORT(code) ((code) & 0x03) + +// PWM frequency related +#define MIN_PWM_FREQ 50 +#define MAX_PWM_FREQ 400 + +// PWM controller version request related +#define PWM_VERS_APPL 0 // Is application firmware +#define PWM_VERS_BOOT 1 // Is bootloader firmware diff --git "a/kicad/10ch_pwm_ctrl-L\303\266tseite.ps" "b/kicad/10ch_pwm_ctrl-L\303\266tseite.ps" deleted file mode 100644 index e27450d..0000000 --- "a/kicad/10ch_pwm_ctrl-L\303\266tseite.ps" +++ /dev/null @@ -1,4881 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: PCBNEW-PS -%%CreationDate: Tue Feb 09 13:07:54 2010 -%%Title: D:/data/atmega/aurora/kicad/10ch_pwm_ctrl-Lötseite.ps -%%Pages: 1 -%%PageOrder: Ascend -%%BoundingBox: 0 0 596 843 -%%DocumentMedia: A4 595 842 0 () () -%%Orientation: Landscape -%%EndComments -%%Page: 1 1 -/line { - newpath - moveto - lineto - stroke -} bind def -/cir0 { newpath 0 360 arc stroke } bind def -/cir1 { newpath 0 360 arc gsave fill grestore stroke } bind def -/cir2 { newpath 0 360 arc gsave fill grestore stroke } bind def -/arc0 { newpath arc stroke } bind def -/arc1 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def -/arc2 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def -/poly0 { stroke } bind def -/poly1 { closepath gsave fill grestore stroke } bind def -/poly2 { closepath gsave fill grestore stroke } bind def -/rect0 { rectstroke } bind def -/rect1 { rectfill } bind def -/rect2 { rectfill } bind def -gsave -72 72 scale % Talk inches -1 setlinecap -1 setlinejoin -1 setlinewidth -8.267000 0.000000 translate 90 rotate -0.000100 0.000100 scale % Move to User coordinates -50 setlinewidth -120 setlinewidth -0.000 0.000 0.000 setrgbcolor -19089 33512 19729 33512 line -19729 33459 19729 33779 line -19729 33779 19657 33832 line -19657 33832 19160 33832 line -19160 33832 19089 33779 line -19089 33779 19089 33459 line -19089 34112 19729 34112 line -19729 34112 19729 34485 line -19444 34112 19444 34325 line -19089 34872 19089 35085 line -19089 34978 19729 34978 line -19657 34978 19515 34872 line -19089 35418 19729 35791 line -19160 35418 19657 35418 line -19657 35418 19729 35471 line -19729 35471 19729 35738 line -19729 35738 19657 35791 line -19657 35791 19160 35791 line -19160 35791 19089 35738 line -19089 35738 19089 35471 line -19089 35471 19160 35418 line -19160 36444 19089 36391 line -19089 36391 19089 36124 line -19089 36124 19160 36071 line -19160 36071 19657 36071 line -19657 36071 19729 36124 line -19729 36124 19729 36391 line -19729 36391 19657 36444 line -19089 36724 19729 36724 line -19089 37097 19729 37097 line -19373 36724 19373 37097 line -19729 38030 19089 38243 line -19089 38243 19729 38457 line -19729 38683 19729 39056 line -19729 39056 19657 39056 line -19657 39056 19444 38843 line -19444 38843 19444 39003 line -19444 39003 19373 39056 line -19373 39056 19160 39056 line -19160 39056 19089 39003 line -19089 39003 19089 38736 line -19089 38736 19160 38683 line -19089 40802 19231 40749 line -19231 40749 19586 40749 line -19586 40749 19729 40802 line -19160 41668 19089 41615 line -19089 41615 19089 41348 line -19089 41348 19160 41295 line -19160 41295 19657 41295 line -19657 41295 19729 41348 line -19729 41348 19729 41615 line -19729 41615 19657 41668 line -19089 42108 19231 42161 line -19231 42161 19586 42161 line -19586 42161 19729 42108 line -19089 43254 19586 43254 line -19586 43254 19729 43361 line -19729 43361 19729 43521 line -19729 43521 19586 43627 line -19586 43627 19089 43627 line -19444 43254 19444 43627 line -19089 43907 19515 43907 line -19444 43907 19515 43960 line -19515 43960 19515 44174 line -19515 44174 19444 44227 line -19444 44227 19089 44227 line -19729 44933 19089 44933 line -19089 44933 19089 44613 line -19089 44613 19160 44560 line -19160 44560 19444 44560 line -19444 44560 19515 44613 line -19515 44613 19515 44933 line -19089 45213 19515 45213 line -19373 45213 19515 45320 line -19515 45320 19515 45480 line -19515 45480 19373 45586 line -19302 45866 19302 46239 line -19302 46239 19444 46239 line -19444 46239 19515 46186 line -19515 46186 19515 45919 line -19515 45919 19444 45866 line -19444 45866 19160 45866 line -19160 45866 19089 45919 line -19089 45919 19089 46186 line -19089 46186 19160 46239 line -19515 46519 19515 46839 line -19515 46839 19444 46892 line -19444 46892 19089 46892 line -19089 46892 19089 46572 line -19089 46572 19160 46519 line -19160 46519 19231 46519 line -19231 46519 19302 46572 line -19302 46572 19302 46892 line -19160 47172 19089 47225 line -19089 47225 19089 47492 line -19089 47492 19160 47545 line -19160 47545 19231 47545 line -19231 47545 19302 47492 line -19302 47492 19302 47225 line -19302 47225 19373 47172 line -19373 47172 19444 47172 line -19444 47172 19515 47225 line -19515 47225 19515 47492 line -19515 47492 19444 47545 line -19089 48478 19586 48478 line -19586 48478 19729 48585 line -19729 48585 19729 48745 line -19729 48745 19586 48851 line -19586 48851 19089 48851 line -19444 48478 19444 48851 line -19515 49131 19231 49131 line -19231 49131 19089 49238 line -19089 49238 19089 49398 line -19089 49398 19231 49504 line -19231 49504 19515 49504 line -19089 49784 19515 49784 line -19373 49784 19515 49891 line -19515 49891 19515 50051 line -19515 50051 19373 50157 line -19515 50437 19515 50757 line -19515 50757 19444 50810 line -19444 50810 19089 50810 line -19089 50810 19089 50490 line -19089 50490 19160 50437 line -19160 50437 19231 50437 line -19231 50437 19302 50490 line -19302 50490 19302 50810 line -19160 51090 19089 51143 line -19089 51143 19089 51410 line -19089 51410 19160 51463 line -19160 51463 19231 51463 line -19231 51463 19302 51410 line -19302 51410 19302 51143 line -19302 51143 19373 51090 line -19373 51090 19444 51090 line -19444 51090 19515 51143 line -19515 51143 19515 51410 line -19515 51410 19444 51463 line -19089 52556 19231 52503 line -19231 52503 19586 52503 line -19586 52503 19729 52556 line -19160 53422 19089 53369 line -19089 53369 19089 53102 line -19089 53102 19160 53049 line -19160 53049 19444 53049 line -19444 53049 19515 53102 line -19515 53102 19515 53369 line -19515 53369 19444 53422 line -19089 53755 19160 53702 line -19160 53702 19444 53702 line -19444 53702 19515 53755 line -19515 53755 19515 54022 line -19515 54022 19444 54075 line -19444 54075 19160 54075 line -19160 54075 19089 54022 line -19089 54022 19089 53755 line -18876 54355 19515 54355 line -19444 54355 19515 54408 line -19515 54408 19515 54675 line -19515 54675 19444 54728 line -19444 54728 19160 54728 line -19160 54728 19089 54675 line -19089 54675 19089 54408 line -19089 54408 19160 54355 line -18876 55008 19515 55008 line -19444 55008 19515 55061 line -19515 55061 19515 55328 line -19515 55328 19444 55381 line -19444 55381 19160 55381 line -19160 55381 19089 55328 line -19089 55328 19089 55061 line -19089 55061 19160 55008 line -19302 55661 19302 56034 line -19302 56034 19444 56034 line -19444 56034 19515 55981 line -19515 55981 19515 55714 line -19515 55714 19444 55661 line -19444 55661 19160 55661 line -19160 55661 19089 55714 line -19089 55714 19089 55981 line -19089 55981 19160 56034 line -19089 56314 19515 56314 line -19373 56314 19515 56421 line -19515 56421 19515 56581 line -19515 56581 19373 56687 line -19160 57620 19089 57673 line -19089 57673 19089 57940 line -19089 57940 19160 57993 line -19160 57993 19231 57993 line -19231 57993 19302 57940 line -19302 57940 19302 57673 line -19302 57673 19373 57620 line -19373 57620 19444 57620 line -19444 57620 19515 57673 line -19515 57673 19515 57940 line -19515 57940 19444 57993 line -19729 58433 19657 58433 line -19444 58433 19160 58433 line -19160 58433 19089 58486 line -19089 58486 19089 58540 line -19729 59299 19089 59299 line -19089 59299 19089 58979 line -19089 58979 19160 58926 line -19160 58926 19444 58926 line -19444 58926 19515 58979 line -19515 58979 19515 59299 line -19302 59579 19302 59952 line -19302 59952 19444 59952 line -19444 59952 19515 59899 line -19515 59899 19515 59632 line -19515 59632 19444 59579 line -19444 59579 19160 59579 line -19160 59579 19089 59632 line -19089 59632 19089 59899 line -19089 59899 19160 59952 line -19089 60392 19231 60445 line -19231 60445 19586 60445 line -19586 60445 19729 60392 line -150 setlinewidth -17402 66371 17402 46686 line -80394 66371 17402 66371 line -80394 27001 80394 66371 line -17402 27001 80394 27001 line -17402 46686 17402 27001 line -50 setlinewidth -newpath 72000 30170 945 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -1890 setlinewidth -72000 31625 72000 33515 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 74000 31070 945 0 360 arc fill stroke -newpath 66000 30170 945 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -1890 setlinewidth -66000 31625 66000 33515 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 68000 31070 945 0 360 arc fill stroke -newpath 61850 63920 500 0 360 arc fill stroke -newpath 55650 63920 500 0 360 arc fill stroke -620 setlinewidth -58950 63540 58950 63820 line -58150 63540 58150 63820 line -59750 63540 59750 63820 line -58550 62540 58550 62820 line -57750 62540 57750 62820 line -59350 62540 59350 62820 line -50 setlinewidth -newpath 53600 63920 500 0 360 arc fill stroke -newpath 47400 63920 500 0 360 arc fill stroke -620 setlinewidth -50700 63540 50700 63820 line -49900 63540 49900 63820 line -51500 63540 51500 63820 line -50300 62540 50300 62820 line -49500 62540 49500 62820 line -51100 62540 51100 62820 line -50 setlinewidth -newpath 45350 63920 500 0 360 arc fill stroke -newpath 39150 63920 500 0 360 arc fill stroke -620 setlinewidth -42450 63540 42450 63820 line -41650 63540 41650 63820 line -43250 63540 43250 63820 line -42050 62540 42050 62820 line -41250 62540 41250 62820 line -42850 62540 42850 62820 line -50 setlinewidth -newpath 37100 63920 500 0 360 arc fill stroke -newpath 30900 63920 500 0 360 arc fill stroke -620 setlinewidth -34200 63540 34200 63820 line -33400 63540 33400 63820 line -35000 63540 35000 63820 line -33800 62540 33800 62820 line -33000 62540 33000 62820 line -34600 62540 34600 62820 line -50 setlinewidth -newpath 28850 63920 500 0 360 arc fill stroke -newpath 22650 63920 500 0 360 arc fill stroke -620 setlinewidth -25950 63540 25950 63820 line -25150 63540 25150 63820 line -26750 63540 26750 63820 line -25550 62540 25550 62820 line -24750 62540 24750 62820 line -26350 62540 26350 62820 line -50 setlinewidth -newpath 22650 29420 500 0 360 arc fill stroke -newpath 28850 29420 500 0 360 arc fill stroke -620 setlinewidth -25550 29800 25550 29520 line -26350 29800 26350 29520 line -24750 29800 24750 29520 line -25950 30800 25950 30520 line -26750 30800 26750 30520 line -25150 30800 25150 30520 line -50 setlinewidth -newpath 30900 29420 500 0 360 arc fill stroke -newpath 37100 29420 500 0 360 arc fill stroke -620 setlinewidth -33800 29800 33800 29520 line -34600 29800 34600 29520 line -33000 29800 33000 29520 line -34200 30800 34200 30520 line -35000 30800 35000 30520 line -33400 30800 33400 30520 line -50 setlinewidth -newpath 39150 29420 500 0 360 arc fill stroke -newpath 45350 29420 500 0 360 arc fill stroke -620 setlinewidth -42050 29800 42050 29520 line -42850 29800 42850 29520 line -41250 29800 41250 29520 line -42450 30800 42450 30520 line -43250 30800 43250 30520 line -41650 30800 41650 30520 line -50 setlinewidth -newpath 47400 29420 500 0 360 arc fill stroke -newpath 53600 29420 500 0 360 arc fill stroke -620 setlinewidth -50300 29800 50300 29520 line -51100 29800 51100 29520 line -49500 29800 49500 29520 line -50700 30800 50700 30520 line -51500 30800 51500 30520 line -49900 30800 49900 30520 line -50 setlinewidth -newpath 55650 29420 500 0 360 arc fill stroke -newpath 61850 29420 500 0 360 arc fill stroke -620 setlinewidth -58550 29800 58550 29520 line -59350 29800 59350 29520 line -57750 29800 57750 29520 line -58950 30800 58950 30520 line -59750 30800 59750 30520 line -58150 30800 58150 30520 line -50 setlinewidth -newpath 66500 51170 275 0 360 arc fill stroke -newpath 65500 51170 275 0 360 arc fill stroke -newpath 66500 53170 275 0 360 arc fill stroke -newpath 65500 53170 275 0 360 arc fill stroke -newpath 63000 53170 350 0 360 arc fill stroke -newpath 63000 55170 350 0 360 arc fill stroke -newpath 71500 64420 330 0 360 arc fill stroke -newpath 72500 64420 330 0 360 arc fill stroke -newpath 65500 60320 300 0 360 arc fill stroke -newpath 66500 60320 300 0 360 arc fill stroke -newpath 66500 61107 300 0 360 arc fill stroke -newpath 65500 61107 300 0 360 arc fill stroke -newpath 63638 62170 531 0 360 arc fill stroke -newpath 68362 62170 531 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -900 setlinewidth -32690 53920 33310 53920 line -50 setlinewidth -1 setlinecap 1 setlinejoin -620 setlinewidth -34000 54060 34000 53780 line -35000 54060 35000 53780 line -36000 54060 36000 53780 line -37000 54060 37000 53780 line -38000 54060 38000 53780 line -39000 54060 39000 53780 line -40000 54060 40000 53780 line -41000 54060 41000 53780 line -41000 57060 41000 56780 line -40000 57060 40000 56780 line -39000 57060 39000 56780 line -38000 57060 38000 56780 line -37000 57060 37000 56780 line -36000 57060 36000 56780 line -35000 57060 35000 56780 line -34000 57060 34000 56780 line -33000 57060 33000 56780 line -0 setlinewidth 0 setlinecap 0 setlinejoin -900 setlinewidth -39310 39420 38690 39420 line -50 setlinewidth -1 setlinecap 1 setlinejoin -620 setlinewidth -38000 39280 38000 39560 line -37000 39280 37000 39560 line -36000 39280 36000 39560 line -35000 39280 35000 39560 line -34000 39280 34000 39560 line -33000 39280 33000 39560 line -32000 39280 32000 39560 line -31000 39280 31000 39560 line -31000 36280 31000 36560 line -32000 36280 32000 36560 line -33000 36280 33000 36560 line -34000 36280 34000 36560 line -35000 36280 35000 36560 line -36000 36280 36000 36560 line -37000 36280 37000 36560 line -38000 36280 38000 36560 line -39000 36280 39000 36560 line -0 setlinewidth 0 setlinecap 0 setlinejoin -900 setlinewidth -50310 39420 49690 39420 line -50 setlinewidth -1 setlinecap 1 setlinejoin -620 setlinewidth -49000 39280 49000 39560 line -48000 39280 48000 39560 line -47000 39280 47000 39560 line -46000 39280 46000 39560 line -45000 39280 45000 39560 line -44000 39280 44000 39560 line -43000 39280 43000 39560 line -42000 39280 42000 39560 line -42000 36280 42000 36560 line -43000 36280 43000 36560 line -44000 36280 44000 36560 line -45000 36280 45000 36560 line -46000 36280 46000 36560 line -47000 36280 47000 36560 line -48000 36280 48000 36560 line -49000 36280 49000 36560 line -50000 36280 50000 36560 line -0 setlinewidth 0 setlinecap 0 setlinejoin -900 setlinewidth -43690 53920 44310 53920 line -50 setlinewidth -1 setlinecap 1 setlinejoin -620 setlinewidth -45000 54060 45000 53780 line -46000 54060 46000 53780 line -47000 54060 47000 53780 line -48000 54060 48000 53780 line -49000 54060 49000 53780 line -50000 54060 50000 53780 line -51000 54060 51000 53780 line -52000 54060 52000 53780 line -52000 57060 52000 56780 line -51000 57060 51000 56780 line -50000 57060 50000 56780 line -49000 57060 49000 56780 line -48000 57060 48000 56780 line -47000 57060 47000 56780 line -46000 57060 46000 56780 line -45000 57060 45000 56780 line -44000 57060 44000 56780 line -50 setlinewidth -newpath 62500 32670 350 0 360 arc fill stroke -newpath 62500 33670 350 0 360 arc fill stroke -newpath 53000 37420 350 0 360 arc fill stroke -newpath 54000 37420 350 0 360 arc fill stroke -newpath 55000 38420 350 0 360 arc fill stroke -newpath 53000 38420 350 0 360 arc fill stroke -newpath 62500 34670 350 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -550 setlinewidth -69975 53170 70525 53170 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 71250 53170 275 0 360 arc fill stroke -newpath 54000 38420 350 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -550 setlinewidth -61500 40895 61500 41445 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 61500 40170 275 0 360 arc fill stroke -newpath 62500 40170 275 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -550 setlinewidth -71725 35670 72275 35670 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 73000 35670 275 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -3500 setlinewidth -73750 41170 77250 41170 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 69000 42170 350 0 360 arc fill stroke -newpath 69000 41170 350 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -700 setlinewidth -68650 40170 69350 40170 line -50 setlinewidth -1 setlinecap 1 setlinejoin -0 setlinewidth 0 setlinecap 0 setlinejoin -900 setlinewidth -51310 49670 50690 49670 line -50 setlinewidth -1 setlinecap 1 setlinejoin -620 setlinewidth -50000 49530 50000 49810 line -49000 49530 49000 49810 line -48000 49530 48000 49810 line -47000 49530 47000 49810 line -46000 49530 46000 49810 line -45000 49530 45000 49810 line -44000 49530 44000 49810 line -43000 49530 43000 49810 line -42000 49530 42000 49810 line -41000 49530 41000 49810 line -40000 49530 40000 49810 line -39000 49530 39000 49810 line -38000 49530 38000 49810 line -37000 49530 37000 49810 line -36000 49530 36000 49810 line -35000 49530 35000 49810 line -34000 49530 34000 49810 line -33000 49530 33000 49810 line -32000 49530 32000 49810 line -32000 43530 32000 43810 line -33000 43530 33000 43810 line -34000 43530 34000 43810 line -35000 43530 35000 43810 line -36000 43530 36000 43810 line -37000 43530 37000 43810 line -38000 43530 38000 43810 line -39000 43530 39000 43810 line -40000 43530 40000 43810 line -41000 43530 41000 43810 line -42000 43530 42000 43810 line -43000 43530 43000 43810 line -44000 43530 44000 43810 line -45000 43530 45000 43810 line -46000 43530 46000 43810 line -47000 43530 47000 43810 line -48000 43530 48000 43810 line -49000 43530 49000 43810 line -50000 43530 50000 43810 line -51000 43530 51000 43810 line -50 setlinewidth -newpath 19370 62631 800 0 360 arc fill stroke -newpath 19370 30741 800 0 360 arc fill stroke -newpath 78425 62631 800 0 360 arc fill stroke -newpath 78425 30741 800 0 360 arc fill stroke -newpath 51000 42170 275 0 360 arc fill stroke -newpath 51000 41170 275 0 360 arc fill stroke -newpath 63000 49170 275 0 360 arc fill stroke -newpath 63000 50170 275 0 360 arc fill stroke -newpath 65500 58170 275 0 360 arc fill stroke -newpath 64500 58170 275 0 360 arc fill stroke -newpath 68750 35670 275 0 360 arc fill stroke -newpath 68750 36670 275 0 360 arc fill stroke -newpath 63250 37670 350 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -700 setlinewidth -59600 37670 58900 37670 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 71250 47670 350 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -700 setlinewidth -67600 47670 66900 47670 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 71250 46170 350 0 360 arc fill stroke -0 setlinewidth 0 setlinecap 0 setlinejoin -700 setlinewidth -67600 46170 66900 46170 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 55500 53170 300 0 360 arc fill stroke -newpath 55500 57170 300 0 360 arc fill stroke -newpath 55500 43920 300 0 360 arc fill stroke -newpath 55500 39920 300 0 360 arc fill stroke -newpath 57750 41170 300 0 360 arc fill stroke -newpath 57750 37170 300 0 360 arc fill stroke -newpath 68000 38920 300 0 360 arc fill stroke -newpath 64000 38920 300 0 360 arc fill stroke -newpath 63250 36170 300 0 360 arc fill stroke -newpath 59250 36170 300 0 360 arc fill stroke -newpath 53250 45670 300 0 360 arc fill stroke -newpath 53250 49670 300 0 360 arc fill stroke -newpath 66000 44670 300 0 360 arc fill stroke -newpath 62000 44670 300 0 360 arc fill stroke -newpath 66000 46170 300 0 360 arc fill stroke -newpath 62000 46170 300 0 360 arc fill stroke -newpath 66000 47670 300 0 360 arc fill stroke -newpath 62000 47670 300 0 360 arc fill stroke -newpath 54500 49670 300 0 360 arc fill stroke -newpath 54500 45670 300 0 360 arc fill stroke -620 setlinewidth -60360 44170 60640 44170 line -60360 45170 60640 45170 line -60360 46170 60640 46170 line -60360 47170 60640 47170 line -60360 48170 60640 48170 line -60360 49170 60640 49170 line -60360 50170 60640 50170 line -60360 51170 60640 51170 line -60360 52170 60640 52170 line -60360 53170 60640 53170 line -60360 54170 60640 54170 line -60360 55170 60640 55170 line -60360 56170 60640 56170 line -0 setlinewidth 0 setlinecap 0 setlinejoin -900 setlinewidth -60500 42860 60500 43480 line -50 setlinewidth -1 setlinecap 1 setlinejoin -620 setlinewidth -57360 56170 57640 56170 line -57360 55170 57640 55170 line -57360 54170 57640 54170 line -57360 53170 57640 53170 line -57360 52170 57640 52170 line -57360 51170 57640 51170 line -57360 50170 57640 50170 line -57360 49170 57640 49170 line -57360 48170 57640 48170 line -57360 47170 57640 47170 line -57360 46170 57640 46170 line -57360 45170 57640 45170 line -57360 44170 57640 44170 line -57360 43170 57640 43170 line -0 setlinewidth 0 setlinecap 0 setlinejoin -600 setlinewidth -61500 57620 61500 58220 line -50 setlinewidth -1 setlinecap 1 setlinejoin -newpath 61500 58920 300 0 360 arc fill stroke -newpath 70500 56170 300 0 360 arc fill stroke -newpath 65500 56170 300 0 360 arc fill stroke -newpath 32000 51170 500 0 360 arc fill stroke -newpath 26000 51170 500 0 360 arc fill stroke -500 setlinewidth -71250 53170 71250 53920 line -66500 51170 66500 53170 line -63000 50170 66250 50170 line -66500 50420 66500 51170 line -66250 50170 66500 50420 line -71250 63420 71500 63420 line -68250 63420 71250 63420 line -71500 63420 72250 63420 line -72250 63420 72500 63670 line -72500 63670 72500 64420 line -71250 53170 71250 47670 line -71250 47670 71250 46170 line -71250 46170 71250 36670 line -54000 41170 51000 41170 line -63750 28420 63750 29670 line -63750 29670 63750 33170 line -63750 33170 63250 33670 line -63250 33670 62500 33670 line -57750 41170 54000 41170 line -63750 28420 62500 28420 line -32000 51170 32000 49670 line -54000 38420 54000 41170 line -71500 54170 71500 63420 line -71250 53920 71500 54170 line -66000 28420 66000 30170 line -72000 28420 72000 30170 line -63750 28420 66000 28420 line -66000 28420 72000 28420 line -72000 28420 74500 28420 line -73500 35670 73000 35670 line -54000 38420 54000 37420 line -68362 63420 68250 63420 line -74500 34670 73500 35670 line -24000 51170 26000 51170 line -74500 33670 74500 34670 line -75750 32420 74500 33670 line -75750 29670 75750 32420 line -74500 28420 75750 29670 line -61500 41170 64500 41170 line -64500 57170 64500 57420 line -61250 34170 56250 34170 line -64500 58170 64500 58920 line -64500 58920 64500 60670 line -64500 60670 64937 61107 line -64937 61107 65500 61107 line -66500 53170 66500 53420 line -64500 55420 64500 57420 line -315 setlinewidth -61500 58920 64500 58920 line -55500 57170 55500 57420 line -61000 58920 61500 58920 line -60000 57920 61000 58920 line -56000 57920 60000 57920 line -55500 57420 56000 57920 line -58750 51670 58500 51670 line -59500 50420 59750 50170 line -59750 50170 60500 50170 line -58750 51670 59500 50920 line -56650 49270 56650 51570 line -56650 51570 56750 51670 line -157 setlinewidth -56750 51670 58500 51670 line -315 setlinewidth -57500 49170 56750 49170 line -56750 49170 56650 49270 line -59500 50920 59500 50420 line -500 setlinewidth -65500 61107 65500 62170 line -68362 62170 68362 63420 line -32000 49670 32000 47670 line -54000 37420 54000 36420 line -54000 36420 54000 36420 line -68750 36670 71500 36670 line -71500 36670 71250 36670 line -71250 36670 72000 36670 line -72000 36670 73000 36670 line -73000 36670 73000 35670 line -63638 62170 65500 62170 line -65500 62920 66000 63420 line -66000 63420 68250 63420 line -65500 62170 65500 62920 line -57750 41170 61500 41170 line -61750 33670 61250 34170 line -64500 57420 64500 58170 line -56250 34170 54000 36420 line -62500 33670 61750 33670 line -62500 28420 61750 27670 line -61750 27670 22500 27670 line -22500 27670 21500 28670 line -21500 28670 21500 48670 line -21500 48670 24000 51170 line -60500 50170 63000 50170 line -66500 53420 64500 55420 line -72000 34170 72000 32570 line -69000 39420 69000 40170 line -68500 38920 69000 39420 line -66150 32570 67750 34170 line -72000 35670 72000 34170 line -67250 38170 68000 38920 line -68750 35670 67750 35670 line -67750 34170 72000 34170 line -66000 32570 66150 32570 line -665 setlinewidth -72000 35670 68750 35670 line -500 setlinewidth -67750 35670 67250 36170 line -68000 38920 68500 38920 line -67250 36170 67250 38170 line -315 setlinewidth -60250 61170 60250 63180 line -60250 63180 59750 63680 line -51000 56920 51000 57420 line -55000 59920 59000 59920 line -53000 57920 55000 59920 line -51000 57420 51500 57920 line -51500 57920 53000 57920 line -59750 63680 58950 63680 line -59000 59920 60250 61170 line -500 setlinewidth -51500 30060 51100 29660 line -27500 37170 23500 33170 line -51100 29020 51100 29660 line -24750 62680 24750 63280 line -51500 30660 51500 30060 line -59750 30660 59750 30060 line -41250 62680 41250 63280 line -35000 30060 34600 29660 line -35000 30660 35000 30060 line -26750 30660 26750 30060 line -33000 63280 33400 63680 line -43250 30060 42850 29660 line -43250 30660 43250 30060 line -59750 30060 59350 29660 line -35000 30660 39510 30660 line -40000 29670 41000 28670 line -40000 30170 40000 29670 line -42850 29020 42850 29660 line -39510 30660 40000 30170 line -49250 28670 50750 28670 line -26750 30660 31490 30660 line -24500 28670 26000 28670 line -43250 30660 47760 30660 line -26350 29020 26350 29660 line -24750 62680 24750 59670 line -33000 62680 33000 63280 line -57750 62680 57750 63280 line -24750 63280 25150 63680 line -34250 28670 34600 29020 line -49500 63280 49900 63680 line -47760 30660 48250 30170 line -26750 30060 26350 29660 line -41000 28670 42500 28670 line -26000 28670 26350 29020 line -48250 29670 49250 28670 line -48250 30170 48250 29670 line -42500 28670 42850 29020 line -23500 33170 23500 29670 line -31750 29670 32750 28670 line -33000 62680 28740 62680 line -25150 64320 25150 63680 line -25500 64670 25150 64320 line -27250 64670 25500 64670 line -27750 64170 27250 64670 line -27750 63670 27750 64170 line -28740 62680 27750 63670 line -41250 62680 36990 62680 line -33400 64320 33400 63680 line -33750 64670 33400 64320 line -35500 64670 33750 64670 line -36000 64170 35500 64670 line -36000 63670 36000 64170 line -36990 62680 36000 63670 line -49500 62680 45240 62680 line -41650 64320 41650 63680 line -42000 64670 41650 64320 line -44000 64670 42000 64670 line -44250 64420 44000 64670 line -44250 63670 44250 64420 line -45240 62680 44250 63670 line -57750 62680 53490 62680 line -49900 64320 49900 63680 line -50250 64670 49900 64320 line -52000 64670 50250 64670 line -52500 64170 52000 64670 line -52500 63670 52500 64170 line -53490 62680 52500 63670 line -51500 30660 56260 30660 line -59350 29020 59350 29660 line -59000 28670 59350 29020 line -57500 28670 59000 28670 line -56500 29670 57500 28670 line -56500 30420 56500 29670 line -56260 30660 56500 30420 line -59750 30660 61740 30660 line -62500 31420 62500 32670 line -61740 30660 62500 31420 line -50750 28670 51100 29020 line -34600 29020 34600 29660 line -49500 62680 49500 63280 line -32750 28670 34250 28670 line -57750 63280 58150 63680 line -31750 30400 31750 29670 line -31490 30660 31750 30400 line -23500 29670 24500 28670 line -24750 59670 27500 56920 line -27500 56920 27500 37170 line -41250 63280 41650 63680 line -315 setlinewidth -49000 56920 49000 58170 line -58250 61420 58550 61720 line -49000 58170 50250 59420 line -50250 59420 51500 59420 line -51500 59420 53500 61420 line -58550 61720 58550 62680 line -53500 61420 58250 61420 line -52250 58670 54250 60670 line -50000 57670 51000 58670 line -58750 60670 59350 61270 line -59350 61270 59350 62680 line -50000 56920 50000 57670 line -54250 60670 58750 60670 line -51000 58670 52250 58670 line -48000 58420 49750 60170 line -52000 61420 52000 63180 line -48000 56920 48000 58420 line -50750 60170 52000 61420 line -51500 63680 50700 63680 line -49750 60170 50750 60170 line -52000 63180 51500 63680 line -49750 61670 50300 62220 line -46000 56920 46000 59420 line -48250 61670 49750 61670 line -46000 59420 48250 61670 line -50300 62220 50300 62680 line -47000 58920 49000 60920 line -47000 56920 47000 58920 line -51100 61770 51100 62680 line -50250 60920 51100 61770 line -49000 60920 50250 60920 line -45000 56920 45000 58170 line -43250 63680 42450 63680 line -43750 63180 43250 63680 line -43750 59420 43750 63180 line -45000 58170 43750 59420 line -40000 56920 40000 59420 line -42050 61470 42050 62680 line -40000 59420 42050 61470 line -44000 57420 42850 58570 line -42850 58570 42850 62680 line -44000 56920 44000 57420 line -35000 63680 34200 63680 line -35500 63180 35000 63680 line -39000 58420 35500 61920 line -35500 61920 35500 63180 line -39000 56920 39000 58420 line -37000 57920 33800 61120 line -37000 56920 37000 57920 line -33800 61120 33800 62680 line -38000 58170 34600 61570 line -34600 61570 34600 62680 line -38000 56920 38000 58170 line -36000 57670 33500 60170 line -36000 56920 36000 57670 line -27250 63180 26750 63680 line -26750 63680 25950 63680 line -28250 60170 27250 61170 line -33500 60170 28250 60170 line -27250 61170 27250 63180 line -34000 56920 34000 57170 line -32500 58670 27250 58670 line -34000 57170 32500 58670 line -27250 58670 25550 60370 line -25550 60370 25550 62680 line -26350 60820 26350 62680 line -35000 57420 33000 59420 line -27750 59420 26350 60820 line -33000 59420 27750 59420 line -35000 56920 35000 57420 line -26250 34420 24250 32420 line -24750 29660 25550 29660 line -33000 36420 33000 36170 line -33000 36170 33000 36420 line -24750 29660 24250 30160 line -31250 34420 26250 34420 line -31250 34420 31250 34420 line -24250 32420 24250 30160 line -31250 34420 33000 36170 line -25950 31370 27000 32420 line -35000 35670 35000 36420 line -27000 32420 31750 32420 line -25950 30660 25950 31370 line -31750 32420 35000 35670 line -34000 35920 34000 36420 line -25150 31820 26750 33420 line -31500 33420 34000 35920 line -25150 30660 25150 31820 line -26750 33420 31500 33420 line -32500 31920 32500 30160 line -36000 36420 36000 35420 line -36000 35420 32500 31920 line -33000 29660 33800 29660 line -32500 30160 33000 29660 line -38000 34920 34200 31120 line -34200 31120 34200 30660 line -38000 36420 38000 34920 line -37000 36420 37000 35170 line -33400 31570 33400 30660 line -37000 35170 33400 31570 line -41250 29660 42050 29660 line -40750 33170 40750 30160 line -39000 34920 40750 33170 line -40750 30160 41250 29660 line -39000 36420 39000 34920 line -42450 32620 42450 30660 line -44000 36420 44000 34170 line -44000 34170 42450 32620 line -43000 36420 43000 34920 line -43000 34920 41650 33570 line -41650 33570 41650 30660 line -49000 31170 49000 30160 line -49000 30160 49500 29660 line -49500 29660 50300 29660 line -45000 35170 49000 31170 line -45000 36420 45000 35170 line -47000 36420 47000 35920 line -50700 32220 50700 30660 line -47000 35920 50700 32220 line -46000 36420 46000 35670 line -46000 35670 49900 31770 line -49900 31770 49900 30660 line -48000 36170 50750 33420 line -50750 33420 53000 33420 line -56750 31670 57250 31170 line -57750 29660 58550 29660 line -48000 36420 48000 36170 line -57250 31170 57250 30160 line -53250 33420 55000 31670 line -57250 30160 57750 29660 line -55000 31670 56750 31670 line -53000 33420 53250 33420 line -55750 33170 57750 33170 line -51250 35170 53750 35170 line -50000 36420 50000 36170 line -50000 36420 51250 35170 line -53750 35170 55750 33170 line -57750 33170 58950 31970 line -58950 31970 58950 30660 line -49000 36420 49000 36170 line -57250 32420 58150 31520 line -53500 34420 55500 32420 line -55500 32420 57250 32420 line -49000 36170 50750 34420 line -53250 34420 53500 34420 line -58150 31520 58150 30660 line -50750 34420 53250 34420 line -60500 51170 63000 51170 line -63000 51170 65500 51170 line -63000 53170 63000 51170 line -55000 48020 55350 48020 line -63500 55170 65500 53170 line -33000 49670 33000 48920 line -42900 48020 55000 48020 line -55000 48020 55100 48020 line -42500 48420 42900 48020 line -63000 55170 63500 55170 line -42250 50670 42500 50420 line -40750 50670 42250 50670 line -40500 50420 40750 50670 line -157 setlinewidth -40500 48920 40500 50420 line -315 setlinewidth -40250 48670 40500 48920 line -33250 48670 40250 48670 line -33000 48920 33250 48670 line -59250 52670 59750 52170 line -59750 52170 60500 52170 line -157 setlinewidth -56500 52670 58500 52670 line -315 setlinewidth -56000 52170 56500 52670 line -56000 48670 56000 52170 line -55350 48020 56000 48670 line -157 setlinewidth -42500 50420 42500 48420 line -315 setlinewidth -61750 53920 63000 55170 line -61750 52920 61750 53920 line -61000 52170 61750 52920 line -60500 52170 61000 52170 line -59250 52670 58500 52670 line -53250 56670 55500 58920 line -61750 62170 64000 64420 line -61750 61170 61750 62170 line -59500 58920 61750 61170 line -55500 58920 59500 58920 line -64000 64420 71500 64420 line -53250 49670 53250 56670 line -500 setlinewidth -65500 56170 65500 58170 line -65500 60320 65500 58170 line -315 setlinewidth -66000 47670 67250 47670 line -66500 60320 66850 60320 line -67750 47670 67250 47670 line -68250 48170 67750 47670 line -68250 58920 68250 56670 line -68250 56670 68250 48170 line -66850 60320 68250 58920 line -66000 46170 66000 47670 line -69000 57420 69000 55920 line -67250 45670 67250 46170 line -67313 61107 69000 59420 line -69000 59420 69000 57420 line -69000 55920 69000 47420 line -66000 44670 66250 44670 line -66250 44670 67250 45670 line -69000 47420 67750 46170 line -67313 61107 66500 61107 line -67250 46170 67750 46170 line -31000 43920 31250 43670 line -31250 43670 32000 43670 line -33000 53920 34000 53920 line -31000 45670 31000 52420 line -31000 52420 32500 53920 line -33000 53920 32500 53920 line -31000 45670 31000 43920 line -35000 49670 35000 53920 line -36000 49670 36000 53920 line -37000 49670 37000 53920 line -38000 49670 38000 53920 line -39000 49670 39000 53920 line -40000 49670 40000 53920 line -500 setlinewidth -53000 38420 52000 38420 line -30000 53170 31750 54920 line -30000 43170 30000 53170 line -31000 42170 30000 43170 line -31000 39420 31000 42170 line -52000 38420 42000 38420 line -41000 53920 41000 54920 line -42000 39420 42000 38420 line -31000 39420 31000 38420 line -52000 54920 41000 54920 line -52000 53920 52000 54920 line -31000 38420 42000 38420 line -31750 54920 41000 54920 line -30750 55920 41000 55920 line -53000 37420 51000 37420 line -51000 37420 42250 37420 line -41000 56920 41000 55920 line -42000 36420 42000 37420 line -31000 37420 30000 37420 line -31000 36420 31000 37420 line -31000 37420 42250 37420 line -28750 38670 28750 53920 line -52000 55920 41000 55920 line -52000 56920 52000 55920 line -42000 37420 42250 37420 line -30000 37420 28750 38670 line -28750 53920 30750 55920 line -315 setlinewidth -39000 43670 39000 39420 line -38000 43670 38000 39420 line -37000 43670 37000 39420 line -36000 43670 36000 39420 line -35000 43670 35000 39420 line -34000 43670 34000 39420 line -33000 39420 32000 39420 line -33000 43670 33000 39420 line -50000 43670 50000 39420 line -49000 43670 49000 39420 line -48000 43670 48000 39420 line -47000 43670 47000 39420 line -46000 43670 46000 39420 line -45000 43670 45000 39420 line -44000 43670 44000 39420 line -43000 43670 43000 39420 line -44000 49670 44000 53920 line -45000 49670 45000 53920 line -46000 49670 46000 53920 line -47000 49670 47000 53920 line -48000 49670 48000 53920 line -49000 49670 49000 53920 line -50000 49670 50000 53920 line -51000 49670 51000 53920 line -500 setlinewidth -66000 35920 66000 38920 line -62500 34670 64750 34670 line -66000 35920 64750 34670 line -68250 41170 69000 41170 line -66000 38920 68250 41170 line -57250 35170 55000 37420 line -62000 35170 62500 34670 line -55000 38420 55000 37420 line -62000 35170 57250 35170 line -70250 53170 70250 55920 line -70250 55920 70500 56170 line -315 setlinewidth -57500 51170 58000 51170 line -59500 49170 60500 49170 line -58500 50170 59500 49170 line -58500 50670 58500 50170 line -58000 51170 58500 50670 line -500 setlinewidth -60500 49170 63000 49170 line -63000 49170 63000 42170 line -51000 42170 63000 42170 line -63000 42170 65250 42170 line -65250 42170 70000 46920 line -70000 46920 70000 49420 line -70000 49420 70000 52670 line -70000 52670 70250 52920 line -70250 52920 70250 53170 line -51000 43670 51000 42170 line -315 setlinewidth -55500 39920 56250 39170 line -60500 39170 61500 40170 line -56250 39170 57750 39170 line -57750 39170 60500 39170 line -57750 37170 57750 39170 line -62500 38420 63250 37670 line -62500 40170 62500 38420 line -65000 36670 65000 39170 line -64500 36170 65000 36670 line -63250 36170 64500 36170 line -68000 42170 69000 42170 line -65000 39170 68000 42170 line -54750 48670 55250 49170 line -55250 52920 55500 53170 line -55250 49170 55250 52920 line -55500 53170 57500 53170 line -43000 48920 43250 48670 line -43000 49670 43000 48920 line -43250 48670 54750 48670 line -60500 45170 59000 45170 line -56250 45920 56250 46920 line -56250 46920 55750 47420 line -55750 47420 54750 47420 line -58500 45670 59000 45170 line -157 setlinewidth -56500 45670 58500 45670 line -315 setlinewidth -42250 47420 54750 47420 line -42000 47670 42250 47420 line -42000 47920 42000 47670 line -42000 47920 42000 49670 line -56500 45670 56250 45920 line -60500 44170 58750 44170 line -55500 46670 55500 45420 line -55500 45420 56250 44670 line -56250 44670 56500 44670 line -58250 44670 58750 44170 line -157 setlinewidth -56500 44670 58250 44670 line -315 setlinewidth -55500 46670 54250 46670 line -41000 49670 41000 47570 line -41000 47570 41900 46670 line -41900 46670 54250 46670 line -54250 46670 54300 46670 line -157 setlinewidth -42500 44170 42500 42920 line -315 setlinewidth -42500 42920 42250 42670 line -42250 42670 40250 42670 line -40250 42670 40000 42920 line -40000 42920 40000 43670 line -51500 44670 52250 43920 line -55500 43920 52250 43920 line -43000 44670 50250 44670 line -42500 44170 43000 44670 line -50250 44670 51500 44670 line -52150 46020 52900 46020 line -41450 46020 52150 46020 line -41000 45570 41450 46020 line -41000 43670 41000 45570 line -52900 46020 53250 45670 line -54000 44920 54250 44920 line -52050 45370 52500 44920 line -52500 44920 54000 44920 line -51250 45370 52050 45370 line -54500 45170 54500 45670 line -54250 44920 54500 45170 line -42100 45370 51250 45370 line -51250 45370 51300 45370 line -42000 43670 42000 45270 line -42000 45270 42100 45370 line -64000 36920 64000 38920 line -59250 37670 59250 36920 line -59250 36920 59250 36170 line -59250 36920 64000 36920 line -62000 44920 62000 44670 line -60750 46170 62000 44920 line -60250 46170 60500 46170 line -60500 46170 60750 46170 line -61000 47170 62000 46170 line -60500 47170 61000 47170 line -60500 48170 61500 48170 line -61500 48170 62000 47670 line -54500 49670 54500 53670 line -55000 54170 57500 54170 line -54500 53670 55000 54170 line -60500 56920 61500 57920 line -60500 56170 60500 56920 line -319 setlinewidth -58484 53692 59516 53692 line -58583 53948 59415 53948 line -58609 54204 59392 54204 line -58568 54460 59432 54460 line -54066 54460 54136 54460 line -58499 54716 59500 54716 line -54066 54716 54392 54716 line -58588 54972 59411 54972 line -54066 54972 54850 54972 line -58609 55228 59392 55228 line -54066 55228 56392 55228 line -58558 55484 59442 55484 line -54066 55484 56442 55484 line -58509 55740 59489 55740 line -54066 55740 56489 55740 line -58593 55996 59406 55996 line -54066 55996 56406 55996 line -58609 56252 59392 56252 line -55782 56252 56392 56252 line -54066 56252 55212 56252 line -58549 56508 59452 56508 line -56194 56508 56452 56508 line -54241 56508 54807 56508 line -58409 56764 59593 56764 line -56367 56764 56593 56764 line -54497 56764 54630 56764 line -58109 57020 59694 57020 line -56448 57020 56893 57020 line -56456 57276 59769 57276 line -56387 57532 59958 57532 line -56237 57788 60214 57788 line -55895 58044 60470 58044 line -60024 58300 60544 58300 line -60289 58556 60613 58556 line -60545 58812 60545 58812 line -31816 50840 34184 50840 line -31816 51096 34184 51096 line -31816 51352 34184 51352 line -31816 51608 34184 51608 line -31816 51864 34184 51864 line -31854 52120 34184 52120 line -32110 52376 34184 52376 line -32366 52632 34184 52632 line -33624 52888 33624 52888 line -59316 50574 59480 50574 line -59300 50830 59452 50830 line -59199 51086 59391 51086 line -58982 51342 59407 51342 line -58726 51598 59168 51598 line -58557 51854 58912 51854 line -39223 44753 39773 44753 line -38223 44753 38773 44753 line -37223 44753 37773 44753 line -36223 44753 36773 44753 line -35223 44753 35773 44753 line -34223 44753 34773 44753 line -33223 44753 33773 44753 line -32223 44753 32773 44753 line -31816 45009 40184 45009 line -31816 45265 40184 45265 line -31816 45521 40184 45521 line -31816 45777 40214 45777 line -31816 46033 40329 46033 line -31816 46289 40565 46289 line -31816 46545 40821 46545 line -31816 46801 40615 46801 line -31816 47057 40369 47057 line -31816 47313 40229 47313 line -31816 47569 40184 47569 line -31816 47825 40184 47825 line -31816 48081 32687 48081 line -31816 48337 32429 48337 line -32254 48593 32254 48593 line -63909 43218 65011 43218 line -63909 43474 65267 43474 line -63909 43730 65523 43730 line -63909 43986 65328 43986 line -63909 44242 65139 44242 line -63909 44498 65057 44498 line -63909 44754 65043 44754 line -63909 45010 65103 45010 line -63909 45266 65248 45266 line -63909 45522 65294 45522 line -63909 45778 65125 45778 line -63909 46034 65051 46034 line -63909 46290 65046 46290 line -63909 46546 65119 46546 line -63909 46802 65184 46802 line -63909 47058 65184 47058 line -63909 47314 65110 47314 line -63909 47570 65044 47570 line -63909 47826 65054 47826 line -63909 48082 65134 48082 line -63909 48338 65314 48338 line -66266 48594 66573 48594 line -63909 48594 65734 48594 line -63909 48850 67434 48850 line -63931 49106 67434 49106 line -63914 49362 67434 49362 line -63824 49618 67434 49618 line -63891 49874 67434 49874 line -63932 50130 67434 50130 line -67008 50386 67434 50386 line -67270 50642 67434 50642 line -67396 50898 67434 50898 line -67432 51154 67434 51154 line -67405 51410 67434 51410 line -67292 51666 67434 51666 line -67056 51922 67434 51922 line -63816 52178 67434 52178 line -67081 52434 67434 52434 line -63816 52434 64922 52434 line -67304 52690 67434 52690 line -63889 52690 64698 52690 line -67407 52946 67434 52946 line -63982 52946 64570 52946 line -67433 53202 67434 53202 line -64007 53202 64314 53202 line -67392 53458 67434 53458 line -63971 53458 64058 53458 line -67260 53714 67434 53714 line -66985 53970 67434 53970 line -65985 53970 66016 53970 line -65598 54226 67434 54226 line -65342 54482 67434 54482 line -65086 54738 67434 54738 line -64830 54994 67434 54994 line -61592 54994 61669 54994 line -65777 55250 67434 55250 line -64574 55250 65221 55250 line -61609 55250 61925 55250 line -66192 55506 67434 55506 line -64318 55506 64809 55506 line -61549 55506 62048 55506 line -66366 55762 67434 55762 line -64059 55762 64631 55762 line -61518 55762 62184 55762 line -66447 56018 67434 56018 line -63547 56018 64554 56018 line -61597 56018 62455 56018 line -66456 56274 67434 56274 line -61607 56274 64543 56274 line -66409 56530 67434 56530 line -61540 56530 64591 56530 line -66409 56786 67434 56786 line -61519 56786 64591 56786 line -66409 57042 67434 57042 line -62121 57042 64591 57042 line -66409 57298 67434 57298 line -62378 57298 64162 57298 line -66409 57554 67434 57554 line -62459 57554 63796 57554 line -66409 57810 67434 57810 line -62459 57810 63637 57810 line -66431 58066 67434 58066 line -62459 58066 63569 58066 line -66422 58322 67434 58322 line -62452 58322 63578 58322 line -66409 58578 67434 58578 line -62396 58578 63659 58578 line -66409 58834 67182 58834 line -62455 58834 63844 58834 line -66409 59090 66926 59090 line -62443 59090 64338 59090 line -66409 59346 66670 59346 line -62361 59346 64591 59346 line -62174 59602 64591 59602 line -61697 59858 64591 59858 line -61847 60114 64564 60114 line -62103 60370 64543 60370 line -62353 60626 64589 60626 line -62510 60882 64567 60882 line -64230 61138 64543 61138 line -62563 61138 63039 61138 line -64545 61394 64582 61394 line -62566 61394 62734 61394 line -62566 61650 62566 61650 line -50969 39469 54651 39469 line -50969 39725 54562 39725 line -50960 39981 54543 39981 line -57975 40237 60413 40237 line -56406 40237 57530 40237 line -51088 40237 54594 40237 line -50858 40237 50934 40237 line -58428 40493 60622 40493 line -56270 40493 57072 40493 line -51643 40493 54732 40493 line -58611 40749 60581 40749 line -55985 40749 56886 40749 line -51834 40749 55018 40749 line -58694 41005 60566 41005 line -51920 41005 56806 41005 line -58707 41261 60566 41261 line -51933 41261 56792 41261 line -60072 31715 61509 31715 line -59766 31971 61591 31971 line -59721 32227 61591 32227 line -59581 32483 61509 32483 line -59335 32739 61493 32739 line -59079 32995 61544 32995 line -58823 33251 61581 33251 line -58567 33507 61505 33507 line -58308 33763 61493 33763 line -56055 34019 61554 34019 line -55799 34275 57113 34275 line -55543 34531 56603 34531 line -55287 34787 56347 34787 line -55031 35043 56091 35043 line -54775 35299 55835 35299 line -54519 35555 55579 35555 line -54250 35811 55323 35811 line -51506 36067 55067 36067 line -51250 36323 54811 36323 line -54555 36579 54555 36579 line -17977 27652 79819 27652 line -59495 27908 79819 27908 line -51245 27908 57005 27908 line -42995 27908 48755 27908 line -34745 27908 40505 27908 line -26495 27908 32255 27908 line -17977 27908 24005 27908 line -59779 28164 79819 28164 line -51529 28164 56720 28164 line -43279 28164 48470 28164 line -35029 28164 40220 28164 line -26779 28164 31970 28164 line -17977 28164 23720 28164 line -62435 28420 79819 28420 line -60026 28420 61259 28420 line -56235 28420 56464 28420 line -54185 28420 55059 28420 line -51776 28420 53009 28420 line -47985 28420 48214 28420 line -45935 28420 46809 28420 line -43526 28420 44759 28420 line -39735 28420 39964 28420 line -37685 28420 38559 28420 line -35276 28420 36509 28420 line -31485 28420 31714 28420 line -29435 28420 30309 28420 line -27026 28420 28259 28420 line -23235 28420 23464 28420 line -17977 28420 22059 28420 line -72580 28676 79819 28676 line -66580 28676 71415 28676 line -62742 28676 65415 28676 line -60189 28676 60958 28676 line -54492 28676 54758 28676 line -51939 28676 52708 28676 line -46242 28676 46508 28676 line -43689 28676 44458 28676 line -37992 28676 38258 28676 line -35439 28676 36208 28676 line -29742 28676 30008 28676 line -27189 28676 27958 28676 line -17977 28676 21758 28676 line -73023 28932 79819 28932 line -67023 28932 70973 28932 line -62900 28932 64973 28932 line -60250 28932 60797 28932 line -52000 28932 52547 28932 line -43750 28932 44297 28932 line -35500 28932 36047 28932 line -27250 28932 27797 28932 line -17977 28932 21597 28932 line -73269 29188 79819 29188 line -67269 29188 70726 29188 line -62984 29188 64726 29188 line -60259 29188 60715 29188 line -52009 29188 52465 29188 line -43759 29188 44215 29188 line -35509 29188 35965 29188 line -27259 29188 27715 29188 line -17977 29188 21515 29188 line -79104 29444 79819 29444 line -73430 29444 77749 29444 line -67430 29444 70563 29444 line -63006 29444 64563 29444 line -60413 29444 60693 29444 line -52163 29444 52443 29444 line -43913 29444 44193 29444 line -35663 29444 35943 29444 line -27413 29444 27693 29444 line -20049 29444 21493 29444 line -17977 29444 18694 29444 line -79447 29700 79819 29700 line -74832 29700 77402 29700 line -68832 29700 70462 29700 line -62976 29700 64462 29700 line -60583 29700 60726 29700 line -52333 29700 52476 29700 line -44083 29700 44226 29700 line -35833 29700 35976 29700 line -27583 29700 27726 29700 line -20392 29700 21526 29700 line -17977 29700 18347 29700 line -79656 29956 79819 29956 line -75154 29956 77194 29956 line -69154 29956 70409 29956 line -62882 29956 64409 29956 line -20601 29956 21620 29956 line -17977 29956 18139 29956 line -79786 30212 79819 30212 line -75356 30212 77065 30212 line -69356 30212 70398 30212 line -62696 30212 64398 30212 line -20731 30212 21804 30212 line -17977 30212 18010 30212 line -75486 30468 76991 30468 line -69486 30468 70425 30468 line -62832 30468 64425 30468 line -20803 30468 22153 30468 line -75565 30724 76966 30724 line -69565 30724 70494 30724 line -63088 30724 64494 30724 line -20826 30724 22591 30724 line -75599 30980 76985 30980 line -69599 30980 70612 30980 line -63289 30980 64612 30980 line -20810 30980 22591 30980 line -79799 31236 79819 31236 line -75602 31236 77051 31236 line -69602 31236 70522 31236 line -63389 31236 64522 31236 line -20744 31236 22591 31236 line -17977 31236 17995 31236 line -79678 31492 79819 31492 line -75551 31492 77171 31492 line -69551 31492 70409 31492 line -63409 31492 64409 31492 line -20623 31492 22591 31492 line -17977 31492 18116 31492 line -79482 31748 79819 31748 line -75455 31748 77368 31748 line -69455 31748 70396 31748 line -63409 31748 64396 31748 line -20427 31748 22591 31748 line -17977 31748 18313 31748 line -79163 32004 79819 32004 line -75304 32004 77691 32004 line -69304 32004 70396 32004 line -63409 32004 64396 32004 line -20108 32004 22591 32004 line -17977 32004 18636 32004 line -75078 32260 79819 32260 line -69078 32260 70396 32260 line -63421 32260 64396 32260 line -17977 32260 22591 32260 line -74698 32516 79819 32516 line -68698 32516 70396 32516 line -63498 32516 64396 32516 line -17977 32516 22591 32516 line -73604 32772 79819 32772 line -67637 32772 70396 32772 line -63508 32772 64396 32772 line -17977 32772 22591 32772 line -73604 33028 79819 33028 line -67893 33028 70396 33028 line -63444 33028 64396 33028 line -20289 33028 22591 33028 line -17977 33028 18529 33028 line -73604 33284 79819 33284 line -63431 33284 64396 33284 line -20289 33284 22602 33284 line -17977 33284 18529 33284 line -73604 33540 79819 33540 line -63504 33540 64396 33540 line -20289 33540 22672 33540 line -17977 33540 18529 33540 line -73543 33796 79819 33796 line -20289 33796 22843 33796 line -17977 33796 18529 33796 line -73328 34052 79819 34052 line -20289 34052 23096 34052 line -17977 34052 18529 34052 line -72909 34308 79819 34308 line -20289 34308 23352 34308 line -17977 34308 18529 34308 line -72909 34564 79819 34564 line -20289 34564 23608 34564 line -17977 34564 18529 34564 line -73392 34820 79819 34820 line -20289 34820 23864 34820 line -17977 34820 18529 34820 line -73724 35076 79819 35076 line -20289 35076 24120 35076 line -17977 35076 18529 35076 line -73872 35332 79819 35332 line -20289 35332 24376 35332 line -17977 35332 18529 35332 line -73931 35588 79819 35588 line -20289 35588 24632 35588 line -17977 35588 18529 35588 line -73918 35844 79819 35844 line -20289 35844 24888 35844 line -17977 35844 18529 35844 line -73833 36100 79819 36100 line -20289 36100 25144 36100 line -17977 36100 18529 36100 line -73635 36356 79819 36356 line -20289 36356 25400 36356 line -17977 36356 18529 36356 line -72292 36612 79819 36612 line -20289 36612 25656 36612 line -17977 36612 18529 36612 line -69663 36868 79819 36868 line -20289 36868 25912 36868 line -17977 36868 18529 36868 line -69570 37124 79819 37124 line -20289 37124 26168 37124 line -17977 37124 18529 37124 line -69361 37380 79819 37380 line -20289 37380 26424 37380 line -17977 37380 18529 37380 line -68159 37636 79819 37636 line -20289 37636 26591 37636 line -17977 37636 18529 37636 line -68256 37892 79819 37892 line -20289 37892 26591 37892 line -17977 37892 18529 37892 line -68975 38148 79819 38148 line -20289 38148 26591 38148 line -17977 38148 18529 38148 line -69270 38404 79819 38404 line -20289 38404 26591 38404 line -17977 38404 18529 38404 line -69526 38660 79819 38660 line -20289 38660 26591 38660 line -17977 38660 18529 38660 line -77678 38916 79819 38916 line -69757 38916 73322 38916 line -20289 38916 26591 38916 line -17977 38916 18529 38916 line -77860 39172 79819 39172 line -69869 39172 73139 39172 line -20289 39172 26591 39172 line -17977 39172 18529 39172 line -77909 39428 79819 39428 line -69909 39428 73091 39428 line -20289 39428 26591 39428 line -17977 39428 18529 39428 line -77909 39684 79819 39684 line -69995 39684 73091 39684 line -63316 39684 63419 39684 line -20289 39684 26591 39684 line -17977 39684 18529 39684 line -77909 39940 79819 39940 line -70009 39940 73091 39940 line -63405 39940 64616 39940 line -20289 39940 26591 39940 line -17977 39940 18529 39940 line -77909 40196 79819 40196 line -70009 40196 73091 40196 line -63433 40196 64872 40196 line -20289 40196 26591 40196 line -17977 40196 18529 40196 line -77909 40452 79819 40452 line -70009 40452 73091 40452 line -63394 40452 65128 40452 line -20289 40452 26591 40452 line -17977 40452 18529 40452 line -77909 40708 79819 40708 line -69985 40708 73091 40708 line -63264 40708 65384 40708 line -20289 40708 26591 40708 line -17977 40708 18529 40708 line -77909 40964 79819 40964 line -69986 40964 73091 40964 line -62994 40964 65640 40964 line -20289 40964 26591 40964 line -17977 40964 18529 40964 line -77909 41220 79819 41220 line -70007 41220 73091 41220 line -62434 41220 65896 41220 line -20289 41220 26591 41220 line -17977 41220 18529 41220 line -77909 41476 79819 41476 line -69965 41476 73091 41476 line -65829 41476 66152 41476 line -20289 41476 26591 41476 line -17977 41476 18529 41476 line -77909 41732 79819 41732 line -69908 41732 73091 41732 line -66096 41732 66408 41732 line -20289 41732 26591 41732 line -17977 41732 18529 41732 line -77909 41988 79819 41988 line -69992 41988 73091 41988 line -66352 41988 66664 41988 line -20289 41988 26591 41988 line -17977 41988 18529 41988 line -77909 42244 79819 42244 line -70007 42244 73091 42244 line -66608 42244 66920 42244 line -20289 42244 26591 42244 line -17977 42244 18529 42244 line -77909 42500 79819 42500 line -69955 42500 73091 42500 line -66864 42500 67176 42500 line -20289 42500 26591 42500 line -17977 42500 18529 42500 line -77909 42756 79819 42756 line -69821 42756 73091 42756 line -67120 42756 67433 42756 line -20289 42756 26591 42756 line -17977 42756 18529 42756 line -77904 43012 79819 43012 line -69555 43012 73096 43012 line -67376 43012 68446 43012 line -20289 43012 26591 43012 line -17977 43012 18529 43012 line -77811 43268 79819 43268 line -67632 43268 73190 43268 line -20289 43268 26591 43268 line -17977 43268 18529 43268 line -77515 43524 79819 43524 line -67888 43524 73486 43524 line -20289 43524 26591 43524 line -17977 43524 18529 43524 line -68144 43780 79819 43780 line -20289 43780 26591 43780 line -17977 43780 18529 43780 line -68400 44036 79819 44036 line -20289 44036 26591 44036 line -17977 44036 18529 44036 line -68656 44292 79819 44292 line -20289 44292 26591 44292 line -17977 44292 18529 44292 line -68912 44548 79819 44548 line -20289 44548 26591 44548 line -17977 44548 18529 44548 line -69168 44804 79819 44804 line -20289 44804 26591 44804 line -17977 44804 18529 44804 line -69424 45060 79819 45060 line -20289 45060 26591 45060 line -17977 45060 18529 45060 line -71785 45316 79819 45316 line -69680 45316 70712 45316 line -20289 45316 26591 45316 line -17977 45316 18529 45316 line -72062 45572 79819 45572 line -69936 45572 70436 45572 line -20289 45572 26591 45572 line -17977 45572 18529 45572 line -72201 45828 79819 45828 line -70192 45828 70300 45828 line -20289 45828 26591 45828 line -17977 45828 18529 45828 line -72255 46084 79819 46084 line -20289 46084 26591 46084 line -17977 46084 18529 46084 line -72245 46340 79819 46340 line -20289 46340 26591 46340 line -17977 46340 18529 46340 line -72165 46596 79819 46596 line -20289 46596 26591 46596 line -17977 46596 18529 46596 line -71994 46852 79819 46852 line -20289 46852 26591 46852 line -17977 46852 18529 46852 line -72087 47108 79819 47108 line -20289 47108 26591 47108 line -17977 47108 18529 47108 line -72214 47364 79819 47364 line -20289 47364 26591 47364 line -17977 47364 18529 47364 line -72256 47620 79819 47620 line -20289 47620 26591 47620 line -17977 47620 18529 47620 line -72238 47876 79819 47876 line -20289 47876 26591 47876 line -17977 47876 18529 47876 line -72150 48132 79819 48132 line -20289 48132 26591 48132 line -17977 48132 18529 48132 line -71958 48388 79819 48388 line -20289 48388 26591 48388 line -17977 48388 18529 48388 line -71520 48644 79819 48644 line -70909 48644 70975 48644 line -20289 48644 26591 48644 line -17977 48644 18529 48644 line -70909 48900 79819 48900 line -20289 48900 26591 48900 line -17977 48900 18529 48900 line -70909 49156 79819 49156 line -20289 49156 26591 49156 line -17977 49156 18529 49156 line -70909 49412 79819 49412 line -20289 49412 26591 49412 line -17977 49412 18529 49412 line -70909 49668 79819 49668 line -20289 49668 26591 49668 line -17977 49668 18529 49668 line -70909 49924 79819 49924 line -20289 49924 26591 49924 line -17977 49924 18529 49924 line -70909 50180 79819 50180 line -20289 50180 26591 50180 line -17977 50180 18529 50180 line -70909 50436 79819 50436 line -20289 50436 26591 50436 line -17977 50436 18529 50436 line -70909 50692 79819 50692 line -20289 50692 26591 50692 line -17977 50692 18529 50692 line -70909 50948 79819 50948 line -20289 50948 26591 50948 line -17977 50948 18529 50948 line -70909 51204 79819 51204 line -20289 51204 26591 51204 line -17977 51204 18529 51204 line -70909 51460 79819 51460 line -20289 51460 26591 51460 line -17977 51460 18529 51460 line -70909 51716 79819 51716 line -20289 51716 26591 51716 line -17977 51716 18529 51716 line -70909 51972 79819 51972 line -20289 51972 26591 51972 line -17977 51972 18529 51972 line -70909 52228 79819 52228 line -20289 52228 26591 52228 line -17977 52228 18529 52228 line -71883 52484 79819 52484 line -20289 52484 26591 52484 line -17977 52484 18529 52484 line -72080 52740 79819 52740 line -20289 52740 26591 52740 line -17977 52740 18529 52740 line -72168 52996 79819 52996 line -20289 52996 26591 52996 line -17977 52996 18529 52996 line -72183 53252 79819 53252 line -20289 53252 26591 53252 line -17977 53252 18529 53252 line -72121 53508 79819 53508 line -20289 53508 26591 53508 line -17977 53508 18529 53508 line -71977 53764 79819 53764 line -20289 53764 26591 53764 line -17977 53764 18529 53764 line -71639 54020 79819 54020 line -20289 54020 26591 54020 line -17977 54020 18529 54020 line -71159 54276 79819 54276 line -20289 54276 26591 54276 line -17977 54276 18529 54276 line -71159 54532 79819 54532 line -20289 54532 26591 54532 line -17977 54532 18529 54532 line -71159 54788 79819 54788 line -20289 54788 26591 54788 line -17977 54788 18529 54788 line -71159 55044 79819 55044 line -20289 55044 26591 55044 line -17977 55044 18529 55044 line -71159 55300 79819 55300 line -20289 55300 26591 55300 line -17977 55300 18529 55300 line -71239 55556 79819 55556 line -20289 55556 26591 55556 line -17977 55556 18529 55556 line -71389 55812 79819 55812 line -20289 55812 26591 55812 line -17977 55812 18529 55812 line -71455 56068 79819 56068 line -20289 56068 26591 56068 line -17977 56068 18529 56068 line -71446 56324 79819 56324 line -20289 56324 26591 56324 line -17977 56324 18529 56324 line -71368 56580 79819 56580 line -20289 56580 26554 56580 line -17977 56580 18529 56580 line -71189 56836 79819 56836 line -20289 56836 26298 56836 line -17977 56836 18529 56836 line -70776 57092 79819 57092 line -69816 57092 70226 57092 line -20289 57092 26042 57092 line -17977 57092 18529 57092 line -69816 57348 79819 57348 line -20289 57348 25786 57348 line -17977 57348 18529 57348 line -69816 57604 79819 57604 line -20289 57604 25530 57604 line -17977 57604 18529 57604 line -69816 57860 79819 57860 line -20289 57860 25274 57860 line -17977 57860 18529 57860 line -69816 58116 79819 58116 line -20289 58116 25018 58116 line -17977 58116 18529 58116 line -69816 58372 79819 58372 line -20289 58372 24762 58372 line -17977 58372 18529 58372 line -69816 58628 79819 58628 line -20289 58628 24506 58628 line -17977 58628 18529 58628 line -69816 58884 79819 58884 line -20289 58884 24250 58884 line -17977 58884 18529 58884 line -69816 59140 79819 59140 line -20289 59140 24015 59140 line -17977 59140 18529 59140 line -69816 59396 79819 59396 line -20289 59396 23887 59396 line -17977 59396 18529 59396 line -69778 59652 79819 59652 line -20289 59652 23842 59652 line -17977 59652 18529 59652 line -69651 59908 79819 59908 line -20289 59908 23841 59908 line -17977 59908 18529 59908 line -69410 60164 79819 60164 line -20289 60164 23841 60164 line -17977 60164 18529 60164 line -69154 60420 79819 60420 line -20289 60420 23841 60420 line -17977 60420 18529 60420 line -68898 60676 79819 60676 line -20289 60676 23841 60676 line -17977 60676 18529 60676 line -68642 60932 79819 60932 line -20289 60932 23841 60932 line -17977 60932 18529 60932 line -78644 61188 79819 61188 line -69033 61188 78192 61188 line -20289 61188 23841 61188 line -17977 61188 18529 61188 line -79277 61444 79819 61444 line -69305 61444 77576 61444 line -20222 61444 23841 61444 line -17977 61444 18521 61444 line -79554 61700 79819 61700 line -69454 61700 77295 61700 line -64729 61700 64745 61700 line -20499 61700 23841 61700 line -17977 61700 18240 61700 line -79721 61956 79819 61956 line -69532 61956 77124 61956 line -66954 61956 67191 61956 line -65954 61956 66048 61956 line -64808 61956 65048 61956 line -20666 61956 23841 61956 line -17977 61956 18069 61956 line -69549 62212 77021 62212 line -64825 62212 67174 62212 line -20770 62212 23841 62212 line -69516 62468 76971 62468 line -64792 62468 67210 62468 line -20824 62468 23785 62468 line -69420 62724 76968 62724 line -64696 62724 67306 62724 line -20828 62724 23785 62724 line -69234 62980 77008 62980 line -64510 62980 67490 62980 line -23330 62980 23798 62980 line -20788 62980 21973 62980 line -79754 63236 79819 63236 line -68895 63236 77097 63236 line -64171 63236 67826 63236 line -23584 63236 23841 63236 line -20699 63236 21712 63236 line -17977 63236 18042 63236 line -79605 63492 79819 63492 line -72839 63492 77247 63492 line -71839 63492 72156 63492 line -64225 63492 71156 63492 line -23726 63492 23868 63492 line -20550 63492 21574 63492 line -17977 63492 18192 63492 line -79373 63748 79819 63748 line -73227 63748 77480 63748 line -56797 63748 56974 63748 line -48547 63748 48724 63748 line -40297 63748 40474 63748 line -32047 63748 32224 63748 line -23797 63748 23974 63748 line -20318 63748 21504 63748 line -17977 63748 18425 63748 line -78924 64004 79819 64004 line -73396 64004 77930 64004 line -56807 64004 57188 64004 line -48557 64004 48938 64004 line -40307 64004 40688 64004 line -32057 64004 32438 64004 line -23807 64004 24188 64004 line -19869 64004 21494 64004 line -17977 64004 18875 64004 line -73476 64260 79819 64260 line -60614 64260 60739 64260 line -56763 64260 57288 64260 line -48513 64260 48991 64260 line -40263 64260 40741 64260 line -32013 64260 32491 64260 line -23763 64260 24241 64260 line -17977 64260 21539 64260 line -73487 64516 79819 64516 line -62845 64516 62941 64516 line -60423 64516 60855 64516 line -56645 64516 57479 64516 line -54595 64516 54655 64516 line -48395 64516 49014 64516 line -46345 64516 46405 64516 line -40145 64516 40764 64516 line -38095 64516 38155 64516 line -31895 64516 32514 64516 line -29845 64516 29905 64516 line -23645 64516 24264 64516 line -17977 64516 21655 64516 line -73424 64772 79819 64772 line -62636 64772 63197 64772 line -59929 64772 61065 64772 line -59129 64772 59569 64772 line -58329 64772 58769 64772 line -56436 64772 57969 64772 line -54386 64772 54865 64772 line -48186 64772 49116 64772 line -46136 64772 46615 64772 line -39936 64772 40866 64772 line -37886 64772 38365 64772 line -31686 64772 32616 64772 line -29636 64772 30115 64772 line -23436 64772 24366 64772 line -17977 64772 21865 64772 line -73283 65028 79819 65028 line -62204 65028 63460 65028 line -56004 65028 61502 65028 line -53954 65028 55302 65028 line -52928 65028 53252 65028 line -47754 65028 49322 65028 line -45704 65028 47052 65028 line -44923 65028 45001 65028 line -39504 65028 41072 65028 line -37454 65028 38802 65028 line -36428 65028 36752 65028 line -31254 65028 32822 65028 line -29204 65028 30552 65028 line -28178 65028 28502 65028 line -23004 65028 24572 65028 line -17977 65028 22302 65028 line -72986 65284 79819 65284 line -71986 65284 72015 65284 line -52672 65284 71016 65284 line -44672 65284 49578 65284 line -36172 65284 41328 65284 line -27922 65284 33078 65284 line -17977 65284 24828 65284 line -52251 65540 79819 65540 line -44251 65540 50001 65540 line -35751 65540 41751 65540 line -27500 65540 33501 65540 line -17977 65540 25251 65540 line -17977 65796 79819 65796 line -newpath 79819 27576 moveto -79819 30292 lineto -79816 30278 lineto -79700 30017 lineto -79535 29783 lineto -79328 29586 lineto -79086 29432 lineto -78819 29329 lineto -78537 29279 lineto -78251 29285 lineto -77972 29347 lineto -77710 29461 lineto -77475 29625 lineto -77276 29830 lineto -77121 30071 lineto -77016 30337 lineto -76964 30618 lineto -76968 30904 lineto -77028 31184 lineto -77140 31447 lineto -77302 31683 lineto -77506 31884 lineto -77746 32040 lineto -78011 32147 lineto -78292 32201 lineto -78578 32199 lineto -78859 32141 lineto -79122 32031 lineto -79360 31871 lineto -79561 31668 lineto -79719 31429 lineto -79819 31187 lineto -79819 62182 lineto -79816 62168 lineto -79700 61907 lineto -79535 61673 lineto -79328 61476 lineto -79086 61322 lineto -78819 61219 lineto -78537 61169 lineto -78251 61175 lineto -77972 61237 lineto -77710 61351 lineto -77475 61515 lineto -77276 61720 lineto -77121 61961 lineto -77016 62227 lineto -76964 62508 lineto -76968 62794 lineto -77028 63074 lineto -77140 63337 lineto -77302 63573 lineto -77506 63774 lineto -77746 63930 lineto -78011 64037 lineto -78292 64091 lineto -78578 64089 lineto -78859 64031 lineto -79122 63921 lineto -79360 63761 lineto -79561 63558 lineto -79719 63319 lineto -79819 63077 lineto -79819 65796 lineto -17977 65796 lineto -17977 63084 lineto -18085 63337 lineto -18247 63573 lineto -18451 63774 lineto -18691 63930 lineto -18956 64037 lineto -19237 64091 lineto -19523 64089 lineto -19804 64031 lineto -20067 63921 lineto -20305 63761 lineto -20506 63558 lineto -20664 63319 lineto -20773 63055 lineto -20829 62774 lineto -20824 62447 lineto -20761 62168 lineto -20645 61907 lineto -20480 61673 lineto -20273 61476 lineto -20046 61332 lineto -20289 61332 lineto -20289 32906 lineto -18529 32906 lineto -18529 61332 lineto -18698 61332 lineto -18655 61351 lineto -18420 61515 lineto -18221 61720 lineto -18066 61961 lineto -17977 62187 lineto -17977 46686 lineto -17977 31194 lineto -18085 31447 lineto -18247 31683 lineto -18451 31884 lineto -18691 32040 lineto -18956 32147 lineto -19237 32201 lineto -19523 32199 lineto -19804 32141 lineto -20067 32031 lineto -20305 31871 lineto -20506 31668 lineto -20664 31429 lineto -20773 31165 lineto -20829 30884 lineto -20824 30557 lineto -20761 30278 lineto -20645 30017 lineto -20480 29783 lineto -20273 29586 lineto -20031 29432 lineto -19764 29329 lineto -19482 29279 lineto -19196 29285 lineto -18917 29347 lineto -18655 29461 lineto -18420 29625 lineto -18221 29830 lineto -18066 30071 lineto -17977 30297 lineto -17977 27576 lineto -58991 27576 lineto -58991 27761 lineto -57497 27761 lineto -57487 27761 lineto -57401 27771 lineto -57320 27779 lineto -57315 27781 lineto -57311 27781 lineto -57171 27826 lineto -57151 27832 lineto -57150 27833 lineto -57142 27835 lineto -57066 27877 lineto -56994 27914 lineto -56988 27919 lineto -56986 27920 lineto -56955 27946 lineto -56857 28027 lineto -56374 28510 lineto -56367 28503 lineto -56175 28382 lineto -55963 28299 lineto -55740 28260 lineto -55513 28265 lineto -55291 28313 lineto -55083 28404 lineto -54896 28534 lineto -54738 28697 lineto -54624 28874 lineto -54612 28846 lineto -54481 28660 lineto -54317 28503 lineto -54125 28382 lineto -53913 28299 lineto -53690 28260 lineto -53463 28265 lineto -53241 28313 lineto -53033 28404 lineto -52846 28534 lineto -52688 28697 lineto -52565 28888 lineto -52482 29099 lineto -52441 29322 lineto -52444 29549 lineto -52486 29751 lineto -52350 29751 lineto -52347 29743 lineto -52338 29710 lineto -52336 29708 lineto -52335 29702 lineto -52281 29605 lineto -52255 29554 lineto -52253 29552 lineto -52250 29546 lineto -52181 29465 lineto -52142 29417 lineto -52043 29319 lineto -52023 29223 lineto -52009 29191 lineto -52009 29016 lineto -52009 29007 lineto -51989 28831 lineto -51947 28703 lineto -51938 28670 lineto -51936 28668 lineto -51935 28662 lineto -51881 28565 lineto -51855 28514 lineto -51853 28512 lineto -51850 28506 lineto -51781 28425 lineto -51742 28377 lineto -51391 28026 lineto -51391 28025 lineto -51390 28025 lineto -51384 28018 lineto -51318 27967 lineto -51253 27913 lineto -51247 27911 lineto -51245 27908 lineto -51165 27867 lineto -51096 27830 lineto -51092 27830 lineto -51087 27826 lineto -50996 27800 lineto -50927 27778 lineto -50922 27778 lineto -50917 27776 lineto -50820 27768 lineto -50750 27761 lineto -50741 27761 lineto -49247 27761 lineto -49237 27761 lineto -49151 27771 lineto -49070 27779 lineto -49065 27781 lineto -49061 27781 lineto -48921 27826 lineto -48901 27832 lineto -48900 27833 lineto -48892 27835 lineto -48816 27877 lineto -48744 27914 lineto -48738 27919 lineto -48736 27920 lineto -48705 27946 lineto -48607 28027 lineto -48124 28510 lineto -48117 28503 lineto -47925 28382 lineto -47713 28299 lineto -47490 28260 lineto -47263 28265 lineto -47041 28313 lineto -46833 28404 lineto -46646 28534 lineto -46488 28697 lineto -46374 28874 lineto -46362 28846 lineto -46231 28660 lineto -46067 28503 lineto -45875 28382 lineto -45663 28299 lineto -45440 28260 lineto -45213 28265 lineto -44991 28313 lineto -44783 28404 lineto -44596 28534 lineto -44438 28697 lineto -44315 28888 lineto -44232 29099 lineto -44191 29322 lineto -44194 29549 lineto -44236 29751 lineto -44100 29751 lineto -44097 29743 lineto -44088 29710 lineto -44086 29708 lineto -44085 29702 lineto -44031 29605 lineto -44005 29554 lineto -44003 29552 lineto -44000 29546 lineto -43931 29465 lineto -43892 29417 lineto -43793 29319 lineto -43773 29223 lineto -43759 29191 lineto -43759 29016 lineto -43759 29007 lineto -43739 28831 lineto -43697 28703 lineto -43688 28670 lineto -43686 28668 lineto -43685 28662 lineto -43631 28564 lineto -43605 28514 lineto -43603 28512 lineto -43600 28506 lineto -43531 28425 lineto -43492 28377 lineto -43141 28026 lineto -43141 28025 lineto -43140 28025 lineto -43134 28018 lineto -43068 27967 lineto -43003 27913 lineto -42997 27911 lineto -42995 27908 lineto -42915 27867 lineto -42846 27830 lineto -42842 27830 lineto -42837 27826 lineto -42746 27800 lineto -42677 27778 lineto -42672 27778 lineto -42667 27776 lineto -42570 27768 lineto -42500 27761 lineto -42491 27761 lineto -40997 27761 lineto -40987 27761 lineto -40901 27771 lineto -40820 27779 lineto -40815 27781 lineto -40811 27781 lineto -40672 27826 lineto -40651 27832 lineto -40650 27833 lineto -40642 27835 lineto -40566 27877 lineto -40494 27914 lineto -40488 27919 lineto -40486 27920 lineto -40455 27946 lineto -40357 28027 lineto -39874 28510 lineto -39867 28503 lineto -39675 28382 lineto -39463 28299 lineto -39240 28260 lineto -39013 28265 lineto -38791 28313 lineto -38583 28404 lineto -38396 28534 lineto -38238 28697 lineto -38124 28874 lineto -38112 28846 lineto -37981 28660 lineto -37817 28503 lineto -37625 28382 lineto -37413 28299 lineto -37190 28260 lineto -36963 28265 lineto -36741 28313 lineto -36533 28404 lineto -36346 28534 lineto -36188 28697 lineto -36065 28888 lineto -35982 29099 lineto -35941 29322 lineto -35944 29549 lineto -35986 29751 lineto -35850 29751 lineto -35847 29743 lineto -35838 29710 lineto -35836 29708 lineto -35835 29702 lineto -35781 29604 lineto -35755 29554 lineto -35753 29552 lineto -35750 29546 lineto -35681 29465 lineto -35642 29417 lineto -35543 29319 lineto -35523 29223 lineto -35509 29191 lineto -35509 29016 lineto -35509 29007 lineto -35489 28831 lineto -35447 28703 lineto -35438 28670 lineto -35436 28668 lineto -35435 28662 lineto -35381 28564 lineto -35355 28514 lineto -35353 28512 lineto -35350 28506 lineto -35281 28425 lineto -35242 28377 lineto -34891 28026 lineto -34891 28025 lineto -34890 28025 lineto -34884 28018 lineto -34818 27967 lineto -34753 27913 lineto -34747 27911 lineto -34745 27908 lineto -34665 27867 lineto -34596 27830 lineto -34592 27830 lineto -34587 27826 lineto -34496 27800 lineto -34427 27778 lineto -34422 27778 lineto -34417 27776 lineto -34320 27768 lineto -34250 27761 lineto -34241 27761 lineto -32747 27761 lineto -32737 27761 lineto -32651 27771 lineto -32570 27779 lineto -32565 27781 lineto -32561 27781 lineto -32422 27826 lineto -32401 27832 lineto -32400 27833 lineto -32392 27835 lineto -32316 27877 lineto -32244 27914 lineto -32238 27919 lineto -32236 27920 lineto -32205 27946 lineto -32107 28027 lineto -31624 28510 lineto -31617 28503 lineto -31425 28382 lineto -31213 28299 lineto -30990 28260 lineto -30763 28265 lineto -30541 28313 lineto -30333 28404 lineto -30146 28534 lineto -29988 28697 lineto -29874 28874 lineto -29862 28846 lineto -29731 28660 lineto -29567 28503 lineto -29375 28382 lineto -29163 28299 lineto -28940 28260 lineto -28713 28265 lineto -28491 28313 lineto -28283 28404 lineto -28096 28534 lineto -27938 28697 lineto -27815 28888 lineto -27732 29099 lineto -27691 29322 lineto -27694 29549 lineto -27736 29751 lineto -27600 29751 lineto -27597 29743 lineto -27588 29710 lineto -27586 29708 lineto -27585 29702 lineto -27531 29605 lineto -27505 29554 lineto -27503 29552 lineto -27500 29546 lineto -27431 29465 lineto -27392 29417 lineto -27293 29319 lineto -27273 29223 lineto -27259 29191 lineto -27259 29016 lineto -27259 29007 lineto -27239 28831 lineto -27197 28703 lineto -27188 28670 lineto -27186 28668 lineto -27185 28662 lineto -27131 28565 lineto -27105 28514 lineto -27103 28512 lineto -27100 28506 lineto -27031 28425 lineto -26992 28377 lineto -26641 28026 lineto -26641 28025 lineto -26640 28025 lineto -26634 28018 lineto -26568 27967 lineto -26503 27913 lineto -26497 27911 lineto -26495 27908 lineto -26415 27867 lineto -26346 27830 lineto -26342 27830 lineto -26337 27826 lineto -26246 27800 lineto -26177 27778 lineto -26172 27778 lineto -26167 27776 lineto -26070 27768 lineto -26000 27761 lineto -25991 27761 lineto -24497 27761 lineto -24487 27761 lineto -24401 27771 lineto -24320 27779 lineto -24315 27781 lineto -24311 27781 lineto -24172 27826 lineto -24151 27832 lineto -24150 27833 lineto -24142 27835 lineto -24066 27877 lineto -23994 27914 lineto -23988 27919 lineto -23986 27920 lineto -23955 27946 lineto -23857 28027 lineto -23374 28510 lineto -23367 28503 lineto -23175 28382 lineto -22963 28299 lineto -22740 28260 lineto -22513 28265 lineto -22291 28313 lineto -22083 28404 lineto -21896 28534 lineto -21738 28697 lineto -21615 28888 lineto -21532 29099 lineto -21491 29322 lineto -21494 29549 lineto -21541 29771 lineto -21630 29980 lineto -21758 30168 lineto -21921 30327 lineto -22111 30451 lineto -22321 30536 lineto -22544 30579 lineto -22591 30579 lineto -22591 33173 lineto -22591 33183 lineto -22600 33269 lineto -22609 33350 lineto -22610 33356 lineto -22611 33359 lineto -22631 33424 lineto -22661 33519 lineto -22663 33525 lineto -22665 33528 lineto -22690 33575 lineto -22740 33669 lineto -22740 62760 lineto -22513 62765 lineto -22291 62813 lineto -22083 62904 lineto -21896 63034 lineto -21738 63197 lineto -21615 63388 lineto -21532 63599 lineto -21491 63822 lineto -21494 64049 lineto -21541 64271 lineto -21630 64480 lineto -21758 64668 lineto -21921 64827 lineto -22111 64951 lineto -22321 65036 lineto -22544 65079 lineto -22771 65077 lineto -22994 65032 lineto -23203 64944 lineto -23391 64817 lineto -23551 64656 lineto -23677 64467 lineto -23764 64257 lineto -23808 64034 lineto -23804 63775 lineto -23754 63553 lineto -23662 63346 lineto -23531 63160 lineto -23367 63003 lineto -23175 62882 lineto -22963 62799 lineto -22740 62760 lineto -22740 33669 lineto -22744 33676 lineto -22748 33682 lineto -22750 33684 lineto -22775 33715 lineto -22857 33813 lineto -26591 37547 lineto -26591 56543 lineto -24105 59029 lineto -24098 59036 lineto -24046 59102 lineto -23993 59167 lineto -23990 59173 lineto -23988 59175 lineto -23946 59255 lineto -23910 59324 lineto -23909 59328 lineto -23906 59333 lineto -23879 59424 lineto -23858 59493 lineto -23857 59498 lineto -23856 59503 lineto -23847 59600 lineto -23841 59670 lineto -23841 59679 lineto -23841 62212 lineto -23823 62255 lineto -23786 62440 lineto -23785 62743 lineto -23787 62933 lineto -23827 63117 lineto -23841 63150 lineto -23841 63283 lineto -23841 63293 lineto -23850 63379 lineto -23859 63460 lineto -23860 63466 lineto -23861 63469 lineto -23881 63535 lineto -23911 63629 lineto -23913 63635 lineto -23915 63638 lineto -23940 63685 lineto -23994 63786 lineto -23998 63792 lineto -24000 63794 lineto -24025 63825 lineto -24107 63923 lineto -24206 64023 lineto -24227 64117 lineto -24241 64150 lineto -24241 64323 lineto -24241 64333 lineto -24250 64419 lineto -24259 64500 lineto -24260 64506 lineto -24261 64509 lineto -24281 64574 lineto -24311 64669 lineto -24313 64675 lineto -24315 64678 lineto -24340 64725 lineto -24394 64826 lineto -24398 64832 lineto -24400 64834 lineto -24425 64865 lineto -24507 64963 lineto -24854 65310 lineto -24859 65315 lineto -24864 65320 lineto -24866 65321 lineto -24909 65357 lineto -24997 65427 lineto -24999 65429 lineto -25004 65432 lineto -25085 65474 lineto -25154 65510 lineto -25159 65512 lineto -25162 65513 lineto -25201 65525 lineto -25323 65562 lineto -25331 65563 lineto -25332 65563 lineto -25343 65565 lineto -25500 65579 lineto -27253 65579 lineto -27263 65579 lineto -27348 65570 lineto -27430 65561 lineto -27435 65560 lineto -27439 65559 lineto -27503 65539 lineto -27599 65509 lineto -27604 65507 lineto -27608 65505 lineto -27654 65480 lineto -27756 65426 lineto -27761 65422 lineto -27764 65420 lineto -27794 65395 lineto -27893 65313 lineto -28277 64929 lineto -28311 64951 lineto -28521 65036 lineto -28744 65079 lineto -28971 65077 lineto -29194 65032 lineto -29403 64944 lineto -29591 64817 lineto -29751 64656 lineto -29875 64470 lineto -29880 64480 lineto -30008 64668 lineto -30171 64827 lineto -30361 64951 lineto -30571 65036 lineto -30794 65079 lineto -31021 65077 lineto -31244 65032 lineto -31453 64944 lineto -31641 64817 lineto -31801 64656 lineto -31927 64467 lineto -32014 64257 lineto -32058 64034 lineto -32054 63775 lineto -32012 63589 lineto -32148 63589 lineto -32161 63629 lineto -32163 63635 lineto -32165 63638 lineto -32190 63685 lineto -32244 63786 lineto -32248 63792 lineto -32250 63794 lineto -32275 63825 lineto -32357 63923 lineto -32456 64023 lineto -32477 64117 lineto -32491 64150 lineto -32491 64323 lineto -32491 64333 lineto -32500 64419 lineto -32509 64500 lineto -32510 64506 lineto -32511 64509 lineto -32531 64575 lineto -32561 64669 lineto -32563 64675 lineto -32565 64678 lineto -32590 64725 lineto -32644 64826 lineto -32648 64832 lineto -32650 64834 lineto -32675 64865 lineto -32757 64963 lineto -33104 65310 lineto -33109 65315 lineto -33114 65320 lineto -33116 65321 lineto -33159 65357 lineto -33247 65427 lineto -33249 65429 lineto -33254 65432 lineto -33335 65474 lineto -33404 65510 lineto -33409 65512 lineto -33412 65513 lineto -33451 65525 lineto -33573 65562 lineto -33581 65563 lineto -33582 65563 lineto -33593 65565 lineto -33750 65579 lineto -35503 65579 lineto -35513 65579 lineto -35598 65570 lineto -35680 65561 lineto -35685 65560 lineto -35689 65559 lineto -35754 65539 lineto -35849 65509 lineto -35854 65507 lineto -35858 65505 lineto -35904 65480 lineto -36006 65426 lineto -36011 65422 lineto -36014 65420 lineto -36044 65395 lineto -36143 65313 lineto -36527 64929 lineto -36561 64951 lineto -36771 65036 lineto -36994 65079 lineto -37221 65077 lineto -37444 65032 lineto -37653 64944 lineto -37841 64817 lineto -38001 64656 lineto -38125 64470 lineto -38130 64480 lineto -38258 64668 lineto -38421 64827 lineto -38611 64951 lineto -38821 65036 lineto -39044 65079 lineto -39271 65077 lineto -39494 65032 lineto -39703 64944 lineto -39891 64817 lineto -40051 64656 lineto -40177 64467 lineto -40264 64257 lineto -40308 64034 lineto -40304 63775 lineto -40262 63589 lineto -40398 63589 lineto -40411 63629 lineto -40413 63635 lineto -40415 63638 lineto -40440 63685 lineto -40494 63786 lineto -40498 63792 lineto -40500 63794 lineto -40525 63825 lineto -40607 63923 lineto -40706 64023 lineto -40727 64117 lineto -40741 64150 lineto -40741 64323 lineto -40741 64333 lineto -40750 64419 lineto -40759 64500 lineto -40760 64506 lineto -40761 64509 lineto -40781 64574 lineto -40811 64669 lineto -40813 64675 lineto -40815 64678 lineto -40840 64725 lineto -40894 64826 lineto -40898 64832 lineto -40900 64834 lineto -40925 64865 lineto -41007 64963 lineto -41354 65310 lineto -41359 65315 lineto -41364 65320 lineto -41366 65321 lineto -41409 65357 lineto -41497 65427 lineto -41499 65429 lineto -41504 65432 lineto -41585 65474 lineto -41654 65510 lineto -41659 65512 lineto -41662 65513 lineto -41701 65525 lineto -41823 65562 lineto -41831 65563 lineto -41832 65563 lineto -41843 65565 lineto -42000 65579 lineto -44003 65579 lineto -44013 65579 lineto -44098 65570 lineto -44180 65561 lineto -44185 65560 lineto -44189 65559 lineto -44254 65539 lineto -44349 65509 lineto -44354 65507 lineto -44358 65505 lineto -44404 65480 lineto -44506 65426 lineto -44511 65422 lineto -44514 65420 lineto -44544 65395 lineto -44643 65313 lineto -44895 65061 lineto -44902 65054 lineto -44941 65004 lineto -45021 65036 lineto -45244 65079 lineto -45471 65077 lineto -45694 65032 lineto -45903 64944 lineto -46091 64817 lineto -46251 64656 lineto -46375 64470 lineto -46380 64480 lineto -46508 64668 lineto -46671 64827 lineto -46861 64951 lineto -47071 65036 lineto -47294 65079 lineto -47521 65077 lineto -47744 65032 lineto -47953 64944 lineto -48141 64817 lineto -48301 64656 lineto -48427 64467 lineto -48514 64257 lineto -48558 64034 lineto -48554 63775 lineto -48512 63589 lineto -48648 63589 lineto -48661 63629 lineto -48663 63635 lineto -48665 63638 lineto -48690 63685 lineto -48744 63786 lineto -48748 63792 lineto -48750 63794 lineto -48775 63825 lineto -48857 63923 lineto -48956 64023 lineto -48977 64117 lineto -48991 64150 lineto -48991 64323 lineto -48991 64333 lineto -49000 64419 lineto -49009 64500 lineto -49010 64506 lineto -49011 64509 lineto -49031 64574 lineto -49061 64669 lineto -49063 64675 lineto -49065 64678 lineto -49090 64725 lineto -49144 64826 lineto -49148 64832 lineto -49150 64834 lineto -49175 64865 lineto -49257 64963 lineto -49604 65310 lineto -49609 65315 lineto -49614 65320 lineto -49616 65321 lineto -49659 65357 lineto -49747 65427 lineto -49749 65429 lineto -49754 65432 lineto -49835 65474 lineto -49904 65510 lineto -49909 65512 lineto -49912 65513 lineto -49951 65525 lineto -50073 65562 lineto -50081 65563 lineto -50082 65563 lineto -50094 65565 lineto -50250 65579 lineto -52003 65579 lineto -52013 65579 lineto -52098 65570 lineto -52180 65561 lineto -52185 65560 lineto -52189 65559 lineto -52254 65539 lineto -52349 65509 lineto -52354 65507 lineto -52358 65505 lineto -52404 65480 lineto -52506 65426 lineto -52511 65422 lineto -52514 65420 lineto -52544 65395 lineto -52643 65313 lineto -53027 64929 lineto -53061 64951 lineto -53271 65036 lineto -53494 65079 lineto -53721 65077 lineto -53944 65032 lineto -54153 64944 lineto -54341 64817 lineto -54501 64656 lineto -54625 64470 lineto -54630 64480 lineto -54758 64668 lineto -54921 64827 lineto -55111 64951 lineto -55321 65036 lineto -55544 65079 lineto -55771 65077 lineto -55994 65032 lineto -56203 64944 lineto -56391 64817 lineto -56551 64656 lineto -56677 64467 lineto -56764 64257 lineto -56808 64034 lineto -56804 63775 lineto -56762 63589 lineto -56898 63589 lineto -56911 63629 lineto -56913 63635 lineto -56915 63638 lineto -56940 63685 lineto -56994 63786 lineto -56998 63792 lineto -57000 63794 lineto -57025 63825 lineto -57107 63923 lineto -57206 64023 lineto -57227 64117 lineto -57301 64291 lineto -57408 64447 lineto -57543 64580 lineto -57701 64683 lineto -57876 64754 lineto -58062 64790 lineto -58251 64788 lineto -58436 64750 lineto -58549 64703 lineto -58676 64754 lineto -58862 64790 lineto -59051 64788 lineto -59236 64750 lineto -59349 64703 lineto -59476 64754 lineto -59662 64790 lineto -59851 64788 lineto -60036 64750 lineto -60210 64677 lineto -60367 64572 lineto -60500 64438 lineto -60605 64280 lineto -60677 64105 lineto -60693 64022 lineto -60694 64049 lineto -60741 64271 lineto -60830 64480 lineto -60958 64668 lineto -61121 64827 lineto -61311 64951 lineto -61521 65036 lineto -61744 65079 lineto -61971 65077 lineto -62194 65032 lineto -62403 64944 lineto -62591 64817 lineto -62751 64656 lineto -62877 64467 lineto -62881 64456 lineto -63424 64999 lineto -63430 65004 lineto -63472 65038 lineto -63548 65100 lineto -63553 65104 lineto -63555 65104 lineto -63601 65128 lineto -63689 65174 lineto -63691 65175 lineto -63696 65177 lineto -63764 65197 lineto -63842 65220 lineto -63847 65221 lineto -63849 65221 lineto -63871 65223 lineto -64000 65236 lineto -70942 65236 lineto -71040 65300 lineto -71220 65372 lineto -71410 65409 lineto -71604 65407 lineto -71793 65368 lineto -71972 65293 lineto -72000 65275 lineto -72040 65300 lineto -72220 65372 lineto -72410 65409 lineto -72604 65407 lineto -72793 65368 lineto -72972 65293 lineto -73133 65185 lineto -73269 65048 lineto -73376 64886 lineto -73450 64707 lineto -73488 64517 lineto -73485 64296 lineto -73442 64107 lineto -73363 63930 lineto -73252 63771 lineto -73111 63638 lineto -72948 63534 lineto -72767 63464 lineto -72576 63430 lineto -72383 63434 lineto -72193 63476 lineto -72016 63553 lineto -71997 63566 lineto -71948 63534 lineto -71767 63464 lineto -71576 63430 lineto -71383 63434 lineto -71193 63476 lineto -71016 63553 lineto -70942 63604 lineto -64337 63604 lineto -64029 63296 lineto -64206 63221 lineto -64399 63091 lineto -64564 62925 lineto -64693 62731 lineto -64782 62516 lineto -64827 62287 lineto -64823 62021 lineto -64772 61793 lineto -64703 61641 lineto -64763 61726 lineto -64897 61857 lineto -65054 61960 lineto -65228 62030 lineto -65413 62066 lineto -65601 62064 lineto -65785 62027 lineto -65958 61954 lineto -66000 61926 lineto -66054 61960 lineto -66228 62030 lineto -66413 62066 lineto -66601 62064 lineto -66785 62027 lineto -66958 61954 lineto -67004 61923 lineto -67198 61923 lineto -67171 62070 lineto -67175 62303 lineto -67223 62531 lineto -67315 62745 lineto -67447 62938 lineto -67613 63101 lineto -67808 63229 lineto -68024 63316 lineto -68253 63360 lineto -68486 63358 lineto -68715 63311 lineto -68930 63221 lineto -69123 63091 lineto -69288 62925 lineto -69417 62731 lineto -69506 62516 lineto -69551 62287 lineto -69547 62021 lineto -69496 61793 lineto -69401 61580 lineto -69267 61390 lineto -69098 61229 lineto -68901 61104 lineto -68684 61019 lineto -68574 61000 lineto -69579 59995 lineto -69584 59990 lineto -69617 59948 lineto -69680 59872 lineto -69683 59867 lineto -69684 59865 lineto -69707 59819 lineto -69754 59731 lineto -69754 59729 lineto -69757 59724 lineto -69774 59665 lineto -69800 59578 lineto -69800 59572 lineto -69801 59570 lineto -69802 59556 lineto -69816 59420 lineto -69816 57420 lineto -69816 57409 lineto -69816 56841 lineto -69897 56920 lineto -70054 57023 lineto -70228 57093 lineto -70413 57129 lineto -70601 57127 lineto -70785 57090 lineto -70958 57017 lineto -71114 56912 lineto -71246 56778 lineto -71350 56622 lineto -71421 56448 lineto -71458 56264 lineto -71455 56049 lineto -71413 55866 lineto -71337 55695 lineto -71229 55541 lineto -71159 55475 lineto -71159 54104 lineto -71165 54105 lineto -71348 54103 lineto -71527 54067 lineto -71696 53996 lineto -71848 53893 lineto -71977 53763 lineto -72078 53611 lineto -72148 53442 lineto -72184 53262 lineto -72181 53053 lineto -72141 52874 lineto -72066 52707 lineto -71961 52557 lineto -71828 52431 lineto -71674 52332 lineto -71503 52266 lineto -71322 52234 lineto -71139 52238 lineto -70960 52277 lineto -70910 52299 lineto -70909 52298 lineto -70909 49420 lineto -70909 49407 lineto -70909 48620 lineto -70964 48642 lineto -71158 48679 lineto -71356 48677 lineto -71549 48638 lineto -71732 48561 lineto -71895 48451 lineto -72035 48310 lineto -72144 48146 lineto -72220 47963 lineto -72258 47769 lineto -72255 47543 lineto -72211 47350 lineto -72131 47170 lineto -72017 47008 lineto -71925 46921 lineto -72035 46810 lineto -72144 46646 lineto -72220 46463 lineto -72258 46269 lineto -72255 46043 lineto -72211 45850 lineto -72131 45670 lineto -72017 45508 lineto -71874 45372 lineto -71707 45266 lineto -71523 45195 lineto -71328 45160 lineto -71130 45164 lineto -70937 45207 lineto -70756 45286 lineto -70594 45399 lineto -70456 45541 lineto -70349 45707 lineto -70276 45891 lineto -70272 45908 lineto -65891 41526 lineto -65891 41525 lineto -65890 41525 lineto -65884 41518 lineto -65818 41467 lineto -65753 41413 lineto -65747 41411 lineto -65745 41408 lineto -65665 41367 lineto -65596 41330 lineto -65592 41330 lineto -65587 41326 lineto -65496 41300 lineto -65427 41278 lineto -65422 41278 lineto -65417 41276 lineto -65320 41268 lineto -65250 41261 lineto -65241 41261 lineto -63000 41261 lineto -62994 41261 lineto -62987 41261 lineto -62434 41261 lineto -62434 41105 lineto -62598 41103 lineto -62777 41067 lineto -62946 40996 lineto -63098 40893 lineto -63227 40763 lineto -63328 40611 lineto -63398 40442 lineto -63434 40262 lineto -63431 40053 lineto -63391 39874 lineto -63316 39707 lineto -63316 39591 lineto -63397 39670 lineto -63554 39773 lineto -63728 39843 lineto -63913 39879 lineto -64101 39877 lineto -64285 39840 lineto -64447 39772 lineto -67425 42749 lineto -67430 42754 lineto -67472 42788 lineto -67548 42850 lineto -67553 42854 lineto -67555 42854 lineto -67601 42878 lineto -67689 42924 lineto -67691 42925 lineto -67696 42927 lineto -67755 42945 lineto -67842 42970 lineto -67848 42971 lineto -67850 42971 lineto -67880 42974 lineto -68000 42986 lineto -68008 42986 lineto -68406 42986 lineto -68531 43068 lineto -68714 43142 lineto -68908 43179 lineto -69106 43177 lineto -69299 43138 lineto -69482 43061 lineto -69645 42951 lineto -69785 42810 lineto -69894 42646 lineto -69970 42463 lineto -70008 42269 lineto -70005 42043 lineto -69961 41850 lineto -69881 41670 lineto -69879 41668 lineto -69894 41646 lineto -69970 41463 lineto -70008 41269 lineto -70005 41043 lineto -69961 40850 lineto -69943 40811 lineto -69984 40712 lineto -70009 40585 lineto -70009 39751 lineto -69983 39625 lineto -69933 39505 lineto -69909 39470 lineto -69909 39417 lineto -69909 39407 lineto -69899 39322 lineto -69891 39240 lineto -69889 39235 lineto -69889 39231 lineto -69868 39166 lineto -69839 39071 lineto -69836 39066 lineto -69835 39062 lineto -69809 39016 lineto -69756 38914 lineto -69751 38909 lineto -69750 38906 lineto -69724 38876 lineto -69643 38777 lineto -69141 38275 lineto -69134 38268 lineto -69068 38217 lineto -69003 38163 lineto -68997 38161 lineto -68995 38158 lineto -68915 38117 lineto -68846 38080 lineto -68842 38080 lineto -68837 38076 lineto -68746 38050 lineto -68677 38028 lineto -68672 38028 lineto -68667 38026 lineto -68570 38018 lineto -68500 38011 lineto -68491 38011 lineto -68376 38012 lineto -68159 37794 lineto -68159 37399 lineto -68162 37401 lineto -68315 37502 lineto -68485 37570 lineto -68665 37605 lineto -68848 37603 lineto -69027 37567 lineto -69196 37496 lineto -69348 37393 lineto -69477 37263 lineto -69578 37111 lineto -69648 36942 lineto -69684 36762 lineto -69682 36661 lineto -72014 36661 lineto -72206 36639 lineto -72317 36604 lineto -72344 36604 lineto -72470 36578 lineto -72590 36528 lineto -72604 36518 lineto -72735 36570 lineto -72915 36605 lineto -73098 36603 lineto -73277 36567 lineto -73446 36496 lineto -73598 36393 lineto -73681 36310 lineto -73681 38761 lineto -73555 38787 lineto -73435 38837 lineto -73328 38910 lineto -73237 39001 lineto -73165 39109 lineto -73116 39228 lineto -73091 39355 lineto -73091 42989 lineto -73117 43115 lineto -73167 43235 lineto -73240 43342 lineto -73331 43433 lineto -73439 43505 lineto -73558 43554 lineto -73685 43579 lineto -77319 43579 lineto -77445 43553 lineto -77565 43503 lineto -77672 43430 lineto -77763 43339 lineto -77835 43231 lineto -77884 43112 lineto -77909 42985 lineto -77909 39351 lineto -77883 39225 lineto -77833 39105 lineto -77760 38998 lineto -77669 38907 lineto -77561 38835 lineto -77442 38786 lineto -77315 38761 lineto -73681 38761 lineto -73681 36310 lineto -73727 36263 lineto -73828 36111 lineto -73898 35942 lineto -73934 35762 lineto -73931 35553 lineto -73891 35374 lineto -73816 35207 lineto -73711 35057 lineto -73578 34931 lineto -73424 34832 lineto -73253 34766 lineto -73072 34734 lineto -72909 34738 lineto -72909 34174 lineto -73014 34174 lineto -73140 34148 lineto -73260 34098 lineto -73367 34025 lineto -73458 33934 lineto -73530 33826 lineto -73579 33707 lineto -73604 33580 lineto -73604 32627 lineto -73854 32674 lineto -74169 32672 lineto -74476 32609 lineto -74766 32487 lineto -75027 32311 lineto -75248 32088 lineto -75422 31826 lineto -75542 31535 lineto -75603 31227 lineto -75598 30868 lineto -75528 30561 lineto -75400 30274 lineto -75219 30017 lineto -74991 29801 lineto -74726 29632 lineto -74433 29519 lineto -74123 29464 lineto -73809 29471 lineto -73502 29538 lineto -73477 29549 lineto -73400 29374 lineto -73219 29117 lineto -72991 28901 lineto -72726 28732 lineto -72433 28619 lineto -72123 28564 lineto -71809 28571 lineto -71502 28638 lineto -71214 28764 lineto -70956 28944 lineto -70738 29170 lineto -70567 29434 lineto -70452 29726 lineto -70395 30035 lineto -70399 30350 lineto -70465 30657 lineto -70589 30946 lineto -70681 31082 lineto -70633 31115 lineto -70542 31206 lineto -70470 31314 lineto -70421 31433 lineto -70396 31560 lineto -70396 33261 lineto -68126 33261 lineto -67604 32739 lineto -67604 32627 lineto -67854 32674 lineto -68169 32672 lineto -68476 32609 lineto -68766 32487 lineto -69027 32311 lineto -69248 32088 lineto -69422 31826 lineto -69542 31535 lineto -69603 31227 lineto -69598 30868 lineto -69528 30561 lineto -69400 30274 lineto -69219 30017 lineto -68991 29801 lineto -68726 29632 lineto -68433 29519 lineto -68123 29464 lineto -67809 29471 lineto -67502 29538 lineto -67477 29549 lineto -67400 29374 lineto -67219 29117 lineto -66991 28901 lineto -66726 28732 lineto -66433 28619 lineto -66123 28564 lineto -65809 28571 lineto -65502 28638 lineto -65214 28764 lineto -64956 28944 lineto -64738 29170 lineto -64567 29434 lineto -64452 29726 lineto -64395 30035 lineto -64399 30350 lineto -64465 30657 lineto -64589 30946 lineto -64681 31082 lineto -64633 31115 lineto -64542 31206 lineto -64470 31314 lineto -64421 31433 lineto -64396 31560 lineto -64396 33584 lineto -64422 33710 lineto -64443 33761 lineto -63507 33761 lineto -63505 33543 lineto -63461 33350 lineto -63381 33170 lineto -63379 33168 lineto -63394 33146 lineto -63470 32963 lineto -63508 32769 lineto -63505 32543 lineto -63461 32350 lineto -63409 32233 lineto -63409 31417 lineto -63409 31407 lineto -63389 31231 lineto -63347 31103 lineto -63338 31070 lineto -63336 31068 lineto -63335 31062 lineto -63281 30965 lineto -63255 30914 lineto -63253 30912 lineto -63250 30906 lineto -63181 30825 lineto -63142 30777 lineto -62636 30272 lineto -62751 30156 lineto -62877 29967 lineto -62964 29757 lineto -63008 29534 lineto -63004 29275 lineto -62954 29053 lineto -62862 28846 lineto -62731 28660 lineto -62567 28503 lineto -62375 28382 lineto -62163 28299 lineto -61940 28260 lineto -61713 28265 lineto -61491 28313 lineto -61283 28404 lineto -61096 28534 lineto -60938 28697 lineto -60815 28888 lineto -60732 29099 lineto -60691 29322 lineto -60694 29549 lineto -60736 29751 lineto -60600 29751 lineto -60597 29743 lineto -60588 29710 lineto -60586 29708 lineto -60585 29702 lineto -60531 29605 lineto -60505 29554 lineto -60503 29552 lineto -60500 29546 lineto -60431 29465 lineto -60392 29417 lineto -60293 29319 lineto -60273 29223 lineto -60259 29191 lineto -60259 29016 lineto -60259 29007 lineto -60239 28831 lineto -60197 28703 lineto -60188 28670 lineto -60186 28668 lineto -60185 28662 lineto -60131 28565 lineto -60105 28514 lineto -60103 28512 lineto -60100 28506 lineto -60031 28425 lineto -59992 28377 lineto -59641 28026 lineto -59641 28025 lineto -59640 28025 lineto -59634 28018 lineto -59568 27967 lineto -59503 27913 lineto -59497 27911 lineto -59495 27908 lineto -59415 27867 lineto -59346 27830 lineto -59342 27830 lineto -59337 27826 lineto -59246 27800 lineto -59177 27778 lineto -59172 27778 lineto -59167 27776 lineto -59070 27768 lineto -59000 27761 lineto -58991 27761 lineto -58991 27576 lineto -79819 27576 lineto -poly0 -newpath 61363 31569 moveto -61591 31797 lineto -61591 32228 lineto -61526 32391 lineto -61491 32585 lineto -61493 32783 lineto -61535 32976 lineto -61612 33158 lineto -61621 33172 lineto -61599 33207 lineto -61526 33391 lineto -61491 33585 lineto -61493 33783 lineto -61535 33976 lineto -61612 34158 lineto -61621 34172 lineto -61599 34207 lineto -61577 34261 lineto -57246 34261 lineto -57237 34261 lineto -57061 34281 lineto -56932 34323 lineto -56900 34332 lineto -56897 34334 lineto -56892 34335 lineto -56793 34389 lineto -56744 34415 lineto -56741 34417 lineto -56736 34420 lineto -56654 34489 lineto -56607 34528 lineto -54555 36579 lineto -54457 36516 lineto -54273 36445 lineto -54078 36410 lineto -53880 36414 lineto -53687 36457 lineto -53506 36536 lineto -53497 36542 lineto -53457 36516 lineto -53273 36445 lineto -53078 36410 lineto -52880 36414 lineto -52687 36457 lineto -52563 36511 lineto -51062 36511 lineto -51587 35986 lineto -53753 35986 lineto -53761 35986 lineto -53828 35979 lineto -53911 35970 lineto -53916 35969 lineto -53920 35968 lineto -54010 35940 lineto -54063 35923 lineto -54065 35922 lineto -54071 35920 lineto -54190 35855 lineto -54204 35847 lineto -54204 35847 lineto -54211 35843 lineto -54284 35782 lineto -54327 35747 lineto -54332 35742 lineto -56087 33986 lineto -57753 33986 lineto -57761 33986 lineto -57828 33979 lineto -57911 33970 lineto -57916 33969 lineto -57920 33968 lineto -58010 33940 lineto -58063 33923 lineto -58065 33922 lineto -58071 33920 lineto -58190 33855 lineto -58204 33847 lineto -58204 33847 lineto -58211 33843 lineto -58284 33782 lineto -58327 33747 lineto -58333 33741 lineto -59529 32545 lineto -59535 32539 lineto -59564 32503 lineto -59630 32422 lineto -59704 32281 lineto -59705 32276 lineto -59707 32273 lineto -59733 32182 lineto -59750 32128 lineto -59750 32127 lineto -59752 32120 lineto -59760 32027 lineto -59766 31970 lineto -59766 31962 lineto -59766 31769 lineto -59851 31768 lineto -60036 31730 lineto -60210 31657 lineto -60341 31569 lineto -61363 31569 lineto -poly0 -newpath 54500 39299 moveto -54531 39318 lineto -54703 39388 lineto -54644 39480 lineto -54575 39655 lineto -54541 39839 lineto -54543 40027 lineto -54582 40211 lineto -54656 40384 lineto -54763 40539 lineto -54897 40670 lineto -55054 40773 lineto -55228 40843 lineto -55413 40879 lineto -55601 40877 lineto -55785 40840 lineto -55958 40767 lineto -56114 40662 lineto -56246 40528 lineto -56350 40372 lineto -56421 40198 lineto -56432 40142 lineto -56587 39986 lineto -57750 39986 lineto -57756 39986 lineto -57761 39986 lineto -60162 39986 lineto -60598 40423 lineto -60605 40453 lineto -60652 40565 lineto -60640 40584 lineto -60591 40703 lineto -60566 40830 lineto -60566 41261 lineto -58707 41261 lineto -58705 41049 lineto -58663 40866 lineto -58587 40695 lineto -58479 40541 lineto -58343 40412 lineto -58184 40311 lineto -58009 40243 lineto -57824 40210 lineto -57636 40214 lineto -57453 40254 lineto -57280 40330 lineto -57126 40437 lineto -56996 40572 lineto -56894 40730 lineto -56825 40905 lineto -56791 41089 lineto -56792 41261 lineto -51933 41261 lineto -51931 41053 lineto -51891 40874 lineto -51816 40707 lineto -51711 40557 lineto -51578 40431 lineto -51424 40332 lineto -51253 40266 lineto -51072 40234 lineto -50889 40238 lineto -50851 40247 lineto -50895 40181 lineto -50944 40062 lineto -50969 39935 lineto -50969 39329 lineto -52000 39329 lineto -52013 39329 lineto -52558 39329 lineto -52714 39392 lineto -52908 39429 lineto -53106 39427 lineto -53299 39388 lineto -53482 39311 lineto -53500 39299 lineto -53531 39318 lineto -53714 39392 lineto -53908 39429 lineto -54106 39427 lineto -54299 39388 lineto -54482 39311 lineto -54500 39299 lineto -poly0 -newpath 63909 43079 moveto -64872 43080 lineto -65595 43802 lineto -65530 43830 lineto -65376 43937 lineto -65246 44072 lineto -65144 44230 lineto -65075 44405 lineto -65041 44589 lineto -65043 44777 lineto -65082 44961 lineto -65156 45134 lineto -65263 45289 lineto -65397 45420 lineto -65398 45422 lineto -65376 45437 lineto -65246 45572 lineto -65144 45730 lineto -65075 45905 lineto -65041 46089 lineto -65043 46277 lineto -65082 46461 lineto -65156 46634 lineto -65184 46675 lineto -65184 47169 lineto -65144 47230 lineto -65075 47405 lineto -65041 47589 lineto -65043 47777 lineto -65082 47961 lineto -65156 48134 lineto -65263 48289 lineto -65397 48420 lineto -65554 48523 lineto -65728 48593 lineto -65913 48629 lineto -66101 48627 lineto -66285 48590 lineto -66458 48517 lineto -66462 48515 lineto -66481 48533 lineto -66589 48605 lineto -66708 48654 lineto -66835 48679 lineto -67434 48679 lineto -67434 51262 lineto -67434 53262 lineto -67434 56670 lineto -67434 56681 lineto -67434 58582 lineto -66643 59373 lineto -66574 59360 lineto -66409 59364 lineto -66409 58387 lineto -66434 58262 lineto -66431 58053 lineto -66409 57955 lineto -66409 56478 lineto -66421 56448 lineto -66458 56264 lineto -66455 56049 lineto -66413 55866 lineto -66337 55695 lineto -66229 55541 lineto -66093 55412 lineto -65934 55311 lineto -65759 55243 lineto -65574 55210 lineto -65386 55214 lineto -65203 55254 lineto -65030 55330 lineto -64876 55437 lineto -64746 55572 lineto -64644 55730 lineto -64575 55905 lineto -64541 56089 lineto -64543 56277 lineto -64582 56461 lineto -64591 56483 lineto -64591 57238 lineto -64572 57234 lineto -64389 57238 lineto -64210 57277 lineto -64042 57351 lineto -63892 57455 lineto -63765 57587 lineto -63665 57741 lineto -63598 57911 lineto -63565 58091 lineto -63567 58274 lineto -63605 58453 lineto -63677 58622 lineto -63781 58773 lineto -63912 58901 lineto -64065 59002 lineto -64235 59070 lineto -64415 59105 lineto -64591 59104 lineto -64591 60015 lineto -64575 60055 lineto -64541 60239 lineto -64543 60427 lineto -64582 60611 lineto -64625 60714 lineto -64575 60842 lineto -64541 61026 lineto -64543 61214 lineto -64582 61398 lineto -64633 61519 lineto -64543 61390 lineto -64374 61229 lineto -64177 61104 lineto -63960 61019 lineto -63730 60979 lineto -63497 60984 lineto -63269 61034 lineto -63055 61127 lineto -62864 61260 lineto -62702 61428 lineto -62576 61624 lineto -62566 61650 lineto -62566 61159 lineto -62555 61068 lineto -62550 61008 lineto -62548 61003 lineto -62548 61000 lineto -62500 60849 lineto -62447 60754 lineto -62427 60715 lineto -62424 60713 lineto -62423 60709 lineto -62371 60647 lineto -62326 60592 lineto -62321 60587 lineto -61609 59876 lineto -61785 59840 lineto -61958 59767 lineto -62114 59662 lineto -62246 59528 lineto -62350 59372 lineto -62421 59198 lineto -62458 59014 lineto -62455 58799 lineto -62413 58616 lineto -62379 58540 lineto -62385 58531 lineto -62434 58412 lineto -62459 58285 lineto -62459 57551 lineto -62433 57425 lineto -62383 57305 lineto -62310 57198 lineto -62219 57107 lineto -62111 57035 lineto -61992 56986 lineto -61865 56961 lineto -61694 56961 lineto -61443 56710 lineto -61503 56619 lineto -61574 56444 lineto -61610 56258 lineto -61608 56069 lineto -61570 55884 lineto -61497 55710 lineto -61469 55670 lineto -61503 55619 lineto -61574 55444 lineto -61610 55258 lineto -61608 55069 lineto -61572 54897 lineto -62002 55327 lineto -62035 55476 lineto -62112 55658 lineto -62224 55821 lineto -62365 55959 lineto -62531 56068 lineto -62714 56142 lineto -62908 56179 lineto -63106 56177 lineto -63299 56138 lineto -63482 56061 lineto -63609 55976 lineto -63661 55970 lineto -63666 55969 lineto -63670 55968 lineto -63760 55940 lineto -63813 55923 lineto -63815 55922 lineto -63821 55920 lineto -63940 55855 lineto -63954 55847 lineto -63954 55847 lineto -63961 55843 lineto -64034 55782 lineto -64077 55747 lineto -64082 55742 lineto -65751 54073 lineto -65777 54067 lineto -65946 53996 lineto -66000 53960 lineto -66065 54002 lineto -66235 54070 lineto -66415 54105 lineto -66598 54103 lineto -66777 54067 lineto -66946 53996 lineto -67098 53893 lineto -67227 53763 lineto -67328 53611 lineto -67398 53442 lineto -67434 53262 lineto -67431 53053 lineto -67391 52874 lineto -67316 52707 lineto -67211 52557 lineto -67078 52431 lineto -66924 52332 lineto -66753 52266 lineto -66572 52234 lineto -66389 52238 lineto -66210 52277 lineto -66042 52351 lineto -65999 52381 lineto -65924 52332 lineto -65753 52266 lineto -65572 52234 lineto -65389 52238 lineto -65210 52277 lineto -65042 52351 lineto -64892 52455 lineto -64765 52587 lineto -64665 52741 lineto -64598 52911 lineto -64596 52920 lineto -63911 53605 lineto -63970 53463 lineto -64008 53269 lineto -64005 53043 lineto -63961 52850 lineto -63881 52670 lineto -63816 52578 lineto -63816 51986 lineto -65040 51986 lineto -65065 52002 lineto -65235 52070 lineto -65415 52105 lineto -65598 52103 lineto -65777 52067 lineto -65946 51996 lineto -66000 51960 lineto -66065 52002 lineto -66235 52070 lineto -66415 52105 lineto -66598 52103 lineto -66777 52067 lineto -66946 51996 lineto -67098 51893 lineto -67227 51763 lineto -67328 51611 lineto -67398 51442 lineto -67434 51262 lineto -67431 51053 lineto -67391 50874 lineto -67316 50707 lineto -67211 50557 lineto -67078 50431 lineto -66924 50332 lineto -66753 50266 lineto -66572 50234 lineto -66389 50238 lineto -66210 50277 lineto -66042 50351 lineto -65999 50381 lineto -65924 50332 lineto -65753 50266 lineto -65572 50234 lineto -65389 50238 lineto -65210 50277 lineto -65042 50351 lineto -65037 50354 lineto -63915 50354 lineto -63934 50262 lineto -63931 50053 lineto -63891 49874 lineto -63816 49707 lineto -63789 49670 lineto -63828 49611 lineto -63898 49442 lineto -63934 49262 lineto -63931 49053 lineto -63909 48955 lineto -63909 43079 lineto -poly0 -newpath 39500 44640 moveto -39551 44673 lineto -39726 44744 lineto -39912 44780 lineto -40101 44778 lineto -40184 44761 lineto -40184 45573 lineto -40184 45581 lineto -40191 45649 lineto -40200 45731 lineto -40201 45737 lineto -40202 45740 lineto -40230 45831 lineto -40247 45883 lineto -40248 45886 lineto -40250 45891 lineto -40315 46011 lineto -40323 46024 lineto -40323 46025 lineto -40327 46031 lineto -40388 46105 lineto -40423 46147 lineto -40429 46153 lineto -40846 46570 lineto -40421 46995 lineto -40415 47001 lineto -40385 47038 lineto -40320 47118 lineto -40246 47259 lineto -40244 47265 lineto -40243 47267 lineto -40216 47358 lineto -40200 47412 lineto -40199 47414 lineto -40198 47420 lineto -40189 47515 lineto -40184 47570 lineto -40184 47578 lineto -40184 47854 lineto -33247 47854 lineto -33239 47854 lineto -33174 47862 lineto -33088 47870 lineto -33082 47872 lineto -33080 47872 lineto -33025 47890 lineto -32936 47917 lineto -32932 47919 lineto -32929 47920 lineto -32817 47982 lineto -32796 47993 lineto -32795 47994 lineto -32789 47997 lineto -32715 48059 lineto -32673 48093 lineto -32667 48099 lineto -32421 48345 lineto -32415 48351 lineto -32385 48388 lineto -32320 48468 lineto -32254 48593 lineto -32088 48560 lineto -31899 48562 lineto -31816 48580 lineto -31816 45670 lineto -31816 45659 lineto -31816 44762 lineto -31912 44780 lineto -32101 44778 lineto -32286 44740 lineto -32460 44667 lineto -32500 44640 lineto -32551 44673 lineto -32726 44744 lineto -32912 44780 lineto -33101 44778 lineto -33286 44740 lineto -33460 44667 lineto -33500 44640 lineto -33551 44673 lineto -33726 44744 lineto -33912 44780 lineto -34101 44778 lineto -34286 44740 lineto -34460 44667 lineto -34500 44640 lineto -34551 44673 lineto -34726 44744 lineto -34912 44780 lineto -35101 44778 lineto -35286 44740 lineto -35460 44667 lineto -35500 44640 lineto -35551 44673 lineto -35726 44744 lineto -35912 44780 lineto -36101 44778 lineto -36286 44740 lineto -36460 44667 lineto -36500 44640 lineto -36551 44673 lineto -36726 44744 lineto -36912 44780 lineto -37101 44778 lineto -37286 44740 lineto -37460 44667 lineto -37500 44640 lineto -37551 44673 lineto -37726 44744 lineto -37912 44780 lineto -38101 44778 lineto -38286 44740 lineto -38460 44667 lineto -38500 44640 lineto -38551 44673 lineto -38726 44744 lineto -38912 44780 lineto -39101 44778 lineto -39286 44740 lineto -39460 44667 lineto -39500 44640 lineto -poly0 -newpath 59419 50405 moveto -59430 50456 lineto -59503 50630 lineto -59530 50671 lineto -59497 50721 lineto -59426 50896 lineto -59390 51082 lineto -59392 51271 lineto -59423 51424 lineto -59309 51486 lineto -59296 51493 lineto -59295 51494 lineto -59289 51497 lineto -59215 51559 lineto -59173 51593 lineto -59166 51600 lineto -58912 51854 lineto -58557 51854 lineto -58528 51787 lineto -58534 51782 lineto -58577 51747 lineto -58583 51741 lineto -59079 51245 lineto -59085 51239 lineto -59114 51203 lineto -59180 51122 lineto -59254 50981 lineto -59255 50976 lineto -59257 50973 lineto -59283 50882 lineto -59300 50828 lineto -59300 50827 lineto -59302 50820 lineto -59310 50726 lineto -59316 50670 lineto -59316 50662 lineto -59316 50508 lineto -59419 50405 lineto -poly0 -newpath 33500 50640 moveto -33551 50673 lineto -33726 50744 lineto -33912 50780 lineto -34101 50778 lineto -34184 50761 lineto -34184 52829 lineto -34088 52810 lineto -33899 52812 lineto -33714 52850 lineto -33624 52888 lineto -33621 52885 lineto -33502 52836 lineto -33375 52811 lineto -32621 52811 lineto -32558 52824 lineto -31816 52082 lineto -31816 50762 lineto -31912 50780 lineto -32101 50778 lineto -32286 50740 lineto -32460 50667 lineto -32500 50640 lineto -32551 50673 lineto -32726 50744 lineto -32912 50780 lineto -33101 50778 lineto -33286 50740 lineto -33460 50667 lineto -33500 50640 lineto -poly0 -newpath 59433 53464 moveto -59503 53630 lineto -59530 53671 lineto -59497 53721 lineto -59426 53896 lineto -59390 54082 lineto -59392 54271 lineto -59430 54456 lineto -59503 54630 lineto -59530 54671 lineto -59497 54721 lineto -59426 54896 lineto -59390 55082 lineto -59392 55271 lineto -59430 55456 lineto -59503 55630 lineto -59530 55671 lineto -59497 55721 lineto -59426 55896 lineto -59390 56082 lineto -59392 56271 lineto -59430 56456 lineto -59503 56630 lineto -59608 56787 lineto -59684 56863 lineto -59684 56923 lineto -59684 56931 lineto -59691 56999 lineto -59700 57081 lineto -59701 57087 lineto -59702 57090 lineto -59730 57181 lineto -59747 57233 lineto -59748 57236 lineto -59750 57241 lineto -59815 57361 lineto -59823 57374 lineto -59823 57375 lineto -59827 57381 lineto -59888 57455 lineto -59923 57497 lineto -59929 57503 lineto -60541 58115 lineto -60541 58289 lineto -60567 58415 lineto -60617 58535 lineto -60620 58540 lineto -60575 58655 lineto -60545 58812 lineto -60075 58341 lineto -60069 58335 lineto -60032 58306 lineto -59952 58240 lineto -59811 58166 lineto -59805 58165 lineto -59803 58163 lineto -59712 58137 lineto -59658 58120 lineto -59656 58120 lineto -59650 58118 lineto -59555 58110 lineto -59500 58104 lineto -59492 58104 lineto -55837 58104 lineto -55812 58079 lineto -55958 58017 lineto -56114 57912 lineto -56246 57778 lineto -56350 57622 lineto -56421 57448 lineto -56458 57264 lineto -56455 57049 lineto -56413 56866 lineto -56337 56695 lineto -56229 56541 lineto -56093 56412 lineto -55934 56311 lineto -55759 56243 lineto -55574 56210 lineto -55386 56214 lineto -55203 56254 lineto -55030 56330 lineto -54876 56437 lineto -54746 56572 lineto -54644 56730 lineto -54593 56860 lineto -54066 56332 lineto -54066 54390 lineto -54425 54749 lineto -54431 54755 lineto -54467 54785 lineto -54548 54850 lineto -54689 54924 lineto -54694 54926 lineto -54697 54927 lineto -54787 54954 lineto -54842 54970 lineto -54843 54971 lineto -54850 54972 lineto -54943 54981 lineto -55000 54986 lineto -55008 54986 lineto -56408 54986 lineto -56390 55082 lineto -56392 55271 lineto -56430 55456 lineto -56503 55630 lineto -56530 55671 lineto -56497 55721 lineto -56426 55896 lineto -56390 56082 lineto -56392 56271 lineto -56430 56456 lineto -56503 56630 lineto -56608 56787 lineto -56742 56920 lineto -56900 57025 lineto -57075 57097 lineto -57260 57134 lineto -57563 57135 lineto -57753 57133 lineto -57937 57093 lineto -58111 57019 lineto -58267 56912 lineto -58400 56777 lineto -58503 56619 lineto -58574 56444 lineto -58610 56258 lineto -58608 56069 lineto -58570 55884 lineto -58497 55710 lineto -58469 55670 lineto -58503 55619 lineto -58574 55444 lineto -58610 55258 lineto -58608 55069 lineto -58570 54884 lineto -58497 54710 lineto -58469 54670 lineto -58503 54619 lineto -58574 54444 lineto -58610 54258 lineto -58608 54069 lineto -58570 53884 lineto -58497 53710 lineto -58469 53670 lineto -58503 53619 lineto -58556 53486 lineto -59253 53486 lineto -59261 53486 lineto -59328 53479 lineto -59411 53470 lineto -59416 53469 lineto -59420 53468 lineto -59433 53464 lineto -poly0 - 1 setgray -50 setlinewidth -newpath 32000 51170 159 0 360 arc fill stroke -newpath 26000 51170 159 0 360 arc fill stroke -400 setlinewidth -71610 30170 72390 30170 line -71610 32570 72390 32570 line -74000 30680 74000 31460 line -65610 30170 66390 30170 line -65610 32570 66390 32570 line -68000 30680 68000 31460 line -50 setlinewidth -newpath 61850 63920 472 0 360 arc fill stroke -newpath 55650 63920 472 0 360 arc fill stroke -newpath 58950 63680 160 0 360 arc fill stroke -newpath 58150 63680 160 0 360 arc fill stroke -newpath 59750 63680 160 0 360 arc fill stroke -newpath 58550 62680 160 0 360 arc fill stroke -newpath 57750 62680 160 0 360 arc fill stroke -newpath 59350 62680 160 0 360 arc fill stroke -newpath 53600 63920 472 0 360 arc fill stroke -newpath 47400 63920 472 0 360 arc fill stroke -newpath 50700 63680 160 0 360 arc fill stroke -newpath 49900 63680 160 0 360 arc fill stroke -newpath 51500 63680 160 0 360 arc fill stroke -newpath 50300 62680 160 0 360 arc fill stroke -newpath 49500 62680 160 0 360 arc fill stroke -newpath 51100 62680 160 0 360 arc fill stroke -newpath 45350 63920 472 0 360 arc fill stroke -newpath 39150 63920 472 0 360 arc fill stroke -newpath 42450 63680 160 0 360 arc fill stroke -newpath 41650 63680 160 0 360 arc fill stroke -newpath 43250 63680 160 0 360 arc fill stroke -newpath 42050 62680 160 0 360 arc fill stroke -newpath 41250 62680 160 0 360 arc fill stroke -newpath 42850 62680 160 0 360 arc fill stroke -newpath 37100 63920 472 0 360 arc fill stroke -newpath 30900 63920 472 0 360 arc fill stroke -newpath 34200 63680 160 0 360 arc fill stroke -newpath 33400 63680 160 0 360 arc fill stroke -newpath 35000 63680 160 0 360 arc fill stroke -newpath 33800 62680 160 0 360 arc fill stroke -newpath 33000 62680 160 0 360 arc fill stroke -newpath 34600 62680 160 0 360 arc fill stroke -newpath 28850 63920 472 0 360 arc fill stroke -newpath 22650 63920 472 0 360 arc fill stroke -newpath 25950 63680 160 0 360 arc fill stroke -newpath 25150 63680 160 0 360 arc fill stroke -newpath 26750 63680 160 0 360 arc fill stroke -newpath 25550 62680 160 0 360 arc fill stroke -newpath 24750 62680 160 0 360 arc fill stroke -newpath 26350 62680 160 0 360 arc fill stroke -newpath 22650 29420 472 0 360 arc fill stroke -newpath 28850 29420 472 0 360 arc fill stroke -newpath 25550 29660 160 0 360 arc fill stroke -newpath 26350 29660 160 0 360 arc fill stroke -newpath 24750 29660 160 0 360 arc fill stroke -newpath 25950 30660 160 0 360 arc fill stroke -newpath 26750 30660 160 0 360 arc fill stroke -newpath 25150 30660 160 0 360 arc fill stroke -newpath 30900 29420 472 0 360 arc fill stroke -newpath 37100 29420 472 0 360 arc fill stroke -newpath 33800 29660 160 0 360 arc fill stroke -newpath 34600 29660 160 0 360 arc fill stroke -newpath 33000 29660 160 0 360 arc fill stroke -newpath 34200 30660 160 0 360 arc fill stroke -newpath 35000 30660 160 0 360 arc fill stroke -newpath 33400 30660 160 0 360 arc fill stroke -newpath 39150 29420 472 0 360 arc fill stroke -newpath 45350 29420 472 0 360 arc fill stroke -newpath 42050 29660 160 0 360 arc fill stroke -newpath 42850 29660 160 0 360 arc fill stroke -newpath 41250 29660 160 0 360 arc fill stroke -newpath 42450 30660 160 0 360 arc fill stroke -newpath 43250 30660 160 0 360 arc fill stroke -newpath 41650 30660 160 0 360 arc fill stroke -newpath 47400 29420 472 0 360 arc fill stroke -newpath 53600 29420 472 0 360 arc fill stroke -newpath 50300 29660 160 0 360 arc fill stroke -newpath 51100 29660 160 0 360 arc fill stroke -newpath 49500 29660 160 0 360 arc fill stroke -newpath 50700 30660 160 0 360 arc fill stroke -newpath 51500 30660 160 0 360 arc fill stroke -newpath 49900 30660 160 0 360 arc fill stroke -newpath 55650 29420 472 0 360 arc fill stroke -newpath 61850 29420 472 0 360 arc fill stroke -newpath 58550 29660 160 0 360 arc fill stroke -newpath 59350 29660 160 0 360 arc fill stroke -newpath 57750 29660 160 0 360 arc fill stroke -newpath 58950 30660 160 0 360 arc fill stroke -newpath 59750 30660 160 0 360 arc fill stroke -newpath 58150 30660 160 0 360 arc fill stroke -newpath 66500 51170 160 0 360 arc fill stroke -newpath 65500 51170 160 0 360 arc fill stroke -newpath 66500 53170 160 0 360 arc fill stroke -newpath 65500 53170 160 0 360 arc fill stroke -newpath 63000 53170 160 0 360 arc fill stroke -newpath 63000 55170 160 0 360 arc fill stroke -newpath 71500 64420 160 0 360 arc fill stroke -newpath 72500 64420 160 0 360 arc fill stroke -newpath 65500 60320 160 0 360 arc fill stroke -newpath 66500 60320 160 0 360 arc fill stroke -newpath 66500 61107 160 0 360 arc fill stroke -newpath 65500 61107 160 0 360 arc fill stroke -newpath 63638 62170 453 0 360 arc fill stroke -newpath 68362 62170 453 0 360 arc fill stroke -newpath 33000 53920 160 0 360 arc fill stroke -newpath 34000 53920 160 0 360 arc fill stroke -newpath 35000 53920 160 0 360 arc fill stroke -newpath 36000 53920 160 0 360 arc fill stroke -newpath 37000 53920 160 0 360 arc fill stroke -newpath 38000 53920 160 0 360 arc fill stroke -newpath 39000 53920 160 0 360 arc fill stroke -newpath 40000 53920 160 0 360 arc fill stroke -newpath 41000 53920 160 0 360 arc fill stroke -newpath 41000 56920 160 0 360 arc fill stroke -newpath 40000 56920 160 0 360 arc fill stroke -newpath 39000 56920 160 0 360 arc fill stroke -newpath 38000 56920 160 0 360 arc fill stroke -newpath 37000 56920 160 0 360 arc fill stroke -newpath 36000 56920 160 0 360 arc fill stroke -newpath 35000 56920 160 0 360 arc fill stroke -newpath 34000 56920 160 0 360 arc fill stroke -newpath 33000 56920 160 0 360 arc fill stroke -newpath 39000 39420 160 0 360 arc fill stroke -newpath 38000 39420 160 0 360 arc fill stroke -newpath 37000 39420 160 0 360 arc fill stroke -newpath 36000 39420 160 0 360 arc fill stroke -newpath 35000 39420 160 0 360 arc fill stroke -newpath 34000 39420 160 0 360 arc fill stroke -newpath 33000 39420 160 0 360 arc fill stroke -newpath 32000 39420 160 0 360 arc fill stroke -newpath 31000 39420 160 0 360 arc fill stroke -newpath 31000 36420 160 0 360 arc fill stroke -newpath 32000 36420 160 0 360 arc fill stroke -newpath 33000 36420 160 0 360 arc fill stroke -newpath 34000 36420 160 0 360 arc fill stroke -newpath 35000 36420 160 0 360 arc fill stroke -newpath 36000 36420 160 0 360 arc fill stroke -newpath 37000 36420 160 0 360 arc fill stroke -newpath 38000 36420 160 0 360 arc fill stroke -newpath 39000 36420 160 0 360 arc fill stroke -newpath 50000 39420 160 0 360 arc fill stroke -newpath 49000 39420 160 0 360 arc fill stroke -newpath 48000 39420 160 0 360 arc fill stroke -newpath 47000 39420 160 0 360 arc fill stroke -newpath 46000 39420 160 0 360 arc fill stroke -newpath 45000 39420 160 0 360 arc fill stroke -newpath 44000 39420 160 0 360 arc fill stroke -newpath 43000 39420 160 0 360 arc fill stroke -newpath 42000 39420 160 0 360 arc fill stroke -newpath 42000 36420 160 0 360 arc fill stroke -newpath 43000 36420 160 0 360 arc fill stroke -newpath 44000 36420 160 0 360 arc fill stroke -newpath 45000 36420 160 0 360 arc fill stroke -newpath 46000 36420 160 0 360 arc fill stroke -newpath 47000 36420 160 0 360 arc fill stroke -newpath 48000 36420 160 0 360 arc fill stroke -newpath 49000 36420 160 0 360 arc fill stroke -newpath 50000 36420 160 0 360 arc fill stroke -newpath 44000 53920 160 0 360 arc fill stroke -newpath 45000 53920 160 0 360 arc fill stroke -newpath 46000 53920 160 0 360 arc fill stroke -newpath 47000 53920 160 0 360 arc fill stroke -newpath 48000 53920 160 0 360 arc fill stroke -newpath 49000 53920 160 0 360 arc fill stroke -newpath 50000 53920 160 0 360 arc fill stroke -newpath 51000 53920 160 0 360 arc fill stroke -newpath 52000 53920 160 0 360 arc fill stroke -newpath 52000 56920 160 0 360 arc fill stroke -newpath 51000 56920 160 0 360 arc fill stroke -newpath 50000 56920 160 0 360 arc fill stroke -newpath 49000 56920 160 0 360 arc fill stroke -newpath 48000 56920 160 0 360 arc fill stroke -newpath 47000 56920 160 0 360 arc fill stroke -newpath 46000 56920 160 0 360 arc fill stroke -newpath 45000 56920 160 0 360 arc fill stroke -newpath 44000 56920 160 0 360 arc fill stroke -newpath 62500 32670 159 0 360 arc fill stroke -newpath 62500 33670 159 0 360 arc fill stroke -newpath 53000 37420 159 0 360 arc fill stroke -newpath 54000 37420 159 0 360 arc fill stroke -newpath 55000 38420 159 0 360 arc fill stroke -newpath 53000 38420 159 0 360 arc fill stroke -newpath 62500 34670 159 0 360 arc fill stroke -newpath 70250 53170 160 0 360 arc fill stroke -newpath 71250 53170 160 0 360 arc fill stroke -newpath 54000 38420 159 0 360 arc fill stroke -newpath 61500 41170 160 0 360 arc fill stroke -newpath 61500 40170 160 0 360 arc fill stroke -newpath 62500 40170 160 0 360 arc fill stroke -newpath 72000 35670 160 0 360 arc fill stroke -newpath 73000 35670 160 0 360 arc fill stroke -newpath 75500 41170 600 0 360 arc fill stroke -newpath 69000 42170 225 0 360 arc fill stroke -newpath 69000 41170 225 0 360 arc fill stroke -newpath 69000 40170 225 0 360 arc fill stroke -newpath 51000 49670 160 0 360 arc fill stroke -newpath 50000 49670 160 0 360 arc fill stroke -newpath 49000 49670 160 0 360 arc fill stroke -newpath 48000 49670 160 0 360 arc fill stroke -newpath 47000 49670 160 0 360 arc fill stroke -newpath 46000 49670 160 0 360 arc fill stroke -newpath 45000 49670 160 0 360 arc fill stroke -newpath 44000 49670 160 0 360 arc fill stroke -newpath 43000 49670 160 0 360 arc fill stroke -newpath 42000 49670 160 0 360 arc fill stroke -newpath 41000 49670 160 0 360 arc fill stroke -newpath 40000 49670 160 0 360 arc fill stroke -newpath 39000 49670 160 0 360 arc fill stroke -newpath 38000 49670 160 0 360 arc fill stroke -newpath 37000 49670 160 0 360 arc fill stroke -newpath 36000 49670 160 0 360 arc fill stroke -newpath 35000 49670 160 0 360 arc fill stroke -newpath 34000 49670 160 0 360 arc fill stroke -newpath 33000 49670 160 0 360 arc fill stroke -newpath 32000 49670 160 0 360 arc fill stroke -newpath 32000 43670 160 0 360 arc fill stroke -newpath 33000 43670 160 0 360 arc fill stroke -newpath 34000 43670 160 0 360 arc fill stroke -newpath 35000 43670 160 0 360 arc fill stroke -newpath 36000 43670 160 0 360 arc fill stroke -newpath 37000 43670 160 0 360 arc fill stroke -newpath 38000 43670 160 0 360 arc fill stroke -newpath 39000 43670 160 0 360 arc fill stroke -newpath 40000 43670 160 0 360 arc fill stroke -newpath 41000 43670 160 0 360 arc fill stroke -newpath 42000 43670 160 0 360 arc fill stroke -newpath 43000 43670 160 0 360 arc fill stroke -newpath 44000 43670 160 0 360 arc fill stroke -newpath 45000 43670 160 0 360 arc fill stroke -newpath 46000 43670 160 0 360 arc fill stroke -newpath 47000 43670 160 0 360 arc fill stroke -newpath 48000 43670 160 0 360 arc fill stroke -newpath 49000 43670 160 0 360 arc fill stroke -newpath 50000 43670 160 0 360 arc fill stroke -newpath 51000 43670 160 0 360 arc fill stroke -newpath 19370 62631 600 0 360 arc fill stroke -newpath 19370 30741 600 0 360 arc fill stroke -newpath 78425 62631 600 0 360 arc fill stroke -newpath 78425 30741 600 0 360 arc fill stroke -newpath 51000 42170 160 0 360 arc fill stroke -newpath 51000 41170 160 0 360 arc fill stroke -newpath 63000 49170 160 0 360 arc fill stroke -newpath 63000 50170 160 0 360 arc fill stroke -newpath 65500 58170 160 0 360 arc fill stroke -newpath 64500 58170 160 0 360 arc fill stroke -newpath 68750 35670 160 0 360 arc fill stroke -newpath 68750 36670 160 0 360 arc fill stroke -newpath 63250 37670 200 0 360 arc fill stroke -newpath 59250 37670 200 0 360 arc fill stroke -newpath 71250 47670 200 0 360 arc fill stroke -newpath 67250 47670 200 0 360 arc fill stroke -newpath 71250 46170 200 0 360 arc fill stroke -newpath 67250 46170 200 0 360 arc fill stroke -newpath 55500 53170 160 0 360 arc fill stroke -newpath 55500 57170 160 0 360 arc fill stroke -newpath 55500 43920 160 0 360 arc fill stroke -newpath 55500 39920 160 0 360 arc fill stroke -newpath 57750 41170 160 0 360 arc fill stroke -newpath 57750 37170 160 0 360 arc fill stroke -newpath 68000 38920 160 0 360 arc fill stroke -newpath 64000 38920 160 0 360 arc fill stroke -newpath 63250 36170 160 0 360 arc fill stroke -newpath 59250 36170 160 0 360 arc fill stroke -newpath 53250 45670 160 0 360 arc fill stroke -newpath 53250 49670 160 0 360 arc fill stroke -newpath 66000 44670 160 0 360 arc fill stroke -newpath 62000 44670 160 0 360 arc fill stroke -newpath 66000 46170 160 0 360 arc fill stroke -newpath 62000 46170 160 0 360 arc fill stroke -newpath 66000 47670 160 0 360 arc fill stroke -newpath 62000 47670 160 0 360 arc fill stroke -newpath 54500 49670 160 0 360 arc fill stroke -newpath 54500 45670 160 0 360 arc fill stroke -newpath 60500 44170 160 0 360 arc fill stroke -newpath 60500 45170 160 0 360 arc fill stroke -newpath 60500 46170 160 0 360 arc fill stroke -newpath 60500 47170 160 0 360 arc fill stroke -newpath 60500 48170 160 0 360 arc fill stroke -newpath 60500 49170 160 0 360 arc fill stroke -newpath 60500 50170 160 0 360 arc fill stroke -newpath 60500 51170 160 0 360 arc fill stroke -newpath 60500 52170 160 0 360 arc fill stroke -newpath 60500 53170 160 0 360 arc fill stroke -newpath 60500 54170 160 0 360 arc fill stroke -newpath 60500 55170 160 0 360 arc fill stroke -newpath 60500 56170 160 0 360 arc fill stroke -newpath 60500 43170 160 0 360 arc fill stroke -newpath 57500 56170 160 0 360 arc fill stroke -newpath 57500 55170 160 0 360 arc fill stroke -newpath 57500 54170 160 0 360 arc fill stroke -newpath 57500 53170 160 0 360 arc fill stroke -newpath 57500 52170 160 0 360 arc fill stroke -newpath 57500 51170 160 0 360 arc fill stroke -newpath 57500 50170 160 0 360 arc fill stroke -newpath 57500 49170 160 0 360 arc fill stroke -newpath 57500 48170 160 0 360 arc fill stroke -newpath 57500 47170 160 0 360 arc fill stroke -newpath 57500 46170 160 0 360 arc fill stroke -newpath 57500 45170 160 0 360 arc fill stroke -newpath 57500 44170 160 0 360 arc fill stroke -newpath 57500 43170 160 0 360 arc fill stroke -newpath 61500 57920 200 0 360 arc fill stroke -newpath 61500 58920 200 0 360 arc fill stroke -newpath 70500 56170 160 0 360 arc fill stroke -newpath 65500 56170 160 0 360 arc fill stroke - 0 setgray -showpage -grestore -%%EOF diff --git a/kicad/10ch_pwm_ctrl-solder-side.ps b/kicad/10ch_pwm_ctrl-solder-side.ps new file mode 100644 index 0000000..e27450d --- /dev/null +++ b/kicad/10ch_pwm_ctrl-solder-side.ps @@ -0,0 +1,4881 @@ +%!PS-Adobe-3.0 +%%Creator: PCBNEW-PS +%%CreationDate: Tue Feb 09 13:07:54 2010 +%%Title: D:/data/atmega/aurora/kicad/10ch_pwm_ctrl-Lötseite.ps +%%Pages: 1 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 843 +%%DocumentMedia: A4 595 842 0 () () +%%Orientation: Landscape +%%EndComments +%%Page: 1 1 +/line { + newpath + moveto + lineto + stroke +} bind def +/cir0 { newpath 0 360 arc stroke } bind def +/cir1 { newpath 0 360 arc gsave fill grestore stroke } bind def +/cir2 { newpath 0 360 arc gsave fill grestore stroke } bind def +/arc0 { newpath arc stroke } bind def +/arc1 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def +/arc2 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def +/poly0 { stroke } bind def +/poly1 { closepath gsave fill grestore stroke } bind def +/poly2 { closepath gsave fill grestore stroke } bind def +/rect0 { rectstroke } bind def +/rect1 { rectfill } bind def +/rect2 { rectfill } bind def +gsave +72 72 scale % Talk inches +1 setlinecap +1 setlinejoin +1 setlinewidth +8.267000 0.000000 translate 90 rotate +0.000100 0.000100 scale % Move to User coordinates +50 setlinewidth +120 setlinewidth +0.000 0.000 0.000 setrgbcolor +19089 33512 19729 33512 line +19729 33459 19729 33779 line +19729 33779 19657 33832 line +19657 33832 19160 33832 line +19160 33832 19089 33779 line +19089 33779 19089 33459 line +19089 34112 19729 34112 line +19729 34112 19729 34485 line +19444 34112 19444 34325 line +19089 34872 19089 35085 line +19089 34978 19729 34978 line +19657 34978 19515 34872 line +19089 35418 19729 35791 line +19160 35418 19657 35418 line +19657 35418 19729 35471 line +19729 35471 19729 35738 line +19729 35738 19657 35791 line +19657 35791 19160 35791 line +19160 35791 19089 35738 line +19089 35738 19089 35471 line +19089 35471 19160 35418 line +19160 36444 19089 36391 line +19089 36391 19089 36124 line +19089 36124 19160 36071 line +19160 36071 19657 36071 line +19657 36071 19729 36124 line +19729 36124 19729 36391 line +19729 36391 19657 36444 line +19089 36724 19729 36724 line +19089 37097 19729 37097 line +19373 36724 19373 37097 line +19729 38030 19089 38243 line +19089 38243 19729 38457 line +19729 38683 19729 39056 line +19729 39056 19657 39056 line +19657 39056 19444 38843 line +19444 38843 19444 39003 line +19444 39003 19373 39056 line +19373 39056 19160 39056 line +19160 39056 19089 39003 line +19089 39003 19089 38736 line +19089 38736 19160 38683 line +19089 40802 19231 40749 line +19231 40749 19586 40749 line +19586 40749 19729 40802 line +19160 41668 19089 41615 line +19089 41615 19089 41348 line +19089 41348 19160 41295 line +19160 41295 19657 41295 line +19657 41295 19729 41348 line +19729 41348 19729 41615 line +19729 41615 19657 41668 line +19089 42108 19231 42161 line +19231 42161 19586 42161 line +19586 42161 19729 42108 line +19089 43254 19586 43254 line +19586 43254 19729 43361 line +19729 43361 19729 43521 line +19729 43521 19586 43627 line +19586 43627 19089 43627 line +19444 43254 19444 43627 line +19089 43907 19515 43907 line +19444 43907 19515 43960 line +19515 43960 19515 44174 line +19515 44174 19444 44227 line +19444 44227 19089 44227 line +19729 44933 19089 44933 line +19089 44933 19089 44613 line +19089 44613 19160 44560 line +19160 44560 19444 44560 line +19444 44560 19515 44613 line +19515 44613 19515 44933 line +19089 45213 19515 45213 line +19373 45213 19515 45320 line +19515 45320 19515 45480 line +19515 45480 19373 45586 line +19302 45866 19302 46239 line +19302 46239 19444 46239 line +19444 46239 19515 46186 line +19515 46186 19515 45919 line +19515 45919 19444 45866 line +19444 45866 19160 45866 line +19160 45866 19089 45919 line +19089 45919 19089 46186 line +19089 46186 19160 46239 line +19515 46519 19515 46839 line +19515 46839 19444 46892 line +19444 46892 19089 46892 line +19089 46892 19089 46572 line +19089 46572 19160 46519 line +19160 46519 19231 46519 line +19231 46519 19302 46572 line +19302 46572 19302 46892 line +19160 47172 19089 47225 line +19089 47225 19089 47492 line +19089 47492 19160 47545 line +19160 47545 19231 47545 line +19231 47545 19302 47492 line +19302 47492 19302 47225 line +19302 47225 19373 47172 line +19373 47172 19444 47172 line +19444 47172 19515 47225 line +19515 47225 19515 47492 line +19515 47492 19444 47545 line +19089 48478 19586 48478 line +19586 48478 19729 48585 line +19729 48585 19729 48745 line +19729 48745 19586 48851 line +19586 48851 19089 48851 line +19444 48478 19444 48851 line +19515 49131 19231 49131 line +19231 49131 19089 49238 line +19089 49238 19089 49398 line +19089 49398 19231 49504 line +19231 49504 19515 49504 line +19089 49784 19515 49784 line +19373 49784 19515 49891 line +19515 49891 19515 50051 line +19515 50051 19373 50157 line +19515 50437 19515 50757 line +19515 50757 19444 50810 line +19444 50810 19089 50810 line +19089 50810 19089 50490 line +19089 50490 19160 50437 line +19160 50437 19231 50437 line +19231 50437 19302 50490 line +19302 50490 19302 50810 line +19160 51090 19089 51143 line +19089 51143 19089 51410 line +19089 51410 19160 51463 line +19160 51463 19231 51463 line +19231 51463 19302 51410 line +19302 51410 19302 51143 line +19302 51143 19373 51090 line +19373 51090 19444 51090 line +19444 51090 19515 51143 line +19515 51143 19515 51410 line +19515 51410 19444 51463 line +19089 52556 19231 52503 line +19231 52503 19586 52503 line +19586 52503 19729 52556 line +19160 53422 19089 53369 line +19089 53369 19089 53102 line +19089 53102 19160 53049 line +19160 53049 19444 53049 line +19444 53049 19515 53102 line +19515 53102 19515 53369 line +19515 53369 19444 53422 line +19089 53755 19160 53702 line +19160 53702 19444 53702 line +19444 53702 19515 53755 line +19515 53755 19515 54022 line +19515 54022 19444 54075 line +19444 54075 19160 54075 line +19160 54075 19089 54022 line +19089 54022 19089 53755 line +18876 54355 19515 54355 line +19444 54355 19515 54408 line +19515 54408 19515 54675 line +19515 54675 19444 54728 line +19444 54728 19160 54728 line +19160 54728 19089 54675 line +19089 54675 19089 54408 line +19089 54408 19160 54355 line +18876 55008 19515 55008 line +19444 55008 19515 55061 line +19515 55061 19515 55328 line +19515 55328 19444 55381 line +19444 55381 19160 55381 line +19160 55381 19089 55328 line +19089 55328 19089 55061 line +19089 55061 19160 55008 line +19302 55661 19302 56034 line +19302 56034 19444 56034 line +19444 56034 19515 55981 line +19515 55981 19515 55714 line +19515 55714 19444 55661 line +19444 55661 19160 55661 line +19160 55661 19089 55714 line +19089 55714 19089 55981 line +19089 55981 19160 56034 line +19089 56314 19515 56314 line +19373 56314 19515 56421 line +19515 56421 19515 56581 line +19515 56581 19373 56687 line +19160 57620 19089 57673 line +19089 57673 19089 57940 line +19089 57940 19160 57993 line +19160 57993 19231 57993 line +19231 57993 19302 57940 line +19302 57940 19302 57673 line +19302 57673 19373 57620 line +19373 57620 19444 57620 line +19444 57620 19515 57673 line +19515 57673 19515 57940 line +19515 57940 19444 57993 line +19729 58433 19657 58433 line +19444 58433 19160 58433 line +19160 58433 19089 58486 line +19089 58486 19089 58540 line +19729 59299 19089 59299 line +19089 59299 19089 58979 line +19089 58979 19160 58926 line +19160 58926 19444 58926 line +19444 58926 19515 58979 line +19515 58979 19515 59299 line +19302 59579 19302 59952 line +19302 59952 19444 59952 line +19444 59952 19515 59899 line +19515 59899 19515 59632 line +19515 59632 19444 59579 line +19444 59579 19160 59579 line +19160 59579 19089 59632 line +19089 59632 19089 59899 line +19089 59899 19160 59952 line +19089 60392 19231 60445 line +19231 60445 19586 60445 line +19586 60445 19729 60392 line +150 setlinewidth +17402 66371 17402 46686 line +80394 66371 17402 66371 line +80394 27001 80394 66371 line +17402 27001 80394 27001 line +17402 46686 17402 27001 line +50 setlinewidth +newpath 72000 30170 945 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +1890 setlinewidth +72000 31625 72000 33515 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 74000 31070 945 0 360 arc fill stroke +newpath 66000 30170 945 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +1890 setlinewidth +66000 31625 66000 33515 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 68000 31070 945 0 360 arc fill stroke +newpath 61850 63920 500 0 360 arc fill stroke +newpath 55650 63920 500 0 360 arc fill stroke +620 setlinewidth +58950 63540 58950 63820 line +58150 63540 58150 63820 line +59750 63540 59750 63820 line +58550 62540 58550 62820 line +57750 62540 57750 62820 line +59350 62540 59350 62820 line +50 setlinewidth +newpath 53600 63920 500 0 360 arc fill stroke +newpath 47400 63920 500 0 360 arc fill stroke +620 setlinewidth +50700 63540 50700 63820 line +49900 63540 49900 63820 line +51500 63540 51500 63820 line +50300 62540 50300 62820 line +49500 62540 49500 62820 line +51100 62540 51100 62820 line +50 setlinewidth +newpath 45350 63920 500 0 360 arc fill stroke +newpath 39150 63920 500 0 360 arc fill stroke +620 setlinewidth +42450 63540 42450 63820 line +41650 63540 41650 63820 line +43250 63540 43250 63820 line +42050 62540 42050 62820 line +41250 62540 41250 62820 line +42850 62540 42850 62820 line +50 setlinewidth +newpath 37100 63920 500 0 360 arc fill stroke +newpath 30900 63920 500 0 360 arc fill stroke +620 setlinewidth +34200 63540 34200 63820 line +33400 63540 33400 63820 line +35000 63540 35000 63820 line +33800 62540 33800 62820 line +33000 62540 33000 62820 line +34600 62540 34600 62820 line +50 setlinewidth +newpath 28850 63920 500 0 360 arc fill stroke +newpath 22650 63920 500 0 360 arc fill stroke +620 setlinewidth +25950 63540 25950 63820 line +25150 63540 25150 63820 line +26750 63540 26750 63820 line +25550 62540 25550 62820 line +24750 62540 24750 62820 line +26350 62540 26350 62820 line +50 setlinewidth +newpath 22650 29420 500 0 360 arc fill stroke +newpath 28850 29420 500 0 360 arc fill stroke +620 setlinewidth +25550 29800 25550 29520 line +26350 29800 26350 29520 line +24750 29800 24750 29520 line +25950 30800 25950 30520 line +26750 30800 26750 30520 line +25150 30800 25150 30520 line +50 setlinewidth +newpath 30900 29420 500 0 360 arc fill stroke +newpath 37100 29420 500 0 360 arc fill stroke +620 setlinewidth +33800 29800 33800 29520 line +34600 29800 34600 29520 line +33000 29800 33000 29520 line +34200 30800 34200 30520 line +35000 30800 35000 30520 line +33400 30800 33400 30520 line +50 setlinewidth +newpath 39150 29420 500 0 360 arc fill stroke +newpath 45350 29420 500 0 360 arc fill stroke +620 setlinewidth +42050 29800 42050 29520 line +42850 29800 42850 29520 line +41250 29800 41250 29520 line +42450 30800 42450 30520 line +43250 30800 43250 30520 line +41650 30800 41650 30520 line +50 setlinewidth +newpath 47400 29420 500 0 360 arc fill stroke +newpath 53600 29420 500 0 360 arc fill stroke +620 setlinewidth +50300 29800 50300 29520 line +51100 29800 51100 29520 line +49500 29800 49500 29520 line +50700 30800 50700 30520 line +51500 30800 51500 30520 line +49900 30800 49900 30520 line +50 setlinewidth +newpath 55650 29420 500 0 360 arc fill stroke +newpath 61850 29420 500 0 360 arc fill stroke +620 setlinewidth +58550 29800 58550 29520 line +59350 29800 59350 29520 line +57750 29800 57750 29520 line +58950 30800 58950 30520 line +59750 30800 59750 30520 line +58150 30800 58150 30520 line +50 setlinewidth +newpath 66500 51170 275 0 360 arc fill stroke +newpath 65500 51170 275 0 360 arc fill stroke +newpath 66500 53170 275 0 360 arc fill stroke +newpath 65500 53170 275 0 360 arc fill stroke +newpath 63000 53170 350 0 360 arc fill stroke +newpath 63000 55170 350 0 360 arc fill stroke +newpath 71500 64420 330 0 360 arc fill stroke +newpath 72500 64420 330 0 360 arc fill stroke +newpath 65500 60320 300 0 360 arc fill stroke +newpath 66500 60320 300 0 360 arc fill stroke +newpath 66500 61107 300 0 360 arc fill stroke +newpath 65500 61107 300 0 360 arc fill stroke +newpath 63638 62170 531 0 360 arc fill stroke +newpath 68362 62170 531 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +900 setlinewidth +32690 53920 33310 53920 line +50 setlinewidth +1 setlinecap 1 setlinejoin +620 setlinewidth +34000 54060 34000 53780 line +35000 54060 35000 53780 line +36000 54060 36000 53780 line +37000 54060 37000 53780 line +38000 54060 38000 53780 line +39000 54060 39000 53780 line +40000 54060 40000 53780 line +41000 54060 41000 53780 line +41000 57060 41000 56780 line +40000 57060 40000 56780 line +39000 57060 39000 56780 line +38000 57060 38000 56780 line +37000 57060 37000 56780 line +36000 57060 36000 56780 line +35000 57060 35000 56780 line +34000 57060 34000 56780 line +33000 57060 33000 56780 line +0 setlinewidth 0 setlinecap 0 setlinejoin +900 setlinewidth +39310 39420 38690 39420 line +50 setlinewidth +1 setlinecap 1 setlinejoin +620 setlinewidth +38000 39280 38000 39560 line +37000 39280 37000 39560 line +36000 39280 36000 39560 line +35000 39280 35000 39560 line +34000 39280 34000 39560 line +33000 39280 33000 39560 line +32000 39280 32000 39560 line +31000 39280 31000 39560 line +31000 36280 31000 36560 line +32000 36280 32000 36560 line +33000 36280 33000 36560 line +34000 36280 34000 36560 line +35000 36280 35000 36560 line +36000 36280 36000 36560 line +37000 36280 37000 36560 line +38000 36280 38000 36560 line +39000 36280 39000 36560 line +0 setlinewidth 0 setlinecap 0 setlinejoin +900 setlinewidth +50310 39420 49690 39420 line +50 setlinewidth +1 setlinecap 1 setlinejoin +620 setlinewidth +49000 39280 49000 39560 line +48000 39280 48000 39560 line +47000 39280 47000 39560 line +46000 39280 46000 39560 line +45000 39280 45000 39560 line +44000 39280 44000 39560 line +43000 39280 43000 39560 line +42000 39280 42000 39560 line +42000 36280 42000 36560 line +43000 36280 43000 36560 line +44000 36280 44000 36560 line +45000 36280 45000 36560 line +46000 36280 46000 36560 line +47000 36280 47000 36560 line +48000 36280 48000 36560 line +49000 36280 49000 36560 line +50000 36280 50000 36560 line +0 setlinewidth 0 setlinecap 0 setlinejoin +900 setlinewidth +43690 53920 44310 53920 line +50 setlinewidth +1 setlinecap 1 setlinejoin +620 setlinewidth +45000 54060 45000 53780 line +46000 54060 46000 53780 line +47000 54060 47000 53780 line +48000 54060 48000 53780 line +49000 54060 49000 53780 line +50000 54060 50000 53780 line +51000 54060 51000 53780 line +52000 54060 52000 53780 line +52000 57060 52000 56780 line +51000 57060 51000 56780 line +50000 57060 50000 56780 line +49000 57060 49000 56780 line +48000 57060 48000 56780 line +47000 57060 47000 56780 line +46000 57060 46000 56780 line +45000 57060 45000 56780 line +44000 57060 44000 56780 line +50 setlinewidth +newpath 62500 32670 350 0 360 arc fill stroke +newpath 62500 33670 350 0 360 arc fill stroke +newpath 53000 37420 350 0 360 arc fill stroke +newpath 54000 37420 350 0 360 arc fill stroke +newpath 55000 38420 350 0 360 arc fill stroke +newpath 53000 38420 350 0 360 arc fill stroke +newpath 62500 34670 350 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +550 setlinewidth +69975 53170 70525 53170 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 71250 53170 275 0 360 arc fill stroke +newpath 54000 38420 350 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +550 setlinewidth +61500 40895 61500 41445 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 61500 40170 275 0 360 arc fill stroke +newpath 62500 40170 275 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +550 setlinewidth +71725 35670 72275 35670 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 73000 35670 275 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +3500 setlinewidth +73750 41170 77250 41170 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 69000 42170 350 0 360 arc fill stroke +newpath 69000 41170 350 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +700 setlinewidth +68650 40170 69350 40170 line +50 setlinewidth +1 setlinecap 1 setlinejoin +0 setlinewidth 0 setlinecap 0 setlinejoin +900 setlinewidth +51310 49670 50690 49670 line +50 setlinewidth +1 setlinecap 1 setlinejoin +620 setlinewidth +50000 49530 50000 49810 line +49000 49530 49000 49810 line +48000 49530 48000 49810 line +47000 49530 47000 49810 line +46000 49530 46000 49810 line +45000 49530 45000 49810 line +44000 49530 44000 49810 line +43000 49530 43000 49810 line +42000 49530 42000 49810 line +41000 49530 41000 49810 line +40000 49530 40000 49810 line +39000 49530 39000 49810 line +38000 49530 38000 49810 line +37000 49530 37000 49810 line +36000 49530 36000 49810 line +35000 49530 35000 49810 line +34000 49530 34000 49810 line +33000 49530 33000 49810 line +32000 49530 32000 49810 line +32000 43530 32000 43810 line +33000 43530 33000 43810 line +34000 43530 34000 43810 line +35000 43530 35000 43810 line +36000 43530 36000 43810 line +37000 43530 37000 43810 line +38000 43530 38000 43810 line +39000 43530 39000 43810 line +40000 43530 40000 43810 line +41000 43530 41000 43810 line +42000 43530 42000 43810 line +43000 43530 43000 43810 line +44000 43530 44000 43810 line +45000 43530 45000 43810 line +46000 43530 46000 43810 line +47000 43530 47000 43810 line +48000 43530 48000 43810 line +49000 43530 49000 43810 line +50000 43530 50000 43810 line +51000 43530 51000 43810 line +50 setlinewidth +newpath 19370 62631 800 0 360 arc fill stroke +newpath 19370 30741 800 0 360 arc fill stroke +newpath 78425 62631 800 0 360 arc fill stroke +newpath 78425 30741 800 0 360 arc fill stroke +newpath 51000 42170 275 0 360 arc fill stroke +newpath 51000 41170 275 0 360 arc fill stroke +newpath 63000 49170 275 0 360 arc fill stroke +newpath 63000 50170 275 0 360 arc fill stroke +newpath 65500 58170 275 0 360 arc fill stroke +newpath 64500 58170 275 0 360 arc fill stroke +newpath 68750 35670 275 0 360 arc fill stroke +newpath 68750 36670 275 0 360 arc fill stroke +newpath 63250 37670 350 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +700 setlinewidth +59600 37670 58900 37670 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 71250 47670 350 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +700 setlinewidth +67600 47670 66900 47670 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 71250 46170 350 0 360 arc fill stroke +0 setlinewidth 0 setlinecap 0 setlinejoin +700 setlinewidth +67600 46170 66900 46170 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 55500 53170 300 0 360 arc fill stroke +newpath 55500 57170 300 0 360 arc fill stroke +newpath 55500 43920 300 0 360 arc fill stroke +newpath 55500 39920 300 0 360 arc fill stroke +newpath 57750 41170 300 0 360 arc fill stroke +newpath 57750 37170 300 0 360 arc fill stroke +newpath 68000 38920 300 0 360 arc fill stroke +newpath 64000 38920 300 0 360 arc fill stroke +newpath 63250 36170 300 0 360 arc fill stroke +newpath 59250 36170 300 0 360 arc fill stroke +newpath 53250 45670 300 0 360 arc fill stroke +newpath 53250 49670 300 0 360 arc fill stroke +newpath 66000 44670 300 0 360 arc fill stroke +newpath 62000 44670 300 0 360 arc fill stroke +newpath 66000 46170 300 0 360 arc fill stroke +newpath 62000 46170 300 0 360 arc fill stroke +newpath 66000 47670 300 0 360 arc fill stroke +newpath 62000 47670 300 0 360 arc fill stroke +newpath 54500 49670 300 0 360 arc fill stroke +newpath 54500 45670 300 0 360 arc fill stroke +620 setlinewidth +60360 44170 60640 44170 line +60360 45170 60640 45170 line +60360 46170 60640 46170 line +60360 47170 60640 47170 line +60360 48170 60640 48170 line +60360 49170 60640 49170 line +60360 50170 60640 50170 line +60360 51170 60640 51170 line +60360 52170 60640 52170 line +60360 53170 60640 53170 line +60360 54170 60640 54170 line +60360 55170 60640 55170 line +60360 56170 60640 56170 line +0 setlinewidth 0 setlinecap 0 setlinejoin +900 setlinewidth +60500 42860 60500 43480 line +50 setlinewidth +1 setlinecap 1 setlinejoin +620 setlinewidth +57360 56170 57640 56170 line +57360 55170 57640 55170 line +57360 54170 57640 54170 line +57360 53170 57640 53170 line +57360 52170 57640 52170 line +57360 51170 57640 51170 line +57360 50170 57640 50170 line +57360 49170 57640 49170 line +57360 48170 57640 48170 line +57360 47170 57640 47170 line +57360 46170 57640 46170 line +57360 45170 57640 45170 line +57360 44170 57640 44170 line +57360 43170 57640 43170 line +0 setlinewidth 0 setlinecap 0 setlinejoin +600 setlinewidth +61500 57620 61500 58220 line +50 setlinewidth +1 setlinecap 1 setlinejoin +newpath 61500 58920 300 0 360 arc fill stroke +newpath 70500 56170 300 0 360 arc fill stroke +newpath 65500 56170 300 0 360 arc fill stroke +newpath 32000 51170 500 0 360 arc fill stroke +newpath 26000 51170 500 0 360 arc fill stroke +500 setlinewidth +71250 53170 71250 53920 line +66500 51170 66500 53170 line +63000 50170 66250 50170 line +66500 50420 66500 51170 line +66250 50170 66500 50420 line +71250 63420 71500 63420 line +68250 63420 71250 63420 line +71500 63420 72250 63420 line +72250 63420 72500 63670 line +72500 63670 72500 64420 line +71250 53170 71250 47670 line +71250 47670 71250 46170 line +71250 46170 71250 36670 line +54000 41170 51000 41170 line +63750 28420 63750 29670 line +63750 29670 63750 33170 line +63750 33170 63250 33670 line +63250 33670 62500 33670 line +57750 41170 54000 41170 line +63750 28420 62500 28420 line +32000 51170 32000 49670 line +54000 38420 54000 41170 line +71500 54170 71500 63420 line +71250 53920 71500 54170 line +66000 28420 66000 30170 line +72000 28420 72000 30170 line +63750 28420 66000 28420 line +66000 28420 72000 28420 line +72000 28420 74500 28420 line +73500 35670 73000 35670 line +54000 38420 54000 37420 line +68362 63420 68250 63420 line +74500 34670 73500 35670 line +24000 51170 26000 51170 line +74500 33670 74500 34670 line +75750 32420 74500 33670 line +75750 29670 75750 32420 line +74500 28420 75750 29670 line +61500 41170 64500 41170 line +64500 57170 64500 57420 line +61250 34170 56250 34170 line +64500 58170 64500 58920 line +64500 58920 64500 60670 line +64500 60670 64937 61107 line +64937 61107 65500 61107 line +66500 53170 66500 53420 line +64500 55420 64500 57420 line +315 setlinewidth +61500 58920 64500 58920 line +55500 57170 55500 57420 line +61000 58920 61500 58920 line +60000 57920 61000 58920 line +56000 57920 60000 57920 line +55500 57420 56000 57920 line +58750 51670 58500 51670 line +59500 50420 59750 50170 line +59750 50170 60500 50170 line +58750 51670 59500 50920 line +56650 49270 56650 51570 line +56650 51570 56750 51670 line +157 setlinewidth +56750 51670 58500 51670 line +315 setlinewidth +57500 49170 56750 49170 line +56750 49170 56650 49270 line +59500 50920 59500 50420 line +500 setlinewidth +65500 61107 65500 62170 line +68362 62170 68362 63420 line +32000 49670 32000 47670 line +54000 37420 54000 36420 line +54000 36420 54000 36420 line +68750 36670 71500 36670 line +71500 36670 71250 36670 line +71250 36670 72000 36670 line +72000 36670 73000 36670 line +73000 36670 73000 35670 line +63638 62170 65500 62170 line +65500 62920 66000 63420 line +66000 63420 68250 63420 line +65500 62170 65500 62920 line +57750 41170 61500 41170 line +61750 33670 61250 34170 line +64500 57420 64500 58170 line +56250 34170 54000 36420 line +62500 33670 61750 33670 line +62500 28420 61750 27670 line +61750 27670 22500 27670 line +22500 27670 21500 28670 line +21500 28670 21500 48670 line +21500 48670 24000 51170 line +60500 50170 63000 50170 line +66500 53420 64500 55420 line +72000 34170 72000 32570 line +69000 39420 69000 40170 line +68500 38920 69000 39420 line +66150 32570 67750 34170 line +72000 35670 72000 34170 line +67250 38170 68000 38920 line +68750 35670 67750 35670 line +67750 34170 72000 34170 line +66000 32570 66150 32570 line +665 setlinewidth +72000 35670 68750 35670 line +500 setlinewidth +67750 35670 67250 36170 line +68000 38920 68500 38920 line +67250 36170 67250 38170 line +315 setlinewidth +60250 61170 60250 63180 line +60250 63180 59750 63680 line +51000 56920 51000 57420 line +55000 59920 59000 59920 line +53000 57920 55000 59920 line +51000 57420 51500 57920 line +51500 57920 53000 57920 line +59750 63680 58950 63680 line +59000 59920 60250 61170 line +500 setlinewidth +51500 30060 51100 29660 line +27500 37170 23500 33170 line +51100 29020 51100 29660 line +24750 62680 24750 63280 line +51500 30660 51500 30060 line +59750 30660 59750 30060 line +41250 62680 41250 63280 line +35000 30060 34600 29660 line +35000 30660 35000 30060 line +26750 30660 26750 30060 line +33000 63280 33400 63680 line +43250 30060 42850 29660 line +43250 30660 43250 30060 line +59750 30060 59350 29660 line +35000 30660 39510 30660 line +40000 29670 41000 28670 line +40000 30170 40000 29670 line +42850 29020 42850 29660 line +39510 30660 40000 30170 line +49250 28670 50750 28670 line +26750 30660 31490 30660 line +24500 28670 26000 28670 line +43250 30660 47760 30660 line +26350 29020 26350 29660 line +24750 62680 24750 59670 line +33000 62680 33000 63280 line +57750 62680 57750 63280 line +24750 63280 25150 63680 line +34250 28670 34600 29020 line +49500 63280 49900 63680 line +47760 30660 48250 30170 line +26750 30060 26350 29660 line +41000 28670 42500 28670 line +26000 28670 26350 29020 line +48250 29670 49250 28670 line +48250 30170 48250 29670 line +42500 28670 42850 29020 line +23500 33170 23500 29670 line +31750 29670 32750 28670 line +33000 62680 28740 62680 line +25150 64320 25150 63680 line +25500 64670 25150 64320 line +27250 64670 25500 64670 line +27750 64170 27250 64670 line +27750 63670 27750 64170 line +28740 62680 27750 63670 line +41250 62680 36990 62680 line +33400 64320 33400 63680 line +33750 64670 33400 64320 line +35500 64670 33750 64670 line +36000 64170 35500 64670 line +36000 63670 36000 64170 line +36990 62680 36000 63670 line +49500 62680 45240 62680 line +41650 64320 41650 63680 line +42000 64670 41650 64320 line +44000 64670 42000 64670 line +44250 64420 44000 64670 line +44250 63670 44250 64420 line +45240 62680 44250 63670 line +57750 62680 53490 62680 line +49900 64320 49900 63680 line +50250 64670 49900 64320 line +52000 64670 50250 64670 line +52500 64170 52000 64670 line +52500 63670 52500 64170 line +53490 62680 52500 63670 line +51500 30660 56260 30660 line +59350 29020 59350 29660 line +59000 28670 59350 29020 line +57500 28670 59000 28670 line +56500 29670 57500 28670 line +56500 30420 56500 29670 line +56260 30660 56500 30420 line +59750 30660 61740 30660 line +62500 31420 62500 32670 line +61740 30660 62500 31420 line +50750 28670 51100 29020 line +34600 29020 34600 29660 line +49500 62680 49500 63280 line +32750 28670 34250 28670 line +57750 63280 58150 63680 line +31750 30400 31750 29670 line +31490 30660 31750 30400 line +23500 29670 24500 28670 line +24750 59670 27500 56920 line +27500 56920 27500 37170 line +41250 63280 41650 63680 line +315 setlinewidth +49000 56920 49000 58170 line +58250 61420 58550 61720 line +49000 58170 50250 59420 line +50250 59420 51500 59420 line +51500 59420 53500 61420 line +58550 61720 58550 62680 line +53500 61420 58250 61420 line +52250 58670 54250 60670 line +50000 57670 51000 58670 line +58750 60670 59350 61270 line +59350 61270 59350 62680 line +50000 56920 50000 57670 line +54250 60670 58750 60670 line +51000 58670 52250 58670 line +48000 58420 49750 60170 line +52000 61420 52000 63180 line +48000 56920 48000 58420 line +50750 60170 52000 61420 line +51500 63680 50700 63680 line +49750 60170 50750 60170 line +52000 63180 51500 63680 line +49750 61670 50300 62220 line +46000 56920 46000 59420 line +48250 61670 49750 61670 line +46000 59420 48250 61670 line +50300 62220 50300 62680 line +47000 58920 49000 60920 line +47000 56920 47000 58920 line +51100 61770 51100 62680 line +50250 60920 51100 61770 line +49000 60920 50250 60920 line +45000 56920 45000 58170 line +43250 63680 42450 63680 line +43750 63180 43250 63680 line +43750 59420 43750 63180 line +45000 58170 43750 59420 line +40000 56920 40000 59420 line +42050 61470 42050 62680 line +40000 59420 42050 61470 line +44000 57420 42850 58570 line +42850 58570 42850 62680 line +44000 56920 44000 57420 line +35000 63680 34200 63680 line +35500 63180 35000 63680 line +39000 58420 35500 61920 line +35500 61920 35500 63180 line +39000 56920 39000 58420 line +37000 57920 33800 61120 line +37000 56920 37000 57920 line +33800 61120 33800 62680 line +38000 58170 34600 61570 line +34600 61570 34600 62680 line +38000 56920 38000 58170 line +36000 57670 33500 60170 line +36000 56920 36000 57670 line +27250 63180 26750 63680 line +26750 63680 25950 63680 line +28250 60170 27250 61170 line +33500 60170 28250 60170 line +27250 61170 27250 63180 line +34000 56920 34000 57170 line +32500 58670 27250 58670 line +34000 57170 32500 58670 line +27250 58670 25550 60370 line +25550 60370 25550 62680 line +26350 60820 26350 62680 line +35000 57420 33000 59420 line +27750 59420 26350 60820 line +33000 59420 27750 59420 line +35000 56920 35000 57420 line +26250 34420 24250 32420 line +24750 29660 25550 29660 line +33000 36420 33000 36170 line +33000 36170 33000 36420 line +24750 29660 24250 30160 line +31250 34420 26250 34420 line +31250 34420 31250 34420 line +24250 32420 24250 30160 line +31250 34420 33000 36170 line +25950 31370 27000 32420 line +35000 35670 35000 36420 line +27000 32420 31750 32420 line +25950 30660 25950 31370 line +31750 32420 35000 35670 line +34000 35920 34000 36420 line +25150 31820 26750 33420 line +31500 33420 34000 35920 line +25150 30660 25150 31820 line +26750 33420 31500 33420 line +32500 31920 32500 30160 line +36000 36420 36000 35420 line +36000 35420 32500 31920 line +33000 29660 33800 29660 line +32500 30160 33000 29660 line +38000 34920 34200 31120 line +34200 31120 34200 30660 line +38000 36420 38000 34920 line +37000 36420 37000 35170 line +33400 31570 33400 30660 line +37000 35170 33400 31570 line +41250 29660 42050 29660 line +40750 33170 40750 30160 line +39000 34920 40750 33170 line +40750 30160 41250 29660 line +39000 36420 39000 34920 line +42450 32620 42450 30660 line +44000 36420 44000 34170 line +44000 34170 42450 32620 line +43000 36420 43000 34920 line +43000 34920 41650 33570 line +41650 33570 41650 30660 line +49000 31170 49000 30160 line +49000 30160 49500 29660 line +49500 29660 50300 29660 line +45000 35170 49000 31170 line +45000 36420 45000 35170 line +47000 36420 47000 35920 line +50700 32220 50700 30660 line +47000 35920 50700 32220 line +46000 36420 46000 35670 line +46000 35670 49900 31770 line +49900 31770 49900 30660 line +48000 36170 50750 33420 line +50750 33420 53000 33420 line +56750 31670 57250 31170 line +57750 29660 58550 29660 line +48000 36420 48000 36170 line +57250 31170 57250 30160 line +53250 33420 55000 31670 line +57250 30160 57750 29660 line +55000 31670 56750 31670 line +53000 33420 53250 33420 line +55750 33170 57750 33170 line +51250 35170 53750 35170 line +50000 36420 50000 36170 line +50000 36420 51250 35170 line +53750 35170 55750 33170 line +57750 33170 58950 31970 line +58950 31970 58950 30660 line +49000 36420 49000 36170 line +57250 32420 58150 31520 line +53500 34420 55500 32420 line +55500 32420 57250 32420 line +49000 36170 50750 34420 line +53250 34420 53500 34420 line +58150 31520 58150 30660 line +50750 34420 53250 34420 line +60500 51170 63000 51170 line +63000 51170 65500 51170 line +63000 53170 63000 51170 line +55000 48020 55350 48020 line +63500 55170 65500 53170 line +33000 49670 33000 48920 line +42900 48020 55000 48020 line +55000 48020 55100 48020 line +42500 48420 42900 48020 line +63000 55170 63500 55170 line +42250 50670 42500 50420 line +40750 50670 42250 50670 line +40500 50420 40750 50670 line +157 setlinewidth +40500 48920 40500 50420 line +315 setlinewidth +40250 48670 40500 48920 line +33250 48670 40250 48670 line +33000 48920 33250 48670 line +59250 52670 59750 52170 line +59750 52170 60500 52170 line +157 setlinewidth +56500 52670 58500 52670 line +315 setlinewidth +56000 52170 56500 52670 line +56000 48670 56000 52170 line +55350 48020 56000 48670 line +157 setlinewidth +42500 50420 42500 48420 line +315 setlinewidth +61750 53920 63000 55170 line +61750 52920 61750 53920 line +61000 52170 61750 52920 line +60500 52170 61000 52170 line +59250 52670 58500 52670 line +53250 56670 55500 58920 line +61750 62170 64000 64420 line +61750 61170 61750 62170 line +59500 58920 61750 61170 line +55500 58920 59500 58920 line +64000 64420 71500 64420 line +53250 49670 53250 56670 line +500 setlinewidth +65500 56170 65500 58170 line +65500 60320 65500 58170 line +315 setlinewidth +66000 47670 67250 47670 line +66500 60320 66850 60320 line +67750 47670 67250 47670 line +68250 48170 67750 47670 line +68250 58920 68250 56670 line +68250 56670 68250 48170 line +66850 60320 68250 58920 line +66000 46170 66000 47670 line +69000 57420 69000 55920 line +67250 45670 67250 46170 line +67313 61107 69000 59420 line +69000 59420 69000 57420 line +69000 55920 69000 47420 line +66000 44670 66250 44670 line +66250 44670 67250 45670 line +69000 47420 67750 46170 line +67313 61107 66500 61107 line +67250 46170 67750 46170 line +31000 43920 31250 43670 line +31250 43670 32000 43670 line +33000 53920 34000 53920 line +31000 45670 31000 52420 line +31000 52420 32500 53920 line +33000 53920 32500 53920 line +31000 45670 31000 43920 line +35000 49670 35000 53920 line +36000 49670 36000 53920 line +37000 49670 37000 53920 line +38000 49670 38000 53920 line +39000 49670 39000 53920 line +40000 49670 40000 53920 line +500 setlinewidth +53000 38420 52000 38420 line +30000 53170 31750 54920 line +30000 43170 30000 53170 line +31000 42170 30000 43170 line +31000 39420 31000 42170 line +52000 38420 42000 38420 line +41000 53920 41000 54920 line +42000 39420 42000 38420 line +31000 39420 31000 38420 line +52000 54920 41000 54920 line +52000 53920 52000 54920 line +31000 38420 42000 38420 line +31750 54920 41000 54920 line +30750 55920 41000 55920 line +53000 37420 51000 37420 line +51000 37420 42250 37420 line +41000 56920 41000 55920 line +42000 36420 42000 37420 line +31000 37420 30000 37420 line +31000 36420 31000 37420 line +31000 37420 42250 37420 line +28750 38670 28750 53920 line +52000 55920 41000 55920 line +52000 56920 52000 55920 line +42000 37420 42250 37420 line +30000 37420 28750 38670 line +28750 53920 30750 55920 line +315 setlinewidth +39000 43670 39000 39420 line +38000 43670 38000 39420 line +37000 43670 37000 39420 line +36000 43670 36000 39420 line +35000 43670 35000 39420 line +34000 43670 34000 39420 line +33000 39420 32000 39420 line +33000 43670 33000 39420 line +50000 43670 50000 39420 line +49000 43670 49000 39420 line +48000 43670 48000 39420 line +47000 43670 47000 39420 line +46000 43670 46000 39420 line +45000 43670 45000 39420 line +44000 43670 44000 39420 line +43000 43670 43000 39420 line +44000 49670 44000 53920 line +45000 49670 45000 53920 line +46000 49670 46000 53920 line +47000 49670 47000 53920 line +48000 49670 48000 53920 line +49000 49670 49000 53920 line +50000 49670 50000 53920 line +51000 49670 51000 53920 line +500 setlinewidth +66000 35920 66000 38920 line +62500 34670 64750 34670 line +66000 35920 64750 34670 line +68250 41170 69000 41170 line +66000 38920 68250 41170 line +57250 35170 55000 37420 line +62000 35170 62500 34670 line +55000 38420 55000 37420 line +62000 35170 57250 35170 line +70250 53170 70250 55920 line +70250 55920 70500 56170 line +315 setlinewidth +57500 51170 58000 51170 line +59500 49170 60500 49170 line +58500 50170 59500 49170 line +58500 50670 58500 50170 line +58000 51170 58500 50670 line +500 setlinewidth +60500 49170 63000 49170 line +63000 49170 63000 42170 line +51000 42170 63000 42170 line +63000 42170 65250 42170 line +65250 42170 70000 46920 line +70000 46920 70000 49420 line +70000 49420 70000 52670 line +70000 52670 70250 52920 line +70250 52920 70250 53170 line +51000 43670 51000 42170 line +315 setlinewidth +55500 39920 56250 39170 line +60500 39170 61500 40170 line +56250 39170 57750 39170 line +57750 39170 60500 39170 line +57750 37170 57750 39170 line +62500 38420 63250 37670 line +62500 40170 62500 38420 line +65000 36670 65000 39170 line +64500 36170 65000 36670 line +63250 36170 64500 36170 line +68000 42170 69000 42170 line +65000 39170 68000 42170 line +54750 48670 55250 49170 line +55250 52920 55500 53170 line +55250 49170 55250 52920 line +55500 53170 57500 53170 line +43000 48920 43250 48670 line +43000 49670 43000 48920 line +43250 48670 54750 48670 line +60500 45170 59000 45170 line +56250 45920 56250 46920 line +56250 46920 55750 47420 line +55750 47420 54750 47420 line +58500 45670 59000 45170 line +157 setlinewidth +56500 45670 58500 45670 line +315 setlinewidth +42250 47420 54750 47420 line +42000 47670 42250 47420 line +42000 47920 42000 47670 line +42000 47920 42000 49670 line +56500 45670 56250 45920 line +60500 44170 58750 44170 line +55500 46670 55500 45420 line +55500 45420 56250 44670 line +56250 44670 56500 44670 line +58250 44670 58750 44170 line +157 setlinewidth +56500 44670 58250 44670 line +315 setlinewidth +55500 46670 54250 46670 line +41000 49670 41000 47570 line +41000 47570 41900 46670 line +41900 46670 54250 46670 line +54250 46670 54300 46670 line +157 setlinewidth +42500 44170 42500 42920 line +315 setlinewidth +42500 42920 42250 42670 line +42250 42670 40250 42670 line +40250 42670 40000 42920 line +40000 42920 40000 43670 line +51500 44670 52250 43920 line +55500 43920 52250 43920 line +43000 44670 50250 44670 line +42500 44170 43000 44670 line +50250 44670 51500 44670 line +52150 46020 52900 46020 line +41450 46020 52150 46020 line +41000 45570 41450 46020 line +41000 43670 41000 45570 line +52900 46020 53250 45670 line +54000 44920 54250 44920 line +52050 45370 52500 44920 line +52500 44920 54000 44920 line +51250 45370 52050 45370 line +54500 45170 54500 45670 line +54250 44920 54500 45170 line +42100 45370 51250 45370 line +51250 45370 51300 45370 line +42000 43670 42000 45270 line +42000 45270 42100 45370 line +64000 36920 64000 38920 line +59250 37670 59250 36920 line +59250 36920 59250 36170 line +59250 36920 64000 36920 line +62000 44920 62000 44670 line +60750 46170 62000 44920 line +60250 46170 60500 46170 line +60500 46170 60750 46170 line +61000 47170 62000 46170 line +60500 47170 61000 47170 line +60500 48170 61500 48170 line +61500 48170 62000 47670 line +54500 49670 54500 53670 line +55000 54170 57500 54170 line +54500 53670 55000 54170 line +60500 56920 61500 57920 line +60500 56170 60500 56920 line +319 setlinewidth +58484 53692 59516 53692 line +58583 53948 59415 53948 line +58609 54204 59392 54204 line +58568 54460 59432 54460 line +54066 54460 54136 54460 line +58499 54716 59500 54716 line +54066 54716 54392 54716 line +58588 54972 59411 54972 line +54066 54972 54850 54972 line +58609 55228 59392 55228 line +54066 55228 56392 55228 line +58558 55484 59442 55484 line +54066 55484 56442 55484 line +58509 55740 59489 55740 line +54066 55740 56489 55740 line +58593 55996 59406 55996 line +54066 55996 56406 55996 line +58609 56252 59392 56252 line +55782 56252 56392 56252 line +54066 56252 55212 56252 line +58549 56508 59452 56508 line +56194 56508 56452 56508 line +54241 56508 54807 56508 line +58409 56764 59593 56764 line +56367 56764 56593 56764 line +54497 56764 54630 56764 line +58109 57020 59694 57020 line +56448 57020 56893 57020 line +56456 57276 59769 57276 line +56387 57532 59958 57532 line +56237 57788 60214 57788 line +55895 58044 60470 58044 line +60024 58300 60544 58300 line +60289 58556 60613 58556 line +60545 58812 60545 58812 line +31816 50840 34184 50840 line +31816 51096 34184 51096 line +31816 51352 34184 51352 line +31816 51608 34184 51608 line +31816 51864 34184 51864 line +31854 52120 34184 52120 line +32110 52376 34184 52376 line +32366 52632 34184 52632 line +33624 52888 33624 52888 line +59316 50574 59480 50574 line +59300 50830 59452 50830 line +59199 51086 59391 51086 line +58982 51342 59407 51342 line +58726 51598 59168 51598 line +58557 51854 58912 51854 line +39223 44753 39773 44753 line +38223 44753 38773 44753 line +37223 44753 37773 44753 line +36223 44753 36773 44753 line +35223 44753 35773 44753 line +34223 44753 34773 44753 line +33223 44753 33773 44753 line +32223 44753 32773 44753 line +31816 45009 40184 45009 line +31816 45265 40184 45265 line +31816 45521 40184 45521 line +31816 45777 40214 45777 line +31816 46033 40329 46033 line +31816 46289 40565 46289 line +31816 46545 40821 46545 line +31816 46801 40615 46801 line +31816 47057 40369 47057 line +31816 47313 40229 47313 line +31816 47569 40184 47569 line +31816 47825 40184 47825 line +31816 48081 32687 48081 line +31816 48337 32429 48337 line +32254 48593 32254 48593 line +63909 43218 65011 43218 line +63909 43474 65267 43474 line +63909 43730 65523 43730 line +63909 43986 65328 43986 line +63909 44242 65139 44242 line +63909 44498 65057 44498 line +63909 44754 65043 44754 line +63909 45010 65103 45010 line +63909 45266 65248 45266 line +63909 45522 65294 45522 line +63909 45778 65125 45778 line +63909 46034 65051 46034 line +63909 46290 65046 46290 line +63909 46546 65119 46546 line +63909 46802 65184 46802 line +63909 47058 65184 47058 line +63909 47314 65110 47314 line +63909 47570 65044 47570 line +63909 47826 65054 47826 line +63909 48082 65134 48082 line +63909 48338 65314 48338 line +66266 48594 66573 48594 line +63909 48594 65734 48594 line +63909 48850 67434 48850 line +63931 49106 67434 49106 line +63914 49362 67434 49362 line +63824 49618 67434 49618 line +63891 49874 67434 49874 line +63932 50130 67434 50130 line +67008 50386 67434 50386 line +67270 50642 67434 50642 line +67396 50898 67434 50898 line +67432 51154 67434 51154 line +67405 51410 67434 51410 line +67292 51666 67434 51666 line +67056 51922 67434 51922 line +63816 52178 67434 52178 line +67081 52434 67434 52434 line +63816 52434 64922 52434 line +67304 52690 67434 52690 line +63889 52690 64698 52690 line +67407 52946 67434 52946 line +63982 52946 64570 52946 line +67433 53202 67434 53202 line +64007 53202 64314 53202 line +67392 53458 67434 53458 line +63971 53458 64058 53458 line +67260 53714 67434 53714 line +66985 53970 67434 53970 line +65985 53970 66016 53970 line +65598 54226 67434 54226 line +65342 54482 67434 54482 line +65086 54738 67434 54738 line +64830 54994 67434 54994 line +61592 54994 61669 54994 line +65777 55250 67434 55250 line +64574 55250 65221 55250 line +61609 55250 61925 55250 line +66192 55506 67434 55506 line +64318 55506 64809 55506 line +61549 55506 62048 55506 line +66366 55762 67434 55762 line +64059 55762 64631 55762 line +61518 55762 62184 55762 line +66447 56018 67434 56018 line +63547 56018 64554 56018 line +61597 56018 62455 56018 line +66456 56274 67434 56274 line +61607 56274 64543 56274 line +66409 56530 67434 56530 line +61540 56530 64591 56530 line +66409 56786 67434 56786 line +61519 56786 64591 56786 line +66409 57042 67434 57042 line +62121 57042 64591 57042 line +66409 57298 67434 57298 line +62378 57298 64162 57298 line +66409 57554 67434 57554 line +62459 57554 63796 57554 line +66409 57810 67434 57810 line +62459 57810 63637 57810 line +66431 58066 67434 58066 line +62459 58066 63569 58066 line +66422 58322 67434 58322 line +62452 58322 63578 58322 line +66409 58578 67434 58578 line +62396 58578 63659 58578 line +66409 58834 67182 58834 line +62455 58834 63844 58834 line +66409 59090 66926 59090 line +62443 59090 64338 59090 line +66409 59346 66670 59346 line +62361 59346 64591 59346 line +62174 59602 64591 59602 line +61697 59858 64591 59858 line +61847 60114 64564 60114 line +62103 60370 64543 60370 line +62353 60626 64589 60626 line +62510 60882 64567 60882 line +64230 61138 64543 61138 line +62563 61138 63039 61138 line +64545 61394 64582 61394 line +62566 61394 62734 61394 line +62566 61650 62566 61650 line +50969 39469 54651 39469 line +50969 39725 54562 39725 line +50960 39981 54543 39981 line +57975 40237 60413 40237 line +56406 40237 57530 40237 line +51088 40237 54594 40237 line +50858 40237 50934 40237 line +58428 40493 60622 40493 line +56270 40493 57072 40493 line +51643 40493 54732 40493 line +58611 40749 60581 40749 line +55985 40749 56886 40749 line +51834 40749 55018 40749 line +58694 41005 60566 41005 line +51920 41005 56806 41005 line +58707 41261 60566 41261 line +51933 41261 56792 41261 line +60072 31715 61509 31715 line +59766 31971 61591 31971 line +59721 32227 61591 32227 line +59581 32483 61509 32483 line +59335 32739 61493 32739 line +59079 32995 61544 32995 line +58823 33251 61581 33251 line +58567 33507 61505 33507 line +58308 33763 61493 33763 line +56055 34019 61554 34019 line +55799 34275 57113 34275 line +55543 34531 56603 34531 line +55287 34787 56347 34787 line +55031 35043 56091 35043 line +54775 35299 55835 35299 line +54519 35555 55579 35555 line +54250 35811 55323 35811 line +51506 36067 55067 36067 line +51250 36323 54811 36323 line +54555 36579 54555 36579 line +17977 27652 79819 27652 line +59495 27908 79819 27908 line +51245 27908 57005 27908 line +42995 27908 48755 27908 line +34745 27908 40505 27908 line +26495 27908 32255 27908 line +17977 27908 24005 27908 line +59779 28164 79819 28164 line +51529 28164 56720 28164 line +43279 28164 48470 28164 line +35029 28164 40220 28164 line +26779 28164 31970 28164 line +17977 28164 23720 28164 line +62435 28420 79819 28420 line +60026 28420 61259 28420 line +56235 28420 56464 28420 line +54185 28420 55059 28420 line +51776 28420 53009 28420 line +47985 28420 48214 28420 line +45935 28420 46809 28420 line +43526 28420 44759 28420 line +39735 28420 39964 28420 line +37685 28420 38559 28420 line +35276 28420 36509 28420 line +31485 28420 31714 28420 line +29435 28420 30309 28420 line +27026 28420 28259 28420 line +23235 28420 23464 28420 line +17977 28420 22059 28420 line +72580 28676 79819 28676 line +66580 28676 71415 28676 line +62742 28676 65415 28676 line +60189 28676 60958 28676 line +54492 28676 54758 28676 line +51939 28676 52708 28676 line +46242 28676 46508 28676 line +43689 28676 44458 28676 line +37992 28676 38258 28676 line +35439 28676 36208 28676 line +29742 28676 30008 28676 line +27189 28676 27958 28676 line +17977 28676 21758 28676 line +73023 28932 79819 28932 line +67023 28932 70973 28932 line +62900 28932 64973 28932 line +60250 28932 60797 28932 line +52000 28932 52547 28932 line +43750 28932 44297 28932 line +35500 28932 36047 28932 line +27250 28932 27797 28932 line +17977 28932 21597 28932 line +73269 29188 79819 29188 line +67269 29188 70726 29188 line +62984 29188 64726 29188 line +60259 29188 60715 29188 line +52009 29188 52465 29188 line +43759 29188 44215 29188 line +35509 29188 35965 29188 line +27259 29188 27715 29188 line +17977 29188 21515 29188 line +79104 29444 79819 29444 line +73430 29444 77749 29444 line +67430 29444 70563 29444 line +63006 29444 64563 29444 line +60413 29444 60693 29444 line +52163 29444 52443 29444 line +43913 29444 44193 29444 line +35663 29444 35943 29444 line +27413 29444 27693 29444 line +20049 29444 21493 29444 line +17977 29444 18694 29444 line +79447 29700 79819 29700 line +74832 29700 77402 29700 line +68832 29700 70462 29700 line +62976 29700 64462 29700 line +60583 29700 60726 29700 line +52333 29700 52476 29700 line +44083 29700 44226 29700 line +35833 29700 35976 29700 line +27583 29700 27726 29700 line +20392 29700 21526 29700 line +17977 29700 18347 29700 line +79656 29956 79819 29956 line +75154 29956 77194 29956 line +69154 29956 70409 29956 line +62882 29956 64409 29956 line +20601 29956 21620 29956 line +17977 29956 18139 29956 line +79786 30212 79819 30212 line +75356 30212 77065 30212 line +69356 30212 70398 30212 line +62696 30212 64398 30212 line +20731 30212 21804 30212 line +17977 30212 18010 30212 line +75486 30468 76991 30468 line +69486 30468 70425 30468 line +62832 30468 64425 30468 line +20803 30468 22153 30468 line +75565 30724 76966 30724 line +69565 30724 70494 30724 line +63088 30724 64494 30724 line +20826 30724 22591 30724 line +75599 30980 76985 30980 line +69599 30980 70612 30980 line +63289 30980 64612 30980 line +20810 30980 22591 30980 line +79799 31236 79819 31236 line +75602 31236 77051 31236 line +69602 31236 70522 31236 line +63389 31236 64522 31236 line +20744 31236 22591 31236 line +17977 31236 17995 31236 line +79678 31492 79819 31492 line +75551 31492 77171 31492 line +69551 31492 70409 31492 line +63409 31492 64409 31492 line +20623 31492 22591 31492 line +17977 31492 18116 31492 line +79482 31748 79819 31748 line +75455 31748 77368 31748 line +69455 31748 70396 31748 line +63409 31748 64396 31748 line +20427 31748 22591 31748 line +17977 31748 18313 31748 line +79163 32004 79819 32004 line +75304 32004 77691 32004 line +69304 32004 70396 32004 line +63409 32004 64396 32004 line +20108 32004 22591 32004 line +17977 32004 18636 32004 line +75078 32260 79819 32260 line +69078 32260 70396 32260 line +63421 32260 64396 32260 line +17977 32260 22591 32260 line +74698 32516 79819 32516 line +68698 32516 70396 32516 line +63498 32516 64396 32516 line +17977 32516 22591 32516 line +73604 32772 79819 32772 line +67637 32772 70396 32772 line +63508 32772 64396 32772 line +17977 32772 22591 32772 line +73604 33028 79819 33028 line +67893 33028 70396 33028 line +63444 33028 64396 33028 line +20289 33028 22591 33028 line +17977 33028 18529 33028 line +73604 33284 79819 33284 line +63431 33284 64396 33284 line +20289 33284 22602 33284 line +17977 33284 18529 33284 line +73604 33540 79819 33540 line +63504 33540 64396 33540 line +20289 33540 22672 33540 line +17977 33540 18529 33540 line +73543 33796 79819 33796 line +20289 33796 22843 33796 line +17977 33796 18529 33796 line +73328 34052 79819 34052 line +20289 34052 23096 34052 line +17977 34052 18529 34052 line +72909 34308 79819 34308 line +20289 34308 23352 34308 line +17977 34308 18529 34308 line +72909 34564 79819 34564 line +20289 34564 23608 34564 line +17977 34564 18529 34564 line +73392 34820 79819 34820 line +20289 34820 23864 34820 line +17977 34820 18529 34820 line +73724 35076 79819 35076 line +20289 35076 24120 35076 line +17977 35076 18529 35076 line +73872 35332 79819 35332 line +20289 35332 24376 35332 line +17977 35332 18529 35332 line +73931 35588 79819 35588 line +20289 35588 24632 35588 line +17977 35588 18529 35588 line +73918 35844 79819 35844 line +20289 35844 24888 35844 line +17977 35844 18529 35844 line +73833 36100 79819 36100 line +20289 36100 25144 36100 line +17977 36100 18529 36100 line +73635 36356 79819 36356 line +20289 36356 25400 36356 line +17977 36356 18529 36356 line +72292 36612 79819 36612 line +20289 36612 25656 36612 line +17977 36612 18529 36612 line +69663 36868 79819 36868 line +20289 36868 25912 36868 line +17977 36868 18529 36868 line +69570 37124 79819 37124 line +20289 37124 26168 37124 line +17977 37124 18529 37124 line +69361 37380 79819 37380 line +20289 37380 26424 37380 line +17977 37380 18529 37380 line +68159 37636 79819 37636 line +20289 37636 26591 37636 line +17977 37636 18529 37636 line +68256 37892 79819 37892 line +20289 37892 26591 37892 line +17977 37892 18529 37892 line +68975 38148 79819 38148 line +20289 38148 26591 38148 line +17977 38148 18529 38148 line +69270 38404 79819 38404 line +20289 38404 26591 38404 line +17977 38404 18529 38404 line +69526 38660 79819 38660 line +20289 38660 26591 38660 line +17977 38660 18529 38660 line +77678 38916 79819 38916 line +69757 38916 73322 38916 line +20289 38916 26591 38916 line +17977 38916 18529 38916 line +77860 39172 79819 39172 line +69869 39172 73139 39172 line +20289 39172 26591 39172 line +17977 39172 18529 39172 line +77909 39428 79819 39428 line +69909 39428 73091 39428 line +20289 39428 26591 39428 line +17977 39428 18529 39428 line +77909 39684 79819 39684 line +69995 39684 73091 39684 line +63316 39684 63419 39684 line +20289 39684 26591 39684 line +17977 39684 18529 39684 line +77909 39940 79819 39940 line +70009 39940 73091 39940 line +63405 39940 64616 39940 line +20289 39940 26591 39940 line +17977 39940 18529 39940 line +77909 40196 79819 40196 line +70009 40196 73091 40196 line +63433 40196 64872 40196 line +20289 40196 26591 40196 line +17977 40196 18529 40196 line +77909 40452 79819 40452 line +70009 40452 73091 40452 line +63394 40452 65128 40452 line +20289 40452 26591 40452 line +17977 40452 18529 40452 line +77909 40708 79819 40708 line +69985 40708 73091 40708 line +63264 40708 65384 40708 line +20289 40708 26591 40708 line +17977 40708 18529 40708 line +77909 40964 79819 40964 line +69986 40964 73091 40964 line +62994 40964 65640 40964 line +20289 40964 26591 40964 line +17977 40964 18529 40964 line +77909 41220 79819 41220 line +70007 41220 73091 41220 line +62434 41220 65896 41220 line +20289 41220 26591 41220 line +17977 41220 18529 41220 line +77909 41476 79819 41476 line +69965 41476 73091 41476 line +65829 41476 66152 41476 line +20289 41476 26591 41476 line +17977 41476 18529 41476 line +77909 41732 79819 41732 line +69908 41732 73091 41732 line +66096 41732 66408 41732 line +20289 41732 26591 41732 line +17977 41732 18529 41732 line +77909 41988 79819 41988 line +69992 41988 73091 41988 line +66352 41988 66664 41988 line +20289 41988 26591 41988 line +17977 41988 18529 41988 line +77909 42244 79819 42244 line +70007 42244 73091 42244 line +66608 42244 66920 42244 line +20289 42244 26591 42244 line +17977 42244 18529 42244 line +77909 42500 79819 42500 line +69955 42500 73091 42500 line +66864 42500 67176 42500 line +20289 42500 26591 42500 line +17977 42500 18529 42500 line +77909 42756 79819 42756 line +69821 42756 73091 42756 line +67120 42756 67433 42756 line +20289 42756 26591 42756 line +17977 42756 18529 42756 line +77904 43012 79819 43012 line +69555 43012 73096 43012 line +67376 43012 68446 43012 line +20289 43012 26591 43012 line +17977 43012 18529 43012 line +77811 43268 79819 43268 line +67632 43268 73190 43268 line +20289 43268 26591 43268 line +17977 43268 18529 43268 line +77515 43524 79819 43524 line +67888 43524 73486 43524 line +20289 43524 26591 43524 line +17977 43524 18529 43524 line +68144 43780 79819 43780 line +20289 43780 26591 43780 line +17977 43780 18529 43780 line +68400 44036 79819 44036 line +20289 44036 26591 44036 line +17977 44036 18529 44036 line +68656 44292 79819 44292 line +20289 44292 26591 44292 line +17977 44292 18529 44292 line +68912 44548 79819 44548 line +20289 44548 26591 44548 line +17977 44548 18529 44548 line +69168 44804 79819 44804 line +20289 44804 26591 44804 line +17977 44804 18529 44804 line +69424 45060 79819 45060 line +20289 45060 26591 45060 line +17977 45060 18529 45060 line +71785 45316 79819 45316 line +69680 45316 70712 45316 line +20289 45316 26591 45316 line +17977 45316 18529 45316 line +72062 45572 79819 45572 line +69936 45572 70436 45572 line +20289 45572 26591 45572 line +17977 45572 18529 45572 line +72201 45828 79819 45828 line +70192 45828 70300 45828 line +20289 45828 26591 45828 line +17977 45828 18529 45828 line +72255 46084 79819 46084 line +20289 46084 26591 46084 line +17977 46084 18529 46084 line +72245 46340 79819 46340 line +20289 46340 26591 46340 line +17977 46340 18529 46340 line +72165 46596 79819 46596 line +20289 46596 26591 46596 line +17977 46596 18529 46596 line +71994 46852 79819 46852 line +20289 46852 26591 46852 line +17977 46852 18529 46852 line +72087 47108 79819 47108 line +20289 47108 26591 47108 line +17977 47108 18529 47108 line +72214 47364 79819 47364 line +20289 47364 26591 47364 line +17977 47364 18529 47364 line +72256 47620 79819 47620 line +20289 47620 26591 47620 line +17977 47620 18529 47620 line +72238 47876 79819 47876 line +20289 47876 26591 47876 line +17977 47876 18529 47876 line +72150 48132 79819 48132 line +20289 48132 26591 48132 line +17977 48132 18529 48132 line +71958 48388 79819 48388 line +20289 48388 26591 48388 line +17977 48388 18529 48388 line +71520 48644 79819 48644 line +70909 48644 70975 48644 line +20289 48644 26591 48644 line +17977 48644 18529 48644 line +70909 48900 79819 48900 line +20289 48900 26591 48900 line +17977 48900 18529 48900 line +70909 49156 79819 49156 line +20289 49156 26591 49156 line +17977 49156 18529 49156 line +70909 49412 79819 49412 line +20289 49412 26591 49412 line +17977 49412 18529 49412 line +70909 49668 79819 49668 line +20289 49668 26591 49668 line +17977 49668 18529 49668 line +70909 49924 79819 49924 line +20289 49924 26591 49924 line +17977 49924 18529 49924 line +70909 50180 79819 50180 line +20289 50180 26591 50180 line +17977 50180 18529 50180 line +70909 50436 79819 50436 line +20289 50436 26591 50436 line +17977 50436 18529 50436 line +70909 50692 79819 50692 line +20289 50692 26591 50692 line +17977 50692 18529 50692 line +70909 50948 79819 50948 line +20289 50948 26591 50948 line +17977 50948 18529 50948 line +70909 51204 79819 51204 line +20289 51204 26591 51204 line +17977 51204 18529 51204 line +70909 51460 79819 51460 line +20289 51460 26591 51460 line +17977 51460 18529 51460 line +70909 51716 79819 51716 line +20289 51716 26591 51716 line +17977 51716 18529 51716 line +70909 51972 79819 51972 line +20289 51972 26591 51972 line +17977 51972 18529 51972 line +70909 52228 79819 52228 line +20289 52228 26591 52228 line +17977 52228 18529 52228 line +71883 52484 79819 52484 line +20289 52484 26591 52484 line +17977 52484 18529 52484 line +72080 52740 79819 52740 line +20289 52740 26591 52740 line +17977 52740 18529 52740 line +72168 52996 79819 52996 line +20289 52996 26591 52996 line +17977 52996 18529 52996 line +72183 53252 79819 53252 line +20289 53252 26591 53252 line +17977 53252 18529 53252 line +72121 53508 79819 53508 line +20289 53508 26591 53508 line +17977 53508 18529 53508 line +71977 53764 79819 53764 line +20289 53764 26591 53764 line +17977 53764 18529 53764 line +71639 54020 79819 54020 line +20289 54020 26591 54020 line +17977 54020 18529 54020 line +71159 54276 79819 54276 line +20289 54276 26591 54276 line +17977 54276 18529 54276 line +71159 54532 79819 54532 line +20289 54532 26591 54532 line +17977 54532 18529 54532 line +71159 54788 79819 54788 line +20289 54788 26591 54788 line +17977 54788 18529 54788 line +71159 55044 79819 55044 line +20289 55044 26591 55044 line +17977 55044 18529 55044 line +71159 55300 79819 55300 line +20289 55300 26591 55300 line +17977 55300 18529 55300 line +71239 55556 79819 55556 line +20289 55556 26591 55556 line +17977 55556 18529 55556 line +71389 55812 79819 55812 line +20289 55812 26591 55812 line +17977 55812 18529 55812 line +71455 56068 79819 56068 line +20289 56068 26591 56068 line +17977 56068 18529 56068 line +71446 56324 79819 56324 line +20289 56324 26591 56324 line +17977 56324 18529 56324 line +71368 56580 79819 56580 line +20289 56580 26554 56580 line +17977 56580 18529 56580 line +71189 56836 79819 56836 line +20289 56836 26298 56836 line +17977 56836 18529 56836 line +70776 57092 79819 57092 line +69816 57092 70226 57092 line +20289 57092 26042 57092 line +17977 57092 18529 57092 line +69816 57348 79819 57348 line +20289 57348 25786 57348 line +17977 57348 18529 57348 line +69816 57604 79819 57604 line +20289 57604 25530 57604 line +17977 57604 18529 57604 line +69816 57860 79819 57860 line +20289 57860 25274 57860 line +17977 57860 18529 57860 line +69816 58116 79819 58116 line +20289 58116 25018 58116 line +17977 58116 18529 58116 line +69816 58372 79819 58372 line +20289 58372 24762 58372 line +17977 58372 18529 58372 line +69816 58628 79819 58628 line +20289 58628 24506 58628 line +17977 58628 18529 58628 line +69816 58884 79819 58884 line +20289 58884 24250 58884 line +17977 58884 18529 58884 line +69816 59140 79819 59140 line +20289 59140 24015 59140 line +17977 59140 18529 59140 line +69816 59396 79819 59396 line +20289 59396 23887 59396 line +17977 59396 18529 59396 line +69778 59652 79819 59652 line +20289 59652 23842 59652 line +17977 59652 18529 59652 line +69651 59908 79819 59908 line +20289 59908 23841 59908 line +17977 59908 18529 59908 line +69410 60164 79819 60164 line +20289 60164 23841 60164 line +17977 60164 18529 60164 line +69154 60420 79819 60420 line +20289 60420 23841 60420 line +17977 60420 18529 60420 line +68898 60676 79819 60676 line +20289 60676 23841 60676 line +17977 60676 18529 60676 line +68642 60932 79819 60932 line +20289 60932 23841 60932 line +17977 60932 18529 60932 line +78644 61188 79819 61188 line +69033 61188 78192 61188 line +20289 61188 23841 61188 line +17977 61188 18529 61188 line +79277 61444 79819 61444 line +69305 61444 77576 61444 line +20222 61444 23841 61444 line +17977 61444 18521 61444 line +79554 61700 79819 61700 line +69454 61700 77295 61700 line +64729 61700 64745 61700 line +20499 61700 23841 61700 line +17977 61700 18240 61700 line +79721 61956 79819 61956 line +69532 61956 77124 61956 line +66954 61956 67191 61956 line +65954 61956 66048 61956 line +64808 61956 65048 61956 line +20666 61956 23841 61956 line +17977 61956 18069 61956 line +69549 62212 77021 62212 line +64825 62212 67174 62212 line +20770 62212 23841 62212 line +69516 62468 76971 62468 line +64792 62468 67210 62468 line +20824 62468 23785 62468 line +69420 62724 76968 62724 line +64696 62724 67306 62724 line +20828 62724 23785 62724 line +69234 62980 77008 62980 line +64510 62980 67490 62980 line +23330 62980 23798 62980 line +20788 62980 21973 62980 line +79754 63236 79819 63236 line +68895 63236 77097 63236 line +64171 63236 67826 63236 line +23584 63236 23841 63236 line +20699 63236 21712 63236 line +17977 63236 18042 63236 line +79605 63492 79819 63492 line +72839 63492 77247 63492 line +71839 63492 72156 63492 line +64225 63492 71156 63492 line +23726 63492 23868 63492 line +20550 63492 21574 63492 line +17977 63492 18192 63492 line +79373 63748 79819 63748 line +73227 63748 77480 63748 line +56797 63748 56974 63748 line +48547 63748 48724 63748 line +40297 63748 40474 63748 line +32047 63748 32224 63748 line +23797 63748 23974 63748 line +20318 63748 21504 63748 line +17977 63748 18425 63748 line +78924 64004 79819 64004 line +73396 64004 77930 64004 line +56807 64004 57188 64004 line +48557 64004 48938 64004 line +40307 64004 40688 64004 line +32057 64004 32438 64004 line +23807 64004 24188 64004 line +19869 64004 21494 64004 line +17977 64004 18875 64004 line +73476 64260 79819 64260 line +60614 64260 60739 64260 line +56763 64260 57288 64260 line +48513 64260 48991 64260 line +40263 64260 40741 64260 line +32013 64260 32491 64260 line +23763 64260 24241 64260 line +17977 64260 21539 64260 line +73487 64516 79819 64516 line +62845 64516 62941 64516 line +60423 64516 60855 64516 line +56645 64516 57479 64516 line +54595 64516 54655 64516 line +48395 64516 49014 64516 line +46345 64516 46405 64516 line +40145 64516 40764 64516 line +38095 64516 38155 64516 line +31895 64516 32514 64516 line +29845 64516 29905 64516 line +23645 64516 24264 64516 line +17977 64516 21655 64516 line +73424 64772 79819 64772 line +62636 64772 63197 64772 line +59929 64772 61065 64772 line +59129 64772 59569 64772 line +58329 64772 58769 64772 line +56436 64772 57969 64772 line +54386 64772 54865 64772 line +48186 64772 49116 64772 line +46136 64772 46615 64772 line +39936 64772 40866 64772 line +37886 64772 38365 64772 line +31686 64772 32616 64772 line +29636 64772 30115 64772 line +23436 64772 24366 64772 line +17977 64772 21865 64772 line +73283 65028 79819 65028 line +62204 65028 63460 65028 line +56004 65028 61502 65028 line +53954 65028 55302 65028 line +52928 65028 53252 65028 line +47754 65028 49322 65028 line +45704 65028 47052 65028 line +44923 65028 45001 65028 line +39504 65028 41072 65028 line +37454 65028 38802 65028 line +36428 65028 36752 65028 line +31254 65028 32822 65028 line +29204 65028 30552 65028 line +28178 65028 28502 65028 line +23004 65028 24572 65028 line +17977 65028 22302 65028 line +72986 65284 79819 65284 line +71986 65284 72015 65284 line +52672 65284 71016 65284 line +44672 65284 49578 65284 line +36172 65284 41328 65284 line +27922 65284 33078 65284 line +17977 65284 24828 65284 line +52251 65540 79819 65540 line +44251 65540 50001 65540 line +35751 65540 41751 65540 line +27500 65540 33501 65540 line +17977 65540 25251 65540 line +17977 65796 79819 65796 line +newpath 79819 27576 moveto +79819 30292 lineto +79816 30278 lineto +79700 30017 lineto +79535 29783 lineto +79328 29586 lineto +79086 29432 lineto +78819 29329 lineto +78537 29279 lineto +78251 29285 lineto +77972 29347 lineto +77710 29461 lineto +77475 29625 lineto +77276 29830 lineto +77121 30071 lineto +77016 30337 lineto +76964 30618 lineto +76968 30904 lineto +77028 31184 lineto +77140 31447 lineto +77302 31683 lineto +77506 31884 lineto +77746 32040 lineto +78011 32147 lineto +78292 32201 lineto +78578 32199 lineto +78859 32141 lineto +79122 32031 lineto +79360 31871 lineto +79561 31668 lineto +79719 31429 lineto +79819 31187 lineto +79819 62182 lineto +79816 62168 lineto +79700 61907 lineto +79535 61673 lineto +79328 61476 lineto +79086 61322 lineto +78819 61219 lineto +78537 61169 lineto +78251 61175 lineto +77972 61237 lineto +77710 61351 lineto +77475 61515 lineto +77276 61720 lineto +77121 61961 lineto +77016 62227 lineto +76964 62508 lineto +76968 62794 lineto +77028 63074 lineto +77140 63337 lineto +77302 63573 lineto +77506 63774 lineto +77746 63930 lineto +78011 64037 lineto +78292 64091 lineto +78578 64089 lineto +78859 64031 lineto +79122 63921 lineto +79360 63761 lineto +79561 63558 lineto +79719 63319 lineto +79819 63077 lineto +79819 65796 lineto +17977 65796 lineto +17977 63084 lineto +18085 63337 lineto +18247 63573 lineto +18451 63774 lineto +18691 63930 lineto +18956 64037 lineto +19237 64091 lineto +19523 64089 lineto +19804 64031 lineto +20067 63921 lineto +20305 63761 lineto +20506 63558 lineto +20664 63319 lineto +20773 63055 lineto +20829 62774 lineto +20824 62447 lineto +20761 62168 lineto +20645 61907 lineto +20480 61673 lineto +20273 61476 lineto +20046 61332 lineto +20289 61332 lineto +20289 32906 lineto +18529 32906 lineto +18529 61332 lineto +18698 61332 lineto +18655 61351 lineto +18420 61515 lineto +18221 61720 lineto +18066 61961 lineto +17977 62187 lineto +17977 46686 lineto +17977 31194 lineto +18085 31447 lineto +18247 31683 lineto +18451 31884 lineto +18691 32040 lineto +18956 32147 lineto +19237 32201 lineto +19523 32199 lineto +19804 32141 lineto +20067 32031 lineto +20305 31871 lineto +20506 31668 lineto +20664 31429 lineto +20773 31165 lineto +20829 30884 lineto +20824 30557 lineto +20761 30278 lineto +20645 30017 lineto +20480 29783 lineto +20273 29586 lineto +20031 29432 lineto +19764 29329 lineto +19482 29279 lineto +19196 29285 lineto +18917 29347 lineto +18655 29461 lineto +18420 29625 lineto +18221 29830 lineto +18066 30071 lineto +17977 30297 lineto +17977 27576 lineto +58991 27576 lineto +58991 27761 lineto +57497 27761 lineto +57487 27761 lineto +57401 27771 lineto +57320 27779 lineto +57315 27781 lineto +57311 27781 lineto +57171 27826 lineto +57151 27832 lineto +57150 27833 lineto +57142 27835 lineto +57066 27877 lineto +56994 27914 lineto +56988 27919 lineto +56986 27920 lineto +56955 27946 lineto +56857 28027 lineto +56374 28510 lineto +56367 28503 lineto +56175 28382 lineto +55963 28299 lineto +55740 28260 lineto +55513 28265 lineto +55291 28313 lineto +55083 28404 lineto +54896 28534 lineto +54738 28697 lineto +54624 28874 lineto +54612 28846 lineto +54481 28660 lineto +54317 28503 lineto +54125 28382 lineto +53913 28299 lineto +53690 28260 lineto +53463 28265 lineto +53241 28313 lineto +53033 28404 lineto +52846 28534 lineto +52688 28697 lineto +52565 28888 lineto +52482 29099 lineto +52441 29322 lineto +52444 29549 lineto +52486 29751 lineto +52350 29751 lineto +52347 29743 lineto +52338 29710 lineto +52336 29708 lineto +52335 29702 lineto +52281 29605 lineto +52255 29554 lineto +52253 29552 lineto +52250 29546 lineto +52181 29465 lineto +52142 29417 lineto +52043 29319 lineto +52023 29223 lineto +52009 29191 lineto +52009 29016 lineto +52009 29007 lineto +51989 28831 lineto +51947 28703 lineto +51938 28670 lineto +51936 28668 lineto +51935 28662 lineto +51881 28565 lineto +51855 28514 lineto +51853 28512 lineto +51850 28506 lineto +51781 28425 lineto +51742 28377 lineto +51391 28026 lineto +51391 28025 lineto +51390 28025 lineto +51384 28018 lineto +51318 27967 lineto +51253 27913 lineto +51247 27911 lineto +51245 27908 lineto +51165 27867 lineto +51096 27830 lineto +51092 27830 lineto +51087 27826 lineto +50996 27800 lineto +50927 27778 lineto +50922 27778 lineto +50917 27776 lineto +50820 27768 lineto +50750 27761 lineto +50741 27761 lineto +49247 27761 lineto +49237 27761 lineto +49151 27771 lineto +49070 27779 lineto +49065 27781 lineto +49061 27781 lineto +48921 27826 lineto +48901 27832 lineto +48900 27833 lineto +48892 27835 lineto +48816 27877 lineto +48744 27914 lineto +48738 27919 lineto +48736 27920 lineto +48705 27946 lineto +48607 28027 lineto +48124 28510 lineto +48117 28503 lineto +47925 28382 lineto +47713 28299 lineto +47490 28260 lineto +47263 28265 lineto +47041 28313 lineto +46833 28404 lineto +46646 28534 lineto +46488 28697 lineto +46374 28874 lineto +46362 28846 lineto +46231 28660 lineto +46067 28503 lineto +45875 28382 lineto +45663 28299 lineto +45440 28260 lineto +45213 28265 lineto +44991 28313 lineto +44783 28404 lineto +44596 28534 lineto +44438 28697 lineto +44315 28888 lineto +44232 29099 lineto +44191 29322 lineto +44194 29549 lineto +44236 29751 lineto +44100 29751 lineto +44097 29743 lineto +44088 29710 lineto +44086 29708 lineto +44085 29702 lineto +44031 29605 lineto +44005 29554 lineto +44003 29552 lineto +44000 29546 lineto +43931 29465 lineto +43892 29417 lineto +43793 29319 lineto +43773 29223 lineto +43759 29191 lineto +43759 29016 lineto +43759 29007 lineto +43739 28831 lineto +43697 28703 lineto +43688 28670 lineto +43686 28668 lineto +43685 28662 lineto +43631 28564 lineto +43605 28514 lineto +43603 28512 lineto +43600 28506 lineto +43531 28425 lineto +43492 28377 lineto +43141 28026 lineto +43141 28025 lineto +43140 28025 lineto +43134 28018 lineto +43068 27967 lineto +43003 27913 lineto +42997 27911 lineto +42995 27908 lineto +42915 27867 lineto +42846 27830 lineto +42842 27830 lineto +42837 27826 lineto +42746 27800 lineto +42677 27778 lineto +42672 27778 lineto +42667 27776 lineto +42570 27768 lineto +42500 27761 lineto +42491 27761 lineto +40997 27761 lineto +40987 27761 lineto +40901 27771 lineto +40820 27779 lineto +40815 27781 lineto +40811 27781 lineto +40672 27826 lineto +40651 27832 lineto +40650 27833 lineto +40642 27835 lineto +40566 27877 lineto +40494 27914 lineto +40488 27919 lineto +40486 27920 lineto +40455 27946 lineto +40357 28027 lineto +39874 28510 lineto +39867 28503 lineto +39675 28382 lineto +39463 28299 lineto +39240 28260 lineto +39013 28265 lineto +38791 28313 lineto +38583 28404 lineto +38396 28534 lineto +38238 28697 lineto +38124 28874 lineto +38112 28846 lineto +37981 28660 lineto +37817 28503 lineto +37625 28382 lineto +37413 28299 lineto +37190 28260 lineto +36963 28265 lineto +36741 28313 lineto +36533 28404 lineto +36346 28534 lineto +36188 28697 lineto +36065 28888 lineto +35982 29099 lineto +35941 29322 lineto +35944 29549 lineto +35986 29751 lineto +35850 29751 lineto +35847 29743 lineto +35838 29710 lineto +35836 29708 lineto +35835 29702 lineto +35781 29604 lineto +35755 29554 lineto +35753 29552 lineto +35750 29546 lineto +35681 29465 lineto +35642 29417 lineto +35543 29319 lineto +35523 29223 lineto +35509 29191 lineto +35509 29016 lineto +35509 29007 lineto +35489 28831 lineto +35447 28703 lineto +35438 28670 lineto +35436 28668 lineto +35435 28662 lineto +35381 28564 lineto +35355 28514 lineto +35353 28512 lineto +35350 28506 lineto +35281 28425 lineto +35242 28377 lineto +34891 28026 lineto +34891 28025 lineto +34890 28025 lineto +34884 28018 lineto +34818 27967 lineto +34753 27913 lineto +34747 27911 lineto +34745 27908 lineto +34665 27867 lineto +34596 27830 lineto +34592 27830 lineto +34587 27826 lineto +34496 27800 lineto +34427 27778 lineto +34422 27778 lineto +34417 27776 lineto +34320 27768 lineto +34250 27761 lineto +34241 27761 lineto +32747 27761 lineto +32737 27761 lineto +32651 27771 lineto +32570 27779 lineto +32565 27781 lineto +32561 27781 lineto +32422 27826 lineto +32401 27832 lineto +32400 27833 lineto +32392 27835 lineto +32316 27877 lineto +32244 27914 lineto +32238 27919 lineto +32236 27920 lineto +32205 27946 lineto +32107 28027 lineto +31624 28510 lineto +31617 28503 lineto +31425 28382 lineto +31213 28299 lineto +30990 28260 lineto +30763 28265 lineto +30541 28313 lineto +30333 28404 lineto +30146 28534 lineto +29988 28697 lineto +29874 28874 lineto +29862 28846 lineto +29731 28660 lineto +29567 28503 lineto +29375 28382 lineto +29163 28299 lineto +28940 28260 lineto +28713 28265 lineto +28491 28313 lineto +28283 28404 lineto +28096 28534 lineto +27938 28697 lineto +27815 28888 lineto +27732 29099 lineto +27691 29322 lineto +27694 29549 lineto +27736 29751 lineto +27600 29751 lineto +27597 29743 lineto +27588 29710 lineto +27586 29708 lineto +27585 29702 lineto +27531 29605 lineto +27505 29554 lineto +27503 29552 lineto +27500 29546 lineto +27431 29465 lineto +27392 29417 lineto +27293 29319 lineto +27273 29223 lineto +27259 29191 lineto +27259 29016 lineto +27259 29007 lineto +27239 28831 lineto +27197 28703 lineto +27188 28670 lineto +27186 28668 lineto +27185 28662 lineto +27131 28565 lineto +27105 28514 lineto +27103 28512 lineto +27100 28506 lineto +27031 28425 lineto +26992 28377 lineto +26641 28026 lineto +26641 28025 lineto +26640 28025 lineto +26634 28018 lineto +26568 27967 lineto +26503 27913 lineto +26497 27911 lineto +26495 27908 lineto +26415 27867 lineto +26346 27830 lineto +26342 27830 lineto +26337 27826 lineto +26246 27800 lineto +26177 27778 lineto +26172 27778 lineto +26167 27776 lineto +26070 27768 lineto +26000 27761 lineto +25991 27761 lineto +24497 27761 lineto +24487 27761 lineto +24401 27771 lineto +24320 27779 lineto +24315 27781 lineto +24311 27781 lineto +24172 27826 lineto +24151 27832 lineto +24150 27833 lineto +24142 27835 lineto +24066 27877 lineto +23994 27914 lineto +23988 27919 lineto +23986 27920 lineto +23955 27946 lineto +23857 28027 lineto +23374 28510 lineto +23367 28503 lineto +23175 28382 lineto +22963 28299 lineto +22740 28260 lineto +22513 28265 lineto +22291 28313 lineto +22083 28404 lineto +21896 28534 lineto +21738 28697 lineto +21615 28888 lineto +21532 29099 lineto +21491 29322 lineto +21494 29549 lineto +21541 29771 lineto +21630 29980 lineto +21758 30168 lineto +21921 30327 lineto +22111 30451 lineto +22321 30536 lineto +22544 30579 lineto +22591 30579 lineto +22591 33173 lineto +22591 33183 lineto +22600 33269 lineto +22609 33350 lineto +22610 33356 lineto +22611 33359 lineto +22631 33424 lineto +22661 33519 lineto +22663 33525 lineto +22665 33528 lineto +22690 33575 lineto +22740 33669 lineto +22740 62760 lineto +22513 62765 lineto +22291 62813 lineto +22083 62904 lineto +21896 63034 lineto +21738 63197 lineto +21615 63388 lineto +21532 63599 lineto +21491 63822 lineto +21494 64049 lineto +21541 64271 lineto +21630 64480 lineto +21758 64668 lineto +21921 64827 lineto +22111 64951 lineto +22321 65036 lineto +22544 65079 lineto +22771 65077 lineto +22994 65032 lineto +23203 64944 lineto +23391 64817 lineto +23551 64656 lineto +23677 64467 lineto +23764 64257 lineto +23808 64034 lineto +23804 63775 lineto +23754 63553 lineto +23662 63346 lineto +23531 63160 lineto +23367 63003 lineto +23175 62882 lineto +22963 62799 lineto +22740 62760 lineto +22740 33669 lineto +22744 33676 lineto +22748 33682 lineto +22750 33684 lineto +22775 33715 lineto +22857 33813 lineto +26591 37547 lineto +26591 56543 lineto +24105 59029 lineto +24098 59036 lineto +24046 59102 lineto +23993 59167 lineto +23990 59173 lineto +23988 59175 lineto +23946 59255 lineto +23910 59324 lineto +23909 59328 lineto +23906 59333 lineto +23879 59424 lineto +23858 59493 lineto +23857 59498 lineto +23856 59503 lineto +23847 59600 lineto +23841 59670 lineto +23841 59679 lineto +23841 62212 lineto +23823 62255 lineto +23786 62440 lineto +23785 62743 lineto +23787 62933 lineto +23827 63117 lineto +23841 63150 lineto +23841 63283 lineto +23841 63293 lineto +23850 63379 lineto +23859 63460 lineto +23860 63466 lineto +23861 63469 lineto +23881 63535 lineto +23911 63629 lineto +23913 63635 lineto +23915 63638 lineto +23940 63685 lineto +23994 63786 lineto +23998 63792 lineto +24000 63794 lineto +24025 63825 lineto +24107 63923 lineto +24206 64023 lineto +24227 64117 lineto +24241 64150 lineto +24241 64323 lineto +24241 64333 lineto +24250 64419 lineto +24259 64500 lineto +24260 64506 lineto +24261 64509 lineto +24281 64574 lineto +24311 64669 lineto +24313 64675 lineto +24315 64678 lineto +24340 64725 lineto +24394 64826 lineto +24398 64832 lineto +24400 64834 lineto +24425 64865 lineto +24507 64963 lineto +24854 65310 lineto +24859 65315 lineto +24864 65320 lineto +24866 65321 lineto +24909 65357 lineto +24997 65427 lineto +24999 65429 lineto +25004 65432 lineto +25085 65474 lineto +25154 65510 lineto +25159 65512 lineto +25162 65513 lineto +25201 65525 lineto +25323 65562 lineto +25331 65563 lineto +25332 65563 lineto +25343 65565 lineto +25500 65579 lineto +27253 65579 lineto +27263 65579 lineto +27348 65570 lineto +27430 65561 lineto +27435 65560 lineto +27439 65559 lineto +27503 65539 lineto +27599 65509 lineto +27604 65507 lineto +27608 65505 lineto +27654 65480 lineto +27756 65426 lineto +27761 65422 lineto +27764 65420 lineto +27794 65395 lineto +27893 65313 lineto +28277 64929 lineto +28311 64951 lineto +28521 65036 lineto +28744 65079 lineto +28971 65077 lineto +29194 65032 lineto +29403 64944 lineto +29591 64817 lineto +29751 64656 lineto +29875 64470 lineto +29880 64480 lineto +30008 64668 lineto +30171 64827 lineto +30361 64951 lineto +30571 65036 lineto +30794 65079 lineto +31021 65077 lineto +31244 65032 lineto +31453 64944 lineto +31641 64817 lineto +31801 64656 lineto +31927 64467 lineto +32014 64257 lineto +32058 64034 lineto +32054 63775 lineto +32012 63589 lineto +32148 63589 lineto +32161 63629 lineto +32163 63635 lineto +32165 63638 lineto +32190 63685 lineto +32244 63786 lineto +32248 63792 lineto +32250 63794 lineto +32275 63825 lineto +32357 63923 lineto +32456 64023 lineto +32477 64117 lineto +32491 64150 lineto +32491 64323 lineto +32491 64333 lineto +32500 64419 lineto +32509 64500 lineto +32510 64506 lineto +32511 64509 lineto +32531 64575 lineto +32561 64669 lineto +32563 64675 lineto +32565 64678 lineto +32590 64725 lineto +32644 64826 lineto +32648 64832 lineto +32650 64834 lineto +32675 64865 lineto +32757 64963 lineto +33104 65310 lineto +33109 65315 lineto +33114 65320 lineto +33116 65321 lineto +33159 65357 lineto +33247 65427 lineto +33249 65429 lineto +33254 65432 lineto +33335 65474 lineto +33404 65510 lineto +33409 65512 lineto +33412 65513 lineto +33451 65525 lineto +33573 65562 lineto +33581 65563 lineto +33582 65563 lineto +33593 65565 lineto +33750 65579 lineto +35503 65579 lineto +35513 65579 lineto +35598 65570 lineto +35680 65561 lineto +35685 65560 lineto +35689 65559 lineto +35754 65539 lineto +35849 65509 lineto +35854 65507 lineto +35858 65505 lineto +35904 65480 lineto +36006 65426 lineto +36011 65422 lineto +36014 65420 lineto +36044 65395 lineto +36143 65313 lineto +36527 64929 lineto +36561 64951 lineto +36771 65036 lineto +36994 65079 lineto +37221 65077 lineto +37444 65032 lineto +37653 64944 lineto +37841 64817 lineto +38001 64656 lineto +38125 64470 lineto +38130 64480 lineto +38258 64668 lineto +38421 64827 lineto +38611 64951 lineto +38821 65036 lineto +39044 65079 lineto +39271 65077 lineto +39494 65032 lineto +39703 64944 lineto +39891 64817 lineto +40051 64656 lineto +40177 64467 lineto +40264 64257 lineto +40308 64034 lineto +40304 63775 lineto +40262 63589 lineto +40398 63589 lineto +40411 63629 lineto +40413 63635 lineto +40415 63638 lineto +40440 63685 lineto +40494 63786 lineto +40498 63792 lineto +40500 63794 lineto +40525 63825 lineto +40607 63923 lineto +40706 64023 lineto +40727 64117 lineto +40741 64150 lineto +40741 64323 lineto +40741 64333 lineto +40750 64419 lineto +40759 64500 lineto +40760 64506 lineto +40761 64509 lineto +40781 64574 lineto +40811 64669 lineto +40813 64675 lineto +40815 64678 lineto +40840 64725 lineto +40894 64826 lineto +40898 64832 lineto +40900 64834 lineto +40925 64865 lineto +41007 64963 lineto +41354 65310 lineto +41359 65315 lineto +41364 65320 lineto +41366 65321 lineto +41409 65357 lineto +41497 65427 lineto +41499 65429 lineto +41504 65432 lineto +41585 65474 lineto +41654 65510 lineto +41659 65512 lineto +41662 65513 lineto +41701 65525 lineto +41823 65562 lineto +41831 65563 lineto +41832 65563 lineto +41843 65565 lineto +42000 65579 lineto +44003 65579 lineto +44013 65579 lineto +44098 65570 lineto +44180 65561 lineto +44185 65560 lineto +44189 65559 lineto +44254 65539 lineto +44349 65509 lineto +44354 65507 lineto +44358 65505 lineto +44404 65480 lineto +44506 65426 lineto +44511 65422 lineto +44514 65420 lineto +44544 65395 lineto +44643 65313 lineto +44895 65061 lineto +44902 65054 lineto +44941 65004 lineto +45021 65036 lineto +45244 65079 lineto +45471 65077 lineto +45694 65032 lineto +45903 64944 lineto +46091 64817 lineto +46251 64656 lineto +46375 64470 lineto +46380 64480 lineto +46508 64668 lineto +46671 64827 lineto +46861 64951 lineto +47071 65036 lineto +47294 65079 lineto +47521 65077 lineto +47744 65032 lineto +47953 64944 lineto +48141 64817 lineto +48301 64656 lineto +48427 64467 lineto +48514 64257 lineto +48558 64034 lineto +48554 63775 lineto +48512 63589 lineto +48648 63589 lineto +48661 63629 lineto +48663 63635 lineto +48665 63638 lineto +48690 63685 lineto +48744 63786 lineto +48748 63792 lineto +48750 63794 lineto +48775 63825 lineto +48857 63923 lineto +48956 64023 lineto +48977 64117 lineto +48991 64150 lineto +48991 64323 lineto +48991 64333 lineto +49000 64419 lineto +49009 64500 lineto +49010 64506 lineto +49011 64509 lineto +49031 64574 lineto +49061 64669 lineto +49063 64675 lineto +49065 64678 lineto +49090 64725 lineto +49144 64826 lineto +49148 64832 lineto +49150 64834 lineto +49175 64865 lineto +49257 64963 lineto +49604 65310 lineto +49609 65315 lineto +49614 65320 lineto +49616 65321 lineto +49659 65357 lineto +49747 65427 lineto +49749 65429 lineto +49754 65432 lineto +49835 65474 lineto +49904 65510 lineto +49909 65512 lineto +49912 65513 lineto +49951 65525 lineto +50073 65562 lineto +50081 65563 lineto +50082 65563 lineto +50094 65565 lineto +50250 65579 lineto +52003 65579 lineto +52013 65579 lineto +52098 65570 lineto +52180 65561 lineto +52185 65560 lineto +52189 65559 lineto +52254 65539 lineto +52349 65509 lineto +52354 65507 lineto +52358 65505 lineto +52404 65480 lineto +52506 65426 lineto +52511 65422 lineto +52514 65420 lineto +52544 65395 lineto +52643 65313 lineto +53027 64929 lineto +53061 64951 lineto +53271 65036 lineto +53494 65079 lineto +53721 65077 lineto +53944 65032 lineto +54153 64944 lineto +54341 64817 lineto +54501 64656 lineto +54625 64470 lineto +54630 64480 lineto +54758 64668 lineto +54921 64827 lineto +55111 64951 lineto +55321 65036 lineto +55544 65079 lineto +55771 65077 lineto +55994 65032 lineto +56203 64944 lineto +56391 64817 lineto +56551 64656 lineto +56677 64467 lineto +56764 64257 lineto +56808 64034 lineto +56804 63775 lineto +56762 63589 lineto +56898 63589 lineto +56911 63629 lineto +56913 63635 lineto +56915 63638 lineto +56940 63685 lineto +56994 63786 lineto +56998 63792 lineto +57000 63794 lineto +57025 63825 lineto +57107 63923 lineto +57206 64023 lineto +57227 64117 lineto +57301 64291 lineto +57408 64447 lineto +57543 64580 lineto +57701 64683 lineto +57876 64754 lineto +58062 64790 lineto +58251 64788 lineto +58436 64750 lineto +58549 64703 lineto +58676 64754 lineto +58862 64790 lineto +59051 64788 lineto +59236 64750 lineto +59349 64703 lineto +59476 64754 lineto +59662 64790 lineto +59851 64788 lineto +60036 64750 lineto +60210 64677 lineto +60367 64572 lineto +60500 64438 lineto +60605 64280 lineto +60677 64105 lineto +60693 64022 lineto +60694 64049 lineto +60741 64271 lineto +60830 64480 lineto +60958 64668 lineto +61121 64827 lineto +61311 64951 lineto +61521 65036 lineto +61744 65079 lineto +61971 65077 lineto +62194 65032 lineto +62403 64944 lineto +62591 64817 lineto +62751 64656 lineto +62877 64467 lineto +62881 64456 lineto +63424 64999 lineto +63430 65004 lineto +63472 65038 lineto +63548 65100 lineto +63553 65104 lineto +63555 65104 lineto +63601 65128 lineto +63689 65174 lineto +63691 65175 lineto +63696 65177 lineto +63764 65197 lineto +63842 65220 lineto +63847 65221 lineto +63849 65221 lineto +63871 65223 lineto +64000 65236 lineto +70942 65236 lineto +71040 65300 lineto +71220 65372 lineto +71410 65409 lineto +71604 65407 lineto +71793 65368 lineto +71972 65293 lineto +72000 65275 lineto +72040 65300 lineto +72220 65372 lineto +72410 65409 lineto +72604 65407 lineto +72793 65368 lineto +72972 65293 lineto +73133 65185 lineto +73269 65048 lineto +73376 64886 lineto +73450 64707 lineto +73488 64517 lineto +73485 64296 lineto +73442 64107 lineto +73363 63930 lineto +73252 63771 lineto +73111 63638 lineto +72948 63534 lineto +72767 63464 lineto +72576 63430 lineto +72383 63434 lineto +72193 63476 lineto +72016 63553 lineto +71997 63566 lineto +71948 63534 lineto +71767 63464 lineto +71576 63430 lineto +71383 63434 lineto +71193 63476 lineto +71016 63553 lineto +70942 63604 lineto +64337 63604 lineto +64029 63296 lineto +64206 63221 lineto +64399 63091 lineto +64564 62925 lineto +64693 62731 lineto +64782 62516 lineto +64827 62287 lineto +64823 62021 lineto +64772 61793 lineto +64703 61641 lineto +64763 61726 lineto +64897 61857 lineto +65054 61960 lineto +65228 62030 lineto +65413 62066 lineto +65601 62064 lineto +65785 62027 lineto +65958 61954 lineto +66000 61926 lineto +66054 61960 lineto +66228 62030 lineto +66413 62066 lineto +66601 62064 lineto +66785 62027 lineto +66958 61954 lineto +67004 61923 lineto +67198 61923 lineto +67171 62070 lineto +67175 62303 lineto +67223 62531 lineto +67315 62745 lineto +67447 62938 lineto +67613 63101 lineto +67808 63229 lineto +68024 63316 lineto +68253 63360 lineto +68486 63358 lineto +68715 63311 lineto +68930 63221 lineto +69123 63091 lineto +69288 62925 lineto +69417 62731 lineto +69506 62516 lineto +69551 62287 lineto +69547 62021 lineto +69496 61793 lineto +69401 61580 lineto +69267 61390 lineto +69098 61229 lineto +68901 61104 lineto +68684 61019 lineto +68574 61000 lineto +69579 59995 lineto +69584 59990 lineto +69617 59948 lineto +69680 59872 lineto +69683 59867 lineto +69684 59865 lineto +69707 59819 lineto +69754 59731 lineto +69754 59729 lineto +69757 59724 lineto +69774 59665 lineto +69800 59578 lineto +69800 59572 lineto +69801 59570 lineto +69802 59556 lineto +69816 59420 lineto +69816 57420 lineto +69816 57409 lineto +69816 56841 lineto +69897 56920 lineto +70054 57023 lineto +70228 57093 lineto +70413 57129 lineto +70601 57127 lineto +70785 57090 lineto +70958 57017 lineto +71114 56912 lineto +71246 56778 lineto +71350 56622 lineto +71421 56448 lineto +71458 56264 lineto +71455 56049 lineto +71413 55866 lineto +71337 55695 lineto +71229 55541 lineto +71159 55475 lineto +71159 54104 lineto +71165 54105 lineto +71348 54103 lineto +71527 54067 lineto +71696 53996 lineto +71848 53893 lineto +71977 53763 lineto +72078 53611 lineto +72148 53442 lineto +72184 53262 lineto +72181 53053 lineto +72141 52874 lineto +72066 52707 lineto +71961 52557 lineto +71828 52431 lineto +71674 52332 lineto +71503 52266 lineto +71322 52234 lineto +71139 52238 lineto +70960 52277 lineto +70910 52299 lineto +70909 52298 lineto +70909 49420 lineto +70909 49407 lineto +70909 48620 lineto +70964 48642 lineto +71158 48679 lineto +71356 48677 lineto +71549 48638 lineto +71732 48561 lineto +71895 48451 lineto +72035 48310 lineto +72144 48146 lineto +72220 47963 lineto +72258 47769 lineto +72255 47543 lineto +72211 47350 lineto +72131 47170 lineto +72017 47008 lineto +71925 46921 lineto +72035 46810 lineto +72144 46646 lineto +72220 46463 lineto +72258 46269 lineto +72255 46043 lineto +72211 45850 lineto +72131 45670 lineto +72017 45508 lineto +71874 45372 lineto +71707 45266 lineto +71523 45195 lineto +71328 45160 lineto +71130 45164 lineto +70937 45207 lineto +70756 45286 lineto +70594 45399 lineto +70456 45541 lineto +70349 45707 lineto +70276 45891 lineto +70272 45908 lineto +65891 41526 lineto +65891 41525 lineto +65890 41525 lineto +65884 41518 lineto +65818 41467 lineto +65753 41413 lineto +65747 41411 lineto +65745 41408 lineto +65665 41367 lineto +65596 41330 lineto +65592 41330 lineto +65587 41326 lineto +65496 41300 lineto +65427 41278 lineto +65422 41278 lineto +65417 41276 lineto +65320 41268 lineto +65250 41261 lineto +65241 41261 lineto +63000 41261 lineto +62994 41261 lineto +62987 41261 lineto +62434 41261 lineto +62434 41105 lineto +62598 41103 lineto +62777 41067 lineto +62946 40996 lineto +63098 40893 lineto +63227 40763 lineto +63328 40611 lineto +63398 40442 lineto +63434 40262 lineto +63431 40053 lineto +63391 39874 lineto +63316 39707 lineto +63316 39591 lineto +63397 39670 lineto +63554 39773 lineto +63728 39843 lineto +63913 39879 lineto +64101 39877 lineto +64285 39840 lineto +64447 39772 lineto +67425 42749 lineto +67430 42754 lineto +67472 42788 lineto +67548 42850 lineto +67553 42854 lineto +67555 42854 lineto +67601 42878 lineto +67689 42924 lineto +67691 42925 lineto +67696 42927 lineto +67755 42945 lineto +67842 42970 lineto +67848 42971 lineto +67850 42971 lineto +67880 42974 lineto +68000 42986 lineto +68008 42986 lineto +68406 42986 lineto +68531 43068 lineto +68714 43142 lineto +68908 43179 lineto +69106 43177 lineto +69299 43138 lineto +69482 43061 lineto +69645 42951 lineto +69785 42810 lineto +69894 42646 lineto +69970 42463 lineto +70008 42269 lineto +70005 42043 lineto +69961 41850 lineto +69881 41670 lineto +69879 41668 lineto +69894 41646 lineto +69970 41463 lineto +70008 41269 lineto +70005 41043 lineto +69961 40850 lineto +69943 40811 lineto +69984 40712 lineto +70009 40585 lineto +70009 39751 lineto +69983 39625 lineto +69933 39505 lineto +69909 39470 lineto +69909 39417 lineto +69909 39407 lineto +69899 39322 lineto +69891 39240 lineto +69889 39235 lineto +69889 39231 lineto +69868 39166 lineto +69839 39071 lineto +69836 39066 lineto +69835 39062 lineto +69809 39016 lineto +69756 38914 lineto +69751 38909 lineto +69750 38906 lineto +69724 38876 lineto +69643 38777 lineto +69141 38275 lineto +69134 38268 lineto +69068 38217 lineto +69003 38163 lineto +68997 38161 lineto +68995 38158 lineto +68915 38117 lineto +68846 38080 lineto +68842 38080 lineto +68837 38076 lineto +68746 38050 lineto +68677 38028 lineto +68672 38028 lineto +68667 38026 lineto +68570 38018 lineto +68500 38011 lineto +68491 38011 lineto +68376 38012 lineto +68159 37794 lineto +68159 37399 lineto +68162 37401 lineto +68315 37502 lineto +68485 37570 lineto +68665 37605 lineto +68848 37603 lineto +69027 37567 lineto +69196 37496 lineto +69348 37393 lineto +69477 37263 lineto +69578 37111 lineto +69648 36942 lineto +69684 36762 lineto +69682 36661 lineto +72014 36661 lineto +72206 36639 lineto +72317 36604 lineto +72344 36604 lineto +72470 36578 lineto +72590 36528 lineto +72604 36518 lineto +72735 36570 lineto +72915 36605 lineto +73098 36603 lineto +73277 36567 lineto +73446 36496 lineto +73598 36393 lineto +73681 36310 lineto +73681 38761 lineto +73555 38787 lineto +73435 38837 lineto +73328 38910 lineto +73237 39001 lineto +73165 39109 lineto +73116 39228 lineto +73091 39355 lineto +73091 42989 lineto +73117 43115 lineto +73167 43235 lineto +73240 43342 lineto +73331 43433 lineto +73439 43505 lineto +73558 43554 lineto +73685 43579 lineto +77319 43579 lineto +77445 43553 lineto +77565 43503 lineto +77672 43430 lineto +77763 43339 lineto +77835 43231 lineto +77884 43112 lineto +77909 42985 lineto +77909 39351 lineto +77883 39225 lineto +77833 39105 lineto +77760 38998 lineto +77669 38907 lineto +77561 38835 lineto +77442 38786 lineto +77315 38761 lineto +73681 38761 lineto +73681 36310 lineto +73727 36263 lineto +73828 36111 lineto +73898 35942 lineto +73934 35762 lineto +73931 35553 lineto +73891 35374 lineto +73816 35207 lineto +73711 35057 lineto +73578 34931 lineto +73424 34832 lineto +73253 34766 lineto +73072 34734 lineto +72909 34738 lineto +72909 34174 lineto +73014 34174 lineto +73140 34148 lineto +73260 34098 lineto +73367 34025 lineto +73458 33934 lineto +73530 33826 lineto +73579 33707 lineto +73604 33580 lineto +73604 32627 lineto +73854 32674 lineto +74169 32672 lineto +74476 32609 lineto +74766 32487 lineto +75027 32311 lineto +75248 32088 lineto +75422 31826 lineto +75542 31535 lineto +75603 31227 lineto +75598 30868 lineto +75528 30561 lineto +75400 30274 lineto +75219 30017 lineto +74991 29801 lineto +74726 29632 lineto +74433 29519 lineto +74123 29464 lineto +73809 29471 lineto +73502 29538 lineto +73477 29549 lineto +73400 29374 lineto +73219 29117 lineto +72991 28901 lineto +72726 28732 lineto +72433 28619 lineto +72123 28564 lineto +71809 28571 lineto +71502 28638 lineto +71214 28764 lineto +70956 28944 lineto +70738 29170 lineto +70567 29434 lineto +70452 29726 lineto +70395 30035 lineto +70399 30350 lineto +70465 30657 lineto +70589 30946 lineto +70681 31082 lineto +70633 31115 lineto +70542 31206 lineto +70470 31314 lineto +70421 31433 lineto +70396 31560 lineto +70396 33261 lineto +68126 33261 lineto +67604 32739 lineto +67604 32627 lineto +67854 32674 lineto +68169 32672 lineto +68476 32609 lineto +68766 32487 lineto +69027 32311 lineto +69248 32088 lineto +69422 31826 lineto +69542 31535 lineto +69603 31227 lineto +69598 30868 lineto +69528 30561 lineto +69400 30274 lineto +69219 30017 lineto +68991 29801 lineto +68726 29632 lineto +68433 29519 lineto +68123 29464 lineto +67809 29471 lineto +67502 29538 lineto +67477 29549 lineto +67400 29374 lineto +67219 29117 lineto +66991 28901 lineto +66726 28732 lineto +66433 28619 lineto +66123 28564 lineto +65809 28571 lineto +65502 28638 lineto +65214 28764 lineto +64956 28944 lineto +64738 29170 lineto +64567 29434 lineto +64452 29726 lineto +64395 30035 lineto +64399 30350 lineto +64465 30657 lineto +64589 30946 lineto +64681 31082 lineto +64633 31115 lineto +64542 31206 lineto +64470 31314 lineto +64421 31433 lineto +64396 31560 lineto +64396 33584 lineto +64422 33710 lineto +64443 33761 lineto +63507 33761 lineto +63505 33543 lineto +63461 33350 lineto +63381 33170 lineto +63379 33168 lineto +63394 33146 lineto +63470 32963 lineto +63508 32769 lineto +63505 32543 lineto +63461 32350 lineto +63409 32233 lineto +63409 31417 lineto +63409 31407 lineto +63389 31231 lineto +63347 31103 lineto +63338 31070 lineto +63336 31068 lineto +63335 31062 lineto +63281 30965 lineto +63255 30914 lineto +63253 30912 lineto +63250 30906 lineto +63181 30825 lineto +63142 30777 lineto +62636 30272 lineto +62751 30156 lineto +62877 29967 lineto +62964 29757 lineto +63008 29534 lineto +63004 29275 lineto +62954 29053 lineto +62862 28846 lineto +62731 28660 lineto +62567 28503 lineto +62375 28382 lineto +62163 28299 lineto +61940 28260 lineto +61713 28265 lineto +61491 28313 lineto +61283 28404 lineto +61096 28534 lineto +60938 28697 lineto +60815 28888 lineto +60732 29099 lineto +60691 29322 lineto +60694 29549 lineto +60736 29751 lineto +60600 29751 lineto +60597 29743 lineto +60588 29710 lineto +60586 29708 lineto +60585 29702 lineto +60531 29605 lineto +60505 29554 lineto +60503 29552 lineto +60500 29546 lineto +60431 29465 lineto +60392 29417 lineto +60293 29319 lineto +60273 29223 lineto +60259 29191 lineto +60259 29016 lineto +60259 29007 lineto +60239 28831 lineto +60197 28703 lineto +60188 28670 lineto +60186 28668 lineto +60185 28662 lineto +60131 28565 lineto +60105 28514 lineto +60103 28512 lineto +60100 28506 lineto +60031 28425 lineto +59992 28377 lineto +59641 28026 lineto +59641 28025 lineto +59640 28025 lineto +59634 28018 lineto +59568 27967 lineto +59503 27913 lineto +59497 27911 lineto +59495 27908 lineto +59415 27867 lineto +59346 27830 lineto +59342 27830 lineto +59337 27826 lineto +59246 27800 lineto +59177 27778 lineto +59172 27778 lineto +59167 27776 lineto +59070 27768 lineto +59000 27761 lineto +58991 27761 lineto +58991 27576 lineto +79819 27576 lineto +poly0 +newpath 61363 31569 moveto +61591 31797 lineto +61591 32228 lineto +61526 32391 lineto +61491 32585 lineto +61493 32783 lineto +61535 32976 lineto +61612 33158 lineto +61621 33172 lineto +61599 33207 lineto +61526 33391 lineto +61491 33585 lineto +61493 33783 lineto +61535 33976 lineto +61612 34158 lineto +61621 34172 lineto +61599 34207 lineto +61577 34261 lineto +57246 34261 lineto +57237 34261 lineto +57061 34281 lineto +56932 34323 lineto +56900 34332 lineto +56897 34334 lineto +56892 34335 lineto +56793 34389 lineto +56744 34415 lineto +56741 34417 lineto +56736 34420 lineto +56654 34489 lineto +56607 34528 lineto +54555 36579 lineto +54457 36516 lineto +54273 36445 lineto +54078 36410 lineto +53880 36414 lineto +53687 36457 lineto +53506 36536 lineto +53497 36542 lineto +53457 36516 lineto +53273 36445 lineto +53078 36410 lineto +52880 36414 lineto +52687 36457 lineto +52563 36511 lineto +51062 36511 lineto +51587 35986 lineto +53753 35986 lineto +53761 35986 lineto +53828 35979 lineto +53911 35970 lineto +53916 35969 lineto +53920 35968 lineto +54010 35940 lineto +54063 35923 lineto +54065 35922 lineto +54071 35920 lineto +54190 35855 lineto +54204 35847 lineto +54204 35847 lineto +54211 35843 lineto +54284 35782 lineto +54327 35747 lineto +54332 35742 lineto +56087 33986 lineto +57753 33986 lineto +57761 33986 lineto +57828 33979 lineto +57911 33970 lineto +57916 33969 lineto +57920 33968 lineto +58010 33940 lineto +58063 33923 lineto +58065 33922 lineto +58071 33920 lineto +58190 33855 lineto +58204 33847 lineto +58204 33847 lineto +58211 33843 lineto +58284 33782 lineto +58327 33747 lineto +58333 33741 lineto +59529 32545 lineto +59535 32539 lineto +59564 32503 lineto +59630 32422 lineto +59704 32281 lineto +59705 32276 lineto +59707 32273 lineto +59733 32182 lineto +59750 32128 lineto +59750 32127 lineto +59752 32120 lineto +59760 32027 lineto +59766 31970 lineto +59766 31962 lineto +59766 31769 lineto +59851 31768 lineto +60036 31730 lineto +60210 31657 lineto +60341 31569 lineto +61363 31569 lineto +poly0 +newpath 54500 39299 moveto +54531 39318 lineto +54703 39388 lineto +54644 39480 lineto +54575 39655 lineto +54541 39839 lineto +54543 40027 lineto +54582 40211 lineto +54656 40384 lineto +54763 40539 lineto +54897 40670 lineto +55054 40773 lineto +55228 40843 lineto +55413 40879 lineto +55601 40877 lineto +55785 40840 lineto +55958 40767 lineto +56114 40662 lineto +56246 40528 lineto +56350 40372 lineto +56421 40198 lineto +56432 40142 lineto +56587 39986 lineto +57750 39986 lineto +57756 39986 lineto +57761 39986 lineto +60162 39986 lineto +60598 40423 lineto +60605 40453 lineto +60652 40565 lineto +60640 40584 lineto +60591 40703 lineto +60566 40830 lineto +60566 41261 lineto +58707 41261 lineto +58705 41049 lineto +58663 40866 lineto +58587 40695 lineto +58479 40541 lineto +58343 40412 lineto +58184 40311 lineto +58009 40243 lineto +57824 40210 lineto +57636 40214 lineto +57453 40254 lineto +57280 40330 lineto +57126 40437 lineto +56996 40572 lineto +56894 40730 lineto +56825 40905 lineto +56791 41089 lineto +56792 41261 lineto +51933 41261 lineto +51931 41053 lineto +51891 40874 lineto +51816 40707 lineto +51711 40557 lineto +51578 40431 lineto +51424 40332 lineto +51253 40266 lineto +51072 40234 lineto +50889 40238 lineto +50851 40247 lineto +50895 40181 lineto +50944 40062 lineto +50969 39935 lineto +50969 39329 lineto +52000 39329 lineto +52013 39329 lineto +52558 39329 lineto +52714 39392 lineto +52908 39429 lineto +53106 39427 lineto +53299 39388 lineto +53482 39311 lineto +53500 39299 lineto +53531 39318 lineto +53714 39392 lineto +53908 39429 lineto +54106 39427 lineto +54299 39388 lineto +54482 39311 lineto +54500 39299 lineto +poly0 +newpath 63909 43079 moveto +64872 43080 lineto +65595 43802 lineto +65530 43830 lineto +65376 43937 lineto +65246 44072 lineto +65144 44230 lineto +65075 44405 lineto +65041 44589 lineto +65043 44777 lineto +65082 44961 lineto +65156 45134 lineto +65263 45289 lineto +65397 45420 lineto +65398 45422 lineto +65376 45437 lineto +65246 45572 lineto +65144 45730 lineto +65075 45905 lineto +65041 46089 lineto +65043 46277 lineto +65082 46461 lineto +65156 46634 lineto +65184 46675 lineto +65184 47169 lineto +65144 47230 lineto +65075 47405 lineto +65041 47589 lineto +65043 47777 lineto +65082 47961 lineto +65156 48134 lineto +65263 48289 lineto +65397 48420 lineto +65554 48523 lineto +65728 48593 lineto +65913 48629 lineto +66101 48627 lineto +66285 48590 lineto +66458 48517 lineto +66462 48515 lineto +66481 48533 lineto +66589 48605 lineto +66708 48654 lineto +66835 48679 lineto +67434 48679 lineto +67434 51262 lineto +67434 53262 lineto +67434 56670 lineto +67434 56681 lineto +67434 58582 lineto +66643 59373 lineto +66574 59360 lineto +66409 59364 lineto +66409 58387 lineto +66434 58262 lineto +66431 58053 lineto +66409 57955 lineto +66409 56478 lineto +66421 56448 lineto +66458 56264 lineto +66455 56049 lineto +66413 55866 lineto +66337 55695 lineto +66229 55541 lineto +66093 55412 lineto +65934 55311 lineto +65759 55243 lineto +65574 55210 lineto +65386 55214 lineto +65203 55254 lineto +65030 55330 lineto +64876 55437 lineto +64746 55572 lineto +64644 55730 lineto +64575 55905 lineto +64541 56089 lineto +64543 56277 lineto +64582 56461 lineto +64591 56483 lineto +64591 57238 lineto +64572 57234 lineto +64389 57238 lineto +64210 57277 lineto +64042 57351 lineto +63892 57455 lineto +63765 57587 lineto +63665 57741 lineto +63598 57911 lineto +63565 58091 lineto +63567 58274 lineto +63605 58453 lineto +63677 58622 lineto +63781 58773 lineto +63912 58901 lineto +64065 59002 lineto +64235 59070 lineto +64415 59105 lineto +64591 59104 lineto +64591 60015 lineto +64575 60055 lineto +64541 60239 lineto +64543 60427 lineto +64582 60611 lineto +64625 60714 lineto +64575 60842 lineto +64541 61026 lineto +64543 61214 lineto +64582 61398 lineto +64633 61519 lineto +64543 61390 lineto +64374 61229 lineto +64177 61104 lineto +63960 61019 lineto +63730 60979 lineto +63497 60984 lineto +63269 61034 lineto +63055 61127 lineto +62864 61260 lineto +62702 61428 lineto +62576 61624 lineto +62566 61650 lineto +62566 61159 lineto +62555 61068 lineto +62550 61008 lineto +62548 61003 lineto +62548 61000 lineto +62500 60849 lineto +62447 60754 lineto +62427 60715 lineto +62424 60713 lineto +62423 60709 lineto +62371 60647 lineto +62326 60592 lineto +62321 60587 lineto +61609 59876 lineto +61785 59840 lineto +61958 59767 lineto +62114 59662 lineto +62246 59528 lineto +62350 59372 lineto +62421 59198 lineto +62458 59014 lineto +62455 58799 lineto +62413 58616 lineto +62379 58540 lineto +62385 58531 lineto +62434 58412 lineto +62459 58285 lineto +62459 57551 lineto +62433 57425 lineto +62383 57305 lineto +62310 57198 lineto +62219 57107 lineto +62111 57035 lineto +61992 56986 lineto +61865 56961 lineto +61694 56961 lineto +61443 56710 lineto +61503 56619 lineto +61574 56444 lineto +61610 56258 lineto +61608 56069 lineto +61570 55884 lineto +61497 55710 lineto +61469 55670 lineto +61503 55619 lineto +61574 55444 lineto +61610 55258 lineto +61608 55069 lineto +61572 54897 lineto +62002 55327 lineto +62035 55476 lineto +62112 55658 lineto +62224 55821 lineto +62365 55959 lineto +62531 56068 lineto +62714 56142 lineto +62908 56179 lineto +63106 56177 lineto +63299 56138 lineto +63482 56061 lineto +63609 55976 lineto +63661 55970 lineto +63666 55969 lineto +63670 55968 lineto +63760 55940 lineto +63813 55923 lineto +63815 55922 lineto +63821 55920 lineto +63940 55855 lineto +63954 55847 lineto +63954 55847 lineto +63961 55843 lineto +64034 55782 lineto +64077 55747 lineto +64082 55742 lineto +65751 54073 lineto +65777 54067 lineto +65946 53996 lineto +66000 53960 lineto +66065 54002 lineto +66235 54070 lineto +66415 54105 lineto +66598 54103 lineto +66777 54067 lineto +66946 53996 lineto +67098 53893 lineto +67227 53763 lineto +67328 53611 lineto +67398 53442 lineto +67434 53262 lineto +67431 53053 lineto +67391 52874 lineto +67316 52707 lineto +67211 52557 lineto +67078 52431 lineto +66924 52332 lineto +66753 52266 lineto +66572 52234 lineto +66389 52238 lineto +66210 52277 lineto +66042 52351 lineto +65999 52381 lineto +65924 52332 lineto +65753 52266 lineto +65572 52234 lineto +65389 52238 lineto +65210 52277 lineto +65042 52351 lineto +64892 52455 lineto +64765 52587 lineto +64665 52741 lineto +64598 52911 lineto +64596 52920 lineto +63911 53605 lineto +63970 53463 lineto +64008 53269 lineto +64005 53043 lineto +63961 52850 lineto +63881 52670 lineto +63816 52578 lineto +63816 51986 lineto +65040 51986 lineto +65065 52002 lineto +65235 52070 lineto +65415 52105 lineto +65598 52103 lineto +65777 52067 lineto +65946 51996 lineto +66000 51960 lineto +66065 52002 lineto +66235 52070 lineto +66415 52105 lineto +66598 52103 lineto +66777 52067 lineto +66946 51996 lineto +67098 51893 lineto +67227 51763 lineto +67328 51611 lineto +67398 51442 lineto +67434 51262 lineto +67431 51053 lineto +67391 50874 lineto +67316 50707 lineto +67211 50557 lineto +67078 50431 lineto +66924 50332 lineto +66753 50266 lineto +66572 50234 lineto +66389 50238 lineto +66210 50277 lineto +66042 50351 lineto +65999 50381 lineto +65924 50332 lineto +65753 50266 lineto +65572 50234 lineto +65389 50238 lineto +65210 50277 lineto +65042 50351 lineto +65037 50354 lineto +63915 50354 lineto +63934 50262 lineto +63931 50053 lineto +63891 49874 lineto +63816 49707 lineto +63789 49670 lineto +63828 49611 lineto +63898 49442 lineto +63934 49262 lineto +63931 49053 lineto +63909 48955 lineto +63909 43079 lineto +poly0 +newpath 39500 44640 moveto +39551 44673 lineto +39726 44744 lineto +39912 44780 lineto +40101 44778 lineto +40184 44761 lineto +40184 45573 lineto +40184 45581 lineto +40191 45649 lineto +40200 45731 lineto +40201 45737 lineto +40202 45740 lineto +40230 45831 lineto +40247 45883 lineto +40248 45886 lineto +40250 45891 lineto +40315 46011 lineto +40323 46024 lineto +40323 46025 lineto +40327 46031 lineto +40388 46105 lineto +40423 46147 lineto +40429 46153 lineto +40846 46570 lineto +40421 46995 lineto +40415 47001 lineto +40385 47038 lineto +40320 47118 lineto +40246 47259 lineto +40244 47265 lineto +40243 47267 lineto +40216 47358 lineto +40200 47412 lineto +40199 47414 lineto +40198 47420 lineto +40189 47515 lineto +40184 47570 lineto +40184 47578 lineto +40184 47854 lineto +33247 47854 lineto +33239 47854 lineto +33174 47862 lineto +33088 47870 lineto +33082 47872 lineto +33080 47872 lineto +33025 47890 lineto +32936 47917 lineto +32932 47919 lineto +32929 47920 lineto +32817 47982 lineto +32796 47993 lineto +32795 47994 lineto +32789 47997 lineto +32715 48059 lineto +32673 48093 lineto +32667 48099 lineto +32421 48345 lineto +32415 48351 lineto +32385 48388 lineto +32320 48468 lineto +32254 48593 lineto +32088 48560 lineto +31899 48562 lineto +31816 48580 lineto +31816 45670 lineto +31816 45659 lineto +31816 44762 lineto +31912 44780 lineto +32101 44778 lineto +32286 44740 lineto +32460 44667 lineto +32500 44640 lineto +32551 44673 lineto +32726 44744 lineto +32912 44780 lineto +33101 44778 lineto +33286 44740 lineto +33460 44667 lineto +33500 44640 lineto +33551 44673 lineto +33726 44744 lineto +33912 44780 lineto +34101 44778 lineto +34286 44740 lineto +34460 44667 lineto +34500 44640 lineto +34551 44673 lineto +34726 44744 lineto +34912 44780 lineto +35101 44778 lineto +35286 44740 lineto +35460 44667 lineto +35500 44640 lineto +35551 44673 lineto +35726 44744 lineto +35912 44780 lineto +36101 44778 lineto +36286 44740 lineto +36460 44667 lineto +36500 44640 lineto +36551 44673 lineto +36726 44744 lineto +36912 44780 lineto +37101 44778 lineto +37286 44740 lineto +37460 44667 lineto +37500 44640 lineto +37551 44673 lineto +37726 44744 lineto +37912 44780 lineto +38101 44778 lineto +38286 44740 lineto +38460 44667 lineto +38500 44640 lineto +38551 44673 lineto +38726 44744 lineto +38912 44780 lineto +39101 44778 lineto +39286 44740 lineto +39460 44667 lineto +39500 44640 lineto +poly0 +newpath 59419 50405 moveto +59430 50456 lineto +59503 50630 lineto +59530 50671 lineto +59497 50721 lineto +59426 50896 lineto +59390 51082 lineto +59392 51271 lineto +59423 51424 lineto +59309 51486 lineto +59296 51493 lineto +59295 51494 lineto +59289 51497 lineto +59215 51559 lineto +59173 51593 lineto +59166 51600 lineto +58912 51854 lineto +58557 51854 lineto +58528 51787 lineto +58534 51782 lineto +58577 51747 lineto +58583 51741 lineto +59079 51245 lineto +59085 51239 lineto +59114 51203 lineto +59180 51122 lineto +59254 50981 lineto +59255 50976 lineto +59257 50973 lineto +59283 50882 lineto +59300 50828 lineto +59300 50827 lineto +59302 50820 lineto +59310 50726 lineto +59316 50670 lineto +59316 50662 lineto +59316 50508 lineto +59419 50405 lineto +poly0 +newpath 33500 50640 moveto +33551 50673 lineto +33726 50744 lineto +33912 50780 lineto +34101 50778 lineto +34184 50761 lineto +34184 52829 lineto +34088 52810 lineto +33899 52812 lineto +33714 52850 lineto +33624 52888 lineto +33621 52885 lineto +33502 52836 lineto +33375 52811 lineto +32621 52811 lineto +32558 52824 lineto +31816 52082 lineto +31816 50762 lineto +31912 50780 lineto +32101 50778 lineto +32286 50740 lineto +32460 50667 lineto +32500 50640 lineto +32551 50673 lineto +32726 50744 lineto +32912 50780 lineto +33101 50778 lineto +33286 50740 lineto +33460 50667 lineto +33500 50640 lineto +poly0 +newpath 59433 53464 moveto +59503 53630 lineto +59530 53671 lineto +59497 53721 lineto +59426 53896 lineto +59390 54082 lineto +59392 54271 lineto +59430 54456 lineto +59503 54630 lineto +59530 54671 lineto +59497 54721 lineto +59426 54896 lineto +59390 55082 lineto +59392 55271 lineto +59430 55456 lineto +59503 55630 lineto +59530 55671 lineto +59497 55721 lineto +59426 55896 lineto +59390 56082 lineto +59392 56271 lineto +59430 56456 lineto +59503 56630 lineto +59608 56787 lineto +59684 56863 lineto +59684 56923 lineto +59684 56931 lineto +59691 56999 lineto +59700 57081 lineto +59701 57087 lineto +59702 57090 lineto +59730 57181 lineto +59747 57233 lineto +59748 57236 lineto +59750 57241 lineto +59815 57361 lineto +59823 57374 lineto +59823 57375 lineto +59827 57381 lineto +59888 57455 lineto +59923 57497 lineto +59929 57503 lineto +60541 58115 lineto +60541 58289 lineto +60567 58415 lineto +60617 58535 lineto +60620 58540 lineto +60575 58655 lineto +60545 58812 lineto +60075 58341 lineto +60069 58335 lineto +60032 58306 lineto +59952 58240 lineto +59811 58166 lineto +59805 58165 lineto +59803 58163 lineto +59712 58137 lineto +59658 58120 lineto +59656 58120 lineto +59650 58118 lineto +59555 58110 lineto +59500 58104 lineto +59492 58104 lineto +55837 58104 lineto +55812 58079 lineto +55958 58017 lineto +56114 57912 lineto +56246 57778 lineto +56350 57622 lineto +56421 57448 lineto +56458 57264 lineto +56455 57049 lineto +56413 56866 lineto +56337 56695 lineto +56229 56541 lineto +56093 56412 lineto +55934 56311 lineto +55759 56243 lineto +55574 56210 lineto +55386 56214 lineto +55203 56254 lineto +55030 56330 lineto +54876 56437 lineto +54746 56572 lineto +54644 56730 lineto +54593 56860 lineto +54066 56332 lineto +54066 54390 lineto +54425 54749 lineto +54431 54755 lineto +54467 54785 lineto +54548 54850 lineto +54689 54924 lineto +54694 54926 lineto +54697 54927 lineto +54787 54954 lineto +54842 54970 lineto +54843 54971 lineto +54850 54972 lineto +54943 54981 lineto +55000 54986 lineto +55008 54986 lineto +56408 54986 lineto +56390 55082 lineto +56392 55271 lineto +56430 55456 lineto +56503 55630 lineto +56530 55671 lineto +56497 55721 lineto +56426 55896 lineto +56390 56082 lineto +56392 56271 lineto +56430 56456 lineto +56503 56630 lineto +56608 56787 lineto +56742 56920 lineto +56900 57025 lineto +57075 57097 lineto +57260 57134 lineto +57563 57135 lineto +57753 57133 lineto +57937 57093 lineto +58111 57019 lineto +58267 56912 lineto +58400 56777 lineto +58503 56619 lineto +58574 56444 lineto +58610 56258 lineto +58608 56069 lineto +58570 55884 lineto +58497 55710 lineto +58469 55670 lineto +58503 55619 lineto +58574 55444 lineto +58610 55258 lineto +58608 55069 lineto +58570 54884 lineto +58497 54710 lineto +58469 54670 lineto +58503 54619 lineto +58574 54444 lineto +58610 54258 lineto +58608 54069 lineto +58570 53884 lineto +58497 53710 lineto +58469 53670 lineto +58503 53619 lineto +58556 53486 lineto +59253 53486 lineto +59261 53486 lineto +59328 53479 lineto +59411 53470 lineto +59416 53469 lineto +59420 53468 lineto +59433 53464 lineto +poly0 + 1 setgray +50 setlinewidth +newpath 32000 51170 159 0 360 arc fill stroke +newpath 26000 51170 159 0 360 arc fill stroke +400 setlinewidth +71610 30170 72390 30170 line +71610 32570 72390 32570 line +74000 30680 74000 31460 line +65610 30170 66390 30170 line +65610 32570 66390 32570 line +68000 30680 68000 31460 line +50 setlinewidth +newpath 61850 63920 472 0 360 arc fill stroke +newpath 55650 63920 472 0 360 arc fill stroke +newpath 58950 63680 160 0 360 arc fill stroke +newpath 58150 63680 160 0 360 arc fill stroke +newpath 59750 63680 160 0 360 arc fill stroke +newpath 58550 62680 160 0 360 arc fill stroke +newpath 57750 62680 160 0 360 arc fill stroke +newpath 59350 62680 160 0 360 arc fill stroke +newpath 53600 63920 472 0 360 arc fill stroke +newpath 47400 63920 472 0 360 arc fill stroke +newpath 50700 63680 160 0 360 arc fill stroke +newpath 49900 63680 160 0 360 arc fill stroke +newpath 51500 63680 160 0 360 arc fill stroke +newpath 50300 62680 160 0 360 arc fill stroke +newpath 49500 62680 160 0 360 arc fill stroke +newpath 51100 62680 160 0 360 arc fill stroke +newpath 45350 63920 472 0 360 arc fill stroke +newpath 39150 63920 472 0 360 arc fill stroke +newpath 42450 63680 160 0 360 arc fill stroke +newpath 41650 63680 160 0 360 arc fill stroke +newpath 43250 63680 160 0 360 arc fill stroke +newpath 42050 62680 160 0 360 arc fill stroke +newpath 41250 62680 160 0 360 arc fill stroke +newpath 42850 62680 160 0 360 arc fill stroke +newpath 37100 63920 472 0 360 arc fill stroke +newpath 30900 63920 472 0 360 arc fill stroke +newpath 34200 63680 160 0 360 arc fill stroke +newpath 33400 63680 160 0 360 arc fill stroke +newpath 35000 63680 160 0 360 arc fill stroke +newpath 33800 62680 160 0 360 arc fill stroke +newpath 33000 62680 160 0 360 arc fill stroke +newpath 34600 62680 160 0 360 arc fill stroke +newpath 28850 63920 472 0 360 arc fill stroke +newpath 22650 63920 472 0 360 arc fill stroke +newpath 25950 63680 160 0 360 arc fill stroke +newpath 25150 63680 160 0 360 arc fill stroke +newpath 26750 63680 160 0 360 arc fill stroke +newpath 25550 62680 160 0 360 arc fill stroke +newpath 24750 62680 160 0 360 arc fill stroke +newpath 26350 62680 160 0 360 arc fill stroke +newpath 22650 29420 472 0 360 arc fill stroke +newpath 28850 29420 472 0 360 arc fill stroke +newpath 25550 29660 160 0 360 arc fill stroke +newpath 26350 29660 160 0 360 arc fill stroke +newpath 24750 29660 160 0 360 arc fill stroke +newpath 25950 30660 160 0 360 arc fill stroke +newpath 26750 30660 160 0 360 arc fill stroke +newpath 25150 30660 160 0 360 arc fill stroke +newpath 30900 29420 472 0 360 arc fill stroke +newpath 37100 29420 472 0 360 arc fill stroke +newpath 33800 29660 160 0 360 arc fill stroke +newpath 34600 29660 160 0 360 arc fill stroke +newpath 33000 29660 160 0 360 arc fill stroke +newpath 34200 30660 160 0 360 arc fill stroke +newpath 35000 30660 160 0 360 arc fill stroke +newpath 33400 30660 160 0 360 arc fill stroke +newpath 39150 29420 472 0 360 arc fill stroke +newpath 45350 29420 472 0 360 arc fill stroke +newpath 42050 29660 160 0 360 arc fill stroke +newpath 42850 29660 160 0 360 arc fill stroke +newpath 41250 29660 160 0 360 arc fill stroke +newpath 42450 30660 160 0 360 arc fill stroke +newpath 43250 30660 160 0 360 arc fill stroke +newpath 41650 30660 160 0 360 arc fill stroke +newpath 47400 29420 472 0 360 arc fill stroke +newpath 53600 29420 472 0 360 arc fill stroke +newpath 50300 29660 160 0 360 arc fill stroke +newpath 51100 29660 160 0 360 arc fill stroke +newpath 49500 29660 160 0 360 arc fill stroke +newpath 50700 30660 160 0 360 arc fill stroke +newpath 51500 30660 160 0 360 arc fill stroke +newpath 49900 30660 160 0 360 arc fill stroke +newpath 55650 29420 472 0 360 arc fill stroke +newpath 61850 29420 472 0 360 arc fill stroke +newpath 58550 29660 160 0 360 arc fill stroke +newpath 59350 29660 160 0 360 arc fill stroke +newpath 57750 29660 160 0 360 arc fill stroke +newpath 58950 30660 160 0 360 arc fill stroke +newpath 59750 30660 160 0 360 arc fill stroke +newpath 58150 30660 160 0 360 arc fill stroke +newpath 66500 51170 160 0 360 arc fill stroke +newpath 65500 51170 160 0 360 arc fill stroke +newpath 66500 53170 160 0 360 arc fill stroke +newpath 65500 53170 160 0 360 arc fill stroke +newpath 63000 53170 160 0 360 arc fill stroke +newpath 63000 55170 160 0 360 arc fill stroke +newpath 71500 64420 160 0 360 arc fill stroke +newpath 72500 64420 160 0 360 arc fill stroke +newpath 65500 60320 160 0 360 arc fill stroke +newpath 66500 60320 160 0 360 arc fill stroke +newpath 66500 61107 160 0 360 arc fill stroke +newpath 65500 61107 160 0 360 arc fill stroke +newpath 63638 62170 453 0 360 arc fill stroke +newpath 68362 62170 453 0 360 arc fill stroke +newpath 33000 53920 160 0 360 arc fill stroke +newpath 34000 53920 160 0 360 arc fill stroke +newpath 35000 53920 160 0 360 arc fill stroke +newpath 36000 53920 160 0 360 arc fill stroke +newpath 37000 53920 160 0 360 arc fill stroke +newpath 38000 53920 160 0 360 arc fill stroke +newpath 39000 53920 160 0 360 arc fill stroke +newpath 40000 53920 160 0 360 arc fill stroke +newpath 41000 53920 160 0 360 arc fill stroke +newpath 41000 56920 160 0 360 arc fill stroke +newpath 40000 56920 160 0 360 arc fill stroke +newpath 39000 56920 160 0 360 arc fill stroke +newpath 38000 56920 160 0 360 arc fill stroke +newpath 37000 56920 160 0 360 arc fill stroke +newpath 36000 56920 160 0 360 arc fill stroke +newpath 35000 56920 160 0 360 arc fill stroke +newpath 34000 56920 160 0 360 arc fill stroke +newpath 33000 56920 160 0 360 arc fill stroke +newpath 39000 39420 160 0 360 arc fill stroke +newpath 38000 39420 160 0 360 arc fill stroke +newpath 37000 39420 160 0 360 arc fill stroke +newpath 36000 39420 160 0 360 arc fill stroke +newpath 35000 39420 160 0 360 arc fill stroke +newpath 34000 39420 160 0 360 arc fill stroke +newpath 33000 39420 160 0 360 arc fill stroke +newpath 32000 39420 160 0 360 arc fill stroke +newpath 31000 39420 160 0 360 arc fill stroke +newpath 31000 36420 160 0 360 arc fill stroke +newpath 32000 36420 160 0 360 arc fill stroke +newpath 33000 36420 160 0 360 arc fill stroke +newpath 34000 36420 160 0 360 arc fill stroke +newpath 35000 36420 160 0 360 arc fill stroke +newpath 36000 36420 160 0 360 arc fill stroke +newpath 37000 36420 160 0 360 arc fill stroke +newpath 38000 36420 160 0 360 arc fill stroke +newpath 39000 36420 160 0 360 arc fill stroke +newpath 50000 39420 160 0 360 arc fill stroke +newpath 49000 39420 160 0 360 arc fill stroke +newpath 48000 39420 160 0 360 arc fill stroke +newpath 47000 39420 160 0 360 arc fill stroke +newpath 46000 39420 160 0 360 arc fill stroke +newpath 45000 39420 160 0 360 arc fill stroke +newpath 44000 39420 160 0 360 arc fill stroke +newpath 43000 39420 160 0 360 arc fill stroke +newpath 42000 39420 160 0 360 arc fill stroke +newpath 42000 36420 160 0 360 arc fill stroke +newpath 43000 36420 160 0 360 arc fill stroke +newpath 44000 36420 160 0 360 arc fill stroke +newpath 45000 36420 160 0 360 arc fill stroke +newpath 46000 36420 160 0 360 arc fill stroke +newpath 47000 36420 160 0 360 arc fill stroke +newpath 48000 36420 160 0 360 arc fill stroke +newpath 49000 36420 160 0 360 arc fill stroke +newpath 50000 36420 160 0 360 arc fill stroke +newpath 44000 53920 160 0 360 arc fill stroke +newpath 45000 53920 160 0 360 arc fill stroke +newpath 46000 53920 160 0 360 arc fill stroke +newpath 47000 53920 160 0 360 arc fill stroke +newpath 48000 53920 160 0 360 arc fill stroke +newpath 49000 53920 160 0 360 arc fill stroke +newpath 50000 53920 160 0 360 arc fill stroke +newpath 51000 53920 160 0 360 arc fill stroke +newpath 52000 53920 160 0 360 arc fill stroke +newpath 52000 56920 160 0 360 arc fill stroke +newpath 51000 56920 160 0 360 arc fill stroke +newpath 50000 56920 160 0 360 arc fill stroke +newpath 49000 56920 160 0 360 arc fill stroke +newpath 48000 56920 160 0 360 arc fill stroke +newpath 47000 56920 160 0 360 arc fill stroke +newpath 46000 56920 160 0 360 arc fill stroke +newpath 45000 56920 160 0 360 arc fill stroke +newpath 44000 56920 160 0 360 arc fill stroke +newpath 62500 32670 159 0 360 arc fill stroke +newpath 62500 33670 159 0 360 arc fill stroke +newpath 53000 37420 159 0 360 arc fill stroke +newpath 54000 37420 159 0 360 arc fill stroke +newpath 55000 38420 159 0 360 arc fill stroke +newpath 53000 38420 159 0 360 arc fill stroke +newpath 62500 34670 159 0 360 arc fill stroke +newpath 70250 53170 160 0 360 arc fill stroke +newpath 71250 53170 160 0 360 arc fill stroke +newpath 54000 38420 159 0 360 arc fill stroke +newpath 61500 41170 160 0 360 arc fill stroke +newpath 61500 40170 160 0 360 arc fill stroke +newpath 62500 40170 160 0 360 arc fill stroke +newpath 72000 35670 160 0 360 arc fill stroke +newpath 73000 35670 160 0 360 arc fill stroke +newpath 75500 41170 600 0 360 arc fill stroke +newpath 69000 42170 225 0 360 arc fill stroke +newpath 69000 41170 225 0 360 arc fill stroke +newpath 69000 40170 225 0 360 arc fill stroke +newpath 51000 49670 160 0 360 arc fill stroke +newpath 50000 49670 160 0 360 arc fill stroke +newpath 49000 49670 160 0 360 arc fill stroke +newpath 48000 49670 160 0 360 arc fill stroke +newpath 47000 49670 160 0 360 arc fill stroke +newpath 46000 49670 160 0 360 arc fill stroke +newpath 45000 49670 160 0 360 arc fill stroke +newpath 44000 49670 160 0 360 arc fill stroke +newpath 43000 49670 160 0 360 arc fill stroke +newpath 42000 49670 160 0 360 arc fill stroke +newpath 41000 49670 160 0 360 arc fill stroke +newpath 40000 49670 160 0 360 arc fill stroke +newpath 39000 49670 160 0 360 arc fill stroke +newpath 38000 49670 160 0 360 arc fill stroke +newpath 37000 49670 160 0 360 arc fill stroke +newpath 36000 49670 160 0 360 arc fill stroke +newpath 35000 49670 160 0 360 arc fill stroke +newpath 34000 49670 160 0 360 arc fill stroke +newpath 33000 49670 160 0 360 arc fill stroke +newpath 32000 49670 160 0 360 arc fill stroke +newpath 32000 43670 160 0 360 arc fill stroke +newpath 33000 43670 160 0 360 arc fill stroke +newpath 34000 43670 160 0 360 arc fill stroke +newpath 35000 43670 160 0 360 arc fill stroke +newpath 36000 43670 160 0 360 arc fill stroke +newpath 37000 43670 160 0 360 arc fill stroke +newpath 38000 43670 160 0 360 arc fill stroke +newpath 39000 43670 160 0 360 arc fill stroke +newpath 40000 43670 160 0 360 arc fill stroke +newpath 41000 43670 160 0 360 arc fill stroke +newpath 42000 43670 160 0 360 arc fill stroke +newpath 43000 43670 160 0 360 arc fill stroke +newpath 44000 43670 160 0 360 arc fill stroke +newpath 45000 43670 160 0 360 arc fill stroke +newpath 46000 43670 160 0 360 arc fill stroke +newpath 47000 43670 160 0 360 arc fill stroke +newpath 48000 43670 160 0 360 arc fill stroke +newpath 49000 43670 160 0 360 arc fill stroke +newpath 50000 43670 160 0 360 arc fill stroke +newpath 51000 43670 160 0 360 arc fill stroke +newpath 19370 62631 600 0 360 arc fill stroke +newpath 19370 30741 600 0 360 arc fill stroke +newpath 78425 62631 600 0 360 arc fill stroke +newpath 78425 30741 600 0 360 arc fill stroke +newpath 51000 42170 160 0 360 arc fill stroke +newpath 51000 41170 160 0 360 arc fill stroke +newpath 63000 49170 160 0 360 arc fill stroke +newpath 63000 50170 160 0 360 arc fill stroke +newpath 65500 58170 160 0 360 arc fill stroke +newpath 64500 58170 160 0 360 arc fill stroke +newpath 68750 35670 160 0 360 arc fill stroke +newpath 68750 36670 160 0 360 arc fill stroke +newpath 63250 37670 200 0 360 arc fill stroke +newpath 59250 37670 200 0 360 arc fill stroke +newpath 71250 47670 200 0 360 arc fill stroke +newpath 67250 47670 200 0 360 arc fill stroke +newpath 71250 46170 200 0 360 arc fill stroke +newpath 67250 46170 200 0 360 arc fill stroke +newpath 55500 53170 160 0 360 arc fill stroke +newpath 55500 57170 160 0 360 arc fill stroke +newpath 55500 43920 160 0 360 arc fill stroke +newpath 55500 39920 160 0 360 arc fill stroke +newpath 57750 41170 160 0 360 arc fill stroke +newpath 57750 37170 160 0 360 arc fill stroke +newpath 68000 38920 160 0 360 arc fill stroke +newpath 64000 38920 160 0 360 arc fill stroke +newpath 63250 36170 160 0 360 arc fill stroke +newpath 59250 36170 160 0 360 arc fill stroke +newpath 53250 45670 160 0 360 arc fill stroke +newpath 53250 49670 160 0 360 arc fill stroke +newpath 66000 44670 160 0 360 arc fill stroke +newpath 62000 44670 160 0 360 arc fill stroke +newpath 66000 46170 160 0 360 arc fill stroke +newpath 62000 46170 160 0 360 arc fill stroke +newpath 66000 47670 160 0 360 arc fill stroke +newpath 62000 47670 160 0 360 arc fill stroke +newpath 54500 49670 160 0 360 arc fill stroke +newpath 54500 45670 160 0 360 arc fill stroke +newpath 60500 44170 160 0 360 arc fill stroke +newpath 60500 45170 160 0 360 arc fill stroke +newpath 60500 46170 160 0 360 arc fill stroke +newpath 60500 47170 160 0 360 arc fill stroke +newpath 60500 48170 160 0 360 arc fill stroke +newpath 60500 49170 160 0 360 arc fill stroke +newpath 60500 50170 160 0 360 arc fill stroke +newpath 60500 51170 160 0 360 arc fill stroke +newpath 60500 52170 160 0 360 arc fill stroke +newpath 60500 53170 160 0 360 arc fill stroke +newpath 60500 54170 160 0 360 arc fill stroke +newpath 60500 55170 160 0 360 arc fill stroke +newpath 60500 56170 160 0 360 arc fill stroke +newpath 60500 43170 160 0 360 arc fill stroke +newpath 57500 56170 160 0 360 arc fill stroke +newpath 57500 55170 160 0 360 arc fill stroke +newpath 57500 54170 160 0 360 arc fill stroke +newpath 57500 53170 160 0 360 arc fill stroke +newpath 57500 52170 160 0 360 arc fill stroke +newpath 57500 51170 160 0 360 arc fill stroke +newpath 57500 50170 160 0 360 arc fill stroke +newpath 57500 49170 160 0 360 arc fill stroke +newpath 57500 48170 160 0 360 arc fill stroke +newpath 57500 47170 160 0 360 arc fill stroke +newpath 57500 46170 160 0 360 arc fill stroke +newpath 57500 45170 160 0 360 arc fill stroke +newpath 57500 44170 160 0 360 arc fill stroke +newpath 57500 43170 160 0 360 arc fill stroke +newpath 61500 57920 200 0 360 arc fill stroke +newpath 61500 58920 200 0 360 arc fill stroke +newpath 70500 56170 160 0 360 arc fill stroke +newpath 65500 56170 160 0 360 arc fill stroke + 0 setgray +showpage +grestore +%%EOF diff --git a/pwm_appl/10ch_pwm_appl.c b/pwm_appl/10ch_pwm_appl.c deleted file mode 100644 index afb4350..0000000 --- a/pwm_appl/10ch_pwm_appl.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Auras - * - * This file is part of the DF10CH Atmolight controller project. - * - * DF10CH Atmolight controller 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. - * - * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - */ - -// ====================================================================== -// Application firmware for PWM processor. -// - -#include -#include -#include -#include -#include -#include -#include - -#include "../df10ch_common.h" -#include "../df10ch_usb_proto.h" - - -// --- -// Fuse-Bit settings for the flash programmer (ATmega 162): -// -// M161C=1 -// BODLEVEL2=1 -// BODLEVEL1=0 -// BODLEVEL0=0 -// -// OCDEN=1 -// JTAGEN=1 -// SPIEN=0 -// WDTON=0 -// EESAVE=1 -// BOOTSZ1=0 -// BOOTSZ0=0 -// BOOTRST=1 -// -// CKDIV8=1 -// CKOUT=1 -// SUT1=0 -// SUT0=1 -// CKSEL3=1 -// CKSEL2=1 -// CKSEL1=1 -// CKSEL0=1 -// -// Memory-Lock Bits: -// BLB12=1, BLB11=0, BLB02=1, BLB01=1, LB2=1, LB1=1 -// -FUSES = -{ - .low = (FUSE_SUT1), - .high = (FUSE_SPIEN & FUSE_WDTON & FUSE_BOOTSZ1 & FUSE_BOOTSZ0), - .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0), -}; -LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); -//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; - - -// --- -// System clock related. -// System clock is implemented with hardware timer 0 -// -#define SYS_HWPRESCALE 64 // Hardware Prescaler -#define SYS_PRESCALER 256 // Timer Prescaler - - // useconds <-> timer ticks conversation -#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE * (double)SYS_PRESCALER) + 0.5)) -#define TICKS2US(t) (((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE * SYS_PRESCALER)))) - -static uint16_t sys_clock; - - -// --- -// Keep alive reply related -// -#define MIN_KEEP_ALIVE_PAUSE US2TICKS(15000) - -static uint16_t last_keep_alive; - - -// --- -// Request parser related variables -// -typedef union -{ - uint8_t bytes[REQ_HEADER_SIZE]; - struct - { - uint8_t request_type; - uint8_t request; - bytes_word_t value; - bytes_word_t index; - bytes_word_t length; - }; -} pwm_request_t; - -static pwm_request_t actual_req; -static uint8_t header_pos; -static uint8_t payload_pos; -static uint8_t payload_count; - - -// --- -// PWM generation related -// -#define DEF_F_PWM 100UL // Default PWM cycle frequency in Hz -#define PWM_HWPRESCALE 16 // Hardware timer prescale -#define PWM_PRESCALE 9 // require: (PWM_PRESCALE * PWM_HWPRESCALE) > (size of ISR for timer ) - -#define DEF_MAX_PWM (F_CPU / (PWM_HWPRESCALE * PWM_PRESCALE * DEF_F_PWM) - 1) // Maximum internal resolution for pwm - -#define PWM_STEP_PAGE_SIZE (NCHANNELS + 2) // possible maximum steps: NCHANNELS + Pause + End of Table - -typedef struct pwm_step_s { - uint8_t port_val[NPORTS]; // Values for Port A,B,C,D - uint16_t timer_val; // Timer compare value - struct pwm_step_s *next_step; // Pointer to next list entry - } pwm_step_t; - - // One actual and one shadow page -static pwm_step_t pwm_step_page1[PWM_STEP_PAGE_SIZE] NOMEMINIT; -static pwm_step_t pwm_step_page2[PWM_STEP_PAGE_SIZE] NOMEMINIT; -static pwm_step_t *shadow_pwm_page NOMEMINIT; -static pwm_step_t *active_pwm_page NOMEMINIT; -static pwm_step_t * volatile actual_pwm_step NOMEMINIT; -static uint8_t update_pwm_page NOMEMINIT; - - -// --- -// RX buffer related variables -// -#define RXBUF_SIZE (REQ_HEADER_SIZE + MAX_REQ_PAYLOAD_SIZE + 1) -#if RXBUF_SIZE == 256 -#define CHECK_RXBUF_END(pos) -#else -#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0 -#endif - -static uint8_t volatile rxrpos, rxwpos, rxspos, rx_err_status; -static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT; - - -// --- -// Actual brightness values for each channel -// -static uint16_t bright_vals[NCHANNELS]; - - -// --- -// Port channel mapping related variables -// -typedef struct { uint8_t code, port_bits; } channel_map_t; - -static channel_map_t default_channel_map[NCHANNELS] PROGMEM = { - // J3 - { CM_CODE(PA_IDX, 0), _BV(2) }, - { CM_CODE(PA_IDX, 1), _BV(1) }, - { CM_CODE(PA_IDX, 2), _BV(0) }, - - // J4 - { CM_CODE(PA_IDX, 3), _BV(5) }, - { CM_CODE(PA_IDX, 4), _BV(4) }, - { CM_CODE(PA_IDX, 5), _BV(3) }, - - // J5 - { CM_CODE(PC_IDX, 6), _BV(7) }, - { CM_CODE(PA_IDX, 7), _BV(7) }, - { CM_CODE(PA_IDX, 8), _BV(6) }, - - // J6 - { CM_CODE(PC_IDX, 9), _BV(4) }, - { CM_CODE(PC_IDX, 10), _BV(5) }, - { CM_CODE(PC_IDX, 11), _BV(6) }, - - // J7 - { CM_CODE(PC_IDX, 12), _BV(1) }, - { CM_CODE(PC_IDX, 13), _BV(2) }, - { CM_CODE(PC_IDX, 14), _BV(3) }, - - // J8 - { CM_CODE(PD_IDX, 15), _BV(6) }, - { CM_CODE(PD_IDX, 16), _BV(7) }, - { CM_CODE(PC_IDX, 17), _BV(0) }, - - // J9 - { CM_CODE(PD_IDX, 18), _BV(3) }, - { CM_CODE(PD_IDX, 19), _BV(4) }, - { CM_CODE(PD_IDX, 20), _BV(5) }, - - // J10 - { CM_CODE(PB_IDX, 21), _BV(6) }, - { CM_CODE(PB_IDX, 22), _BV(7) }, - { CM_CODE(PD_IDX, 23), _BV(2) }, - - // J11 - { CM_CODE(PB_IDX, 24), _BV(3) }, - { CM_CODE(PB_IDX, 25), _BV(4) }, - { CM_CODE(PB_IDX, 26), _BV(5) }, - - // J12 - { CM_CODE(PB_IDX, 27), _BV(0) }, - { CM_CODE(PB_IDX, 28), _BV(1) }, - { CM_CODE(PB_IDX, 29), _BV(2) } - - }; - - -// --- -// Setup values that will be stored to eeprom. -// - -typedef struct { - uint16_t max_pwm; - uint8_t common_pwm; - channel_map_t channel_map[NCHANNELS]; - } setup_t; - -setup_t setup NOMEMINIT; - -#define EE_VALID_MARK 0xA5 -static uint8_t ee_valid EEMEM; // If eeprom content is valid this byte is EE_VALID_MARK -static setup_t ee_setup EEMEM; - - -// Status LED related -#define STATUS_LED_PORT PORTE -#define STATUS_LED_BIT 1 - -// Common PWM channel related -#define MAX_COMMON_PWM 255 -#define DEF_COMMON_PWM 255 // Default common pwm value - -#define COMMON_PWM_PORT PORTE -#define COMMON_PWM_BIT 2 - - -// Input pin for enable/disable of bootloader -#define BL_SENSE_PIN PINE -#define BL_SENSE_BIT 0 - - -// --- -// Definition of port direction and initial values. -// -#define PA_DDR 0xFF -#define PA_INIT 0x00 - -#define PB_DDR 0xFF -#define PB_INIT 0x00 - -#define PC_DDR 0xFF -#define PC_INIT 0x00 - -#define PD_DDR (_BV(1) | _BV(2) | _BV(3) | _BV(4) | _BV(5) | _BV(6) | _BV(7)) -#define PD_INIT _BV(1) - -#define PE_DDR (_BV(STATUS_LED_BIT) | _BV(COMMON_PWM_BIT)) -#define PE_INIT _BV(BL_SENSE_BIT) - - -// --- -// Catchup all unused interrupts and wait until watchdog resets device. -// This ISR is only for unexpected interrupts. -// -ISR(BADISR_vect) -{ - for (;;); -} - - -// --- -// ISR for PWM generation. -// -ISR(TIMER3_COMPA_vect) -{ - pwm_step_t *p = actual_pwm_step; - - // Optimized OCR3A = p->timer_val - OCR3AH = ((uint8_t *)&(p->timer_val))[1]; - OCR3AL = ((uint8_t *)&(p->timer_val))[0]; - - PORTA = p->port_val[PA_IDX]; - PORTB = p->port_val[PB_IDX]; - PORTC = p->port_val[PC_IDX]; - PORTD = p->port_val[PD_IDX]; - - // Optimized actual_pwm_step = p->next_step - ((uint8_t *)&(actual_pwm_step))[0] = ((uint8_t *)&(p->next_step))[0]; - ((uint8_t *)&(actual_pwm_step))[1] = ((uint8_t *)&(p->next_step))[1]; -} - - -// --- -// ISR for receiving data. -// -ISR(USART0_RXC_vect) -{ - clear_bit(UCSR0B, RXCIE0); - sei(); - - do - { - uint8_t i = rxwpos; - uint8_t p = i + 1; - CHECK_RXBUF_END(p); - - if (bit_is_set(UCSR0A, FE0)) - set_bit(rx_err_status, COMM_ERR_FRAME); - else if (bit_is_set(UCSR0A, DOR0)) - set_bit(rx_err_status, COMM_ERR_OVERRUN); - else if (p == rxrpos) - set_bit(rx_err_status, COMM_ERR_OVERFLOW); - else - { - if (bit_is_set(UCSR0B, RXB80)) - rxspos = i; // save start of request message - rxwpos = p; // set data valid - } - rxbuf[i] = UDR0; // read data - } - while (bit_is_set(UCSR0A, RXC0)); - - cli(); - set_bit(UCSR0B, RXCIE0); -} - - -// --- -// Processing while waiting for a event. -// -static void background_processing(void) -{ - wdt_reset(); - - // count system clock - if (bit_is_set(TIFR, TOV0)) - { - ++sys_clock; - TIFR = _BV(TOV0); - } -} - - -// --- -// Put data into transmit buffer. -// -static void send_reply_data(uint8_t c) -{ - // Wait until transmit buffer free - while (bit_is_clear(UCSR0A, UDRE0)) - background_processing(); - - UDR0 = c; -} - - -// --- -// Send reply start. -// -static void send_reply_start(uint8_t len) -{ - // Wait until transmit buffer free - while (bit_is_clear(UCSR0A, UDRE0)) - background_processing(); - - uint8_t id = actual_req.request_type & PWMRQ_ID_MASK; - if (len) - id |= PWMRP_HAS_PAYLOAD; - - set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply - UDR0 = id; // Send reply id - clear_bit(UCSR0B, TXB80); - - if (len) - send_reply_data(len); // Send reply length - - last_keep_alive = sys_clock; -} - - -// --- -// Send keep alive reply. -// -static void send_keep_alive_reply(void) -{ - background_processing(); - if ((sys_clock - last_keep_alive) > MIN_KEEP_ALIVE_PAUSE) - { - // Wait until transmit buffer free - while (bit_is_clear(UCSR0A, UDRE0)) - background_processing(); - - set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply - UDR0 = PWMRP_KEEP_ALIVE; // Send keep alive ID - clear_bit(UCSR0B, TXB80); - - last_keep_alive = sys_clock; - } -} - - -// --- -// Set on time 'v' for port bits 'pb' of port 'pi' in shadow pwm page. -// -static void set_channel(uint8_t pi, uint8_t pb, uint16_t v) -{ - pwm_step_t *p = shadow_pwm_page; - pwm_step_t *l, *n; - - while (p->timer_val && v >= p->timer_val) - { - p->port_val[pi] |= pb; - if (p->timer_val == v) - return; - l = p; - p = l->next_step; - } - - if (p->timer_val) - { - n = p; - do - { - l = n; - n = l->next_step; - } - while (n->timer_val); - - l->next_step = n->next_step; - n[0] = p[0]; - p->next_step = n; - } - else - { - p->port_val[PA_IDX] = PA_INIT; - p->port_val[PB_IDX] = PB_INIT; - p->port_val[PC_IDX] = PC_INIT; - p->port_val[PD_IDX] = PD_INIT; - } - p->timer_val = v; - p->port_val[pi] |= pb; -} - - -// --- -// Init shadow pwm page. -// -static uint8_t init_pwm_page(uint8_t do_init) -{ - pwm_step_t *p = shadow_pwm_page; - pwm_step_t *e = p + PWM_STEP_PAGE_SIZE; - - // Check if shadow page is deactivated - cli(); - pwm_step_t *a = actual_pwm_step; - sei(); - if (a >= p && a < e) - return(0); // Shadow page is still active - - if (do_init) - { - while (p < e) - { - p->timer_val = 0; - a = p + 1; - p->next_step = a; - p = a; - } - } - - return(1); -} - - -// --- -// Finalize shadow pwm page and activate it. -// -static void activate_pwm_page(void) -{ - pwm_step_t *p = shadow_pwm_page; - pwm_step_t *l; - uint16_t t = 0; - - // Calculate time steps - while (p->timer_val) - { - uint16_t ts = p->timer_val - t; - t = p->timer_val; - p->timer_val = ts * PWM_PRESCALE; - l = p; - p = l->next_step; - } - - // Add pause entry to reach a full cycle - t = setup.max_pwm - t; - if (t) - { - p->port_val[PA_IDX] = PA_INIT; - p->port_val[PB_IDX] = PB_INIT; - p->port_val[PC_IDX] = PC_INIT; - p->port_val[PD_IDX] = PD_INIT; - p->timer_val = t * PWM_PRESCALE; - l = p; - } - - // Make list cyclic - p = shadow_pwm_page; - l->next_step = p; - - // Install Link to shadow page in active page - p = active_pwm_page; - active_pwm_page = l; - l = shadow_pwm_page; - cli(); - p->next_step = l; - sei(); - - // Swap shadow page - if (l == pwm_step_page1) - p = pwm_step_page2; - else - p = pwm_step_page1; - shadow_pwm_page = p; - - update_pwm_page = 0; -} - - -// --- -// Calculate pwm page. -// -static void calc_pwm_page(void) -{ - uint8_t c; - - c = NCHANNELS; - while (c--) - { - uint8_t port_bits = setup.channel_map[c].port_bits; - if (port_bits) - { - uint8_t code = setup.channel_map[c].code; - uint16_t v = bright_vals[CM_CHANNEL(code)]; - if (v) - { - if (v > setup.max_pwm) - v = setup.max_pwm; - set_channel(CM_PORT(code), port_bits, v); - } - } - } -} - - -// --- -// Initialize pwm step table and start pwm timer. -// -static void init_pwm_step_tab(void) -{ - // Set up pwm step table - shadow_pwm_page = pwm_step_page1; - active_pwm_page = pwm_step_page2; - actual_pwm_step = pwm_step_page2; - init_pwm_page(1); - calc_pwm_page(); - activate_pwm_page(); - actual_pwm_step = active_pwm_page->next_step; - - TCNT3 = 0; // Reset timer counter - OCR3A = PWM_PRESCALE; // Initial startup step - TCCR3B = _BV(CS32) | _BV(CS31) | _BV(WGM32); // Start timer, Prescaler 16, CTC mode -} - - -// --- -// Set default setup values. -// -static void init_setup_values(void) -{ - setup.max_pwm = DEF_MAX_PWM; - setup.common_pwm = DEF_COMMON_PWM; - - memcpy_P(&setup.channel_map, &default_channel_map, sizeof(setup.channel_map)); -} - - -// --- -// Read setup values from eeprom. -// -static void read_setup_values(void) -{ - if (eeprom_read_byte(&ee_valid) == EE_VALID_MARK) - eeprom_read_block(&setup, &ee_setup, sizeof(setup)); - else - init_setup_values(); -} - - -// --- -// Store actual setup values into eeprom. -// -static void store_setup_values(void) -{ - uint8_t i = sizeof(setup); - uint8_t *src = (uint8_t *) (&setup); - uint8_t *dst = (uint8_t *) (&ee_setup); - while (i--) - { - if (eeprom_read_byte(dst) != *src) - { - eeprom_write_byte(dst, *src); - while (!eeprom_is_ready()) - send_keep_alive_reply(); - } - ++src; - ++dst; - } - if (eeprom_read_byte(&ee_valid) != EE_VALID_MARK) - { - eeprom_write_byte(&ee_valid, EE_VALID_MARK); - while (!eeprom_is_ready()) - send_keep_alive_reply(); - } -} - - -// --- -// Set common pwm value. -// -static void set_common_pwm(void) -{ - uint8_t v = setup.common_pwm; - - if (v == 0 || v == 255) - { - if (v) - set_bit(COMMON_PWM_PORT, COMMON_PWM_BIT); - else - clear_bit(COMMON_PWM_PORT, COMMON_PWM_BIT); - clear_bit(TCCR1A, COM1B1); // Normal port output - } - else - { - OCR1B = v; - clear_bit(COMMON_PWM_PORT, COMMON_PWM_BIT); - set_bit(TCCR1A, COM1B1); // pwm port output - } -} - - -// --- -// Send reply packet from ram memory. -// -static void send_reply_mem(uint8_t *data, uint16_t len) -{ - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - uint16_t p = r->index.word << 1; - uint16_t n = r->length.word; - if (p >= len) - n = 0; - if (n && (p + n) > len) - n = len - p; - if (n > MAX_REPLY_PAYLOAD_SIZE) - n = 0; // Send nothing! - - send_reply_start(n); - - data += p; - while (n) - { - send_reply_data(*data++); - --n; - } -} - - -// --- -// Process set brightness value. -// -static void req_set_brightness(void) -{ - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - uint8_t p = payload_pos; - uint16_t c = r->index.word; - uint16_t len = r->length.word >> 1; - while (len && c < NCHANNELS) - { - bytes_word_t v; - v.bytes[0] = rxbuf[p++]; - CHECK_RXBUF_END(p); - v.bytes[1] = rxbuf[p++]; - CHECK_RXBUF_END(p); - - if (bright_vals[c] != v.word) - { - bright_vals[c] = v.word; - update_pwm_page = 1; - } - - ++c; - --len; - } -} - - -// --- -// Process set channel map request. -// -static void req_set_channel_map(void) -{ - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - uint8_t p = payload_pos; - uint16_t c = r->index.word; - uint16_t len = r->length.word >> 1; - while (len && c < NCHANNELS) - { - uint8_t v = rxbuf[p++]; - CHECK_RXBUF_END(p); - - if (CM_CHANNEL(v) >= NCHANNELS) - v = NCHANNELS - 1; - - if (setup.channel_map[c].code != v) - { - setup.channel_map[c].code = v; - update_pwm_page = 1; - } - - v = rxbuf[p++]; - CHECK_RXBUF_END(p); - - if (setup.channel_map[c].port_bits != v) - { - setup.channel_map[c].port_bits = v; - update_pwm_page = 1; - } - - ++c; - --len; - } -} - - -// --- -// Process received request. -// -static void process_request(void) -{ - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - uint8_t req = r->request; - - if (req == PWM_REQ_SET_BRIGHTNESS) - req_set_brightness(); - else if (req == PWM_REQ_SET_BRIGHTNESS_SYNCED) - { - req_set_brightness(); - if (update_pwm_page) - { - while (!init_pwm_page(0)) - background_processing(); - } - } - else if (req == PWM_REQ_GET_BRIGHTNESS) - { - send_reply_mem((uint8_t *)bright_vals, sizeof(bright_vals)); - return; - } - else if (req == PWM_REQ_SET_CHANNEL_MAP) - req_set_channel_map(); - else if (req == PWM_REQ_GET_CHANNEL_MAP) - { - send_reply_mem((uint8_t *)&setup.channel_map, sizeof(setup.channel_map)); - return; - } - else if (req == PWM_REQ_STORE_SETUP) - store_setup_values(); - else if (req == PWM_REQ_RESET_SETUP) - { - init_setup_values(); - update_pwm_page = 1; - if (eeprom_read_byte(&ee_valid) == EE_VALID_MARK) - eeprom_write_byte(&ee_valid, (uint8_t)(~EE_VALID_MARK)); // Invalidate eeprom values - } - else if (req == PWM_REQ_GET_REQUEST_ERR_STATUS) - { - send_reply_start(1); - send_reply_data(rx_err_status); - rx_err_status = 0; - return; - } - else if (req == PWM_REQ_SET_COMMON_PWM) - { - setup.common_pwm = (r->value.word <= MAX_COMMON_PWM) ? r->value.bytes[0]: MAX_COMMON_PWM; - set_common_pwm(); - } - else if (req == PWM_REQ_GET_COMMON_PWM) - { - send_reply_start(2); - send_reply_data(setup.common_pwm); - send_reply_data(0); - return; - } - else if (req == PWM_REQ_GET_MAX_PWM) - { - send_reply_start(4); - send_reply_data((uint8_t)(setup.max_pwm & 0x00FF)); - send_reply_data((uint8_t)(setup.max_pwm >> 8)); - send_reply_data(MAX_COMMON_PWM); - send_reply_data(0); - return; - } - else if (req == PWM_REQ_SET_PWM_FREQ) - { - if (r->value.word >= MIN_PWM_FREQ && r->value.word <= MAX_PWM_FREQ) - { - setup.max_pwm = F_CPU / (PWM_HWPRESCALE * PWM_PRESCALE * (uint32_t)r->value.word) - 1; - update_pwm_page = 1; - } - } - else if (req == PWM_REQ_GET_PWM_FREQ) - { - uint16_t f = F_CPU / (((uint32_t)setup.max_pwm + 1) * PWM_HWPRESCALE * PWM_PRESCALE); - send_reply_start(2); - send_reply_data((uint8_t)(f & 0x00FF)); - send_reply_data((uint8_t)(f >> 8)); - return; - } - else if (req == PWM_REQ_GET_VERSION) - { - send_reply_start(2); - send_reply_data(PWM_VERS_APPL); - send_reply_data(FIRMWARE_VERSION); - return; - } - else if (req == PWM_REQ_ECHO_TEST) - { - send_reply_start(8); - send_reply_data(r->bytes[0]); - send_reply_data(r->bytes[1]); - send_reply_data(r->bytes[2]); - send_reply_data(r->bytes[3]); - send_reply_data(r->bytes[4]); - send_reply_data(r->bytes[5]); - send_reply_data(r->bytes[6]); - send_reply_data(r->bytes[7]); - return; - } - - send_reply_start(0); -} - - -// --- -// Decode data byte of received data. -// -static void read_data(void) -{ - uint8_t p, c, is_req_start; - - - // Read data from RX buffer - p = rxrpos; - is_req_start = (p == rxspos); - c = rxbuf[p++]; - CHECK_RXBUF_END(p); - rxrpos = p; - - p = header_pos; - if (is_req_start) - { - if (p) - set_bit(rx_err_status, COMM_ERR_TIMEOUT); - - p = 0; - } - else if (!p) - return; // Discard garbage - - if (p < sizeof(pwm_request_t)) - { - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - r->bytes[p++] = c; - header_pos = p; - - if (p < sizeof(pwm_request_t)) - return; - - // Header complete - if (!(r->request_type & PWMRQ_DEVICE_TO_HOST) && r->length.word) - { - payload_pos = rxrpos; - payload_count = r->length.word; - return; - } - } - else if (--payload_count) - return; // Payload not complete - - last_keep_alive = sys_clock; - process_request(); - header_pos = 0; -} - - -// --- -// Device initialization and main program loop. -// -void main(void) NORETURN; -void main(void) -{ - wdt_enable(WDTO_30MS); // Set watchdog timeout - - // Port init, enable pull-up resistors for unused ports - PORTA = PA_INIT; - PORTB = PB_INIT; - PORTC = PC_INIT; - PORTD = PD_INIT; - PORTE = PE_INIT; - DDRA = PA_DDR; - DDRB = PB_DDR; - DDRC = PC_DDR; - DDRD = PD_DDR; - DDRE = PE_DDR; - - // USART init - // 9 data bits, 1 stop bit, no parity, asynchron mode - // Enable TX, RX and RX Interrupts -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A = _BV(U2X); -#endif - UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00); - UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UCSZ02); - - read_setup_values(); - - // Timer 0 is used for system clock - // Normal mode, Prescaler 64 - TCCR0 = _BV(CS01) | _BV(CS00); - - // Timer 1 is used for common PWM generation - // Fast 8-Bit PWM mode, Prescaler 1, PWM output at OC1B Pin - TCCR1A = _BV(WGM10); - TCCR1B = _BV(WGM12) | _BV(CS10); - set_common_pwm(); - - // Timer 3 is used for PWM generation - ETIMSK = _BV(OCIE3A); // Enable timer 3 compare a interrupt - init_pwm_step_tab(); - - // Main loop - for (;;) - { - background_processing(); - - if (rxrpos != rxwpos) - read_data(); - - if (update_pwm_page && init_pwm_page(1)) - { - calc_pwm_page(); - activate_pwm_page(); - } - - if (update_pwm_page || header_pos) - clear_bit(STATUS_LED_PORT, STATUS_LED_BIT); // We are processing a request - else - set_bit(STATUS_LED_PORT, STATUS_LED_BIT); // No request - } -} diff --git a/pwm_appl/Makefile b/pwm_appl/Makefile index d9faba8..4824c29 100644 --- a/pwm_appl/Makefile +++ b/pwm_appl/Makefile @@ -1,106 +1,106 @@ -# -# Copyright (C) 2010 Andreas Auras -# -# This file is part of the DF10CH Atmolight controller project. -# -# DF10CH Atmolight controller 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. -# -# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -# -# -############################################################################### -# Makefile for the application firmware of PWM processor -############################################################################### - -## General Flags -PROJECT = 10ch_pwm_appl -MCU = atmega162 -TARGET = 10ch_pwm_appl.elf -CC = avr-gcc -AVRDUDE ?= avrdude -c stk500v2 -P avrdoper -F_CPU ?= 16000000UL -FIRMWARE_VERSION ?= 1 - -## Options common to compile, link and assembly rules -COMMON = -mmcu=$(MCU) - -## Compile options common for all C compilation units. -CFLAGS = $(COMMON) -CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) - -## Assembly specific flags -ASMFLAGS = $(COMMON) -ASMFLAGS += $(CFLAGS) -ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 - -## Linker flags -LDFLAGS = $(COMMON) -LDFLAGS += -Wl,-Map=10ch_pwm_appl.map -LDFLAGS += -Wl,-section-start=.eeprom=0x810001 - - -## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature - -HEX_EEPROM_FLAGS = -j .eeprom -HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" -HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0x01 --no-change-warnings - -## Include Directories -INCLUDES = -I. -I.. - -## Objects that must be built in order to link -OBJECTS = 10ch_pwm_appl.o - -## Objects explicitly added by the user -LINKONLYOBJECTS = - -## Build -all: $(TARGET) 10ch_pwm_appl.dff 10ch_pwm_appl.lss size - -10ch_pwm_appl.dff: 10ch_pwm_appl.hex - echo "@DF10CH-PWM" $(FIRMWARE_VERSION) > $@ - cat 10ch_pwm_appl.hex >> $@ - -prog: flash - $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0xc0:m -Uhfuse:w:0xc9:m -Uefuse:w:0xf9:m -Ulock:w:0xef:m - -flash: 10ch_pwm_appl.hex - $(AVRDUDE) -p $(MCU) -U flash:w:10ch_pwm_appl.hex:i - -## Compile -10ch_pwm_appl.o: 10ch_pwm_appl.c ../df10ch_usb_proto.h ../df10ch_common.h - $(CC) $(INCLUDES) $(CFLAGS) -c $< - -##Link -$(TARGET): $(OBJECTS) - $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) - -%.hex: $(TARGET) - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -%.eep: $(TARGET) - -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 - -%.lss: $(TARGET) - avr-objdump -h -S $< > $@ - -size: ${TARGET} - @echo - @avr-size -C --mcu=${MCU} ${TARGET} - -## Clean target -.PHONY: clean -clean: - -rm -rf $(OBJECTS) 10ch_pwm_appl.elf 10ch_pwm_appl.dff 10ch_pwm_appl.hex 10ch_pwm_appl.eep 10ch_pwm_appl.lss 10ch_pwm_appl.map +# +# Copyright (C) 2010 Andreas Auras +# +# This file is part of the DF10CH Atmolight controller project. +# +# DF10CH Atmolight controller 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. +# +# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +# +# +############################################################################### +# Makefile for the application firmware of PWM processor +############################################################################### + +## General Flags +PROJECT = df10ch_pwm_appl +MCU = atmega162 +TARGET = df10ch_pwm_appl.elf +CC = avr-gcc +AVRDUDE ?= avrdude -c stk500v2 -P avrdoper +F_CPU ?= 16000000UL +FIRMWARE_VERSION ?= 1 + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-Map=df10ch_pwm_appl.map +LDFLAGS += -Wl,-section-start=.eeprom=0x810001 + + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0x01 --no-change-warnings + +## Include Directories +INCLUDES = -I. -I.. + +## Objects that must be built in order to link +OBJECTS = df10ch_pwm_appl.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET) df10ch_pwm_appl.dff df10ch_pwm_appl.lss size + +df10ch_pwm_appl.dff: df10ch_pwm_appl.hex + echo "@DF10CH-PWM" $(FIRMWARE_VERSION) > $@ + cat df10ch_pwm_appl.hex >> $@ + +prog: flash + $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0xc0:m -Uhfuse:w:0xc9:m -Uefuse:w:0xf9:m -Ulock:w:0xef:m + +flash: df10ch_pwm_appl.hex + $(AVRDUDE) -p $(MCU) -U flash:w:df10ch_pwm_appl.hex:i + +## Compile +df10ch_pwm_appl.o: df10ch_pwm_appl.c ../df10ch_usb_proto.h ../df10ch_common.h + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) + +%.hex: $(TARGET) + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET) + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET) + avr-objdump -h -S $< > $@ + +size: ${TARGET} + @echo + @avr-size -C --mcu=${MCU} ${TARGET} + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) df10ch_pwm_appl.elf df10ch_pwm_appl.dff df10ch_pwm_appl.hex df10ch_pwm_appl.eep df10ch_pwm_appl.lss df10ch_pwm_appl.map diff --git a/pwm_appl/df10ch_pwm_appl.c b/pwm_appl/df10ch_pwm_appl.c new file mode 100644 index 0000000..f31240a --- /dev/null +++ b/pwm_appl/df10ch_pwm_appl.c @@ -0,0 +1,1000 @@ +/* + * Copyright (C) 2010 Andreas Auras + * + * This file is part of the DF10CH Atmolight controller project. + * + * DF10CH Atmolight controller 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. + * + * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +// ====================================================================== +// Application firmware for PWM processor. +// + +#include +#include +#include +#include +#include +#include +#include + +#include "../df10ch_common.h" +#include "../df10ch_usb_proto.h" + + +// --- +// Fuse-Bit settings for the flash programmer (ATmega 162): +// +// M161C=1 +// BODLEVEL2=1 +// BODLEVEL1=0 +// BODLEVEL0=0 +// +// OCDEN=1 +// JTAGEN=1 +// SPIEN=0 +// WDTON=0 +// EESAVE=1 +// BOOTSZ1=0 +// BOOTSZ0=0 +// BOOTRST=1 +// +// CKDIV8=1 +// CKOUT=1 +// SUT1=0 +// SUT0=1 +// CKSEL3=1 +// CKSEL2=1 +// CKSEL1=1 +// CKSEL0=1 +// +// Memory-Lock Bits: +// BLB12=1, BLB11=0, BLB02=1, BLB01=1, LB2=1, LB1=1 +// +FUSES = +{ + .low = (FUSE_SUT1), + .high = (FUSE_SPIEN & FUSE_WDTON & FUSE_BOOTSZ1 & FUSE_BOOTSZ0), + .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0), +}; +LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); +//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; + + +// --- +// System clock related. +// System clock is implemented with hardware timer 0 +// +#define SYS_HWPRESCALE 64 // Hardware Prescaler +#define SYS_PRESCALER 256 // Timer Prescaler + + // useconds <-> timer ticks conversation +#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE * (double)SYS_PRESCALER) + 0.5)) +#define TICKS2US(t) (((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE * SYS_PRESCALER)))) + +static uint16_t sys_clock; + + +// --- +// Keep alive reply related +// +#define MIN_KEEP_ALIVE_PAUSE US2TICKS(15000) + +static uint16_t last_keep_alive; + + +// --- +// Request parser related variables +// +typedef union +{ + uint8_t bytes[REQ_HEADER_SIZE]; + struct + { + uint8_t request_type; + uint8_t request; + bytes_word_t value; + bytes_word_t index; + bytes_word_t length; + }; +} pwm_request_t; + +static pwm_request_t actual_req; +static uint8_t header_pos; +static uint8_t payload_pos; +static uint8_t payload_count; + + +// --- +// PWM generation related +// +#define DEF_F_PWM 100UL // Default PWM cycle frequency in Hz +#define PWM_HWPRESCALE 16 // Hardware timer prescale +#define PWM_PRESCALE 9 // require: (PWM_PRESCALE * PWM_HWPRESCALE) > (size of ISR for timer ) + +#define DEF_MAX_PWM (F_CPU / (PWM_HWPRESCALE * PWM_PRESCALE * DEF_F_PWM) - 1) // Maximum internal resolution for pwm + +#define PWM_STEP_PAGE_SIZE (NCHANNELS + 2) // possible maximum steps: NCHANNELS + Pause + End of Table + +typedef struct pwm_step_s { + uint8_t port_val[NPORTS]; // Values for Port A,B,C,D + uint16_t timer_val; // Timer compare value + struct pwm_step_s *next_step; // Pointer to next list entry + } pwm_step_t; + + // One actual and one shadow page +static pwm_step_t pwm_step_page1[PWM_STEP_PAGE_SIZE] NOMEMINIT; +static pwm_step_t pwm_step_page2[PWM_STEP_PAGE_SIZE] NOMEMINIT; +static pwm_step_t *shadow_pwm_page NOMEMINIT; +static pwm_step_t *active_pwm_page NOMEMINIT; +static pwm_step_t * volatile actual_pwm_step NOMEMINIT; +static uint8_t update_pwm_page NOMEMINIT; + + +// --- +// RX buffer related variables +// +#define RXBUF_SIZE (REQ_HEADER_SIZE + MAX_REQ_PAYLOAD_SIZE + 1) +#if RXBUF_SIZE == 256 +#define CHECK_RXBUF_END(pos) +#else +#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0 +#endif + +static uint8_t volatile rxrpos, rxwpos, rxspos, rx_err_status; +static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT; + + +// --- +// Actual brightness values for each channel +// +static uint16_t bright_vals[NCHANNELS]; + + +// --- +// Port channel mapping related variables +// +typedef struct { uint8_t code, port_bits; } channel_map_t; + +static channel_map_t default_channel_map[NCHANNELS] PROGMEM = { + // J3 + { CM_CODE(PA_IDX, 0), _BV(2) }, + { CM_CODE(PA_IDX, 1), _BV(1) }, + { CM_CODE(PA_IDX, 2), _BV(0) }, + + // J4 + { CM_CODE(PA_IDX, 3), _BV(5) }, + { CM_CODE(PA_IDX, 4), _BV(4) }, + { CM_CODE(PA_IDX, 5), _BV(3) }, + + // J5 + { CM_CODE(PC_IDX, 6), _BV(7) }, + { CM_CODE(PA_IDX, 7), _BV(7) }, + { CM_CODE(PA_IDX, 8), _BV(6) }, + + // J6 + { CM_CODE(PC_IDX, 9), _BV(4) }, + { CM_CODE(PC_IDX, 10), _BV(5) }, + { CM_CODE(PC_IDX, 11), _BV(6) }, + + // J7 + { CM_CODE(PC_IDX, 12), _BV(1) }, + { CM_CODE(PC_IDX, 13), _BV(2) }, + { CM_CODE(PC_IDX, 14), _BV(3) }, + + // J8 + { CM_CODE(PD_IDX, 15), _BV(6) }, + { CM_CODE(PD_IDX, 16), _BV(7) }, + { CM_CODE(PC_IDX, 17), _BV(0) }, + + // J9 + { CM_CODE(PD_IDX, 18), _BV(3) }, + { CM_CODE(PD_IDX, 19), _BV(4) }, + { CM_CODE(PD_IDX, 20), _BV(5) }, + + // J10 + { CM_CODE(PB_IDX, 21), _BV(6) }, + { CM_CODE(PB_IDX, 22), _BV(7) }, + { CM_CODE(PD_IDX, 23), _BV(2) }, + + // J11 + { CM_CODE(PB_IDX, 24), _BV(3) }, + { CM_CODE(PB_IDX, 25), _BV(4) }, + { CM_CODE(PB_IDX, 26), _BV(5) }, + + // J12 + { CM_CODE(PB_IDX, 27), _BV(0) }, + { CM_CODE(PB_IDX, 28), _BV(1) }, + { CM_CODE(PB_IDX, 29), _BV(2) } + + }; + + +// --- +// Setup values that will be stored to eeprom. +// + +typedef struct { + uint16_t max_pwm; + uint8_t common_pwm; + channel_map_t channel_map[NCHANNELS]; + } setup_t; + +setup_t setup NOMEMINIT; + +#define EE_VALID_MARK 0xA5 +static uint8_t ee_valid EEMEM; // If eeprom content is valid this byte is EE_VALID_MARK +static setup_t ee_setup EEMEM; + + +// Status LED related +#define STATUS_LED_PORT PORTE +#define STATUS_LED_BIT 1 + +// Common PWM channel related +#define MAX_COMMON_PWM 255 +#define DEF_COMMON_PWM 255 // Default common pwm value + +#define COMMON_PWM_PORT PORTE +#define COMMON_PWM_BIT 2 + + +// Input pin for enable/disable of bootloader +#define BL_SENSE_PIN PINE +#define BL_SENSE_BIT 0 + + +// --- +// Definition of port direction and initial values. +// +#define PA_DDR 0xFF +#define PA_INIT 0x00 + +#define PB_DDR 0xFF +#define PB_INIT 0x00 + +#define PC_DDR 0xFF +#define PC_INIT 0x00 + +#define PD_DDR (_BV(1) | _BV(2) | _BV(3) | _BV(4) | _BV(5) | _BV(6) | _BV(7)) +#define PD_INIT _BV(1) + +#define PE_DDR (_BV(STATUS_LED_BIT) | _BV(COMMON_PWM_BIT)) +#define PE_INIT _BV(BL_SENSE_BIT) + + +// --- +// Catchup all unused interrupts and wait until watchdog resets device. +// This ISR is only for unexpected interrupts. +// +ISR(BADISR_vect) +{ + for (;;); +} + + +// --- +// ISR for PWM generation. +// +ISR(TIMER3_COMPA_vect) +{ + pwm_step_t *p = actual_pwm_step; + + // Optimized OCR3A = p->timer_val + OCR3AH = ((uint8_t *)&(p->timer_val))[1]; + OCR3AL = ((uint8_t *)&(p->timer_val))[0]; + + PORTA = p->port_val[PA_IDX]; + PORTB = p->port_val[PB_IDX]; + PORTC = p->port_val[PC_IDX]; + PORTD = p->port_val[PD_IDX]; + + // Optimized actual_pwm_step = p->next_step + ((uint8_t *)&(actual_pwm_step))[0] = ((uint8_t *)&(p->next_step))[0]; + ((uint8_t *)&(actual_pwm_step))[1] = ((uint8_t *)&(p->next_step))[1]; +} + + +// --- +// ISR for receiving data. +// +ISR(USART0_RXC_vect) +{ + clear_bit(UCSR0B, RXCIE0); + sei(); + + do + { + uint8_t i = rxwpos; + uint8_t p = i + 1; + CHECK_RXBUF_END(p); + + if (bit_is_set(UCSR0A, FE0)) + set_bit(rx_err_status, COMM_ERR_FRAME); + else if (bit_is_set(UCSR0A, DOR0)) + set_bit(rx_err_status, COMM_ERR_OVERRUN); + else if (p == rxrpos) + set_bit(rx_err_status, COMM_ERR_OVERFLOW); + else + { + if (bit_is_set(UCSR0B, RXB80)) + rxspos = i; // save start of request message + rxwpos = p; // set data valid + } + rxbuf[i] = UDR0; // read data + } + while (bit_is_set(UCSR0A, RXC0)); + + cli(); + set_bit(UCSR0B, RXCIE0); +} + + +// --- +// Processing while waiting for a event. +// +static void background_processing(void) +{ + wdt_reset(); + + // count system clock + if (bit_is_set(TIFR, TOV0)) + { + ++sys_clock; + TIFR = _BV(TOV0); + } +} + + +// --- +// Put data into transmit buffer. +// +static void send_reply_data(uint8_t c) +{ + // Wait until transmit buffer free + while (bit_is_clear(UCSR0A, UDRE0)) + background_processing(); + + UDR0 = c; +} + + +// --- +// Send reply start. +// +static void send_reply_start(uint8_t len) +{ + // Wait until transmit buffer free + while (bit_is_clear(UCSR0A, UDRE0)) + background_processing(); + + uint8_t id = actual_req.request_type & PWMRQ_ID_MASK; + if (len) + id |= PWMRP_HAS_PAYLOAD; + + set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply + UDR0 = id; // Send reply id + clear_bit(UCSR0B, TXB80); + + if (len) + send_reply_data(len); // Send reply length + + last_keep_alive = sys_clock; +} + + +// --- +// Send keep alive reply. +// +static void send_keep_alive_reply(void) +{ + background_processing(); + if ((sys_clock - last_keep_alive) > MIN_KEEP_ALIVE_PAUSE) + { + // Wait until transmit buffer free + while (bit_is_clear(UCSR0A, UDRE0)) + background_processing(); + + set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply + UDR0 = PWMRP_KEEP_ALIVE; // Send keep alive ID + clear_bit(UCSR0B, TXB80); + + last_keep_alive = sys_clock; + } +} + + +// --- +// Set on time 'v' for port bits 'pb' of port 'pi' in shadow pwm page. +// +static void set_channel(uint8_t pi, uint8_t pb, uint16_t v) +{ + pwm_step_t *p = shadow_pwm_page; + pwm_step_t *l, *n; + + while (p->timer_val && v >= p->timer_val) + { + p->port_val[pi] |= pb; + if (p->timer_val == v) + return; + l = p; + p = l->next_step; + } + + if (p->timer_val) + { + n = p; + do + { + l = n; + n = l->next_step; + } + while (n->timer_val); + + l->next_step = n->next_step; + n[0] = p[0]; + p->next_step = n; + } + else + { + p->port_val[PA_IDX] = PA_INIT; + p->port_val[PB_IDX] = PB_INIT; + p->port_val[PC_IDX] = PC_INIT; + p->port_val[PD_IDX] = PD_INIT; + } + p->timer_val = v; + p->port_val[pi] |= pb; +} + + +// --- +// Init shadow pwm page. +// +static uint8_t init_pwm_page(uint8_t do_init) +{ + pwm_step_t *p = shadow_pwm_page; + pwm_step_t *e = p + PWM_STEP_PAGE_SIZE; + + // Check if shadow page is deactivated + cli(); + pwm_step_t *a = actual_pwm_step; + sei(); + if (a >= p && a < e) + return(0); // Shadow page is still active + + if (do_init) + { + while (p < e) + { + p->timer_val = 0; + a = p + 1; + p->next_step = a; + p = a; + } + } + + return(1); +} + + +// --- +// Finalize shadow pwm page and activate it. +// +static void activate_pwm_page(void) +{ + pwm_step_t *p = shadow_pwm_page; + pwm_step_t *l; + uint16_t t = 0; + + // Calculate time steps + while (p->timer_val) + { + uint16_t ts = p->timer_val - t; + t = p->timer_val; + p->timer_val = ts * PWM_PRESCALE; + l = p; + p = l->next_step; + } + + // Add pause entry to reach a full cycle + t = setup.max_pwm - t; + if (t) + { + p->port_val[PA_IDX] = PA_INIT; + p->port_val[PB_IDX] = PB_INIT; + p->port_val[PC_IDX] = PC_INIT; + p->port_val[PD_IDX] = PD_INIT; + p->timer_val = t * PWM_PRESCALE; + l = p; + } + + // Make list cyclic + p = shadow_pwm_page; + l->next_step = p; + + // Install Link to shadow page in active page + p = active_pwm_page; + active_pwm_page = l; + l = shadow_pwm_page; + cli(); + p->next_step = l; + sei(); + + // Swap shadow page + if (l == pwm_step_page1) + p = pwm_step_page2; + else + p = pwm_step_page1; + shadow_pwm_page = p; + + update_pwm_page = 0; +} + + +// --- +// Calculate pwm page. +// +static void calc_pwm_page(void) +{ + uint8_t c; + + c = NCHANNELS; + while (c--) + { + uint8_t port_bits = setup.channel_map[c].port_bits; + if (port_bits) + { + uint8_t code = setup.channel_map[c].code; + uint16_t v = bright_vals[CM_CHANNEL(code)]; + if (v) + { + if (v > setup.max_pwm) + v = setup.max_pwm; + set_channel(CM_PORT(code), port_bits, v); + } + } + } +} + + +// --- +// Initialize pwm step table and start pwm timer. +// +static void init_pwm_step_tab(void) +{ + // Set up pwm step table + shadow_pwm_page = pwm_step_page1; + active_pwm_page = pwm_step_page2; + actual_pwm_step = pwm_step_page2; + init_pwm_page(1); + calc_pwm_page(); + activate_pwm_page(); + actual_pwm_step = active_pwm_page->next_step; + + TCNT3 = 0; // Reset timer counter + OCR3A = PWM_PRESCALE; // Initial startup step + TCCR3B = _BV(CS32) | _BV(CS31) | _BV(WGM32); // Start timer, Prescaler 16, CTC mode +} + + +// --- +// Set default setup values. +// +static void init_setup_values(void) +{ + setup.max_pwm = DEF_MAX_PWM; + setup.common_pwm = DEF_COMMON_PWM; + + memcpy_P(&setup.channel_map, &default_channel_map, sizeof(setup.channel_map)); +} + + +// --- +// Read setup values from eeprom. +// +static void read_setup_values(void) +{ + if (eeprom_read_byte(&ee_valid) == EE_VALID_MARK) + eeprom_read_block(&setup, &ee_setup, sizeof(setup)); + else + init_setup_values(); +} + + +// --- +// Store actual setup values into eeprom. +// +static void store_setup_values(void) +{ + uint8_t i = sizeof(setup); + uint8_t *src = (uint8_t *) (&setup); + uint8_t *dst = (uint8_t *) (&ee_setup); + while (i--) + { + if (eeprom_read_byte(dst) != *src) + { + eeprom_write_byte(dst, *src); + while (!eeprom_is_ready()) + send_keep_alive_reply(); + } + ++src; + ++dst; + } + if (eeprom_read_byte(&ee_valid) != EE_VALID_MARK) + { + eeprom_write_byte(&ee_valid, EE_VALID_MARK); + while (!eeprom_is_ready()) + send_keep_alive_reply(); + } +} + + +// --- +// Set common pwm value. +// +static void set_common_pwm(void) +{ + uint8_t v = setup.common_pwm; + + if (v == 0 || v == 255) + { + if (v) + set_bit(COMMON_PWM_PORT, COMMON_PWM_BIT); + else + clear_bit(COMMON_PWM_PORT, COMMON_PWM_BIT); + clear_bit(TCCR1A, COM1B1); // Normal port output + } + else + { + OCR1B = v; + clear_bit(COMMON_PWM_PORT, COMMON_PWM_BIT); + set_bit(TCCR1A, COM1B1); // pwm port output + } +} + + +// --- +// Send reply packet from ram memory. +// +static void send_reply_mem(uint8_t *data, uint16_t len) +{ + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + uint16_t p = r->index.word << 1; + uint16_t n = r->length.word; + if (p >= len) + n = 0; + if (n && (p + n) > len) + n = len - p; + if (n > MAX_REPLY_PAYLOAD_SIZE) + n = 0; // Send nothing! + + send_reply_start(n); + + data += p; + while (n) + { + send_reply_data(*data++); + --n; + } +} + + +// --- +// Process set brightness value. +// +static void req_set_brightness(void) +{ + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + uint8_t p = payload_pos; + uint16_t c = r->index.word; + uint16_t len = r->length.word >> 1; + while (len && c < NCHANNELS) + { + bytes_word_t v; + v.bytes[0] = rxbuf[p++]; + CHECK_RXBUF_END(p); + v.bytes[1] = rxbuf[p++]; + CHECK_RXBUF_END(p); + + if (bright_vals[c] != v.word) + { + bright_vals[c] = v.word; + update_pwm_page = 1; + } + + ++c; + --len; + } +} + + +// --- +// Process set channel map request. +// +static void req_set_channel_map(void) +{ + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + uint8_t p = payload_pos; + uint16_t c = r->index.word; + uint16_t len = r->length.word >> 1; + while (len && c < NCHANNELS) + { + uint8_t v = rxbuf[p++]; + CHECK_RXBUF_END(p); + + if (CM_CHANNEL(v) >= NCHANNELS) + v = NCHANNELS - 1; + + if (setup.channel_map[c].code != v) + { + setup.channel_map[c].code = v; + update_pwm_page = 1; + } + + v = rxbuf[p++]; + CHECK_RXBUF_END(p); + + if (setup.channel_map[c].port_bits != v) + { + setup.channel_map[c].port_bits = v; + update_pwm_page = 1; + } + + ++c; + --len; + } +} + + +// --- +// Process received request. +// +static void process_request(void) +{ + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + uint8_t req = r->request; + + if (req == PWM_REQ_SET_BRIGHTNESS) + req_set_brightness(); + else if (req == PWM_REQ_SET_BRIGHTNESS_SYNCED) + { + req_set_brightness(); + if (update_pwm_page) + { + while (!init_pwm_page(0)) + background_processing(); + } + } + else if (req == PWM_REQ_GET_BRIGHTNESS) + { + send_reply_mem((uint8_t *)bright_vals, sizeof(bright_vals)); + return; + } + else if (req == PWM_REQ_SET_CHANNEL_MAP) + req_set_channel_map(); + else if (req == PWM_REQ_GET_CHANNEL_MAP) + { + send_reply_mem((uint8_t *)&setup.channel_map, sizeof(setup.channel_map)); + return; + } + else if (req == PWM_REQ_STORE_SETUP) + store_setup_values(); + else if (req == PWM_REQ_RESET_SETUP) + { + init_setup_values(); + update_pwm_page = 1; + if (eeprom_read_byte(&ee_valid) == EE_VALID_MARK) + eeprom_write_byte(&ee_valid, (uint8_t)(~EE_VALID_MARK)); // Invalidate eeprom values + } + else if (req == PWM_REQ_GET_REQUEST_ERR_STATUS) + { + send_reply_start(1); + send_reply_data(rx_err_status); + rx_err_status = 0; + return; + } + else if (req == PWM_REQ_SET_COMMON_PWM) + { + setup.common_pwm = (r->value.word <= MAX_COMMON_PWM) ? r->value.bytes[0]: MAX_COMMON_PWM; + set_common_pwm(); + } + else if (req == PWM_REQ_GET_COMMON_PWM) + { + send_reply_start(2); + send_reply_data(setup.common_pwm); + send_reply_data(0); + return; + } + else if (req == PWM_REQ_GET_MAX_PWM) + { + send_reply_start(4); + send_reply_data((uint8_t)(setup.max_pwm & 0x00FF)); + send_reply_data((uint8_t)(setup.max_pwm >> 8)); + send_reply_data(MAX_COMMON_PWM); + send_reply_data(0); + return; + } + else if (req == PWM_REQ_SET_PWM_FREQ) + { + if (r->value.word >= MIN_PWM_FREQ && r->value.word <= MAX_PWM_FREQ) + { + setup.max_pwm = F_CPU / (PWM_HWPRESCALE * PWM_PRESCALE * (uint32_t)r->value.word) - 1; + update_pwm_page = 1; + } + } + else if (req == PWM_REQ_GET_PWM_FREQ) + { + uint16_t f = F_CPU / (((uint32_t)setup.max_pwm + 1) * PWM_HWPRESCALE * PWM_PRESCALE); + send_reply_start(2); + send_reply_data((uint8_t)(f & 0x00FF)); + send_reply_data((uint8_t)(f >> 8)); + return; + } + else if (req == PWM_REQ_GET_VERSION) + { + send_reply_start(2); + send_reply_data(PWM_VERS_APPL); + send_reply_data(FIRMWARE_VERSION); + return; + } + else if (req == PWM_REQ_ECHO_TEST) + { + send_reply_start(8); + send_reply_data(r->bytes[0]); + send_reply_data(r->bytes[1]); + send_reply_data(r->bytes[2]); + send_reply_data(r->bytes[3]); + send_reply_data(r->bytes[4]); + send_reply_data(r->bytes[5]); + send_reply_data(r->bytes[6]); + send_reply_data(r->bytes[7]); + return; + } + + send_reply_start(0); +} + + +// --- +// Decode data byte of received data. +// +static void read_data(void) +{ + uint8_t p, c, is_req_start; + + + // Read data from RX buffer + p = rxrpos; + is_req_start = (p == rxspos); + c = rxbuf[p++]; + CHECK_RXBUF_END(p); + rxrpos = p; + + p = header_pos; + if (is_req_start) + { + if (p) + set_bit(rx_err_status, COMM_ERR_TIMEOUT); + + p = 0; + } + else if (!p) + return; // Discard garbage + + if (p < sizeof(pwm_request_t)) + { + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + r->bytes[p++] = c; + header_pos = p; + + if (p < sizeof(pwm_request_t)) + return; + + // Header complete + if (!(r->request_type & PWMRQ_DEVICE_TO_HOST) && r->length.word) + { + payload_pos = rxrpos; + payload_count = r->length.word; + return; + } + } + else if (--payload_count) + return; // Payload not complete + + last_keep_alive = sys_clock; + process_request(); + header_pos = 0; +} + + +// --- +// Device initialization and main program loop. +// +void main(void) NORETURN; +void main(void) +{ + wdt_enable(WDTO_30MS); // Set watchdog timeout + + // Port init, enable pull-up resistors for unused ports + PORTA = PA_INIT; + PORTB = PB_INIT; + PORTC = PC_INIT; + PORTD = PD_INIT; + PORTE = PE_INIT; + DDRA = PA_DDR; + DDRB = PB_DDR; + DDRC = PC_DDR; + DDRD = PD_DDR; + DDRE = PE_DDR; + + // USART init + // 9 data bits, 1 stop bit, no parity, asynchron mode + // Enable TX, RX and RX Interrupts +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A = _BV(U2X); +#endif + UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00); + UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UCSZ02); + + read_setup_values(); + + // Timer 0 is used for system clock + // Normal mode, Prescaler 64 + TCCR0 = _BV(CS01) | _BV(CS00); + + // Timer 1 is used for common PWM generation + // Fast 8-Bit PWM mode, Prescaler 1, PWM output at OC1B Pin + TCCR1A = _BV(WGM10); + TCCR1B = _BV(WGM12) | _BV(CS10); + set_common_pwm(); + + // Timer 3 is used for PWM generation + ETIMSK = _BV(OCIE3A); // Enable timer 3 compare a interrupt + init_pwm_step_tab(); + + // Main loop + for (;;) + { + background_processing(); + + if (rxrpos != rxwpos) + read_data(); + + if (update_pwm_page && init_pwm_page(1)) + { + calc_pwm_page(); + activate_pwm_page(); + } + + if (update_pwm_page || header_pos) + clear_bit(STATUS_LED_PORT, STATUS_LED_BIT); // We are processing a request + else + set_bit(STATUS_LED_PORT, STATUS_LED_BIT); // No request + } +} diff --git a/pwm_boot/10ch_pwm_boot.c b/pwm_boot/10ch_pwm_boot.c deleted file mode 100644 index 787f5df..0000000 --- a/pwm_boot/10ch_pwm_boot.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Auras - * - * This file is part of the DF10CH Atmolight controller project. - * - * DF10CH Atmolight controller 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. - * - * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - */ - -// ====================================================================== -// Bootloader firmware for PWM processor. -// - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../df10ch_common.h" -#include "../df10ch_usb_proto.h" - - -// --- -// Fuse-Bit settings for the flash programmer (Atmega 162): -// -// M161C=1 -// BODLEVEL2=1 -// BODLEVEL1=0 -// BODLEVEL0=0 -// -// OCDEN=1 -// JTAGEN=1 -// SPIEN=0 -// WDTON=0 -// EESAVE=1 -// BOOTSZ1=0 -// BOOTSZ0=0 -// BOOTRST=0 -// -// CKDIV8=1 -// CKOUT=1 -// SUT1=0 -// SUT0=1 -// CKSEL3=1 -// CKSEL2=1 -// CKSEL1=1 -// CKSEL0=1 -// -// Memory-Lock Bits: -// BLB12=1, BLB11=0, BLB02=1, BLB01=1, LB2=1, LB1=1 -// -FUSES = -{ - .low = (FUSE_SUT1), - .high = (FUSE_SPIEN & FUSE_WDTON & FUSE_BOOTSZ1 & FUSE_BOOTSZ0 & FUSE_BOOTRST), - .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0), -}; -LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); -//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; - - -// --- -// System clock related. -// System clock is implemented with hardware timer 0 -// -#define SYS_HWPRESCALE 64 // Hardware Prescaler -#define SYS_PRESCALER 256 // Timer Prescaler - - // useconds <-> timer ticks conversation -#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE * (double)SYS_PRESCALER) + 0.5)) -#define TICKS2US(t) (((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE * SYS_PRESCALER)))) - -static uint16_t sys_clock; - - -// --- -// Keep alive reply related -// -#define MIN_KEEP_ALIVE_PAUSE US2TICKS(15000) - -static uint16_t last_keep_alive; - - -// --- -// Request parser related variables -// -typedef union -{ - uint8_t bytes[REQ_HEADER_SIZE]; - struct - { - uint8_t request_type; - uint8_t request; - bytes_word_t value; - bytes_word_t index; - bytes_word_t length; - }; -} pwm_request_t; - -static pwm_request_t actual_req; -static uint8_t header_pos; -static uint8_t payload_pos; -static uint8_t payload_count; - - -// --- -// RX buffer related variables -// -#define RXBUF_SIZE (REQ_HEADER_SIZE + MAX_REQ_PAYLOAD_SIZE + 1) -#if RXBUF_SIZE == 256 -#define CHECK_RXBUF_END(pos) -#else -#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0 -#endif - -static uint8_t volatile rxrpos, rxwpos, rxspos, rx_err_status; -static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT; - - -// Status LED related -#define STATUS_LED_PORT PORTE -#define STATUS_LED_BIT 1 - -// Input pin for enable/disable of bootloader -#define BL_SENSE_PIN PINE -#define BL_SENSE_BIT 0 - -#define APPL_START_VECT 0x0000 - -// --- -// Definition of port direction and initial values. -// -#define PE_DDR _BV(STATUS_LED_BIT) -#define PE_INIT _BV(BL_SENSE_BIT) - - -// --- -// ISR handler for IRQ's that do not have a dedicated handler. -// -EMPTY_INTERRUPT(BADISR_vect) - - -// --- -// ISR for receiving data. -// -ISR(USART0_RXC_vect) -{ - do - { - uint8_t i = rxwpos; - uint8_t p = i + 1; - CHECK_RXBUF_END(p); - - if (bit_is_set(UCSR0A, FE0)) - set_bit(rx_err_status, COMM_ERR_FRAME); - else if (bit_is_set(UCSR0A, DOR0)) - set_bit(rx_err_status, COMM_ERR_OVERRUN); - else if (p == rxrpos) - set_bit(rx_err_status, COMM_ERR_OVERFLOW); - else - { - if (bit_is_set(UCSR0B, RXB80)) - rxspos = i; // save start of request message - rxwpos = p; // set data valid - } - rxbuf[i] = UDR0; // read data - } - while (bit_is_set(UCSR0A, RXC0)); -} - - -// --- -// Processing while waiting for a event. -// -static void background_processing(void) -{ - wdt_reset(); - - // count system clock - if (bit_is_set(TIFR, TOV0)) - { - ++sys_clock; - TIFR = _BV(TOV0); - } -} - - -// --- -// Put data into transmit buffer. -// -static void send_reply_data(uint8_t c) -{ - // Wait until transmit buffer free - while (bit_is_clear(UCSR0A, UDRE0)) - background_processing(); - - UDR0 = c; -} - - -// --- -// Send reply start. -// -static void send_reply_start(uint8_t len) -{ - // Wait until transmit buffer free - while (bit_is_clear(UCSR0A, UDRE0)) - background_processing(); - - uint8_t id = actual_req.request_type & PWMRQ_ID_MASK; - if (len) - id |= PWMRP_HAS_PAYLOAD; - - set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply - UDR0 = id; // Send reply id - clear_bit(UCSR0B, TXB80); - - if (len) - send_reply_data(len); // Send reply length - - last_keep_alive = sys_clock; -} - - -// --- -// Send keep alive reply. -// -static void send_keep_alive_reply(void) -{ - background_processing(); - if ((sys_clock - last_keep_alive) > MIN_KEEP_ALIVE_PAUSE) - { - // Wait until transmit buffer free - while (bit_is_clear(UCSR0A, UDRE0)) - background_processing(); - - set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply - UDR0 = PWMRP_KEEP_ALIVE; // Send keep alive ID - clear_bit(UCSR0B, TXB80); - - last_keep_alive = sys_clock; - } -} - - -// --- -// Send reply packet from flash memory. -// -static void send_reply_read_flash(PGM_P p, uint16_t n) -{ - if (n > MAX_REPLY_PAYLOAD_SIZE) - n = 0; // Send nothing! - - send_reply_start((uint8_t)n); - - while (n) - { - send_reply_data(pgm_read_byte(p)); - ++p; - --n; - } -} - - -// --- -// Process write flash page request. -// -static void req_write_flash_page(uint16_t page_address, uint16_t len) -{ - while (!eeprom_is_ready()) - send_keep_alive_reply(); - - cli(); - boot_page_erase(page_address); - sei(); - - while (boot_spm_busy()) - send_keep_alive_reply(); - - uint8_t page_offset = 0; - uint8_t p = payload_pos; - while (len > 1 && page_offset < SPM_PAGESIZE) - { - bytes_word_t v; - v.bytes[0] = rxbuf[p++]; - CHECK_RXBUF_END(p); - v.bytes[1] = rxbuf[p++]; - CHECK_RXBUF_END(p); - - cli(); - boot_page_fill(page_address + page_offset, v.word); - sei(); - - page_offset += 2; - len -= 2; - } - - cli(); - boot_page_write(page_address); - sei(); - - while (boot_spm_busy()) - send_keep_alive_reply(); - - if (boot_rww_busy()) - boot_rww_enable(); -} - - -// --- -// Process received request. -// -static void process_request(void) -{ - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - uint8_t req = r->request; - - if (req == BL_PWM_REQ_WRITE_PAGE) - req_write_flash_page(r->index.word, r->length.word); - else if (req == BL_PWM_REQ_READ_FLASH) - { - send_reply_read_flash((PGM_P) r->index.word, r->length.word); - return; - } - else if (req == BL_PWM_REQ_GET_PAGE_SIZE) - { - send_reply_start(2); - send_reply_data(SPM_PAGESIZE & 0xFF); - send_reply_data(SPM_PAGESIZE >> 8); - return; - } - else if (req == BL_PWM_REQ_GET_REQUEST_ERR_STATUS) - { - send_reply_start(1); - send_reply_data(rx_err_status); - rx_err_status = 0; - return; - } - else if (req == PWM_REQ_GET_VERSION) - { - send_reply_start(2); - send_reply_data(PWM_VERS_BOOT); - send_reply_data(FIRMWARE_VERSION); - return; - } - - send_reply_start(0); -} - - -// --- -// Decode data byte of received data. -// -static void read_data(void) -{ - uint8_t p, c, is_req_start; - - // Read data from RX buffer - p = rxrpos; - is_req_start = (p == rxspos); - c = rxbuf[p++]; - CHECK_RXBUF_END(p); - rxrpos = p; - - p = header_pos; - if (is_req_start) - { - if (p) - set_bit(rx_err_status, COMM_ERR_TIMEOUT); - - p = 0; - } - else if (!p) - return; // Discard garbage - - if (p < sizeof(pwm_request_t)) - { - pwm_request_t *r = &actual_req; - FIX_POINTER(r); - - r->bytes[p++] = c; - header_pos = p; - - if (p < sizeof(pwm_request_t)) - return; - - // Header complete - if (!(r->request_type & PWMRQ_DEVICE_TO_HOST) && r->length.word) - { - payload_pos = rxrpos; - payload_count = r->length.word; - return; - } - } - else if (--payload_count) - return; // Payload not complete - - last_keep_alive = sys_clock; - process_request(); - header_pos = 0; -} - - -// --- -// Device initialization and main program loop. -// -void main(void) NORETURN; -void main(void) -{ - wdt_enable(WDTO_30MS); // Set watchdog timeout - - // Port init, enable pull-up resistors for unused ports - PORTE = PE_INIT; - DDRE = PE_DDR; - - if ((pgm_read_word(APPL_START_VECT) != 0xFFFF) && // Application reset vector programmed? - bit_is_set(BL_SENSE_PIN, BL_SENSE_BIT)) - { // boot loader disabled -> start application - void (*jump_to_app)(void) = APPL_START_VECT / 2; // Need flash word address! - jump_to_app(); - } - - GICR = _BV(IVCE); // enable change of interrupt vectors - GICR = _BV(IVSEL); // move interrupts to boot flash section - - // USART init - // 9 data bits, 1 stop bit, no parity, asynchron mode - // Enable TX, RX and RX Interrupts -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A = _BV(U2X); -#endif - UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00); - UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UCSZ02); - - // Timer 0 is used for system clock - // Normal mode, Prescaler 64 - TCCR0 = _BV(CS01) | _BV(CS00); - - sei(); - - // Main loop - for (;;) - { - background_processing(); - - if (rxrpos != rxwpos) - read_data(); - - if (header_pos) - clear_bit(STATUS_LED_PORT, STATUS_LED_BIT); // We are processing a request - else - set_bit(STATUS_LED_PORT, STATUS_LED_BIT); // No request - } -} diff --git a/pwm_boot/Makefile b/pwm_boot/Makefile index 1a98f84..fb401ea 100644 --- a/pwm_boot/Makefile +++ b/pwm_boot/Makefile @@ -1,102 +1,102 @@ -# -# Copyright (C) 2010 Andreas Auras -# -# This file is part of the DF10CH Atmolight controller project. -# -# DF10CH Atmolight controller 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. -# -# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -# -# -############################################################################### -# Makefile for the bootloader firmware of PWM processor -############################################################################### - -## General Flags -PROJECT = 10ch_pwm_boot -MCU = atmega162 -TARGET = 10ch_pwm_boot.elf -CC = avr-gcc -AVRDUDE ?= avrdude -c stk500v2 -P avrdoper -F_CPU ?= 16000000UL -FIRMWARE_VERSION ?= 1 - -## Options common to compile, link and assembly rules -COMMON = -mmcu=$(MCU) - -## Compile options common for all C compilation units. -CFLAGS = $(COMMON) -CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) - -## Assembly specific flags -ASMFLAGS = $(COMMON) -ASMFLAGS += $(CFLAGS) -ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 - -## Linker flags -LDFLAGS = $(COMMON) -LDFLAGS += -Wl,-Map=10ch_pwm_boot.map -LDFLAGS += -Wl,-section-start=.text=0x3800 - - -## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature - -HEX_EEPROM_FLAGS = -j .eeprom -HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" - -## Include Directories -INCLUDES = -I. -I.. - -## Objects that must be built in order to link -OBJECTS = 10ch_pwm_boot.o - -## Objects explicitly added by the user -LINKONLYOBJECTS = - -## Build -all: $(TARGET) 10ch_pwm_boot.hex 10ch_pwm_boot.lss size - -prog: flash - $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0xc0:m -Uhfuse:w:0xc8:m -Uefuse:w:0xf9:m -Ulock:w:0xef:m - -flash: 10ch_pwm_boot.hex - $(AVRDUDE) -p $(MCU) -Uflash:w:10ch_pwm_boot.hex:i - - -## Compile -10ch_pwm_boot.o: 10ch_pwm_boot.c ../df10ch_usb_proto.h ../df10ch_common.h - $(CC) $(INCLUDES) $(CFLAGS) -c $< - -##Link -$(TARGET): $(OBJECTS) - $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) - -%.hex: $(TARGET) - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -%.eep: $(TARGET) - -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 - -%.lss: $(TARGET) - avr-objdump -h -S $< > $@ - -size: ${TARGET} - @echo - @avr-size -C --mcu=${MCU} ${TARGET} - -## Clean target -.PHONY: clean -clean: - -rm -rf $(OBJECTS) 10ch_pwm_boot.elf 10ch_pwm_boot.hex 10ch_pwm_boot.eep 10ch_pwm_boot.lss 10ch_pwm_boot.map +# +# Copyright (C) 2010 Andreas Auras +# +# This file is part of the DF10CH Atmolight controller project. +# +# DF10CH Atmolight controller 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. +# +# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +# +# +############################################################################### +# Makefile for the bootloader firmware of PWM processor +############################################################################### + +## General Flags +PROJECT = df10ch_pwm_boot +MCU = atmega162 +TARGET = df10ch_pwm_boot.elf +CC = avr-gcc +AVRDUDE ?= avrdude -c stk500v2 -P avrdoper +F_CPU ?= 16000000UL +FIRMWARE_VERSION ?= 1 + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-Map=df10ch_pwm_boot.map +LDFLAGS += -Wl,-section-start=.text=0x3800 + + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" + +## Include Directories +INCLUDES = -I. -I.. + +## Objects that must be built in order to link +OBJECTS = df10ch_pwm_boot.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET) df10ch_pwm_boot.hex df10ch_pwm_boot.lss size + +prog: flash + $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0xc0:m -Uhfuse:w:0xc8:m -Uefuse:w:0xf9:m -Ulock:w:0xef:m + +flash: df10ch_pwm_boot.hex + $(AVRDUDE) -p $(MCU) -Uflash:w:df10ch_pwm_boot.hex:i + + +## Compile +df10ch_pwm_boot.o: df10ch_pwm_boot.c ../df10ch_usb_proto.h ../df10ch_common.h + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) + +%.hex: $(TARGET) + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET) + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET) + avr-objdump -h -S $< > $@ + +size: ${TARGET} + @echo + @avr-size -C --mcu=${MCU} ${TARGET} + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) df10ch_pwm_boot.elf df10ch_pwm_boot.hex df10ch_pwm_boot.eep df10ch_pwm_boot.lss df10ch_pwm_boot.map diff --git a/pwm_boot/df10ch_pwm_boot.c b/pwm_boot/df10ch_pwm_boot.c new file mode 100644 index 0000000..8795a5c --- /dev/null +++ b/pwm_boot/df10ch_pwm_boot.c @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2010 Andreas Auras + * + * This file is part of the DF10CH Atmolight controller project. + * + * DF10CH Atmolight controller 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. + * + * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +// ====================================================================== +// Bootloader firmware for PWM processor. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../df10ch_common.h" +#include "../df10ch_usb_proto.h" + + +// --- +// Fuse-Bit settings for the flash programmer (Atmega 162): +// +// M161C=1 +// BODLEVEL2=1 +// BODLEVEL1=0 +// BODLEVEL0=0 +// +// OCDEN=1 +// JTAGEN=1 +// SPIEN=0 +// WDTON=0 +// EESAVE=1 +// BOOTSZ1=0 +// BOOTSZ0=0 +// BOOTRST=0 +// +// CKDIV8=1 +// CKOUT=1 +// SUT1=0 +// SUT0=1 +// CKSEL3=1 +// CKSEL2=1 +// CKSEL1=1 +// CKSEL0=1 +// +// Memory-Lock Bits: +// BLB12=1, BLB11=0, BLB02=1, BLB01=1, LB2=1, LB1=1 +// +FUSES = +{ + .low = (FUSE_SUT1), + .high = (FUSE_SPIEN & FUSE_WDTON & FUSE_BOOTSZ1 & FUSE_BOOTSZ0 & FUSE_BOOTRST), + .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0), +}; +LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); +//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; + + +// --- +// System clock related. +// System clock is implemented with hardware timer 0 +// +#define SYS_HWPRESCALE 64 // Hardware Prescaler +#define SYS_PRESCALER 256 // Timer Prescaler + + // useconds <-> timer ticks conversation +#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE * (double)SYS_PRESCALER) + 0.5)) +#define TICKS2US(t) (((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE * SYS_PRESCALER)))) + +static uint16_t sys_clock; + + +// --- +// Keep alive reply related +// +#define MIN_KEEP_ALIVE_PAUSE US2TICKS(15000) + +static uint16_t last_keep_alive; + + +// --- +// Request parser related variables +// +typedef union +{ + uint8_t bytes[REQ_HEADER_SIZE]; + struct + { + uint8_t request_type; + uint8_t request; + bytes_word_t value; + bytes_word_t index; + bytes_word_t length; + }; +} pwm_request_t; + +static pwm_request_t actual_req; +static uint8_t header_pos; +static uint8_t payload_pos; +static uint8_t payload_count; + + +// --- +// RX buffer related variables +// +#define RXBUF_SIZE (REQ_HEADER_SIZE + MAX_REQ_PAYLOAD_SIZE + 1) +#if RXBUF_SIZE == 256 +#define CHECK_RXBUF_END(pos) +#else +#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0 +#endif + +static uint8_t volatile rxrpos, rxwpos, rxspos, rx_err_status; +static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT; + + +// Status LED related +#define STATUS_LED_PORT PORTE +#define STATUS_LED_BIT 1 + +// Input pin for enable/disable of bootloader +#define BL_SENSE_PIN PINE +#define BL_SENSE_BIT 0 + +#define APPL_START_VECT 0x0000 + +// --- +// Definition of port direction and initial values. +// +#define PE_DDR _BV(STATUS_LED_BIT) +#define PE_INIT _BV(BL_SENSE_BIT) + + +// --- +// ISR handler for IRQ's that do not have a dedicated handler. +// +EMPTY_INTERRUPT(BADISR_vect) + + +// --- +// ISR for receiving data. +// +ISR(USART0_RXC_vect) +{ + do + { + uint8_t i = rxwpos; + uint8_t p = i + 1; + CHECK_RXBUF_END(p); + + if (bit_is_set(UCSR0A, FE0)) + set_bit(rx_err_status, COMM_ERR_FRAME); + else if (bit_is_set(UCSR0A, DOR0)) + set_bit(rx_err_status, COMM_ERR_OVERRUN); + else if (p == rxrpos) + set_bit(rx_err_status, COMM_ERR_OVERFLOW); + else + { + if (bit_is_set(UCSR0B, RXB80)) + rxspos = i; // save start of request message + rxwpos = p; // set data valid + } + rxbuf[i] = UDR0; // read data + } + while (bit_is_set(UCSR0A, RXC0)); +} + + +// --- +// Processing while waiting for a event. +// +static void background_processing(void) +{ + wdt_reset(); + + // count system clock + if (bit_is_set(TIFR, TOV0)) + { + ++sys_clock; + TIFR = _BV(TOV0); + } +} + + +// --- +// Put data into transmit buffer. +// +static void send_reply_data(uint8_t c) +{ + // Wait until transmit buffer free + while (bit_is_clear(UCSR0A, UDRE0)) + background_processing(); + + UDR0 = c; +} + + +// --- +// Send reply start. +// +static void send_reply_start(uint8_t len) +{ + // Wait until transmit buffer free + while (bit_is_clear(UCSR0A, UDRE0)) + background_processing(); + + uint8_t id = actual_req.request_type & PWMRQ_ID_MASK; + if (len) + id |= PWMRP_HAS_PAYLOAD; + + set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply + UDR0 = id; // Send reply id + clear_bit(UCSR0B, TXB80); + + if (len) + send_reply_data(len); // Send reply length + + last_keep_alive = sys_clock; +} + + +// --- +// Send keep alive reply. +// +static void send_keep_alive_reply(void) +{ + background_processing(); + if ((sys_clock - last_keep_alive) > MIN_KEEP_ALIVE_PAUSE) + { + // Wait until transmit buffer free + while (bit_is_clear(UCSR0A, UDRE0)) + background_processing(); + + set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply + UDR0 = PWMRP_KEEP_ALIVE; // Send keep alive ID + clear_bit(UCSR0B, TXB80); + + last_keep_alive = sys_clock; + } +} + + +// --- +// Send reply packet from flash memory. +// +static void send_reply_read_flash(PGM_P p, uint16_t n) +{ + if (n > MAX_REPLY_PAYLOAD_SIZE) + n = 0; // Send nothing! + + send_reply_start((uint8_t)n); + + while (n) + { + send_reply_data(pgm_read_byte(p)); + ++p; + --n; + } +} + + +// --- +// Process write flash page request. +// +static void req_write_flash_page(uint16_t page_address, uint16_t len) +{ + while (!eeprom_is_ready()) + send_keep_alive_reply(); + + cli(); + boot_page_erase(page_address); + sei(); + + while (boot_spm_busy()) + send_keep_alive_reply(); + + uint8_t page_offset = 0; + uint8_t p = payload_pos; + while (len > 1 && page_offset < SPM_PAGESIZE) + { + bytes_word_t v; + v.bytes[0] = rxbuf[p++]; + CHECK_RXBUF_END(p); + v.bytes[1] = rxbuf[p++]; + CHECK_RXBUF_END(p); + + cli(); + boot_page_fill(page_address + page_offset, v.word); + sei(); + + page_offset += 2; + len -= 2; + } + + cli(); + boot_page_write(page_address); + sei(); + + while (boot_spm_busy()) + send_keep_alive_reply(); + + if (boot_rww_busy()) + boot_rww_enable(); +} + + +// --- +// Process received request. +// +static void process_request(void) +{ + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + uint8_t req = r->request; + + if (req == BL_PWM_REQ_WRITE_PAGE) + req_write_flash_page(r->index.word, r->length.word); + else if (req == BL_PWM_REQ_READ_FLASH) + { + send_reply_read_flash((PGM_P) r->index.word, r->length.word); + return; + } + else if (req == BL_PWM_REQ_GET_PAGE_SIZE) + { + send_reply_start(2); + send_reply_data(SPM_PAGESIZE & 0xFF); + send_reply_data(SPM_PAGESIZE >> 8); + return; + } + else if (req == BL_PWM_REQ_GET_REQUEST_ERR_STATUS) + { + send_reply_start(1); + send_reply_data(rx_err_status); + rx_err_status = 0; + return; + } + else if (req == PWM_REQ_GET_VERSION) + { + send_reply_start(2); + send_reply_data(PWM_VERS_BOOT); + send_reply_data(FIRMWARE_VERSION); + return; + } + + send_reply_start(0); +} + + +// --- +// Decode data byte of received data. +// +static void read_data(void) +{ + uint8_t p, c, is_req_start; + + // Read data from RX buffer + p = rxrpos; + is_req_start = (p == rxspos); + c = rxbuf[p++]; + CHECK_RXBUF_END(p); + rxrpos = p; + + p = header_pos; + if (is_req_start) + { + if (p) + set_bit(rx_err_status, COMM_ERR_TIMEOUT); + + p = 0; + } + else if (!p) + return; // Discard garbage + + if (p < sizeof(pwm_request_t)) + { + pwm_request_t *r = &actual_req; + FIX_POINTER(r); + + r->bytes[p++] = c; + header_pos = p; + + if (p < sizeof(pwm_request_t)) + return; + + // Header complete + if (!(r->request_type & PWMRQ_DEVICE_TO_HOST) && r->length.word) + { + payload_pos = rxrpos; + payload_count = r->length.word; + return; + } + } + else if (--payload_count) + return; // Payload not complete + + last_keep_alive = sys_clock; + process_request(); + header_pos = 0; +} + + +// --- +// Device initialization and main program loop. +// +void main(void) NORETURN; +void main(void) +{ + wdt_enable(WDTO_30MS); // Set watchdog timeout + + // Port init, enable pull-up resistors for unused ports + PORTE = PE_INIT; + DDRE = PE_DDR; + + if ((pgm_read_word(APPL_START_VECT) != 0xFFFF) && // Application reset vector programmed? + bit_is_set(BL_SENSE_PIN, BL_SENSE_BIT)) + { // boot loader disabled -> start application + void (*jump_to_app)(void) = APPL_START_VECT / 2; // Need flash word address! + jump_to_app(); + } + + GICR = _BV(IVCE); // enable change of interrupt vectors + GICR = _BV(IVSEL); // move interrupts to boot flash section + + // USART init + // 9 data bits, 1 stop bit, no parity, asynchron mode + // Enable TX, RX and RX Interrupts +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A = _BV(U2X); +#endif + UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00); + UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UCSZ02); + + // Timer 0 is used for system clock + // Normal mode, Prescaler 64 + TCCR0 = _BV(CS01) | _BV(CS00); + + sei(); + + // Main loop + for (;;) + { + background_processing(); + + if (rxrpos != rxwpos) + read_data(); + + if (header_pos) + clear_bit(STATUS_LED_PORT, STATUS_LED_BIT); // We are processing a request + else + set_bit(STATUS_LED_PORT, STATUS_LED_BIT); // No request + } +} diff --git a/usb_appl/10ch_usb_appl.c b/usb_appl/10ch_usb_appl.c deleted file mode 100644 index 3728c55..0000000 --- a/usb_appl/10ch_usb_appl.c +++ /dev/null @@ -1,838 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Auras - * - * This file is part of the DF10CH Atmolight controller project. - * - * DF10CH Atmolight controller 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. - * - * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - */ - -// ====================================================================== -// Application firmware for USB processor. -// - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "../df10ch_common.h" -#include "../df10ch_usb_proto.h" -#include "usbconfig.h" - - -// --- -// Fuse-Bit settings for the flash programmer (ATmega8): -// RSTDISBL=1 -// WDTON=1 -// SPIEN=0 -// CKOPT=0 -// EESAVE=1 -// BOOTSZ1=0 -// BOOTSZ0=0 -// BOOTRST=1 -// -// BODLEVEL=0 -// BODEN=0 -// SUT1=0 -// SUT0=1 -// CKSEL3=1 -// CKSEL2=1 -// CKSEL1=1 -// CKSEL0=1 -// -// Memory-Lock Bits: -// BL12=1, BL11=0, BL02=1, BL01=1, LB2=1, LB1=1 -// -FUSES = -{ - .low = (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT1), - .high = (FUSE_SPIEN & FUSE_CKOPT & FUSE_BOOTSZ1 & FUSE_BOOTSZ0) -}; -LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); -//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; - - -#define EE_MEM_SIZE (E2END + 1) - - -// --- -// System clock related. -// System clock ist implemented with hardware timer 1 -// -#define SYS_HWPRESCALE 1024 // Hardware Prescaler - - // useconds <-> timer ticks conversation -#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE) + 0.5)) -#define TICKS2US(t) ((uint16_t)((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE)))) - - -// --- -// pwm controller reset related. -// -#define RESET_TIME US2TICKS(128UL) -#define STARTUP_TIME US2TICKS(10000UL) - - // Output pin for PWM controller reset -#define RESET_PORT PORTB -#define RESET_BIT 4 - - // Output pin for enabling PWM controller bootloader -#define BOOTLOADER_PORT PORTB -#define BOOTLOADER_BIT 3 - - -// --- -// bootloader related. -// -#define BL_START_VECT 0x1800 - -// Input/Output pin for bootloader startup -#define BL_SENSE_DDR DDRB -#define BL_SENSE_PORT PORTB -#define BL_SENSE_PIN PINB -#define BL_SENSE_BIT 0 - -#define BL_START_DELAY_TIME US2TICKS(30000UL) - -static uint8_t bl_start; -static uint16_t bl_time; - - -// --- -// USB related. -// -#define USB_SLEEP_TIMEOUT US2TICKS(5000UL) -#define USB_DISCONNECT_TIME US2TICKS(500000UL) -#define USB_INITIALIZE_TIMEOUT US2TICKS(1750000UL) -#define USB_STALL_RC 0xFF - -volatile uint16_t usb_sof_time; // Time of last USB start of frame IRQ -static uint8_t usb_is_resetting; // Is true while reset condition on USB bus happen -static uint8_t usb_is_initialized; // Is true after USB address has been set -static uint8_t usb_last_data_token; // Token PID of last usb packet received -static uint8_t usb_last_rc; // Return status of last payload packet -static uint8_t payload_req; // ID of actual proccessed USB request -static uint16_t payload_pos; // Position of actual payload read/write -static uint16_t payload_count; // Number of bytes left of actual payload read/write - - - -// --- -// RX buffer related. -// -#define RXBUF_SIZE 256 -#if RXBUF_SIZE == 256 -#define CHECK_RXBUF_END(pos) -#else -#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0 -#endif - -static volatile uint8_t rxrpos, rxwpos; -static volatile uint8_t rxspos; // Start position of reply -static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT; - - -// --- -// TX buffer related. -// -#define TXBUF_SIZE 256 -#if TXBUF_SIZE == 256 -#define CHECK_TXBUF_END(pos) -#else -#define CHECK_TXBUF_END(pos) if ((pos) == TXBUF_SIZE) (pos) = 0 -#endif - -static uint8_t txrpos, txwpos; -static uint8_t txbuf[TXBUF_SIZE] NOMEMINIT; - - -// --- -// PWM controller communication related. -// -#define REPLY_START_TIMEOUT US2TICKS(50000UL) -#define REPLY_TIMEOUT US2TICKS(10000UL) - -static uint8_t actual_req_id; -static uint8_t reply_start; -static uint8_t reply_count; -static volatile uint8_t reply_err_status; -static uint16_t reply_start_timeout = REPLY_START_TIMEOUT; -static uint16_t reply_timeout = REPLY_TIMEOUT; - - -// --- -// Port setup related. -// -#define PORTB_INIT (_BV(BL_SENSE_BIT) | _BV(BOOTLOADER_BIT) | _BV(1) | _BV(2) | _BV(5)) -#define DDRB_INIT (_BV(BOOTLOADER_BIT) | _BV(RESET_BIT)) - -#define PORTC_INIT (0xFF) -#define DDRC_INIT (0) - -#define PORTD_INIT (_BV(1) | _BV(5) | _BV(6) | _BV(7)) -#define DDRD_INIT (_BV(1)) - - -#include - - -// --- -// ISR handler for IRQ's that do not have a dedicated handler. -// -ISR(BADISR_vect) -{ - for (;;); // wait until watchdog resets device -} - - -// --- -// ISR for receiving data. -// -ISR(USART_RXC_vect) -{ - clear_bit(UCSRB, RXCIE); - sei(); - - do - { - uint8_t i = rxwpos; - uint8_t p = i + 1; - CHECK_RXBUF_END(p); - - if (bit_is_set(UCSRA, DOR)) - set_bit(reply_err_status, COMM_ERR_OVERRUN); - else if (bit_is_set(UCSRA, FE)) - set_bit(reply_err_status, COMM_ERR_FRAME); - else if (p == rxrpos) - set_bit(reply_err_status, COMM_ERR_OVERFLOW); - else - { - if (bit_is_set(UCSRB, RXB8)) - rxspos = i; // save reply start position - rxwpos = p; // set data valid - } - rxbuf[i] = UDR; // read data - } - while (bit_is_set(UCSRA, RXC)); - - cli(); - set_bit(UCSRB, RXCIE); -} - - -// --- -// Read actual system clock counter. -// Note: Counter is also read inside USB irq handler -> we need save read! -// -static uint16_t get_sys_clock(void) -{ - uint8_t sreg = SREG; - cli(); - uint16_t t = TCNT1; - SREG = sreg; - nop(); - return t; -} - - -// --- -// Calculate timer ticks from milliseconds. -// -static uint16_t ms_to_ticks(uint16_t ms) -{ - uint32_t t = F_CPU / SYS_HWPRESCALE; - t *= ms; - t /= 1000; - return (uint16_t) t; -} - - -// --- -// Processing while waiting for a event. -// -static void background_processing(void) -{ - wdt_reset(); - - // Write data from transmit buffer to USART - while (bit_is_set(UCSRA, UDRE)) - { - uint8_t p = txrpos; - if (p == txwpos) - break; - - UDR = txbuf[p++]; - CHECK_TXBUF_END(p); - txrpos = p; - } -} - - -// --- -// Timer based delay. -// -static void timer_delay(uint16_t d) -{ - uint16_t t = get_sys_clock(); - while ((get_sys_clock() - t) < d) - background_processing(); -} - - -// --- -// Put data into transmit buffer. -// -static void send_data(uint8_t c) -{ - uint8_t p = txwpos + 1; - CHECK_TXBUF_END(p); - - // Wait until space available - while (p == txrpos) - background_processing(); - - txbuf[txwpos] = c; - txwpos = p; - - background_processing(); -} - - -// --- -// Send command request for PWM controller. -// -static void send_request(uint8_t req_type) -{ - // Wait until transmit buffers are empty - while (txrpos != txwpos || bit_is_clear(UCSRA, UDRE)) - background_processing(); - - rxspos = rxwpos - 1; // Reset start reply position - - ++actual_req_id; - actual_req_id &= PWMRQ_ID_MASK; - - set_bit(UCSRB, TXB8); // Set 9th bit for start of request - UDR = req_type | actual_req_id; // Send request type and id unbuffered - clear_bit(UCSRB, TXB8); -} - - -// --- -// Read reply data. -// -static uint8_t read_data(void) -{ - uint8_t p = rxrpos; - uint8_t c = rxbuf[p++]; - CHECK_RXBUF_END(p); - rxrpos = p; - return c; -} - - -// --- -// Wait for reply data from PWM controller. -// -static uint8_t wait_for_reply(void) -{ - uint16_t t = get_sys_clock(); - uint16_t d = reply_timeout; - - while ((get_sys_clock() - t) < d) - { - background_processing(); - - if (rxwpos != rxrpos) - { - if (reply_start == rxspos) // Check for same reply - return 1; - set_bit(reply_err_status, COMM_ERR_START); - return 0; - } - } - - set_bit(reply_err_status, COMM_ERR_TIMEOUT); - return 0; -} - - -// --- -// Wait for start of reply data from PWM controller. -// -static uint8_t wait_for_reply_start(void) -{ - uint16_t t = get_sys_clock(); - uint16_t d = reply_start_timeout; - - while ((get_sys_clock() - t) < d) - { - background_processing(); - - uint8_t p = rxrpos; - if (rxwpos != p) - { - if (rxspos == p) - { // reply start detected - uint8_t id = read_data(); - if (id == PWMRP_KEEP_ALIVE) - { // keep alive reply - t = get_sys_clock(); - continue; - } - if ((id & PWMRQ_ID_MASK) == actual_req_id) - { // reply is for actual request - reply_start = p; - if (!(id & PWMRP_HAS_PAYLOAD)) - { - reply_count = 0; - return 1; - } - if (wait_for_reply()) - { - reply_count = read_data(); - return 1; - } - return 0; - } - } - // drop garbagge - ++p; - CHECK_RXBUF_END(p); - rxrpos = p; - } - - if (bit_is_clear(UCSRA, TXC)) - t = get_sys_clock(); - } - - set_bit(reply_err_status, COMM_ERR_TIMEOUT); - return 0; -} - - -// --- -// Stop PWM controller. -// -static void stop_pwm_ctrl(void) -{ - clear_bit(UCSRB, RXEN); // Disable USART RX - clear_bit(RESET_PORT, RESET_BIT); -} - - -// --- -// Reset PWM controller. -// -static void reset_pwm_ctrl(void) -{ - stop_pwm_ctrl(); - timer_delay(RESET_TIME); - - set_bit(RESET_PORT, RESET_BIT); - timer_delay(STARTUP_TIME); - - rxwpos = rxrpos = 0; // Flush reply buffer - reply_err_status = 0; - - set_bit(UCSRB, RXEN); // Enable USART RX -} - - -// --- -// Send PWM controller request payload data. -// -static uint8_t send_payload_data(uint8_t *data, uint8_t len) -{ - if(len > payload_count) - len = payload_count; - payload_count -= len; - - uint8_t i = 0; - while (i < len) - send_data(data[i++]); - - if (!payload_count) - { - if (wait_for_reply_start()) // Wait for ACK - return 1; // all done successfull - return USB_STALL_RC; // error happen - } - - return 0; // next packet -} - - -// --- -// Read PWM controller request payload data. -// -static uint8_t read_payload_data(uint8_t *data, uint8_t len) -{ - if (len > reply_count) - len = reply_count; - if(len > payload_count) - len = payload_count; - reply_count -= len; - payload_count -= len; - - uint8_t i = 0; - while (i < len && wait_for_reply()) - data[i++] = read_data(); - - if (i < len) - return USB_STALL_RC; // error happen - - return i; -} - - -// --- -// Write EE prom data. -// -static uint8_t write_ee_data(uint8_t *data, uint8_t len) -{ - if(len > payload_count) - len = payload_count; - payload_count -= len; - - uint8_t i = 0; - while (i < len && payload_pos < EE_MEM_SIZE) - { - uint8_t old_data = eeprom_read_byte((uint8_t *)payload_pos); - uint8_t new_data = data[i]; - if (old_data != new_data) - { - eeprom_write_byte((uint8_t *)payload_pos, new_data); - - while (!eeprom_is_ready()) - background_processing(); - - old_data = eeprom_read_byte((uint8_t *)payload_pos); - if (old_data != new_data) - return USB_STALL_RC; // write error - } - ++i; - ++payload_pos; - } - - return payload_count == 0; -} - - -// --- -// Read EE prom data. -// -static uint8_t read_ee_data(uint8_t *data, uint8_t len) -{ - if(len > payload_count) - len = payload_count; - payload_count -= len; - - uint8_t i = 0; - while (i < len && payload_pos < EE_MEM_SIZE) - { - data[i] = eeprom_read_byte((uint8_t *)payload_pos); - ++i; - ++payload_pos; - } - - return i; -} - - -// --- -// Write request payload data. -// -USB_PUBLIC uint8_t usbFunctionWrite(uint8_t *data, uint8_t len) -{ - uint8_t rc = USB_STALL_RC; - - if (usb_last_rc != USB_STALL_RC) - { - if (len != 8 || usbCrc16(data, 8) == ((uint16_t *)data)[4]) - { - if (usbCurrentDataToken == usb_last_data_token) - { - set_bit(reply_err_status, COMM_ERR_DUPLICATE); - return usb_last_rc; // Ignore packet - } - - if (payload_req >= REQ_PWM_START) - rc = send_payload_data(data, len); - else if (payload_req == REQ_WRITE_EE_DATA) - rc = write_ee_data(data, len); - } - else - set_bit(reply_err_status, COMM_ERR_CRC); - } - - usb_last_data_token = usbCurrentDataToken; - usb_last_rc = rc; - - return rc; -} - - -// --- -// Read request payload data. -// -USB_PUBLIC uint8_t usbFunctionRead(uint8_t *data, uint8_t len) -{ - uint8_t rc = USB_STALL_RC; - - if (usb_last_rc != USB_STALL_RC) - { - if (payload_req >= REQ_PWM_START) - rc = read_payload_data(data, len); - else if (payload_req == REQ_READ_EE_DATA) - rc = read_ee_data(data, len); - } - - usb_last_rc = rc; - - return rc; -} - - -// --- -// Handle a non-standard USB SETUP packet. -// -USB_PUBLIC usbMsgLen_t usbFunctionSetup(uint8_t data[8]) -{ - usbRequest_t *r = (usbRequest_t *) data; - static uint8_t reply[1]; - - usb_last_data_token = USBPID_SETUP; - usb_last_rc = USB_STALL_RC; - uint8_t rc = USB_NO_MSG; - - if (usbCrc16(data, 8) != ((uint16_t *)data)[4]) - { - set_bit(reply_err_status, COMM_ERR_CRC); - return rc; - } - - uint8_t req = r->bRequest; - - if (req >= REQ_PWM_START) - { - if (bit_is_clear (RESET_PORT, RESET_BIT)) - reset_pwm_ctrl(); - - uint8_t req_type = (r->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST ? PWMRQ_DEVICE_TO_HOST: 0; - if (r->wLength.word <= MAX_REQ_PAYLOAD_SIZE) - { - send_request(req_type); - send_data(req); - send_data(r->wValue.bytes[0]); - send_data(r->wValue.bytes[1]); - send_data(r->wIndex.bytes[0]); - send_data(r->wIndex.bytes[1]); - send_data(r->wLength.bytes[0]); - send_data(r->wLength.bytes[1]); - - payload_req = req; - payload_count = r->wLength.word; - - if (req_type == PWMRQ_DEVICE_TO_HOST || !r->wLength.word) - { - if (wait_for_reply_start()) - { - if (reply_count && r->wLength.word) - usb_last_rc = 0; - else - rc = 0; - } - } - else - usb_last_rc = 0; - } - } - else if (req == REQ_READ_EE_DATA || req == REQ_WRITE_EE_DATA) - { - if (r->wLength.word) - { - payload_pos = r->wIndex.word; - payload_req = req; - payload_count = r->wLength.word; - usb_last_rc = 0; - } - else - rc = 0; - } - else if (req == REQ_STOP_PWM_CTRL) - { - set_bit(BOOTLOADER_PORT, BOOTLOADER_BIT); - stop_pwm_ctrl(); - rc = 0; - } - else if (req == REQ_RESET_PWM_CTRL) - { - set_bit(BOOTLOADER_PORT, BOOTLOADER_BIT); - reset_pwm_ctrl(); - rc = 0; - } - else if (req == REQ_BOOTLOADER_RESET_PWM_CTRL) - { - clear_bit(BOOTLOADER_PORT, BOOTLOADER_BIT); - reset_pwm_ctrl(); - rc = 0; - } - else if (req == REQ_GET_REPLY_ERR_STATUS) - { - reply[0] = reply_err_status; - reply_err_status = 0; - usbMsgPtr = reply; - rc = 1; - } - else if (req == REQ_SET_REPLY_TIMEOUT) - { - reply_start_timeout = ms_to_ticks(r->wValue.word); - reply_timeout = ms_to_ticks(r->wIndex.word); - rc = 0; - } - else if (req == REQ_START_BOOTLOADER) - { - bl_start = 1; - bl_time = get_sys_clock(); - rc = 0; - } - - return rc; -} - - -// ---- -// Main -// -void main(void) NORETURN; -void main(void) -{ - wdt_enable(WDTO_120MS); // Set watchdog timeout - - // Initialize Ports - PORTB = PORTB_INIT; - DDRB = DDRB_INIT; - PORTC = PORTC_INIT; - DDRC = DDRC_INIT; - PORTD = PORTD_INIT; - DDRD = DDRD_INIT; - - usbDeviceDisconnect(); - - set_bit(ACSR, ACD); // Disable analog comparator saving some power - - // Initialize Timer 1 - TCNT1 = 0; - TCCR1B = _BV(CS12) | _BV(CS10); // Start timer 1, Prescaler 1024 - - // Initialize USART -#include - UBRRH = UBRRH_VALUE; - UBRRL = UBRRL_VALUE; -#if USE_2X - UCSRA = _BV(U2X); -#endif - UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // 9 data bits, 1 stop bit, no parity, asynchron mode - UCSRB = _BV(TXEN) | _BV(UCSZ2) | _BV(RXCIE); // Enable TX and RX IRQ - - reset_pwm_ctrl(); - - timer_delay(USB_DISCONNECT_TIME); - usbDeviceConnect(); - usbInit(); - - sei(); - - // Main loop - for (;;) - { - background_processing(); - - usbPoll(); // process USB requests - - if ((bit_is_clear(BL_SENSE_PIN, BL_SENSE_BIT) || - (bl_start && (get_sys_clock() - bl_time) > BL_START_DELAY_TIME)) && - pgm_read_word(BL_START_VECT) != 0xFFFF) - { - cli(); - stop_pwm_ctrl(); - clear_bit(USB_INTR_ENABLE, USB_INTR_ENABLE_BIT); // Stop USB - UCSRB = 0; // Stop USART - TCCR1B = 0; // Stop Timer - - // enable boot loader by setting sense pin to 0 - clear_bit(BL_SENSE_PORT, BL_SENSE_BIT); - set_bit(BL_SENSE_DDR, BL_SENSE_BIT); - - // start bootloader - void (*jump_to_bl)(void) = BL_START_VECT / 2; // Need flash word address for jump! - jump_to_bl(); - } - - -#if 0 - if (!usb_is_initialized && get_sys_clock() > USB_INITIALIZE_TIMEOUT) - { // request USB device enumeration - cli(); - usb_is_initialized = 1; - usbDeviceDisconnect(); - timer_delay(USB_DISCONNECT_TIME); - usbDeviceConnect(); - usbInit(); - sei(); - } -#endif - - // Check for standby state - if (usb_is_resetting) - { // ongoing USB reset -> reset activity timeout - cli(); - usb_sof_time = TCNT1; - sei(); - } - else - { - cli(); - uint16_t t = usb_sof_time; - sei(); - if ((get_sys_clock() - t) > USB_SLEEP_TIMEOUT) - { // no USB activity -> go sleeping - cli(); - stop_pwm_ctrl(); - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - USB_INTR_CFG &= ~USB_INTR_CFG_SET; // set low level triggered IRQ for wakeup - USB_INTR_PENDING = _BV(USB_INTR_PENDING_BIT); // reset pending IRQ - wdt_disable(); - sleep_enable(); - sei(); - sleep_cpu(); - sleep_disable(); - wdt_enable(WDTO_30MS); - cli(); - TCNT1 = 0; - usb_sof_time = 0; - sei(); - reset_pwm_ctrl(); - } - } - } -} diff --git a/usb_appl/Makefile b/usb_appl/Makefile index 03ca6d8..97fad42 100644 --- a/usb_appl/Makefile +++ b/usb_appl/Makefile @@ -1,109 +1,109 @@ -# -# Copyright (C) 2010 Andreas Auras -# -# This file is part of the DF10CH Atmolight controller project. -# -# DF10CH Atmolight controller 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. -# -# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -# -# -############################################################################### -# Makefile for the application firmware of USB processor -############################################################################### - -## General Flags -PROJECT = 10ch_usb_appl -MCU = atmega8 -TARGET = 10ch_usb_appl.elf -CC = avr-gcc -AVRDUDE ?= avrdude -c stk500v2 -P avrdoper -USBDRV ?= ../usbdrv -F_CPU ?= 16000000UL -FIRMWARE_VERSION ?= 1 - -## Options common to compile, link and assembly rules -COMMON = -mmcu=$(MCU) - -## Compile options common for all C compilation units. -CFLAGS = $(COMMON) -CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) - -## Assembly specific flags -ASMFLAGS = $(COMMON) -ASMFLAGS += $(CFLAGS) -ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 - -## Linker flags -LDFLAGS = $(COMMON) -LDFLAGS += -Wl,-Map=10ch_usb_appl.map - - -## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature - -HEX_EEPROM_FLAGS = -j .eeprom -HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" - -## Include Directories -INCLUDES = -I. -I.. -I$(USBDRV) - -## Objects that must be built in order to link -OBJECTS = 10ch_usb_appl.o usbdrvasm.o - -## Objects explicitly added by the user -LINKONLYOBJECTS = - -## Build -all: $(TARGET) 10ch_usb_appl.dff 10ch_usb_appl.lss size - -10ch_usb_appl.dff: 10ch_usb_appl.hex - echo "@DF10CH-USB" $(FIRMWARE_VERSION) > $@ - cat 10ch_usb_appl.hex >> $@ - -prog: flash - $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0x1F:m -Uhfuse:w:0xC9:m -Ulock:w:0xEF:m - -flash: 10ch_usb_appl.hex - $(AVRDUDE) -p $(MCU) -Uflash:w:10ch_usb_appl.hex:i - - -## Compile -usbdrvasm.o: $(USBDRV)/usbdrvasm.S usbconfig.h - $(CC) $(INCLUDES) $(ASMFLAGS) -c $< - -10ch_usb_appl.o: 10ch_usb_appl.c usbconfig.h ../df10ch_usb_proto.h ../df10ch_common.h - $(CC) $(INCLUDES) $(CFLAGS) -c $< - -##Link -$(TARGET): $(OBJECTS) - $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) - -%.hex: $(TARGET) - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -%.eep: $(TARGET) - -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 - -%.lss: $(TARGET) - avr-objdump -h -S $< > $@ - -size: ${TARGET} - @echo - @avr-size -C --mcu=${MCU} ${TARGET} - -## Clean target -.PHONY: clean -clean: - -rm -rf $(OBJECTS) 10ch_usb_appl.elf 10ch_usb_appl.dff 10ch_usb_appl.hex 10ch_usb_appl.eep 10ch_usb_appl.lss 10ch_usb_appl.map +# +# Copyright (C) 2010 Andreas Auras +# +# This file is part of the DF10CH Atmolight controller project. +# +# DF10CH Atmolight controller 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. +# +# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +# +# +############################################################################### +# Makefile for the application firmware of USB processor +############################################################################### + +## General Flags +PROJECT = df10ch_usb_appl +MCU = atmega8 +TARGET = df10ch_usb_appl.elf +CC = avr-gcc +AVRDUDE ?= avrdude -c stk500v2 -P avrdoper +USBDRV ?= ../usbdrv +F_CPU ?= 16000000UL +FIRMWARE_VERSION ?= 1 + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-Map=df10ch_usb_appl.map + + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" + +## Include Directories +INCLUDES = -I. -I.. -I$(USBDRV) + +## Objects that must be built in order to link +OBJECTS = df10ch_usb_appl.o usbdrvasm.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET) df10ch_usb_appl.dff df10ch_usb_appl.lss size + +df10ch_usb_appl.dff: df10ch_usb_appl.hex + echo "@DF10CH-USB" $(FIRMWARE_VERSION) > $@ + cat df10ch_usb_appl.hex >> $@ + +prog: flash + $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0x1F:m -Uhfuse:w:0xC9:m -Ulock:w:0xEF:m + +flash: df10ch_usb_appl.hex + $(AVRDUDE) -p $(MCU) -Uflash:w:df10ch_usb_appl.hex:i + + +## Compile +usbdrvasm.o: $(USBDRV)/usbdrvasm.S usbconfig.h + $(CC) $(INCLUDES) $(ASMFLAGS) -c $< + +df10ch_usb_appl.o: df10ch_usb_appl.c usbconfig.h ../df10ch_usb_proto.h ../df10ch_common.h + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) + +%.hex: $(TARGET) + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET) + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET) + avr-objdump -h -S $< > $@ + +size: ${TARGET} + @echo + @avr-size -C --mcu=${MCU} ${TARGET} + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) df10ch_usb_appl.elf df10ch_usb_appl.dff df10ch_usb_appl.hex df10ch_usb_appl.eep df10ch_usb_appl.lss df10ch_usb_appl.map diff --git a/usb_appl/df10ch_usb_appl.c b/usb_appl/df10ch_usb_appl.c new file mode 100644 index 0000000..ba0d2c8 --- /dev/null +++ b/usb_appl/df10ch_usb_appl.c @@ -0,0 +1,838 @@ +/* + * Copyright (C) 2010 Andreas Auras + * + * This file is part of the DF10CH Atmolight controller project. + * + * DF10CH Atmolight controller 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. + * + * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +// ====================================================================== +// Application firmware for USB processor. +// + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../df10ch_common.h" +#include "../df10ch_usb_proto.h" +#include "usbconfig.h" + + +// --- +// Fuse-Bit settings for the flash programmer (ATmega8): +// RSTDISBL=1 +// WDTON=1 +// SPIEN=0 +// CKOPT=0 +// EESAVE=1 +// BOOTSZ1=0 +// BOOTSZ0=0 +// BOOTRST=1 +// +// BODLEVEL=0 +// BODEN=0 +// SUT1=0 +// SUT0=1 +// CKSEL3=1 +// CKSEL2=1 +// CKSEL1=1 +// CKSEL0=1 +// +// Memory-Lock Bits: +// BL12=1, BL11=0, BL02=1, BL01=1, LB2=1, LB1=1 +// +FUSES = +{ + .low = (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT1), + .high = (FUSE_SPIEN & FUSE_CKOPT & FUSE_BOOTSZ1 & FUSE_BOOTSZ0) +}; +LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); +//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; + + +#define EE_MEM_SIZE (E2END + 1) + + +// --- +// System clock related. +// System clock ist implemented with hardware timer 1 +// +#define SYS_HWPRESCALE 1024 // Hardware Prescaler + + // useconds <-> timer ticks conversation +#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE) + 0.5)) +#define TICKS2US(t) ((uint16_t)((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE)))) + + +// --- +// pwm controller reset related. +// +#define RESET_TIME US2TICKS(128UL) +#define STARTUP_TIME US2TICKS(10000UL) + + // Output pin for PWM controller reset +#define RESET_PORT PORTB +#define RESET_BIT 4 + + // Output pin for enabling PWM controller bootloader +#define BOOTLOADER_PORT PORTB +#define BOOTLOADER_BIT 3 + + +// --- +// bootloader related. +// +#define BL_START_VECT 0x1800 + +// Input/Output pin for bootloader startup +#define BL_SENSE_DDR DDRB +#define BL_SENSE_PORT PORTB +#define BL_SENSE_PIN PINB +#define BL_SENSE_BIT 0 + +#define BL_START_DELAY_TIME US2TICKS(30000UL) + +static uint8_t bl_start; +static uint16_t bl_time; + + +// --- +// USB related. +// +#define USB_SLEEP_TIMEOUT US2TICKS(5000UL) +#define USB_DISCONNECT_TIME US2TICKS(500000UL) +#define USB_INITIALIZE_TIMEOUT US2TICKS(1750000UL) +#define USB_STALL_RC 0xFF + +volatile uint16_t usb_sof_time; // Time of last USB start of frame IRQ +static uint8_t usb_is_resetting; // Is true while reset condition on USB bus happen +static uint8_t usb_is_initialized; // Is true after USB address has been set +static uint8_t usb_last_data_token; // Token PID of last usb packet received +static uint8_t usb_last_rc; // Return status of last payload packet +static uint8_t payload_req; // ID of actual proccessed USB request +static uint16_t payload_pos; // Position of actual payload read/write +static uint16_t payload_count; // Number of bytes left of actual payload read/write + + + +// --- +// RX buffer related. +// +#define RXBUF_SIZE 256 +#if RXBUF_SIZE == 256 +#define CHECK_RXBUF_END(pos) +#else +#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0 +#endif + +static volatile uint8_t rxrpos, rxwpos; +static volatile uint8_t rxspos; // Start position of reply +static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT; + + +// --- +// TX buffer related. +// +#define TXBUF_SIZE 256 +#if TXBUF_SIZE == 256 +#define CHECK_TXBUF_END(pos) +#else +#define CHECK_TXBUF_END(pos) if ((pos) == TXBUF_SIZE) (pos) = 0 +#endif + +static uint8_t txrpos, txwpos; +static uint8_t txbuf[TXBUF_SIZE] NOMEMINIT; + + +// --- +// PWM controller communication related. +// +#define REPLY_START_TIMEOUT US2TICKS(50000UL) +#define REPLY_TIMEOUT US2TICKS(10000UL) + +static uint8_t actual_req_id; +static uint8_t reply_start; +static uint8_t reply_count; +static volatile uint8_t reply_err_status; +static uint16_t reply_start_timeout = REPLY_START_TIMEOUT; +static uint16_t reply_timeout = REPLY_TIMEOUT; + + +// --- +// Port setup related. +// +#define PORTB_INIT (_BV(BL_SENSE_BIT) | _BV(BOOTLOADER_BIT) | _BV(1) | _BV(2) | _BV(5)) +#define DDRB_INIT (_BV(BOOTLOADER_BIT) | _BV(RESET_BIT)) + +#define PORTC_INIT (0xFF) +#define DDRC_INIT (0) + +#define PORTD_INIT (_BV(1) | _BV(5) | _BV(6) | _BV(7)) +#define DDRD_INIT (_BV(1)) + + +#include + + +// --- +// ISR handler for IRQ's that do not have a dedicated handler. +// +ISR(BADISR_vect) +{ + for (;;); // wait until watchdog resets device +} + + +// --- +// ISR for receiving data. +// +ISR(USART_RXC_vect) +{ + clear_bit(UCSRB, RXCIE); + sei(); + + do + { + uint8_t i = rxwpos; + uint8_t p = i + 1; + CHECK_RXBUF_END(p); + + if (bit_is_set(UCSRA, DOR)) + set_bit(reply_err_status, COMM_ERR_OVERRUN); + else if (bit_is_set(UCSRA, FE)) + set_bit(reply_err_status, COMM_ERR_FRAME); + else if (p == rxrpos) + set_bit(reply_err_status, COMM_ERR_OVERFLOW); + else + { + if (bit_is_set(UCSRB, RXB8)) + rxspos = i; // save reply start position + rxwpos = p; // set data valid + } + rxbuf[i] = UDR; // read data + } + while (bit_is_set(UCSRA, RXC)); + + cli(); + set_bit(UCSRB, RXCIE); +} + + +// --- +// Read actual system clock counter. +// Note: Counter is also read inside USB irq handler -> we need save read! +// +static uint16_t get_sys_clock(void) +{ + uint8_t sreg = SREG; + cli(); + uint16_t t = TCNT1; + SREG = sreg; + nop(); + return t; +} + + +// --- +// Calculate timer ticks from milliseconds. +// +static uint16_t ms_to_ticks(uint16_t ms) +{ + uint32_t t = F_CPU / SYS_HWPRESCALE; + t *= ms; + t /= 1000; + return (uint16_t) t; +} + + +// --- +// Processing while waiting for a event. +// +static void background_processing(void) +{ + wdt_reset(); + + // Write data from transmit buffer to USART + while (bit_is_set(UCSRA, UDRE)) + { + uint8_t p = txrpos; + if (p == txwpos) + break; + + UDR = txbuf[p++]; + CHECK_TXBUF_END(p); + txrpos = p; + } +} + + +// --- +// Timer based delay. +// +static void timer_delay(uint16_t d) +{ + uint16_t t = get_sys_clock(); + while ((get_sys_clock() - t) < d) + background_processing(); +} + + +// --- +// Put data into transmit buffer. +// +static void send_data(uint8_t c) +{ + uint8_t p = txwpos + 1; + CHECK_TXBUF_END(p); + + // Wait until space available + while (p == txrpos) + background_processing(); + + txbuf[txwpos] = c; + txwpos = p; + + background_processing(); +} + + +// --- +// Send command request for PWM controller. +// +static void send_request(uint8_t req_type) +{ + // Wait until transmit buffers are empty + while (txrpos != txwpos || bit_is_clear(UCSRA, UDRE)) + background_processing(); + + rxspos = rxwpos - 1; // Reset start reply position + + ++actual_req_id; + actual_req_id &= PWMRQ_ID_MASK; + + set_bit(UCSRB, TXB8); // Set 9th bit for start of request + UDR = req_type | actual_req_id; // Send request type and id unbuffered + clear_bit(UCSRB, TXB8); +} + + +// --- +// Read reply data. +// +static uint8_t read_data(void) +{ + uint8_t p = rxrpos; + uint8_t c = rxbuf[p++]; + CHECK_RXBUF_END(p); + rxrpos = p; + return c; +} + + +// --- +// Wait for reply data from PWM controller. +// +static uint8_t wait_for_reply(void) +{ + uint16_t t = get_sys_clock(); + uint16_t d = reply_timeout; + + while ((get_sys_clock() - t) < d) + { + background_processing(); + + if (rxwpos != rxrpos) + { + if (reply_start == rxspos) // Check for same reply + return 1; + set_bit(reply_err_status, COMM_ERR_START); + return 0; + } + } + + set_bit(reply_err_status, COMM_ERR_TIMEOUT); + return 0; +} + + +// --- +// Wait for start of reply data from PWM controller. +// +static uint8_t wait_for_reply_start(void) +{ + uint16_t t = get_sys_clock(); + uint16_t d = reply_start_timeout; + + while ((get_sys_clock() - t) < d) + { + background_processing(); + + uint8_t p = rxrpos; + if (rxwpos != p) + { + if (rxspos == p) + { // reply start detected + uint8_t id = read_data(); + if (id == PWMRP_KEEP_ALIVE) + { // keep alive reply + t = get_sys_clock(); + continue; + } + if ((id & PWMRQ_ID_MASK) == actual_req_id) + { // reply is for actual request + reply_start = p; + if (!(id & PWMRP_HAS_PAYLOAD)) + { + reply_count = 0; + return 1; + } + if (wait_for_reply()) + { + reply_count = read_data(); + return 1; + } + return 0; + } + } + // drop garbagge + ++p; + CHECK_RXBUF_END(p); + rxrpos = p; + } + + if (bit_is_clear(UCSRA, TXC)) + t = get_sys_clock(); + } + + set_bit(reply_err_status, COMM_ERR_TIMEOUT); + return 0; +} + + +// --- +// Stop PWM controller. +// +static void stop_pwm_ctrl(void) +{ + clear_bit(UCSRB, RXEN); // Disable USART RX + clear_bit(RESET_PORT, RESET_BIT); +} + + +// --- +// Reset PWM controller. +// +static void reset_pwm_ctrl(void) +{ + stop_pwm_ctrl(); + timer_delay(RESET_TIME); + + set_bit(RESET_PORT, RESET_BIT); + timer_delay(STARTUP_TIME); + + rxwpos = rxrpos = 0; // Flush reply buffer + reply_err_status = 0; + + set_bit(UCSRB, RXEN); // Enable USART RX +} + + +// --- +// Send PWM controller request payload data. +// +static uint8_t send_payload_data(uint8_t *data, uint8_t len) +{ + if(len > payload_count) + len = payload_count; + payload_count -= len; + + uint8_t i = 0; + while (i < len) + send_data(data[i++]); + + if (!payload_count) + { + if (wait_for_reply_start()) // Wait for ACK + return 1; // all done successfull + return USB_STALL_RC; // error happen + } + + return 0; // next packet +} + + +// --- +// Read PWM controller request payload data. +// +static uint8_t read_payload_data(uint8_t *data, uint8_t len) +{ + if (len > reply_count) + len = reply_count; + if(len > payload_count) + len = payload_count; + reply_count -= len; + payload_count -= len; + + uint8_t i = 0; + while (i < len && wait_for_reply()) + data[i++] = read_data(); + + if (i < len) + return USB_STALL_RC; // error happen + + return i; +} + + +// --- +// Write EE prom data. +// +static uint8_t write_ee_data(uint8_t *data, uint8_t len) +{ + if(len > payload_count) + len = payload_count; + payload_count -= len; + + uint8_t i = 0; + while (i < len && payload_pos < EE_MEM_SIZE) + { + uint8_t old_data = eeprom_read_byte((uint8_t *)payload_pos); + uint8_t new_data = data[i]; + if (old_data != new_data) + { + eeprom_write_byte((uint8_t *)payload_pos, new_data); + + while (!eeprom_is_ready()) + background_processing(); + + old_data = eeprom_read_byte((uint8_t *)payload_pos); + if (old_data != new_data) + return USB_STALL_RC; // write error + } + ++i; + ++payload_pos; + } + + return payload_count == 0; +} + + +// --- +// Read EE prom data. +// +static uint8_t read_ee_data(uint8_t *data, uint8_t len) +{ + if(len > payload_count) + len = payload_count; + payload_count -= len; + + uint8_t i = 0; + while (i < len && payload_pos < EE_MEM_SIZE) + { + data[i] = eeprom_read_byte((uint8_t *)payload_pos); + ++i; + ++payload_pos; + } + + return i; +} + + +// --- +// Write request payload data. +// +USB_PUBLIC uint8_t usbFunctionWrite(uint8_t *data, uint8_t len) +{ + uint8_t rc = USB_STALL_RC; + + if (usb_last_rc != USB_STALL_RC) + { + if (len != 8 || usbCrc16(data, 8) == ((uint16_t *)data)[4]) + { + if (usbCurrentDataToken == usb_last_data_token) + { + set_bit(reply_err_status, COMM_ERR_DUPLICATE); + return usb_last_rc; // Ignore packet + } + + if (payload_req >= REQ_PWM_START) + rc = send_payload_data(data, len); + else if (payload_req == REQ_WRITE_EE_DATA) + rc = write_ee_data(data, len); + } + else + set_bit(reply_err_status, COMM_ERR_CRC); + } + + usb_last_data_token = usbCurrentDataToken; + usb_last_rc = rc; + + return rc; +} + + +// --- +// Read request payload data. +// +USB_PUBLIC uint8_t usbFunctionRead(uint8_t *data, uint8_t len) +{ + uint8_t rc = USB_STALL_RC; + + if (usb_last_rc != USB_STALL_RC) + { + if (payload_req >= REQ_PWM_START) + rc = read_payload_data(data, len); + else if (payload_req == REQ_READ_EE_DATA) + rc = read_ee_data(data, len); + } + + usb_last_rc = rc; + + return rc; +} + + +// --- +// Handle a non-standard USB SETUP packet. +// +USB_PUBLIC usbMsgLen_t usbFunctionSetup(uint8_t data[8]) +{ + usbRequest_t *r = (usbRequest_t *) data; + static uint8_t reply[1]; + + usb_last_data_token = USBPID_SETUP; + usb_last_rc = USB_STALL_RC; + uint8_t rc = USB_NO_MSG; + + if (usbCrc16(data, 8) != ((uint16_t *)data)[4]) + { + set_bit(reply_err_status, COMM_ERR_CRC); + return rc; + } + + uint8_t req = r->bRequest; + + if (req >= REQ_PWM_START) + { + if (bit_is_clear (RESET_PORT, RESET_BIT)) + reset_pwm_ctrl(); + + uint8_t req_type = (r->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST ? PWMRQ_DEVICE_TO_HOST: 0; + if (r->wLength.word <= MAX_REQ_PAYLOAD_SIZE) + { + send_request(req_type); + send_data(req); + send_data(r->wValue.bytes[0]); + send_data(r->wValue.bytes[1]); + send_data(r->wIndex.bytes[0]); + send_data(r->wIndex.bytes[1]); + send_data(r->wLength.bytes[0]); + send_data(r->wLength.bytes[1]); + + payload_req = req; + payload_count = r->wLength.word; + + if (req_type == PWMRQ_DEVICE_TO_HOST || !r->wLength.word) + { + if (wait_for_reply_start()) + { + if (reply_count && r->wLength.word) + usb_last_rc = 0; + else + rc = 0; + } + } + else + usb_last_rc = 0; + } + } + else if (req == REQ_READ_EE_DATA || req == REQ_WRITE_EE_DATA) + { + if (r->wLength.word) + { + payload_pos = r->wIndex.word; + payload_req = req; + payload_count = r->wLength.word; + usb_last_rc = 0; + } + else + rc = 0; + } + else if (req == REQ_STOP_PWM_CTRL) + { + set_bit(BOOTLOADER_PORT, BOOTLOADER_BIT); + stop_pwm_ctrl(); + rc = 0; + } + else if (req == REQ_RESET_PWM_CTRL) + { + set_bit(BOOTLOADER_PORT, BOOTLOADER_BIT); + reset_pwm_ctrl(); + rc = 0; + } + else if (req == REQ_BOOTLOADER_RESET_PWM_CTRL) + { + clear_bit(BOOTLOADER_PORT, BOOTLOADER_BIT); + reset_pwm_ctrl(); + rc = 0; + } + else if (req == REQ_GET_REPLY_ERR_STATUS) + { + reply[0] = reply_err_status; + reply_err_status = 0; + usbMsgPtr = reply; + rc = 1; + } + else if (req == REQ_SET_REPLY_TIMEOUT) + { + reply_start_timeout = ms_to_ticks(r->wValue.word); + reply_timeout = ms_to_ticks(r->wIndex.word); + rc = 0; + } + else if (req == REQ_START_BOOTLOADER) + { + bl_start = 1; + bl_time = get_sys_clock(); + rc = 0; + } + + return rc; +} + + +// ---- +// Main +// +void main(void) NORETURN; +void main(void) +{ + wdt_enable(WDTO_120MS); // Set watchdog timeout + + // Initialize Ports + PORTB = PORTB_INIT; + DDRB = DDRB_INIT; + PORTC = PORTC_INIT; + DDRC = DDRC_INIT; + PORTD = PORTD_INIT; + DDRD = DDRD_INIT; + + usbDeviceDisconnect(); + + set_bit(ACSR, ACD); // Disable analog comparator saving some power + + // Initialize Timer 1 + TCNT1 = 0; + TCCR1B = _BV(CS12) | _BV(CS10); // Start timer 1, Prescaler 1024 + + // Initialize USART +#include + UBRRH = UBRRH_VALUE; + UBRRL = UBRRL_VALUE; +#if USE_2X + UCSRA = _BV(U2X); +#endif + UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // 9 data bits, 1 stop bit, no parity, asynchron mode + UCSRB = _BV(TXEN) | _BV(UCSZ2) | _BV(RXCIE); // Enable TX and RX IRQ + + reset_pwm_ctrl(); + + timer_delay(USB_DISCONNECT_TIME); + usbDeviceConnect(); + usbInit(); + + sei(); + + // Main loop + for (;;) + { + background_processing(); + + usbPoll(); // process USB requests + + if ((bit_is_clear(BL_SENSE_PIN, BL_SENSE_BIT) || + (bl_start && (get_sys_clock() - bl_time) > BL_START_DELAY_TIME)) && + pgm_read_word(BL_START_VECT) != 0xFFFF) + { + cli(); + stop_pwm_ctrl(); + clear_bit(USB_INTR_ENABLE, USB_INTR_ENABLE_BIT); // Stop USB + UCSRB = 0; // Stop USART + TCCR1B = 0; // Stop Timer + + // enable boot loader by setting sense pin to 0 + clear_bit(BL_SENSE_PORT, BL_SENSE_BIT); + set_bit(BL_SENSE_DDR, BL_SENSE_BIT); + + // start bootloader + void (*jump_to_bl)(void) = BL_START_VECT / 2; // Need flash word address for jump! + jump_to_bl(); + } + + +#if 0 + if (!usb_is_initialized && get_sys_clock() > USB_INITIALIZE_TIMEOUT) + { // request USB device enumeration + cli(); + usb_is_initialized = 1; + usbDeviceDisconnect(); + timer_delay(USB_DISCONNECT_TIME); + usbDeviceConnect(); + usbInit(); + sei(); + } +#endif + + // Check for standby state + if (usb_is_resetting) + { // ongoing USB reset -> reset activity timeout + cli(); + usb_sof_time = TCNT1; + sei(); + } + else + { + cli(); + uint16_t t = usb_sof_time; + sei(); + if ((get_sys_clock() - t) > USB_SLEEP_TIMEOUT) + { // no USB activity -> go sleeping + cli(); + stop_pwm_ctrl(); + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + USB_INTR_CFG &= ~USB_INTR_CFG_SET; // set low level triggered IRQ for wakeup + USB_INTR_PENDING = _BV(USB_INTR_PENDING_BIT); // reset pending IRQ + wdt_disable(); + sleep_enable(); + sei(); + sleep_cpu(); + sleep_disable(); + wdt_enable(WDTO_30MS); + cli(); + TCNT1 = 0; + usb_sof_time = 0; + sei(); + reset_pwm_ctrl(); + } + } + } +} diff --git a/usb_appl/usbconfig.h b/usb_appl/usbconfig.h index 0744d16..0d5e4af 100644 --- a/usb_appl/usbconfig.h +++ b/usb_appl/usbconfig.h @@ -183,18 +183,18 @@ section at the end of this file). * Please note that Start Of Frame detection works only if D- is wired to the * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! */ - -/* Save timestamp of sof */ -#ifdef __ASSEMBLER__ -macro customSofHook +/* Save timestamp of sof */ + +#ifdef __ASSEMBLER__ +macro customSofHook in YL, TCNT1L sts usb_sof_time, YL in YL, TCNT1H sts usb_sof_time+1, YL endm #endif - + #define USB_CFG_CHECK_DATA_TOGGLING 1 /* define this macro to 1 if you want to filter out duplicate data packets * sent by the host. Duplicates occur only as a consequence of communication @@ -207,15 +207,15 @@ endm /* define this macro to 1 if you want the function usbMeasureFrameLength() * compiled in. This function can be used to calibrate the AVR's RC oscillator. */ -#define USB_USE_FAST_CRC 1 -/* The assembler module has two implementations for the CRC algorithm. One is - * faster, the other is smaller. This CRC routine is only used for transmitted - * messages where timing is not critical. The faster routine needs 31 cycles - * per byte while the smaller one needs 61 to 69 cycles. The faster routine - * may be worth the 32 bytes bigger code size if you transmit lots of data and - * run the AVR close to its limit. - */ - +#define USB_USE_FAST_CRC 1 +/* The assembler module has two implementations for the CRC algorithm. One is + * faster, the other is smaller. This CRC routine is only used for transmitted + * messages where timing is not critical. The faster routine needs 31 cycles + * per byte while the smaller one needs 61 to 69 cycles. The faster routine + * may be worth the 32 bytes bigger code size if you transmit lots of data and + * run the AVR close to its limit. + */ + /* -------------------------- Device Description --------------------------- */ #define USB_CFG_VENDOR_ID 0xc0, 0x16 @@ -361,9 +361,9 @@ endm */ #define USB_INTR_CFG MCUCR #if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK) -#define USB_INTR_CFG_SET ((1 << ISC11)) +#define USB_INTR_CFG_SET ((1 << ISC11)) #else -#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11)) +#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11)) #endif /* #define USB_INTR_CFG_CLR 0 */ /* #define USB_INTR_ENABLE GIMSK */ @@ -371,22 +371,22 @@ endm /* #define USB_INTR_PENDING GIFR */ #define USB_INTR_PENDING_BIT INTF1 #define USB_INTR_VECTOR SIG_INTERRUPT1 - - -/* This is a new macro that is executed and the beginning of the usb irq handler. - * This needs a patch in the corresponding clock dependend assembler file of VUSB!!! - * It is save to use register YH here - */ -#define USB_START_IRQ_HOOK customTriggerHook - - + + +/* This is a new macro that is executed and the beginning of the usb irq handler. + * This needs a patch in the corresponding clock dependend assembler file of VUSB!!! + * It is save to use register YH here + */ +#define USB_START_IRQ_HOOK customTriggerHook + + /* Reinstall edge level interrupt triggering (after sleep) */ #ifdef __ASSEMBLER__ -macro customTriggerHook - in YH, USB_INTR_CFG +macro customTriggerHook + in YH, USB_INTR_CFG ori YH, USB_INTR_CFG_SET out USB_INTR_CFG, YH -endm +endm #endif - + #endif /* __usbconfig_h_included__ */ diff --git a/usb_boot/10ch_usb_boot.c b/usb_boot/10ch_usb_boot.c deleted file mode 100644 index 4d90a4a..0000000 --- a/usb_boot/10ch_usb_boot.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Auras - * - * This file is part of the DF10CH Atmolight controller project. - * - * DF10CH Atmolight controller 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. - * - * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - */ - -// ====================================================================== -// Bootloader firmware for USB processor. -// - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../df10ch_common.h" -#include "../df10ch_usb_proto.h" -#include "usbconfig.h" - - -// --- -// Fuse-Bit settings for the flash programmer (ATmega8): -// RSTDISBL=1 -// WDTON=1 -// SPIEN=0 -// CKOPT=0 -// EESAVE=1 -// BOOTSZ1=0 -// BOOTSZ0=0 -// BOOTRST=0 -// -// BODLEVEL=0 -// BODEN=0 -// SUT1=0 -// SUT0=1 -// CKSEL3=1 -// CKSEL2=1 -// CKSEL1=1 -// CKSEL0=1 -// -// Memory-Lock Bits: -// BL12=1, BL11=0, BL02=1, BL01=1, LB2=1, LB1=1 -// -FUSES = -{ - .low = (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT1), - .high = (FUSE_SPIEN & FUSE_CKOPT & FUSE_BOOTSZ1 & FUSE_BOOTSZ0 & FUSE_BOOTRST) -}; -LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); -//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; - - -// --- -// System clock related. -// System clock ist implemented with hardware timer 1 -// -#define SYS_HWPRESCALE 1024 // Hardware Prescaler - - // useconds <-> timer ticks conversation -#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE) + 0.5)) -#define TICKS2US(t) ((uint16_t)((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE)))) - - - // Input pin (Jumper) for enable/disable of bootloader - // Enabled when Jumper set -> 0, Disabled if Jumper is away -> 1 -#define BL_SENSE_DDR DDRB -#define BL_SENSE_PORT PORTB -#define BL_SENSE_PIN PINB -#define BL_SENSE_BIT 0 - -#define APPL_START_VECT 0x0000 - -static uint8_t leave_state; // Is true when bootloader should be leaved - - -// --- -// USB related. -// -#define USB_DISCONNECT_TIME US2TICKS(500000UL) -#define USB_STALL_RC 0xFF - -static uint8_t usb_last_data_token NOMEMINIT; // Token PID of last usb packet received -static uint8_t usb_last_rc = USB_STALL_RC; // Return status of last payload packet -static uint8_t payload_req NOMEMINIT; // ID of actual proccessed USB request - -// --- -// flash programming related. -// -static uint16_t page_address NOMEMINIT; // actual page address -static uint8_t page_offset NOMEMINIT; // actual offset into page -static uint8_t page_size_reply[2] = { (SPM_PAGESIZE & 0xFF), (SPM_PAGESIZE >> 8) }; - -#include - - -// --- -// ISR handler for IRQ's that do not have a dedicated handler. -// -EMPTY_INTERRUPT(BADISR_vect) - - -// --- -// Write request payload data. -// -USB_PUBLIC uint8_t usbFunctionWrite(uint8_t *data, uint8_t len) -{ - uint8_t rc = USB_STALL_RC; - - if (usb_last_rc != USB_STALL_RC) - { - if (len != 8 || usbCrc16(data, 8) == ((uint16_t *)data)[4]) - { - if (usbCurrentDataToken == usb_last_data_token) - return usb_last_rc; // Ignore packet - - if (payload_req == BL_REQ_WRITE_PAGE) - { - rc = 0; - while (len > 1) - { - bytes_word_t code; - code.bytes[0] = *data++; - code.bytes[1] = *data++; - - cli(); - boot_page_fill(page_address + page_offset, code.word); - sei(); - - page_offset += 2; - len -= 2; - if (page_offset >= SPM_PAGESIZE) - { - cli(); - boot_page_write(page_address); - sei(); - - while (boot_spm_busy()) - wdt_reset(); - - rc = 1; - } - } - } - } - } - - if (rc) - usb_last_rc = USB_STALL_RC; - usb_last_data_token = usbCurrentDataToken; - - return rc; -} - - -// --- -// Read request payload data. -// -USB_PUBLIC uint8_t usbFunctionRead(uint8_t *data, uint8_t len) -{ - uint8_t rc = USB_STALL_RC; - - if (usb_last_rc != USB_STALL_RC) - { - if (payload_req == BL_REQ_READ_FLASH) - { - if (len > page_offset) - len = page_offset; - rc = len; - if (len) - { - page_offset -= len; - PGM_P p = (PGM_P) page_address; - page_address += len; - memcpy_P(data, p, len); - } - } - - if (rc != 8) - usb_last_rc = USB_STALL_RC; - } - - return rc; -} - - -// --- -// Handle a non-standard USB SETUP packet. -// -USB_PUBLIC usbMsgLen_t usbFunctionSetup(uint8_t data[8]) -{ - usbRequest_t *r = (usbRequest_t *) data; - - usb_last_data_token = USBPID_SETUP; - usb_last_rc = USB_STALL_RC; - uint8_t rc = USB_NO_MSG; - - if (leave_state || usbCrc16(data, 8) != ((uint16_t *)data)[4]) - return rc; - - uint8_t req = r->bRequest; - payload_req = req; - - if (req == BL_REQ_WRITE_PAGE) - { - page_address = r->wIndex.word; - page_offset = 0; - - while (!eeprom_is_ready()) - wdt_reset(); - - cli(); - boot_page_erase(page_address); - sei(); - - while (boot_spm_busy()) - wdt_reset(); - - usb_last_rc = 0; - } - else if (req == BL_REQ_LEAVE_BOOT) - { - if (boot_rww_busy()) - boot_rww_enable(); - leave_state = 1; - rc = 0; - } - else if (req == BL_REQ_GET_PAGE_SIZE) - { - usbMsgPtr = page_size_reply; - rc = sizeof(page_size_reply); - } - else if (req == BL_REQ_READ_FLASH) - { - if (boot_rww_busy()) - boot_rww_enable(); - page_address = r->wIndex.word; - page_offset = r->wLength.bytes[0]; - usb_last_rc = 0; - } - - return rc; -} - - -// ---- -// Main -// -void main(void) NORETURN; -void main(void) -{ - cli(); - - wdt_enable(WDTO_120MS); // Set watchdog timeout - - // Note: If application calls bootloader it must set the enable pin to output and low level - if (bit_is_clear(BL_SENSE_DDR, BL_SENSE_BIT)) - set_bit(BL_SENSE_PORT, BL_SENSE_BIT); // activate pullup - - if ((pgm_read_word(APPL_START_VECT) != 0xFFFF) && // Application reset vector programmed? - bit_is_set(BL_SENSE_PIN, BL_SENSE_BIT)) - { // boot loader disabled -> start application - void (*jump_to_app)(void) = APPL_START_VECT / 2; // Need flash word address! - jump_to_app(); - } - - GICR = _BV(IVCE); // enable change of interrupt vectors - GICR = _BV(IVSEL); // move interrupts to boot flash section - - // initialize boot loader disable pin: input + pullup - clear_bit(BL_SENSE_DDR, BL_SENSE_BIT); - set_bit(BL_SENSE_PORT, BL_SENSE_BIT); - - usbDeviceDisconnect(); - - // Initialize Timer 1 - TIMSK = 0; - TCCR1A = 0; - TCCR1B = 0; - TCNT1 = 0; - TCCR1B = _BV(CS12) | _BV(CS10); // Start timer 1, Prescaler 1024 - - while (TCNT1 < USB_DISCONNECT_TIME) - wdt_reset(); - - TCCR1B = 0; // Stop timer 1 - - usbDeviceConnect(); - usbInit(); - - sei(); - - // Main loop - for (;;) - { - // Note: Delayed boot loader exit is done via watchdog timer reset - if (!leave_state) - wdt_reset(); - - usbPoll(); // process USB requests - } -} - diff --git a/usb_boot/Makefile b/usb_boot/Makefile index 6f63ffa..db3beb5 100644 --- a/usb_boot/Makefile +++ b/usb_boot/Makefile @@ -1,106 +1,106 @@ -# -# Copyright (C) 2010 Andreas Auras -# -# This file is part of the DF10CH Atmolight controller project. -# -# DF10CH Atmolight controller 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. -# -# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -# -# -############################################################################### -# Makefile for the bootloader firmware of USB processor -############################################################################### - -## General Flags -PROJECT = 10ch_usb_boot -MCU = atmega8 -TARGET = 10ch_usb_boot.elf -CC = avr-gcc -AVRDUDE ?= avrdude -c stk500v2 -P avrdoper -USBDRV ?= ../usbdrv -F_CPU ?= 16000000UL -FIRMWARE_VERSION ?= 1 - -## Options common to compile, link and assembly rules -COMMON = -mmcu=$(MCU) - -## Compile options common for all C compilation units. -CFLAGS = $(COMMON) -CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) - -## Assembly specific flags -ASMFLAGS = $(COMMON) -ASMFLAGS += $(CFLAGS) -ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 - -## Linker flags -LDFLAGS = $(COMMON) -LDFLAGS += -Wl,-Map=10ch_usb_boot.map -LDFLAGS += -Wl,-section-start=.text=0x1800 - - -## Intel Hex file production flags -HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature - -HEX_EEPROM_FLAGS = -j .eeprom -HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" - -## Include Directories -INCLUDES = -I. -I.. -I$(USBDRV) - -## Objects that must be built in order to link -OBJECTS = 10ch_usb_boot.o usbdrvasm.o - -## Objects explicitly added by the user -LINKONLYOBJECTS = - -## Build -all: $(TARGET) 10ch_usb_boot.hex 10ch_usb_boot.lss size - -prog: flash - $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0x1F:m -Uhfuse:w:0xC8:m -Ulock:w:0xEF:m - -flash: 10ch_usb_boot.hex - $(AVRDUDE) -p $(MCU) -Uflash:w:10ch_usb_boot.hex:i - - -## Compile -usbdrvasm.o: $(USBDRV)/usbdrvasm.S usbconfig.h - $(CC) $(INCLUDES) $(ASMFLAGS) -c $< - -10ch_usb_boot.o: 10ch_usb_boot.c usbconfig.h ../df10ch_usb_proto.h ../df10ch_common.h - $(CC) $(INCLUDES) $(CFLAGS) -c $< - -##Link -$(TARGET): $(OBJECTS) - $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) - -%.hex: $(TARGET) - avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ - -%.eep: $(TARGET) - -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 - -%.lss: $(TARGET) - avr-objdump -h -S $< > $@ - -size: ${TARGET} - @echo - @avr-size -C --mcu=${MCU} ${TARGET} - -## Clean target -.PHONY: clean -clean: - -rm -rf $(OBJECTS) 10ch_usb_boot.elf 10ch_usb_boot.hex 10ch_usb_boot.eep 10ch_usb_boot.lss 10ch_usb_boot.map +# +# Copyright (C) 2010 Andreas Auras +# +# This file is part of the DF10CH Atmolight controller project. +# +# DF10CH Atmolight controller 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. +# +# DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +# +# +############################################################################### +# Makefile for the bootloader firmware of USB processor +############################################################################### + +## General Flags +PROJECT = df10ch_usb_boot +MCU = atmega8 +TARGET = df10ch_usb_boot.elf +CC = avr-gcc +AVRDUDE ?= avrdude -c stk500v2 -P avrdoper +USBDRV ?= ../usbdrv +F_CPU ?= 16000000UL +FIRMWARE_VERSION ?= 1 + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION) + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-Map=df10ch_usb_boot.map +LDFLAGS += -Wl,-section-start=.text=0x1800 + + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" + +## Include Directories +INCLUDES = -I. -I.. -I$(USBDRV) + +## Objects that must be built in order to link +OBJECTS = df10ch_usb_boot.o usbdrvasm.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET) df10ch_usb_boot.hex df10ch_usb_boot.lss size + +prog: flash + $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0x1F:m -Uhfuse:w:0xC8:m -Ulock:w:0xEF:m + +flash: df10ch_usb_boot.hex + $(AVRDUDE) -p $(MCU) -Uflash:w:df10ch_usb_boot.hex:i + + +## Compile +usbdrvasm.o: $(USBDRV)/usbdrvasm.S usbconfig.h + $(CC) $(INCLUDES) $(ASMFLAGS) -c $< + +df10ch_usb_boot.o: df10ch_usb_boot.c usbconfig.h ../df10ch_usb_proto.h ../df10ch_common.h + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) + +%.hex: $(TARGET) + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET) + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET) + avr-objdump -h -S $< > $@ + +size: ${TARGET} + @echo + @avr-size -C --mcu=${MCU} ${TARGET} + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) df10ch_usb_boot.elf df10ch_usb_boot.hex df10ch_usb_boot.eep df10ch_usb_boot.lss df10ch_usb_boot.map diff --git a/usb_boot/df10ch_usb_boot.c b/usb_boot/df10ch_usb_boot.c new file mode 100644 index 0000000..9e72810 --- /dev/null +++ b/usb_boot/df10ch_usb_boot.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2010 Andreas Auras + * + * This file is part of the DF10CH Atmolight controller project. + * + * DF10CH Atmolight controller 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. + * + * DF10CH Atmolight controller 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +// ====================================================================== +// Bootloader firmware for USB processor. +// + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../df10ch_common.h" +#include "../df10ch_usb_proto.h" +#include "usbconfig.h" + + +// --- +// Fuse-Bit settings for the flash programmer (ATmega8): +// RSTDISBL=1 +// WDTON=1 +// SPIEN=0 +// CKOPT=0 +// EESAVE=1 +// BOOTSZ1=0 +// BOOTSZ0=0 +// BOOTRST=0 +// +// BODLEVEL=0 +// BODEN=0 +// SUT1=0 +// SUT0=1 +// CKSEL3=1 +// CKSEL2=1 +// CKSEL1=1 +// CKSEL0=1 +// +// Memory-Lock Bits: +// BL12=1, BL11=0, BL02=1, BL01=1, LB2=1, LB1=1 +// +FUSES = +{ + .low = (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT1), + .high = (FUSE_SPIEN & FUSE_CKOPT & FUSE_BOOTSZ1 & FUSE_BOOTSZ0 & FUSE_BOOTRST) +}; +LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2); +//SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ; + + +// --- +// System clock related. +// System clock ist implemented with hardware timer 1 +// +#define SYS_HWPRESCALE 1024 // Hardware Prescaler + + // useconds <-> timer ticks conversation +#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE) + 0.5)) +#define TICKS2US(t) ((uint16_t)((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE)))) + + + // Input pin (Jumper) for enable/disable of bootloader + // Enabled when Jumper set -> 0, Disabled if Jumper is away -> 1 +#define BL_SENSE_DDR DDRB +#define BL_SENSE_PORT PORTB +#define BL_SENSE_PIN PINB +#define BL_SENSE_BIT 0 + +#define APPL_START_VECT 0x0000 + +static uint8_t leave_state; // Is true when bootloader should be leaved + + +// --- +// USB related. +// +#define USB_DISCONNECT_TIME US2TICKS(500000UL) +#define USB_STALL_RC 0xFF + +static uint8_t usb_last_data_token NOMEMINIT; // Token PID of last usb packet received +static uint8_t usb_last_rc = USB_STALL_RC; // Return status of last payload packet +static uint8_t payload_req NOMEMINIT; // ID of actual proccessed USB request + +// --- +// flash programming related. +// +static uint16_t page_address NOMEMINIT; // actual page address +static uint8_t page_offset NOMEMINIT; // actual offset into page +static uint8_t page_size_reply[2] = { (SPM_PAGESIZE & 0xFF), (SPM_PAGESIZE >> 8) }; + +#include + + +// --- +// ISR handler for IRQ's that do not have a dedicated handler. +// +EMPTY_INTERRUPT(BADISR_vect) + + +// --- +// Write request payload data. +// +USB_PUBLIC uint8_t usbFunctionWrite(uint8_t *data, uint8_t len) +{ + uint8_t rc = USB_STALL_RC; + + if (usb_last_rc != USB_STALL_RC) + { + if (len != 8 || usbCrc16(data, 8) == ((uint16_t *)data)[4]) + { + if (usbCurrentDataToken == usb_last_data_token) + return usb_last_rc; // Ignore packet + + if (payload_req == BL_REQ_WRITE_PAGE) + { + rc = 0; + while (len > 1) + { + bytes_word_t code; + code.bytes[0] = *data++; + code.bytes[1] = *data++; + + cli(); + boot_page_fill(page_address + page_offset, code.word); + sei(); + + page_offset += 2; + len -= 2; + if (page_offset >= SPM_PAGESIZE) + { + cli(); + boot_page_write(page_address); + sei(); + + while (boot_spm_busy()) + wdt_reset(); + + rc = 1; + } + } + } + } + } + + if (rc) + usb_last_rc = USB_STALL_RC; + usb_last_data_token = usbCurrentDataToken; + + return rc; +} + + +// --- +// Read request payload data. +// +USB_PUBLIC uint8_t usbFunctionRead(uint8_t *data, uint8_t len) +{ + uint8_t rc = USB_STALL_RC; + + if (usb_last_rc != USB_STALL_RC) + { + if (payload_req == BL_REQ_READ_FLASH) + { + if (len > page_offset) + len = page_offset; + rc = len; + if (len) + { + page_offset -= len; + PGM_P p = (PGM_P) page_address; + page_address += len; + memcpy_P(data, p, len); + } + } + + if (rc != 8) + usb_last_rc = USB_STALL_RC; + } + + return rc; +} + + +// --- +// Handle a non-standard USB SETUP packet. +// +USB_PUBLIC usbMsgLen_t usbFunctionSetup(uint8_t data[8]) +{ + usbRequest_t *r = (usbRequest_t *) data; + + usb_last_data_token = USBPID_SETUP; + usb_last_rc = USB_STALL_RC; + uint8_t rc = USB_NO_MSG; + + if (leave_state || usbCrc16(data, 8) != ((uint16_t *)data)[4]) + return rc; + + uint8_t req = r->bRequest; + payload_req = req; + + if (req == BL_REQ_WRITE_PAGE) + { + page_address = r->wIndex.word; + page_offset = 0; + + while (!eeprom_is_ready()) + wdt_reset(); + + cli(); + boot_page_erase(page_address); + sei(); + + while (boot_spm_busy()) + wdt_reset(); + + usb_last_rc = 0; + } + else if (req == BL_REQ_LEAVE_BOOT) + { + if (boot_rww_busy()) + boot_rww_enable(); + leave_state = 1; + rc = 0; + } + else if (req == BL_REQ_GET_PAGE_SIZE) + { + usbMsgPtr = page_size_reply; + rc = sizeof(page_size_reply); + } + else if (req == BL_REQ_READ_FLASH) + { + if (boot_rww_busy()) + boot_rww_enable(); + page_address = r->wIndex.word; + page_offset = r->wLength.bytes[0]; + usb_last_rc = 0; + } + + return rc; +} + + +// ---- +// Main +// +void main(void) NORETURN; +void main(void) +{ + cli(); + + wdt_enable(WDTO_120MS); // Set watchdog timeout + + // Note: If application calls bootloader it must set the enable pin to output and low level + if (bit_is_clear(BL_SENSE_DDR, BL_SENSE_BIT)) + set_bit(BL_SENSE_PORT, BL_SENSE_BIT); // activate pullup + + if ((pgm_read_word(APPL_START_VECT) != 0xFFFF) && // Application reset vector programmed? + bit_is_set(BL_SENSE_PIN, BL_SENSE_BIT)) + { // boot loader disabled -> start application + void (*jump_to_app)(void) = APPL_START_VECT / 2; // Need flash word address! + jump_to_app(); + } + + GICR = _BV(IVCE); // enable change of interrupt vectors + GICR = _BV(IVSEL); // move interrupts to boot flash section + + // initialize boot loader disable pin: input + pullup + clear_bit(BL_SENSE_DDR, BL_SENSE_BIT); + set_bit(BL_SENSE_PORT, BL_SENSE_BIT); + + usbDeviceDisconnect(); + + // Initialize Timer 1 + TIMSK = 0; + TCCR1A = 0; + TCCR1B = 0; + TCNT1 = 0; + TCCR1B = _BV(CS12) | _BV(CS10); // Start timer 1, Prescaler 1024 + + while (TCNT1 < USB_DISCONNECT_TIME) + wdt_reset(); + + TCCR1B = 0; // Stop timer 1 + + usbDeviceConnect(); + usbInit(); + + sei(); + + // Main loop + for (;;) + { + // Note: Delayed boot loader exit is done via watchdog timer reset + if (!leave_state) + wdt_reset(); + + usbPoll(); // process USB requests + } +} + diff --git a/usb_boot/usbconfig.h b/usb_boot/usbconfig.h index e9899b7..70f76f1 100644 --- a/usb_boot/usbconfig.h +++ b/usb_boot/usbconfig.h @@ -183,17 +183,17 @@ section at the end of this file). * Please note that Start Of Frame detection works only if D- is wired to the * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! */ - -/* Save timestamp of sof */ -#ifdef __ASSEMBLER__ -macro customSofHook - ldi YL, 0 +/* Save timestamp of sof */ + +#ifdef __ASSEMBLER__ +macro customSofHook + ldi YL, 0 out TCNT1H, YL out TCNT1L, YL endm #endif - + #define USB_CFG_CHECK_DATA_TOGGLING 1 /* define this macro to 1 if you want to filter out duplicate data packets * sent by the host. Duplicates occur only as a consequence of communication @@ -206,15 +206,15 @@ endm /* define this macro to 1 if you want the function usbMeasureFrameLength() * compiled in. This function can be used to calibrate the AVR's RC oscillator. */ -#define USB_USE_FAST_CRC 1 -/* The assembler module has two implementations for the CRC algorithm. One is - * faster, the other is smaller. This CRC routine is only used for transmitted - * messages where timing is not critical. The faster routine needs 31 cycles - * per byte while the smaller one needs 61 to 69 cycles. The faster routine - * may be worth the 32 bytes bigger code size if you transmit lots of data and - * run the AVR close to its limit. - */ - +#define USB_USE_FAST_CRC 1 +/* The assembler module has two implementations for the CRC algorithm. One is + * faster, the other is smaller. This CRC routine is only used for transmitted + * messages where timing is not critical. The faster routine needs 31 cycles + * per byte while the smaller one needs 61 to 69 cycles. The faster routine + * may be worth the 32 bytes bigger code size if you transmit lots of data and + * run the AVR close to its limit. + */ + /* -------------------------- Device Description --------------------------- */ #define USB_CFG_VENDOR_ID 0xc0, 0x16 @@ -360,9 +360,9 @@ endm */ #define USB_INTR_CFG MCUCR #if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK) || 1 -#define USB_INTR_CFG_SET ((1 << ISC11)) +#define USB_INTR_CFG_SET ((1 << ISC11)) #else -#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11)) +#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11)) #endif /* #define USB_INTR_CFG_CLR 0 */ /* #define USB_INTR_ENABLE GIMSK */ @@ -370,22 +370,22 @@ endm /* #define USB_INTR_PENDING GIFR */ #define USB_INTR_PENDING_BIT INTF1 #define USB_INTR_VECTOR SIG_INTERRUPT1 - - -/* This is a new macro that is executed and the beginning of the usb irq handler. - * This needs a patch in the corresponding clock dependend assembler file of VUSB!!! - * It is save to use register YH here - */ -/*#define USB_START_IRQ_HOOK customTriggerHook*/ - - + + +/* This is a new macro that is executed and the beginning of the usb irq handler. + * This needs a patch in the corresponding clock dependend assembler file of VUSB!!! + * It is save to use register YH here + */ +/*#define USB_START_IRQ_HOOK customTriggerHook*/ + + /* Reinstall edge level interrupt triggering (after sleep) */ #ifdef __ASSEMBLER__ -macro customTriggerHook - in YH, USB_INTR_CFG +macro customTriggerHook + in YH, USB_INTR_CFG ori YH, USB_INTR_CFG_SET out USB_INTR_CFG, YH -endm +endm #endif - + #endif /* __usbconfig_h_included__ */ -- cgit v1.2.3