Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 886 → Rev 885

/branches/V0.69k Code Redesign killagreg/led.c
File deleted
/branches/V0.69k Code Redesign killagreg/gps.c
File deleted
/branches/V0.69k Code Redesign killagreg/led.h
File deleted
/branches/V0.69k Code Redesign killagreg/eeprom.h
File deleted
/branches/V0.69k Code Redesign killagreg/mm3.c
File deleted
/branches/V0.69k Code Redesign killagreg/fifo.c
File deleted
/branches/V0.69k Code Redesign killagreg/mymath.h
File deleted
/branches/V0.69k Code Redesign killagreg/mymath.c
File deleted
/branches/V0.69k Code Redesign killagreg/mm3.h
File deleted
/branches/V0.69k Code Redesign killagreg/fifo.h
File deleted
/branches/V0.69k Code Redesign killagreg/uart1.c
File deleted
/branches/V0.69k Code Redesign killagreg/timer2.c
File deleted
/branches/V0.69k Code Redesign killagreg/timer2.h
File deleted
/branches/V0.69k Code Redesign killagreg/ubx.c
File deleted
/branches/V0.69k Code Redesign killagreg/uart1.h
File deleted
/branches/V0.69k Code Redesign killagreg/ubx.h
File deleted
/branches/V0.69k Code Redesign killagreg/mk3mag.h
File deleted
/branches/V0.69k Code Redesign killagreg/mk3mag.c
File deleted
/branches/V0.69k Code Redesign killagreg/FlightCtrl.aps
1,0 → 0,0
<AVRStudio><MANAGEMENT><ProjectName>FlightCtrl</ProjectName><Created>15-May-2007 11:20:41</Created><LastEdit>21-Mar-2008 18:51:49</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>15-May-2007 11:20:41</Created><Version>4</Version><Build>4, 13, 0, 528</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\Flight-Ctrl.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>E:\Daten\Bastelprojekte\Mikrokopter\Software\Soucen\FlightCtrl\V0.68d Code Redesign killagreg\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega644.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>uart.c</SOURCEFILE><SOURCEFILE>analog.c</SOURCEFILE><SOURCEFILE>eeprom.c</SOURCEFILE><SOURCEFILE>fc.c</SOURCEFILE><SOURCEFILE>GPS.c</SOURCEFILE><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>menu.c</SOURCEFILE><SOURCEFILE>printf_P.c</SOURCEFILE><SOURCEFILE>rc.c</SOURCEFILE><SOURCEFILE>timer0.c</SOURCEFILE><SOURCEFILE>twimaster.c</SOURCEFILE><SOURCEFILE>ubx.c</SOURCEFILE><SOURCEFILE>cmps03.c</SOURCEFILE><SOURCEFILE>fifo.c</SOURCEFILE><SOURCEFILE>mm3.c</SOURCEFILE><SOURCEFILE>mymath.c</SOURCEFILE><SOURCEFILE>spi.c</SOURCEFILE><SOURCEFILE>timer2.c</SOURCEFILE><SOURCEFILE>uart1.c</SOURCEFILE><SOURCEFILE>led.c</SOURCEFILE><HEADERFILE>uart.h</HEADERFILE><HEADERFILE>_Settings.h</HEADERFILE><HEADERFILE>analog.h</HEADERFILE><HEADERFILE>fc.h</HEADERFILE><HEADERFILE>gps.h</HEADERFILE><HEADERFILE>main.h</HEADERFILE><HEADERFILE>menu.h</HEADERFILE><HEADERFILE>old_macros.h</HEADERFILE><HEADERFILE>printf_P.h</HEADERFILE><HEADERFILE>rc.h</HEADERFILE><HEADERFILE>timer0.h</HEADERFILE><HEADERFILE>twimaster.h</HEADERFILE><HEADERFILE>cmps03.h</HEADERFILE><HEADERFILE>eeprom.h</HEADERFILE><HEADERFILE>fifo.h</HEADERFILE><HEADERFILE>led.h</HEADERFILE><HEADERFILE>mm3.h</HEADERFILE><HEADERFILE>mymath.h</HEADERFILE><HEADERFILE>spi.h</HEADERFILE><HEADERFILE>timer2.h</HEADERFILE><HEADERFILE>uart1.h</HEADERFILE><HEADERFILE>ubx.h</HEADERFILE><OTHERFILE>makefile</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>YES</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE>makefile</EXTERNALMAKEFILE><PART>atmega644</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Flight-Ctrl.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>GPS.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>analog.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>cmps03.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>eeprom.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>fc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>fifo.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>led.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>menu.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>mm3.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>mymath.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>printf_P.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>rc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>spi.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>timer0.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>timer2.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>twimaster.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>uart.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>uart1.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>ubx.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS><LIB>libc.a</LIB><LIB>libm.a</LIB></LIBS><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -Wstrict-prototypes -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Programme\Winavr\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Programme\Winavr\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><IOView><usergroups/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>uart.c</FileName><Status>1</Status></File00001><File00002><FileId>00002</FileId><FileName>menu.c</FileName><Status>1</Status></File00002><File00003><FileId>00003</FileId><FileName>timer0.c</FileName><Status>1</Status></File00003><File00004><FileId>00004</FileId><FileName>fc.c</FileName><Status>1</Status></File00004><File00005><FileId>00005</FileId><FileName>fc.h</FileName><Status>1</Status></File00005><File00006><FileId>00006</FileId><FileName>menu.h</FileName><Status>1</Status></File00006><File00007><FileId>00007</FileId><FileName>TWIMASTER.C</FileName><Status>1</Status></File00007><File00008><FileId>00008</FileId><FileName>twimaster.h</FileName><Status>1</Status></File00008><File00009><FileId>00009</FileId><FileName>uart.h</FileName><Status>1</Status></File00009><File00010><FileId>00010</FileId><FileName>_Settings.h</FileName><Status>1</Status></File00010><File00011><FileId>00011</FileId><FileName>analog.h</FileName><Status>1</Status></File00011><File00012><FileId>00012</FileId><FileName>gps.h</FileName><Status>1</Status></File00012><File00013><FileId>00013</FileId><FileName>main.h</FileName><Status>1</Status></File00013><File00014><FileId>00014</FileId><FileName>old_macros.h</FileName><Status>1</Status></File00014><File00015><FileId>00015</FileId><FileName>printf_P.h</FileName><Status>1</Status></File00015><File00016><FileId>00016</FileId><FileName>rc.h</FileName><Status>1</Status></File00016><File00017><FileId>00017</FileId><FileName>timer0.h</FileName><Status>1</Status></File00017><File00018><FileId>00018</FileId><FileName>makefile</FileName><Status>1</Status></File00018></Files><Workspace><File00000><Position>251 96 720 458</Position><LineCol>0 0</LineCol></File00000><File00001><Position>273 118 734 450</Position><LineCol>0 0</LineCol></File00001><File00002><Position>295 140 756 472</Position><LineCol>0 0</LineCol></File00002><File00003><Position>317 162 778 494</Position><LineCol>0 0</LineCol></File00003><File00004><Position>339 184 800 516</Position><LineCol>0 0</LineCol></File00004><File00005><Position>361 206 822 538</Position><LineCol>0 0</LineCol></File00005><File00006><Position>383 228 844 560</Position><LineCol>0 0</LineCol></File00006><File00007><Position>405 250 866 582</Position><LineCol>0 0</LineCol></File00007><File00008><Position>251 96 712 428</Position><LineCol>0 0</LineCol></File00008><File00009><Position>273 118 734 450</Position><LineCol>0 0</LineCol></File00009><File00010><Position>295 140 756 472</Position><LineCol>0 0</LineCol></File00010><File00011><Position>317 162 778 494</Position><LineCol>0 0</LineCol></File00011><File00012><Position>339 184 800 516</Position><LineCol>0 0</LineCol></File00012><File00013><Position>361 206 822 538</Position><LineCol>0 0</LineCol></File00013><File00014><Position>383 228 844 560</Position><LineCol>0 0</LineCol></File00014><File00015><Position>405 250 866 582</Position><LineCol>0 0</LineCol></File00015><File00016><Position>251 96 712 428</Position><LineCol>0 0</LineCol></File00016><File00017><Position>273 118 734 450</Position><LineCol>0 0</LineCol></File00017><File00018><Position>295 140 756 472</Position><LineCol>0 0</LineCol></File00018></Workspace><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
<AVRStudio><MANAGEMENT><ProjectName>FlightCtrl</ProjectName><Created>15-May-2007 11:20:41</Created><LastEdit>11-Oct-2007 22:58:54</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>15-May-2007 11:20:41</Created><Version>4</Version><Build>4, 13, 0, 528</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\Flight-Ctrl.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>F:\SVN\MikroKopter\FlightCtrl\branches\V0.64_ZeroWarnings\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega644.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>uart.c</SOURCEFILE><SOURCEFILE>analog.c</SOURCEFILE><SOURCEFILE>eeprom.c</SOURCEFILE><SOURCEFILE>fc.c</SOURCEFILE><SOURCEFILE>GPS.c</SOURCEFILE><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>menu.c</SOURCEFILE><SOURCEFILE>printf_P.c</SOURCEFILE><SOURCEFILE>rc.c</SOURCEFILE><SOURCEFILE>timer0.c</SOURCEFILE><SOURCEFILE>twimaster.c</SOURCEFILE><HEADERFILE>uart.h</HEADERFILE><HEADERFILE>_Settings.h</HEADERFILE><HEADERFILE>analog.h</HEADERFILE><HEADERFILE>fc.h</HEADERFILE><HEADERFILE>gps.h</HEADERFILE><HEADERFILE>main.h</HEADERFILE><HEADERFILE>menu.h</HEADERFILE><HEADERFILE>old_macros.h</HEADERFILE><HEADERFILE>printf_P.h</HEADERFILE><HEADERFILE>rc.h</HEADERFILE><HEADERFILE>Settings.h</HEADERFILE><HEADERFILE>timer0.h</HEADERFILE><HEADERFILE>twimaster.h</HEADERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega644</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Flight-Ctrl.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>GPS.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>analog.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>eeprom.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>fc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>menu.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>printf_P.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>rc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>timer0.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>twimaster.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>uart.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS><LIB>libc.a</LIB><LIB>libm.a</LIB></LIBS><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -Wstrict-prototypes -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -DVERSION_HAUPTVERSION=0 -DVERSION_NEBENVERSION=64 -DVERSION_KOMPATIBEL=5</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Program Files\WinAVR\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Program Files\WinAVR\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><IOView><usergroups/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>uart.c</FileName><Status>1</Status></File00001><File00002><FileId>00002</FileId><FileName>menu.c</FileName><Status>1</Status></File00002><File00003><FileId>00003</FileId><FileName>timer0.c</FileName><Status>1</Status></File00003><File00004><FileId>00004</FileId><FileName>fc.c</FileName><Status>1</Status></File00004><File00005><FileId>00005</FileId><FileName>fc.h</FileName><Status>1</Status></File00005><File00006><FileId>00006</FileId><FileName>menu.h</FileName><Status>1</Status></File00006><File00007><FileId>00007</FileId><FileName>TWIMASTER.C</FileName><Status>1</Status></File00007><File00008><FileId>00008</FileId><FileName>twimaster.h</FileName><Status>1</Status></File00008><File00009><FileId>00009</FileId><FileName>uart.h</FileName><Status>1</Status></File00009><File00010><FileId>00010</FileId><FileName>_Settings.h</FileName><Status>1</Status></File00010><File00011><FileId>00011</FileId><FileName>analog.h</FileName><Status>1</Status></File00011><File00012><FileId>00012</FileId><FileName>gps.h</FileName><Status>1</Status></File00012><File00013><FileId>00013</FileId><FileName>main.h</FileName><Status>1</Status></File00013><File00014><FileId>00014</FileId><FileName>old_macros.h</FileName><Status>1</Status></File00014><File00015><FileId>00015</FileId><FileName>printf_P.h</FileName><Status>1</Status></File00015><File00016><FileId>00016</FileId><FileName>rc.h</FileName><Status>1</Status></File00016><File00017><FileId>00017</FileId><FileName>Settings.h</FileName><Status>1</Status></File00017><File00018><FileId>00018</FileId><FileName>timer0.h</FileName><Status>1</Status></File00018></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
/branches/V0.69k Code Redesign killagreg/GPS.c
0,0 → 1,32
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 04.2007 Holger Buss
// + only for non-profit use
// + www.MikroKopter.com
// + see the File "License.txt" for further Informations
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "main.h"
 
signed int GPS_Nick = 0;
signed int GPS_Roll = 0;
signed int GPS_Nick2 = 0;
signed int GPS_Roll2 = 0;
long GpsAktuell_X = 0;
long GpsAktuell_Y = 0;
long GpsZiel_X = 0;
long GpsZiel_Y = 0;
void GPS_Neutral(void)
{
GpsZiel_X = GpsAktuell_X;
GpsZiel_Y = GpsAktuell_Y;
}
 
void GPS_BerechneZielrichtung(void)
{
GPS_Nick = 0;
GPS_Roll = 0;
}
 
 
 
 
/branches/V0.69k Code Redesign killagreg/Hex-Files/Readme.txt
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Flight-Ctrl_MEGA644p_NAVICTRL_V0_69k.hex
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Flight-Ctrl_MEGA644p_V0_69k.hex
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Flight-Ctrl_MEGA644_KILLAGREG_V0_69k.hex
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Flight-Ctrl_MEGA644p_KILLAGREG_V0_69k.hex
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Conrad LEA-4H Config-4Hz.txt
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Conrad LEA-4H Config-5Hz.txt
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Flight-Ctrl_MEGA644_NAVICTRL_V0_69k.hex
File deleted
/branches/V0.69k Code Redesign killagreg/Hex-Files/Flight-Ctrl_MEGA644_V0_69k.hex
1,2125 → 1,2212
:100000000C9451020C946E020C946E020C946E02CD
:100010000C946E020C946E020C946E020C946E02A0
:100020000C946E020C94A90C0C946E020C946E024B
:100030000C9404170C946E020C946E020C94D0165F
:100040000C946E020C946E020C94D40B0C946E0201
:100050000C944A040C946E020C9414040C946E02DA
:100060000C947E0D0C946E020C9418160C946E0277
:100070000A0A0D004E65757472616C004865616412
:10008000696E67486F6C64000A0D436F6E74726F1F
:100090006C3A20004F4B0A0D000A0D43616C6962F7
:1000A000726174696E672061697220707265737322
:1000B0007572652073656E736F722E2E000A0D5374
:1000C0007570706F727420666F72204D4B334D41A6
:1000D0004720436F6D70617373000A0D41434320E5
:1000E0006E6F742063616C69627261746564210073
:1000F0000A0D3D3D3D3D3D3D3D3D3D3D3D3D3D3D93
:100100003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D1F
:10011000000A0D466C69676874436F6E74726F6C89
:100120000A0D48617264776172653A25642E256410
:100130000A0D536F6674776172653A5625642E25F1
:1001400064256320002E0048693A25346920204345
:10015000663A253469200054683A253469202059CC
:10016000613A253469200050693A253469202052CB
:100170006F3A253469200045787465726E436F6E5E
:1001800074726F6C20200052616E67653A25336986
:100190002D25336900506F736974696F6E3A20259D
:1001A000336900536574706F696E7420202533695C
:1001B00000536572766F202000506F343A2025334B
:1001C0006920506F383A2025336900506F333A2048
:1001D00025336920506F373A2025336900506F323C
:1001E0003A2025336920506F363A20253369005074
:1001F0006F313A2025336920506F353A2025336915
:10020000004F6666436F757273653A202535690045
:1002100048656164696E673A20202025356900438E
:100220006F757273653A2020202025356900436F71
:100230006D70617373202020202020200052432DF8
:100240004C6576656C3A2025356900566F6C746193
:1002500067653A202025356900486569676874201C
:1002600025346920282533692900526F6C6C2020C1
:100270002025346920282533692900506974636872
:100280002020253469202825336929004143432053
:100290002D2053656E736F720059617720202025E1
:1002A000346920282533692900526F6C6C20202581
:1002B0003469202825336929005069746368202532
:1002C00034692028253369290059617720202025A9
:1002D000346920282533692900526F6C6C20202551
:1002E0003469202825336929005069746368202502
:1002F0003469202825336929004779726F202D2021
:1003000053656E736F720050333A25346920205064
:10031000343A253469200050313A25346920205080
:10032000323A253469200047733A25346920205930
:10033000613A253469200050693A253469202052F9
:100340006F3A253469200043373A25346920204329
:10035000383A253469200043353A25346920204352
:10036000363A253469200043333A25346920204346
:10037000343A253469200043313A2534692020433A
:10038000323A253469200048656164696E673A2015
:10039000202025356900526F6C6C3A2020202020E7
:1003A000202535690050697463683A202020202098
:1003B0002535690041747469747564650048656920
:1003C00067687420436F6E74726F6C004E6F20000C
:1003D0004F6666736574202020203A2535690041F8
:1003E00069722050726573732E3A25356900536522
:1003F0007420506F696E743A20253569004865692C
:100400006768743A20202020253569002863292058
:10041000486F6C676572204275737300536574741E
:10042000696E673A202564200048573A5625642EA5
:1004300025642053573A25642E25642563002B201C
:100440004D696B726F4B6F70746572202B005B256A
:10045000695D005B25695D000A0D5573696E672053
:10046000506172616D6574657220536574202564F6
:10047000000A0D496E69742E20454550524F4D3A81
:100480002047656E65726174696E672044656661B8
:10049000756C742D506172616D657465722E2E2EAF
:1004A000000011241FBECFEFD0E1DEBFCDBF14E0AE
:1004B000A0E0B1E0EEEFF0E802C005900D92A43BA1
:1004C000B107D9F718E0A4EBB4E001C01D92A73141
:1004D000B107E1F70E9470020C947E400C9400007A
:1004E000CF93DF93F89414B815B8189B02C08BE033
:1004F00001C08AE08093000184B1836084B92091B7
:1005000000012A3011F4289A01C02898299884B74C
:10051000877F84BF80916000886180936000109223
:10052000600080ED97E09093D0048093CF04109208
:1005300068071092670710926F0510926E0510926F
:100540006D0510926C0510926B0510926A052A30A9
:1005500011F4289801C0289A0E9468150E948A0BFD
:100560000E94860C0E94E5050E949C160E94610D67
:100570000E94C1150E942E3B78941092690685E472
:1005800080936A0687E080936B0620910001822F9A
:100590006AE00E94AF3F492F50E0822F0E94AF3F98
:1005A00090E02BE630E03F932F9325E430E03F933B
:1005B0002F931F921F925F934F939F938F9381E18D
:1005C00091E09F938F931F920E94E60880EF90E046
:1005D0009F938F931F920E94E608299A0E94773A70
:1005E00084E00E9477382DB73EB7205F3F4F0FB6AB
:1005F000F8943EBF0FBE2DBF8050944050F08AED5E
:1006000090E09F938F931F920E94E6080F900F90A7
:100610000F9084EF91E00E94BF0BEC01CE010E948D
:10062000C80B8823D9F38DEB90E09F938F931F9293
:100630000E94E6088091D1070F900F900F9080FFE5
:1006400020C089E990E09F938F931F920E94E60853
:1006500088EE93E00E94BF0BEC010E945D100F90AA
:100660000F900F90CE010E94C80B8823D9F384E924
:1006700090E09F938F931F920E94E6080F900F9037
:100680000F900E94FC20809100018A3011F428987C
:1006900001C0289A80ED97E09093D0048093CF0416
:1006A00085E58093730688E890E09F938F931F926F
:1006B0000E94E6088091D1070F900F900F9082FF63
:1006C00003C08CE790E002C084E790E09F938F9393
:1006D0001F920E94E6080F900F900F9080E790E025
:1006E0009F938F931F920E94E6080E949D1088E8B6
:1006F00093E190936D0380936C030F900F900F9094
:100700008091CC048823E1F31092CC040E94A622AD
:100710000E94B520209100012A3011F4289801C0D0
:10072000289A80910301882321F08150809303014E
:1007300012C01092C0041092C10410927D06109253
:100740007B0510927A0510927D0510927C0510921F
:100750007F0510927E0580916C0390916D03892B2B
:1007600001F585E090E090936D0380936C030E9407
:10077000E81580910403909105038F5F9F4FF9F472
:10078000809156058823D9F080E197E29093D004B8
:100790008093CF0480E890E0909305038093040356
:1007A0000EC080916C0390916D03019790936D033F
:1007B00080936C032A3011F4289801C0289A809104
:1007C000CC04882321F080915605882311F40E94DF
:1007D00054060E945007CE010E94C80B882309F4DA
:1007E0008FCF20910803309109038091E10790E0B9
:1007F000281739079CF480910403909105038F5FBB
:100800009F4F61F480E797E19093D0048093CF04E9
:1008100080E093E0909305038093040384E190E0EB
:100820000E94BF0BEC016CCF1F920F920FB60F927C
:1008300011248F939F93EF93FF938091020188235C
:10084000E1F48091C8049091C90401969093C90481
:100850008093C804FC01E054F94FE081ED3019F0B9
:100860008639910539F41092C9041092C80481E0C8
:1008700080930201E093C60004C01092C904109254
:10088000C804FF91EF919F918F910F900FBE0F9031
:100890001F9018951F920F920FB60F9211242F934D
:1008A0003F934F935F936F937F938F939F93AF93F8
:1008B000BF93CF93DF93EF93FF937091C600809126
:1008C000BA04882309F06DC06091C504662371F4F1
:1008D000733279F47093CF0581E08093C50483E28D
:1008E00090E09093C7048093C6045BC0663908F01B
:1008F00054C0A62FB0E02091C6043091C7047D30CB
:1009000069F0A153BA4F7C936F5F6093C504270FC2
:10091000311D3093C7042093C60443C0FD01E35347
:10092000FA4F9081ED01C253DA4F8881A901491B2A
:100930005109481B51095F705093C7044093C60486
:100940002081CA0136E0969587953A95E1F7835C58
:100950008217F1F49881842F8F73835C8917C1F417
:1009600081E08093BA046093BB04A153BA4F7C9397
:100970008091D105823571F488E190E02CE00FB6CA
:10098000F894A895809360000FBE2093600002C089
:100990001092BA041092C50404C01092C5041092BB
:1009A000BA04FF91EF91DF91CF91BF91AF919F91E9
:1009B0008F917F916F915F914F913F912F910F9008
:1009C0000FBE0F901F901895DC0120E030E040E052
:1009D00050E008C0FA01E054F94F8081280F311D22
:1009E0004F5F5F4F4A175B07A9F73F70C90146E0A9
:1009F000969587954A95E1F7835CFD01E054F94FA0
:100A0000808311962F73235CFD01E054F94F2083FE
:100A1000AF53B94F8DE08C93109202018091C006C4
:100A20008093C60008951F93CF93DF93EA01722F3E
:100A300093E29093C0066093C1068093C206A3E040
:100A4000B0E060E04FC0FE01E60FF11D90816F5FE6
:100A5000715019F410E040E00FC0FE01E60FF11DE7
:100A600040816F5F715011F410E006C0FE01E60F87
:100A7000F11D10816F5F7150892F86958695835C7B
:100A8000FD01E054F94F808350E09A0184E03695EF
:100A900027958A95E1F7892F90E083709070F4E0B4
:100AA000880F991FFA95E1F7282B235CFD01EF537E
:100AB000F94F2083812F82958695869583704F709C
:100AC0005070440F551F440F551F842B835CFD014C
:100AD000EE53F94F80831F73135CFD01ED53F94F03
:100AE00010831496772309F0AECFCD010E94E40461
:100AF000DF91CF911F9108951F93CF93DF93EC0166
:100B000070E0A22FB0E0129748C0E42FF0E0E1536C
:100B1000FA4F30814F5FE42FF0E0E153FA4F5081FC
:100B20004F5FE42FF0E0E153FA4F10814F5FE42F65
:100B3000F0E0E153FA4F20814F5F842F90E0A81737
:100B4000B90774F15D53FE01E70FF11D852F829502
:100B50008F703D53330F330F382B3083613001F1E9
:100B6000912F9D537F5FFE01E70FF11D715052954C
:100B7000507F892F86958695582B508363506F3F01
:100B800079F07E5FFE01E70FF11D9295990F990FA5
:100B9000907C2D53922B90837F5F662309F0B5CF15
:100BA000DF91CF911F9108951F93182F8A3019F468
:100BB0008DE00E94D4058091C00085FFFCCF10938A
:100BC000C60080E090E01F9108951F931FB7F8942E
:100BD0008091C1008F778093C1008091C1008F7B8D
:100BE0008093C100589A5098599A519A1092C50012
:100BF0008AE28093C4008091C00082608093C0002C
:100C000088E18093C1008091C2008F778093C200F9
:100C10008091C2008F7B8093C2008091C2008F7D43
:100C20008093C2008091C2008F7E8093C200809129
:100C3000C200877F8093C2008091C1008B7F809328
:100C4000C1008091C20084608093C2008091C20084
:100C500082608093C20002C08091C6008091C00073
:100C600087FDFACF8091C10080688093C100809198
:100C7000C10080648093C1001092BA0481E0809327
:100C8000020188EC90E00E94BF0B9093680680936D
:100C900067068CED90E00E94BF0B909366068093F0
:100CA00065061FBF1F91089580910201882309F4F2
:100CB000F6C08091B504882371F0809102018823E9
:100CC00051F06091C4042BE043E756E087E40E94B2
:100CD00013051092B50480916506909166060E94F6
:100CE000C80B882309F44BC080910201882309F4C2
:100CF00046C0609118057091190580911A05909170
:100D00001B052CE630E040E050E00E9404403093A8
:100D1000100820930F0860912005709121058091A3
:100D20002205909123052CE630E040E050E00E943F
:100D30000440309312082093110880918B03809314
:100D4000130880918C038093140880914E05809342
:100D500015086091C40428E04FE058E087E70E943E
:100D6000130580914E05853010F010924E0583E6F4
:100D700090E00E94BF0B9093660680936506809179
:100D80006706909168060E94C80B882321F4809121
:100D9000B7048823B1F080910201882391F060911B
:100DA000C40422E44EE756E084E40E941305109246
:100DB000B7048AEF90E00E94BF0B9093680680937F
:100DC0006706609101016F3F89F0462F50E094E083
:100DD000440F551F9A95E1F74C5F5E4F605D20E12F
:100DE00081E40E9413058FEF8093010190915607D3
:100DF0009923A1F080910201882381F083E28093FE
:100E0000C0069093C1068DE08093C2061092020145
:100E1000109256078091C0068093C6008091B60458
:100E2000882359F180910201882339F10E94A6108C
:100E30001092B6043091B904932F9F5F9093B90438
:100E4000943021F08091B804882359F02EE143E6D4
:100E500057E060E084E30E9413058FEF8093B904AC
:100E60000CC044E1949FA0011124465E5C4F24E134
:100E700060E0832F8F5C0E9413058091B404882367
:100E800071F080910201882351F06091C4042AE03E
:100E900049E656E086E50E9413051092B4040895D1
:100EA0001F93CF93DF93CDB7DEB724970FB6F89497
:100EB000DEBF0FBECDBF8091BA04882309F423C1E1
:100EC0008091D105883609F486C0893690F482363F
:100ED00009F453C0833630F48B34F1F0813609F0D5
:100EE00010C13FC0833609F45CC0873609F009C1E0
:100EF000A7C0813738F48C3608F0D0C08B3609F0A3
:100F000000C18DC0843709F481C0863709F494C0CC
:100F1000813709F0F6C098C02091BB0443E062E03D
:100F2000CE0101960E947C0589819A8190936F037E
:100F300080936E0380916E0390916F0320917003F4
:100F400030917103845E9D4F821B930B68E671E0C4
:100F50000E94CF3F845B904090934D0580934C0559
:100F6000D0C02091BB0443E062E0CE0103960E9412
:100F70007C058B81809301012AC02091BB0443E052
:100F80006BE083E796E00E947C058091F2049091EB
:100F90007506892B8093F20480917C068093560716
:100FA000B0C02091BB0443E06BE083E796E00E9471
:100FB0007C058091F20490917506892B8093F20450
:100FC00080917C068093560781E08093B7048FEF71
:100FD0008093030196C02091BB0443E062E0CE0100
:100FE00003960E947C058091F2049B81892B80935B
:100FF000F2048C818F3F21F481E08093B80402C019
:101000001092B80481E08093B6047BC02091BB04A9
:1010100043E064E08CEB94E00E947C05D8CF209103
:10102000BB0443E064E080EC94E00E947C05809186
:10103000C30480935607CBCF81E08093B40461C092
:1010400081E08093B5045DC02091BB0443E062E081
:10105000CE0103960E947C05809102018823E1F372
:101060008B818F3F71F0863010F085E08B838B8110
:101070000E94A5386091C4048B8126E449EC57E0B6
:1010800009C01091C40482E00E94663826E449EC4D
:1010900057E0612F855B0E94130533C02091BB048C
:1010A00043E066E489EC97E00E947C058091D105DD
:1010B0008B560E9490386091F40770E080E090E0D9
:1010C00024EC39E040E050E00E94903F60937403CC
:1010D0007093750380937603909377036091F5077F
:1010E00070E080E090E00E94903F609378037093FE
:1010F000790380937A0390937B030E94683A0E945D
:1011000061221092BA0424960FB6F894DEBF0FBE87
:10111000CDBFDF91CF911F910895982F80915707F0
:10112000813069F48091F104E82FF0E0E65EFC4F35
:1011300090838F5F8093F10421E030E005C0892F18
:101140000E94D405282F30E0C90108951F93182F5D
:1011500004C080E30E948D0811501116D4F31F9132
:1011600008951F93182F04C080E20E948D0811502B
:101170001116D4F31F9108950F931F93CF93DF930C
:101180008C01EB0108C0F8010F5F1F4FE4918E2F17
:101190000E948D0821972097B1F7DF91CF911F9181
:1011A0000F9108950F931F93CF93DF938C01EB0161
:1011B00006C0F80181918F010E948D082197209728
:1011C000C1F7DF91CF911F910F9108952F923F9218
:1011D0004F925F926F927F928F929F92AF92BF9247
:1011E000CF92DF92EF92FF920F931F93CF93DF93F3
:1011F000CDB7DEB7E5970FB6F894DEBF0FBECDBF13
:101200002B968FAD2B9780935707CE01835B9F4F13
:101210009B838A832D964EAC5FAC2D971EA61FA68E
:1012200018AA19AA9E01225D3F4F3DAB2CAB82014B
:1012300002C00F5F1F4FF801F490FF2019F0F5E294
:10124000FF16B9F7B8016419750919F0C2010E94B7
:10125000BC08FF2009F445C228010894411C511C18
:101260001982AA81BB8133241BAA2FEF2AABF2017A
:101270000894411C511CB490632D70E06170707033
:1012800035E7B31621F08B2D80628837C9F46115DC
:10129000710559F02D913D914D915C9113972EA7B9
:1012A0003FA748AB59AB14960BC08D919C911197F9
:1012B0009C0140E050E02EA73FA748AB59AB1296E7
:1012C00030E2B31621F48981882389F61CC043E2F9
:1012D000B41611F458E055C08AE2B81621F09DE228
:1012E000B91671F408C0FD011296E081EBABE7FF7F
:1012F000BECFE195EBABE0E13E2AFFED3F22B7CF59
:101300002BE2B21611F4B982B2CF3EE2B31699F5D0
:10131000F2010894411C511C84918A3221F0B82EAC
:1013200020E030E01DC0FD0112964081518157FF41
:1013300002C04FEF5FEF4AAB9ACFC90153E0880F6D
:10134000991F5A95E1F7220F331F280F391F2B0DD4
:10135000311D20533040F2010894411C511CB490BF
:101360008B2D80538A3048F3A90137FF02C04FEF1D
:101370005FEF4AAB85CF40E3B41629F434FC77CF56
:1013800050E2352A74CF8B2D81538930D8F420E078
:1013900030E0C90103E0880F991F0A95E1F7220F99
:1013A000331F280F391F2B0D311D20533040F20100
:1013B0000894411C511CB4908B2D80538A3048F303
:1013C0002BAB5ECF88E6B81619F494E0392A4FCFDC
:1013D000ECE6BE1619F4F1E03F2A49CFBB83AA839D
:1013E00023E6B21639F41296BB83AA8312978C9126
:1013F0008E8322C134E4B31639F044E6B41631F0DA
:1014000059E6B516A9F502C081E0382A30FE08C0B9
:101410001496BB83AA835E914E913E912E910AC091
:101420001296BB83AA839E918E919C01442737FD1F
:101430004095542F2EA73FA748AB59AB8EA59FA52B
:10144000A8A9B9A9BB238CF42EA53FA548A959A9E1
:1014500050954095309521953F4F4F4F5F4F2EA7A8
:101460003FA748AB59AB8DE28983BAE02B2E80C0F1
:101470003FE4B31621F04FE6B41631F402C051E058
:10148000352AA8E02A2E73C080E7B81689F4129690
:10149000BB83AA839E918E919C0140E050E02EA7D1
:1014A0003FA748AB59AB30E4332AF8E7BF2E5DC005
:1014B00043E7B416D1F51296BB83AA83DE90CE9093
:1014C000C114D10489F488E28E838EE68F8385E788
:1014D00088878CE689878A8789E28B871C86E6E085
:1014E000CE2ED12CCC0EDD1E5AA957FD14C0452F8F
:1014F000552747FD509560E070E0C6010E94683DA9
:10150000009711F4FAA80EC0F82EFC188AA98F15BE
:101510004CF4F82E07C0F60101900020E9F731974E
:10152000FE2EFC18198240E090C095E5B91621F016
:10153000A5E7BA1631F402C0B1E03B2A7AE0272EC3
:1015400016C0E8E5BE1621F0F8E7BF1609F070C036
:1015500033FE0BC02EA53FA548A959A92115310579
:101560004105510511F030E4332A60E1262E19823D
:101570004AA947FD02C05FED35228EA59FA5A8A907
:10158000B9A90097A105B10549F49AA9992331F4A5
:101590005EE2C52ED12CCC0EDD1E46C06EA47FA40B
:1015A00088A899A84EE2C42ED12CCC0EDD1EE22CC8
:1015B000FF2400E010E06EA57FA588A999A9A801E5
:1015C00097010E94E23F6A3020F430E3A32EA60E7A
:1015D00008C027E5A22EA60EA8E5BA1611F4BFEDA5
:1015E000AB22F601A2926F016EA57FA588A999A9E9
:1015F000A80197010E94E23F2EA73FA748AB59AB35
:101600006E147F048006910618F039014A01D3CF89
:10161000F8E02F1649F433FE07C020E3A21621F0AC
:1016200080E3D6018E936D01FCA8FC184AA90DC079
:10163000BB2009F456C0BE82198296E0C92ED12C77
:10164000CC0EDD1E40E0FF24F394E42EEF18E7FCFF
:10165000EE248981882319F08F2D8F5F06C036FC18
:1016600002C08F2D02C08F2D8E5FA82EAE0C032DD1
:1016700010E080E3882E912C802291228114910425
:1016800021F48BA98A190E94B1088981882329F045
:1016900061E070E0CE01019609C006FF09C080E359
:1016A0008C83BD8262E070E0CE0104960E94D20875
:1016B000B0E28B16910421F48BA98A190E94A60826
:1016C0008E2D0E94A6086F2D772767FD7095C601A5
:1016D0000E94D20804FFABCD8BA98A190E94B108E1
:1016E000A6CDE5960FB6F894DEBF0FBECDBFDF9155
:1016F000CF911F910F91FF90EF90DF90CF90BF900F
:10170000AF909F908F907F906F905F904F903F90A1
:101710002F9008952FB7F894909100019A3019F402
:10172000529A5A9802C03F9A479884B1886184B906
:1017300085B1877E85B99A3019F4529A5A9802C0B9
:101740003F9A479884B58F7A84BD84B5836A84BDF7
:1017500085B5877385BD85B5887F826085BD17BCDB
:1017600088E788BD16BC80916E00897F80936E00EB
:1017700080916E00816080936E002FBF089520914C
:10178000CA043091CB042F5F3F4F820F931F0895FF
:101790002091CA043091CB04821B930B892F992787
:1017A0008695807490E008951F920F920FB60F9265
:1017B00011242F933F934F935F936F937F938F9356
:1017C0009F93AF93BF93EF93FF938091D104815088
:1017D0008093D1048F3FB9F489E08093D104809144
:1017E00006038F5F817080930603882319F481E0DC
:1017F0008093CC048091CA049091CB04019690937D
:10180000CB048093CA048091CF049091D004892B9B
:10181000B1F08091CF049091D00401979093D004BF
:101820008093CF042091CF043091D00480910403A1
:101830009091050382239323892BD1F406C08FEF67
:101840009FEF9093050380930403809100018A30F9
:1018500039F404C05A9A05C0479A03C05A9801C087
:1018600047988091D10783FF08C00E94383B05C08C
:10187000809100018A3081F7EDCFFF91EF91BF9108
:10188000AF919F918F917F916F915F914F913F9118
:101890002F910F900FBE0F901F901895AC012091C3
:1018A000CA043091CB042F5F3F4F05C080917A006E
:1018B000886C80937A008091CA049091CB04B9011E
:1018C000681B790BCB01840F951F80709078892F4E
:1018D00099278695882351F30895AC012091CA0475
:1018E0003091CB042F5F3F4F8091CA049091CB047D
:1018F000B901681B790BCB01840F951F807090781C
:10190000892F99278695882379F308959FB7F894AE
:10191000579A5F9AE0EBF0E080818F788083808136
:1019200083688083E1EBF0E080818673808380812F
:10193000866080838AE08093B3001092B200E0E773
:10194000F0E080818A7F80838081826080839FBF76
:1019500008951F920F920FB60F921124FF920F93CA
:101960001F932F933F934F935F936F937F938F9327
:101970009F93AF93BF93EF93FF93809107038150A1
:10198000809307038F3F09F082C08091B00080935D
:10199000B0008091B00080688093B0008091930384
:1019A00090E09093D3048093D2048091FE07F0904E
:1019B000EB0780FF23C00091D2041091D304609103
:1019C00018057091190580911A0590911B0520E862
:1019D00030E040E050E00E940440CA01B9012F2DE0
:1019E00030E040E050E00E94903F20E032E040E0F4
:1019F00050E00E940440020F131F22C00091D20445
:101A00001091D304609118057091190580911A0501
:101A100090911B0520E830E040E050E00E94044037
:101A2000CA01B9012F2D30E040E050E00E94903F04
:101A300020E032E040E050E00E940440021B130B23
:101A40001093D3040093D2042091D2043091D30494
:101A50008091EC0790E02817390754F02091D204C8
:101A60003091D3048091ED0790E08217930724F41E
:101A70009093D3048093D2048091D2049091D304A4
:101A80008093B3008091EE078093070306C0809196
:101A9000B0008F738093B0005F98FF91EF91BF917A
:101AA000AF919F918F917F916F915F914F913F91F6
:101AB0002F911F910F91FF900F900FBE0F901F90CD
:101AC00018959FB7F89411B812B88FEF80937E00E5
:101AD000ECE7F0E080818F7180838081807E80835D
:101AE000AAE7B0E087E28C93EBE7F0E08081887FA3
:101AF00080838C91886C8C939FBF08951F920F9266
:101B00000FB60F921124EF92FF920F931F932F9312
:101B10003F934F935F936F937F938F939F93AF9375
:101B2000BF93CF93DF93EF93FF9380917A008773F6
:101B300080937A008091EF048F5F8093EF0481504F
:101B4000853009F47EC0863090F4823009F440C0BC
:101B5000833030F48823F1F0813009F082C22FC045
:101B6000833009F441C0843009F07BC25AC0883008
:101B700009F4B2C0893038F4863009F473C0873074
:101B800009F06FC28CC0893009F4C3C08A3009F0F3
:101B900068C2DBC180917800909179009093EE0447
:101BA0008093ED0481E08093F0048091E4049091AF
:101BB000E50401969093E5048093E40456C2809175
:101BC0007800909179009093EC048093EB0482C0AC
:101BD00080917800909179009093EA048093E904D1
:101BE00084E08093F00441C24091080350910903BE
:101BF00080917800909179009A01220F331F240F71
:101C0000351F63E070E00E94BB3F260F371F3695FB
:101C1000279536952795309309032093080386E08E
:101C2000E0CF8091120590911305209178003091BA
:101C30007900821B930B9093DD048093DC0487E092
:101C4000D0CF80917800909179002091100530914B
:101C50001105821B930B9093DF048093DE04109296
:101C6000F00403C2809100012091ED043091EE0454
:101C70008A3049F48091780090917900820F931F07
:101C80009695879506C08091780090917900820F93
:101C9000931F9093DB048093DA0481E0A2CF8091BC
:101CA00000012091EB043091EC048A3049F48091DA
:101CB000780090917900820F931F9695879506C0C2
:101CC0008091780090917900820F931F9093D904AE
:101CD0008093D80482E085CF809100012091E904AF
:101CE0003091EA048A3049F480917800909179002B
:101CF000820F931F9695879506C0809178009091EA
:101D00007900820F931F9093D7048093D60485E0C7
:101D100068CF6091780070917900E0901405F090A0
:101D200015050091160510911705882777FD8095F8
:101D3000982F0E94753EA80197010E94753D0E9450
:101D4000423E7093E1046093E004E091E004F0917E
:101D5000E1048091DE049091DF04C091DC04D09115
:101D6000DD0497FF03C0909581959F4F64E070E07C
:101D70000E94CF3F9B01CE01D7FF03C09095819574
:101D80009F4F64E070E00E94CF3F260F371FE20FA5
:101D9000F31FF093E104E093E0048091E00490915C
:101DA000E10402970CF43EC0609114057091150592
:101DB000809116059091170520E030E84BE354E43C
:101DC0000E94B03E88230CF078C060911405709199
:101DD000150580911605909117052AE037ED43EA25
:101DE0005CE30E94763D6093140570931505809323
:101DF0001605909317058091580590915905845FB9
:101E0000914008F05AC060911405709115058091B9
:101E10001605909117052DEC3CEC4CEC5DE30E940F
:101E2000763D43C08091E0049091E1048F5F9F4F25
:101E30000CF043C060911405709115058091160552
:101E40009091170520E030E849E054E40E94B43E48
:101E500018169CF560911405709115058091160572
:101E6000909117052AE037ED43EA5CE30E94753D47
:101E700060931405709315058093160590931705CC
:101E80008091580590915905845F9140B0F460911C
:101E900014057091150580911605909117052DEC8C
:101EA0003CEC4CEC5DE30E94753D6093140570932F
:101EB00015058093160590931705809178009091F1
:101EC00079009093D5048093D404209148053091F3
:101ED000490540914A0550914B058091E00490914D
:101EE000E104AA2797FDA095BA2F820F931FA41F84
:101EF000B51F8093480590934905A0934A05B09378
:101F00004B05E0904805F090490500914A05109175
:101F10004B05609148057091490580914A05909163
:101F20004B0520E034E040E050E00E940440E21A1B
:101F3000F30A040B150BE0924805F0924905009353
:101F40004A0510934B0583E04CCEE0917800F09168
:101F500079008091E6049091E704E80FF91FF0936F
:101F6000E704E093E6048091E8048F5F8093E8043F
:101F7000853008F476C08091780090917900909334
:101F80000F0380930E034091E2045091E3042091EB
:101F90005807309159072E1B3F0B80918005909177
:101FA0008105281B390B8091820390E0BC01269F9C
:101FB000C001279F900D369F900D11249A01A3E038
:101FC000220F331FAA95E1F7241B350B820F931FB5
:101FD00068E070E00E94CF3F7093E3046093E204F6
:101FE000E0900A03F0900B0300910C0310910D0395
:101FF000BF01882777FD8095982FA8019701220FB0
:10200000331F441F551F2E0D3F1D401F511F620FD0
:10201000731F841F951F24E030E040E050E00E94D1
:10202000044020930A0330930B0340930C03509316
:102030000D03209158073091590780910A03909120
:102040000B03A0910C03B0910D03281B390B3093A7
:102050008105209380051092E8041092E704109205
:10206000E6041092F0041092EF0480917C00807ED0
:102070009091F004892B80937C008091EF04882359
:1020800029F080917A00886C80937A00FF91EF911B
:10209000DF91CF91BF91AF919F918F917F916F9180
:1020A0005F914F913F912F911F910F91FF90EF9072
:1020B0000F900FBE0F901F9018951F93CF93DF9333
:1020C00083E00E946638182F853108F01A5017BD3A
:1020D00084E690E00E944E0C80910E0390910F03D5
:1020E00082559340C0F410E016C017BD82E390E023
:1020F0000E944E0CDF93CF931F920E94E6088091BE
:102100000E0390910F030F900F900F9084589340FF
:1021100030F01F5F02C0C5E4D1E01A3F30F3612FF9
:1021200083E00E946F3810935A078CE291E00E947E
:102130004E0CDF91CF911F910895EAE1F3E080E228
:10214000819383E0EA36F807D1F708951F938091D1
:10215000F204282F30E0C90181709070682F882325
:10216000A9F08091F304882311F0815002C080917E
:102170006A038093F304EAE1F3E080E2819383E071
:10218000EA36F807D1F78FEF8093B904A9014270BE
:10219000507021FF17C09091F30480916A03981743
:1021A00019F41092F30403C09F5F9093F304EAE1E3
:1021B000F3E080E2819393E0EA36F907D1F78FEFFD
:1021C0008093B904662321F0452B11F01092F3049B
:1021D0008091F304282F30E08A3040F481E180932D
:1021E000F1043F932F9383E594E007C080E180934F
:1021F000F1043F932F938EE494E09F938F9381E0BB
:102200008F930E94E6080F900F900F900F900F9001
:102210001091F304153009F4FBC1163090F412301C
:1022200009F4D0C0133030F4112309F1113009F052
:1022300046C465C0133009F41BC1143009F03FC413
:102240006BC1183009F411C3193038F4163009F491
:1022500099C2173009F033C4E3C21A3009F49FC39E
:102260001A3008F440C31B3009F029C4D6C31092B9
:10227000F1048EE394E09F938F9311E01F930E94EB
:10228000E60884E18093F10420910001822F6AE046
:102290000E94AF3F492F50E0822F0E94AF3F90E055
:1022A0002BE630E03F932F9325E430E03F932F93CC
:1022B0001F921F925F934F939F938F9389E294E0B5
:1022C0009F938F931F930E94E60888E28093F10406
:1022D0000E94683A90E09F938F938CE194E09F93E3
:1022E0008F931F930E94E6088CE38093F1048CE0A7
:1022F00094E09F938F931F930E94E608DCC3809124
:10230000D10780FF47C01092F10480918005909121
:1023100081059F938F938DEF93E09F938F931F93EE
:102320000E94E60884E18093F104809182059091F7
:1023300083059F938F938EEE93E09F938F931F93CC
:102340000E94E60888E28093F10480910E03909148
:102350000F039F938F938FED93E09F938F931F9322
:102360000E94E6088CE38093F10480915A0790E084
:102370009F938F9380ED93E09F938F931F930E9481
:10238000E6088DB79EB744960FB6F8949EBF0FBE71
:102390008DBF9AC384E18093F1048CEC93E09F930A
:1023A0008F931F930E94E60888E28093F1048DEBDF
:1023B00093E09F938F931F930E94E6088DB79EB77B
:1023C0000696E2CF1092F10484EB93E09F938F93F3
:1023D00011E01F930E94E60884E18093F10460916C
:1023E00018057091190580911A0590911B0520E040
:1023F00034E040E050E00E9404405F934F933F93ED
:102400002F9385EA93E09F938F931F930E94E60892
:1024100088E28093F10460912005709121058091FC
:1024200022059091230520E034E040E050E00E9436
:1024300004405F934F933F932F9386E993E09F93DC
:102440008F931F930E94E6088CE38093F1048091A0
:102450006E0390916F039F938F9387E893E09F9310
:102460008F931F930E94E6088DB79EB746968CCF38
:102470001092F10480916707909168072091650799
:10248000309166079F938F933F932F9387E793E055
:102490009F938F9311E01F930E94E60884E180933D
:1024A000F10480916B0790916C072091690730913E
:1024B0006A079F938F933F932F9387E693E09F93B1
:1024C0008F931F930E94E60888E28093F104809125
:1024D0006F079091700720916D0730916E079F9361
:1024E0008F933F932F9387E593E09F938F931F9351
:1024F0000E94E6088CE38093F10480917307909129
:10250000740720917107309172079F938F933F93C7
:102510002F9387E493E03AC21092F104E091CA0746
:10252000F0E0EE0FFF1FED59F84F20813181E0916F
:10253000C907F0E0EE0FFF1FED59F84F8081918140
:102540003F932F939F938F9387E393E09F938F9372
:1025500011E01F930E94E60884E18093F104E0916A
:10256000CC07F0E0EE0FFF1FED59F84F20813181CD
:10257000E091CB07F0E0EE0FFF1FED59F84F80819F
:1025800091813F932F939F938F9387E293E09F9343
:102590008F931F930E94E60888E28093F104E091F4
:1025A000CE07F0E0EE0FFF1FED59F84F208131818B
:1025B000E091CD07F0E0EE0FFF1FED59F84F80815D
:1025C00091813F932F939F938F9387E193E09F9304
:1025D0008F931F930E94E6088CE38093F104E091AF
:1025E000D007F0E0EE0FFF1FED59F84F2081318149
:1025F000E091CF07F0E0EE0FFF1FED59F84F80811B
:1026000091813F932F939F938F9387E093E0BEC177
:102610001092F10489EF92E09F938F9311E01F9342
:102620000E94E6080F900F900F90809100018A3071
:1026300009F04AC084E18093F1044091060550916D
:1026400007058091D6049091D7042091060530911A
:102650000705821B930B5F934F939F938F9389EE94
:1026600092E09F938F931F930E94E60888E28093E5
:10267000F10440910805509109058091D80490918A
:10268000D9042091080530910905821B930B5F93B3
:102690004F939F938F9389ED92E09F938F931F9316
:1026A0000E94E6088CE38093F10480910A059091E2
:1026B0000B052091B5073091B6079F938F933F93F9
:1026C0002F9389EC92E055C084E18093F1048091CE
:1026D00006059091070562E070E00E94CF3F80916F
:1026E000D6049091D7042091060530910705821BEE
:1026F000930B7F936F939F938F9389EB92E09F93BC
:102700008F931F930E94E60888E28093F1048091E2
:1027100008059091090562E070E00E94CF3F80912A
:10272000D8049091D9042091080530910905821BA5
:10273000930B7F936F939F938F9389EA92E09F937C
:102740008F931F930E94E6088CE38093F10480919D
:102750000A0590910B0562E070E00E94CF3F8091E6
:10276000B5079091B6077F936F939F938F9389E9F5
:1027700092E09F938F931F930E94E6088DB79EB7B8
:10278000459602CE1092F1048CE892E09F938F93CD
:1027900011E01F930E94E60884E18093F104809188
:1027A0001005909111052091DE043091DF049F9374
:1027B0008F933F932F938BE792E09F938F931F9379
:1027C0000E94E60888E28093F104809112059091BE
:1027D00013052091DC043091DD049F938F933F9388
:1027E0002F938AE692E09F938F931F930E94E608AF
:1027F0008CE38093F104609114057091150580912C
:102800001605909117050E94423E2091AA0730912B
:10281000AB077F936F933F932F9389E592E046C177
:1028200084E18093F10480910803909109039F93C0
:102830008F938BE492E09F938F9311E01F930E94FC
:10284000E60888E28093F1048091FF0490910005EE
:102850009F938F938DE392E09F938F931F930E949A
:10286000E6088DB79EB70A968FCD1092F1048EE2DE
:1028700092E09F938F9311E01F930E94E60884E1FA
:102880008093F10480917003909171039F938F93D3
:102890008FE192E09F938F931F930E94E60888E256
:1028A0008093F10480916E0390916F039F938F93B7
:1028B00080E192E09F938F931F930E94E6088CE340
:1028C0008093F10480914C0590914D059F938F93D7
:1028D00081E092E09F938F931F930E94E6088DB74B
:1028E0009EB7429651CD1092F1048091620590916D
:1028F000630520915A0530915B059F938F933F9319
:102900002F938FEE91E09F938F9311E01F930E947E
:10291000E60884E18093F104809164059091650557
:1029200020915C0530915D059F938F933F932F938A
:102930008DED91E09F938F931F930E94E60888E2AC
:102940008093F104809166059091670520915E0562
:1029500030915F059F938F933F932F938BEC91E082
:102960009F938F931F930E94E6088CE38093F1045A
:10297000809168059091690520916005309161050D
:102980009F938F933F932F9389EB91E09F938F9326
:102990001F930E94E6088DB79EB74C96F5CC109217
:1029A000F10481EB91E09F938F9311E01F930E94BC
:1029B000E60884E18093F1048091930390E09F9373
:1029C0008F9383EA91E09F938F931F930E94E60871
:1029D00088E28093F1048091D2049091D3049F9374
:1029E0008F9385E991E09F938F931F930E94E60850
:1029F0008CE38093F1042091ED0730E08091EC07A7
:102A000090E03F932F939F938F9387E891E09F935C
:102A10008F931F930E94E608B4CC1092F10487E7CD
:102A200091E09F938F9311E01F930E94E60884E149
:102A30008093F10420917706332727FD309580910C
:102A40007606992787FD90953F932F939F938F93B9
:102A500087E691E09F938F931F930E94E60888E298
:102A60008093F10420917806332727FD30958091DB
:102A7000790690E03F932F939F938F9387E591E0A2
:102A80009F938F931F930E94E6088CE38093F10439
:102A900020917D0630E080917A06992787FD9095F8
:102AA0003F932F939F938F9387E491E09F938F930E
:102AB0001F930E94E6088DB79EB7489665CC1150CB
:102AC00010936A031092F3041092F2041F91089578
:102AD00087B18C6087B94298439808954091F40477
:102AE0005091F5044431510500F14C3D5105E8F495
:102AF0002091FA043091FB04C901880F991F8417B3
:102B0000950710F4429A01C042982F5F3F4F3093CF
:102B1000FB042093FA04215030402417350730F08D
:102B20001092FB041092FA0401C0429A4091F604FC
:102B30005091F7044431510510F4439808954C3DE9
:102B40005105E8F42091F8043091F904C901880F87
:102B5000991F8417950710F4439A01C043982F5F7B
:102B60003F4F3093F9042093F8042150304024174C
:102B7000350730F01092F9041092F8040895439844
:102B800008959FB7F8943998389A88B1836088B9C6
:102B9000E9EBF0E080818C7F80838AE28093B8004B
:102BA0009FBF089585EA8093BC00089584E98093CF
:102BB000BC0008958093BB0085E88093BC00089515
:102BC00085EC8093BC00089585E88093BC0008954F
:102BD000EF92FF920F931F938CEBE82EF12C84E978
:102BE000F70180831092FC040BEB10E0F801808168
:102BF0008093FD041092FD0480E8F7018083109219
:102C0000BD001092BA00F80110821092B900109223
:102C1000B8000E94C11585EAF7018083F80110828F
:102C200085E8F70180831F910F91FF90EF90089541
:102C30001F920F920FB60F9211248F939F93EF93D1
:102C4000FF938091FC048F5F8093FC04815083305C
:102C5000D1F1843028F4813081F0823060F508C0F1
:102C60008530C1F18530A0F1863009F04FC03EC0FB
:102C70008091FD04880F8E5A12C08091FD048F5FF1
:102C80008093FD048150813069F0813030F08230D2
:102C900061F0833009F047C00BC08091A107809399
:102CA000BB0020C08091B707FACF8091AC07F7CF67
:102CB0008091C807F4CF8091FD04843010F4109205
:102CC000FC0485EA10C08091FE04880F8D5AE7CF7E
:102CD00085EC09C0E091FE04F0E08091BB00E55A6C
:102CE000F84F808385E88093BC001DC08091FE046E
:102CF000E82FF0E09091BB00E15AF84F90838F5F8E
:102D00008093FE04843010F01092FE0484E98093D6
:102D1000BC001092FC048AE090E090936D038093D5
:102D20006C031092FD04FF91EF919F918F910F9092
:102D30000FBE0F901F9018959FB7F89456985E9A03
:102D40008AB180638AB98BB18F7C8BB98091000185
:102D50008A3011F4539A5B98809180008C70809334
:102D6000800080918100837E80938100809181002A
:102D7000836C80938100809182008F7380938200A6
:102D800080916F00897F80936F0080916F008162D6
:102D900080936F00109200051092FF049FBF08956A
:102DA0001F920F920FB60F9211242F933F935F93B0
:102DB0006F937F938F939F93AF93BF938091010500
:102DC000882391F42091FF04309100058091FF0445
:102DD0009091000568E070E00E94CF3F261B370B02
:102DE000309300052093FF0410920105BF91AF912D
:102DF0009F918F917F916F915F913F912F910F9054
:102E00000FBE0F901F9018951F920F920FB60F9242
:102E100011240F931F932F933F934F935F936F93BF
:102E20007F938F939F93AF93BF93CF93DF93EF9352
:102E3000FF93209186003091870080910205909148
:102E40000305281B390B8091860090918700909391
:102E5000030580930205C9018D5494400091040537
:102E600010910505835F9A4188F4043011053CF008
:102E700010926B03809101058F5F8093010581E0C3
:102E800090E0909305058093040598C00E301105DD
:102E90000CF094C0C9018B5F9040845B914008F0B6
:102EA00072C0E901C25DD140F801EE0FFF1FED597C
:102EB000F84F808191819E01281B390BC90137FF92
:102EC00003C0909581959F4F069784F48091FF04ED
:102ED00090910005883C91054CF48091FF049091FD
:102EE00000050A96909300058093FF04F801EE0F09
:102EF000FF1FED59F84F20813181C901880F991FBB
:102F0000820F931F8C0F9D1F64E070E00E94CF3FE3
:102F10009B01CE010196861797071CF42150304083
:102F200006C021976C177D0714F42F5F3F4F8091E7
:102F3000FF0490910005E801CC0FDD1F833C910553
:102F4000BCF0FE01ED59F84F80819181A901481B29
:102F5000590BCA0163E070E00E94CF3FCB01880F9C
:102F6000991F860F971FCF57D84F9983888304C026
:102F7000CF57D84F19821882F801EE0FFF1FED5975
:102F8000F84F31832083F8013196F0930505E093E3
:102F90000405E530F10511F45D9A06C05D98E63050
:102FA000F10511F45C9A01C05C98809100018A30AF
:102FB00029F4379711F45B9A01C05B988091FF0464
:102FC00090910005892B49F08091FF0490910005B4
:102FD0000197909300058093FF04FF91EF91DF919B
:102FE000CF91BF91AF919F918F917F916F915F91A1
:102FF0004F913F912F911F910F910F900FBE0F9006
:103000001F9018952F923F924F925F926F927F92EE
:103010008F929F92AF92BF92CF92DF92EF92FF92E8
:103020000F931F93CF93DF93CDB7DEB722970FB6E1
:10303000F894DEBF0FBECDBF80910A0590910B05BD
:103040002091DA043091DB04821B930B9093B60736
:103050008093B5078091D8049091D90420910805F8
:1030600030910905821B930B9093B2078093B107AF
:103070008091D6049091D7042091060530910705E0
:10308000821B930B9093B4078093B307E090B8072B
:10309000F090B9076091DE047091DF04882777FD16
:1030A0008095982F2CE030E040E050E00E94903F67
:1030B0000027F7FC0095102FE60EF71E081F191FBA
:1030C000C801B70122E030E040E050E00E94044037
:1030D0003093B9072093B807E090C207F090C30778
:1030E0006091DC047091DD04882777FD8095982F2E
:1030F0002CE030E040E050E00E94903F0027F7FCD9
:103100000095102FE60EF71E081F191FC801B70102
:1031100022E030E040E050E00E9404403093C307DA
:103120002093C2072091AA073091AB076091E00479
:103130007091E104882777FD8095982F442737FD0B
:103140004095542F620F731F841F951F22E030E0BB
:1031500040E050E00E9404403093AB072093AA0760
:1031600040914005509141056091420570914305A1
:103170002091DE043091DF04C901880F991F820F6E
:10318000931F880F991F880F991FAA2797FDA09555
:10319000BA2F840F951FA61FB71F809340059093E9
:1031A0004105A0934205B0934305409144055091D9
:1031B000450560914605709147052091DC043091EA
:1031C000DD04C901880F991F820F931F880F991F73
:1031D000880F991FAA2797FDA095BA2F840F951FD6
:1031E000A61FB71F8093440590934505A0934605FD
:1031F000B09347052091DE043091DF0480915005A3
:1032000090915105820F931F909351058093500523
:103210002091DC043091DD0480915205909153059A
:10322000820F931F9093530580935205809154050C
:1032300090915505019690935505809354052091E2
:103240003C0530913D0540913E0550913F058091F0
:10325000B5079091B607AA2797FDA095BA2F820FC0
:10326000931FA41FB51F80933C0590933D05A09329
:103270003E05B0933F058091B5079091B6079C013C
:10328000442737FD4095542F8091BA079091BB0792
:10329000A091BC07B091BD07280F391F4A1F5B1FC3
:1032A0002093BA073093BB074093BC075093BD07E8
:1032B000203B83E8380788E0480780E0580764F03F
:1032C000205B3348484050402093BA073093BB07F7
:1032D0004093BC075093BD078091BA079091BB07FC
:1032E000A091BC07B091BD07B7FF0CC080559C47AB
:1032F000A74FBF4F8093BA079093BB07A093BC071B
:10330000B093BD07909188059A83992309F08AC0EC
:1033100080918905882309F085C08091D10786FFB7
:1033200081C06091B5077091B60720912C0530914E
:103330002D0540912E0550912F05E0909503FF2417
:1033400000E010E0882777FD8095982F0E94903F3D
:1033500020E038E040E050E00E940440CA01B9019A
:10336000A80197010E94903F20E030E140E050E04A
:103370000E94044059016A012093C7053093C80593
:103380004093C9055093CA056091B5077091B6077F
:10339000209134053091350540913605509137051F
:1033A000882777FD8095982F0E94903F20E038E095
:1033B00040E050E00E940440CA01B901A801970111
:1033C0000E94903F20E030E140E050E00E94044045
:1033D0002093C3053093C4054093C5055093C6059B
:1033E000D601C501D7FE07C0B095A09590958195EF
:1033F0009F4FAF4FBF4F81389105A105B10574F4C0
:1034000057FF07C050954095309521953F4F4F4F3E
:103410005F4F2138310541055105A4F081E08093CB
:103420004F0510C01092C3051092C4051092C50537
:103430001092C6051092C7051092C8051092C905D2
:103440001092CA058091B1079091B2072090C705EC
:103450003090C8054090C9055090CA05820D931D53
:103460009093B2078093B1070091B1071091B20712
:10347000A090C305B090C405C090C505D090C60506
:1034800080919603682E772488249924C401B3017F
:10349000A60195010E94903F20E032E040E050E01C
:1034A0000E940440020F131F1093B2070093B1074C
:1034B000209138053091390540913A0550913B05EE
:1034C0008091B1079091B207AA2797FDA095BA2FD6
:1034D000820F931FA41FB51F809338059093390561
:1034E000A0933A05B0933B054091340550913505C2
:1034F00060913605709137058091B1079091B207C0
:103500002091840530918505821B930BAA2797FD96
:10351000A095BA2F840F951FA61FB71F809334055F
:1035200090933505A0933605B09337058091340507
:1035300090913505A0913605B0913705E09078035C
:10354000F090790300917A0310917B03E816F90655
:103550000A071B0704F580E197E2A0E0B0E08E19AE
:103560009F09A00BB10B8093340590933505A09370
:103570003605B09337058091340590913505A091BB
:103580003605B09137058093380590933905A0939F
:103590003A05B0933B0520913405309135054091B3
:1035A00036055091370588279927DC018E199F0928
:1035B000A00BB10B281739074A075B0704F580EF0A
:1035C00098EDAFEFBFEFE80EF91E0A1F1B1FE09248
:1035D0003405F09235050093360510933705809138
:1035E000340590913505A0913605B091370580934B
:1035F000380590933905A0933A05B0933B05809127
:10360000D8049091D9040F9734F488E19CEF9093FB
:10361000B2078093B1078091D8049091D90407979D
:1036200034F480E398EF9093B2078093B1079091C0
:10363000000199839A30A9F48091D8049091D9041B
:10364000835F934034F088EE93E09093B2078093C9
:10365000B1078091D8049091D9048A5F9340DCF03F
:1036600014C08091D8049091D904855E974034F0BD
:1036700088EE93E09093B2078093B1078091D804CD
:103680009091D904835F974034F080ED97E0909358
:10369000B2078093B1078091B3079091B4078A195C
:1036A0009B099093B4078093B3070091B3071091DF
:1036B000B407C401B301A20191010E94903F20E030
:1036C00032E040E050E00E940440021B130B1093D4
:1036D000B4070093B3072091300530913105409134
:1036E0003205509133058091B3079091B407AA2712
:1036F00097FDA095BA2F820F931FA41FB51F80932B
:10370000300590933105A0933205B0933305409175
:103710002C0550912D0560912E0570912F058091FB
:10372000B3079091B4072091860530918705821BDD
:10373000930BAA2797FDA095BA2F840F951FA61F5C
:10374000B71F80932C0590932D05A0932E05B09361
:103750002F0580912C0590912D05A0912E05B091FB
:103760002F05E0907403F09075030091760310919B
:103770007703E816F9060A071B0704F588EA91E6BD
:10378000A0E0B0E08E199F09A00BB10B80932C052F
:1037900090932D05A0932E05B0932F0580912C05B5
:1037A00090912D05A0912E05B0912F0580933005A5
:1037B00090933105A0933205B093330520912C05E9
:1037C00030912D0540912E0550912F05882799277E
:1037D000DC018E199F09A00BB10B281739074A0786
:1037E0005B0704F588E59EE9AFEFBFEFE80EF91E31
:1037F0000A1F1B1FE0922C05F0922D0500932E0549
:1038000010932F0580912C0590912D05A0912E05E8
:10381000B0912F058093300590933105A093320528
:10382000B09333058091D6049091D7040F9734F468
:1038300088E19CEF9093B4078093B3078091D604FE
:103840009091D704079734F480E398EF9093B407EE
:103850008093B30799819A30A9F48091D60490910E
:10386000D704835F934034F088EE93E09093B407DD
:103870008093B3078091D6049091D7048A5F9340D8
:10388000DCF014C08091D6049091D704855E9740F7
:1038900034F088EE93E09093B4078093B30780915F
:1038A000D6049091D704835F974034F080ED97E081
:1038B0009093B4078093B30780917A00886C8093CB
:1038C0007A0080913C0590913D05A0913E05B09114
:1038D0003F058093280590932905A0932A05B0936E
:1038E0002B0580912C0590912D05A0912E05B0916E
:1038F0002F058093180590931905A0931A05B0938E
:103900001B058091340590913505A0913605B09145
:1039100037058093200590932105A0932205B0934D
:1039200023058091300590913105A0913205B09129
:10393000330580931C0590931D05A0931E05B0933D
:103940001F058091380590913905A0913A05B091F5
:103950003B058093240590932505A0932605B093FD
:1039600027058091D10787FF63C02A81222309F0B0
:103970005FC080918905882309F05AC08091B30700
:103980009091B407893C91055CF02091B307309188
:10399000B4078091B3079091B4072052334011C00F
:1039A0008091B3079091B40788539F4FA4F420915E
:1039B000B3073091B4078091B3079091B407205EAC
:1039C0003C4F880F991F880F991F280F391F30937C
:1039D000B4072093B3078091B1079091B207893C57
:1039E00091055CF02091B1073091B2078091B10749
:1039F0009091B2072052334011C08091B10790914D
:103A0000B20788539F4FA4F42091B1073091B207B9
:103A10008091B1079091B207205E3C4F880F991FAB
:103A2000880F991F280F391F3093B2072093B107D1
:103A300022960FB6F894DEBF0FBECDBFDF91CF91B7
:103A40001F910F91FF90EF90DF90CF90BF90AF90BC
:103A50009F908F907F906F905F904F903F902F90AE
:103A600008950F931F930AE710E0F8018081877390
:103A700080838091D6049091D7049093B40780936B
:103A8000B3078091D8049091D9049093B2078093A2
:103A9000B1078091DA049091DB049093B60780938C
:103AA000B5076091DE047091DF04882777FD80956B
:103AB000982F2CE030E040E050E00E94903F70935F
:103AC000B9076093B8076091DC047091DD04882722
:103AD00077FD8095982F0E94903F7093C307609365
:103AE000C2078091E0049091E1049093AB0780932A
:103AF000AA07F8018081886C80836091F40770E0E8
:103B000080E090E024EC39E040E050E00E94903FFB
:103B10006093740370937503809376039093770397
:103B20006091F50770E080E090E00E94903F609324
:103B300078037093790380937A0390937B031F91AA
:103B40000F9108958091FF0490910005813A9105AD
:103B50000CF40AC38091D4078B3F98F08B3F19F483
:103B600080915A050EC08C3F19F480915C0509C004
:103B70008D3F19F480915E0504C08E3F21F4809141
:103B800060058093830380918303882319F4109246
:103B9000830304C08F3F11F4809383038091D30784
:103BA0008B3F98F08B3F19F480915A050EC08C3FE3
:103BB00019F480915C0509C08D3F19F480915E0570
:103BC00004C08E3F21F48091600580938203809130
:103BD0008203882319F41092820305C0843618F0FA
:103BE00084E6809382038091D5078B3F98F08B3FCA
:103BF00019F480915A050EC08C3F19F480915C0530
:103C000009C08D3F19F480915E0504C08E3F21F4F8
:103C1000809160058093840380918403882319F444
:103C20001092840305C0843618F084E680938403E0
:103C30008091D7078B3F98F08B3F19F480915A05FC
:103C40000EC08C3F19F480915C0509C08D3F19F4BA
:103C500080915E0504C08E3F21F4809160058093C1
:103C6000850380918503882319F41092850304C08D
:103C70008F3F11F4809385038091DE078B3F98F08E
:103C80008B3F19F480915A050EC08C3F19F4809136
:103C90005C0509C08D3F19F480915E0504C08E3F1C
:103CA00021F48091600580938603809186038823A8
:103CB00019F41092860304C08F3F11F48093860399
:103CC0008091DF078B3F98F08B3F19F480915A0564
:103CD0000EC08C3F19F480915C0509C08D3F19F42A
:103CE00080915E0504C08E3F21F480916005809331
:103CF0008703809187038B3010F48AE002C08F3FE6
:103D000011F4809387038091E0078B3F98F08B3FFD
:103D100019F480915A050EC08C3F19F480915C050E
:103D200009C08D3F19F480915E0504C08E3F21F4D7
:103D3000809160058093880380918803882319F41B
:103D40001092880304C08F3F11F480938803809100
:103D5000E5078B3F98F08B3F19F480915A050EC010
:103D60008C3F19F480915C0509C08D3F19F4809156
:103D70005E0504C08E3F21F48091600580938A0324
:103D800080918A03882319F410928A0304C08F3F1C
:103D900011F480938A038091E6078B3F98F08B3F64
:103DA00019F480915A050EC08C3F19F480915C057E
:103DB00009C08D3F19F480915E0504C08E3F21F447
:103DC0008091600580938B0380918B03882319F485
:103DD00010928B0304C08F3F11F480938B0380916A
:103DE000E7078B3F98F08B3F19F480915A050EC07E
:103DF0008C3F19F480915C0509C08D3F19F48091C6
:103E00005E0504C08E3F21F48091600580938C0391
:103E100080918C03882319F410928C0304C08F3F87
:103E200011F480938C038091E8078B3F98F08B3FCF
:103E300019F480915A050EC08C3F19F480915C05ED
:103E400009C08D3F19F480915E0504C08E3F21F4B6
:103E50008091600580938D0380918D03882319F4F0
:103E600010928D0304C08F3F11F480938D038091D5
:103E7000E9078B3F98F08B3F19F480915A050EC0EB
:103E80008C3F19F480915C0509C08D3F19F4809135
:103E90005E0504C08E3F21F48091600580938E03FF
:103EA00080918E03882319F410928E0304C08F3FF3
:103EB00011F480938E038091F9078B3F98F08B3F2C
:103EC00019F480915A050EC08C3F19F480915C055D
:103ED00009C08D3F19F480915E0504C08E3F21F426
:103EE0008091600580938F0380918F03882319F45C
:103EF00010928F0304C08F3F11F480938F03809141
:103F0000FA078B3F98F08B3F19F480915A050EC049
:103F10008C3F19F480915C0509C08D3F19F48091A4
:103F20005E0504C08E3F21F480916005809390036C
:103F300080919003882319F41092900304C08F3F5E
:103F400011F4809390038091FB078B3F98F08B3F97
:103F500019F480915A050EC08C3F19F480915C05CC
:103F600009C08D3F19F480915E0504C08E3F21F495
:103F7000809160058093910380919103882319F4C7
:103F80001092910304C08F3F11F4809391038091AC
:103F9000FC078B3F98F08B3F19F480915A050EC0B7
:103FA0008C3F19F480915C0509C08D3F19F4809114
:103FB0005E0504C08E3F21F48091600580939203DA
:103FC00080919203882319F41092920304C08F3FCA
:103FD00011F4809392038091EA078B3F98F08B3F16
:103FE00019F480915A050EC08C3F19F480915C053C
:103FF00009C08D3F19F480915E0504C08E3F21F405
:10400000809160058093930380919303882319F432
:104010001092930304C08F3F11F480939303809117
:10402000EF078B3F98F08B3F19F480915A050EC033
:104030008C3F19F480915C0509C08D3F19F4809183
:104040005E0504C08E3F21F4809160058093940347
:1040500080919403882319F41092940304C08F3F35
:1040600011F4809394038091F2078B3F98F08B3F7B
:1040700019F480915A050EC08C3F19F480915C05AB
:1040800009C08D3F19F480915E0504C08E3F21F474
:10409000809160058093950380919503882319F49E
:1040A0001092950304C08F3F11F480939503809183
:1040B000F3078B3F98F08B3F19F480915A050EC09F
:1040C0008C3F19F480915C0509C08D3F19F48091F3
:1040D0005E0504C08E3F21F48091600580939603B5
:1040E00080919603882319F41092960304C08F3FA1
:1040F00011F4809396038091F8078B3F98F08B3FE3
:1041000019F480915A050EC08C3F19F480915C051A
:1041100009C08D3F19F480915E0504C08E3F21F4E3
:10412000809160058093970380919703882319F409
:104130001092970304C08F3F11F48093970360910E
:104140008A0370E080E090E00E94C83B27E137EBF3
:1041500041ED58E30E942D3F60937E0370937F03EF
:10416000809380039093810308958091560588235E
:1041700001F51092B7071092A1071092AC071092A8
:10418000C8078091BC04882311F08093A107809117
:10419000BD04882311F08093B7078091BE04882363
:1041A00011F08093C8078091BF04882311F0809399
:1041B000AC078091A10790E09093990680939806B0
:1041C0008091B70790E090939B0680939A06809128
:1041D000C80790E090939D0680939C068091AC0761
:1041E00090E090939F0680939E061092FC0410929C
:1041F000FD040E94D2150895109211051092100529
:10420000109213051092120580E090E0A0E0B0E05B
:104210008093140590931505A0931605B093170588
:1042200010920705109206051092090510920805D4
:1042300010920B0510920A051092950310929603A6
:104240000E94311D84E690E00E944E0C0E94311DB8
:104250008091D10780FF10C080910E0390910F03D1
:10426000875B934038F480910E0390910F038E5E2C
:10427000924010F40E945D108091D6049091D70472
:1042800090930705809306058091D8049091D904F6
:1042900090930905809308058091DA049091DB04DE
:1042A00090930B0580930A0580910805909109056C
:1042B00090930D0580930C0580910605909107055C
:1042C00090930F0580930E0584E00E94773880500C
:1042D000944058F18091C2079091C30797FF03C0A3
:1042E000909581959F4F6CE070E00E94CF3F709356
:1042F0001305609312058091B8079091B90797FF55
:1043000003C0909581959F4F6CE070E00E94CF3F75
:1043100070931105609310056091D4047091D504D9
:10432000882777FD8095982F17C084E00E94773802
:10433000909311058093100586E00E947738909342
:1043400013058093120588E00E947738AA2797FD0D
:10435000A095BA2FBC01CD010E94753E6093140553
:1043600070931505809316059093170510922C05F0
:1043700010922D0510922E0510922F0510923005E7
:1043800010923105109232051092330510923405C7
:1043900010923505109236051092370510923805A7
:1043A0001092390510923A0510923B0510923C0587
:1043B00010923D0510923E0510923F051092B407F1
:1043C0001092B3071092B2071092B1071092B6077D
:1043D0001092B50780910A0390910B03A0910C03F2
:1043E000B0910D0390935907809358071092E304FE
:1043F0001092E204109248051092490510924A0565
:1044000010924B0580916E0390916F03909371030E
:104410008093700382E390E09093D0048093CF0464
:104420006091F40770E080E090E024EC39E040E037
:1044300050E00E94903F6856754C8F4F9F4F60939D
:104440007403709375038093760390937703609160
:10445000F50770E080E090E00E94903F6856754C50
:104460008F4F9F4F609378037093790380937A0303
:1044700090937B0310927D0310927C03109273053E
:1044800010927205109275051092740560916E037A
:1044900070916F03882777FD8095982F2EE036E086
:1044A00040E050E00E94903F6093BA077093BB07D2
:1044B0008093BC079093BD071092BF071092BE0770
:1044C00008951F93182F0EC080915605882361F41C
:1044D00084E690E09093D0048093CF048AEF90E03C
:1044E0000E946D0C115080F71F9108958091C907AB
:1044F000E82FF0E0EE0FFF1FED59F84F808191811A
:104500008D5E9F4F14F010929803808191818A5B99
:104510009F4FDCF4809198038823B9F481E0809365
:10452000980380914E058F5F80934E0580914E05D4
:10453000853028F480914E050E946122089588EE0E
:1045400093E09093D0048093CF0408952F923F92EC
:104550004F925F926F927F928F929F92AF92BF9293
:10456000CF92DF92EF92FF920F931F93CF93DF933F
:10457000CDB7DEB7A2970FB6F894DEBF0FBECDBFA2
:104580000E940218299A209170053091710580913E
:10459000DB07482F50E0465F5F4F58874F83421735
:1045A000530714F438872F838091FF0490910005FE
:1045B000883791050CF071C080910301882399F42C
:1045C00080910403909105038F5F9F4F61F488E908
:1045D0009AE39093D0048093CF0480E09CE0909382
:1045E0000503809304038091AD059091AE0500977B
:1045F00031F001979093AE058093AD0504C0109201
:10460000560510925705809100018A3011F4289ABE
:1046100001C028988091580590915905895E934072
:1046200008F403C48091E207A82FB0E0B887AF83F5
:1046300081E080935705E091C9072E2F30E0220FCB
:10464000331FF901EF57F84F11821082A091CA076A
:10465000B0E0AA0FBB1FFD01EF57F84F1182108287
:10466000E091CC074E2F50E0440F551FCA018F57E1
:10467000984FFC01118210822D59384FF901118297
:104680001082AD59B84F11961C921E924D59584F39
:10469000DA0111961C921E92CDC38091FF04909175
:1046A00000058D3891050CF4C5C310925705809113
:1046B000E30722E3829FC00111249093AE0580930B
:1046C000AD05EF81F885B9976CF080915805909110
:1046D0005905FFEF8F3F9F0729F0019690935905E9
:1046E0008093580580915805909159058F3F910509
:1046F00009F0E8F41092BF051092C0051092C105B0
:104700001092C2051092BB051092BC051092BD0517
:104710001092BE0510926F0510926E058A3F9105AA
:1047200031F481E090E09093A5058093A405209159
:104730005A0530915B058091CD07E82FF0E0EE0F30
:10474000FF1FED59F84F8081918182599F4F2817A3
:1047500039071CF42F5F3F4F0CC080819181825933
:104760009F4F821793074CF42115310531F02150EA
:10477000304030935B0520935A0520915C053091C1
:104780005D058091CE07E82FF0E0EE0FFF1FED5999
:10479000F84F8081918182599F4F281739071CF467
:1047A0002F5F3F4F0CC08081918182599F4F8217AC
:1047B00093074CF42115310531F0215030403093EE
:1047C0005D0520935C0520915E0530915F05809129
:1047D000CF07E82FF0E0EE0FFF1FED59F84F808173
:1047E000918182599F4F281739071CF42F5F3F4F43
:1047F0000CC08081918182599F4F821793074CF49E
:104800002115310531F02150304030935F05209360
:104810005E0520916005309161058091D007E82FF9
:10482000F0E0EE0FFF1FED59F84F80819181825922
:104830009F4F281739071CF42F5F3F4F0CC0808112
:10484000918182599F4F821793074CF421153105AE
:1048500031F0215030403093610520936005209164
:1048600062053091630580917507909176078259B2
:104870009F4F281739071CF42F5F3F4F0EC08091C0
:1048800075079091760782599F4F821793074CF4D2
:104890002115310531F021503040309363052093CC
:1048A00062052091640530916505809177079091AC
:1048B000780782599F4F281739071CF42F5F3F4F05
:1048C0000EC0809177079091780782599F4F821789
:1048D00093074CF42115310531F0215030403093CD
:1048E00065052093640520916605309167058091E8
:1048F000790790917A0782599F4F281739071CF43E
:104900002F5F3F4F0EC08091790790917A078259AF
:104910009F4F821793074CF42115310531F0215038
:1049200030403093670520936605209168053091EB
:10493000690580917B0790917C0782599F4F2817CA
:1049400039071CF42F5F3F4F0EC080917B07909179
:104950007C0782599F4F821793074CF4211531052C
:1049600031F02150304030936905209368058091E3
:104970005A0590915B0597FF05C010925B05109258
:104980005A050AC08F3F910539F034F08FEF90E05F
:1049900090935B0580935A0580915C0590915D052D
:1049A00097FF05C010925D0510925C050AC08F3F0D
:1049B000910539F034F08FEF90E090935D0580938E
:1049C0005C0580915E0590915F0597FF05C0109290
:1049D0005F0510925E050AC08F3F910539F034F0F3
:1049E0008FEF90E090935F0580935E058091600566
:1049F0009091610597FF05C01092610510926005C6
:104A00000AC08F3F910539F034F08FEF90E090931A
:104A1000610580936005809162059091630597FF21
:104A200005C010926305109262050AC08F3F910580
:104A300039F034F08FEF90E0909363058093620536
:104A4000809164059091650597FF05C010926505FA
:104A5000109264050AC08F3F910539F034F08FEF52
:104A600090E0909365058093640580916605909130
:104A7000670597FF05C010926705109266050AC08A
:104A80008F3F910539F034F08FEF90E090936705F8
:104A900080936605809168059091690597FF05C030
:104AA00010926905109268050AC08F3F910539F090
:104AB00034F08FEF90E09093690580936805E09162
:104AC000CB07F0E0EE0FFF1FED59F84F8081918189
:104AD000813591050CF40EC180915605882309F0AB
:104AE00009C18091CC07E82FF0E0EE0FFF1FED59D0
:104AF000F84F808191818C3491050CF4BFC0809176
:104B0000AC058F5F8093AC05893C08F4F3C010922C
:104B1000AC05299810925905109258058091C90743
:104B2000282F30E0D901AA0FBB1FAD59B84F8D9186
:104B30009C911197873491059CF48091CA07E82FC6
:104B4000F0E0EE0FFF1FED59F84F8081918197FF44
:104B500003C0909581959F4F873491050CF46BC0ED
:104B60008091CA07682F70E0DB01AA0FBB1FAD5907
:104B7000B84F8D919C911197873491053CF0F901C4
:104B8000EE0FFF1FED59F84F808191818D919C911F
:104B90008734910564F0F901EE0FFF1FED59F84FCE
:104BA000808191818734910514F042E001C041E099
:104BB000FB01EE0FFF1FED59F84F80819181863484
:104BC00091055CF4F901EE0FFF1FED59F84F80815C
:104BD0009181873491050CF043E0FB01EE0FFF1F3C
:104BE000ED59F84F808191818A5B9F4F5CF4F90108
:104BF000EE0FFF1FED59F84F8081918187349105A9
:104C00000CF044E0660F771F6D59784FDB018D91F2
:104C10009C918A5B9F4F5CF4220F331F2D59384FB4
:104C2000F90180819181863491050CF445E0842F4F
:104C30000E9487381CC08091D10783FF18C08081F3
:104C4000918197FF03C0909581959F4F44977CF485
:104C50008D919C918A5B9F4F54F481E080934E0527
:104C600088EE93E09093D0048093CF0443C00E94D9
:104C7000683A0E94A5380E94FC2035C0808191814D
:104C8000855B9F4FACF58091AC058F5F8093AC0541
:104C9000893C80F11092AC0529986FEF7FEF84E09A
:104CA0000E947F3810925905109258050E94FC20EE
:104CB000609110057091110584E00E947F38609129
:104CC00012057091130586E00E947F3860911405EB
:104CD0007091150580911605909117050E94473E29
:104CE00088E00E947F380E94683A0E94612202C0D8
:104CF0001092AC05E091CB07F0E0EE0FFF1FED59ED
:104D0000F84F808191818B5A9F4F0CF093C0809116
:104D1000CC07482F50E0FA01EE0FFF1FED59F84F76
:104D200080819181855B9F4F0CF065C08091AB05C0
:104D30008F5F8093AB05893C08F45FC088EC80935B
:104D4000AB0581E090E0909359058093580581E090
:104D5000809356051092B7051092B8051092B905C8
:104D60001092BA0510923C0510923D0510923E0536
:104D700010923F0510922C0510922D0510922E05D1
:104D800010922F05109234051092350510923605B9
:104D9000109237058091180590911905A0911A0578
:104DA000B0911B058093300590933105A093320597
:104DB000B09333058091200590912105A0912205A3
:104DC000B09123058093380590933905A0933A0557
:104DD000B0933B051092BF051092C0051092C1051B
:104DE0001092C2051092BB051092BC051092BD0531
:104DF0001092BE0502C01092AB05440F551F4D59CD
:104E0000584FDA018D919C918C3491058CF08091F2
:104E1000AA058F5F8093AA05893C60F088EC809397
:104E2000AA0510925905109258051092560502C015
:104E30001092AA0580916B03815080936B0380913F
:104E40006B038F3F29F080915705882309F477C3BE
:104E50000E94A21DE0916A05F0916B05FAA3E9A3F7
:104E60008091C907E82EFF24D701AA0FBB1FCD01EF
:104E70008D59984FFC018081918198A38F8F8091EB
:104E8000D807682E7724AF57B84F0D90BC91A02D4E
:104E9000BE8FAD8F8091D907A82EBB2420917205BB
:104EA000309173053C8F2B8F20906C0530906D05F1
:104EB0008091CA07082F10E0C801880F991FDC01F4
:104EC000AD59B84F0D90BC91A02DBA8FA98F8F57B7
:104ED000984FDC018D919C91988F8F8BE091740598
:104EE000F0917505FE8BED8BE091CC07AE2FB0E015
:104EF000AA0FBB1FAD59B84F0D90BC91A02DBC8B14
:104F0000AB8BE091CB07F0E0EE0FFF1FED59F84FB0
:104F1000C080D18028E730E0C20ED31ED092710548
:104F2000C09270056091870370E080E090E00E947D
:104F3000C83B20E030E040E251E40E94763D20E0B2
:104F400030E040E85CE30E942D3F6F87788B898BCF
:104F50009A8B6093C4077093C5078093C60790939C
:104F6000C7076091880370E080E090E00E94C83B32
:104F700020E030EE4BE256E40E94DA3D6093AD074C
:104F80007093AE078093AF079093B0072091C10450
:104F9000222331F08AE090E09093D0048093CF04F4
:104FA000E22F22FF09C080919203482F50E0440F66
:104FB000551F440F551F10C023FD03C040E050E0B3
:104FC0000BC08091920390E0880F991F880F991F62
:104FD00044275527481B590B20917A0530917B05B2
:104FE000C901B3E0880F991FBA95E1F7821B930BB3
:104FF000840F951F68E070E00E94CF3F2B017093F3
:105000007B0560937A05E4FF09C080919203482FE5
:1050100050E0440F551F440F551F10C0E5FD03C05D
:1050200040E050E00BC08091920390E0880F991F00
:10503000880F991F44275527481B590B80917C05E1
:1050400090917D059C01E3E0220F331FEA95E1F783
:10505000281B390BCA01820F931F68E070E00E9481
:10506000CF3F4B0170937D0560937C058091C00418
:10507000282F83FF03C082E390E004C082FF07C0B3
:105080008EEC9FEF90937F0580937E0504C0109275
:105090007F0510927E0521FF09C080917C039091CD
:1050A0007D03019690937D0380937C0324FF09C0C8
:1050B00080917C0390917D03019790937D03809371
:1050C0007C034F8D58A1469DC001479D900D569D74
:1050D000900D112429A13AA1220F331F69A17AA1B1
:1050E000260F371FED8DFE8DEA9DD001EB9DB00D93
:1050F000FA9DB00D11244B8D5C8DA41BB50BBAA38A
:10510000A9A3820F931F64E070E00E94CF3F89A1A2
:105110009AA1860F971F9AA389A3C20162E070E04B
:105120000E94CF3FA9A1BAA1A60FB71FBAA3A9A3F6
:10513000B0936B05A0936A05E98DFA8DE69DC001D9
:10514000E79D900DF69D900D11249101220F331FC4
:10515000220D331D4F89588DB501469F5001479F41
:10516000B00C569FB00C1124AD89BE89AA1ABB0A97
:10517000820F931F64E070E00E94CF3FA60EB71E1F
:10518000C40162E070E00E94CF3FA60EB71EB0924D
:105190006D05A0926C0520917E0530917F05220F50
:1051A000331F220F331FEB89FC892E1B3F0B3093DB
:1051B0006F0520936E0580917D0680FF56C080911B
:1051C0009203813808F451C080917606992787FDB3
:1051D0009095AC01469DC001479D900D569D900D48
:1051E000112469A17AA1680F791F70936B056093F0
:1051F0006A0580917706992787FD9095DC01A69D29
:10520000C001A79D900DB69D900D1124A80EB91E4A
:10521000B0926D05A0926C0580917806992787FD64
:105220009095280F391F30936F0520936E052091BC
:10523000D60730E080917A06992787FD9095FC018A
:105240002E9FC0012F9F900D3E9F900D1124909393
:105250007D0380937C038091790690E08C159D05F9
:1052600024F490937105809370058091700590915E
:10527000710597FF04C0109271051092700580911E
:10528000D10782FF0CC080E090E0A0E0B0E0809306
:10529000AD079093AE07A093AF07B093B00720E09F
:1052A00030E040E050E06F85788989899A890E94D2
:1052B000B03E882364F480E090E0A0E0B0E080930A
:1052C000C4079093C507A093C607B093C70720E013
:1052D00030E040E050E06091AD077091AE07809102
:1052E000AF079091B0070E94B03E882364F480E03D
:1052F00090E0A0E0B0E08093AD079093AE07A0935C
:10530000AF07B093B007E0916A05F0916B0520916B
:10531000760530917705CF0164E070E00E94CF3FC1
:1053200077FF03C0709561957F4F261737077CF490
:10533000CF01F7FF03C0909581959F4F64E070E027
:105340000E94CF3F709377056093760506C0215089
:1053500030403093770520937605E0916C05F0910D
:105360006D052091780530917905CF0164E070E0FA
:105370000E94CF3F77FF03C0709561957F4F26173E
:1053800037077CF4CF01F7FF03C0909581959F4FBD
:1053900064E070E00E94CF3F7093790560937805D8
:1053A00006C0215030403093790520937805F801EC
:1053B000EE0FFF1FED59F84F208131818091F007EA
:1053C000482F50E04217530744F48091FD0782FFB5
:1053D00004C081E080938A0515C080918A058823E6
:1053E00089F0F801EE0FFF1FED59F84F2081318150
:1053F0008091F107BA01681B71092617370714F469
:1054000010928A05F801EE0FFF1FED59F84F8081C9
:10541000918166277727641B750B8617970744F4DD
:105420008091FD0783FF04C081E080938B0515C048
:1054300080918B05882389F0000F111F0D59184F9B
:10544000D8012D913C918091F10790E0841B950B40
:105450008217930714F410928B05F701EE0FFF1FCC
:10546000ED59F84F808191814817590744F4809194
:10547000FD0780FF04C081E080938D0515C08091F9
:105480008D05882389F0F701EE0FFF1FED59F84FC6
:10549000208131818091F107FA01E81BF1092E1773
:1054A0003F0714F410928D05F701EE0FFF1FED5921
:1054B000F84F808191818617970744F48091FD070A
:1054C00081FF04C081E080938C0517C080918C051A
:1054D000882399F0EE0CFF1C23E637E0E20EF31E62
:1054E000D7012D913C918091F10790E0841B950BA1
:1054F0008217930714F410928C0580918A058823F3
:1055000021F480918B05882321F081E08093890527
:1055100002C01092890580918D05882321F4809125
:105520008C05882351F081E08093880510928905CD
:1055300010928A0510928B0502C010928805809106
:105540008905882311F40C94433884E690E0909305
:10555000D0048093CF048091EF0790E0EF81F8852D
:105560008E179F0714F498878F838091910390E0A2
:105570009093F5048093F4048091920390E09093CB
:10558000F7048093F6040E946E15809157058823D6
:1055900081F110926F0510926E0510926B051092BA
:1055A0006A0510926D0510926C0580E090E0A8EC01
:1055B000BFE38093C4079093C507A093C607B09339
:1055C000C7078BE09CEBA2E3BCE38093AD0790930D
:1055D000AE07A093AF07B093B00710928905109261
:1055E0008805109277051092760510927905109231
:1055F00078052091A6073091A7074091A807509100
:10560000A9078091180590911905A0911A05B091EC
:105610001B05820F931FA41FB51F8093A6079093AD
:10562000A707A093A807B093A9072091A2073091DC
:10563000A3074091A4075091A50780912005909160
:105640002105A0912205B0912305820F931FA41F6D
:10565000B51F8093A2079093A307A093A407B093CC
:10566000A50750908805552029F480918905882345
:1056700009F44FC01092E5041092E4041092400522
:105680001092410510924205109243051092440574
:105690001092450510924605109247051092A607F4
:1056A0001092A7071092A8071092A9071092A207BC
:1056B0001092A3071092A4071092A50780912C05C1
:1056C00090912D05A0912E05B0912F058093300566
:1056D00090933105A0933205B09333058091340542
:1056E00090913505A0913605B09137058093380526
:1056F00090933905A0933A05B0933B051092870526
:10570000109286051092850510928405552009F0A7
:10571000F5C080918905882309F0F0C060911805D3
:105720007091190580911A0590911B05A090DD07D5
:10573000BB24CC24DD24E090B807F090B907A60183
:1057400095010E9404400027F7FC0095102F2E19A8
:105750003F09400B510BCA01B90120E130E040E0A4
:1057600050E00E94044039014A0160912005709187
:1057700021058091220590912305E090C207F090C9
:10578000C307A60195010E9404400027F7FC00957D
:10579000102F2E193F09400B510BCA01B90120E10E
:1057A00030E040E050E00E94044079018A0180919D
:1057B000760590917705819734F4809178059091E2
:1057C00079058197A4F0C401B30123E030E040E003
:1057D00050E00E94044039014A01C801B70123E0AA
:1057E00030E040E050E00E94044079018A01E091FD
:1057F000CC07F0E0EE0FFF1FED59F84F0190F0815C
:10580000E02DF7FF03C0F095E195FF4F7A97A4F0E4
:10581000C401B30123E030E040E050E00E940440C6
:1058200039014A01C801B70123E030E040E050E00F
:105830000E94044079018A01F1E26F16710481042B
:10584000910434F070E2672E712C812C912C11C0E0
:1058500020EE62162FEF72062FEF82062FEF9206D0
:1058600044F460EE662E6FEF762E6FEF862E6FEFAC
:10587000962E31E2E316F1040105110534F050E2F1
:10588000E52EF12C012D112D11C040EEE4164FEF45
:10589000F4064FEF04074FEF140744F440EEE42EF4
:1058A0004FEFF42E4FEF042F4FEF142F80912C0564
:1058B00090912D05A0912E05B0912F05861997097D
:1058C000A809B90980932C0590932D05A0932E0566
:1058D000B0932F058091340590913505A091360540
:1058E000B09137058E199F09A00BB10B8093340539
:1058F00090933505A0933605B09337058091E40465
:105900009091E5048F3F910509F008F445C45520B6
:1059100009F0DCC380918905882309F0D7C3809101
:105920004F05882309F0D2C36091A6077091A7079D
:105930008091A8079091A90720E031E040E050E075
:105940000E9404402093A6073093A7074093A8071E
:105950005093A9076091A2077091A3078091A407B3
:105960009091A50720E031E040E050E00E94044023
:105970002093A2073093A3074093A4075093A50751
:10598000E090DD07FF2400E010E020914005309119
:1059900041054091420550914305C801B7010E945D
:1059A000903F20E031E040E050E00E94044020932E
:1059B00040053093410540934205509343052091A3
:1059C0004405309145054091460550914705C80171
:1059D000B7010E94903F20E031E040E050E00E949B
:1059E0000440209344053093450540934605509369
:1059F00047056091A6077091A7078091A80790912D
:105A0000A9072091400530914105409142055091F0
:105A10004305E090F607FF2400E010E0621B730BE3
:105A2000840B950BA80197010E940440CA01B9019B
:105A300020E031E040E050E00E94044069013093F2
:105A40008705209386056091A2077091A307809136
:105A5000A4079091A50720914405309145054091F8
:105A6000460550914705621B730B840B950BA801EB
:105A700097010E940440CA01B90120E031E040E0F2
:105A800050E00E94044089013093850520938405ED
:105A900080917605909177058197BCF48091780587
:105AA0009091790581978CF4E091CC07F0E0EE0FAE
:105AB000FF1FED59F84F0190F081E02DF7FF03C073
:105AC000F095E195FF4F7A9794F0C60162E070E09F
:105AD0000E94CF3F7093870560938605C80162E0FE
:105AE00070E00E94CF3F7093850560938405E0903D
:105AF0001C05F0901D0500911E0510911F05809159
:105B0000180590911905A0911A05B0911B05E81A86
:105B1000F90A0A0B1B0BE092B305F092B40500934F
:105B2000B5051093B6058091300590913105A0918F
:105B30003205B09133058E199F09A00BB10B8093EC
:105B4000300590933105A0933205B09333056090F2
:105B5000240570902505809026059090270580915A
:105B6000200590912105A0912205B0912305681A86
:105B7000790A8A0A9B0A6092AF057092B0058092FA
:105B8000B1059092B2058091380590913905A091A8
:105B90003A05B0913B0586199709A809B909809380
:105BA000380590933905A0933A05B0933B052091B1
:105BB000BE073091BF07213831054CF080910A05AE
:105BC00090910B05019690930B0580930A05205840
:105BD0003F4F4CF480910A0590910B0501979093EB
:105BE0000B0580930A051092BF071092BE0781E053
:105BF00090E090939B0580939A051092A0051092D7
:105C0000A1051092A2051092A3058091A60790917C
:105C1000A707A091A807B091A907209192053091FC
:105C200093054091940550919505281B390B4A0B1B
:105C30005B0B57FF07C050954095309521953F4F1E
:105C40004F4F5F4F20523E44404050400CF0C1C087
:105C500071E0E71670E1F70670E0070770E01707DC
:105C60000CF452C080919905882309F449C0D801E9
:105C7000C7012CE0B595A795979587952A95D1F7FB
:105C8000019690939B0580939A05D801C701F3E094
:105C9000B595A79597958795FA95D1F78093A00527
:105CA0009093A105A093A205B093A30589589341B1
:105CB000A040B04064F088E893E1A0E0B0E08093B9
:105CC000A0059093A105A093A205B093A3056091B0
:105CD000A0057091A1058091A2059091A30520E0F7
:105CE00031E040E050E00E940440809186059091B0
:105CF0008705820F931F909387058093860566C062
:105D000081E08093990562C010929905F0E0EF164A
:105D1000F0EFFF06FFEF0F07FFEF1F070CF056C075
:105D200080919805882309F44DC088279927DC01C4
:105D30008E199F09A00BB10BECE0B595A79597952F
:105D40008795EA95D1F7019690939B0580939A05E4
:105D5000C801B70128E030E040E050E00E94044074
:105D60002093A0053093A1054093A2055093A3056D
:105D700028573C4E4F4F5F4F64F488E79CEEAFEFDF
:105D8000BFEF8093A0059093A105A093A205B093C7
:105D9000A3056091A0057091A1058091A205909145
:105DA000A30520E031E040E050E00E9404408091F3
:105DB000860590918705820F931F909387058093A6
:105DC000860511C081E0809398050DC0109298055A
:105DD0000AC010929B0510929A0584EF91E090936F
:105DE0007303809372038091F707C82EDD2480919E
:105DF0009A0590919B05C816D90624F4D0929B056C
:105E0000C0929A0571E0E71674E0F70670E00707A4
:105E100070E0170774F080910605909107052091B6
:105E20009A0530919B05820F931F909307058093ED
:105E3000060580E0E8168CEFF8068FEF08078FEF75
:105E4000180774F4809106059091070520919A0532
:105E500030919B05821B930B909307058093060559
:105E600081E090E090939B0580939A0510929C05A9
:105E700010929D0510929E0510929F058091A20799
:105E80009091A307A091A407B091A50720918E053A
:105E900030918F054091900550919105281B390B49
:105EA0004A0B5B0B57FF07C05095409530952195E5
:105EB0003F4F4F4F5F4F20523E44404050400CF008
:105EC000C1C0A1E06A16A0E17A06A0E08A06A0E0BF
:105ED0009A060CF452C080919705882309F449C0B2
:105EE000D401C3017CE0B595A795979587957A95E0
:105EF000D1F7019690939B0580939A05D401C30135
:105F000063E0B595A795979587956A95D1F78093A6
:105F10009C0590939D05A0939E05B0939F0589587D
:105F20009341A040B04064F088E893E1A0E0B0E085
:105F300080939C0590939D05A0939E05B0939F052B
:105F400060919C0570919D0580919E0590919F05A3
:105F500020E031E040E050E00E9404408091840560
:105F600090918505820F931F9093850580938405FA
:105F700066C081E08093970562C010929705F0E0BB
:105F80006F16F0EF7F06FFEF8F06FFEF9F060CF016
:105F900056C080919605882309F44DC0882799271B
:105FA000DC0186199709A809B9095CE0B595A795A0
:105FB000979587955A95D1F7019690939B05809375
:105FC0009A05C401B30128E030E040E050E00E94AF
:105FD000044020939C0530939D0540939E0550936B
:105FE0009F0528573C4E4F4F5F4F64F488E79CEE67
:105FF000AFEFBFEF80939C0590939D05A0939E0506
:10600000B0939F0560919C0570919D0580919E05C0
:1060100090919F0520E031E040E050E00E94044074
:106020008091840590918505820F931F909385053B
:106030008093840511C081E0809396050DC0109275
:1060400096050AC010929B0510929A0584EF91E084
:10605000909373038093720380919A0590919B05AE
:10606000C816D90624F4D0929B05C0929A0571E017
:10607000671674E0770670E0870670E0970674F0A4
:10608000809108059091090520919A0530919B0512
:10609000820F931F909309058093080580E068168E
:1060A0008CEF78068FEF88068FEF9806CCF48091FE
:1060B00008059091090520919A0530919B05821B56
:1060C000930B90930905809308050AC010928505EB
:1060D00010928405109287051092860510924F0544
:1060E00020E030E040E050E06091AD077091AE07F5
:1060F0008091AF079091B0070E94B03E882341F491
:1061000010928505109284051092870510928605DD
:106110008091A6079091A707A091A807B091A90721
:106120008093920590939305A0939405B093950561
:106130008091A2079091A307A091A407B091A50711
:1061400080938E0590938F05A0939005B093910551
:10615000109240051092410510924205109243059D
:10616000109244051092450510924605109247057D
:106170001092A6071092A7071092A8071092A907DD
:106180001092A2071092A3071092A4071092A507DD
:106190001092E5041092E404C0906E05D0906F0553
:1061A0008601D7FE04C0002711270C191D090031F4
:1061B0001105C4F08091D10784FD14C081E090E006
:1061C0009093A5058093A4058091BA079091BB0791
:1061D00090937103809370038AEF90E09093730320
:1061E00080937203E090DA07B601882777FD8095E7
:1061F000982F2E2D30E040E050E00E94903F980113
:10620000442737FD4095542F0E94903F20E032E014
:1062100040E050E00E94044089019A01FF24EC9C78
:10622000C001ED9C900DFC9C900D112464E070E089
:106230000E94CF3F600F711F882777FD8095982FB0
:106240006093B7057093B8058093B9059093BA052C
:1062500020913C0530913D0540913E0550913F0510
:10626000261B370B480B590B20933C0530933D05FB
:1062700040933E0550933F0580913C0590913D052C
:10628000A0913E05B0913F058155934CA040B04090
:1062900064F080E593ECA0E0B0E080933C0590933F
:1062A0003D05A0933E05B0933F0580913C0590913C
:1062B0003D05A0913E05B0913F05805B9C43AF4FEB
:1062C000BF4F64F480EB9CE3AFEFBFEF80933C05DE
:1062D00090933D05A0933E05B0933F058091D10773
:1062E00083FF5AC180914E05882339F0809156056D
:1062F000882319F40E9476224FC16091180570918D
:10630000190580911A0590911B0520E032E040E0CC
:1063100050E00E940440890137FF03C010950195A9
:106320001F4F609120057091210580912205909169
:10633000230520E032E040E050E00E940440690183
:1063400037FF04C0D094C194D108D394C016D106AD
:106350000CF4680129E1C216D10444F58091A4052A
:106360009091A505892B11F180917203909173038F
:10637000892BE1F488EC90E09093D0048093CF04D3
:106380006091BA077091BB078091BC079091BD07DF
:106390002EE036E040E050E00E940440309371036C
:1063A000209370031092A5051092A40580916E03AE
:1063B00090916F0397FF03C020E030E029C0E09088
:1063C0006E03F0906F034CE152E0E40EF51E0027DF
:1063D000F7FC0095102F6091BA077091BB07809170
:1063E000BC079091BD072EE036E040E050E00E94EF
:1063F0000440E21AF30A040B150BC801B70128E6A2
:1064000031E040E050E00E9404409B01245B3040BA
:10641000C60168E070E00E94CF3F6F5F7F4FC90107
:1064200043E0880F991F4A95E1F70E94CF3F3B0157
:10643000882477FC8094982C8091BA079091BB07B0
:10644000A091BC07B091BD07680E791E8A1E9B1EE5
:106450006092BA077092BB078092BC079092BD070A
:1064600080918603A82EBB24CA9CC001CB9C900DB2
:10647000DA9C900D112460E470E00E94CF3F25016A
:10648000461A570A141415040CF080C08091720348
:1064900090917303009711F001977AC08091BE0725
:1064A0009091BF07820F931F9093BF078093BE0701
:1064B0008091780590917905209176053091770546
:1064C000820F931F68E070E00E94CF3F6B0160E491
:1064D00070E0C60ED71E8091700390917103AA27B9
:1064E00097FDA095BA2F0CE1E02E02E0F02E012DD1
:1064F000112DE81AF90A0A0B1B0BC401B3012EE097
:1065000036E040E050E00E940440E20EF31E041F1B
:10651000151FC801B70128E631E040E050E00E94B5
:106520000440645B7040649DC001659D900D749D46
:10653000900D1124B6010E94CF3FC501880F991F0D
:106540008A0D9B1D8617970734F0909581959F4F74
:10655000681779070CF4BC0120913C0530913D058A
:1065600040913E0550913F05CB01AA2797FDA0958C
:10657000BA2F820F931FA41FB51F80933C059093E1
:106580003D05A0933E05B0933F0506C08AEF90E01D
:1065900090937303809372038091A605815080933A
:1065A000A6058F3F09F0A4C088E18093A6056091FD
:1065B00018057091190580911A0590911B05E090BE
:1065C000DD07FF2400E010E0A80197010E940440CD
:1065D00030938106209380066091200570912105FB
:1065E0008091220590912305A80197010E94044003
:1065F00030938306209382068091B8079091B90763
:1066000090938506809384068091C2079091C3077A
:1066100090938706809386068091B5079091B60780
:1066200090938906809388068091800590918105DA
:1066300090938B0680938A06609148057091490576
:1066400080914A0590914B0520E032E040E050E017
:106650000E94044030938D0620938C0680916E0337
:1066600090916F0390939106809390068091080318
:106670009091090390939306809392068091FF0472
:106680009091000590939506809394066091BA07C7
:106690007091BB078091BC079091BD072EE036E05A
:1066A00040E050E00E940440309397062093960605
:1066B0008091AA079091AB079093A1068093A006C2
:1066C0008091D2049091D3049093A9068093A80658
:1066D00080917205909173059093BD068093BC06DE
:1066E00080917405909175059093BF068093BE06C6
:1066F000809188058823A9F06091B3077091B40751
:10670000882777FD8095982F0E94753E2091C407B9
:106710003091C5074091C6075091C7070E942D3F91
:1067200032C0609118057091190580911A059091F9
:106730001B05E090B307F090B4070E94753E2091CE
:10674000AD073091AE074091AF075091B0070E945E
:106750002D3F5B016C010027F7FC0095102FC8014D
:10676000B7010E94753E2091C4073091C507409142
:10677000C6075091C7070E942D3F9B01AC01C6017F
:10678000B5010E94763D0E94423E7093B40760932B
:10679000B307809189058823A9F06091B1077091B2
:1067A000B207882777FD8095982F0E94753E20912B
:1067B000C4073091C5074091C6075091C7070E9492
:1067C0002D3F32C0609120057091210580912205F6
:1067D00090912305E090B107F090B2070E94753EBA
:1067E0002091AD073091AE074091AF075091B007AF
:1067F0000E942D3F5B016C010027F7FC0095102FD4
:10680000C801B7010E94753E2091C4073091C507A9
:106810004091C6075091C7070E942D3F9B01AC01D4
:10682000C601B5010E94763D0E94423E7093B207B8
:106830006093B1076091B5077091B607A0902805E5
:10684000B0902905C0902A05D0902B058091AD0706
:106850009091AE07A091AF07B091B00789839A835A
:10686000AB83BC83882777FD8095982F0E94753E67
:106870007B018C016091C4077091C5078091C607A8
:106880009091C7079B01AC010E94763D9B01AC0132
:10689000C801B7010E942D3F7B018C01C601B501E3
:1068A0000E94753E29813A814B815C810E942D3F77
:1068B00020E030E040E05FE30E942D3F9B01AC010F
:1068C000C801B7010E94763D0E94423E7093B60710
:1068D0006093B5078091B3079091B4079093AB068E
:1068E0008093AA068091B1079091B2079093AD066C
:1068F0008093AC068091B3079091B4078150904487
:1069000034F080E090E49093B4078093B3078091D3
:10691000B3079091B4078050904C34F480E090EC31
:106920009093B4078093B3078091B1079091B20719
:106930008150904434F080E090E49093B2078093CB
:10694000B1078091B1079091B2078050904C34F418
:1069500080E090EC9093B2078093B1078091B507E7
:106960009091B6078150904434F080E090E4909389
:10697000B6078093B5078091B5079091B607805010
:10698000904C34F480E090EC9093B6078093B50778
:10699000AF80B884AA0CBB1CAA0CBB1C8091D10789
:1069A000282F80FFC7C080915705882309F0C2C0F7
:1069B0008091830321FF0EC0823310F58091800502
:1069C000909181054497909383058093820510925E
:1069D000A90519C020917C0330917D03280F311D3A
:1069E0008091D60790E0AC01249FC001259F900DB7
:1069F000349F900D112444979093830580938205D2
:106A000081E08093A9052091800530918105409116
:106A1000820550918305421753070CF08BC080917B
:106A2000A905882309F486C08091840390E0241B83
:106A3000350BBC01629FC001639F900D729F900D4A
:106A4000112464E070E00E94CF3F4B01C090E2044B
:106A5000D090E304609148057091490580914A0502
:106A600090914B05E0908503FF2400E010E020E8C2
:106A700030E040E050E00E940440C801B7010E94AD
:106A8000903F20E230E040E050E00E9404407EEF82
:106A9000283E370714F428EE3EEF8091A705909129
:106AA000A805FC01A4E0EE0FFF1FAA95E1F7E81B83
:106AB000F90BC60162E070E00E94CF3FE61BF70BC6
:106AC00081E02931380714F028E131E0E21BF30BB3
:106AD000C501881999098E0F9F1F60E170E00E941F
:106AE000CF3F7093A8056093A7058091D20790E0EF
:106AF000880F991F880F991F6817790764F4A816E3
:106B0000B9062CF09093A8058093A70504C0B09215
:106B1000A805A092A7058091A7059091A805A816A1
:106B2000B90624F4B092A805A092A705A090A705E5
:106B3000B090A8058091DC07282E33248101000F36
:106B4000111F000F111FC8018055904045018A1583
:106B50009B050CF44C0190928F0680928E0620913A
:106B6000B5073091B6078091B7059091B805A0910F
:106B7000B905B091BA0542E0880F991FAA1FBB1F43
:106B80004A95D1F7281B390B91EA89169104ACF08C
:106B9000F401F595E7952E173F070CF4F901C401B0
:106BA00062E070E00E94CF3F709561957F4FCF010A
:106BB000E617F7076CF4CB010BC0C901205B3F4F10
:106BC00014F480EB9FEF8135910514F080E590E09F
:106BD000980128193909281739070CF4C9019401BB
:106BE000201B310B2C01821793070CF42901809193
:106BF000B3079091B40760906A0570906B05861991
:106C000097099093C1078093C00720E030E040E0EF
:106C100050E069817A818B819C810E94B03E8823FB
:106C2000F1F1E0901805F090190500911A05109106
:106C30001B056091BF057091C0058091C1059091C1
:106C4000C2050E94753E5B016C01C801B7010E943C
:106C5000753E29813A814B815C810E942D3F7B01E9
:106C60008C01B301882777FD8095982F0E94753E8F
:106C70009B01AC01C801B7010E94753D9B01AC01AD
:106C8000C601B5010E94763D0E94423E6093BF0559
:106C90007093C0058093C1059093C2051CC02091DC
:106CA000C0073091C107442737FD4095542F80918C
:106CB000BF059091C005A091C105B091C205820F9A
:106CC000931FA41FB51F8093BF059093C005A09389
:106CD000C105B093C2058091BF059091C005A091F8
:106CE000C105B091C20581509A4FA040B04064F0F8
:106CF00080E09AEFA0E0B0E08093BF059093C005DC
:106D0000A093C105B093C2058091BF059091C005C5
:106D1000A091C105B091C20580509640AF4FBF4FC2
:106D200064F480E096E0AFEFBFEF8093BF059093EF
:106D3000C005A093C105B093C2056091C0077091D2
:106D4000C10720917E0330917F03409180035091D1
:106D500081032B873C874D875E87882777FD809549
:106D6000982F0E94753E7B018C016091BF05709148
:106D7000C0058091C1059091C2050E94753E9B019E
:106D8000AC016B857C858D859E850E942D3F9B0186
:106D9000AC01C801B7010E94763D0E94423E7B01D2
:106DA0008C016B01C20157FE04C088279927841902
:106DB000950962E070E00E94CF3F680D791D882739
:106DC00077FD8095982F2091970330E040E050E0C8
:106DD0000E94903F20E430E040E050E00E940440F8
:106DE0003E832D83C216D3060CF497016D817E81FC
:106DF000709561957F4F7A876987261737070CF45E
:106E00009B01F201E80DF91DCF01820F931F64E091
:106E100070E00E94CF3F77FF03C060E070E004C0E5
:106E2000261637060CF4B1018091DB07A82FB0E0DD
:106E3000BAA3A9A36A177B070CF4BD016093A1074D
:106E4000CF01821B930B64E070E00E94CF3F77FF7D
:106E500003C060E070E004C0261637060CF4B101F0
:106E6000E9A1FAA16E177F070CF4BF016093B70781
:106E70008091B1079091B20760906C0570906D059C
:106E8000861997099093A00780939F0720E030E030
:106E900040E050E069817A818B819C810E94B03E04
:106EA0008823F1F1E0902005F09021050091220562
:106EB000109123056091BB057091BC058091BD05C3
:106EC0009091BE050E94753E5B016C01C801B7013F
:106ED0000E94753E29813A814B815C810E942D3F41
:106EE0007B018C01B301882777FD8095982F0E9444
:106EF000753E9B01AC01C801B7010E94753D9B0125
:106F0000AC01C601B5010E94763D0E94423E6093ED
:106F1000BB057093BC058093BD059093BE051CC056
:106F200020919F073091A007442737FD4095542FAB
:106F30008091BB059091BC05A091BD05B091BE05A7
:106F4000820F931FA41FB51F8093BB059093BC05B0
:106F5000A093BD05B093BE058091BB059091BC0583
:106F6000A091BD05B091BE0581589E43A040B040A0
:106F700064F080E89EE3A0E0B0E08093BB059093CE
:106F8000BC05A093BD05B093BE058091BB05909153
:106F9000BC05A091BD05B091BE058058914CAF4F86
:106FA000BF4F64F480E891ECAFEFBFEF8093BB0577
:106FB0009093BC05A093BD05B093BE0560919F075B
:106FC0007091A007882777FD8095982F0E94753EC5
:106FD0007B018C016091BB057091BC058091BD0562
:106FE0009091BE050E94753E9B01AC016B857C852E
:106FF0008D859E850E942D3F9B01AC01C801B70184
:107000000E94763D0E94423E2D813E8162177307A9
:107010000CF49B0149855A85241735070CF49A0115
:10702000C40184199509820F931F64E070E00E94E7
:10703000CF3F77FF03C060E070E004C0261637063C
:107040000CF4B10189A19AA1681779070CF4BC016D
:107050006093C807821A930AC4018419950964E0F1
:1070600070E00E94CF3F77FF03C060E070E004C093
:10707000261637060CF4B101A9A1BAA16A177B073D
:1070800054F4BD0108C080918805882311F00C9448
:10709000AB2A0C94B52A6093AC07A2960FB6F8946D
:1070A000DEBF0FBECDBFDF91CF911F910F91FF903B
:1070B000EF90DF90CF90BF90AF909F908F907F9098
:1070C0006F905F904F903F902F900895A0E0B0E0B8
:1070D000A80FB11D0E945640802D90E00895A0E0B9
:1070E000B0E0A80FB11D062E0E9468400895A0E0F0
:1070F000B0E0A80FB11D0E946340CF010895A0E049
:10710000B0E0A80FB11D0B010E94744008958630B5
:1071100008F085E0A2E0B0E0082E0E9468400895E3
:10712000982F863008F095E086E4989FD0011124CE
:10713000AC59BF4FE9ECF7E0182E0E947940A2E06D
:10714000B0E0092E0E9468400895982F863008F01C
:1071500095E086E4989FD0011124AC59BF4FE9EC2B
:10716000F7E0182E0E945E40089581E08093C907E1
:1071700082E08093CA0743E04093CB0764E06093CA
:10718000CC0755E05093CD0736E03093CE0787E02B
:107190008093CF0728E02093D00788EE8093D10713
:1071A0009EE19093D2078BEF8093D4078AE080937F
:1071B000D5079093D3079093D7074093D607209392
:1071C000D80740E14093D9073093DA072093DB07D3
:1071D00086EE8093DC079093DD0780E88093DE07DE
:1071E00034E63093DF0788E78093E0078EE58093ED
:1071F000E10783E28093E20784E18093E307109242
:10720000E4074093E5078DEF8093E6073093E707A7
:107210009AE59093E8079093E9079093F907909384
:10722000FA071092FB071092FC073093EA0788E2F6
:107230008093EB071092FE0722E32093EC0786E988
:107240008093ED075093EE072093EF079093F0079C
:107250002093F1071092FD079093F2075093F307E4
:107260003093F4073093F50780E28093F60760933C
:10727000F7072093F807A3E0B8E0E9E9F3E089E035
:1072800001900D928150E1F7089581E08093C90744
:1072900082E08093CA0743E04093CB0764E06093A9
:1072A000CC0755E05093CD0736E03093CE0787E00A
:1072B0008093CF0728E02093D00788E68093D107FA
:1072C0009EE19093D2078BEF8093D4078AE080935E
:1072D000D5079093D3079093D7074093D6078CE0B8
:1072E0008093D80780E18093D9073093DA07209301
:1072F000DB0786EE8093DC079093DD0780E88093C0
:10730000DE0780E58093DF0788E78093E0078EE55E
:107310008093E10783E28093E2079093E307109262
:10732000E40740E24093E5078DEF8093E60734E6FB
:107330003093E7072AE52093E8072093E907209395
:10734000F9072093FA071092FB071092FC0730937D
:10735000EA0788E28093EB071092FE0792E390938E
:10736000EC0786E98093ED075093EE079093EF07C3
:107370002093F0079093F1071092FD072093F207F6
:107380005093F3073093F4073093F5074093F607D3
:107390006093F7078BE48093F807A3E0B8E0E3EA93
:1073A000F3E087E001900D928150E1F7089581E0CC
:1073B0008093C90782E08093CA0783E08093CB075C
:1073C00054E05093CC0735E03093CD0786E08093AE
:1073D000CE0787E08093CF0728E02093D00788E688
:1073E0008093D1079EE19093D2078BEF8093D407CF
:1073F0008AE08093D5079093D3079093D707509353
:10740000D6078FE08093D8079093D9078CE08093BC
:10741000DA072093DB0786EE8093DC079093DD0785
:1074200080E88093DE0780E58093DF0746E940939C
:10743000E0078EE58093E10783E28093E207909373
:10744000E3071092E40780E28093E5078DEF8093D5
:10745000E60724E62093E7079AE59093E8079093E0
:10746000E9079093F9079093FA071092FB0710929F
:10747000FC072093EA0788E28093EB071092FE074F
:1074800082E38093EC074093ED073093EE078093FF
:10749000EF079093F0078093F1071092FD07909308
:1074A000F2073093F3072093F4072093F50780E168
:1074B0008093F6075093F7072093F807A3E0B8E00E
:1074C000EBEAF3E086E001900D928150E1F7089538
:1074D00022E030E0D9010E945640802D863028F00D
:1074E00082E0D901082E0E94684090E008950F9331
:1074F0001F93CF93DF93A1E0B0E00E945640802D10
:10750000863469F181E794E09F938F931F920E94E4
:10751000E6080E94D739C0E0D0E00F900F900F909E
:107520000C2FC23039F0C33019F40E94B53804C0B2
:10753000C43010F00E944539802F0E949038219667
:10754000C630D10569F7A2E0B0E083E0082E0E94C2
:107550006840A1E0B0E086E4082E0E94684002E0A6
:1075600010E0D8010E945640802D0E94A538D80115
:107570000E945640802D90E09F938F9388E594E081
:107580009F938F931F920E94E6080F900F900F9089
:107590000F900F90DF91CF911F910F910895CF938E
:1075A000DF93DC01EC01EA81FB8121918E81815026
:1075B00019F48981E81BF109ED01FB83EA838E83CD
:1075C0009FB7F8948C9181508C939FBF822F90E04D
:1075D000DF91CF910895FC011082758364837383DA
:1075E00062834183478346830895CF93DF93DC0111
:1075F0009C91ED018981981718F080E090E016C009
:10760000ED01EC81FD8161938F81815019F48981B5
:10761000E81BF109ED018F83FD83EC839FB7F8949C
:107620008C918F5F8C939FBF81E090E0DF91CF9131
:107630000895FC0180818823E9F3CF010E94CF3AAD
:1076400090E00895FC018081882319F48FEF9FEF6B
:107650000895CF010E94CF3A90E008953C98449A53
:107660001092B2031092150881E0809316080895D5
:107670006091CD057091CE05349B18C0CB01019669
:107680009093CE058093CD058159914008F45FC059
:107690008091B203882319F081508093B2038FEF59
:1076A0009FEF90936F0380936E034DC0CB010197C2
:1076B00089569140B8F56A30710528F410926F032D
:1076C00010926E0315C06A50704080E090E029E18E
:1076D00034E040E050E00E94903F2AE09695879584
:1076E000779567952A95D1F770936F0360936E0332
:1076F00080916E0390916F0320917003309171031C
:10770000845E9D4F821B930B68E671E00E94CF3F21
:10771000845B904090934D0580934C058CE0809362
:10772000B20311C08091B203882319F08150809375
:10773000B2038FEF9FEF90936F0380936E031092CD
:107740004D0510924C051092CE051092CD058091FA
:10775000B2038823E1F48091CB059091CC050E947F
:10776000C80B8823A1F08091CF049091D004892B7D
:1077700031F484E690E09093D0048093CF0484E6C3
:1077800090E00E94BF0B9093CC058093CB050895A9
:10779000A8E0B0E0EEECFBE30C9429407B018C0107
:1077A000611571058105910519F482E089835AC03C
:1077B00083E089838EE1C82ED12CDC82CB82ED82DE
:1077C000FE820F831887C801B7010E943B3CBC01B1
:1077D0006150704077FF33C0EE27FF27E61BF70BA1
:1077E00020E030E040E050E081E090E0A0E0B0E058
:1077F0000E2E04C0880F991FAA1FBB1F0A94D2F730
:107800000197A109B1098E219F21A023B1230097DF
:10781000A105B10521F021E030E040E050E004C0D6
:1078200016950795F794E794EA95D2F72E293F2904
:10783000402B512B2D833E834F8358870FC06115FA
:10784000710581F0062E04C0EE0CFF1C001F111FF5
:107850000A94D2F7ED82FE820F831887C61AD70AE0
:10786000DC82CB821A82CE0101960E94883CE8E03D
:1078700028960C944540EF92FF920F931F939B0123
:10788000AC01203080E0380781E0480780E05807ED
:1078900080F42F3F31054105510509F020F4EE2415
:1078A000FF24870119C068E0E62EF12C012D112D6F
:1078B00013C0203080E0380780E0480781E0580797
:1078C00030F490E1E92EF12C012D112D05C088E155
:1078D000E82EF12C012D112D80E290E0A0E0B0E027
:1078E0008E199F09A00BB10B04C05695479537958B
:1078F0002795EA94D2F7F901ED54FC4F2081821BC1
:107900009109A109B1091F910F91FF90EF9008957E
:107910009F92AF92BF92CF92DF92EF92FF920F931E
:107920001F93EE24FF248701FC01248135814681C9
:10793000578191808081823010F44061A2C08430F0
:1079400009F49BC0823029F420E030E040E050E0B0
:1079500005C0211531054105510519F4E0E0F0E0BD
:1079600092C0828193816FEF823896070CF05AC0E3
:1079700062E87FEF681B790B6A3171052CF020E01B
:1079800030E040E050E02AC0AA24BB24650181E039
:1079900090E0A0E0B0E0062E04C0880F991FAA1F57
:1079A000BB1F0A94D2F70197A109B109822393233F
:1079B000A423B5230097A105B10529F071E0A72EF6
:1079C000B12CC12CD12C04C05695479537952795DD
:1079D0006A95D2F72A293B294C295D29DA01C90188
:1079E0008F779070A070B07080349105A105B105BB
:1079F00039F427FF09C0205C3F4F4F4F5F4F04C051
:107A0000215C3F4F4F4F5F4F80E090E0203060E0BF
:107A1000360760E0460760E4560710F081E090E02A
:107A2000FC0123C08038910544F5FC01E158FF4F6B
:107A3000DA01C9018F779070A070B0708034910521
:107A4000A105B10539F427FF09C0205C3F4F4F4F16
:107A50005F4F04C0215C3F4F4F4F5F4F57FF05C042
:107A60005695479537952795319687E056954795D2
:107A7000379527958A95D1F706C020E030E040E0A1
:107A800050E0EFEFF0E0E22EF32E942F9F77802F5F
:107A90008078892B9E2F9795992797958F77082F18
:107AA000092B9E2F9695812F8078892B9794992466
:107AB00097948F77182F1929C801B7011F910F913B
:107AC000FF90EF90DF90CF90BF90AF909F90089580
:107AD000FC014150504030F001900616D1F731972B
:107AE000CF0108958827992708955058BB27AA27C2
:107AF0000ED079C16AD130F06FD120F031F49F3FC0
:107B000011F41EF45FC10EF4E095E7FB55C1E92FB7
:107B10007BD180F3BA17620773078407950718F0C3
:107B200071F49EF593C10EF4E0950B2EBA2FA02DA3
:107B30000B01B90190010C01CA01A0011124FF271A
:107B4000591B99F0593F50F4503E68F11A16F04015
:107B5000A22F232F342F4427585FF3CF4695379514
:107B60002795A795F0405395C9F77EF41F16BA0BD9
:107B7000620B730B840BBAF09150A1F0FF0FBB1F87
:107B8000661F771F881FC2F70EC0BA0F621F731FD0
:107B9000841F48F4879577956795B795F7959E3F2D
:107BA00008F0B3CF9395880F08F09927EE0F9795BB
:107BB000879508950CD017C10FD140F006D130F051
:107BC00021F45F3F19F0F8C0511141C1FBC01CD135
:107BD00098F39923C9F35523B1F3951B550BBB2794
:107BE000AA2762177307840738F09F5F5F4F220F41
:107BF000331F441FAA1FA9F333D00E2E3AF0E0E83A
:107C000030D091505040E695001CCAF729D0FE2F85
:107C100027D0660F771F881FBB1F26173707480717
:107C2000AB07B0E809F0BB0B802DBF01FF279358CD
:107C30005F4F2AF09E3F510568F0BEC008C15F3F0C
:107C4000ECF3983EDCF3869577956795B795F795B5
:107C50009F5FC9F7880F911D9695879597F90895AD
:107C6000E1E0660F771F881FBB1F62177307840749
:107C7000BA0720F0621B730B840BBA0BEE1F88F758
:107C8000E095089504D06894B111E1C00895C4D07E
:107C900088F09F5790F0B92F9927B751A0F0D1F0F5
:107CA000660F771F881F991F1AF0BA95C9F712C07F
:107CB000B13081F0CBD0B1E00895C8C0672F782FE4
:107CC0008827B85F39F0B93FCCF3869577956795EB
:107CD000B395D9F73EF490958095709561957F4F57
:107CE0008F4F9F4F0895E89409C097FB3EF49095FD
:107CF0008095709561957F4F8F4F9F4F9923A9F085
:107D0000F92F96E9BB279395F69587957795679513
:107D1000B795F111F8CFFAF4BB0F11F460FF1BC057
:107D20006F5F7F4F8F4F9F4F16C0882311F096E9EA
:107D300011C0772321F09EE8872F762F05C0662398
:107D400071F096E8862F70E060E02AF09A95660F51
:107D5000771F881FDAF7880F9695879597F908950A
:107D600007D008F481E0089503D008F48FEF089558
:107D7000990F0008550FAA0BE0E8FEEF161617063C
:107D8000E807F907C0F012161306E407F50798F0A4
:107D9000621B730B840B950B39F40A2661F0232BBD
:107DA000242B252B21F408950A2609F4A140A69539
:107DB0008FEF811D811D089597F99F6780E870E01E
:107DC00060E008959FEF80EC089500240A94161651
:107DD000170618060906089500240A9412161306B9
:107DE000140605060895092E0394000C11F4882347
:107DF00052F0BB0F40F4BF2B11F460FF04C06F5F63
:107E00007F4F8F4F9F4F089557FD9058440F551F38
:107E100059F05F3F71F04795880F97FB991F61F00C
:107E20009F3F79F087950895121613061406551F83
:107E3000F2CF4695F1DF08C0161617061806991FEF
:107E4000F1CF86957105610508940895E894BB27E4
:107E500066277727CB0197F908950BD0C4CFB5DFFC
:107E600028F0BADF18F0952309F0A6CFABCF112484
:107E7000EECFCADFA0F3959FD1F3950F50E0551FC9
:107E8000629FF001729FBB27F00DB11D639FAA276F
:107E9000F00DB11DAA1F649F6627B00DA11D661FBE
:107EA000829F2227B00DA11D621F739FB00DA11DDF
:107EB000621F839FA00D611D221F749F3327A00D99
:107EC000611D231F849F600D211D822F762F6A2F35
:107ED00011249F5750408AF0E1F088234AF0EE0FBA
:107EE000FF1FBB1F661F771F881F91505040A9F7C7
:107EF0009E3F510570F060CFAACF5F3FECF3983EF4
:107F0000DCF3869577956795B795F795E7959F5F2D
:107F1000C1F7FE2B880F911D9695879597F90895C7
:107F2000629FD001739FF001829FE00DF11D649F5D
:107F3000E00DF11D929FF00D839FF00D749FF00DE9
:107F4000659FF00D9927729FB00DE11DF91F639F8A
:107F5000B00DE11DF91FBD01CF0111240895991B3A
:107F600079E004C0991F961708F0961B881F7A9530
:107F7000C9F780950895AA1BBB1B51E107C0AA1F32
:107F8000BB1FA617B70710F0A61BB70B881F991FBA
:107F90005A95A9F780959095BC01CD01089597FB5E
:107FA000092E07260AD077FD04D0E5DF06D0002091
:107FB0001AF4709561957F4F0895F6F79095819525
:107FC0009F4F0895A1E21A2EAA1BBB1BFD010DC0F5
:107FD000AA1FBB1FEE1FFF1FA217B307E407F50779
:107FE00020F0A21BB30BE40BF50B661F771F881F55
:107FF000991F1A9469F760957095809590959B01EB
:10800000AC01BD01CF01089597FB092E05260ED0C6
:1080100057FD04D0D7DF0AD0001C38F450954095A6
:10802000309521953F4F4F4F5F4F0895F6F790954C
:108030008095709561957F4F8F4F9F4F08952F9238
:108040003F924F925F926F927F928F929F92AF92E8
:10805000BF92CF92DF92EF92FF920F931F93CF9335
:10806000DF93CDB7DEB7CA1BDB0B0FB6F894DEBFCC
:108070000FBECDBF09942A88398848885F846E84F2
:108080007D848C849B84AA84B984C884DF80EE803C
:10809000FD800C811B81AA81B981CE0FD11D0FB645
:1080A000F894DEBF0FBECDBFED010895F999FECF64
:1080B000B2BDA1BDF89A119600B40895F7DF019200
:1080C0001A94E1F70895F2DFE02DF0DFF02D089526
:1080D000F999FECFB2BDA1BD00BC11960FB6F894C0
:1080E000FA9AF99A0FBE0895F3DF012CF1DF1124FB
:0E80F00008950190EDDF1A94E1F70895FFCF97
:1080FE000AFF0164496E74656772616C506974633E
:10810E0068202020496E74656772616C526F6C6CCA
:10811E002020202041636350697463682020202052
:10812E0020202020416363526F6C6C202020202081
:10813E00202020204779726F59617720202020203F
:10814E002020202052656164696E67486569676802
:10815E00742020204163635A2020202020202020DC
:10816E002020202054687275737420202020202037
:10817E0020202020436F6D706173734865616469C0
:10818E006E672020566F6C7461676520202020205A
:10819E00202020205265636569766572204C6576D5
:1081AE00656C20205961774779726F486561646903
:1081BE006E6720204D6F746F725F46726F6E742003
:1081CE00202020204D6F746F725F526561722020E7
:1081DE00202020204D6F746F725F52696768742083
:1081EE00202020204D6F746F725F4C6566742020C6
:1081FE00202020204163635F5A2020202020202051
:10820E0020202020535049204572726F722020206A
:10821E0020202020535049204F6B2020202020204A
:10822E002020202020202020202020202020202040
:10823E0020202020536572766F20202020202020C1
:10824E0020202020506974636820202020202020C8
:10825E0020202020526F6C6C2020202020202020F7
:10826E002020202020202020202020202020202000
:10827E0020202020202020202020202020202020F0
:10828E0020202020202020202020202020202020E0
:10829E0020202020202020202020202020202020D0
:1082AE0020202020202020202020202020202020C0
:1082BE0020202020202020202020202020202020B0
:1082CE0020202020202020202020202020202020A0
:1082DE00202020204750535F50697463682020206F
:1082EE00202020204750535F526F6C6C202020209E
:1082FE0020202020FFFF010A6400007D0000FF0304
:10830E000102030405060708090A48656C6C6F2014
:10831E00576F726C64000000000000000000000047
:10832E00000000000000000000000000000000003F
:10833E00000000000000000000000000000000002F
:10834E00000000000000000000000000000000001F
:10835E00000000000000000000000B016400FFFFA1
:10836E00FFFFF40190D0030090D00300ECFF17B78D
:10837E00D13830FB103A409696020A0000000000F9
:10838E00000000644600006401426567696E6E6518
:10839E007200004E6F726D616C000053706F7274DC
:1083AE0000000C000102020303030304040404048E
:1083BE000404040505050505050505050505050562
:1083CE000505050606060606060606060606060642
:1083DE00060606060606060606060606060606062F
:1083EE000606060707070707070707070707070712
:1083FE0007070707070707070707070707070707FF
:10840E0007070707070707070707070707070707EE
:10841E0007070707070707070707070707070707DE
:10842E0007070708080808080808080808080808C1
:10843E0008080808080808080808080808080808AE
:10844E00080808080808080808080808080808089E
:10845E00080808080808080808080808080808088E
:10846E00080808080808080808080808080808087E
:10847E00080808080808080808080808080808086E
:10848E00080808080808080808080808080808085E
:10849E00080808080808080808080808080808084E
:0484AE0008080800B2
:100000000C9432020C944D020C944D020C944D024F
:100010000C944D020C944D020C944D020C944D0224
:100020000C944D020C94940D0C944D020C944D02C2
:100030000C9425180C944D020C944D020C944D0216
:100040000C944D020C944D020C945D0C0C944D02DA
:100050000C94FD040C944D020C94C7040C944D02B6
:100060000C94990E0C944D020C944F170C944D0265
:100070000A0D466C69676874436F6E74726F6C0A20
:100080000D48617264776172653A25642E25640AB1
:100090000D536F6674776172653A5625642E256438
:1000A000256320000A0D3D3D3D3D3D3D3D3D3D3D2F
:1000B0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D70
:1000C0003D3D3D3D000A0D496E69742E2045455069
:1000D000524F4D3A2047656E6572696572652044DE
:1000E000656661756C742D506172616D65746572C1
:1000F0002E2E2E000A0D414343206E696368742042
:1001000061626765676C696368656E21000A0D420C
:10011000656E75747A6520506172616D6574657283
:100120007361747A202564000A0D4162676C656909
:100130006368204C756674647275636B73656E7367
:100140006F722E2E004F4B0A0D000A0D5374657509
:100150006572756E673A200048656164696E67482C
:100160006F6C64004E65757472616C000A0A0D0054
:100170002E005B25695D005B25695D002B204D69C4
:100180006B726F4B6F70746572202B0048573A5634
:1001900025642E25642053573A25642E2564256353
:1001A0000053657474696E673A20256420002863E3
:1001B0002920486F6C676572204275737300486F21
:1001C0006568653A202020202025356900536F6C32
:1001D0006C486F6568653A20253569004C75667412
:1001E000647275636B3A20253569004F666620207E
:1001F000202020203A20253569004B65696E652056
:100200000048F668656E726567656C756E670061BB
:100210006B742E204C616765004E69636B3A202039
:100220002020202025356900526F6C6C3A20202058
:10023000202020253569004B6F6D706173733A2063
:100240002020253569004B313A25346920204B3276
:100250003A25346920004B333A25346920204B3449
:100260003A25346920004B353A25346920204B3635
:100270003A25346920004B373A25346920204B3821
:100280003A25346920004E693A2534692020526F9E
:100290003A253469200047733A253469202047699C
:1002A0003A253469200050313A25346920205032F3
:1002B0003A253469200050333A25346920205034DF
:1002C0003A25346920004779726F202D2053656EDE
:1002D000736F72004E69636B2025346920282533C3
:1002E000692900526F6C6C202534692028253369F8
:1002F000290047696572202534692028253369293A
:10030000004E69636B202534692028253369290054
:10031000526F6C6C202534692028253369290047E9
:1003200069657220253469202825336929004143F5
:1003300043202D2053656E736F72004E69636B20EE
:1003400025346920282533692900526F6C6C2025DB
:10035000346920282533692900486F6368202534D3
:1003600069202825336929005370616E6E756E67A8
:100370003A202025356900456D70662E5065676509
:100380006C3A253569004B6F6D70617373202020C6
:1003900020202020005269636874756E673A20201F
:1003A000253569004D657373776572743A20202591
:1003B00035690053746172743A202020202025355D
:1003C0006900506F7469313A202025336900506FFD
:1003D0007469323A202025336900506F7469333ACA
:1003E000202025336900506F7469343A202025336A
:1003F0006900536572766F202000536574706F69D1
:100400006E742020253369005374656C6C756E67BB
:100410003A202533690052616E67653A2533692DAC
:100420002533690045787465726E436F6E74726F20
:100430006C2020004E693A2534692020526F3A25FD
:100440003469200047733A253469202047693A25EA
:100450003469200048693A253469202043663A25EA
:100460003469200011241FBECFEFD0E1DEBFCDBF25
:1004700013E0A0E0B1E0E8E7F7E802C005900D92D4
:10048000AA3AB107D9F718E0AAEAB3E001C01D9271
:10049000AC33B107E1F70C94BB020C940000FB01F4
:1004A000863008F085E0489FD0011124AC59BF4F39
:1004B000842F9927019724F00E94A8430192FACF34
:1004C0000895282FFB01863008F025E0429FD001D7
:1004D0001124AC59BF4F842F9927019724F0019024
:1004E0000E94B043FACFA2E0B0E0022E0E94B043D7
:1004F0000895A2E0B0E09D010E94A843802D8630BF
:1005000028F082E0D901082E0E94B043992708956F
:1005100080916107E82FFF27EE0FFF1FEB5CF84F7C
:10052000808191818D5E9F4F14F010920201808135
:1005300091818A5B9F4FBCF480910201882399F4DA
:1005400081E080930201809132068F5F80933206B2
:10055000853038F088EE93E09093CA038093C90306
:1005600002C00E94C01A809132069927909300071A
:100570008093FF060895CFEFD0E1DEBFCDBF14B862
:1005800015B897EEE92E93E0F92E8EEC9FEFE80E6A
:10059000F91EF7FEFACF88EEE82E83E0F82E189BBE
:1005A00002C08BE001C08AE08093010181E887B935
:1005B0008FEF88B98BE184B981E085B98EE38AB980
:1005C000579A87EF8BB984B7877F84BF809160008B
:1005D0008861809360001092600080ED97E09093B6
:1005E000CA038093C9031092250410922404109228
:1005F0003A0710923907109227041092260410929D
:10060000290410922804809101018A3011F428985D
:1006100001C0289A0E94440D0E9456080E9410189A
:100620000E944B0E0E9418170E94303F789410923F
:10063000220685E48093230687E0809324068BE6D8
:1006400090E09F938F9385E490E09F938F931F9208
:100650001F92809101016AE00E943843892F9927F7
:100660009F938F93809101010E94384399279F9314
:100670008F9380E790E09F938F931F920E94D309FE
:100680008DB79EB70D960FB6F8949EBF0FBE8DBF67
:1006900084EA90E09F938F931F920E94D309299A36
:1006A0000F900F900F9001E010E0D8010E94A84336
:1006B000802D863461F185EC90E09F938F931F929B
:1006C0000E94D3090E940F19C0E00F900F900F9065
:1006D000C23039F0C33019F40E94301A04C0C4305B
:1006E00010F00E949F1947E461E677E08C2F0E948A
:1006F0006102CF5FC63060F3A2E0B0E083E0082E75
:100700000E94B04386E4D801082E0E94B043A4E0C2
:10071000B0E00E94A843802D853050F084EF90E037
:100720009F938F931F920E94D3090F900F900F9069
:100730000E94790247E461E677E00E944F020E943E
:10074000790299279F938F938DE091E09F938F93E8
:100750001F920E94D309809169070F900F900F900C
:100760000F900F9080FF20C088E291E09F938F93BD
:100770001F920E94D30988EE93E00E943B0D7C01FA
:100780000E94510E0F900F900F90C7010E946A0DAA
:100790008823D9F385E491E09F938F931F920E9461
:1007A000D3090F900F900F900E943B1C8091010184
:1007B0008A3011F4289801C0289A80ED97E0909330
:1007C000CA038093C90385E5809334068AE491E0E7
:1007D0009F938F931F920E94D309809169070F9076
:1007E0000F900F9082FF03C088E591E002C084E67D
:1007F00091E09F938F931F920E94D3090F900F90C7
:100800000F908CE691E09F938F931F920E94D309E3
:100810000E94A21188E893E190938B0380938A034E
:1008200081E0809333060F900F900F908091CD035D
:10083000882309F4A4C01092CD0380913206882346
:1008400019F00E94880202C00E94A9270E947A24FF
:10085000209101012A3011F4289801C0289A809132
:100860000303882321F081508093030312C08093F7
:10087000AA038093AB0380933E0610920804109263
:1008800007041092060410920504109204041092BA
:10089000030480912A04882329F080912A0481503E
:1008A00080932A0480918A0390918B03892B01F510
:1008B00085E090E090938B0380938A030E94321727
:1008C00080910603909107038F5F9F4FF9F4809109
:1008D00021048823D9F080E197E29093CA038093A2
:1008E000C90380E890E090930703809306030EC04D
:1008F00080918A0390918B03019790938B0380934F
:100900008A032A3011F4289801C0289A8091CD03D7
:10091000882321F080912104882311F40E947C080F
:100920000E94E706C7010E946A0D882341F1809169
:100930007907282F33278091100390911103821794
:1009400093079CF480910603909107038F5F9F4F5C
:1009500061F480E797E19093CA038093C90380E034
:1009600093E090930703809306030E94D84084E0AD
:100970008093C80384E190E00E943B0D7C0180914C
:10098000C803882309F052CF0E9419414FCF1F920C
:100990000F920FB60F9211248F939F93EF93FF93B3
:1009A000809105038823E1F48091BE039091BF03F9
:1009B00001969093BF038093BE03FC01EC50FB4F64
:1009C000E081ED3019F08639910539F41092BF03BA
:1009D0001092BE0381E080930503E093C60004C03B
:1009E0001092BF031092BE03FF91EF919F918F91E0
:1009F0000F900FBE0F901F9018951F920F920FB679
:100A00000F9211242F933F934F935F938F939F9354
:100A1000AF93BF93EF93FF9390E08091C6008093D4
:100A2000B9035091C403563910F09093C5038091D7
:100A3000B9038D3009F05FC08091C503823009F0A1
:100A40005AC09093C503852F99278F5B994FFC015E
:100A5000329740812091C0033091C103241B31099A
:100A6000DC0111978C91281B3109C9019F7090936B
:100A7000C1038093C00346E0969587954A95E1F7B8
:100A8000982F935C9093C2032F733070235C209354
:100A9000C3038081981729F48C91281711F491E0F1
:100AA00006C090E08091B6038F5F8093B60380917B
:100AB000B803882309F06EC0992309F46BC081E064
:100AC0008093B8035093B503E52FFF27EF5BF94FF1
:100AD0008DE0808380914306823509F05BC088E118
:100AE00090E02CE00FB6F894A895809360000FBEBC
:100AF000209360004FC02091C503822F9927813039
:100B00009105F9F0823091051CF4892B21F040C049
:100B1000029711F13DC08091B903833239F480917D
:100B2000B803882319F481E08093C5038091B90349
:100B30008093410681E08093C4038091B903992793
:100B400022C02F5F2093C503E52FFF27EF5BF94FEE
:100B50008091B903808309C0E52FFF27EF5BF94F30
:100B60008091B9038083563920F45F5F5093C403AA
:100B700002C01092C5032091B9038091C0039091E7
:100B8000C103820F911D9093C1038093C00302C0E3
:100B90001092C503FF91EF91BF91AF919F918F91FB
:100BA0005F914F913F912F910F900FBE0F901F902B
:100BB0001895AC01A0E0B0E09D01A817B90748F472
:100BC000E4EFF4E08191280F311D1196A417B507C9
:100BD000C8F33F70FD01EC50FB4FC90156E09695FC
:100BE00087955A95E1F7835C80831196FD01EC505F
:100BF000FB4F2F733070822F835C8083AB50BB4FD1
:100C00008DE08C93109205038091F4048093C600CC
:100C100008951F93CF93DF93382FEA01722F10E0CE
:100C200083E28093F4046093F5043093F604A3E028
:100C3000B0E0772309F458C0772311F4972F07C049
:100C4000FE01E10FF11D1F5F9081715011F4472FDC
:100C50000EC0FE01E10FF11D1F5F4081715039F0A0
:100C6000FE01E10FF11D1F5F6081715001C0672F10
:100C7000FD01EC50FB4F892F86958695835C808320
:100C80001196FD01EC50FB4F892F992783709070CE
:100C900024E0880F991F2A95E1F755279A0194E0DF
:100CA000369527959A95E1F7822B835C8083119680
:100CB000FD01EC50FB4F4F705070440F551F440F17
:100CC000551F862F992726E0969587952A95E1F757
:100CD000842B835C80831196FD01EC50FB4F6F7376
:100CE000635C60831196A5CFCD010E94D905DF9189
:100CF000CF911F9108951F93CF93DF93EC0110E0E4
:100D0000662309F460C0A22FBB271297E42FFF27A8
:100D1000EF5BF94F30813D534F5FE42FFF27EF5BCF
:100D2000F94F50815D534F5FE42FFF27EF5BF94F81
:100D300070817D534F5FE42FFF27EF5BF94FE08118
:100D4000ED534F5F842F9927A817B907E4F1832F3C
:100D50009927880F991F880F991F352F32953F705B
:100D6000382B852F99278F709070F4E0880F991F8A
:100D7000FA95E1F7572F56955695582B872F9927B7
:100D80008370907076E0880F991F7A95E1F78E2B2B
:100D900061506F3FC1F0FE01E10FF11D30831F5F15
:100DA00061506F3F81F0FE01E10FF11D50831F5F25
:100DB00061506F3F41F0FE01E10FF11D80831F5F25
:100DC000662309F0A3CFDF91CF911F910895CF93B0
:100DD000DF93CDB7DEB724970FB6F894DEBF0FBE12
:100DE000CDBF8091B803882309F445C180914306A3
:100DF00099278836910509F494C089369105C4F481
:100E00008236910509F462C08336910544F48B342F
:100E1000910559F18136910509F44CC02AC18336F8
:100E2000910509F467C08736910509F4B2C021C164
:100E3000813791054CF48C3691050CF0D4C08B367B
:100E4000910509F492C015C18437910509F484C055
:100E5000853791052CF48137910509F49EC009C1AD
:100E60008637910509F491C004C12091B50343E090
:100E700062E0CE0101960E947B0689819A8190935F
:100E80003D0480933C0480913C0490913D0420916A
:100E90003A0430913B04821B930B845E9D4F68E6BD
:100EA00071E00E945843845B904090933904809392
:100EB0003804DFC02091B50343E062E0CE01039621
:100EC0000E947B068B81809304035BC02091B50355
:100ED00043E06BE084E396E00E947B068091F1039F
:100EE00090913606892B8093F10380913D06809383
:100EF0001907BFC02091B50343E06BE084E396E09F
:100F00000E947B068091F10390913606892B809395
:100F1000F10380913D068093190781E08093BB0324
:100F200030C02091B50343E062E0CE0103960E94F9
:100F30007B068091F1039B81892B8093F1038C8147
:100F40008F3F21F481E08093B20302C01092B2037C
:100F500081E08093BC038DC02091B50343E064E041
:100F60008EEA93E00E947B060CC02091B50343E01B
:100F700064E08AEA93E00E947B068091AD0380934F
:100F800019078FEF8093030374C081E08093BA0345
:100F900070C081E08093BD036CC02091B50343E035
:100FA00062E0CE0103960E947B06809105038823B0
:100FB000E1F38B818F3F61F0863010F085E08B8309
:100FC00047E461E677E08B810E944F028B8102C08B
:100FD0000E94790227E441E657E06091F304855BC3
:100FE0000E94090646C02091B50343E067E481E60C
:100FF00097E00E947B068091430647E461E677E034
:101000008B560E946102A2E0B0E0809143068B56AD
:10101000082E0E94B04380918C079927AA27BB27EE
:10102000BC01CD0124EC39E040E050E00E941943BE
:10103000DC01CB018093840390938503A093860306
:10104000B093870380918D079927AA27BB27BC01FE
:10105000CD010E941943DC01CB0180938003909362
:101060008103A0938203B09383030E9479020E94BC
:10107000C01A1092B80324960FB6F894DEBF0FBEC4
:10108000CDBFDF91CF910895CF93C82F8A3019F447
:101090008DE00E9444088091C00085FFFCCFC09382
:1010A000C60080E090E0CF910895089588E1809394
:1010B000C1008091C00082608093C0008091C10017
:1010C00080688093C1008091C10080648093C100DA
:1010D0008AE28093C40088EC90E00E943B0D9093DC
:1010E0002106809320068CED90E00E943B0D9093AA
:1010F000400680933F06089580910503882309F4F4
:10110000F7C08091BD03882371F080910503882387
:1011100051F02BE044E356E06091F30487E40E9431
:1011200009061092BD0380913F06909140060E94EF
:101130006A0D882309F44CC080910503882309F4C3
:1011400047C08091760490917704A0917804B09183
:101150007904BC01CD012CE630E040E050E00E9473
:101160008D4330932D0620932C0680916E04909130
:101170006F04A0917004B0917104BC01CD012CE604
:1011800030E040E050E00E948D4330932F062093E2
:101190002E06809112048093300680911104809372
:1011A000310628E04CE256E06091F30487E70E94A4
:1011B000090680913206853018F086E08093320669
:1011C00083E690E00E943B0D9093400680933F069B
:1011D00080912006909121060E946A0D882321F4B7
:1011E0008091BB038823B1F080910503882391F09F
:1011F00022E447ED56E06091F30484E40E9409067E
:101200001092BB038AEF90E00E943B0D9093210661
:1012100080932006609104036F3F91F0862F9927F9
:1012200034E0880F991F3A95E1F78D5F9E4F605D1E
:1012300020E1AC0181E40E9409068FEF8093040352
:10124000909119079923A1F080910503882381F0DB
:1012500083E28093F4049093F5048DE08093F60488
:1012600010920503109219078091F4048093C60030
:101270008091BC03882351F180910503882331F1CB
:101280000E94AB111092BC033091B303832F8F5F88
:101290008093B303843021F06091B203662359F048
:1012A00026E145E357E060E084E30E9409068FEF02
:1012B0008093B3030BC024E1829FC00111248E5E92
:1012C0009C4FAC01832F8F5C0E9409068091BA036A
:1012D000882371F080910503882351F02AE042E2CF
:1012E00056E06091F30486E50E9409061092BA0365
:1012F0000895982F80911A07813069F48091F20344
:10130000E82FFF27EE5EFC4F90838F5F8093F20300
:1013100021E030E005C0892F0E944408282F3327A0
:10132000C90108950F931F93CF93DF938C01EB01B5
:10133000672B39F0F80181918F010E94790921977B
:10134000C9F7DF91CF911F910F9108950F931F93CC
:10135000CF93DF938C01EB01672B41F0F8010F5F16
:101360001F4F84910E9479092197C1F7DF91CF9196
:101370001F910F910895CF93C82F181634F480E26F
:101380000E947909C1501C16D4F3CF910895CF93D0
:10139000C82F181634F480E30E947909C1501C1636
:1013A000D4F3CF9108952F923F924F925F926F9214
:1013B0007F928F929F92AF92BF92CF92DF92EF92E5
:1013C000FF920F931F93CF93DF93CDB7DEB7E097D4
:1013D0000FB6F894DEBF0FBECDBF26968FAD269711
:1013E0002896EEADFFAD28971CA61DA61EA61FA62B
:1013F00080931A07A8E46A2E712C6C0E7D1E5F0183
:10140000C50105C0053239F00894A11CB11CF501D5
:1014100004910023B9F7B501681B790B11F00E9404
:10142000A609002309F430C20894A11CB11C55245C
:1014300058AA252C1FEF59A6F5010894A11CB11C30
:101440000491053721F0802F80628837F1F450FE37
:101450000EC0F30124E030E0620E731E80819181A2
:10146000A281B3818CA79DA7AEA7BFA70EC0F30131
:10147000A2E0B0E06A0E7B1E808191819C0144272E
:1014800055272CA73DA74EA75FA7003221F489A5B9
:10149000882391F61BC0033211F438E081C00A3270
:1014A00011F00D3289F40A3251F4F30142E050E0B8
:1014B000640E751E208022200CF0BECF219450E1D6
:1014C000552A8FED5822B8CF0B3211F409A7B4CFAB
:1014D0000E32C1F5F5010894A11CB11C04910A3229
:1014E00079F4F301A2E0B0E06A0E7B1E60817181A5
:1014F000BFEF6F3F7B0714F46FEF7FEF162F9CCF8A
:1015000060E070E0802F80538A30A0F4CB01F3E0DC
:10151000880F991FFA95E1F7860F971F680F791FBB
:10152000600F711D60537040F5010894A11CB11C3F
:101530000491E8CFEFEF6F3F7E0714F46FEF7FEF7A
:10154000162F7FCF003329F454FC76CFF0E25F2AC8
:1015500073CF802F81538930D8F460E070E0CB01E5
:10156000E3E0880F991FEA95E1F7860F971F680F50
:10157000791F600F711D60537040F5010894A11C24
:10158000B11C0491802F80538A3048F3262E59CF06
:10159000083619F424E0522A4FCF0C3619F431E002
:1015A000532A4ACF033661F44E010894811C911CE2
:1015B000F30142E050E0640E751E808189831BC1F7
:1015C000043421F0043611F00936B1F5043411F475
:1015D00051E0552A50FE0AC0F30184E090E0680E05
:1015E000791E20813181428153810CC0F30142E098
:1015F00050E0640E751E808191819C01442737FD67
:101600004095542F2CA73DA74EA75FA78CA59DA55D
:10161000AEA5BFA5B7FF0DC0B095A09590958195DB
:101620009F4FAF4FBF4F8CA79DA7AEA7BFA78DE21F
:1016300089A77AE0472E7BC00F3411F00F3639F4BA
:101640000F3411F491E0592A68E0462E6FC000373C
:10165000A1F4F301A2E0B0E06A0E7B1E80819181CB
:101660009C01442755272CA73DA74EA75FA750E113
:10167000452E30E4532A08E759C00337C1F5F3017A
:1016800042E050E0640E751E8080918081149104C8
:1016900089F44E010894811C911C88E289838EE6AE
:1016A000F401818385E78B838CE68C838D8389E2CB
:1016B0008E831F8217FD13C0812F992787FD909578
:1016C000AC0160E070E0C4010E94A441009729F0E1
:1016D000D82ED8181D150CF090C0D12E8EC0F40154
:1016E00001900020E9F73197DE2ED81886C0053525
:1016F00011F0053739F4053511F4F1E05F2A4AE0BD
:10170000442E14C0083519F0083709F06CC030E1D8
:10171000432E53FE0BC02CA53DA54EA55FA521155C
:1017200031054105510511F030E4532A19A618ABD3
:1017300017FD02C04FED542229E2822E912C8C0E0F
:101740009D1E8CA59DA5AEA5BFA50097A105B105C1
:1017500021F498A9992309F43FC0C42CDD24EE2478
:10176000FF2433242CA53DA54EA55FA52C153D05D2
:101770004E055F0510F091E0392E6CA57DA58EA574
:101780009FA5A70196010E946B43DC01CB01182F96
:101790008A3010F4105D04C0195A083509F41F7D11
:1017A000D4011E934D016CA57DA58EA59FA5A70113
:1017B00096010E946B432CA73DA74EA75FA733203D
:1017C00081F6B8E04B1641F453FE06C0103321F009
:1017D00080E3F40182934F01CE010196D82ED818F0
:1017E000F8E2DF0E0BC0002309F44EC04E0108944E
:1017F000811C911C098381E0D82E19A61D2DC8A833
:10180000CD18C7FCCC2489A5882311F01F5F02C026
:1018100056FC1E5F1C0DE52CFF24C70180739070E1
:10182000892B21F4822D811B0E94BB0989A5882365
:1018300029F061E070E0CE01899609C0E6FE09C09A
:1018400080E38AA70BA762E070E0CE018A960E942F
:101850009209C70180739070809721F4822D811BBB
:101860000E94C7098C2D0E94C7098D2D992787FDDD
:101870009095BC01C4010E949209E4FEC1CD822D65
:10188000811B0E94BB09BCCDE0960FB6F894DEBF69
:101890000FBECDBFDF91CF911F910F91FF90EF90C1
:1018A000DF90CF90BF90AF909F908F907F906F9080
:1018B0005F904F903F902F9008951F920F920FB618
:1018C0000F9211242F933F935F936F937F938F9386
:1018D0009F93AF93BF93EF93FF938091C8038823A7
:1018E00029F08091C80381508093C8038091D00370
:1018F00081508093D0038F3FB9F489E08093D00367
:10190000809108038F5F817080930803882319F406
:1019100081E08093CD038091CE039091CF03019617
:101920009093CF038093CE038091C9039091CA0313
:101930000297C8F08091C9039091CA0301979093D0
:10194000CA038093C9038091C9039091CA0320916F
:1019500006033091070382239323892B11F021E0A2
:1019600009C020E007C020E08FEF9FEF90930703AE
:101970008093060380910101222331F08A3011F413
:101980005A9A07C0479A05C08A3011F45A9801C084
:1019900047988091690783FF5EC086B19927FC0153
:1019A000E071F07084FF0AC08091CB039091CC036A
:1019B00001969093CC038093CB034DC08091CB03D1
:1019C0009091CC03892B69F18091CB039091CC034A
:1019D0008A56914030F58091CB039091CC0369E217
:1019E00070E00E9444438091CB039091CC03860F1A
:1019F000971F9093CC038093CB038091CB0390915E
:101A0000CC030B9750F08091CB039091CC030A97B5
:101A100090933D0480933C0404C0F0933D04E09314
:101A20003C0480913C0490913D0420913A04309113
:101A30003B04821B930B845E9D4F68E671E00E941D
:101A40005843845B904090933904809338041092FB
:101A5000CC031092CB03FF91EF91BF91AF919F9177
:101A60008F917F916F915F913F912F910F900FBE5A
:101A70000F901F9018952091CE033091CF03280F1F
:101A8000391FC901019608958AE090E00E943B0D3C
:101A90009093D2038093D10382E085BD83EA84BD15
:101AA00017BC88E788BD96E096BD83EC8093B000B4
:101AB0009093B1008091700082608093700080915B
:101AC0006E00816080936E008AE08093B300109274
:101AD000B20008952091CE033091CF03821B930B67
:101AE000892F99278695807490700895CF93DF93FE
:101AF0000E943B0DEC01CE010E946A0D8823D9F3B0
:101B0000DF91CF910895CF93DF930E943B0DEC01BD
:101B100003C08FEE80937A00CE010E946A0D882365
:101B2000C1F3DF91CF9108951F920F920FB60F92DC
:101B300011240F931F932F933F934F935F936F93B2
:101B40007F938F939F93AF93BF93CF93DF93EF9345
:101B5000FF93809109038150809309038F3F09F01F
:101B600081C083E88093B00080917203082F112711
:101B70001093C7030093C603809196076091830773
:101B8000A0917604B0917704C0917804D091790443
:101B900080FF24C07727882799279D01AE01D7FFB2
:101BA00004C021583F4F4F4F5F4FA7E055954795D1
:101BB00037952795AA95D1F70E94194397FF04C03E
:101BC00061507E4F8F4F9F4FF9E0959587957795A0
:101BD0006795FA95D1F7060F171F23C07727882737
:101BE00099279D01AE01D7FF04C021583F4F4F4FA9
:101BF0005F4FE7E05595479537952795EA95D1F7DB
:101C00000E94194397FF04C061507E4F8F4F9F4F32
:101C100039E095958795779567953A95D1F7061BA5
:101C2000170B1093C7030093C6038091840799276D
:101C30002091C6033091C7032817390734F08091EB
:101C4000850799278217930724F49093C7038093FD
:101C5000C6038091C6038093B3008091860780936A
:101C6000090304C083E08093B0005F98FF91EF9177
:101C7000DF91CF91BF91AF919F918F917F916F91A4
:101C80005F914F913F912F911F910F910F900FBE38
:101C90000F901F90189510927C008FEE80937A0021
:101CA00008950F931F93CF93DF9303E010E0D801C3
:101CB0000E94A843802DC82FDD27C531D10508F02B
:101CC0002A97C7BD84E690E00E94830D80910A03A5
:101CD00090910B038255934010F4C0E0D0E0CA3FCE
:101CE000D105C0F4C7BD82E390E00E94830D80E778
:101CF00091E09F938F931F920E94D30980910A03D2
:101D000090910B030F900F900F908458934010F018
:101D10002196E5CFD8010C2E0E94B043C09328072E
:101D20008CE291E00E94830DDF91CF911F910F9182
:101D300008951F920F920FB60F921124EF92FF9207
:101D40000F931F932F933F934F935F936F937F93C3
:101D50008F939F93AF93BF93CF93DF93EF93FF93B3
:101D600010927A008091EA03682F77278F5F809323
:101D7000EA036530710509F48EC066307105BCF464
:101D80006230710509F44AC0633071053CF4611595
:101D9000710531F161307105C1F1AEC26330710579
:101DA00009F446C06430710509F45DC0A5C268300D
:101DB000710509F4C3C0693071054CF466307105D2
:101DC00009F482C06730710509F49BC095C269307F
:101DD000710509F4D0C06A30710509F4EBC18CC2F9
:101DE00080917800909179009093EC038093EB03BD
:101DF00081E08093E9038091D3039091D40301960D
:101E00009093D4038093D3037BC280917800909108
:101E100079009093EE038093ED038EC0809178005B
:101E2000909179009093F0038093EF0384E0BFC119
:101E300080911003909111039C01220F331F280FF2
:101E4000391F80917800909179000E944443260FB9
:101E5000371F369527953695279530931103209394
:101E6000100386E0A4C180918204909183042091A4
:101E7000780030917900821B930B90931C0780931C
:101E80001B0780911B0790911C079093E20380939E
:101E9000E10387E08CC180917800909179002091D6
:101EA000840430918504821B930B909327078093C1
:101EB000260780912607909127079093E00380934F
:101EC000DF031092E9031CC2809101012091EB0312
:101ED0003091EC038A3049F4809178009091790038
:101EE000820F931F9695879506C0809178009091F8
:101EF0007900820F931F9093E4038093E30381E0C2
:101F000056C1809101012091ED033091EE038A309A
:101F100049F48091780090917900820F931F9695F3
:101F2000879506C08091780090917900820F931F69
:101F30009093E6038093E50382E039C1809101012B
:101F40002091EF033091F0038A3049F480917800BA
:101F500090917900820F931F9695879506C0809186
:101F6000780090917900820F931F9093E8038093FB
:101F7000E70385E01CC18091780090917900AA2741
:101F800097FDA095BA2FBC01CD010E9457427B015D
:101F90008C0180917C0490917D04A0917E04B0918D
:101FA0007F049C01AD01C801B7010E94B141DC0171
:101FB000CB01BC01CD010E943A42DC01CB019093E0
:101FC000DE038093DD038091DD039091DE030297B1
:101FD0000CF446C080917C0490917D04A0917E0415
:101FE000B0917F0420E030E84BE354E4BC01CD0124
:101FF0000E94614288230CF088C080917C049091FB
:102000007D04A0917E04B0917F042AE037ED43EA7D
:102010005CE3BC01CD010E94B241DC01CB018093A5
:102020007C0490937D04A0937E04B0937F04809100
:10203000FD039091FE03845F914008F066C080919B
:102040007C0490917D04A0917E04B0917F042DECDE
:102050003CEC4CEC5DE3BC01CD010E94B2414BC0B5
:102060008091DD039091DE038F5F9F4F0CF04DC098
:1020700080917C0490917D04A0917E04B0917F04B6
:1020800020E030E849E054E4BC01CD010E94644204
:102090001816DCF580917C0490917D04A0917E045B
:1020A000B0917F042AE037ED43EA5CE3BC01CD0147
:1020B0000E94B141DC01CB0180937C0490937D04AC
:1020C000A0937E04B0937F048091FD039091FE0362
:1020D000845F9140D0F480917C0490917D04A09124
:1020E0007E04B0917F042DEC3CEC4CEC5DE3BC0134
:1020F000CD010E94B141DC01CB0180937C0490931F
:102100007D04A0937E04B0937F0481E08093D70385
:10211000809178009091790090931E0780931D071D
:102120008091DD039091DE039C01442737FD4095AB
:10213000542F80913E0490913F04A0914004B091AF
:102140004104820F931FA41FB51F80933E049093F8
:102150003F04A0934004B093410420913E04309189
:102160003F04409140045091410457FF04C0215066
:102170003C4F4F4F5F4FAAE05595479537952795B0
:10218000AA95D1F780913E0490913F04A09140041C
:10219000B0914104821B930BA40BB50B80933E04BA
:1021A00090933F04A0934004B093410483E0809354
:1021B000E903A6C080912B0790912C07209178000D
:1021C00030917900820F931F90932C0780932B07F7
:1021D000809123078F5F80932307809123078530A9
:1021E00008F48AC0809178009091790090930B0355
:1021F00080930A03109223078091D5039091D60310
:10220000BC01F3E0660F771FFA95E1F7681B790BC5
:1022100080917B03482F552780911F0790912007BD
:1022200020912B0730912C07821B930B20911F04C8
:1022300030912004821B930B489F9001499F300DE1
:10224000589F300D1124620F731F77FF02C0695F22
:102250007F4FE3E075956795EA95E1F77093D603B4
:102260006093D50380912B0790912C07EC01EE270A
:10227000D7FDE095FE2F20910C0330910D03409186
:102280000E0350910F03DA01C901880F991FAA1F8D
:10229000BB1F820F931FA41FB51FC80FD91FEA1FB2
:1022A000FB1FF7FF03C02396E11DF11D82E0F595AA
:1022B000E795D795C7958A95D1F7C0930C03D0932E
:1022C0000D03E0930E03F0930F0380910C039091A4
:1022D0000D03A0910E03B0910F039C0180911F0785
:1022E00090912007821B930B9093200480931F04EE
:1022F00010922C0710922B071092E9031092EA0318
:102300008091E90380937C008091EA03882319F08F
:102310008FEE80937A00FF91EF91DF91CF91BF9183
:10232000AF919F918F917F916F915F914F913F916D
:102330002F911F910F91FF90EF900F900FBE0F9074
:102340001F90189590E2E2E1F3E08FE491938150C1
:1023500087FFFCCF08951F93CF93DF938091F10304
:1023600080FF0FC08091F503882311F0815002C0D7
:1023700080916C038093F5030E94A2118FEF8093EC
:10238000B3038091F10381FF0AC08091F5038F5F51
:102390008093F5030E94A2118FEF8093B303809185
:1023A000F103992780FF04C081FF02C01092F5035A
:1023B0008091F503282F33278A3040F481E1809300
:1023C000F2033F932F9382E791E007C080E180936F
:1023D000F2033F932F9387E791E09F938F9381E0E0
:1023E0008F930E94D3090F900F900F900F900F9032
:1023F0008091F503C82FDD27C530D10509F46AC2E5
:10240000C630D105ACF4C230D10509F4E9C0C330FF
:10241000D10534F4209739F1219709F477C0FDC430
:10242000C330D10509F44EC1249709F4B7C1F5C4EE
:10243000C830D10509F4A9C3C930D10544F4C63068
:10244000D10509F41CC3279709F47EC3E6C4CA303A
:10245000D10509F432C4CA30D1050CF4D9C32B9785
:1024600009F471C4DAC41092F2038CE791E09F93EF
:102470008F9311E01F930E94D30984E18093F203AC
:102480000F900F900F908BE690E09F938F9385E4D1
:1024900090E09F938F93DF93CF93809101016AE047
:1024A0000E943843892F99279F938F938091010130
:1024B0000E94384399279F938F938CE891E09F93D4
:1024C0008F931F930E94D30988E28093F2038DB704
:1024D0009EB70D960FB6F8949EBF0FBE8DBF0E949B
:1024E000790299279F938F9381EA91E09F938F932D
:1024F0001F930E94D3098CE38093F2030F900F90F7
:102500000F900F900F908EEA91E061C08091690763
:1025100080FF4AC01092F20380911F049091200422
:102520009F938F938EEB91E09F938F9311E01F9376
:102530000E94D30984E18093F2030F900F900F90D3
:102540000F900F9080911D0490911E049F938F9384
:102550008DEC91E09F938F931F930E94D30988E2A3
:102560008093F2030F900F900F900F900F90809137
:102570000A0390910B039F938F938CED91E09F93AF
:102580008F931F930E94D3098CE38093F2030F90E3
:102590000F900F900F900F908091280799279F938D
:1025A0008F938BEE91E07EC384E18093F2038AEFF8
:1025B00091E09F938F9311E01F930E94D30988E2CB
:1025C0008093F2030F900F900F9081E092E09F9321
:1025D0008F931F930E94D3090F900F900F9022C4E6
:1025E0001092F2038FE092E09F938F93C1E0CF931C
:1025F0000E94D30984E18093F2030F900F900F9013
:102600008091760490917704A0917804B091790438
:10261000B7FF04C081509C4FAF4FBF4F6AE0B595E4
:10262000A795979587956A95D1F7BF93AF939F9399
:102630008F9389E192E09F938F93CF930E94D30968
:1026400088E28093F2038DB79EB707960FB6F89491
:102650009EBF0FBE8DBF80916E0490916F04A091BC
:102660007004B0917104B7FF04C081509C4FAF4F0C
:10267000BF4F5AE0B595A795979587955A95D1F78D
:10268000BF93AF939F938F9388E292E09F938F9332
:10269000CF930E94D3098CE38093F2038DB79EB74A
:1026A00007960FB6F8949EBF0FBE8DBF80913C0475
:1026B00090913D049F938F9387E392E09F938F9334
:1026C000CF93F3C21092F2038091390790913A07A9
:1026D0009F938F9380913707909138079F938F93A3
:1026E00086E492E09F938F9311E01F930E94D30999
:1026F00084E18093F2038DB79EB707960FB6F894E6
:102700009EBF0FBE8DBF80913D0790913E079F9366
:102710008F9380913B0790913C079F938F9386E521
:1027200092E09F938F931F930E94D30988E2809336
:10273000F2038DB79EB707960FB6F8949EBF0FBEF3
:102740008DBF80914107909142079F938F93809115
:102750003F07909140079F938F9386E692E09F9367
:102760008F931F930E94D3098CE38093F2038DB75C
:102770009EB707960FB6F8949EBF0FBE8DBF80918F
:102780004507909146079F938F93809143079091BF
:1027900044079F938F9386E792E031C31092F20330
:1027A00080916207E82FFF27EE0FFF1FEB5CF84FC9
:1027B000808191819F938F9380916107E82FFF27FC
:1027C000EE0FFF1FEB5CF84F808191819F938F93F9
:1027D00086E892E09F938F9311E01F930E94D309A4
:1027E00084E18093F2038DB79EB707960FB6F894F5
:1027F0009EBF0FBE8DBF80916407E82FFF27EE0FAD
:10280000FF1FEB5CF84F808191819F938F938091A4
:102810006307E82FFF27EE0FFF1FEB5CF84F808167
:1028200091819F938F9386E992E09F938F931F935B
:102830000E94D30988E28093F2038DB79EB7079672
:102840000FB6F8949EBF0FBE8DBF80916607E82F2C
:10285000FF27EE0FFF1FEB5CF84F808191819F9364
:102860008F9380916507E82FFF27EE0FFF1FEB5C2A
:10287000F84F808191819F938F9386EA92E09F9396
:102880008F931F930E94D3098CE38093F2038DB73B
:102890009EB707960FB6F8949EBF0FBE8DBF80916E
:1028A0006807E82FFF27EE0FFF1FEB5CF84F8081D2
:1028B00091819F938F9380916707E82FFF27EE0FF9
:1028C000FF1FEB5CF84F808191819F938F9386EB84
:1028D00092E095C21092F20386EC92E09F938F9360
:1028E000C1E0CF930E94D309809101010F900F9016
:1028F0000F908A3009F05AC084E18093F2038091EE
:102900008E0490918F049F938F938091E703909111
:10291000E80320918E0430918F04821B930B9F93C8
:102920008F9384ED92E09F938F93CF930E94D3096E
:1029300088E28093F2038DB79EB707960FB6F8949E
:102940009EBF0FBE8DBF80918C0490918D049F938C
:102950008F938091E5039091E60320918C04309150
:102960008D04821B930B9F938F9383EE92E09F9332
:102970008F93CF930E94D3098CE38093F2038DB79A
:102980009EB707960FB6F8949EBF0FBE8DBF80917D
:102990008A0490918B049F938F938091D407909198
:1029A000D5079F938F9382EF92E065C084E1809377
:1029B000F20380918E0490918F0497FD0196959576
:1029C00087959F938F938091E7039091E8032091DF
:1029D0008E0430918F04821B930B9F938F9381E021
:1029E00093E09F938F93CF930E94D30988E28093C3
:1029F000F2038DB79EB707960FB6F8949EBF0FBE31
:102A00008DBF80918C0490918D0497FD01969595D2
:102A100087959F938F938091E5039091E603209192
:102A20008C0430918D04821B930B9F938F9380E1D4
:102A300093E09F938F93CF930E94D3098CE380936D
:102A4000F2038DB79EB707960FB6F8949EBF0FBEE0
:102A50008DBF80918A0490918B0497FD0196959586
:102A600087959F938F938091D4079091D5079F93DB
:102A70008F938FE193E09F938F93CF93C3C1109275
:102A8000F2038EE293E09F938F9311E01F930E94D5
:102A9000D30984E18093F2030F900F900F908091FF
:102AA0008404909185049F938F938091DF0390918C
:102AB000E0039F938F938BE393E09F938F931F93F8
:102AC0000E94D30988E28093F2038DB79EB70796E0
:102AD0000FB6F8949EBF0FBE8DBF80918204909177
:102AE00083049F938F938091E1039091E2039F93DE
:102AF0008F938AE493E09F938F931F930E94D3094F
:102B00008CE38093F2038DB79EB707960FB6F894C7
:102B10009EBF0FBE8DBF80917C0490917D04A091DB
:102B20007E04B0917F04BC01CD010E943A42DC01D9
:102B3000CB019F938F938091BA079091BB079F938E
:102B40008F9389E593E05BC184E18093F2038091E8
:102B50001003909111039F938F9388E693E09F93C6
:102B60008F9311E01F930E94D30988E28093F203B0
:102B70000F900F900F900F900F9080912A0499273B
:102B80009F938F9387E793E08DC01092F20386E8BE
:102B900093E09F938F9311E01F930E94D30984E1E8
:102BA0008093F2030F900F900F90809138049091D2
:102BB00039049F938F9385E993E09F938F931F939D
:102BC0000E94D30988E28093F2030F900F900F9038
:102BD0000F900F9080913C0490913D049F938F93B0
:102BE00084EA93E09F938F931F930E94D3098CE311
:102BF0008093F2030F900F900F900F900F908091A1
:102C00003A0490913B049F938F9383EB93E04AC0E7
:102C10001092F20380913104909132049F938F932C
:102C200082EC93E09F938F9311E01F930E94D3094E
:102C300084E18093F2030F900F900F900F900F900C
:102C400080912F04909130049F938F938EEC93E0AA
:102C50009F938F931F930E94D30988E28093F2037E
:102C60000F900F900F900F900F9080912D049091E6
:102C70002E049F938F938AED93E09F938F931F93DE
:102C80000E94D3098CE38093F2030F900F900F9072
:102C90000F900F9080912B0490912C049F938F9311
:102CA00086EE93E09F938F931F930E94D3090F901A
:102CB0000F900F900F900F90B5C01092F20382EF1B
:102CC00093E09F938F9311E01F930E94D30984E1B7
:102CD0008093F2030F900F900F90809172039927C9
:102CE0009F938F938AEF93E09F938F931F930E94FC
:102CF000D30988E28093F2030F900F900F900F900A
:102D00000F908091C6039091C7039F938F9388E0A3
:102D100094E09F938F931F930E94D3098CE3809339
:102D2000F2030F900F900F900F900F9080918507F6
:102D300099279F938F938091840799279F938F93CF
:102D400086E194E05CC01092F20384E294E09F93E9
:102D50008F9311E01F930E94D30984E18093F203C3
:102D60000F900F900F9080913806992787FD9095CE
:102D70009F938F9380913706992787FD90959F9316
:102D80008F9384E394E09F938F931F930E94D309C2
:102D900088E28093F2038DB79EB707960FB6F8943A
:102DA0009EBF0FBE8DBF80913906992787FD9095F4
:102DB0009F938F9380913A0699279F938F9384E4F2
:102DC00094E09F938F931F930E94D3098CE3809389
:102DD000F2038DB79EB707960FB6F8949EBF0FBE4D
:102DE0008DBF80913E0699279F938F9380913B06DC
:102DF000992787FD90959F938F9384E594E09F9307
:102E00008F931F930E94D3098DB79EB707960FB675
:102E1000F8949EBF0FBE8DBF05C0815080936C0398
:102E20001092F5031092F103DF91CF911F91089555
:102E30001092B9008AE28093B800089585EA8093E1
:102E4000BC0080E090E0089584E98093BC00089580
:102E50001092B9008093BB0085E88093BC0080E0AD
:102E600090E008950E9424171092F8038091BB000F
:102E70001092F70380E88093BC001092BD0010927E
:102E8000BA001092BB001092B9001092B8000E94D4
:102E900018170E941E1780E00E94281708951F929D
:102EA0000F920FB60F9211242F933F934F935F937E
:102EB0006F937F938F939F93AF93BF93EF93FF9302
:102EC0008091F803282F33278F5F8093F8032330F6
:102ED000310509F446C0243031054CF42130310568
:102EE000D1F0223031057CF5232B81F083C02530D1
:102EF0003105E1F1253031050CF441C026303105B2
:102F0000F1F12730310509F45AC074C08091F703FC
:102F1000880F8E5A51C08091F703282F33278F5F77
:102F20008093F7032130310509F43EC0223031058A
:102F30001CF4232BB1F15EC022303105C1F12330E6
:102F40003105C1F157C00E9424178091F7038430E6
:102F500018F41092F80302C01092F7030E941E1793
:102F600049C08091F603880F8D5A26C08091F603E0
:102F7000E82FFF27E35DF84F8091BB0080838091AD
:102F8000F60399278130910579F0823091051CF480
:102F9000892B39F02FC08230910549F0039751F009
:102FA00029C08091AB0708C08091B20705C080910D
:102FB000CC0702C08091CE070E9428171BC09091B9
:102FC000F603E92FFF27E35DF84F8091BB00848370
:102FD000892F8F5F8093F603843010F01092F603F0
:102FE0000E9424178AE090E090938B0380938A03D9
:102FF0001092F8038091BC0080688093BC00FF9120
:10300000EF91BF91AF919F918F917F916F915F9160
:103010004F913F912F910F900FBE0F901F901895D9
:1030200083EC8093810080916F00806280936F00B9
:1030300010928B0410928A0410928D0410928C04CA
:1030400010928F0410928E0408951F920F920FB663
:103050000F9211240F931F932F933F934F935F93DE
:103060006F937F938F939F93AF93BF93CF93DF9390
:10307000EF93FF9340918600509187008091F90370
:103080009091FA03481B590B80918600909187001C
:103090009093FA038093F903CA018D549440A09150
:1030A000FB03B091FC03835F9A4158F4149714F02A
:1030B00010926D0381E090E09093FC038093FB03FA
:1030C00099C0AA30B1050CF095C0CA018B5F904041
:1030D000845B914008F071C0425D5140FD01EA0FF0
:1030E000FB1FEB5CF84F80819181FA01E81BF90B23
:1030F000CF01F7FF03C0909581959F4F06974CF441
:1031000080912A04883C28F480912A04865F809369
:103110002A04FD01EA0FFB1FEB5CF84F80819181CF
:103120009C01220F331F280F391F240F351F37FF33
:1031300002C02D5F3F4FE901D595C795D595C7953D
:10314000CA0101968C179D0714F4219706C04150BF
:103150005040C417D5070CF4219680912A04833C73
:10316000D8F08D010A0F1B1FF801EB5CF84F80812E
:1031700091819E01281B390BC90163E070E00E9418
:103180005843CB01880F991F860F971F055B184F77
:10319000F8019183808307C0AA0FBB1FA55BB84FBE
:1031A00011961C921E92E091FB03F091FC03EE0F2E
:1031B000FF1FEB5CF84FD183C0838091FB0390919C
:1031C000FC0301969093FC038093FB03059711F495
:1031D0005D9A01C05D988091FB039091FC0386305D
:1031E000910511F45C9A01C05C98079711F45B9A01
:1031F00001C05B98FF91EF91DF91CF91BF91AF91AB
:103200009F918F917F916F915F914F913F912F91FE
:103210001F910F910F900FBE0F901F90189581E096
:103220008093610782E08093620783E08093630765
:1032300054E05093640735E03093650786E080934F
:10324000660787E08093670728E02093680788E691
:10325000809369079EE190936A078BEF80936C07D8
:103260008AE080936D0790936B0790936F0750935C
:103270006E078FE080937007909371076CE0609306
:1032800072072093730786EE8093740790937507F7
:1032900080E88093760780E58093770746E940933E
:1032A00078078EE58093790783E280937A0790937D
:1032B0007B0710927C0780E280937D078DEF8093DF
:1032C0007E0724E620937F079AE5909380079093EA
:1032D0008107909391079093920710929307109211
:1032E00094072093820788E28093830710929607C1
:1032F00082E3809384074093850730938607809309
:103300008707909388078093890710929507909379
:103310008A0730938B0720938C0720938D0780E1D9
:1033200080938E0750938F0720939007ABE9B7E007
:10333000ECE8F3E001900D926150E1F7089581E02F
:103340008093610782E08093620743E040936307C4
:1033500074E07093640755E05093650736E030934E
:10336000660787E08093670728E02093680788E670
:10337000809369079EE190936A078BEF80936C07B7
:103380008AE080936D0790936B0790936F0740934B
:103390006E076CE06093700780E180937107309353
:1033A00072072093730786EE8093740790937507D6
:1033B00080E88093760780E58093770788E780939D
:1033C00078078EE58093790783E280937A0790935C
:1033D0007B0710927C0740E240937D078DEF80933E
:1033E0007E0734E630937F072AE5209380072093F9
:1033F00081072093910720939207109293071092D0
:1034000094073093820788E280938307109296078F
:1034100092E39093840786E980938507509386070B
:1034200090938707209388079093890710929507B8
:1034300020938A0750938B0730938C0730938D0726
:1034400040938E0770938F078BE480939007ABE9CE
:10345000B7E0E3E9F3E001900D926150E1F70895E0
:1034600081E08093610782E08093620743E04093AC
:10347000630764E06093640755E05093650736E0A6
:103480003093660787E08093670728E020936807FA
:1034900088EE809369079EE190936A078BEF809393
:1034A0006C078AE080936D0790936B0790936F078A
:1034B00040936E072093700740E14093710730936B
:1034C00072072093730786EE8093740790937507B5
:1034D00080E88093760734E63093770788E7809317
:1034E00078078EE58093790783E280937A0784E1F9
:1034F00080937B0710927C0740937D078DEF80932C
:103500007E0730937F079AE5909380079093810719
:1035100090939107909392071092930710929407BB
:103520003093820788E2809383071092960722E304
:103530002093840786E9809385075093860720931C
:103540008707909388072093890710929507909397
:103550008A0750938B0730938C0730938D0780E256
:1035600080938E0760938F0720939007ABE9B7E0B5
:10357000EBE9F3E08CE001900D928150E1F70895C2
:10358000CF93C82FC150CF3F81F080912104882371
:1035900061F484E690E09093CA038093C9038AEFB4
:1035A00090E00E94760DC15080F7CF91089510925F
:1035B0007A008091E7039091E8039093B407809399
:1035C000B3078091E5039091E6039093AA07809357
:1035D000A9078091E3039091E4039093D50780932A
:1035E000D4078091DF039091E003AA2797FDA0956F
:1035F000BA2FBC01CD012CE030E040E050E00E9449
:103600001943DC01CB019093D2078093D1078091BD
:10361000E1039091E203AA2797FDA095BA2FBC0180
:10362000CD010E941943DC01CB019093E207809306
:10363000E1078091DD039091DE039093BB078093B7
:10364000BA078FEE80937A0080916507E82FFF27F5
:10365000EE0FFF1FEB5CF84F8081918182599F4FE5
:103660002091310430913204281739071CF42F5F60
:103670003F4F0CC08081918182599F4F82179307E1
:103680004CF42115310531F0215030403093320493
:103690002093310480916607E82FFF27EE0FFF1F6C
:1036A000EB5CF84F8081918182599F4F20912F04CC
:1036B00030913004281739071CF42F5F3F4F0CC09E
:1036C0008081918182599F4F821793074CF4211575
:1036D000310531F0215030403093300420932F04D5
:1036E00080916707E82FFF27EE0FFF1FEB5CF84F75
:1036F0008081918182599F4F20912D0430912E0419
:10370000281739071CF42F5F3F4F0CC0808191812F
:1037100082599F4F821793074CF42115310531F0E0
:103720002150304030932E0420932D04809168075F
:10373000E82FFF27EE0FFF1FEB5CF84F8081918190
:1037400082599F4F20912B0430912C042817390760
:103750001CF42F5F3F4F0CC08081918182599F4F95
:10376000821793074CF42115310531F02150304078
:1037700030932C0420932B048091310490913204D7
:1037800097FF05C010923204109231040AC08F3F97
:10379000910539F034F08FEF90E0909332048093EC
:1037A000310480912F049091300497FF05C010924E
:1037B000300410922F040AC08F3F910539F034F085
:1037C0008FEF90E09093300480932F0480912D042C
:1037D00090912E0497FF05C010922E0410922D0494
:1037E0000AC08F3F910539F034F08FEF90E090934D
:1037F0002E0480932D0480912B0490912C0497FF2C
:1038000005C010922C0410922B040AC08F3F910522
:1038100039F034F08FEF90E090932C0480932B04D8
:1038200080918C079927AA27BB27BC01CD0124ECE6
:1038300039E040E050E00E941943DC01CB01809365
:10384000840390938503A0938603B09387038091AC
:103850008D079927AA27BB27BC01CD010E941943D8
:10386000DC01CB018093800390938103A0938203BA
:10387000B0938303089510928504109284041092EB
:1038800083041092820480E090E0A0E0B0E0809396
:103890007C0490937D04A0937E04B0937F041092E7
:1038A0008F0410928E0410928D0410928C0410924A
:1038B0008B0410928A0410920A04109209040E9448
:1038C000D71A84E690E00E94830D0E94D71A809157
:1038D000690780FF10C080910A0390910B03875BFA
:1038E000934038F480910A0390910B038E5E9240CE
:1038F00010F40E94510E8091E7039091E803909399
:103900008F0480938E048091E5039091E603909359
:103910008D0480938C048091E3039091E403909351
:103920008B0480938A0480918C0490918D049093F1
:1039300089048093880480918E0490918F049093E1
:1039400087048093860444E050E0DA010E94A84393
:10395000802D853078F18091E1079091E207809188
:10396000E1079091E20797FF03C0909581959F4FE3
:103970006CE070E00E94584370938304609382046B
:103980008091D1079091D2078091D1079091D20771
:1039900097FF03C0909581959F4F6CE070E00E9467
:1039A0005843709385046093840480911D0790911F
:1039B0001E0734C0DA010E94A843802D9927982F52
:1039C0008827DA0111960E94A843202D820F911DAD
:1039D0009093850480938404DA0112960E94A84390
:1039E000802D9927982F8827DA0113960E94A843E3
:1039F000202D820F911D9093830480938204DA011D
:103A000014960E94A843802D9927982F8827DA01C1
:103A100015960E94A843202D820F911DAA2797FD7D
:103A2000A095BA2FBC01CD010E945742DC01CB0109
:103A300080937C0490937D04A0937E04B0937F04D4
:103A40001092560410925704109258041092590480
:103A50001092520410925304109254041092550480
:103A600010924E0410924F04109250041092510480
:103A700010924A0410924B0410924C0410924D0480
:103A80001092460410924704109248041092490480
:103A90001092B4071092B3071092AA071092A907C8
:103AA0001092D5071092D40780910C0390910D03CA
:103AB000A0910E03B0910F039093200780931F07EE
:103AC0001092D6031092D50310923E0410923F0438
:103AD000109240041092410480913C0490913D0466
:103AE00090933B0480933A040E94063F82E390E067
:103AF0009093CA038093C90380918C079927AA27C2
:103B0000BB27BC01CD0124EC39E040E050E00E942D
:103B10001943DC01CB018856954CAF4FBF4F8093C2
:103B2000840390938503A0938603B09387038091C9
:103B30008D079927AA27BB27BC01CD010E941943F5
:103B4000DC01CB018856954CAF4FBF4F809380036B
:103B500090938103A0938203B093830310926F0329
:103B600010926E0380913C0490913D04AA2797FD2A
:103B7000A095BA2FBC01CD012EE036E040E050E028
:103B80000E941943DC01CB018093DD079093DE078F
:103B9000A093DF07B093E00710923404109233042F
:103BA00081E08093000108959F92AF92BF92CF92DF
:103BB000DF92EF92FF920F931F93CF93DF93809149
:103BC0008A0490918B042091E3033091E403821BDB
:103BD000930B9093D5078093D4078091E503909140
:103BE000E60320918C0430918D04821B930B9093FB
:103BF000AA078093A9078091E7039091E803209199
:103C00008E0430918F04821B930B9093B4078093A2
:103C1000B3078091A9079091AA0790931207809308
:103C200011078091D1079091D2077C010027F7FC02
:103C30000095102F8091DF039091E003AA2797FD54
:103C4000A095BA2FBC01CD012CE030E040E050E05F
:103C50000E941943DC01CB01E80EF91E0A1F1B1F4D
:103C600017FF05C00894E11CF11C011D111D1595DD
:103C70000795F794E794F092D207E092D1078091EC
:103C8000E1079091E2077C010027F7FC0095102FD7
:103C90008091E1039091E203AA2797FDA095BA2FA6
:103CA000BC01CD012CE030E040E050E00E9419431F
:103CB000DC01CB01E80EF91E0A1F1B1F17FF05C010
:103CC0000894E11CF11C011D111D15950795F79431
:103CD000E794F092E207E092E1078091BA079091B1
:103CE000BB079C01442737FD4095542F8091DD038D
:103CF0009091DE03AA2797FDA095BA2F280F391FB0
:103D00004A1F5B1F57FF04C02F5F3F4F4F4F5F4F4E
:103D100055954795379527953093BB072093BA075C
:103D20008091DF039091E0036CE070E0869F90014A
:103D3000879F300D969F300D1124C9019C014427A7
:103D400037FD4095542F8091660490916704A091AF
:103D50006804B0916904820F931FA41FB51F80935C
:103D6000660490936704A0936804B09369048091FB
:103D7000E1039091E203869F9001879F300D969F0B
:103D8000300D1124C9019C01442737FD4095542F63
:103D90008091620490916304A0916404B0916504E1
:103DA000820F931FA41FB51F809362049093630436
:103DB000A0936404B09365048091C2079091C307F7
:103DC0002091DF033091E003820F931F9093C3078C
:103DD0008093C2078091D6079091D7072091E10385
:103DE0003091E203820F931F9093D7078093D607F9
:103DF0008091800490918104019690938104809336
:103E0000800480915E0490915F04A0916004B09161
:103E10006104BC01CD010E9457425B016C0180919D
:103E20001D0790911E07AA2797FDA095BA2FBC01E8
:103E3000CD010E9457427B018C0180917C049091BE
:103E40007D04A0917E04B0917F049C01AD01C80166
:103E5000B7010E94B141DC01CB019C01AD01C6015B
:103E6000B5010E94B241DC01CB01BC01CD010E9431
:103E70003A42DC01CB0180935E0490935F04A093EF
:103E80006004B09361048091D4079091D507AA276C
:103E900097FDA095BA2FC091DD07D091DE07E09184
:103EA000DF07F091E007C80FD91FEA1FFB1FC0937F
:103EB000DD07D093DE07E093DF07F093E007809102
:103EC000D4079091D5079C01442737FD4095542F86
:103ED0008091460490914704A0914804B091490410
:103EE000820F931FA41FB51F80934604909347042D
:103EF000A0934804B09349048091D4079091D507CA
:103F00009C01442737FD4095542F809142049091A5
:103F10004304A0914404B0914504820F931FA41F51
:103F2000B51F8093420490934304A0934404B0933C
:103F30004504C03B33E8D30738E0E30730E0F3073C
:103F400064F0C05BD348E840F040C093DD07D093F5
:103F5000DE07E093DF07F093E0078091DD079091A3
:103F6000DE07A091DF07B091E007B7FF0CC08055D6
:103F70009C47A74FBF4F8093DD079093DE07A09328
:103F8000DF07B093E00790901804992009F0C3C0B0
:103F900080911704882309F0BEC08091690786FFCD
:103FA000BAC08091D4079091D507AA2797FDA09514
:103FB000BA2F2091560430915704409158045091E3
:103FC0005904BC01CD010E9419439B01AC0197FF2C
:103FD00004C02150384F4F4F5F4F6BE055954795C8
:103FE000379527956A95D1F780910A04E82EFF242A
:103FF00000271127CA01B901A80197010E9419439E
:10400000DC01CB018093900490939104A0939204DF
:10401000B0939304B7FF04C08150904FAF4FBF4F90
:104020005C016D013CE0D594C794B794A7943A9590
:10403000D1F7A0929004B0929104C0929204D092D1
:1040400093048091D4079091D507AA2797FDA09556
:10405000BA2F20914E0430914F044091500450915A
:104060005104BC01CD010E94194397FF04C0615067
:10407000784F8F4F9F4F2BE0959587957795679554
:104080002A95D1F7A80197010E941943DC01CB01C1
:104090008093940490939504A0939604B09397040E
:1040A000B7FF04C08150904FAF4FBF4F9C01AD018F
:1040B0001CE055954795379527951A95D1F720938C
:1040C0009404309395044093960450939704D6013A
:1040D000C501D7FE07C0B095A095909581959F4FDB
:1040E000AF4FBF4F81389105A105B10584F4DA01C6
:1040F000C90157FF07C0B095A095909581959F4F36
:10410000AF4FBF4F81389105A105B105A4F081E003
:104110008093350410C0109294041092950410926C
:1041200096041092970410929004109291041092A9
:104130009204109293048091A9079091AA0720916C
:10414000900430919104820F931F9093AA0780935B
:10415000A90700910904202F332744275527809170
:10416000940490919504A0919604B0919704BC0199
:10417000CD010E9419439B01AC0197FF04C021505F
:104180003E4F4F4F5F4FC9E055954795379527955F
:10419000CA95D1F78091A9079091AA07820F931F22
:1041A0009093AA078093A9078091A9079091AA07E5
:1041B0009C01442737FD4095542F80914A049091EB
:1041C0004B04A0914C04B0914D04820F931FA41F87
:1041D000B51F80934A0490934B04A0934C04B09372
:1041E0004D048091A9079091AA0720911B0430915A
:1041F0001C04821B930B9C01442737FD4095542FD0
:1042000080914E0490914F04A0915004B0915104BC
:10421000820F931FA41FB51F80934E0490934F04E9
:10422000A0935004B0935104C0918003D0918103B6
:10423000E0918203F0918303C817D907EA07FB07CF
:10424000C4F488EA91E6A0E0B0E08C1B9D0BAE0BB5
:10425000BF0B80934E0490934F04A0935004B093EF
:10426000510480934A0490934B04A0934C04B09360
:104270004D0422273327A9012C1B3D0B4E0B5F0B4E
:1042800080914E0490914F04A0915004B09151043C
:1042900082179307A407B507B4F4CE01DF01885A4B
:1042A0009146A040B04080934E0490934F04A09359
:1042B0005004B093510480934A0490934B04A0930C
:1042C0004C04B0934D048091E5039091E6030F9761
:1042D00034F488E19CEF9093AA078093A90780911A
:1042E000E5039091E603079734F480E398EF909309
:1042F000AA078093A907109101011A30A9F48091AF
:10430000E5039091E603835F934034F088EE93E0F9
:104310009093AA078093A9078091E5039091E60303
:104320008A5F9340DCF014C08091E5039091E6032E
:10433000855E974034F088EE93E09093AA078093CF
:10434000A9078091E5039091E603835F974034F0DD
:1043500080ED97E09093AA078093A9078091B30717
:104360009091B4072091940430919504821B930B93
:104370009093B4078093B307202F33274427552702
:104380008091900490919104A0919204B091930433
:10439000BC01CD010E9419439B01AC0197FF04C0F1
:1043A00021503E4F4F4F5F4FB9E055954795379598
:1043B0002795BA95D1F78091B3079091B407821BE6
:1043C000930B9093B4078093B3078091B3079091B8
:1043D000B4079C01442737FD4095542F8091520427
:1043E00090915304A0915404B0915504820F931FEF
:1043F000A41FB51F8093520490935304A0935404B8
:10440000B09355048091B3079091B407209119049B
:1044100030911A04821B930B9C01442737FD409571
:10442000542F8091560490915704A0915804B09154
:104430005904820F931FA41FB51F809356049093B5
:104440005704A0935804B0935904C0918403D091A9
:104450008503E0918603F0918703C817D907EA071F
:10446000FB07C4F488EA91E6A0E0B0E08C1B9D0B4A
:10447000AE0BBF0B8093560490935704A09358043F
:10448000B09359048093520490935304A09354041E
:10449000B093550422273327A9012C1B3D0B4E0B4B
:1044A0005F0B8091560490915704A0915804B091ED
:1044B000590482179307A407B507B4F4CE01DF01AE
:1044C000885A9146A040B040809356049093570478
:1044D000A0935804B09359048093520490935304CA
:1044E000A0935404B09355048091E7039091E8039E
:1044F0000F9734F488E19CEF9093B4078093B3074F
:104500008091E7039091E803079734F480E398EFF4
:104510009093B4078093B3071A30A9F48091E7030E
:104520009091E803835F934034F088EE93E090939A
:10453000B4078093B3078091E7039091E8038A5F03
:104540009340DCF014C08091E7039091E803855E0E
:10455000974034F088EE93E09093B4078093B307CC
:104560008091E7039091E803835F974034F080EDFA
:1045700097E09093B4078093B3078FEE80937A000F
:104580008091460490914704A0914804B091490459
:1045900080935A0490935B04A0935C04B0935D04F1
:1045A0008091560490915704A0915804B0915904F9
:1045B0008093760490937704A0937804B093790461
:1045C00080914E0490914F04A0915004B0915104F9
:1045D00080936E0490936F04A0937004B093710461
:1045E0008091520490915304A0915404B0915504C9
:1045F0008093720490937304A0937404B093750431
:1046000080914A0490914B04A0914C04B0914D04C8
:1046100080936A0490936B04A0936C04B0936D0430
:104620008091690787FF6EC0992009F06BC0809167
:104630001704882309F066C08091B3079091B407EE
:10464000893C91058CF02091B3073091B407220F7B
:10465000331F220F331F8091B3079091B407820F4D
:10466000931F8052934017C08091B3079091B40775
:1046700088539F4FA4F42091B3073091B407220FC1
:10468000331F220F331F8091B3079091B407820F1D
:10469000931F805E9C4F9093B4078093B3078091E3
:1046A000A9079091AA07893C91058CF02091A90750
:1046B0003091AA07220F331F220F331F8091A907C1
:1046C0009091AA07820F931F8052934017C0809148
:1046D000A9079091AA0788539F4FA4F42091A90796
:1046E0003091AA07220F331F220F331F8091A90791
:1046F0009091AA07820F931F805E9C4F9093AA0708
:104700008093A90780916507E82FFF27EE0FFF1F11
:10471000EB5CF84F8081918182599F4F2091310449
:1047200030913204281739071CF42F5F3F4F0CC01B
:104730008081918182599F4F821793074CF42115F4
:10474000310531F021503040309332042093310450
:1047500080916607E82FFF27EE0FFF1FEB5CF84FF5
:104760008081918182599F4F20912F043091300494
:10477000281739071CF42F5F3F4F0CC080819181AF
:1047800082599F4F821793074CF42115310531F060
:10479000215030403093300420932F0480916707DC
:1047A000E82FFF27EE0FFF1FEB5CF84F8081918110
:1047B00082599F4F20912D0430912E0428173907DC
:1047C0001CF42F5F3F4F0CC08081918182599F4F15
:1047D000821793074CF42115310531F021503040F8
:1047E00030932E0420932D0480916807E82FFF2733
:1047F000EE0FFF1FEB5CF84F8081918182599F4F34
:1048000020912B0430912C04281739071CF42F5FBA
:104810003F4F0CC08081918182599F4F821793072F
:104820004CF42115310531F02150304030932C04E7
:1048300020932B04809131049091320497FF05C09E
:1048400010923204109231040AC08F3F910539F062
:1048500034F08FEF90E09093320480933104809194
:104860002F049091300497FF05C0109230041092ED
:104870002F040AC08F3F910539F034F08FEF90E09C
:104880009093300480932F0480912D0490912E04F6
:1048900097FF05C010922E0410922D040AC08F3F7E
:1048A000910539F034F08FEF90E090932E048093CF
:1048B0002D0480912B0490912C0497FF05C0109239
:1048C0002C0410922B040AC08F3F910539F034F06C
:1048D0008FEF90E090932C0480932B04DF91CF9185
:1048E0001F910F91FF90EF90DF90CF90BF90AF900E
:1048F0009F90089580912104882301F58093B20749
:104900008093AB078093CC078093CE078091AE0352
:10491000882311F08093AB078091AF03882311F0B7
:104920008093B2078091B003882311F08093CE0763
:104930008091B103882311F08093CC078091AB075D
:1049400099279093F2068093F1068091B2079927F8
:104950009093F4068093F3068091CE079927909365
:10496000F6068093F5068091CC0799279093F80678
:104970008093F7061092F8031092F7030E941E1717
:1049800008951F9380916C078B3F98F08B3F19F42B
:10499000809131040EC08C3F19F480912F0409C01E
:1049A0008D3F19F480912D0404C08E3F21F4809135
:1049B0002B0480937A0380917A03882321F08F3F20
:1049C00011F480937A0380916B078B3F98F08B3FB3
:1049D00019F4809131040EC08C3F19F480912F049A
:1049E00009C08D3F19F480912D0404C08E3F21F43D
:1049F00080912B0480937B0380917B03882329F093
:104A0000843618F084E680937B0380916D078B3F9A
:104A100098F08B3F19F4809131040EC08C3F19F44B
:104A200080912F0409C08D3F19F480912D0404C09A
:104A30008E3F21F480912B04809379038091790338
:104A4000882329F0843618F084E6809379038091D6
:104A50006F078B3F98F08B3F19F4809131040EC0A3
:104A60008C3F19F480912F0409C08D3F19F4809177
:104A70002D0404C08E3F21F480912B048093780391
:104A800080917803882321F08F3F11F4809378037D
:104A9000809176078B3F98F08B3F19F48091310419
:104AA0000EC08C3F19F480912F0409C08D3F19F47A
:104AB00080912D0404C08E3F21F480912B048093BB
:104AC000770380917703882321F08F3F11F480933F
:104AD0007703809177078B3F98F08B3F19F4809193
:104AE00031040EC08C3F19F480912F0409C08D3F12
:104AF00019F480912D0404C08E3F21F480912B0481
:104B000080937603809176038B3010F48AE002C0A4
:104B10008F3F11F480937603809178078B3F98F054
:104B20008B3F19F4809131040EC08C3F19F48091B1
:104B30002F0409C08D3F19F480912D0404C08E3FCD
:104B400021F480912B048093750380917503882351
:104B500021F08F3F11F48093750380917D078B3F87
:104B600098F08B3F19F4809131040EC08C3F19F4FA
:104B700080912F0409C08D3F19F480912D0404C049
:104B80008E3F21F480912B048093730380917303F3
:104B9000882321F08F3F11F48093730380917E0767
:104BA0008B3F98F08B3F19F4809131040EC08C3FFD
:104BB00019F480912F0409C08D3F19F480912D04C0
:104BC00004C08E3F21F480912B04809312048091C5
:104BD0001204882321F08F3F11F4809312048091F6
:104BE0007F078B3F98F08B3F19F4809131040EC002
:104BF0008C3F19F480912F0409C08D3F19F48091E6
:104C00002D0404C08E3F21F480912B048093110465
:104C100080911104882321F08F3F11F480931104B7
:104C2000809180078B3F98F08B3F19F4809131047D
:104C30000EC08C3F19F480912F0409C08D3F19F4E8
:104C400080912D0404C08E3F21F480912B04809329
:104C5000100480911004882321F08F3F11F4809379
:104C60001004809181078B3F98F08B3F19F480915D
:104C700031040EC08C3F19F480912F0409C08D3F80
:104C800019F480912D0404C08E3F21F480912B04EF
:104C900080930F0480910F04882321F08F3F11F43B
:104CA00080930F04809191078B3F98F08B3F19F40C
:104CB000809131040EC08C3F19F480912F0409C0FB
:104CC0008D3F19F480912D0404C08E3F21F4809112
:104CD0002B0480930E0480910E04882321F08F3FD3
:104CE00011F480930E04809192078B3F98F08B3FD4
:104CF00019F4809131040EC08C3F19F480912F0477
:104D000009C08D3F19F480912D0404C08E3F21F419
:104D100080912B0480930D0480910D04882321F051
:104D20008F3F11F480930D04809193078B3F98F08F
:104D30008B3F19F4809131040EC08C3F19F480919F
:104D40002F0409C08D3F19F480912D0404C08E3FBB
:104D500021F480912B0480930C0480910C0488230F
:104D600021F08F3F11F480930C04809194078B3FC6
:104D700098F08B3F19F4809131040EC08C3F19F4E8
:104D800080912F0409C08D3F19F480912D0404C037
:104D90008E3F21F480912B0480930B0480910B04AF
:104DA000882321F08F3F11F480930B0480918207B8
:104DB0008B3F98F08B3F19F4809131040EC08C3FEB
:104DC00019F480912F0409C08D3F19F480912D04AE
:104DD00004C08E3F21F480912B0480937203809154
:104DE0007203882321F08F3F11F480937203809126
:104DF00087078B3F98F08B3F19F4809131040EC0E8
:104E00008C3F19F480912F0409C08D3F19F48091D3
:104E10002D0404C08E3F21F480912B0480937103F4
:104E200080917103882321F08F3F11F480937103E7
:104E300080918A078B3F98F08B3F19F48091310461
:104E40000EC08C3F19F480912F0409C08D3F19F4D6
:104E500080912D0404C08E3F21F480912B04809317
:104E60000A0480910A04882321F08F3F11F4809373
:104E70000A0480918B078B3F98F08B3F19F4809147
:104E800031040EC08C3F19F480912F0409C08D3F6E
:104E900019F480912D0404C08E3F21F480912B04DD
:104EA0008093090480910904882321F08F3F11F435
:104EB00080930904809190078B3F98F08B3F19F401
:104EC000809131040EC08C3F19F480912F0409C0E9
:104ED0008D3F19F480912D0404C08E3F21F4809100
:104EE0002B048093700380917003882321F08F3FFF
:104EF00011F48093700310917303812F992787FD1C
:104F00009095A92FB92FBC01CD010E94574217FFE0
:104F100006C020E030E040E853E40E94B24127E1BF
:104F200037EB41ED58E30E94D142DC01CB01809385
:104F30007C0390937D03A0937E03B0937F038091C5
:104F400074078093D307809173078093B5071F91EF
:104F500008952F923F924F925F926F927F928F921D
:104F60009F92AF92BF92CF92DF92EF92FF920F93F8
:104F70001F93CF93DF93CDB7DEB765970FB6F89445
:104F8000DEBF0FBECDBF0E94D41D299AE09022043F
:104F9000F0902304FA82E9828091B50799270A9656
:104FA000E816F90614F49A83898380912A048436DA
:104FB00008F06EC080910303882399F48091060362
:104FC000909107038F5F9F4F61F488E99AE3909374
:104FD000CA038093C90380E09CE090930703809309
:104FE00006038091B4049091B504009731F00197C5
:104FF0009093B5048093B40404C0109221041092DD
:105000003704809101018A3011F4289A01C0289850
:105010008091FD039091FE03895E9340B0F18091F1
:105020007A07282F33273A83298381E08093370436
:1050300080916107A82FBB27AA0FBB1FFD01E55B6D
:10504000F84F1182108280916207282F3327220F98
:10505000331FC901855B984FFC0111821082AB5C44
:10506000B84F11961C921E922B5C384FD9011196A5
:105070001C921E9280916407E82FFF27EE0FFF1FFE
:10508000EB5CF84F118210828BC21092210488C20F
:1050900080912A048D3808F483C2109237049091CD
:1050A0007B0782E3989FC00111249093B5048093FD
:1050B000B404E981FA81B9976CF08091FD03909175
:1050C000FE03FFEF8F3F9F0729F001969093FE03A9
:1050D0008093FD038091FD039091FE038F3F910526
:1050E00009F0B0F4109298041092990410929A0466
:1050F00010929B0410929C0410929D0410929E04A6
:1051000010929F048A3F910519F481E08093BC04BA
:1051100080916307E82FFF27EE0FFF1FEB5CF84F2E
:1051200080819181813591050CF491C120912104F8
:10513000222309F08CC180916407E82FFF27EE0F2E
:10514000FF1FEB5CF84F808191818C3491050CF44A
:10515000F5C08091B6048F5F8093B604893C08F453
:1051600076C129982093B6041092FE031092FD0395
:1051700030916107E32FFF27EE0FFF1FEB5CF84F25
:105180008081918187349105B4F480916207E82F82
:10519000FF27EE0FFF1FEB5CF84F8081918101909C
:1051A000F081E02DF7FF03C0F095E195FF4FE73464
:1051B000F1050CF47AC041E020916207A22FBB27D1
:1051C000AA0FBB1FAB5CB84F8D919C911197873490
:1051D000910544F0E32FFF27EE0FFF1FEB5CF84F24
:1051E000808191818D919C918734910574F080919B
:1051F0006107E82FFF27EE0FFF1FEB5CF84F808160
:105200009181873491050CF042E0E22FFF27EE0FE9
:10521000FF1FEB5CF84F808191818634910574F417
:1052200080916107E82FFF27EE0FFF1FEB5CF84F1F
:1052300080819181873491050CF043E0E22FFF27B4
:10524000EE0FFF1FEB5CF84F808191818A5B9F4FCF
:1052500074F480916107E82FFF27EE0FFF1FEB5CCE
:10526000F84F80819181873491050CF044E0E22F62
:10527000FF27EE0FFF1FEB5CF84F808191818A5B67
:105280009F4F74F480916107E82FFF27EE0FFF1FF7
:10529000EB5CF84F80819181863491050CF445E0F8
:1052A000A2E0B0E0042E0E94B04380916207E82F94
:1052B000FF27EE0FFF1FEB5CF84F8081918101907B
:1052C000F081E02DF7FF03C0F095E195FF4F749753
:1052D000BCF480916107E82FFF27EE0FFF1FEB5C06
:1052E000F84F808191818A5B9F4F54F481E08093D5
:1052F000320688EE93E09093CA038093C903A7C057
:105300000E94790247E461E677E00E944F028091B3
:10531000690780FF10C080910A0390910B03875B9F
:10532000934038F480910A0390910B038E5E924073
:1053300010F40E94510E0E943B1C82C0808191811A
:10534000855B9F4F0CF081C08091B6048F5F809386
:10535000B604893C08F47BC02998A4E0B0E08FEF44
:10536000082E0E94B043209321042093B60410928B
:10537000FE031092FD030E943B1CA4E0B0E080916C
:1053800084049091850497FF02C081509F4F892F1C
:10539000990F990B082E0E94B043A5E0B0E08091D0
:1053A000840490918504082E0E94B043A6E0B0E0EA
:1053B000809182049091830497FF02C081509F4F97
:1053C000892F990F990B082E0E94B043A7E0B0E0F7
:1053D0008091820490918304082E0E94B04308E0DB
:1053E00010E080917C0490917D04A0917E04B091A6
:1053F0007F04BC01CD010E943A42DC01CB019C013B
:1054000097FF02C021503F4F832F992787FD9A9520
:10541000D801082E0E94B04309E010E080917C047E
:1054200090917D04A0917E04B0917F04BC01CD01D8
:105430000E943A42DC01CB01D801082E0E94B04301
:105440000E9479020E94C01A02C02093B604809183
:105450006307E82FFF27EE0FFF1FEB5CF84F8081FB
:1054600091818B5A9F4F0CF09BC020916407E22FD3
:10547000FF27EE0FFF1FEB5CF84F80819181855B6A
:105480009F4F0CF06DC08091B7048F5F8093B7047D
:10549000893C08F467C088EC8093B70481E090E011
:1054A0009093FE038093FD0381E08093210410928A
:1054B000A0041092A1041092A2041092A3041092CE
:1054C0004604109247041092480410924904109226
:1054D0004204109243041092440410924504109226
:1054E00056041092570410925804109259041092C6
:1054F0004E0410924F041092500410925104809167
:10550000760490917704A0917804B0917904809307
:10551000520490935304A0935404B0935504809183
:105520006E0490916F04A0917004B0917104809307
:105530004A0490934B04A0934C04B0934D041092F2
:1055400098041092990410929A0410929B0410925D
:105550009C0410929D0410929E0410929F0402C01D
:105560001092B704E22FFF27EE0FFF1FEB5CF84FFE
:10557000808191818C3491058CF08091B8048F5F8B
:105580008093B804893C60F01092210488EC8093E9
:10559000B8041092FE031092FD0302C01092B804EA
:1055A00080916D03815080936D0380916D038F3FD7
:1055B00029F080913704882309F4DFC30E94C124B5
:1055C0008091C5049091C604AC01440F551F480F4B
:1055D000591FF0906107AF2DBB27AA0FBB1FFD011C
:1055E000EB5CF84FE0907007CE2CDD248081918138
:1055F0008C9D80018D9D100D9C9D100D1124400FE0
:10560000511F57FF02C04D5F5F4F55954795559508
:105610004795A55BB84F80917107682F77278D91CB
:105620009C91869F9001879F300D969F300D11248D
:10563000420F531F5093C6044093C5048091ED045C
:105640009091EE042091E9043091EA04820F931FB7
:10565000481B590B50932904409328048091C70498
:105660009091C804AC01440F551F480F591F009179
:105670006207A02FBB27AA0FBB1FFD01EB5CF84FF1
:10568000808191818C9DF0018D9DF00D9C9DF00D90
:1056900011244E0F5F1F57FF02C04D5F5F4F55959E
:1056A000479555954795A55BB84F8D919C91869FE1
:1056B0009001879F300D969F300D1124420F531F8C
:1056C0005093C8044093C7048091EB049091EC047C
:1056D0002091E7043091E804820F931F481B590B77
:1056E000509327044093260480916407E82FFF27F6
:1056F000EE0FFF1FEB5CF84F8081918190958195B3
:105700009F4F909325048093240480916307E82F92
:10571000FF27EE0FFF1FEB5CF84F808191818858C7
:105720009F4F909323048093220410917603812F3E
:10573000992787FD9095A92FB92FBC01CD010E9413
:10574000574217FF06C020E030E040E853E40E94D3
:10575000B24120E030E040E251E40E94B241DC017D
:10576000CB0120E030E040E85CE3BC01CD010E94C9
:10577000D142DC01CB018093D8079093D907A09345
:10578000DA07B093DB0710917503812F992787FD06
:105790009095A92FB92FBC01CD010E94574217FF48
:1057A00006C020E030E040E853E40E94B24120E02F
:1057B00030EE4BE256E40E94F441DC01CB018093D1
:1057C000C8079093C907A093CA07B093CB0760910D
:1057D000AB03662331F08AE090E09093CA03809394
:1057E000C903462F552742FF09C080910B04282F7B
:1057F0003327220F331F220F331F13C09A01287043
:10580000307043FF0EC080910B04282F33278CEF9C
:105810009FEF289FA001299F500D389F500D112404
:105820009A018091070490910804AC01F3E0440FC1
:10583000551FFA95E1F7481B590B420F531F57FFAD
:1058400002C0495F5F4FE3E055954795EA95E1F760
:105850005093080440930704462F552744FF09C07E
:1058600080910B04282F3327220F331F220F331F61
:1058700013C09A012072307045FF0EC080910B0456
:10588000282F33278CEF9FEF289FD001299FB00D41
:10589000389FB00D11249D0180910504909106045C
:1058A000AC0163E0440F551F6A95E1F7481B590BA3
:1058B000420F531F57FF02C0495F5F4F83E055956A
:1058C00047958A95E1F7509306044093050440916B
:1058D000AA03842F992783FF03C082E390E007C0C7
:1058E0009C012470307082FF07C08EEC9FEF909374
:1058F00004048093030404C030930404209303043D
:10590000242F332721FF09C080916E0390916F03EC
:10591000019690936F0380936E0324FF09C08091DA
:105920006E0390916F03019790936F0380936E03C2
:10593000809107049091080497FD019695958795AD
:10594000E0912804F0912904E80FF91FF09329044D
:10595000E0932804809105049091060497FD019638
:10596000959587956091260470912704680F791F9B
:10597000709327046093260480910304909104049B
:10598000880F991F880F991F409124045091250476
:10599000480F591F509325044093240480913E06DC
:1059A00080FF59C080910B04813808F454C0809165
:1059B0003706992787FD90952E2D3327829FD0019A
:1059C000839FB00D929FB00D1124EA0FFB1FF0933F
:1059D0002904E093280480913806992787FD909543
:1059E000829FF001839FF00D929FF00D11246E0FA6
:1059F0007F1F7093270460932604809139069927AE
:105A000087FD9095480F591F509325044093240417
:105A100080913B06282F332727FD309580916E0714
:105A20009927289FA001299F500D389F500D1124C0
:105A300050936F0340936E0380913A06282F3327CB
:105A400080912204909123042817390724F430937D
:105A5000230420932204809122049091230497FF31
:105A600004C010922304109222048091690782FFDF
:105A70000CC080E090E0A0E0B0E08093C807909375
:105A8000C907A093CA07B093CB078091D80790911C
:105A9000D907A091DA07B091DB0720E030E040E0C1
:105AA00050E0BC01CD010E946142882364F480E093
:105AB00090E0A0E0B0E08093D8079093D907A0933E
:105AC000DA07B093DB078091C8079091C907A091CE
:105AD000CA07B091CB0720E030E040E050E0BC01C5
:105AE000CD010E946142882364F480E090E0A0E050
:105AF000B0E08093C8079093C907A093CA07B093FA
:105B0000CB074091280450912904CA0157FD039600
:105B10009C01359527953595279537FF03C030951E
:105B200021953F4F809101049091020482179307C1
:105B30006CF4CA0157FF03C0909581959F4F97FD64
:105B40000396959587959595879501C001979093B4
:105B50000204809301044091260450912704CA0155
:105B600057FD03969C01359527953595279537FF69
:105B700003C0309521953F4F8091FF039091000421
:105B8000821793076CF4CA0157FF03C09095819563
:105B90009F4F97FD0396959587959595879501C09D
:105BA0000197909300048093FF038091370488232A
:105BB00041F010920204109201041092000410921D
:105BC000FF03E02FFF27EE0FFF1FEB5CF84F409124
:105BD0008807242F3327808191812817390744F4BF
:105BE0008091950782FF04C081E08093160413C062
:105BF000E02FFF27EE0FFF1FEB5CF84F842F992754
:105C000020918907821B910920813181281739074A
:105C100014F41092160440916207E42FFF27EE0F50
:105C2000FF1FEB5CF84F50918807852F992722279B
:105C30003327281B390B808191818217930744F405
:105C40008091950783FF04C081E08093150416C0FE
:105C500080911504882391F0E42FFF27EE0FFF1F9A
:105C6000EB5CF84F809189079927851B910920816A
:105C700031818217930714F410921504EF2DFF273A
:105C8000EE0FFF1FEB5CF84F40918807242F33275E
:105C9000808191812817390744F48091950780FF0E
:105CA00004C081E08093130417C0809113048823FB
:105CB00099F0EF2DFF27EE0FFF1FEB5CF84F842FBD
:105CC000992720918907821B91092081318128170A
:105CD000390714F41092130440916107E42FFF2751
:105CE000EE0FFF1FEB5CF84F50918807852F992727
:105CF00022273327281B390B808191818217930734
:105D000044F48091950781FF04C081E080931404DE
:105D100016C080911404882391F0E42FFF27EE0F22
:105D2000FF1FEB5CF84F809189079927851B91092C
:105D3000208131818217930714F41092140480910A
:105D40001604882319F480911504811181E0809351
:105D5000170480911304882321F48091140488236C
:105D600051F081E0809318041092170410921604E9
:105D70001092150402C08093180420911704222366
:105D800031F084E690E09093CA038093C903222304
:105D900021F480911804882351F080918707992776
:105DA000A981BA818A179B0714F49A838983B091D9
:105DB0003704BB83BB2341F11092250410922404C5
:105DC000109229041092280410922704109226049D
:105DD00080E090E0A8ECBFE38093D8079093D907C8
:105DE000A093DA07B093DB078BE09CEBA2E3BCE364
:105DF0008093C8079093C907A093CA07B093CB07B5
:105E000010921704109218048091BE079091BF075A
:105E1000A091C007B091C10720917604309177041A
:105E20004091780450917904820F931FA41FB51FED
:105E30008093BE079093BF07A093C007B093C1079C
:105E40008091C4079091C507A091C607B091C7077C
:105E500060906E0470906F04809070049090710454
:105E6000860D971DA81DB91D8093C4079093C50783
:105E7000A093C607B093C7078091B6079091B70764
:105E8000A091B807B091B907E0907204F090730444
:105E90000091740410917504EC82FD820E831F83BF
:105EA0008E0D9F1DA01FB11F8093B6079093B7075B
:105EB000A093B807B093B9078091AE079091AF0750
:105EC000A091B007B091B107E0906A04F0906B0424
:105ED00000916C0410916D04E886F9860A871B878F
:105EE0008E0D9F1DA01FB11F8093AE079093AF072B
:105EF000A093B007B093B10750901804552029F42F
:105F000080911704882309F45FC0109266041092F0
:105F1000670410926804109269041092620410924F
:105F2000630410926404109265041092BE071092EC
:105F3000BF071092C0071092C1071092C4071092B9
:105F4000C5071092C6071092C7071092B6071092A5
:105F5000B7071092B8071092B9071092AE071092C7
:105F6000AF071092B0071092B1078091560490913C
:105F70005704A0915804B09159048093520490930F
:105F80005304A0935404B093550480914E0490910F
:105F90004F04A0915004B091510480934A0490930F
:105FA0004B04A0934C04B0934D041092D403109270
:105FB000D30310921A041092190410921C04109228
:105FC0001B04552009F0FBC080911704882309F0B9
:105FD000F6C080917507E82EFF2400271127CA011B
:105FE000B901A80197010E948D4359016A0180916E
:105FF000D1079091D207AA2797FDA095BA2FA81A8A
:10600000B90ACA0ADB0AC401B301A80197010E94B8
:106010008D4379018A018091E1079091E207AA27D7
:1060200097FDA095BA2FE81AF90A0A0B1B0BD601A7
:10603000C501D7FE03C00F96A11DB11D5C016D0106
:1060400054E0D594C794B794A7945A95D1F7D80142
:10605000C70117FF03C00F96A11DB11D7C018D0163
:1060600044E015950795F794E7944A95D1F7809108
:10607000010490910204819734F48091FF03909180
:1060800000048197A4F0C601B50123E030E040E0B0
:1060900050E00E948D4359016A01C801B70123E015
:1060A00030E040E050E00E948D4379018A01809108
:1060B0006407E82FFF27EE0FFF1FEB5CF84F80818E
:1060C00091810190F081E02DF7FF03C0F095E195FB
:1060D000FF4F7A97A4F0C601B50123E030E040E01D
:1060E00050E00E948D4359016A01C801B70123E0C5
:1060F00030E040E050E00E948D4379018A0121E2C6
:10610000A216B104C104D1042CF030E2A32EB12CAC
:10611000C12CD12C30EEA3163FEFB3063FEFC306E0
:106120003FEFD30644F420EEA22E2FEFB22E2FEF36
:10613000C22E2FEFD22E41E2E416F1040105110523
:106140002CF090E2E92EF12C012D112D50EEE516E8
:106150005FEFF5065FEF05075FEF150744F480EE8C
:10616000E82E8FEFF82E8FEF082F8FEF182F8091EA
:10617000560490915704A0915804B09159048A197B
:106180009B09AC09BD098093560490935704A093D2
:106190005804B093590480914E0490914F04A091FB
:1061A0005004B09151048E199F09A00BB10B80933C
:1061B0004E0490934F04A0935004B09351048091E7
:1061C000D3039091D4038F3F910509F008F474C56F
:1061D000552009F0F1C480911704882309F0ECC41C
:1061E00080913504882309F0E7C48091BE0790911F
:1061F000BF07A091C007B091C107B7FF04C081508D
:106200009F4FAF4FBF4F292E3A2E4B2E552447FCA0
:106210005A942092BE073092BF074092C007509216
:10622000C1078091C4079091C507A091C607B0919E
:10623000C707B7FF04C081509F4FAF4FBF4F892F93
:106240009A2FAB2FBB27A7FDBA958C879D87AE876A
:10625000BF878093C4079093C507A093C607B093E8
:10626000C70780917507E82EFF240027112720918A
:106270006604309167044091680450916904C80134
:10628000B7010E94194397FF04C061507F4F8F4FA1
:106290009F4FA72EB82EC92EDD24C7FCDA94A092FA
:1062A0006604B0926704C0926804D0926904209199
:1062B0006204309163044091640450916504C80104
:1062C000B7010E94194397FF04C061507F4F8F4F61
:1062D0009F4F672E782E892E992487FC9A9460927E
:1062E00062047092630480926404909265048091C9
:1062F0005E0490915F04A0916004B0916104B7FFC7
:1063000004C081509F4FAF4FBF4F892F9A2FAB2FA3
:10631000BB27A7FDBA9580935E0490935F04A0937A
:106320006004B0936104D201C1018A199B09AC09D0
:10633000BD098093AC049093AD04A093AE04B093D8
:10634000AF0420918E07E22EFF2400271127BC0105
:10635000CD01A80197010E948D4359016A01209344
:10636000BD043093BE044093BF045093C0048C8599
:106370009D85AE85BF8586199709A809B9098093BF
:10638000B0049093B104A093B204B093B304BC01E1
:10639000CD01A80197010E948D432093C104309341
:1063A000C2044093C3045093C404D601C501D7FE70
:1063B00004C081509F4FAF4FBF4F892F9A2FAB2FF3
:1063C000BB27A7FDBA9590931A048093190457FF31
:1063D00004C021503F4F4F4F5F4FBB2757FDBA9529
:1063E000A52F942F832F90931C0480931B048091DE
:1063F0000104909102048197D4F48091FF0390915D
:1064000000048197A4F480916407E82FFF27EE0F22
:10641000FF1FEB5CF84F808191810190F081E02DAE
:10642000F7FF03C0F095E195FF4F7A97C4F0809194
:10643000190490911A0497FD01969595879590936C
:106440001A048093190480911B0490911C0497FDF9
:1064500001969595879590931C0480931B048091D9
:10646000B6079091B707A091B807B091B907B7FFE9
:1064700004C081509F4FAF4FBF4F892F9A2FAB2F32
:10648000BB27A7FDBA958093B6079093B707A09353
:10649000B807B093B9078091AE079091AF07A0916C
:1064A000B007B091B107B7FF04C081509F4FAF4F05
:1064B000BF4F892F9A2FAB2FBB27A7FDBA9580938B
:1064C000AE079093AF07A093B007B093B107809148
:1064D000760490917704A0917804B0917904EC80CF
:1064E000FD800E811F81E81AF90A0A0B1B0BE0924E
:1064F000A404F092A5040093A6041093A70480912D
:106500006E0490916F04A0917004B091710428857D
:1065100039854A855B85281B390B4A0B5B0B209319
:10652000A8043093A9044093AA045093AB04E092CA
:10653000AC04F092AD040093AE041093AF0420932A
:10654000B0043093B1044093B2045093B3048091EB
:10655000520490915304A0915404B09155048E19A3
:106560009F09A00BB10B8093520490935304A09306
:106570005404B093550480914A0490914B04A09127
:106580004C04B0914D04821B930BA40BB50B80936C
:106590004A0490934B04A0934C04B0934D04209173
:1065A000330430913404213831054CF080918A0451
:1065B00090918B04019690938B0480938A042058C9
:1065C0003F4F4CF480918A0490918B0401979093F3
:1065D0008B0480938A04A090C407B090C507C09034
:1065E000C607D090C707C601B5012AE130E040E0F8
:1065F00050E00E948D4330930607209305071092C8
:1066000034041092330481E090E09093CA048093A4
:10661000C9048091CF049091D004A091D104B0918D
:10662000D2042091BE073091BF074091C00750911E
:10663000C107821B930BA40BB50B815E914BAF4F2F
:10664000BF4F8F539C49A040B04008F0FEC0F1E01E
:10665000EF16F0E1FF06F0E00F07F0E01F070CF483
:106660006CC08091CB04882309F463C0D801C701B2
:1066700017FF07C088279927DC018E199F09A00BF7
:10668000B10BB7FF04C08150904FAF4FBF4F2CE00C
:10669000B595A795979587952A95D1F701969093EB
:1066A000CA048093C904D801C70117FF03C0079625
:1066B000A11DB11D13E0B595A795979587951A95DE
:1066C000D1F78093BD049093BE04A093BF04B09310
:1066D000C00489589341A040B04064F088E893E139
:1066E000A0E0B0E08093BD049093BE04A093BF04EB
:1066F000B093C0042091BD043091BE044091BF040A
:106700005091C00457FF04C021503F4F4F4F5F4F7F
:10671000232F342F452F552747FD5A958091190473
:1067200090911A04820F931F90931A048093190476
:1067300006C081E08093CB0402C01092CB04E090AD
:10674000AC04F090AD040091AE041091AF0420E0D1
:10675000E21620EFF2062FEF02072FEF12070CF0E0
:1067600071C08091CC04882309F468C0A801970106
:1067700017FF07C022273327A9012E193F09400B15
:10678000510B57FF04C02150304F4F4F5F4FECE08B
:106790005595479537952795EA95D1F78091C90486
:1067A0009091CA04820F931F9093CA048093C904E6
:1067B000D801C70117FF03C00796A11DB11D73E0E3
:1067C000B595A795979587957A95D1F78093BD0450
:1067D0009093BE04A093BF04B093C00488579C4E0E
:1067E000AF4FBF4F64F488E79CEEAFEFBFEF8093ED
:1067F000BD049093BE04A093BF04B093C004209145
:10680000BD043091BE044091BF045091C00457FFB5
:1068100004C021503F4F4F4F5F4F232F342F452F40
:10682000552747FD5A958091190490911A04820FBB
:10683000931F90931A048093190411C081E08093F0
:10684000CC040DC01092CC040AC01092CA0410925D
:10685000C90484EF91E09093890380938803109199
:106860008F07212F33278091C9049091CA042817DC
:10687000390724F43093CA042093C9044091AC042E
:106880005091AD046091AE047091AF04413084E04A
:10689000580780E0680780E0780774F080918E04E4
:1068A00090918F042091C9043091CA04820F931FE4
:1068B00090938F0480938E0440505C4F6F4F7F4FB6
:1068C00074F480918E0490918F042091C9043091CA
:1068D000CA04821B930B90938F0480938E0481E0F3
:1068E00090E09093CA048093C9041092C10410925E
:1068F000C2041092C3041092C4048091D3049091F6
:10690000D404A091D504B091D6048A199B09AC098E
:10691000BD09815E914BAF4FBF4F8F539C49A04043
:10692000B04008F000C1C090B004D090B104E09035
:10693000B204F090B304F1E0CF16F0E1DF06F0E02E
:10694000EF06F0E0FF060CF46CC08091CD048823C4
:1069500009F463C0D701C601F7FE07C0882799274D
:10696000DC018C199D09AE09BF09B7FF04C0815035
:10697000904FAF4FBF4F2CE0B595A7959795879552
:106980002A95D1F701969093CA048093C904D70140
:10699000C601F7FE03C00796A11DB11D03E0B59522
:1069A000A795979587950A95D1F78093C104909301
:1069B000C204A093C304B093C40489589341A04077
:1069C000B04064F088E893E1A0E0B0E08093C104B7
:1069D0009093C204A093C304B093C4042091C10453
:1069E0003091C2044091C3045091C40457FF04C0C5
:1069F00021503F4F4F4F5F4F232F342F452F5527A7
:106A000047FD5A9580911B0490911C04820F931F9F
:106A100090931C0480931B0406C081E08093CD04F6
:106A200002C01092CD0420E0C21620EFD2062FEF54
:106A3000E2062FEFF2060CF073C08091CE0488239B
:106A400009F46AC0D701C601F7FE07C08827992755
:106A5000DC018C199D09AE09BF099C01AD01B7FF8E
:106A600004C02150304F4F4F5F4FECE05595479594
:106A700037952795EA95D1F78091C9049091CA047A
:106A8000820F931F9093CA048093C904D701C60153
:106A9000F7FE03C00796A11DB11D73E0B595A7953C
:106AA000979587957A95D1F78093C1049093C20406
:106AB000A093C304B093C40488579C4EAF4FBF4FFC
:106AC00064F488E79CEEAFEFBFEF8093C10490932E
:106AD000C204A093C304B093C4042091C1043091B4
:106AE000C2044091C3045091C40457FF04C0215014
:106AF0003F4F4F4F5F4F232F342F452F552747FDD3
:106B00005A9580911B0490911C04820F931F9093BF
:106B10001C0480931B0411C081E08093CE040DC03F
:106B20001092CE040AC01092CA041092C90484EFD5
:106B300091E09093890380938803212F33278091DC
:106B4000C9049091CA042817390724F43093CA0461
:106B50002093C9044091B0045091B1046091B204F3
:106B60007091B304413084E0580780E0680780E00A
:106B7000780774F080918C0490918D042091C90461
:106B80003091CA04820F931F90938D0480938C04DC
:106B900040505C4F6F4F7F4FCCF480918C049091AC
:106BA0008D042091C9043091CA04821B930B9093E9
:106BB0008D0480938C040AC010921C0410921B0454
:106BC00010921A0410921904109235048091C8078B
:106BD0009091C907A091CA07B091CB0720E030E09F
:106BE00040E050E0BC01CD010E946142882341F4A5
:106BF00010921C0410921B0410921A041092190493
:106C00008091BE079091BF07A091C007B091C107C6
:106C10008093CF049093D004A093D104B093D20476
:106C20008091C4079091C507A091C607B091C7078E
:106C30008093D3049093D404A093D504B093D60446
:106C4000109266041092670410926804109269040E
:106C5000109262041092630410926404109265040E
:106C600010925E0410925F0410926004109261040E
:106C70001092BE071092BF071092C0071092C10772
:106C80001092C4071092C5071092C6071092C7074A
:106C90001092B6071092B7071092B8071092B90772
:106CA0001092AE071092AF071092B0071092B10782
:106CB0001092D4031092D303A0902404B090250422
:106CC000C501B7FE04C0882799278A199B094097F8
:106CD000ACF08091690784FD11C081E08093BC0411
:106CE0008091DD079091DE0790933B0480933A04F6
:106CF0008AEF90E09093890380938803D090720785
:106D0000ED2CFF2400271127B501882777FD8095FA
:106D1000982F9501B7FE04C0222733272A193B0973
:106D2000442737FD4095542F0E9419439B01AC0125
:106D3000C801B7010E94194397FF04C061507E4FFC
:106D40008F4F9F4F59E095958795779567955A9501
:106D5000D1F79B018D2D99278A9DD0018B9DB00D78
:106D60009A9DB00D1124CD01B7FD03969595879599
:106D700095958795280F391F442737FD4095542F47
:106D80002093A0043093A1044093A2045093A30441
:106D90008091460490914704A0914804B091490421
:106DA000821B930BA40BB50B80934604909347046E
:106DB000A0934804B09349048155934CA040B0403F
:106DC00064F080E593ECA0E0B0E0809346049093FB
:106DD0004704A0934804B0934904809146049091DD
:106DE0004704A0914804B0914904805B9C43AF4F95
:106DF000BF4F64F480EB9CE3AFEFBFEF809346049A
:106E000090934704A0934804B093490480913C04B4
:106E100090913D04892B09F465C18091690783FF36
:106E200061C18091760490917704A0917804B0912B
:106E30007904B7FF04C081509E4FAF4FBF4F29E088
:106E4000B595A795979587952A95D1F74C0197FF0A
:106E500004C0909481949108939480916E049091D1
:106E60006F04A0917004B0917104B7FF04C0815009
:106E70009E4FAF4FBF4F09E0B595A7959795879562
:106E80000A95D1F7BC0197FF03C0709561957F4FBC
:106E9000861697060CF44B01B40197FE02C0695F99
:106EA0007F4F3B0113E0759467941A95E1F70894BE
:106EB000611C711C09E18016910434F58091BC04B9
:106EC000882311F18091880390918903892BE1F443
:106ED00088EC90E09093CA038093C9038091DD070A
:106EE0009091DE07A091DF07B091E007BC01CD01D2
:106EF0002EE036E040E050E00E948D4330933B04AA
:106F000020933A041092BC0480913C0490913D047B
:106F1000845E9D4F7C010027F7FC0095102FA09008
:106F2000DD07B090DE07C090DF07D090E007C60114
:106F3000B5012EE036E040E050E00E948D43E21AB9
:106F4000F30A040B150BC801B70128E631E040E055
:106F500050E00E948D43DC01CB01FC01E45BF0407A
:106F6000CF01B3E0880F991FBA95E1F7B3010E94F2
:106F700058439B01442737FD4095542F2A0D3B1D54
:106F80004C1D5D1D2093DD073093DE074093DF0726
:106F90005093E00710917703612F7727869EC001F9
:106FA000879E900D969E900D112497FDCF964C01D3
:106FB000A6E095948794AA95E1F7681979094B01A1
:106FC000161617060CF088C08091880390918903EB
:106FD000009709F07FC080913304909134048E0FA4
:106FE0009F1F9093340480933304E0900104F09049
:106FF00002048091FF0390910004E80EF91EF7FE51
:1070000004C087E090E0E80EF91E63E0F594E79491
:107010006A95E1F7A0E4B0E0EA0EFB1ECA01B901EF
:107020002EE036E040E050E00E948D43DA01C901D5
:1070300020913A0430913B04442737FD4095542F6A
:10704000821B930BA40BB50B845E9D4FAF4FBF4FBC
:10705000BC01CD0128E631E040E050E00E948D43C4
:10706000DC01CB01845B9040889DF001899DF00D8F
:10707000989DF00D1124CF01B7010E94584383E081
:10708000189F400111248616970614F4B40108C015
:107090008827992788199909681779070CF4BC0182
:1070A0009B01442737FD4095542F809146049091D1
:1070B0004704A0914804B0914904820F931FA41F74
:1070C000B51F8093460490934704A0934804B0935F
:1070D000490408C0019702C08AEF90E090938903A9
:1070E000809388038091BB0481508093BB048F3FC1
:1070F00009F0B8C088E18093BB0480917507E82E41
:10710000FF24002711278091760490917704A091A5
:107110007804B0917904BC01CD01A80197010E94C7
:107120008D433093DA062093D90680916E049091B6
:107130006F04A0917004B0917104BC01CD01A8014D
:1071400097010E948D433093DC062093DB068091EB
:10715000D1079091D2079093DE068093DD0680914F
:10716000E1079091E2079093E0068093DF0680911B
:10717000D4079091D5079093E2068093E106809121
:107180001F04909120049093E4068093E30680917D
:107190003E0490913F04A0914004B0914104B7FF98
:1071A00004C081509E4FAF4FBF4F39E0B595A795B2
:1071B000979587953A95D1F79093E6068093E506E3
:1071C00080913C0490913D049093EA068093E906F7
:1071D00080911003909111039093EC068093EB063D
:1071E0008091DD079091DE07A091DF07B091E00765
:1071F000BC01CD012EE036E040E050E00E948D431E
:107200003093F0062093EF0680912A0499279093FB
:10721000EE068093ED068091BA079091BB0790939C
:10722000FA068093F9068091320699279093000719
:107230008093FF068091C6039091C7039093020745
:10724000809301078091ED049091EE0490931607CE
:10725000809315078091EB049091EC0490931807AC
:107260008093170780911804A090D807B090D90791
:10727000C090DA07D090DB078823A9F08091B3078C
:107280009091B407AA2797FDA095BA2FBC01CD0114
:107290000E945742DC01CB01A6019501BC01CD0142
:1072A0000E94D1423AC08091760490917704A091D7
:1072B0007804B0917904BC01CD010E9457427B0152
:1072C0008C018091C8079091C907A091CA07B0911D
:1072D000CB079C01AD01C801B7010E94D1427B01DF
:1072E0008C018091B3079091B407AA2797FDA095D0
:1072F000BA2FBC01CD010E945742DC01CB01A6018F
:107300009501BC01CD010E94D142DC01CB019C0161
:10731000AD01C801B7010E94B241DC01CB01BC0143
:10732000CD010E943A42DC01CB019093B4078093D7
:10733000B30780911704A090D807B090D907C090E8
:10734000DA07D090DB078823A9F08091A9079091F4
:10735000AA07AA2797FDA095BA2FBC01CD010E94CC
:107360005742DC01CB01A6019501BC01CD010E9471
:10737000D1423AC080916E0490916F04A091700444
:10738000B0917104BC01CD010E9457427B018C0178
:107390008091C8079091C907A091CA07B091CB0707
:1073A0009C01AD01C801B7010E94D1427B018C0153
:1073B0008091A9079091AA07AA2797FDA095BA2FB7
:1073C000BC01CD010E945742DC01CB01A601950111
:1073D000BC01CD010E94D142DC01CB019C01AD0179
:1073E000C801B7010E94B241DC01CB01BC01CD0153
:1073F0000E943A42DC01CB019093AA078093A9072F
:107400008091D4079091D507AA2797FDA095BA2F10
:10741000BC01CD010E9457427B018C018091D807AD
:107420009091D907A091DA07B091DB079C01AD01DB
:10743000BC01CD010E94B241DC01CB019C01AD0138
:10744000C801B7010E94D1427B018C0180915A048E
:1074500090915B04A0915C04B0915D04BC01CD01EE
:107460000E945742DC01CB014090C8075090C907E9
:107470006090CA077090CB07A3019201BC01CD01B7
:107480000E94D142DC01CB0120E030E040E05FE32C
:10749000BC01CD010E94D142DC01CB019C01AD01B8
:1074A000C801B7010E94B241DC01CB01BC01CD0192
:1074B0000E943A42DC01CB019093D5078093D40718
:1074C0008091B3079091B4079093040780930307CA
:1074D0008091A9079091AA079093060780930507CA
:1074E0008091B3079091B4078150904434F080E0CC
:1074F00090E49093B4078093B3078091B307909181
:10750000B4078050904C34F480E090EC9093B40732
:107510008093B3078091A9079091AA078150904466
:1075200034F080E090E49093AA078093A9078091BB
:10753000A9079091AA078050904C34F480E090EC19
:107540009093AA078093A9078091D4079091D507BB
:107550008150904434F080E090E49093D50780937C
:10756000D4078091D4079091D5078050904C34F483
:1075700080E090EC9093D5078093D40789819A811D
:10758000880F991F880F991F9A83898380916907B3
:10759000992780FFF0C020917A0381FF0EC022332B
:1075A00010F580911F0490912004449790931E043D
:1075B00080931D041092360419C080916E0390913F
:1075C0006F03820F911D20916E073327829FD00198
:1075D000839FB00D929FB00D1124CD0144979093DD
:1075E0001E0480931D0481E080933604BB81BB237D
:1075F00021F010921E0410921D0400911F0410919E
:10760000200420911D0430911E04201731070CF036
:10761000B2C080913604882309F4ADC0021B130B5D
:10762000809179039927089FF001099FF00D189F19
:10763000F00D1124CF01F7FD03968C0115950795E8
:1076400015950795E980FA80E01AF10A8701809183
:10765000D5039091D60397FD019695958795081BC4
:10766000190BC0903E04D0903F04E0904004F0908D
:107670004104F7FE08C02FE730E040E050E0C20EC2
:10768000D31EE41EF51EA7E0F594E794D794C794A3
:10769000AA95D1F780917803282F332744275527BF
:1076A000C701B6010E94194397FF04C0615E7F4F76
:1076B0008F4F9F4FF5E09595879577956795FA954C
:1076C000D1F731E0693173071CF068E171E006C061
:1076D0004EEF683E740714F468EE7EEF061B170B3E
:1076E0008091B9049091BA049C01E4E0220F331F09
:1076F000EA95E1F7281B390B200F311F37FF02C035
:10770000215F3F4F74E0359527957A95E1F73093E7
:10771000BA042093B90480916A07482F5527440F73
:10772000551F440F551F2417350794F489819A81FA
:107730008417950724F05093BA044093B904A981A3
:10774000BA81A417B50724F4B093BA04A093B9047E
:107750008091B9049091BA04E981FA81E817F90798
:1077600024F4F093BA04E093B904E090B904F090E3
:10777000BA04FA82E9823090D307832D9927880FC3
:10778000991F880F991F8055904009811A81801791
:10779000910714F49A83898329813A813093E8060A
:1077A0002093E7068091A0049091A104A091A204E7
:1077B000B091A30442E0880F991FAA1FBB1F4A95EE
:1077C000D1F78090D4079090D507881A990A213A6A
:1077D00031058CF0C90137FD01969595879588157F
:1077E00099050CF44C01909581959F4F8816990648
:1077F00094F44C0110C031E5831691041CF010E59F
:10780000812E912C40EB84164FEF940624F4B0EBBC
:107810008B2EBFEF9B2E232D3327220F331F220FDA
:10782000331FC901A981BA818A1B9B0B8815990551
:107830000CF44C01E981FA81E21BF30B8E169F06D2
:107840000CF44F018091B3079091B407E0902804A5
:10785000F0902904FD8AEC8A8E199F099093BD0748
:107860008093BC0720E030E040E050E0C301B2016B
:107870000E946142209198043091990440919A04A9
:1078800050919B04882309F448C0CA01B9010E94A1
:1078900057425B016C018091760490917704A0912E
:1078A0007804B0917904BC01CD010E945742DC01FB
:1078B000CB01A3019201BC01CD010E94D1427B0109
:1078C0008C012C893D89C901AA2797FDA095BA2F63
:1078D000BC01CD010E945742DC01CB019C01AD01EE
:1078E000C801B7010E94B141DC01CB019C01AD018F
:1078F000C601B5010E94B241DC01CB01BC01CD0142
:107900000E943A42DC01CB01809398049093990441
:10791000A0939A04B0939B0414C08091BC079091EB
:10792000BD07AA2797FDA095BA2F280F391F4A1F18
:107930005B1F209398043093990440939A045093CA
:107940009B048091980490919904A0919A04B0911D
:107950009B0481509A4FA040B04064F080E09AEFC1
:10796000A0E0B0E08093980490939904A0939A04C7
:10797000B0939B048091980490919904A0919A04EB
:10798000B0919B0480509640AF4FBF4F64F480E0AD
:1079900096E0AFEFBFEF8093980490939904A09383
:1079A0009A04B0939B048091BC079091BD07AA27CD
:1079B00097FDA095BA2FBC01CD010E9457427B01D3
:1079C0008C018091980490919904A0919A04B091AF
:1079D0009B04BC01CD010E945742DC01CB012091E8
:1079E0007C0330917D0340917E0350917F03288B6F
:1079F000398B4A8B5B8B9C01AD01688979898A89B7
:107A00009B890E94D142DC01CB019C01AD01C801E0
:107A1000B7010E94B241DC01CB01BC01CD010E9443
:107A20003A42DC01CB018C0120907003622D772754
:107A300088279927940197FE04C022273327281905
:107A4000390937FF02C02F5F3F4F35952795498190
:107A50005A81240F351F442737FD4095542F0E942B
:107A6000194397FF04C0615C7F4F8F4F9F4FE6E043
:107A70009595879577956795EA95D1F79B0160175E
:107A800071070CF48B01309521953F4F02171307B6
:107A90000CF4890129813A81200F311F280D391DED
:107AA000C90137FD03969C01359527953595279596
:107AB00037FF03C020E030E006C0832D99278217EE
:107AC00093070CF49C013090B507832D9927281754
:107AD00039070CF49C012093AB0729813A81201BC4
:107AE000310B280D391DC90137FD03969C013595D1
:107AF00027953595279537FF03C020E030E007C074
:107B00008091D3079927821793070CF49C01832D4A
:107B10009927281739070CF49C012093B20780910C
:107B2000A9079091AA07A0912604B0912704BD8BC4
:107B3000AC8B8A1B9B0B9093A8078093A70720E030
:107B400030E040E050E0C301B2010E946142209168
:107B50009C0430919D0440919E0450919F04882381
:107B600009F448C0CA01B9010E9457425B016C0187
:107B700080916E0490916F04A0917004B091710493
:107B8000BC01CD010E945742DC01CB01A30192014F
:107B9000BC01CD010E94D1427B018C01EC89FD89A1
:107BA000CF01AA2797FDA095BA2FBC01CD010E9455
:107BB0005742DC01CB019C01AD01C801B7010E9415
:107BC000B141DC01CB019C01AD01C601B5010E94B0
:107BD000B241DC01CB01BC01CD010E943A42DC0183
:107BE000CB0180939C0490939D04A0939E04B0933A
:107BF0009F0414C08091A7079091A807AA2797FD1A
:107C0000A095BA2F280F391F4A1F5B1F20939C0491
:107C100030939D0440939E0450939F0480919C0454
:107C200090919D04A0919E04B0919F0481589E4321
:107C3000A040B04064F080E89EE3A0E0B0E0809314
:107C40009C0490939D04A0939E04B0939F04809104
:107C50009C0490919D04A0919E04B0919F04805833
:107C6000914CAF4FBF4F64F480E891ECAFEFBFEFA2
:107C700080939C0490939D04A0939E04B0939F04D2
:107C80008091A7079091A807AA2797FDA095BA2FE2
:107C9000BC01CD010E9457427B018C0180919C0464
:107CA00090919D04A0919E04B0919F04BC01CD01D0
:107CB0000E945742DC01CB019C01AD0168897989A2
:107CC0008A899B890E94D142DC01CB019C01AD01D4
:107CD000C801B7010E94B241DC01CB01BC01CD015A
:107CE0000E943A42DC01CB018C01622D7727882764
:107CF0009927940197FE04C02227332728193909B0
:107D000037FF02C02F5F3F4F3595279549815A8134
:107D1000240F351F442737FD4095542F0E941943E7
:107D200097FF04C0615C7F4F8F4F9F4F26E0959572
:107D30008795779567952A95D1F79B01601771070D
:107D40000CF48B01309521953F4F021713070CF46B
:107D5000890129813A81200F311F28193909C90168
:107D600037FD03969C01359527953595279537FF67
:107D700003C020E030E007C08091D3079927821725
:107D800093070CF49C01832D9927281739070CF4CD
:107D90009C012093CE0729813A81201B310B2819A1
:107DA0003909C90137FD03969C013595279535950D
:107DB000279537FF03C020E030E007C08091D3074C
:107DC0009927821793070CF49C01832D9927281774
:107DD00039070CF49C012093CC0765960FB6F894F4
:107DE000DEBF0FBECDBFDF91CF911F910F91FF90EE
:107DF000EF90DF90CF90BF90AF909F908F907F904B
:107E00006F905F904F903F902F9008958091E30482
:107E10009091E404A091E504B091E6048093DB0422
:107E20009093DC04A093DD04B093DE048091DF0422
:107E30009091E004A091E104B091E2048093D70412
:107E40009093D804A093D904B093DA0408951092C3
:107E5000EE041092ED041092EC041092EB040895DD
:107E600084B1806A84B93D9A82E58CBD1DBC459A77
:107E700081E08093E3078AEA8093E70783E88093B1
:107E8000E8078AE08093E9071092EB071092EA076F
:107E90001092ED071092EC07109209080895F894DB
:107EA0008091760490917704A0917804B091790440
:107EB000BC01CD012CE630E040E050E00E948D4353
:107EC0003093EB072093EA0780916E0490916F0442
:107ED000A0917004B0917104BC01CD012CE630E09A
:107EE00040E050E00E948D433093ED072093EC0773
:107EF0008091DD079091DE07A091DF07B091E00748
:107F0000BC01CD012EE036E040E050E00E948D4300
:107F10003093F3072093F207E0918004F0918104FD
:107F20008091C2079091C307BF010E9458432CE083
:107F300030E0629FA001639F500D729F500D11248D
:107F40005093EF074093EE078091D6079091D707A3
:107F5000BF010E945843629FA001639F500D729F12
:107F6000500D11245093F1074093F00710928104B3
:107F7000109280041092C3071092C2071092D70784
:107F80001092D6078091E90799278A30910561F010
:107F90008A3091050CF4A7C08B30910511F182173E
:107FA000930709F497C09FC0809112048093FA0749
:107FB000809111048093FB07809110048093FC074B
:107FC00080910F048093FD0780910E048093FE073B
:107FD00080910D048093FF0780910C04809300082A
:107FE00082C080916307E82FFF27EE0FFF1FEB5C35
:107FF000F84F0190F081E02DE038F1051CF0EFE73B
:10800000F0E006C05FEFE138F50714F4E1E8FFEFB8
:10801000E093FA0780916407E82FFF27EE0FFF1F18
:10802000EB5CF84F0190F081E02DE038F1051CF099
:10803000EFE7F0E006C06FEFE138F60714F4E1E88F
:10804000FFEFE093FB0780916207E82FFF27EE0F19
:10805000FF1FEB5CF84F0190F081E02DE038F10557
:108060001CF0EFE7F0E006C08FEFE138F80714F4FA
:10807000E1E8FFEFE093FC0780916107E82FFF271D
:10808000EE0FFF1FEB5CF84F0190F081E02DE03820
:10809000F1051CF0EFE7F0E006C02FEFE138F20742
:1080A00014F4E1E8FFEFE093FD0780913104809341
:1080B000FE0780912F048093FF0780912D04809309
:1080C000000880912B048093010880912A048093FA
:1080D000020809C080913206863018F010923206EC
:1080E00085E08093FA07789480910908882309F441
:1080F00056C040910B0850910C08CA0181509E4F08
:108100008F5F9340B0F420910D0830910E08C901A3
:1081100081509E4F8F5F934060F48091690785FF87
:1081200008C05093EE044093ED043093EC04209388
:10813000EB04809111089091120821E08936920792
:1081400024F490933D0480933C0480913C049091EE
:108150003D0420913A0430913B04821B930B845ED2
:108160009D4F68E671E00E945843845B9040909375
:1081700039048093380480911508282F3327809183
:10818000C9039091CA038217930788F4809132063D
:10819000882369F43093CA032093C9030895109289
:1081A000EE041092ED041092EC041092EB0408958A
:1081B0008091E307882309F43BC0459887EE97E058
:1081C0009093E5078093E4079091EF04E92FFF2750
:1081D000EB55FC4F9F5F9093EF0480818093E907FC
:1081E000953010F01092EF041092E3070E944F3F79
:1081F00081E08093E607000000000000000000001E
:10820000000000000000000000000000000000006E
:10821000000000000000000000000000000000005E
:108220000000000000008091E707809306088EBDE3
:1082300008953091E307332309F085C00DB407FE9C
:1082400082C084E08093C803459A2EB58091F104E2
:1082500099278130910589F0823091051CF4892B92
:1082600021F03EC00297B9F03BC03093080820933C
:10827000F2042138A9F581E008C0253549F4809140
:10828000F204820F8093F20482E08093F10428C00C
:108290003093F10425C080910808E82FFF27ED5D99
:1082A000F74F20838F5F809308089091F204893103
:1082B000A0F0291769F4AAE0B8E0E3E2F8E089E168
:1082C00001900D928150E1F781E08093090802C08E
:1082D000309309081092F10403C0920F9093F204B6
:1082E0002091E607203208F028C0459800000000E1
:1082F000000000000000000000000000000000007E
:10830000000000000000000000000000000000006D
:10831000000000000000000000000000E091E40701
:10832000F091E507E20FF11D80818EBD8091060876
:108330009081890F8093060803C081E08093E30752
:108340002F5F2093E6070895FC014150504030F024
:1083500001900616D1F73197CF0108958827992704
:1083600008955058192EEFD001D0D2C0BA17620725
:10837000730784079507B1F188F40EF410940B2E5F
:10838000BA2FA02D062E622F202D072E732F302DF1
:10839000082E842F402D092E952F502DFF27552371
:1083A000B9F0591B49F0573E98F0469537952795F7
:1083B000A795F0405395C9F776F0BA0F621F731F67
:1083C000841F30F4879577956795B795F04093951E
:1083D00017FA0F2E0895BF1BBB27BA0B620B730B46
:1083E000840BF6CFDEF6DBC0AED001D091C05523B2
:1083F00059F0992369F09F575F57951B33F442F466
:10840000903811F4915805C09BC091589F3F09F4D2
:10841000C6C0BB27112462177307840730F4660FA8
:10842000771F881FBB1F915098F311D00F920FD068
:108430000F920DD0A0E82617370748071B0609F052
:10844000A048BA2F602D7F918F9100240895A0E855
:108450000024621773078407B10528F0621B730BB1
:10846000840BB1090A2A660F771F881FBB1FA695C8
:1084700081F7089597FB73D09F3738F0FEE9F91B19
:10848000982F872F762F6B2F05C086C096958795DE
:1084900077956795F150D0F73EF49095809570955B
:1084A00061957F4F8F4F9F4F0895E89403C097FBCE
:1084B0000EF4F3DFB62F672F782F892F9EE9002463
:1084C00027C00ED05EF004C00BD026F001C008D04B
:1084D00019F020F48FEF089580E0089581E0089569
:1084E00097FB092E052600F8689430D0E89407FC25
:1084F00007C0621773078407950721F008F40094FA
:108500000794989408959A95BB0F661F771F881F4C
:1085100011249923A1F08823B2F79F3F59F0BB0F94
:1085200048F421F4002011F460FF04C06F5F7F4F16
:108530008F4F9F4F881F9795879597F908952CC067
:108540009FEF80EC0895052E092607FA440F551F6A
:108550005F3F79F0AA27A51708F051E04795880FEB
:10856000991F9F3F31F0BB27B91708F091E087951D
:1085700008959F919F911124E3CF97FB880F991F36
:108580009F3F31F0BB27B91708F091E08795089518
:108590009F919F911124D4CF662777278827992709
:1085A0000895D1DF01D0B4CF992339F0552329F0B4
:1085B0009F575F57950F13F49AF1F1CF91589F3F52
:1085C000E1F3629FA12D0F92BB27639FA00DB11D08
:1085D000EE27729FA00DB11DEE1FAF93AA27649FD7
:1085E000B00DE11D739FB00DE11DAA1F6627829F8C
:1085F000B00DE11DA61F5527749FE00DA11D551F4D
:10860000839FE00DA11D561F849FA00D511D852F36
:108610007A2F6E2F1F900F9088231AF4939539F4B8
:108620008FCF000C111CBB1F661F771F881F0128EE
:108630000895629FD001739FF001829FE00DF11DAC
:10864000649FE00DF11D929FF00D839FF00D749FCC
:10865000F00D659FF00D9927729FB00DE11DF91F78
:10866000639FB00DE11DF91FBD01CF0111240895D5
:10867000991B79E004C0991F961708F0961B881F74
:108680007A95C9F780950895AA1BBB1B51E107C0D5
:10869000AA1FBB1FA617B70710F0A61BB70B881F92
:1086A000991F5A95A9F780959095BC01CD01089521
:1086B00097FB092E07260AD077FD04D0E5DF06D008
:1086C00000201AF4709561957F4F0895F6F7909504
:1086D00081959F4F0895A1E21A2EAA1BBB1BFD0195
:1086E0000DC0AA1FBB1FEE1FFF1FA217B307E40791
:1086F000F50720F0A21BB30BE40BF50B661F771FE9
:10870000881F991F1A9469F76095709580959095C8
:108710009B01AC01BD01CF01089597FB092E0526F1
:108720000ED057FD04D0D7DF0AD0001C38F4509586
:108730004095309521953F4F4F4F5F4F0895F6F785
:1087400090958095709561957F4F8F4F9F4F0895BD
:10875000F999FECFB2BDA1BDF89A119600B4089563
:10876000F999FECFB2BDA1BD00BC11960FB6F89429
:08877000FA9AF99A0FBE089570
:10877800010A01496E74656772616C4E69636B200A
:10878800202020496E74656772616C526F6C6C2092
:108798002020204163634E69636B20202020202025
:1087A800202020416363526F6C6C20202020202001
:1087B8002020204779726F47696572202020202089
:1087C800202020486F6568656E57657274202020E8
:1087D8002020204163635A202020202020202020B0
:1087E80020202047617320202020202020202020C6
:1087F8002020204B6F6D7061737356616C75652016
:108808002020205370616E6E756E67202020202016
:10881800202020456D7066616E6720202020202072
:1088280020202045727361747A6B6F6D7061737369
:108838002020204D6F746F725F566F726E65202016
:108848002020204D6F746F725F48696E74656E20CA
:108858002020204D6F746F725F4C696E6B732020FF
:108868002020204D6F746F725F52656368747320A7
:108878002020204163635F5A2020202020202020D0
:1088880020202044697374616E63652020202020B5
:108898002020204F73644261722020202020202055
:1088A8002020204D4B334D61672043616C53746128
:1088B800746520536572766F2020202020202020A8
:1088C8002020204E69636B2020202020202020209B
:1088D800202020526F6C6C20202020202020202077
:1088E8002020202020202020202020202020202080
:1088F8002020202020202020202020202020202070
:10890800202020202020202020202020202020205F
:10891800202020202020202020202020202020204F
:10892800202020202020202020202020202020203F
:10893800202020202020202020202020202020202F
:10894800202020202020202020202020202020201F
:108958002020204750535F4E69636B202020202041
:108968002020204750535F526F6C6C20202020201D
:1089780020202064FF01FFFF010AFF03007D0000A3
:10898800640048616C6C6F2057656C7400000000CF
:1089980000000000000000000000000000000000CF
:1089A80000000000000000000000000000000000BF
:1089B80000000000000000000000000000000000AF
:1089C800000000000000000000000000000000009F
:1089D80000000102030405060708090A0B01ECFF61
:1089E8006446640A029696403A10FB3017B7D138AD
:1089F80090D0030090D00300F401640053706F72AC
:108A08007400004E6F726D616C0000426567696E9C
:0A8A18006E657200000A0B0A0B0CD9
:00000001FF
/branches/V0.69k Code Redesign killagreg/Hex-Files/WasIstWas.txt
6,20 → 6,10
Der Bootloader nur dann eingespielt werden, wenn noch nie ein Bootloader eingespielt wurde!
Danach können Softwareupdates seriell eingespielt werden.
 
Aktuelle Firmware
Wird per serielle Schnittstelle (durch den Bootloader) eingespielt
Flight-Ctrl SW >= 0.69 benötigt das Kopter-Tool 1.50
Flight-Ctrl_MEGA644_Vx_yy.hex
Aktuelle Firmware
Wird per serielle Schnittstelle (durch den Bootloader) eingespielt
 
Flight-Ctrl_MEGA644_KILLAGREG_V0_69k.hex für Atmega644 mit Extension Board für MM3 und Conrad-GPS
Flight-Ctrl_MEGA644_NAVICTRL_V0_69k.hex für Atmega644 mit NaviCtrl
Flight-Ctrl_MEGA644_V0_69k.hex für Atmega655 mit Support für den CMPS03/MK3MAG an der FC
 
Flight-Ctrl_MEGA644p_KILLAGREG_V0_69k.hex für Atmega644 mit Extension Board für MM3 und Conrad-GPS
Flight-Ctrl_MEGA644p_NAVICTRL_V0_69k.hex für Atmega644 mit NaviCtrl
Flight-Ctrl_MEGA644p_V0_69k.hex für Atmega655 mit Support für den CMPS03/MK3MAG an der FC
 
Die Firmware läuft sowohl auf der FC 1.0 als auch auf der FC 1.1/1.2
 
 
Flight-Ctrl SW > 0.62 benötigt das Kopter-Tool >1.47
/branches/V0.69k Code Redesign killagreg/Kopter-Tool/MikroKopter-Tool.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/branches/V0.69k Code Redesign killagreg/Settings.h
--- V0.69k Code Redesign killagreg/_Settings.h (revision 886)
+++ V0.69k Code Redesign killagreg/_Settings.h (revision 885)
@@ -2,12 +2,14 @@
// Testmodi
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define MOTOR_OFF 0
+#define MOTOR_TEST 0
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Abstimmung
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define ACC_AMPLIFY 12
-#define FACTOR_I 0.0001
+#define FAKTOR_P 1
+#define FAKTOR_I 0.0001
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -16,7 +18,17 @@
#define SIO_DEBUG 1 // Soll der Debugger aktiviert sein?
#define MIN_DEBUG_INTERVALL 250 // in diesem Intervall werden Degugdaten ohne Aufforderung gesendet
-
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Sender
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ #define K_NICK 0
+ #define K_ROLL 1
+ #define K_GAS 2
+ #define K_GIER 3
+ #define K_POTI1 4
+ #define K_POTI2 5
+ #define K_POTI3 6
+ #define K_POTI4 7
// +++++++++++++++++++++++++++++++
// + Getestete Settings:
// +++++++++++++++++++++++++++++++
/branches/V0.69k Code Redesign killagreg/analog.c
4,200 → 4,152
// + www.MikroKopter.com
// + see the File "License.txt" for further Informations
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 
#include "analog.h"
#include "main.h"
#include "timer0.h"
#include "fc.h"
#include "printf_P.h"
#include "eeprom.h"
 
volatile int16_t Current_AccZ = 0;
volatile int16_t UBat = 100;
volatile int16_t AdValueGyrPitch = 0, AdValueGyrRoll = 0, AdValueGyrYaw = 0;
volatile int16_t AdValueAccRoll = 0, AdValueAccPitch = 0, AdValueAccTop = 0;
volatile int32_t AirPressure = 32000;
volatile int16_t StartAirPressure;
volatile uint16_t ReadingAirPressure = 1023;
uint8_t PressureSensorOffset;
volatile int16_t HeightD = 0;
volatile uint16_t MeasurementCounter = 0;
volatile int Aktuell_Nick,Aktuell_Roll,Aktuell_Gier,Aktuell_ax, Aktuell_ay,Aktuell_az, UBat = 100;
volatile int AdWertNick = 0, AdWertRoll = 0, AdWertGier = 0;
volatile int AdWertAccRoll = 0,AdWertAccNick = 0,AdWertAccHoch = 0;
volatile char MessanzahlNick = 0, MessanzahlRoll = 0, MessanzahlGier = 0;
volatile char messanzahl_AccNick = 0, messanzahl_AccRoll = 0, messanzahl_AccHoch = 0;
volatile long Luftdruck = 32000;
volatile int StartLuftdruck;
volatile unsigned int MessLuftdruck = 1023;
unsigned char DruckOffsetSetting;
volatile int HoeheD = 0;
volatile char messanzahl_Druck;
volatile int tmpLuftdruck;
volatile unsigned int ZaehlMessungen = 0;
 
/*****************************************************/
/* Initialize Analog Digital Converter */
/*****************************************************/
//#######################################################################################
//
void ADC_Init(void)
{
uint8_t sreg = SREG;
// disable all interrupts before reconfiguration
cli();
//ADC0 ... ADC7 is connected to PortA pin 0 ... 7
DDRA = 0x00;
PORTA = 0x00;
// Digital Input Disable Register 0
// Disable digital input buffer for analog adc_channel pins
DIDR0 = 0xFF;
// external reference, adjust data to the right
ADMUX &= ~((1 << REFS1)|(1 << REFS0)|(1 << ADLAR));
// set muxer to ADC adc_channel 0 (0 to 7 is a valid choice)
ADMUX = (ADMUX & 0xE0) | 0x00;
//Set ADC Control and Status Register A
//Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz
ADCSRA = (1<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//Set ADC Control and Status Register B
//Trigger Source to Free Running Mode
ADCSRB &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0));
// Enable AD conversion
ADC_Enable();
// restore global interrupt flags
SREG = sreg;
//#######################################################################################
{
ADMUX = 0;//Referenz ist extern
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE);
//Free Running Mode, Division Factor 128, Interrupt on
}
 
void SearchAirPressureOffset(void)
void SucheLuftruckOffset(void)
{
uint8_t off;
off = GetParamByte(PID_PRESSURE_OFFSET);
if(off > 20) off -= 10;
OCR0A = off;
Delay_ms_Mess(100);
if(ReadingAirPressure < 850) off = 0;
for(; off < 250;off++)
{
OCR0A = off;
Delay_ms_Mess(50);
printf(".");
if(ReadingAirPressure < 900) break;
}
SetParamByte(PID_PRESSURE_OFFSET, off);
PressureSensorOffset = off;
Delay_ms_Mess(300);
unsigned int off;
off = eeprom_read_byte(&EEPromArray[EEPROM_ADR_LAST_OFFSET]);
if(off > 20) off -= 10;
OCR0A = off;
Delay_ms_Mess(100);
if(MessLuftdruck < 850) off = 0;
for(; off < 250;off++)
{
OCR0A = off;
Delay_ms_Mess(50);
printf(".");
if(MessLuftdruck < 900) break;
}
eeprom_write_byte(&EEPromArray[EEPROM_ADR_LAST_OFFSET], off);
DruckOffsetSetting = off;
Delay_ms_Mess(300);
}
 
 
/*****************************************************/
/* Interrupt Service Routine for ADC */
/*****************************************************/
// runs at 156.25 kHz or 6.4 µs
// if after (70.4µs) all 11 states are processed the interrupt is disabled
// and the update of further ads is stopped
// The routine changes the ADC input muxer running
// thru the state machine by the following order.
// state 0: ch0 (yaw gyro)
// state 1: ch1 (roll gyro)
// state 2: ch2 (pitch gyro)
// state 3: ch4 (battery voltage -> UBat)
// state 4: ch6 (acc y -> Current_AccY)
// state 5: ch7 (acc x -> Current_AccX)
// state 6: ch0 (yaw gyro average with first reading -> AdValueGyrYaw)
// state 7: ch1 (roll gyro average with first reading -> AdValueGyrRoll)
// state 8: ch2 (pitch gyro average with first reading -> AdValueGyrPitch)
// state 9: ch5 (acc z add also 4th part of acc x and acc y to reading)
// state10: ch3 (air pressure averaging over 5 single readings -> tmpAirPressure)
 
ISR(ADC_vect)
//#######################################################################################
//
SIGNAL(SIG_ADC)
//#######################################################################################
{
static uint8_t adc_channel = 0, state = 0;
static uint16_t yaw1, roll1, pitch1;
static uint8_t average_pressure = 0;
static int16_t tmpAirPressure = 0;
// disable further AD conversion
ADC_Disable();
// state machine
static unsigned char kanal=0,state = 0;
static unsigned int gier1, roll1, nick1;
ANALOG_OFF;
switch(state++)
{
case 0:
yaw1 = ADC; // get Gyro Yaw Voltage 1st sample
adc_channel = 1; // set next channel to ADC1 = ROLL GYRO
MeasurementCounter++; // increment total measurement counter
gier1 = ADC;
kanal = 1;
ZaehlMessungen++;
break;
case 1:
roll1 = ADC; // get Gyro Roll Voltage 1st sample
adc_channel = 2; // set next channel to ADC2 = PITCH GYRO
roll1 = ADC;
kanal = 2;
break;
case 2:
pitch1 = ADC; // get Gyro Pitch Voltage 1st sample
adc_channel = 4; // set next channel to ADC4 = UBAT
nick1 = ADC;
kanal = 4;
break;
case 3:
// get actual UBat (Volts*10) is ADC*30V/1024*10 = ADC/3
UBat = (3 * UBat + ADC / 3) / 4; // low pass filter updates UBat only to 1 quater with actual ADC value
adc_channel = 6; // set next channel to ADC6 = ACC_Y
UBat = (3 * UBat + ADC / 3) / 4;//(UBat + ((ADC * 39) / 256) + 19) / 2;
kanal = 6;
break;
case 4:
AdValueAccRoll = NeutralAccY - ADC; // get acceleration in Y direction
adc_channel = 7; // set next channel to ADC7 = ACC_X
Aktuell_ay = NeutralAccY - ADC;
AdWertAccRoll = Aktuell_ay;
kanal = 7;
break;
case 5:
AdValueAccPitch = ADC - NeutralAccX; // get acceleration in X direction
adc_channel = 0; // set next channel to ADC7 = YAW GYRO
Aktuell_ax = ADC - NeutralAccX;
AdWertAccNick = Aktuell_ax;
kanal = 0;
break;
case 6:
// average over two samples to create current AdValueGyrYaw
if(BoardRelease == 10) AdValueGyrYaw = (ADC + yaw1) / 2;
else AdValueGyrYaw = ADC + yaw1; // gain is 2 times lower on FC 1.1
adc_channel = 1; // set next channel to ADC7 = ROLL GYRO
if(PlatinenVersion == 10) AdWertGier = (ADC + gier1) / 2;
else AdWertGier = ADC + gier1;
kanal = 1;
break;
case 7:
// average over two samples to create current ADValueGyrRoll
if(BoardRelease == 10) AdValueGyrRoll = (ADC + roll1) / 2;
else AdValueGyrRoll = ADC + roll1; // gain is 2 times lower on FC 1.1
adc_channel = 2; // set next channel to ADC2 = PITCH GYRO
if(PlatinenVersion == 10) AdWertRoll = (ADC + roll1) / 2;
else AdWertRoll = ADC + roll1;
kanal = 2;
break;
case 8:
// average over two samples to create current ADValuePitch
if(BoardRelease == 10) AdValueGyrPitch = (ADC + pitch1) / 2;
else AdValueGyrPitch = ADC + pitch1; // gain is 2 times lower on FC 1.1
adc_channel = 5; // set next channel to ADC5 = ACC_Z
if(PlatinenVersion == 10) AdWertNick = (ADC + nick1) / 2;
else AdWertNick = ADC + nick1;
//AdWertNick = 0;
//AdWertNick += Poti2;
kanal = 5;
break;
case 9:
// get z acceleration
AdValueAccTop = (int16_t) ADC - NeutralAccZ; // get plain acceleration in Z direction
AdValueAccTop += abs(AdValueAccPitch) / 4 + abs(AdValueAccRoll) / 4;
if(AdValueAccTop > 1)
AdWertAccHoch = (signed int) ADC - NeutralAccZ;
// AdWertAccHoch += abs(Aktuell_ay) / 4 + abs(Aktuell_ax) / 4;
if(AdWertAccHoch > 1)
{
if(NeutralAccZ < 750)
{
NeutralAccZ += 0.02;
if(Model_Is_Flying < 500) NeutralAccZ += 0.1;
}
}
else if(AdValueAccTop < -1)
if(NeutralAccZ < 750)
{
NeutralAccZ += 0.02;
if(modell_fliegt < 500) NeutralAccZ += 0.1;
}
}
else if(AdWertAccHoch < -1)
{
if(NeutralAccZ > 550)
{
NeutralAccZ-= 0.02;
if(Model_Is_Flying < 500) NeutralAccZ -= 0.1;
}
}
Current_AccZ = ADC;
Reading_Integral_Top += AdValueAccTop; // Integrieren
Reading_Integral_Top -= Reading_Integral_Top / 1024; // dämfen
adc_channel = 3; // set next channel to ADC3 = air pressure
if(NeutralAccZ > 550)
{
NeutralAccZ-= 0.02;
if(modell_fliegt < 500) NeutralAccZ -= 0.1;
}
}
messanzahl_AccHoch = 1;
Aktuell_az = ADC;
Mess_Integral_Hoch += AdWertAccHoch; // Integrieren
Mess_Integral_Hoch -= Mess_Integral_Hoch / 1024; // dämfen
kanal = 3;
break;
case 10:
tmpAirPressure += ADC; // sum vadc values
if(++average_pressure >= 5) // if 5 values are summerized for averaging
{
ReadingAirPressure = ADC; // update measured air pressure
HeightD = (7 * HeightD + (int16_t)FCParam.Height_D * (int16_t)(StartAirPressure - tmpAirPressure - ReadingHeight))/8; // D-Part = CurrentValue - OldValue
AirPressure = (tmpAirPressure + 3 * AirPressure) / 4; // averaging using history
ReadingHeight = StartAirPressure - AirPressure;
average_pressure = 0; // reset air pressure measurement counter
tmpAirPressure = 0;
}
adc_channel = 0; // set next channel to ADC0 = GIER GYRO
state = 0; // reset state machine
tmpLuftdruck += ADC;
if(++messanzahl_Druck >= 5)
{
MessLuftdruck = ADC;
messanzahl_Druck = 0;
HoeheD = (7 * HoeheD + (int) Parameter_Luftdruck_D * (int)(StartLuftdruck - tmpLuftdruck - HoehenWert))/8; // D-Anteil = neuerWert - AlterWert
Luftdruck = (tmpLuftdruck + 3 * Luftdruck) / 4;
HoehenWert = StartLuftdruck - Luftdruck;
tmpLuftdruck = 0;
}
kanal = 0;
state = 0;
break;
default:
adc_channel = 0;
default:
kanal = 0;
state = 0;
break;
}
// set adc muxer to next adc_channel
ADMUX = (ADMUX & 0xE0) | adc_channel;
// after full cycle stop further interrupts
if(state != 0) ADC_Enable();
}
ADMUX = kanal;
if(state != 0) ANALOG_ON;
}
/branches/V0.69k Code Redesign killagreg/analog.h
1,29 → 1,24
#ifndef _ANALOG_H
#define _ANALOG_H
/*#######################################################################################
 
#include <inttypes.h>
#######################################################################################*/
 
extern volatile int16_t UBat;
extern volatile int16_t AdValueGyrPitch, AdValueGyrRoll, AdValueGyrYaw;
extern volatile int16_t AdValueAccRoll, AdValueAccPitch, AdValueAccTop;
extern volatile int16_t Current_AccZ;
extern volatile int32_t AirPressure;
extern volatile uint16_t MeasurementCounter;
extern uint8_t PressureSensorOffset;
extern volatile int16_t HeightD;
extern volatile uint16_t ReadingAirPressure;
extern volatile int16_t StartAirPressure;
extern volatile int UBat;
extern volatile int AdWertNick, AdWertRoll, AdWertGier;
extern volatile int AdWertAccRoll,AdWertAccNick,AdWertAccHoch;
extern volatile int Aktuell_Nick,Aktuell_Roll,Aktuell_Gier,Aktuell_ax, Aktuell_ay,Aktuell_az;
extern volatile long Luftdruck;
extern volatile char messanzahl_Druck;
extern volatile unsigned int ZaehlMessungen;
extern unsigned char DruckOffsetSetting;
extern volatile int HoeheD;
extern volatile unsigned int MessLuftdruck;
extern volatile int StartLuftdruck;
extern volatile char MessanzahlNick;
 
extern void SearchAirPressureOffset(void);
unsigned int ReadADC(unsigned char adc_input);
void ADC_Init(void);
void SucheLuftruckOffset(void);
 
extern void ADC_Init(void);
 
// clear ADC enable & ADC Start Conversion & ADC Interrupt Enable bit
#define ADC_Disable() (ADCSRA &= ~((1<<ADEN)|(1<<ADSC)|(1<<ADIE)))
// set ADC enable & ADC Start Conversion & ADC Interrupt Enable bit
#define ADC_Enable() (ADCSRA |= (1<<ADEN)|(1<<ADSC)|(1<<ADIE))
 
 
#endif //_ANALOG_H
 
 
#define ANALOG_OFF ADCSRA=0
#define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)
/branches/V0.69k Code Redesign killagreg/eeprom.c
1,321 → 1,182
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Konstanten
// + Konstanten
// + 0-250 -> normale Werte
// + 251 -> Poti1
// + 252 -> Poti2
// + 253 -> Poti3
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#ifndef EEMEM
#define EEMEM __attribute__ ((section (".eeprom")))
#endif
 
 
#include <avr/eeprom.h>
#include <string.h>
#include "eeprom.h"
#include "printf_P.h"
 
 
// byte array in eeprom
uint8_t EEPromArray[E2END+1] EEMEM;
 
paramset_t ParamSet;
 
 
 
/***************************************************/
/* Default Values for parameter set 1 */
/***************************************************/
void ParamSet_DefaultSet1(void) // sport
void DefaultKonstanten1(void)
{
ParamSet.ChannelAssignment[CH_PITCH] = 1;
ParamSet.ChannelAssignment[CH_ROLL] = 2;
ParamSet.ChannelAssignment[CH_THRUST] = 3;
ParamSet.ChannelAssignment[CH_YAW] = 4;
ParamSet.ChannelAssignment[CH_POTI1] = 5;
ParamSet.ChannelAssignment[CH_POTI2] = 6;
ParamSet.ChannelAssignment[CH_POTI3] = 7;
ParamSet.ChannelAssignment[CH_POTI4] = 8;
ParamSet.GlobalConfig = CFG_AXIS_COUPLING_ACTIVE | CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE;//CFG_HEIGHT_CONTROL | CFG_HEIGHT_SWITCH | CFG_COMPASS_FIX;//0x01;
ParamSet.Height_MinThrust = 30;
ParamSet.MaxHeight = 251; // Wert : 0-250 251 -> Poti1
ParamSet.Height_P = 10; // Wert : 0-32
ParamSet.Height_D = 30; // Wert : 0-250
ParamSet.Height_ACC_Effect = 30; // Wert : 0-250
ParamSet.Height_Gain = 4; // Wert : 0-50
ParamSet.Stick_P = 15; // Wert : 1-24
ParamSet.Stick_D = 30; // Wert : 0-250
ParamSet.Yaw_P = 12; // Wert : 1-20
ParamSet.Trust_Min = 8; // Wert : 0-32
ParamSet.Trust_Max = 230; // Wert : 33-250
ParamSet.GyroAccFactor = 30; // Wert : 1-64
ParamSet.CompassYawEffect = 128; // Wert : 0-250
ParamSet.Gyro_P = 80; // Wert : 0-250
ParamSet.Gyro_I = 150; // Wert : 0-250
ParamSet.LowVoltageWarning = 94; // Wert : 0-250
ParamSet.EmergencyThrust = 35; // Wert : 0-250 // Gaswert bei Empangsverlust
ParamSet.EmergencyThrustDuration = 30; // Wert : 0-250 // Zeit bis auf EmergencyThrust geschaltet wird, wg. Rx-Problemen
ParamSet.UfoArrangement = 0; // X oder + Formation
ParamSet.I_Factor = 32;
ParamSet.UserParam1 = 253; //zur freien Verwendung
ParamSet.UserParam2 = 100; //zur freien Verwendung
ParamSet.UserParam3 = 90; //zur freien Verwendung
ParamSet.UserParam4 = 90; //zur freien Verwendung
ParamSet.UserParam5 = 90; // zur freien Verwendung
ParamSet.UserParam6 = 90; // zur freien Verwendung
ParamSet.UserParam7 = 0; // zur freien Verwendung
ParamSet.UserParam8 = 0; // zur freien Verwendung
ParamSet.ServoPitchControl = 100; // Wert : 0-250 // Stellung des Servos
ParamSet.ServoPitchComp = 40; // Wert : 0-250 // Einfluss Gyro/Servo
ParamSet.ServoPitchCompInvert = 0; // Wert : 0-250 // Richtung Einfluss Gyro/Servo
ParamSet.ServoPitchMin = 50; // Wert : 0-250 // Anschlag
ParamSet.ServoPitchMax = 150; // Wert : 0-250 // Anschlag
ParamSet.ServoPitchRefresh = 5;
ParamSet.LoopThrustLimit = 50;
ParamSet.LoopThreshold = 90; // Wert: 0-250 Schwelle für Stickausschlag
ParamSet.LoopHysteresis = 50;
ParamSet.LoopConfig = 0; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt
ParamSet.Yaw_PosFeedback = 90;
ParamSet.Yaw_NegFeedback = 5;
ParamSet.AngleTurnOverPitch = 100;
ParamSet.AngleTurnOverRoll = 100;
ParamSet.GyroAccTrim = 16; // 1/k
ParamSet.DriftComp = 4;
ParamSet.DynamicStability = 100;
memcpy(ParamSet.Name, "Sport\0",6);
EE_Parameter.Kanalbelegung[K_NICK] = 1;
EE_Parameter.Kanalbelegung[K_ROLL] = 2;
EE_Parameter.Kanalbelegung[K_GAS] = 3;
EE_Parameter.Kanalbelegung[K_GIER] = 4;
EE_Parameter.Kanalbelegung[K_POTI1] = 5;
EE_Parameter.Kanalbelegung[K_POTI2] = 6;
EE_Parameter.Kanalbelegung[K_POTI3] = 7;
EE_Parameter.Kanalbelegung[K_POTI4] = 8;
EE_Parameter.GlobalConfig = CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV;///*CFG_HOEHEN_SCHALTER |*/ CFG_KOMPASS_AKTIV;//0x01;
EE_Parameter.Hoehe_MinGas = 30;
EE_Parameter.MaxHoehe = 251; // Wert : 0-250 251 -> Poti1
EE_Parameter.Hoehe_P = 10; // Wert : 0-32
EE_Parameter.Luftdruck_D = 30; // Wert : 0-250
EE_Parameter.Hoehe_ACC_Wirkung = 30; // Wert : 0-250
EE_Parameter.Hoehe_Verstaerkung = 4; // Wert : 0-50
EE_Parameter.Stick_P = 15; // Wert : 1-6
EE_Parameter.Stick_D = 30; // Wert : 0-64
EE_Parameter.Gier_P = 12; // Wert : 1-20
EE_Parameter.Gas_Min = 8; // Wert : 0-32
EE_Parameter.Gas_Max = 230; // Wert : 33-250
EE_Parameter.GyroAccFaktor = 30; // Wert : 1-64
EE_Parameter.KompassWirkung = 128; // Wert : 0-250
EE_Parameter.Gyro_P = 80; // Wert : 0-250
EE_Parameter.Gyro_I = 150; // Wert : 0-250
EE_Parameter.UnterspannungsWarnung = 94; // Wert : 0-250
EE_Parameter.NotGas = 35; // Wert : 0-250 // Gaswert bei Empangsverlust
EE_Parameter.NotGasZeit = 30; // Wert : 0-250 // Zeit bis auf NotGas geschaltet wird, wg. Rx-Problemen
EE_Parameter.UfoAusrichtung = 0; // X oder + Formation
EE_Parameter.I_Faktor = 32;
EE_Parameter.UserParam1 = 253; // zur freien Verwendung
EE_Parameter.UserParam2 = 100; // zur freien Verwendung
EE_Parameter.UserParam3 = 90; // zur freien Verwendung
EE_Parameter.UserParam4 = 90; // zur freien Verwendung
EE_Parameter.UserParam5 = 90; // zur freien Verwendung
EE_Parameter.UserParam6 = 90; // zur freien Verwendung
EE_Parameter.UserParam7 = 0; // zur freien Verwendung
EE_Parameter.UserParam8 = 0; // zur freien Verwendung
EE_Parameter.ServoNickControl = 100; // Wert : 0-250 // Stellung des Servos
EE_Parameter.ServoNickComp = 40; // Wert : 0-250 // Einfluss Gyro/Servo
EE_Parameter.ServoNickCompInvert = 0; // Wert : 0-250 // Richtung Einfluss Gyro/Servo
EE_Parameter.ServoNickMin = 50; // Wert : 0-250 // Anschlag
EE_Parameter.ServoNickMax = 150; // Wert : 0-250 // Anschlag
EE_Parameter.ServoNickRefresh = 5;
EE_Parameter.LoopGasLimit = 50;
EE_Parameter.LoopThreshold = 90; // Wert: 0-250 Schwelle für Stickausschlag
EE_Parameter.LoopHysterese = 50;
EE_Parameter.LoopConfig = 0; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt
EE_Parameter.AchsKopplung1 = 90;
EE_Parameter.AchsGegenKopplung1 = 5;
EE_Parameter.WinkelUmschlagNick = 100;
EE_Parameter.WinkelUmschlagRoll = 100;
EE_Parameter.GyroAccAbgleich = 16; // 1/k
EE_Parameter.Driftkomp = 4;
EE_Parameter.DynamicStability = 100;
memcpy(EE_Parameter.Name, "Sport\0", 12);
}
 
 
/***************************************************/
/* Default Values for parameter set 2 */
/***************************************************/
void ParamSet_DefaultSet2(void) // normal
void DefaultKonstanten2(void)
{
ParamSet.ChannelAssignment[CH_PITCH] = 1;
ParamSet.ChannelAssignment[CH_ROLL] = 2;
ParamSet.ChannelAssignment[CH_THRUST] = 3;
ParamSet.ChannelAssignment[CH_YAW] = 4;
ParamSet.ChannelAssignment[CH_POTI1] = 5;
ParamSet.ChannelAssignment[CH_POTI2] = 6;
ParamSet.ChannelAssignment[CH_POTI3] = 7;
ParamSet.ChannelAssignment[CH_POTI4] = 8;
ParamSet.GlobalConfig = CFG_AXIS_COUPLING_ACTIVE | CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE;//CFG_HEIGHT_CONTROL | CFG_HEIGHT_SWITCH | CFG_COMPASS_FIX;//0x01;
ParamSet.Height_MinThrust = 30;
ParamSet.MaxHeight = 251; // Wert : 0-250 251 -> Poti1
ParamSet.Height_P = 10; // Wert : 0-32
ParamSet.Height_D = 30; // Wert : 0-250
ParamSet.Height_ACC_Effect = 30; // Wert : 0-250
ParamSet.Height_Gain = 3; // Wert : 0-50
ParamSet.Stick_P = 12; // Wert : 1-24
ParamSet.Stick_D = 16; // Wert : 0-250
ParamSet.Yaw_P = 6; // Wert : 1-20
ParamSet.Trust_Min = 8; // Wert : 0-32
ParamSet.Trust_Max = 230; // Wert : 33-250
ParamSet.GyroAccFactor = 30; // Wert : 1-64
ParamSet.CompassYawEffect = 128; // Wert : 0-250
ParamSet.Gyro_P = 80; // Wert : 0-250
ParamSet.Gyro_I = 120; // Wert : 0-250
ParamSet.LowVoltageWarning = 94; // Wert : 0-250
ParamSet.EmergencyThrust = 35; // Wert : 0-250 // Gaswert bei Empangsverlust
ParamSet.EmergencyThrustDuration = 30; // Wert : 0-250 // Zeit bis auf EmergencyThrust geschaltet wird, wg. Rx-Problemen
ParamSet.UfoArrangement = 0; // X oder + Formation
ParamSet.I_Factor = 32;
ParamSet.UserParam1 = 253; // zur freien Verwendung
ParamSet.UserParam2 = 100; // zur freien Verwendung
ParamSet.UserParam3 = 90; // zur freien Verwendung
ParamSet.UserParam4 = 90; // zur freien Verwendung
ParamSet.UserParam5 = 90; // zur freien Verwendung
ParamSet.UserParam6 = 90; // zur freien Verwendung
ParamSet.UserParam7 = 0; // zur freien Verwendung
ParamSet.UserParam8 = 0; // zur freien Verwendung
ParamSet.ServoPitchControl = 100; // Wert : 0-250 // Stellung des Servos
ParamSet.ServoPitchComp = 40; // Wert : 0-250 // Einfluss Gyro/Servo
ParamSet.ServoPitchCompInvert = 0; // Wert : 0-250 // Richtung Einfluss Gyro/Servo
ParamSet.ServoPitchMin = 50; // Wert : 0-250 // Anschlag
ParamSet.ServoPitchMax = 150; // Wert : 0-250 // Anschlag
ParamSet.ServoPitchRefresh = 5;
ParamSet.LoopThrustLimit = 50;
ParamSet.LoopThreshold = 90; // Wert: 0-250 Schwelle für Stickausschlag
ParamSet.LoopHysteresis = 50;
ParamSet.LoopConfig = 0; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts
ParamSet.Yaw_PosFeedback = 90; // Faktor, mit dem Yaw die Achsen Roll und Pitch verkoppelt
ParamSet.Yaw_NegFeedback = 5;
ParamSet.AngleTurnOverPitch = 100;
ParamSet.AngleTurnOverRoll = 100;
ParamSet.GyroAccTrim = 32; // 1/k
ParamSet.DriftComp = 4;
ParamSet.DynamicStability = 75;
memcpy(ParamSet.Name, "Normal\0", 7);
EE_Parameter.Kanalbelegung[K_NICK] = 1;
EE_Parameter.Kanalbelegung[K_ROLL] = 2;
EE_Parameter.Kanalbelegung[K_GAS] = 3;
EE_Parameter.Kanalbelegung[K_GIER] = 4;
EE_Parameter.Kanalbelegung[K_POTI1] = 5;
EE_Parameter.Kanalbelegung[K_POTI2] = 6;
EE_Parameter.Kanalbelegung[K_POTI3] = 7;
EE_Parameter.Kanalbelegung[K_POTI4] = 8;
EE_Parameter.GlobalConfig = CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV;///*CFG_HOEHEN_SCHALTER |*/ CFG_KOMPASS_AKTIV;//0x01;
EE_Parameter.Hoehe_MinGas = 30;
EE_Parameter.MaxHoehe = 251; // Wert : 0-250 251 -> Poti1
EE_Parameter.Hoehe_P = 10; // Wert : 0-32
EE_Parameter.Luftdruck_D = 30; // Wert : 0-250
EE_Parameter.Hoehe_ACC_Wirkung = 30; // Wert : 0-250
EE_Parameter.Hoehe_Verstaerkung = 3; // Wert : 0-50
EE_Parameter.Stick_P = 12; // Wert : 1-6
EE_Parameter.Stick_D = 16; // Wert : 0-64
EE_Parameter.Gier_P = 6; // Wert : 1-20
EE_Parameter.Gas_Min = 8; // Wert : 0-32
EE_Parameter.Gas_Max = 230; // Wert : 33-250
EE_Parameter.GyroAccFaktor = 30; // Wert : 1-64
EE_Parameter.KompassWirkung = 128; // Wert : 0-250
EE_Parameter.Gyro_P = 80; // Wert : 0-250
EE_Parameter.Gyro_I = 120; // Wert : 0-250
EE_Parameter.UnterspannungsWarnung = 94; // Wert : 0-250
EE_Parameter.NotGas = 35; // Wert : 0-250 // Gaswert bei Empangsverlust
EE_Parameter.NotGasZeit = 30; // Wert : 0-250 // Zeit bis auf NotGas geschaltet wird, wg. Rx-Problemen
EE_Parameter.UfoAusrichtung = 0; // X oder + Formation
EE_Parameter.I_Faktor = 32;
EE_Parameter.UserParam1 = 253; // zur freien Verwendung
EE_Parameter.UserParam2 = 100; // zur freien Verwendung
EE_Parameter.UserParam3 = 90; // zur freien Verwendung
EE_Parameter.UserParam4 = 90; // zur freien Verwendung
EE_Parameter.UserParam5 = 90; // zur freien Verwendung
EE_Parameter.UserParam6 = 90; // zur freien Verwendung
EE_Parameter.UserParam7 = 0; // zur freien Verwendung
EE_Parameter.UserParam8 = 0; // zur freien Verwendung
EE_Parameter.ServoNickControl = 100; // Wert : 0-250 // Stellung des Servos
EE_Parameter.ServoNickComp = 40; // Wert : 0-250 // Einfluss Gyro/Servo
EE_Parameter.ServoNickCompInvert = 0; // Wert : 0-250 // Richtung Einfluss Gyro/Servo
EE_Parameter.ServoNickMin = 50; // Wert : 0-250 // Anschlag
EE_Parameter.ServoNickMax = 150; // Wert : 0-250 // Anschlag
EE_Parameter.ServoNickRefresh = 5;
EE_Parameter.LoopGasLimit = 50;
EE_Parameter.LoopThreshold = 90; // Wert: 0-250 Schwelle für Stickausschlag
EE_Parameter.LoopHysterese = 50;
EE_Parameter.LoopConfig = 0; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts
EE_Parameter.AchsKopplung1 = 90; // Faktor, mit dem Gier die Achsen Roll und Nick verkoppelt
EE_Parameter.AchsGegenKopplung1 = 5;
EE_Parameter.WinkelUmschlagNick = 100;
EE_Parameter.WinkelUmschlagRoll = 100;
EE_Parameter.GyroAccAbgleich = 32; // 1/k
EE_Parameter.Driftkomp = 4;
EE_Parameter.DynamicStability = 75;
memcpy(EE_Parameter.Name, "Normal\0", 12);
}
 
 
/***************************************************/
/* Default Values for parameter set 3 */
/***************************************************/
void ParamSet_DefaultSet3(void) // beginner
void DefaultKonstanten3(void)
{
ParamSet.ChannelAssignment[CH_PITCH] = 1;
ParamSet.ChannelAssignment[CH_ROLL] = 2;
ParamSet.ChannelAssignment[CH_THRUST] = 3;
ParamSet.ChannelAssignment[CH_YAW] = 4;
ParamSet.ChannelAssignment[CH_POTI1] = 5;
ParamSet.ChannelAssignment[CH_POTI2] = 6;
ParamSet.ChannelAssignment[CH_POTI3] = 7;
ParamSet.ChannelAssignment[CH_POTI4] = 8;
ParamSet.GlobalConfig = CFG_ROTARY_RATE_LIMITER | CFG_AXIS_COUPLING_ACTIVE | CFG_COMPASS_ACTIVE | CFG_GPS_ACTIVE;//CFG_HEIGHT_CONTROL | CFG_HEIGHT_SWITCH | CFG_COMPASS_FIX;//0x01;
ParamSet.Height_MinThrust = 30;
ParamSet.MaxHeight = 251; // Wert : 0-250 251 -> Poti1
ParamSet.Height_P = 10; // Wert : 0-32
ParamSet.Height_D = 30; // Wert : 0-250
ParamSet.Height_ACC_Effect = 30; // Wert : 0-250
ParamSet.Height_Gain = 3; // Wert : 0-50
ParamSet.Stick_P = 8; // Wert : 1-24
ParamSet.Stick_D = 16; // Wert : 0-250
ParamSet.Yaw_P = 6; // Wert : 1-20
ParamSet.Trust_Min = 8; // Wert : 0-32
ParamSet.Trust_Max = 230; // Wert : 33-250
ParamSet.GyroAccFactor = 30; // Wert : 1-64
ParamSet.CompassYawEffect = 128; // Wert : 0-250
ParamSet.Gyro_P = 100; // Wert : 0-250
ParamSet.Gyro_I = 120; // Wert : 0-250
ParamSet.LowVoltageWarning = 94; // Wert : 0-250
ParamSet.EmergencyThrust = 35; // Wert : 0-250 // Gaswert bei Empangsverlust
ParamSet.EmergencyThrustDuration = 20; // Wert : 0-250 // Zeit bis auf EmergencyThrust geschaltet wird, wg. Rx-Problemen
ParamSet.UfoArrangement = 0; // X oder + Formation
ParamSet.I_Factor = 16;
ParamSet.UserParam1 = 253; // zur freien Verwendung
ParamSet.UserParam2 = 100; // zur freien Verwendung
ParamSet.UserParam3 = 90; // zur freien Verwendung
ParamSet.UserParam4 = 90; // zur freien Verwendung
ParamSet.UserParam5 = 90; // zur freien Verwendung
ParamSet.UserParam6 = 90; // zur freien Verwendung
ParamSet.UserParam7 = 0; // zur freien Verwendung
ParamSet.UserParam8 = 0; // zur freien Verwendung
ParamSet.ServoPitchControl = 100; // Wert : 0-250 // Stellung des Servos
ParamSet.ServoPitchComp = 40; // Wert : 0-250 // Einfluss Gyro/Servo
ParamSet.ServoPitchCompInvert = 0; // Wert : 0-250 // Richtung Einfluss Gyro/Servo
ParamSet.ServoPitchMin = 50; // Wert : 0-250 // Anschlag
ParamSet.ServoPitchMax = 150; // Wert : 0-250 // Anschlag
ParamSet.ServoPitchRefresh = 5;
ParamSet.LoopThrustLimit = 50;
ParamSet.LoopThreshold = 90; // Wert: 0-250 Schwelle für Stickausschlag
ParamSet.LoopHysteresis = 50;
ParamSet.LoopConfig = 0; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts
ParamSet.Yaw_PosFeedback = 90; // Faktor, mit dem Yaw die Achsen Roll und Pitch verkoppelt
ParamSet.Yaw_NegFeedback = 5;
ParamSet.AngleTurnOverPitch = 100;
ParamSet.AngleTurnOverRoll = 100;
ParamSet.GyroAccTrim = 32; // 1/k
ParamSet.DriftComp = 4;
ParamSet.DynamicStability = 50;
memcpy(ParamSet.Name, "Beginner\0", 9);
EE_Parameter.Kanalbelegung[K_NICK] = 1;
EE_Parameter.Kanalbelegung[K_ROLL] = 2;
EE_Parameter.Kanalbelegung[K_GAS] = 3;
EE_Parameter.Kanalbelegung[K_GIER] = 4;
EE_Parameter.Kanalbelegung[K_POTI1] = 5;
EE_Parameter.Kanalbelegung[K_POTI2] = 6;
EE_Parameter.Kanalbelegung[K_POTI3] = 7;
EE_Parameter.Kanalbelegung[K_POTI4] = 8;
EE_Parameter.GlobalConfig = CFG_DREHRATEN_BEGRENZER | CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV;///*CFG_HOEHEN_SCHALTER |*/ CFG_KOMPASS_AKTIV;//0x01;
EE_Parameter.Hoehe_MinGas = 30;
EE_Parameter.MaxHoehe = 251; // Wert : 0-250 251 -> Poti1
EE_Parameter.Hoehe_P = 10; // Wert : 0-32
EE_Parameter.Luftdruck_D = 30; // Wert : 0-250
EE_Parameter.Hoehe_ACC_Wirkung = 30; // Wert : 0-250
EE_Parameter.Hoehe_Verstaerkung = 3; // Wert : 0-50
EE_Parameter.Stick_P = 8; // Wert : 1-6
EE_Parameter.Stick_D = 16; // Wert : 0-64
EE_Parameter.Gier_P = 6; // Wert : 1-20
EE_Parameter.Gas_Min = 8; // Wert : 0-32
EE_Parameter.Gas_Max = 230; // Wert : 33-250
EE_Parameter.GyroAccFaktor = 30; // Wert : 1-64
EE_Parameter.KompassWirkung = 128; // Wert : 0-250
EE_Parameter.Gyro_P = 100; // Wert : 0-250
EE_Parameter.Gyro_I = 120; // Wert : 0-250
EE_Parameter.UnterspannungsWarnung = 94; // Wert : 0-250
EE_Parameter.NotGas = 35; // Wert : 0-250 // Gaswert bei Empangsverlust
EE_Parameter.NotGasZeit = 20; // Wert : 0-250 // Zeit bis auf NotGas geschaltet wird, wg. Rx-Problemen
EE_Parameter.UfoAusrichtung = 0; // X oder + Formation
EE_Parameter.I_Faktor = 16;
EE_Parameter.UserParam1 = 253; // zur freien Verwendung
EE_Parameter.UserParam2 = 100; // zur freien Verwendung
EE_Parameter.UserParam3 = 90; // zur freien Verwendung
EE_Parameter.UserParam4 = 90; // zur freien Verwendung
EE_Parameter.UserParam5 = 90; // zur freien Verwendung
EE_Parameter.UserParam6 = 90; // zur freien Verwendung
EE_Parameter.UserParam7 = 0; // zur freien Verwendung
EE_Parameter.UserParam8 = 0; // zur freien Verwendung
EE_Parameter.ServoNickControl = 100; // Wert : 0-250 // Stellung des Servos
EE_Parameter.ServoNickComp = 40; // Wert : 0-250 // Einfluss Gyro/Servo
EE_Parameter.ServoNickCompInvert = 0; // Wert : 0-250 // Richtung Einfluss Gyro/Servo
EE_Parameter.ServoNickMin = 50; // Wert : 0-250 // Anschlag
EE_Parameter.ServoNickMax = 150; // Wert : 0-250 // Anschlag
EE_Parameter.ServoNickRefresh = 5;
EE_Parameter.LoopGasLimit = 50;
EE_Parameter.LoopThreshold = 90; // Wert: 0-250 Schwelle für Stickausschlag
EE_Parameter.LoopHysterese = 50;
EE_Parameter.LoopConfig = 0; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts
EE_Parameter.AchsKopplung1 = 90; // Faktor, mit dem Gier die Achsen Roll und Nick verkoppelt
EE_Parameter.AchsGegenKopplung1 = 5;
EE_Parameter.WinkelUmschlagNick = 100;
EE_Parameter.WinkelUmschlagRoll = 100;
EE_Parameter.GyroAccAbgleich = 32; // 1/k
EE_Parameter.Driftkomp = 4;
EE_Parameter.DynamicStability = 50;
memcpy(EE_Parameter.Name, "Beginner\0", 12);
}
 
/***************************************************/
/* Read Parameter from EEPROM as byte */
/***************************************************/
uint8_t GetParamByte(uint8_t param_id)
{
return eeprom_read_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]);
}
 
/***************************************************/
/* Write Parameter to EEPROM as byte */
/***************************************************/
void SetParamByte(uint8_t param_id, uint8_t value)
{
eeprom_write_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value);
}
 
/***************************************************/
/* Read Parameter from EEPROM as word */
/***************************************************/
uint16_t GetParamWord(uint8_t param_id)
{
return eeprom_read_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]);
}
 
/***************************************************/
/* Write Parameter to EEPROM as word */
/***************************************************/
void SetParamWord(uint8_t param_id, uint16_t value)
{
eeprom_write_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value);
}
 
 
/***************************************************/
/* Read Parameter Set from EEPROM */
/***************************************************/
// number [0..5]
void ParamSet_ReadFromEEProm(uint8_t setnumber)
{
if (setnumber > 5) setnumber = 5;
eeprom_read_block((uint8_t *) &ParamSet.ChannelAssignment[0], &EEPromArray[EEPROM_ADR_PARAMSET_BEGIN + PARAMSET_STRUCT_LEN * setnumber], PARAMSET_STRUCT_LEN);
}
 
/***************************************************/
/* Write Parameter Set to EEPROM */
/***************************************************/
// number [0..5]
void ParamSet_WriteToEEProm(uint8_t setnumber)
{
if(setnumber > 5) setnumber = 5;
eeprom_write_block((uint8_t *) &ParamSet.ChannelAssignment[0], &EEPromArray[EEPROM_ADR_PARAMSET_BEGIN + PARAMSET_STRUCT_LEN * setnumber], PARAMSET_STRUCT_LEN);
// set this parameter set to active set
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber);
}
 
/***************************************************/
/* Get active parameter set */
/***************************************************/
uint8_t GetActiveParamSet(void)
{
uint8_t setnumber;
setnumber = eeprom_read_byte(&EEPromArray[PID_ACTIVE_SET]);
if(setnumber > 5)
{
setnumber = 2;
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber);
}
return(setnumber);
}
 
/***************************************************/
/* Set active parameter set */
/***************************************************/
void SetActiveParamSet(uint8_t setnumber)
{
if(setnumber > 5) setnumber = 5;
eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber);
}
 
/***************************************************/
/* Initialize EEPROM Parameter Sets */
/***************************************************/
void ParamSet_Init(void)
{
// version check
if(eeprom_read_byte(&EEPromArray[PID_VERSION]) != EEPARAM_VERSION)
{
// if version check faild
printf("\n\rInit. EEPROM: Generating Default-Parameter...");
ParamSet_DefaultSet1(); // Fill ParamSet Structure to default parameter set 1 (Sport)
// fill all 5 parameter settings with set 1 except otherwise defined
for (unsigned char i=0;i<6;i++)
{
if(i==2) ParamSet_DefaultSet2(); // Kamera
if(i==3) ParamSet_DefaultSet3(); // Beginner
if(i>3) ParamSet_DefaultSet2(); // Kamera
ParamSet_WriteToEEProm(i);
}
// default-Setting is parameter set 3
SetParamByte(PID_ACTIVE_SET, 3);
// update version info
SetParamByte(PID_VERSION, EEPARAM_VERSION);
}
// read active parameter set to ParamSet stucture
ParamSet_ReadFromEEProm(GetParamByte(PID_ACTIVE_SET));
printf("\n\rUsing Parameter Set %d", GetParamByte(PID_ACTIVE_SET));
}
/branches/V0.69k Code Redesign killagreg/fc.c
6,14 → 6,14
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
// + Verkauf von Luftbildaufnahmen, usw.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
24,21 → 24,21
// + Benutzung auf eigene Gefahr
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * porting to systems other than hardware from www.mikrokopter.de is not allowed
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49,1385 → 49,1187
// + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdlib.h>
#include <avr/io.h>
 
#include "main.h"
#include "eeprom.h"
#include "timer0.h"
#include "_Settings.h"
#include "analog.h"
#include "fc.h"
#include "uart.h"
#include "rc.h"
#include "twimaster.h"
#include "timer2.h"
#ifdef USE_KILLAGREG
#include "mm3.h"
#include "gps.h"
#endif
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
#include "mk3mag.h"
#endif
#include "led.h"
#include "eeprom.c"
 
volatile uint16_t I2CTimeout = 100;
// gyro readings
volatile int16_t Reading_GyroPitch, Reading_GyroRoll, Reading_GyroYaw;
// gyro neutral readings
volatile int16_t AdNeutralPitch = 0, AdNeutralRoll = 0, AdNeutralYaw = 0;
volatile int16_t StartNeutralRoll = 0, StartNeutralPitch = 0;
// mean accelerations
volatile int16_t Mean_AccPitch, Mean_AccRoll, Mean_AccTop;
 
// neutral acceleration readings
volatile int16_t NeutralAccX=0, NeutralAccY=0;
unsigned char h,m,s;
volatile unsigned int I2CTimeout = 100;
volatile int MesswertNick,MesswertRoll,MesswertGier;
volatile int AdNeutralNick = 0,AdNeutralRoll = 0,AdNeutralGier = 0,StartNeutralRoll = 0,StartNeutralNick = 0;
volatile int Mittelwert_AccNick, Mittelwert_AccRoll,Mittelwert_AccHoch, NeutralAccX=0, NeutralAccY=0;
int NaviAccNick, NaviAccRoll,NaviCntAcc = 0;
volatile float NeutralAccZ = 0;
unsigned char CosinusNickWinkel = 0, CosinusRollWinkel = 0;
long IntegralNick = 0,IntegralNick2 = 0;
long IntegralRoll = 0,IntegralRoll2 = 0;
long IntegralAccNick = 0,IntegralAccRoll = 0,IntegralAccZ = 0;
long Integral_Gier = 0;
long Mess_IntegralNick = 0,Mess_IntegralNick2 = 0;
long Mess_IntegralRoll = 0,Mess_IntegralRoll2 = 0;
long Mess_Integral_Gier = 0,Mess_Integral_Gier2 = 0;
long MittelIntegralNick,MittelIntegralRoll,MittelIntegralNick2,MittelIntegralRoll2;
volatile long Mess_Integral_Hoch = 0;
volatile int KompassValue = 0;
volatile int KompassStartwert = 0;
volatile int KompassRichtung = 0;
unsigned int KompassSignalSchlecht = 500;
unsigned char MAX_GAS,MIN_GAS;
unsigned char Notlandung = 0;
unsigned char HoehenReglerAktiv = 0;
unsigned char TrichterFlug = 0;
long Umschlag180Nick = 250000L, Umschlag180Roll = 250000L;
long ErsatzKompass;
int ErsatzKompassInGrad; // Kompasswert in Grad
int GierGyroFehler = 0;
float GyroFaktor;
float IntegralFaktor;
volatile int DiffNick,DiffRoll;
int Poti1 = 0, Poti2 = 0, Poti3 = 0, Poti4 = 0;
volatile unsigned char Motor_Vorne,Motor_Hinten,Motor_Rechts,Motor_Links, Count;
volatile unsigned char SenderOkay = 0;
int StickNick = 0,StickRoll = 0,StickGier = 0,StickGas = 0;
char MotorenEin = 0;
int HoehenWert = 0;
int SollHoehe = 0;
int LageKorrekturRoll = 0,LageKorrekturNick = 0;
float Ki = FAKTOR_I;
unsigned char Looping_Nick = 0,Looping_Roll = 0;
unsigned char Looping_Links = 0, Looping_Rechts = 0, Looping_Unten = 0, Looping_Oben = 0;
 
// attitude gyro integrals
volatile int32_t IntegralPitch = 0,IntegralPitch2 = 0;
volatile int32_t IntegralRoll = 0,IntegralRoll2 = 0;
volatile int32_t IntegralYaw = 0;
volatile int32_t Reading_IntegralGyroPitch = 0, Reading_IntegralGyroPitch2 = 0;
volatile int32_t Reading_IntegralGyroRoll = 0, Reading_IntegralGyroRoll2 = 0;
volatile int32_t Reading_IntegralGyroYaw = 0;
volatile int32_t MeanIntegralPitch;
volatile int32_t MeanIntegralRoll;
unsigned char Parameter_Luftdruck_D = 48; // Wert : 0-250
unsigned char Parameter_MaxHoehe = 251; // Wert : 0-250
unsigned char Parameter_Hoehe_P = 16; // Wert : 0-32
unsigned char Parameter_Hoehe_ACC_Wirkung = 58; // Wert : 0-250
unsigned char Parameter_KompassWirkung = 64; // Wert : 0-250
unsigned char Parameter_Gyro_P = 150; // Wert : 10-250
unsigned char Parameter_Gyro_I = 150; // Wert : 0-250
unsigned char Parameter_Gier_P = 2; // Wert : 1-20
unsigned char Parameter_I_Faktor = 10; // Wert : 1-20
unsigned char Parameter_UserParam1 = 0;
unsigned char Parameter_UserParam2 = 0;
unsigned char Parameter_UserParam3 = 0;
unsigned char Parameter_UserParam4 = 0;
unsigned char Parameter_UserParam5 = 0;
unsigned char Parameter_UserParam6 = 0;
unsigned char Parameter_UserParam7 = 0;
unsigned char Parameter_UserParam8 = 0;
unsigned char Parameter_ServoNickControl = 100;
unsigned char Parameter_LoopGasLimit = 70;
unsigned char Parameter_AchsKopplung1 = 0;
unsigned char Parameter_AchsGegenKopplung1 = 0;
unsigned char Parameter_DynamicStability = 100;
struct mk_param_struct EE_Parameter;
signed int ExternStickNick = 0,ExternStickRoll = 0,ExternStickGier = 0, ExternHoehenValue = -20;
int MaxStickNick = 0,MaxStickRoll = 0;
unsigned int modell_fliegt = 0;
 
// attitude acceleration integrals
volatile int32_t IntegralAccPitch = 0, IntegralAccRoll = 0;
volatile int32_t Reading_Integral_Top = 0;
 
// compass course
volatile int16_t CompassHeading = -1; // negative angle indicates invalid data.
volatile int16_t CompassCourse = -1;
volatile int16_t CompassOffCourse = 0;
volatile uint8_t CompassCalState = 0;
uint8_t FunnelCourse = 0;
uint16_t BadCompassHeading = 500;
int32_t YawGyroHeading;
int16_t YawGyroDrift;
 
 
int16_t NaviAccPitch = 0, NaviAccRoll = 0, NaviCntAcc = 0;
 
 
// flags
uint8_t MotorsOn = 0;
uint8_t EmergencyLanding = 0;
uint16_t Model_Is_Flying = 0;
 
int32_t TurnOver180Pitch = 250000L, TurnOver180Roll = 250000L;
 
float Gyro_P_Factor;
float Gyro_I_Factor;
 
volatile int16_t DiffPitch, DiffRoll;
 
int16_t Poti1 = 0, Poti2 = 0, Poti3 = 0, Poti4 = 0, Poti5 = 0, Poti6 = 0, Poti7 = 0, Poti8 = 0;
 
// setpoints for motors
volatile uint8_t Motor_Front, Motor_Rear, Motor_Right, Motor_Left;
 
// stick values derived by rc channels readings
int16_t StickPitch = 0, StickRoll = 0, StickYaw = 0, StickThrust = 0;
int16_t GPS_Pitch = 0, GPS_Roll = 0;
 
int16_t MaxStickPitch = 0, MaxStickRoll = 0;
// stick values derived by uart inputs
int16_t ExternStickPitch = 0, ExternStickRoll = 0, ExternStickYaw = 0, ExternHeightValue = -20;
 
 
 
 
int16_t ReadingHeight = 0;
int16_t SetPointHeight = 0;
 
int16_t AttitudeCorrectionRoll = 0, AttitudeCorrectionPitch = 0;
 
float Ki = FACTOR_I;
 
uint8_t Looping_Pitch = 0, Looping_Roll = 0;
uint8_t Looping_Left = 0, Looping_Right = 0, Looping_Down = 0, Looping_Top = 0;
 
 
fc_param_t FCParam = {48,251,16,58,64,150,150,2,10,0,0,0,0,0,0,0,0,100,70,0,0,100};
 
 
/************************************************************************/
/* Creates numbeeps beeps at the speaker */
/************************************************************************/
void Beep(uint8_t numbeeps)
void Piep(unsigned char Anzahl)
{
while(numbeeps--)
{
if(MotorsOn) return; //auf keinen Fall im Flug!
BeepTime = 100; // 0.1 second
Delay_ms(250); // blocks 250 ms as pause to next beep,
// this will block the flight control loop,
// therefore do not use this funktion if motors are running
}
while(Anzahl--)
{
if(MotorenEin) return; //auf keinen Fall im Flug!
beeptime = 100;
Delay_ms(250);
}
}
 
/************************************************************************/
/* Neutral Readings */
/************************************************************************/
//############################################################################
// Nullwerte ermitteln
void SetNeutral(void)
//############################################################################
{
NeutralAccX = 0;
NeutralAccX = 0;
NeutralAccY = 0;
NeutralAccZ = 0;
AdNeutralPitch = 0;
AdNeutralRoll = 0;
AdNeutralYaw = 0;
FCParam.Yaw_PosFeedback = 0;
FCParam.Yaw_NegFeedback = 0;
CalibMean();
AdNeutralNick = 0;
AdNeutralRoll = 0;
AdNeutralGier = 0;
Parameter_AchsKopplung1 = 0;
Parameter_AchsGegenKopplung1 = 0;
CalibrierMittelwert();
Delay_ms_Mess(100);
CalibMean();
if((ParamSet.GlobalConfig & CFG_HEIGHT_CONTROL)) // Height Control activated?
CalibrierMittelwert();
if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung aktiviert?
{
if((MessLuftdruck > 950) || (MessLuftdruck < 750)) SucheLuftruckOffset();
}
 
AdNeutralNick= AdWertNick;
AdNeutralRoll= AdWertRoll;
AdNeutralGier= AdWertGier;
StartNeutralRoll = AdNeutralRoll;
StartNeutralNick = AdNeutralNick;
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) > 4)
{
if((ReadingAirPressure > 950) || (ReadingAirPressure < 750)) SearchAirPressureOffset();
NeutralAccY = abs(Mittelwert_AccRoll) / ACC_AMPLIFY;
NeutralAccX = abs(Mittelwert_AccNick) / ACC_AMPLIFY;
NeutralAccZ = Aktuell_az;
}
AdNeutralPitch = AdValueGyrPitch;
AdNeutralRoll = AdValueGyrRoll;
AdNeutralYaw = AdValueGyrYaw;
StartNeutralRoll = AdNeutralRoll;
StartNeutralPitch = AdNeutralPitch;
if(GetParamWord(PID_ACC_PITCH) > 1023)
else
{
NeutralAccY = abs(Mean_AccRoll) / ACC_AMPLIFY;
NeutralAccX = abs(Mean_AccPitch) / ACC_AMPLIFY;
NeutralAccZ = Current_AccZ;
NeutralAccX = (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) * 256 + (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK+1]);
NeutralAccY = (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL]) * 256 + (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL+1]);
NeutralAccZ = (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_Z]) * 256 + (int)eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_Z+1]);
}
else
{
NeutralAccX = (int16_t)GetParamWord(PID_ACC_PITCH);
NeutralAccY = (int16_t)GetParamWord(PID_ACC_ROLL);
NeutralAccZ = (int16_t)GetParamWord(PID_ACC_Z);
}
Reading_IntegralGyroPitch = 0;
Reading_IntegralGyroPitch2 = 0;
Reading_IntegralGyroRoll = 0;
Reading_IntegralGyroRoll2 = 0;
Reading_IntegralGyroYaw = 0;
Reading_GyroPitch = 0;
Reading_GyroRoll = 0;
Reading_GyroYaw = 0;
StartAirPressure = AirPressure;
HeightD = 0;
Reading_Integral_Top = 0;
CompassCourse = CompassHeading;
BeepTime = 50;
TurnOver180Pitch = ((int32_t) ParamSet.AngleTurnOverPitch * 2500L) +15000L;
TurnOver180Roll = ((int32_t) ParamSet.AngleTurnOverRoll * 2500L) +15000L;
ExternHeightValue = 0;
GPS_Pitch = 0;
GPS_Roll = 0;
YawGyroHeading = CompassHeading * YAW_GYRO_DEG_FACTOR;
YawGyroDrift = 0;
Mess_IntegralNick = 0;
Mess_IntegralNick2 = 0;
Mess_IntegralRoll = 0;
Mess_IntegralRoll2 = 0;
Mess_Integral_Gier = 0;
MesswertNick = 0;
MesswertRoll = 0;
MesswertGier = 0;
StartLuftdruck = Luftdruck;
HoeheD = 0;
Mess_Integral_Hoch = 0;
KompassStartwert = KompassValue;
GPS_Neutral();
beeptime = 50;
Umschlag180Nick = ((long) EE_Parameter.WinkelUmschlagNick * 2500L) + 15000L;
Umschlag180Roll = ((long) EE_Parameter.WinkelUmschlagRoll * 2500L) + 15000L;
ExternHoehenValue = 0;
ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR;
GierGyroFehler = 0;
SendVersionToNavi = 1;
}
 
/************************************************************************/
/* Averaging Measurement Readings */
/************************************************************************/
void Mean(void)
{
static int32_t tmpl,tmpl2;
//############################################################################
// Bearbeitet die Messwerte
void Mittelwert(void)
//############################################################################
{
static signed long tmpl,tmpl2;
MesswertGier = (signed int) AdNeutralGier - AdWertGier;
MesswertRoll = (signed int) AdWertRoll - AdNeutralRoll;
MesswertNick = (signed int) AdWertNick - AdNeutralNick;
 
// Get offset corrected gyro readings (~ to angular velocity)
Reading_GyroYaw = AdNeutralYaw - AdValueGyrYaw;
Reading_GyroRoll = AdValueGyrRoll - AdNeutralRoll;
Reading_GyroPitch = AdValueGyrPitch - AdNeutralPitch;
//DebugOut.Analog[26] = MesswertNick;
DebugOut.Analog[28] = MesswertRoll;
 
// Acceleration Sensor
// sliding average sensor readings
Mean_AccPitch = ((int32_t)Mean_AccPitch * 1 + ((ACC_AMPLIFY * (int32_t)AdValueAccPitch))) / 2L;
Mean_AccRoll = ((int32_t)Mean_AccRoll * 1 + ((ACC_AMPLIFY * (int32_t)AdValueAccRoll))) / 2L;
Mean_AccTop = ((int32_t)Mean_AccTop * 1 + ((int32_t)AdValueAccTop)) / 2L;
 
// sum sensor readings for later averaging
IntegralAccPitch += ACC_AMPLIFY * AdValueAccPitch;
IntegralAccRoll += ACC_AMPLIFY * AdValueAccRoll;
 
NaviAccPitch += AdValueAccPitch;
NaviAccRoll += AdValueAccRoll;
// Beschleunigungssensor ++++++++++++++++++++++++++++++++++++++++++++++++
Mittelwert_AccNick = ((long)Mittelwert_AccNick * 1 + ((ACC_AMPLIFY * (long)AdWertAccNick))) / 2L;
Mittelwert_AccRoll = ((long)Mittelwert_AccRoll * 1 + ((ACC_AMPLIFY * (long)AdWertAccRoll))) / 2L;
Mittelwert_AccHoch = ((long)Mittelwert_AccHoch * 1 + ((long)AdWertAccHoch)) / 2L;
IntegralAccNick += ACC_AMPLIFY * AdWertAccNick;
IntegralAccRoll += ACC_AMPLIFY * AdWertAccRoll;
NaviAccNick += AdWertAccNick;
NaviAccRoll += AdWertAccRoll;
NaviCntAcc++;
IntegralAccZ += Aktuell_az - NeutralAccZ;
// Gier ++++++++++++++++++++++++++++++++++++++++++++++++
ErsatzKompass += MesswertGier;
Mess_Integral_Gier += MesswertGier;
Mess_Integral_Gier2 += MesswertGier;
if(ErsatzKompass >= (360L * GIER_GRAD_FAKTOR)) ErsatzKompass -= 360L * GIER_GRAD_FAKTOR; // 360° Umschlag
if(ErsatzKompass < 0) ErsatzKompass += 360L * GIER_GRAD_FAKTOR;
// Kopplungsanteil +++++++++++++++++++++++++++++++++++++
if(!Looping_Nick && !Looping_Roll && (EE_Parameter.GlobalConfig & CFG_ACHSENKOPPLUNG_AKTIV))
{
tmpl = (MesswertGier * Mess_IntegralNick) / 2048L;
tmpl *= Parameter_AchsKopplung1; //125
tmpl /= 4096L;
tmpl2 = (MesswertGier * Mess_IntegralRoll) / 2048L;
tmpl2 *= Parameter_AchsKopplung1;
tmpl2 /= 4096L;
if(labs(tmpl) > 128 || labs(tmpl2) > 128) TrichterFlug = 1;
}
else tmpl = tmpl2 = 0;
// Roll ++++++++++++++++++++++++++++++++++++++++++++++++
MesswertRoll += tmpl;
MesswertRoll += (tmpl2*Parameter_AchsGegenKopplung1)/512L; //109
Mess_IntegralRoll2 += MesswertRoll;
Mess_IntegralRoll += MesswertRoll - LageKorrekturRoll;
if(Mess_IntegralRoll > Umschlag180Roll)
{
Mess_IntegralRoll = -(Umschlag180Roll - 25000L);
Mess_IntegralRoll2 = Mess_IntegralRoll;
}
if(Mess_IntegralRoll <-Umschlag180Roll)
{
Mess_IntegralRoll = (Umschlag180Roll - 25000L);
Mess_IntegralRoll2 = Mess_IntegralRoll;
}
if(AdWertRoll < 15) MesswertRoll = -1000;
if(AdWertRoll < 7) MesswertRoll = -2000;
if(PlatinenVersion == 10)
{
if(AdWertRoll > 1010) MesswertRoll = +1000;
if(AdWertRoll > 1017) MesswertRoll = +2000;
}
else
{
if(AdWertRoll > 2020) MesswertRoll = +1000;
if(AdWertRoll > 2034) MesswertRoll = +2000;
}
// Nick ++++++++++++++++++++++++++++++++++++++++++++++++
MesswertNick -= tmpl2;
MesswertNick -= (tmpl*Parameter_AchsGegenKopplung1)/512L;
Mess_IntegralNick2 += MesswertNick;
Mess_IntegralNick += MesswertNick - LageKorrekturNick;
 
// Yaw
// calculate yaw gyro integral (~ to rotation angle)
Reading_IntegralGyroYaw += Reading_GyroYaw;
YawGyroHeading += Reading_GyroYaw;
if(YawGyroHeading >= (360L * YAW_GYRO_DEG_FACTOR)) YawGyroHeading -= 360L * YAW_GYRO_DEG_FACTOR; // 360° Wrap
if(YawGyroHeading < 0) YawGyroHeading += 360L * YAW_GYRO_DEG_FACTOR;
if(Mess_IntegralNick > Umschlag180Nick)
{
Mess_IntegralNick = -(Umschlag180Nick - 25000L);
Mess_IntegralNick2 = Mess_IntegralNick;
}
if(Mess_IntegralNick <-Umschlag180Nick)
{
Mess_IntegralNick = (Umschlag180Nick - 25000L);
Mess_IntegralNick2 = Mess_IntegralNick;
}
if(AdWertNick < 15) MesswertNick = -1000;
if(AdWertNick < 7) MesswertNick = -2000;
if(PlatinenVersion == 10)
{
if(AdWertNick > 1010) MesswertNick = +1000;
if(AdWertNick > 1017) MesswertNick = +2000;
}
else
{
if(AdWertNick > 2020) MesswertNick = +1000;
if(AdWertNick > 2034) MesswertNick = +2000;
}
//++++++++++++++++++++++++++++++++++++++++++++++++
// ADC einschalten
ANALOG_ON;
//++++++++++++++++++++++++++++++++++++++++++++++++
 
Integral_Gier = Mess_Integral_Gier;
IntegralNick = Mess_IntegralNick;
IntegralRoll = Mess_IntegralRoll;
IntegralNick2 = Mess_IntegralNick2;
IntegralRoll2 = Mess_IntegralRoll2;
 
// Coupling fraction
if(!Looping_Pitch && !Looping_Roll && (ParamSet.GlobalConfig & CFG_AXIS_COUPLING_ACTIVE))
{
tmpl = (Reading_GyroYaw * Reading_IntegralGyroPitch) / 2048L;
tmpl *= FCParam.Yaw_PosFeedback;
tmpl /= 4096L;
tmpl2 = ( Reading_GyroYaw * Reading_IntegralGyroRoll) / 2048L;
tmpl2 *= FCParam.Yaw_PosFeedback;
tmpl2 /= 4096L;
if(labs(tmpl) > 128 || labs(tmpl2) > 128) FunnelCourse = 1;
}
else tmpl = tmpl2 = 0;
 
// Roll
Reading_GyroRoll += tmpl;
Reading_GyroRoll += (tmpl2 * FCParam.Yaw_NegFeedback) / 512L;
Reading_IntegralGyroRoll2 += Reading_GyroRoll;
Reading_IntegralGyroRoll += Reading_GyroRoll - AttitudeCorrectionRoll;
if(Reading_IntegralGyroRoll > TurnOver180Roll)
{
Reading_IntegralGyroRoll = -(TurnOver180Roll - 10000L);
Reading_IntegralGyroRoll2 = Reading_IntegralGyroRoll;
}
if(Reading_IntegralGyroRoll < -TurnOver180Roll)
{
Reading_IntegralGyroRoll = (TurnOver180Roll - 10000L);
Reading_IntegralGyroRoll2 = Reading_IntegralGyroRoll;
}
if(AdValueGyrRoll < 15) Reading_GyroRoll = -1000;
if(AdValueGyrRoll < 7) Reading_GyroRoll = -2000;
if(BoardRelease == 10)
{
if(AdValueGyrRoll > 1010) Reading_GyroRoll = +1000;
if(AdValueGyrRoll > 1017) Reading_GyroRoll = +2000;
}
else
{
if(AdValueGyrRoll > 2020) Reading_GyroRoll = +1000;
if(AdValueGyrRoll > 2034) Reading_GyroRoll = +2000;
}
// Pitch
Reading_GyroPitch -= tmpl2;
Reading_GyroPitch -= (tmpl*FCParam.Yaw_NegFeedback) / 512L;
Reading_IntegralGyroPitch2 += Reading_GyroPitch;
Reading_IntegralGyroPitch += Reading_GyroPitch - AttitudeCorrectionPitch;
if(Reading_IntegralGyroPitch > TurnOver180Pitch)
{
Reading_IntegralGyroPitch = -(TurnOver180Pitch - 25000L);
Reading_IntegralGyroPitch2 = Reading_IntegralGyroPitch;
}
if(Reading_IntegralGyroPitch < -TurnOver180Pitch)
{
Reading_IntegralGyroPitch = (TurnOver180Pitch - 25000L);
Reading_IntegralGyroPitch2 = Reading_IntegralGyroPitch;
}
if(AdValueGyrPitch < 15) Reading_GyroPitch = -1000;
if(AdValueGyrPitch < 7) Reading_GyroPitch = -2000;
if(BoardRelease == 10)
{
if(AdValueGyrPitch > 1010) Reading_GyroPitch = +1000;
if(AdValueGyrPitch > 1017) Reading_GyroPitch = +2000;
}
else
{
if(AdValueGyrPitch > 2020) Reading_GyroPitch = +1000;
if(AdValueGyrPitch > 2034) Reading_GyroPitch = +2000;
}
 
// start ADC again to capture measurement values for the next loop
ADC_Enable();
 
IntegralYaw = Reading_IntegralGyroYaw;
IntegralPitch = Reading_IntegralGyroPitch;
IntegralRoll = Reading_IntegralGyroRoll;
IntegralPitch2 = Reading_IntegralGyroPitch2;
IntegralRoll2 = Reading_IntegralGyroRoll2;
 
if((ParamSet.GlobalConfig & CFG_ROTARY_RATE_LIMITER) && !Looping_Pitch && !Looping_Roll)
{
if(Reading_GyroPitch > 200) Reading_GyroPitch += 4 * (Reading_GyroPitch - 200);
else if(Reading_GyroPitch < -200) Reading_GyroPitch += 4 * (Reading_GyroPitch + 200);
if(Reading_GyroRoll > 200) Reading_GyroRoll += 4 * (Reading_GyroRoll - 200);
else if(Reading_GyroRoll < -200) Reading_GyroRoll += 4 * (Reading_GyroRoll + 200);
}
if(EE_Parameter.GlobalConfig & CFG_DREHRATEN_BEGRENZER && !Looping_Nick && !Looping_Roll)
{
if(MesswertNick > 200) MesswertNick += 4 * (MesswertNick - 200);
else if(MesswertNick < -200) MesswertNick += 4 * (MesswertNick + 200);
if(MesswertRoll > 200) MesswertRoll += 4 * (MesswertRoll - 200);
else if(MesswertRoll < -200) MesswertRoll += 4 * (MesswertRoll + 200);
}
if(Poti1 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110) Poti1++; else if(Poti1 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110 && Poti1) Poti1--;
if(Poti2 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110) Poti2++; else if(Poti2 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110 && Poti2) Poti2--;
if(Poti3 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110) Poti3++; else if(Poti3 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110 && Poti3) Poti3--;
if(Poti4 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110) Poti4++; else if(Poti4 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110 && Poti4) Poti4--;
if(Poti1 < 0) Poti1 = 0; else if(Poti1 > 255) Poti1 = 255;
if(Poti2 < 0) Poti2 = 0; else if(Poti2 > 255) Poti2 = 255;
if(Poti3 < 0) Poti3 = 0; else if(Poti3 > 255) Poti3 = 255;
if(Poti4 < 0) Poti4 = 0; else if(Poti4 > 255) Poti4 = 255;
}
 
/************************************************************************/
/* Averaging Measurement Readings for Calibration */
/************************************************************************/
void CalibMean(void)
{
// stop ADC to avoid changing values during calculation
ADC_Disable();
//############################################################################
// Messwerte beim Ermitteln der Nullage
void CalibrierMittelwert(void)
//############################################################################
{
// ADC auschalten, damit die Werte sich nicht während der Berechnung ändern
ANALOG_OFF;
MesswertNick = AdWertNick;
MesswertRoll = AdWertRoll;
MesswertGier = AdWertGier;
Mittelwert_AccNick = ACC_AMPLIFY * (long)AdWertAccNick;
Mittelwert_AccRoll = ACC_AMPLIFY * (long)AdWertAccRoll;
Mittelwert_AccHoch = (long)AdWertAccHoch;
// ADC einschalten
ANALOG_ON;
if(Poti1 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110) Poti1++; else if(Poti1 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]] + 110 && Poti1) Poti1--;
if(Poti2 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110) Poti2++; else if(Poti2 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]] + 110 && Poti2) Poti2--;
if(Poti3 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110) Poti3++; else if(Poti3 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]] + 110 && Poti3) Poti3--;
if(Poti4 < PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110) Poti4++; else if(Poti4 > PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]] + 110 && Poti4) Poti4--;
if(Poti1 < 0) Poti1 = 0; else if(Poti1 > 255) Poti1 = 255;
if(Poti2 < 0) Poti2 = 0; else if(Poti2 > 255) Poti2 = 255;
if(Poti3 < 0) Poti3 = 0; else if(Poti3 > 255) Poti3 = 255;
if(Poti4 < 0) Poti4 = 0; else if(Poti4 > 255) Poti4 = 255;
 
Reading_GyroPitch = AdValueGyrPitch;
Reading_GyroRoll = AdValueGyrRoll;
Reading_GyroYaw = AdValueGyrYaw;
 
Mean_AccPitch = ACC_AMPLIFY * (int32_t)AdValueAccPitch;
Mean_AccRoll = ACC_AMPLIFY * (int32_t)AdValueAccRoll;
Mean_AccTop = (int32_t)AdValueAccTop;
// start ADC (enables internal trigger so that the ISR in analog.c
// updates the readings once)
ADC_Enable();
 
TurnOver180Pitch = (int32_t) ParamSet.AngleTurnOverPitch * 2500L;
TurnOver180Roll = (int32_t) ParamSet.AngleTurnOverRoll * 2500L;
Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L;
Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L;
}
 
/************************************************************************/
/* Transmit Motor Data via I2C */
/************************************************************************/
//############################################################################
// Senden der Motorwerte per I2C-Bus
void SendMotorData(void)
{
if(MOTOR_OFF || !MotorsOn)
{
Motor_Rear = 0;
Motor_Front = 0;
Motor_Right = 0;
Motor_Left = 0;
if(MotorTest[0]) Motor_Front = MotorTest[0];
if(MotorTest[1]) Motor_Rear = MotorTest[1];
if(MotorTest[2]) Motor_Left = MotorTest[2];
if(MotorTest[3]) Motor_Right = MotorTest[3];
}
//############################################################################
{
if(MOTOR_OFF || !MotorenEin)
{
Motor_Hinten = 0;
Motor_Vorne = 0;
Motor_Rechts = 0;
Motor_Links = 0;
if(MotorTest[0]) Motor_Vorne = MotorTest[0];
if(MotorTest[1]) Motor_Hinten = MotorTest[1];
if(MotorTest[2]) Motor_Links = MotorTest[2];
if(MotorTest[3]) Motor_Rechts = MotorTest[3];
}
 
DebugOut.Analog[12] = Motor_Front;
DebugOut.Analog[13] = Motor_Rear;
DebugOut.Analog[14] = Motor_Left;
DebugOut.Analog[15] = Motor_Right;
DebugOut.Analog[12] = Motor_Vorne;
DebugOut.Analog[13] = Motor_Hinten;
DebugOut.Analog[14] = Motor_Links;
DebugOut.Analog[15] = Motor_Rechts;
 
//Start I2C Interrupt Mode
twi_state = 0;
motor = 0;
I2C_Start();
i2c_start();
}
 
 
 
/************************************************************************/
/* Maps the parameter to poti values */
/************************************************************************/
void ParameterMapping(void)
//############################################################################
// Trägt ggf. das Poti als Parameter ein
void ParameterZuordnung(void)
//############################################################################
{
if(RC_Quality > 160) // do the mapping of RC-Potis only if the rc-signal is ok
// else the last updated values are used
{
//update poti values by rc-signals
#define CHK_POTI(b,a,min,max) { if(a > 250) { if(a == 251) b = Poti1; else if(a == 252) b = Poti2; else if(a == 253) b = Poti3; else if(a == 254) b = Poti4;} else b = a; if(b <= min) b = min; else if(b >= max) b = max;}
CHK_POTI(FCParam.MaxHeight,ParamSet.MaxHeight,0,255);
CHK_POTI(FCParam.Height_D,ParamSet.Height_D,0,100);
CHK_POTI(FCParam.Height_P,ParamSet.Height_P,0,100);
CHK_POTI(FCParam.Height_ACC_Effect,ParamSet.Height_ACC_Effect,0,255);
CHK_POTI(FCParam.CompassYawEffect,ParamSet.CompassYawEffect,0,255);
CHK_POTI(FCParam.Gyro_P,ParamSet.Gyro_P,10,255);
CHK_POTI(FCParam.Gyro_I,ParamSet.Gyro_I,0,255);
CHK_POTI(FCParam.I_Factor,ParamSet.I_Factor,0,255);
CHK_POTI(FCParam.UserParam1,ParamSet.UserParam1,0,255);
CHK_POTI(FCParam.UserParam2,ParamSet.UserParam2,0,255);
CHK_POTI(FCParam.UserParam3,ParamSet.UserParam3,0,255);
CHK_POTI(FCParam.UserParam4,ParamSet.UserParam4,0,255);
CHK_POTI(FCParam.UserParam5,ParamSet.UserParam5,0,255);
CHK_POTI(FCParam.UserParam6,ParamSet.UserParam6,0,255);
CHK_POTI(FCParam.UserParam7,ParamSet.UserParam7,0,255);
CHK_POTI(FCParam.UserParam8,ParamSet.UserParam8,0,255);
CHK_POTI(FCParam.ServoPitchControl,ParamSet.ServoPitchControl,0,255);
CHK_POTI(FCParam.LoopThrustLimit,ParamSet.LoopThrustLimit,0,255);
CHK_POTI(FCParam.Yaw_PosFeedback,ParamSet.Yaw_PosFeedback,0,255);
CHK_POTI(FCParam.Yaw_NegFeedback,ParamSet.Yaw_NegFeedback,0,255);
CHK_POTI(FCParam.DynamicStability,ParamSet.DynamicStability,0,255);
Ki = (float) FCParam.I_Factor * FACTOR_I;
}
}
 
#define CHK_POTI(b,a,min,max) { if(a > 250) { if(a == 251) b = Poti1; else if(a == 252) b = Poti2; else if(a == 253) b = Poti3; else if(a == 254) b = Poti4;} else b = a; if(b <= min) b = min; else if(b >= max) b = max;}
CHK_POTI(Parameter_MaxHoehe,EE_Parameter.MaxHoehe,0,255);
CHK_POTI(Parameter_Luftdruck_D,EE_Parameter.Luftdruck_D,0,100);
CHK_POTI(Parameter_Hoehe_P,EE_Parameter.Hoehe_P,0,100);
CHK_POTI(Parameter_Hoehe_ACC_Wirkung,EE_Parameter.Hoehe_ACC_Wirkung,0,255);
CHK_POTI(Parameter_KompassWirkung,EE_Parameter.KompassWirkung,0,255);
CHK_POTI(Parameter_Gyro_P,EE_Parameter.Gyro_P,10,255);
CHK_POTI(Parameter_Gyro_I,EE_Parameter.Gyro_I,0,255);
CHK_POTI(Parameter_I_Faktor,EE_Parameter.I_Faktor,0,255);
CHK_POTI(Parameter_UserParam1,EE_Parameter.UserParam1,0,255);
CHK_POTI(Parameter_UserParam2,EE_Parameter.UserParam2,0,255);
CHK_POTI(Parameter_UserParam3,EE_Parameter.UserParam3,0,255);
CHK_POTI(Parameter_UserParam4,EE_Parameter.UserParam4,0,255);
CHK_POTI(Parameter_UserParam5,EE_Parameter.UserParam5,0,255);
CHK_POTI(Parameter_UserParam6,EE_Parameter.UserParam6,0,255);
CHK_POTI(Parameter_UserParam7,EE_Parameter.UserParam7,0,255);
CHK_POTI(Parameter_UserParam8,EE_Parameter.UserParam8,0,255);
CHK_POTI(Parameter_ServoNickControl,EE_Parameter.ServoNickControl,0,255);
CHK_POTI(Parameter_LoopGasLimit,EE_Parameter.LoopGasLimit,0,255);
CHK_POTI(Parameter_AchsKopplung1, EE_Parameter.AchsKopplung1,0,255);
CHK_POTI(Parameter_AchsGegenKopplung1,EE_Parameter.AchsGegenKopplung1,0,255);
CHK_POTI(Parameter_DynamicStability,EE_Parameter.DynamicStability,0,255);
 
void SetCompassCalState(void)
{
static uint8_t stick = 1;
 
// if pitch is centered or top set stick to zero
if(PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > -20) stick = 0;
// if pitch is down trigger to next cal state
if((PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] < -70) && !stick)
{
stick = 1;
CompassCalState++;
if(CompassCalState < 5) Beep(CompassCalState);
else BeepTime = 1000;
}
Ki = (float) Parameter_I_Faktor * 0.0001;
MAX_GAS = EE_Parameter.Gas_Max;
MIN_GAS = EE_Parameter.Gas_Min;
}
 
 
 
/************************************************************************/
/* MotorControl */
/************************************************************************/
void MotorControl(void)
 
//############################################################################
//
void MotorRegler(void)
//############################################################################
{
int16_t MotorValue, pd_result, h, tmp_int;
int16_t YawMixFraction, ThrustMixFraction;
static int32_t SumPitch = 0, SumRoll = 0;
static int32_t SetPointYaw = 0;
static int32_t IntegralErrorPitch = 0;
static int32_t IntegralErrorRoll = 0;
static uint16_t RcLostTimer;
static uint8_t delay_neutral = 0, delay_startmotors = 0, delay_stopmotors = 0;
static uint8_t HeightControlActive = 0;
static int16_t HeightControlThrust = 0;
static int8_t TimerDebugOut = 0;
static uint16_t UpdateCompassCourse = 0;
static int32_t CorrectionPitch, CorrectionRoll;
int motorwert,pd_ergebnis,h,tmp_int;
int GierMischanteil,GasMischanteil;
static long SummeNick=0,SummeRoll=0;
static long sollGier = 0,tmp_long,tmp_long2;
static long IntegralFehlerNick = 0;
static long IntegralFehlerRoll = 0;
static unsigned int RcLostTimer;
static unsigned char delay_neutral = 0;
static unsigned char delay_einschalten = 0,delay_ausschalten = 0;
static int hoehenregler = 0;
static char TimerWerteausgabe = 0;
static char NeueKompassRichtungMerken = 0;
static long ausgleichNick, ausgleichRoll;
Mittelwert();
 
Mean();
GRN_ON;
GRN_ON;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gaswert ermitteln
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GasMischanteil = StickGas;
if(GasMischanteil < MIN_GAS + 10) GasMischanteil = MIN_GAS + 10;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Empfang schlecht
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(SenderOkay < 100)
{
if(!PcZugriff)
{
if(BeepMuster == 0xffff)
{
beeptime = 15000;
BeepMuster = 0x0c00;
}
}
if(RcLostTimer) RcLostTimer--;
else
{
MotorenEin = 0;
Notlandung = 0;
}
ROT_ON;
if(modell_fliegt > 1000) // wahrscheinlich in der Luft --> langsam absenken
{
GasMischanteil = EE_Parameter.NotGas;
Notlandung = 1;
PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] = 0;
PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] = 0;
PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] = 0;
PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] = 0;
PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] = 0;
}
else MotorenEin = 0;
}
else
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Emfang gut
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(SenderOkay > 140)
{
Notlandung = 0;
RcLostTimer = EE_Parameter.NotGasZeit * 50;
if(GasMischanteil > 40)
{
if(modell_fliegt < 0xffff) modell_fliegt++;
}
if((modell_fliegt < 256))
{
SummeNick = 0;
SummeRoll = 0;
if(modell_fliegt == 250) NeueKompassRichtungMerken = 1;
}
if((PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] > 80) && MotorenEin == 0)
{
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// auf Nullwerte kalibrieren
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75) // Neutralwerte
{
if(++delay_neutral > 200) // nicht sofort
{
GRN_OFF;
MotorenEin = 0;
delay_neutral = 0;
modell_fliegt = 0;
if(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70 || abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]) > 70)
{
unsigned char setting=1;
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > 70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < 70) setting = 1;
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > 70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70) setting = 2;
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < 70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70) setting = 3;
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] <-70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > 70) setting = 4;
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] <-70 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < 70) setting = 5;
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], setting); // aktiven Datensatz merken
}
// else
if(abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]) < 20 && PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -70)
{
WinkelOut.CalcState = 1;
beeptime = 1000;
}
else
{
ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung aktiviert?
{
if((MessLuftdruck > 950) || (MessLuftdruck < 750)) SucheLuftruckOffset();
}
SetNeutral();
Piep(GetActiveParamSetNumber());
}
}
}
else
if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] < -75) // ACC Neutralwerte speichern
{
if(++delay_neutral > 200) // nicht sofort
{
GRN_OFF;
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_NICK],0xff); // Werte löschen
MotorenEin = 0;
delay_neutral = 0;
modell_fliegt = 0;
SetNeutral();
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_NICK],NeutralAccX / 256); // ACC-NeutralWerte speichern
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_NICK+1],NeutralAccX % 256); // ACC-NeutralWerte speichern
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL],NeutralAccY / 256);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_ROLL+1],NeutralAccY % 256);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_Z],(int)NeutralAccZ / 256);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACC_Z+1],(int)NeutralAccZ % 256);
Piep(GetActiveParamSetNumber());
}
}
else delay_neutral = 0;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gas ist unten
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] < 35-120)
{
// Starten
if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] < -75)
{
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Einschalten
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(++delay_einschalten > 200)
{
delay_einschalten = 200;
modell_fliegt = 1;
MotorenEin = 1;
sollGier = 0;
Mess_Integral_Gier = 0;
Mess_Integral_Gier2 = 0;
Mess_IntegralNick = 0;
Mess_IntegralRoll = 0;
Mess_IntegralNick2 = IntegralNick;
Mess_IntegralRoll2 = IntegralRoll;
SummeNick = 0;
SummeRoll = 0;
}
}
else delay_einschalten = 0;
//Auf Neutralwerte setzen
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Auschalten
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75)
{
if(++delay_ausschalten > 200) // nicht sofort
{
MotorenEin = 0;
delay_ausschalten = 200;
modell_fliegt = 0;
}
}
else delay_ausschalten = 0;
}
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// determine thrust value
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ThrustMixFraction = StickThrust;
if(ThrustMixFraction < ParamSet.Trust_Min + 10) ThrustMixFraction = ParamSet.Trust_Min + 10;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RC-signal is bad
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(RC_Quality < 120) // the rc-frame signal is not reveived or noisy
{
if(!PcAccess) // if also no PC-Access via UART
{
if(BeepModulation == 0xFFFF)
{
BeepTime = 15000; // 1.5 seconds
BeepModulation = 0x0C00;
}
}
if(RcLostTimer) RcLostTimer--; // decremtent timer after rc sigal lost
else // rc lost countdown finished
{
MotorsOn = 0; // stop all motors
EmergencyLanding = 0; // emergency landing is over
}
ROT_ON; // set red led
if(Model_Is_Flying > 1000) // wahrscheinlich in der Luft --> langsam absenken
{
ThrustMixFraction = ParamSet.EmergencyThrust; // set emergency thrust
EmergencyLanding = 1; // enable emergency landing
// set neutral rc inputs
PPM_diff[ParamSet.ChannelAssignment[CH_PITCH]] = 0;
PPM_diff[ParamSet.ChannelAssignment[CH_ROLL]] = 0;
PPM_diff[ParamSet.ChannelAssignment[CH_YAW]] = 0;
PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] = 0;
PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] = 0;
PPM_in[ParamSet.ChannelAssignment[CH_YAW]] = 0;
}
else MotorsOn = 0; // switch of all motors
} // eof RC_Quality < 120
else
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RC-signal is good
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(RC_Quality > 140)
{
EmergencyLanding = 0; // switch off emergency landing if RC-signal is okay
// reset emergency timer
RcLostTimer = ParamSet.EmergencyThrustDuration * 50;
if(ThrustMixFraction > 40)
{
if(Model_Is_Flying < 0xFFFF) Model_Is_Flying++;
}
if(Model_Is_Flying < 256)
{
SumPitch = 0;
SumRoll = 0;
StickYaw = 0;
if(Model_Is_Flying == 250) UpdateCompassCourse = 1;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// neue Werte von der Funke
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!NewPpmData-- || Notlandung)
{
int tmp_int;
static int stick_nick,stick_roll;
ParameterZuordnung();
stick_nick = (stick_nick * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_P) / 4;
stick_nick += PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_D;
StickNick = stick_nick - (GPS_Nick + GPS_Nick2);
// StickNick = (StickNick * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_P) / 4;
 
if(Poti1 < PPM_in[ParamSet.ChannelAssignment[CH_POTI1]] + 110) Poti1++; else if(Poti1 > PPM_in[ParamSet.ChannelAssignment[CH_POTI1]] + 110 && Poti1) Poti1--;
if(Poti2 < PPM_in[ParamSet.ChannelAssignment[CH_POTI2]] + 110) Poti2++; else if(Poti2 > PPM_in[ParamSet.ChannelAssignment[CH_POTI2]] + 110 && Poti2) Poti2--;
if(Poti3 < PPM_in[ParamSet.ChannelAssignment[CH_POTI3]] + 110) Poti3++; else if(Poti3 > PPM_in[ParamSet.ChannelAssignment[CH_POTI3]] + 110 && Poti3) Poti3--;
if(Poti4 < PPM_in[ParamSet.ChannelAssignment[CH_POTI4]] + 110) Poti4++; else if(Poti4 > PPM_in[ParamSet.ChannelAssignment[CH_POTI4]] + 110 && Poti4) Poti4--;
//PPM24-Extension
if(Poti5 < PPM_in[9] + 110) Poti5++; else if(Poti5 > PPM_in[9] + 110 && Poti5) Poti5--;
if(Poti6 < PPM_in[10] + 110) Poti6++; else if(Poti6 > PPM_in[10] + 110 && Poti6) Poti6--;
if(Poti7 < PPM_in[11] + 110) Poti7++; else if(Poti7 > PPM_in[11] + 110 && Poti7) Poti7--;
if(Poti8 < PPM_in[12] + 110) Poti8++; else if(Poti8 > PPM_in[12] + 110 && Poti8) Poti8--;
//limit poti values
if(Poti1 < 0) Poti1 = 0; else if(Poti1 > 255) Poti1 = 255;
if(Poti2 < 0) Poti2 = 0; else if(Poti2 > 255) Poti2 = 255;
if(Poti3 < 0) Poti3 = 0; else if(Poti3 > 255) Poti3 = 255;
if(Poti4 < 0) Poti4 = 0; else if(Poti4 > 255) Poti4 = 255;
//PPM24-Extension
if(Poti5 < 0) Poti5 = 0; else if(Poti5 > 255) Poti5 = 255;
if(Poti6 < 0) Poti6 = 0; else if(Poti6 > 255) Poti6 = 255;
if(Poti7 < 0) Poti7 = 0; else if(Poti7 > 255) Poti7 = 255;
if(Poti8 < 0) Poti8 = 0; else if(Poti8 > 255) Poti8 = 255;
stick_roll = (stick_roll * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_P) / 4;
stick_roll += PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_D;
StickRoll = stick_roll - (GPS_Roll + GPS_Roll2);
 
// if motors are off and the thrust stick is in the upper position
if((PPM_in[ParamSet.ChannelAssignment[CH_THRUST]] > 80) && MotorsOn == 0)
{
// and if the yaw stick is in the leftmost position
if(PPM_in[ParamSet.ChannelAssignment[CH_YAW]] > 75)
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// calibrate the neutral readings of all attitude sensors
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{
// thrust/yaw joystick is top left
// _________
// |x |
// | |
// | |
// | |
// | |
// ¯¯¯¯¯¯¯¯¯
if(++delay_neutral > 200) // not immediately (wait 200 loops = 200 * 2ms = 0.4 s)
{
delay_neutral = 0;
GRN_OFF;
Model_Is_Flying = 0;
// check roll/pitch stick position
// if pitch stick is top or roll stick is left or right --> change parameter setting
// according to roll/pitch stick position
if(PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > 70 || abs(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]]) > 70)
{
uint8_t setting = 1; // default
// pitch/roll joystick
// _________
// |2 3 4|
// | |
// |1 5|
// | |
// | |
// ¯¯¯¯¯¯¯¯¯
// roll stick leftmost and pitch stick centered --> setting 1
if(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] > 70 && PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] < 70) setting = 1;
// roll stick leftmost and pitch stick topmost --> setting 2
if(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] > 70 && PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > 70) setting = 2;
// roll stick centered an pitch stick topmost --> setting 3
if(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] < 70 && PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > 70) setting = 3;
// roll stick rightmost and pitch stick topmost --> setting 4
if(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] <-70 && PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > 70) setting = 4;
// roll stick rightmost and pitch stick centered --> setting 5
if(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] <-70 && PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] < 70) setting = 5;
// update active parameter set in eeprom
SetActiveParamSet(setting);
ParamSet_ReadFromEEProm(GetActiveParamSet());
SetNeutral();
Beep(GetActiveParamSet());
}
else
{
if((ParamSet.GlobalConfig & CFG_COMPASS_ACTIVE))
{
// if roll stick is centered and pitch stick is down
if (abs(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]]) < 20 && PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] < -70)
{
// pitch/roll joystick
// _________
// | |
// | |
// | |
// | |
// | x |
// ¯¯¯¯¯¯¯¯¯
// enable calibration state of compass
CompassCalState = 1;
BeepTime = 1000;
}
else // pitch and roll are centered
{
ParamSet_ReadFromEEProm(GetActiveParamSet());
SetNeutral();
Beep(GetActiveParamSet());
}
}
else // pitch and roll are centered
{
ParamSet_ReadFromEEProm(GetActiveParamSet());
SetNeutral();
Beep(GetActiveParamSet());
}
}
}
}
// and if the yaw stick is in the rightmost position
// save the ACC neutral setting to eeprom
else if(PPM_in[ParamSet.ChannelAssignment[CH_YAW]] < -75)
{
if(++delay_neutral > 200) // not immediately (wait 200 loops = 200 * 2ms = 0.4 s)
{
delay_neutral = 0;
GRN_OFF;
SetParamWord(PID_ACC_PITCH, 0xFFFF); // make value invalid
Model_Is_Flying = 0;
SetNeutral();
// Save ACC neutral settings to eeprom
SetParamWord(PID_ACC_PITCH, (uint16_t)NeutralAccX);
SetParamWord(PID_ACC_ROLL, (uint16_t)NeutralAccY);
SetParamWord(PID_ACC_Z, (uint16_t)NeutralAccZ);
Beep(GetActiveParamSet());
}
}
else delay_neutral = 0;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// thrust stick is down
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(PPM_in[ParamSet.ChannelAssignment[CH_THRUST]] < -85)
{
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// and yaw stick is rightmost --> start motors
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(PPM_in[ParamSet.ChannelAssignment[CH_YAW]] < -75)
{
if(++delay_startmotors > 200) // not immediately (wait 200 loops = 200 * 2ms = 0.4 s)
{
delay_startmotors = 200; // do not repeat if once executed
Model_Is_Flying = 1;
MotorsOn = 1;
SetPointYaw = 0;
Reading_IntegralGyroYaw = 0;
Reading_IntegralGyroPitch = 0;
Reading_IntegralGyroRoll = 0;
Reading_IntegralGyroPitch2 = IntegralPitch;
Reading_IntegralGyroRoll2 = IntegralRoll;
SumPitch = 0;
SumRoll = 0;
#ifdef USE_KILLAGREG
if(ParamSet.GlobalConfig & CFG_GPS_ACTIVE)
{
GPS_SetHomePosition();
}
#endif
}
}
else delay_startmotors = 0; // reset delay timer if sticks are not in this position
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// and yaw stick is leftmost --> stop motors
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(PPM_in[ParamSet.ChannelAssignment[CH_YAW]] > 75)
{
if(++delay_stopmotors > 200) // not immediately (wait 200 loops = 200 * 2ms = 0.4 s)
{
delay_stopmotors = 200; // do not repeat if once executed
Model_Is_Flying = 0;
MotorsOn = 0;
#ifdef USE_KILLAGREG
if(ParamSet.GlobalConfig & CFG_GPS_ACTIVE)
{
GPS_ClearHomePosition();
}
#endif
}
}
else delay_stopmotors = 0; // reset delay timer if sticks are not in this position
}
// remapping of paameters only if the signal rc-sigbnal conditions are good
} // eof RC_Quality > 150
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// new values from RC
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!NewPpmData-- || EmergencyLanding) // NewData = 0 means new data from RC
{
int tmp_int;
ParameterMapping(); // remapping params (online poti replacement)
// calculate Stick inputs by rc channels (P) and changing of rc channels (D)
StickPitch = (StickPitch * 3 + PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] * ParamSet.Stick_P) / 4;
StickPitch += PPM_diff[ParamSet.ChannelAssignment[CH_PITCH]] * ParamSet.Stick_D;
StickPitch -= (GPS_Pitch);
// StickRoll = (StickRoll * 3 + PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_P) / 4;
 
StickRoll = (StickRoll * 3 + PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] * ParamSet.Stick_P) / 4;
StickRoll += PPM_diff[ParamSet.ChannelAssignment[CH_ROLL]] * ParamSet.Stick_D;
StickRoll -= (GPS_Roll);
StickGier = -PPM_in[EE_Parameter.Kanalbelegung[K_GIER]];
StickGas = PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] + 120;
 
// direct mapping of yaw and thrust
StickYaw = -PPM_in[ParamSet.ChannelAssignment[CH_YAW]];
StickThrust = PPM_in[ParamSet.ChannelAssignment[CH_THRUST]] + 120;// shift to positive numbers
/* if(abs(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]]) > MaxStickNick)
MaxStickNick = abs(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]]); else MaxStickNick--;
if(abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]) > MaxStickRoll)
MaxStickRoll = abs(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]); else MaxStickRoll--;
*/
GyroFaktor = ((float)Parameter_Gyro_P + 10.0) / (256.0/STICK_GAIN);
IntegralFaktor = ((float) Parameter_Gyro_I) / (44000 / STICK_GAIN);
 
// update gyro control loop factors
Gyro_P_Factor = ((float) FCParam.Gyro_P + 10.0) / (256.0 / STICK_GAIN);
Gyro_I_Factor = ((float) FCParam.Gyro_I) / (44000 / STICK_GAIN);
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Digital Control via DubWise
//+ Digitale Steuerung per DubWise
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define KEY_VALUE (Parameter_UserParam8 * 4) //(Poti3 * 8)
if(DubWiseKeys[1]) beeptime = 10;
if(DubWiseKeys[1] & DUB_KEY_UP) tmp_int = KEY_VALUE; else
if(DubWiseKeys[1] & DUB_KEY_DOWN) tmp_int = -KEY_VALUE; else tmp_int = 0;
ExternStickNick = (ExternStickNick * 7 + tmp_int) / 8;
if(DubWiseKeys[1] & DUB_KEY_LEFT) tmp_int = KEY_VALUE; else
if(DubWiseKeys[1] & DUB_KEY_RIGHT) tmp_int = -KEY_VALUE; else tmp_int = 0;
ExternStickRoll = (ExternStickRoll * 7 + tmp_int) / 8;
 
#define KEY_VALUE (FCParam.UserParam8 * 4) // step width
if(DubWiseKeys[1]) BeepTime = 10;
if(DubWiseKeys[1] & DUB_KEY_UP) tmp_int = KEY_VALUE;
else if(DubWiseKeys[1] & DUB_KEY_DOWN) tmp_int = -KEY_VALUE;
else tmp_int = 0;
ExternStickPitch = (ExternStickPitch * 7 + tmp_int) / 8;
if(DubWiseKeys[1] & DUB_KEY_LEFT) tmp_int = KEY_VALUE;
else if(DubWiseKeys[1] & DUB_KEY_RIGHT) tmp_int = -KEY_VALUE;
else tmp_int = 0;
ExternStickRoll = (ExternStickRoll * 7 + tmp_int) / 8;
if(DubWiseKeys[0] & 8) ExternStickGier = 50;else
if(DubWiseKeys[0] & 4) ExternStickGier =-50;else ExternStickGier = 0;
if(DubWiseKeys[0] & 2) ExternHoehenValue++;
if(DubWiseKeys[0] & 16) ExternHoehenValue--;
 
if(DubWiseKeys[0] & 8) ExternStickYaw = 50;else
if(DubWiseKeys[0] & 4) ExternStickYaw =-50;else ExternStickYaw = 0;
if(DubWiseKeys[0] & 2) ExternHeightValue++;
if(DubWiseKeys[0] & 16) ExternHeightValue--;
 
StickPitch += (STICK_GAIN * ExternStickPitch) / 8;
StickRoll += (STICK_GAIN * ExternStickRoll) / 8;
StickYaw += (STICK_GAIN * ExternStickYaw);
 
StickNick += (STICK_GAIN * ExternStickNick) / 8;
StickRoll += (STICK_GAIN * ExternStickRoll) / 8;
StickGier += STICK_GAIN * ExternStickGier;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ Analog control via serial communication
//+ Analoge Steuerung per Seriell
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(ExternControl.Config & 0x01 && Parameter_UserParam8 > 128)
{
StickNick += (int) ExternControl.Nick * (int) EE_Parameter.Stick_P;
StickRoll += (int) ExternControl.Roll * (int) EE_Parameter.Stick_P;
StickGier += ExternControl.Gier;
ExternHoehenValue = (int) ExternControl.Hight * (int)EE_Parameter.Hoehe_Verstaerkung;
if(ExternControl.Gas < StickGas) StickGas = ExternControl.Gas;
}
if(StickGas < 0) StickGas = 0;
 
if(ExternControl.Config & 0x01 && FCParam.UserParam8 > 128)
{
StickPitch += (int16_t) ExternControl.Pitch * (int16_t) ParamSet.Stick_P;
StickRoll += (int16_t) ExternControl.Roll * (int16_t) ParamSet.Stick_P;
StickYaw += ExternControl.Yaw;
ExternHeightValue = (int16_t) ExternControl.Height * (int16_t)ParamSet.Height_Gain;
if(ExternControl.Thrust < StickThrust) StickThrust = ExternControl.Thrust;
}
if(StickThrust < 0) StickThrust = 0;
if(EE_Parameter.GlobalConfig & CFG_HEADING_HOLD) IntegralFaktor = 0;
if(GyroFaktor < 0) GyroFaktor = 0;
if(IntegralFaktor < 0) IntegralFaktor = 0;
 
// disable I part of gyro control feedback
if(ParamSet.GlobalConfig & CFG_HEADING_HOLD) Gyro_I_Factor = 0;
// avoid negative scaling factors
if(Gyro_P_Factor < 0) Gyro_P_Factor = 0;
if(Gyro_I_Factor < 0) Gyro_I_Factor = 0;
if(abs(StickNick/STICK_GAIN) > MaxStickNick) MaxStickNick = abs(StickNick)/STICK_GAIN; else MaxStickNick--;
if(abs(StickRoll/STICK_GAIN) > MaxStickRoll) MaxStickRoll = abs(StickRoll)/STICK_GAIN; else MaxStickRoll--;
if(Notlandung) {MaxStickNick = 0; MaxStickRoll = 0;}
 
 
// update max stick positions for pitch and roll
 
if(abs(StickPitch / STICK_GAIN) > MaxStickPitch) MaxStickPitch = abs(StickPitch)/STICK_GAIN;
else MaxStickPitch--;
if(abs(StickRoll / STICK_GAIN) > MaxStickRoll) MaxStickRoll = abs(StickRoll)/STICK_GAIN;
else MaxStickRoll--;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Looping?
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > EE_Parameter.LoopThreshold) && EE_Parameter.LoopConfig & CFG_LOOP_LINKS) Looping_Links = 1;
else
{
{
if((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < (EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese))) Looping_Links = 0;
}
}
if((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < -EE_Parameter.LoopThreshold) && EE_Parameter.LoopConfig & CFG_LOOP_RECHTS) Looping_Rechts = 1;
else
{
if(Looping_Rechts) // Hysterese
{
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > -(EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese)) Looping_Rechts = 0;
}
}
 
if((PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] > ParamSet.LoopThreshold) && ParamSet.LoopConfig & CFG_LOOP_LEFT) Looping_Left = 1;
else
{
if(Looping_Left) // Hysteresis
{
if((PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] < (ParamSet.LoopThreshold - ParamSet.LoopHysteresis))) Looping_Left = 0;
}
}
if((PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] < -ParamSet.LoopThreshold) && ParamSet.LoopConfig & CFG_LOOP_RIGHT) Looping_Right = 1;
else
{
if(Looping_Right) // Hysteresis
{
if(PPM_in[ParamSet.ChannelAssignment[CH_ROLL]] > -(ParamSet.LoopThreshold - ParamSet.LoopHysteresis)) Looping_Right = 0;
}
}
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > EE_Parameter.LoopThreshold) && EE_Parameter.LoopConfig & CFG_LOOP_OBEN) Looping_Oben = 1;
else
{
if(Looping_Oben) // Hysterese
{
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < (EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese))) Looping_Oben = 0;
}
}
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -EE_Parameter.LoopThreshold) && EE_Parameter.LoopConfig & CFG_LOOP_UNTEN) Looping_Unten = 1;
else
{
if(Looping_Unten) // Hysterese
{
if(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > -(EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese)) Looping_Unten = 0;
}
}
 
if((PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > ParamSet.LoopThreshold) && ParamSet.LoopConfig & CFG_LOOP_UP) Looping_Top = 1;
else
{
if(Looping_Top) // Hysteresis
{
if((PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] < (ParamSet.LoopThreshold - ParamSet.LoopHysteresis))) Looping_Top = 0;
}
}
if((PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] < -ParamSet.LoopThreshold) && ParamSet.LoopConfig & CFG_LOOP_DOWN) Looping_Down = 1;
else
{
if(Looping_Down) // Hysteresis
{
if(PPM_in[ParamSet.ChannelAssignment[CH_PITCH]] > -(ParamSet.LoopThreshold - ParamSet.LoopHysteresis)) Looping_Down = 0;
}
}
if(Looping_Links || Looping_Rechts) Looping_Roll = 1; else Looping_Roll = 0;
if(Looping_Oben || Looping_Unten) {Looping_Nick = 1; Looping_Roll = 0; Looping_Links = 0; Looping_Rechts = 0;} else Looping_Nick = 0;
} // Ende neue Funken-Werte
 
if(Looping_Left || Looping_Right) Looping_Roll = 1; else Looping_Roll = 0;
if(Looping_Top || Looping_Down) {Looping_Pitch = 1; Looping_Roll = 0; Looping_Left = 0; Looping_Right = 0;} else Looping_Pitch = 0;
} // End of new RC-Values or Emergency Landing
if(Looping_Roll) beeptime = 100;
if(Looping_Roll || Looping_Nick)
{
if(GasMischanteil > EE_Parameter.LoopGasLimit) GasMischanteil = EE_Parameter.LoopGasLimit;
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Bei Empfangsausfall im Flug
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(Notlandung)
{
StickGier = 0;
StickNick = 0;
StickRoll = 0;
GyroFaktor = (float) 100 / (256.0 / STICK_GAIN);
IntegralFaktor = (float) 120 / (44000 / STICK_GAIN);
Looping_Roll = 0;
Looping_Nick = 0;
}
 
if(Looping_Roll) BeepTime = 100;
if(Looping_Roll || Looping_Pitch)
{
if(ThrustMixFraction > ParamSet.LoopThrustLimit) ThrustMixFraction = ParamSet.LoopThrustLimit;
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Integrale auf ACC-Signal abgleichen
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define ABGLEICH_ANZAHL 256L
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ LED Control on J16/J17
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LED1_Time = FCParam.UserParam7;
LED2_Time = FCParam.UserParam8;
LED_Update();
MittelIntegralNick += IntegralNick; // Für die Mittelwertbildung aufsummieren
MittelIntegralRoll += IntegralRoll;
MittelIntegralNick2 += IntegralNick2;
MittelIntegralRoll2 += IntegralRoll2;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// in case of emergency landing
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// set all inputs to save values
if(EmergencyLanding)
{
StickYaw = 0;
StickPitch = 0;
StickRoll = 0;
Gyro_P_Factor = (float) 100 / (256.0 / STICK_GAIN);
Gyro_I_Factor = (float) 120 / (44000 / STICK_GAIN);
Looping_Roll = 0;
Looping_Pitch = 0;
MaxStickPitch = 0;
MaxStickRoll = 0;
}
if(Looping_Nick || Looping_Roll)
{
IntegralAccNick = 0;
IntegralAccRoll = 0;
MittelIntegralNick = 0;
MittelIntegralRoll = 0;
MittelIntegralNick2 = 0;
MittelIntegralRoll2 = 0;
Mess_IntegralNick2 = Mess_IntegralNick;
Mess_IntegralRoll2 = Mess_IntegralRoll;
ZaehlMessungen = 0;
LageKorrekturNick = 0;
LageKorrekturRoll = 0;
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Trim Gyro-Integrals to ACC-Signals
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!Looping_Nick && !Looping_Roll)
{
long tmp_long, tmp_long2;
tmp_long = (long)(IntegralNick / EE_Parameter.GyroAccFaktor - (long)Mittelwert_AccNick);
tmp_long2 = (long)(IntegralRoll / EE_Parameter.GyroAccFaktor - (long)Mittelwert_AccRoll);
tmp_long /= 16;
tmp_long2 /= 16;
if((MaxStickNick > 32) || (MaxStickRoll > 32))
{
tmp_long /= 3;
tmp_long2 /= 3;
}
if(abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]) > 25)
{
tmp_long /= 3;
tmp_long2 /= 3;
}
 
#define BALANCE_NUMBER 256L
// sum for averaging
MeanIntegralPitch += IntegralPitch;
MeanIntegralRoll += IntegralRoll;
#define AUSGLEICH 32
if(tmp_long > AUSGLEICH) tmp_long = AUSGLEICH;
if(tmp_long < -AUSGLEICH) tmp_long =-AUSGLEICH;
if(tmp_long2 > AUSGLEICH) tmp_long2 = AUSGLEICH;
if(tmp_long2 <-AUSGLEICH) tmp_long2 =-AUSGLEICH;
 
if(Looping_Pitch || Looping_Roll) // if looping in any direction
{
// reset averaging for acc and gyro integral as well as gyro integral acc correction
MeasurementCounter = 0;
Mess_IntegralNick -= tmp_long;
Mess_IntegralRoll -= tmp_long2;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
IntegralAccPitch = 0;
IntegralAccRoll = 0;
if(ZaehlMessungen >= ABGLEICH_ANZAHL)
{
static int cnt = 0;
static char last_n_p,last_n_n,last_r_p,last_r_n;
static long MittelIntegralNick_Alt,MittelIntegralRoll_Alt;
if(!Looping_Nick && !Looping_Roll && !TrichterFlug)
{
MittelIntegralNick /= ABGLEICH_ANZAHL;
MittelIntegralRoll /= ABGLEICH_ANZAHL;
IntegralAccNick = (EE_Parameter.GyroAccFaktor * IntegralAccNick) / ABGLEICH_ANZAHL;
IntegralAccRoll = (EE_Parameter.GyroAccFaktor * IntegralAccRoll) / ABGLEICH_ANZAHL;
IntegralAccZ = IntegralAccZ / ABGLEICH_ANZAHL;
#define MAX_I 0//(Poti2/10)
// Nick ++++++++++++++++++++++++++++++++++++++++++++++++
IntegralFehlerNick = (long)(MittelIntegralNick - (long)IntegralAccNick);
ausgleichNick = IntegralFehlerNick / EE_Parameter.GyroAccAbgleich;
// Roll ++++++++++++++++++++++++++++++++++++++++++++++++
IntegralFehlerRoll = (long)(MittelIntegralRoll - (long)IntegralAccRoll);
ausgleichRoll = IntegralFehlerRoll / EE_Parameter.GyroAccAbgleich;
 
MeanIntegralPitch = 0;
MeanIntegralRoll = 0;
LageKorrekturNick = ausgleichNick / ABGLEICH_ANZAHL;
LageKorrekturRoll = ausgleichRoll / ABGLEICH_ANZAHL;
 
Reading_IntegralGyroPitch2 = Reading_IntegralGyroPitch;
Reading_IntegralGyroRoll2 = Reading_IntegralGyroRoll;
if((MaxStickNick > 32) || (MaxStickRoll > 32) || (abs(PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]) > 25))
{
LageKorrekturNick /= 2;
LageKorrekturRoll /= 2;
}
 
AttitudeCorrectionPitch = 0;
AttitudeCorrectionRoll = 0;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gyro-Drift ermitteln
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MittelIntegralNick2 /= ABGLEICH_ANZAHL;
MittelIntegralRoll2 /= ABGLEICH_ANZAHL;
tmp_long = IntegralNick2 - IntegralNick;
tmp_long2 = IntegralRoll2 - IntegralRoll;
//DebugOut.Analog[25] = MittelIntegralRoll2 / 26;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!Looping_Pitch && !Looping_Roll) // if not lopping in any direction
{
int32_t tmp_long, tmp_long2;
// determine the deviation of gyro integral from averaged acceleration sensor
tmp_long = (int32_t)(IntegralPitch / ParamSet.GyroAccFactor - (int32_t)Mean_AccPitch);
tmp_long /= 16;
tmp_long2 = (int32_t)(IntegralRoll / ParamSet.GyroAccFactor - (int32_t)Mean_AccRoll);
tmp_long2 /= 16;
IntegralFehlerNick = tmp_long;
IntegralFehlerRoll = tmp_long2;
Mess_IntegralNick2 -= IntegralFehlerNick;
Mess_IntegralRoll2 -= IntegralFehlerRoll;
 
if((MaxStickPitch > 32) || (MaxStickRoll > 32)) // reduce effect during stick commands
{
tmp_long /= 3;
tmp_long2 /= 3;
}
if(abs(PPM_in[ParamSet.ChannelAssignment[CH_YAW]]) > 25) // reduce further if yaw stick is active
{
tmp_long /= 3;
tmp_long2 /= 3;
}
// IntegralFehlerNick = (IntegralFehlerNick * 1 + tmp_long) / 2;
// IntegralFehlerRoll = (IntegralFehlerRoll * 1 + tmp_long2) / 2;
if(GierGyroFehler > ABGLEICH_ANZAHL/2) AdNeutralGier++;
if(GierGyroFehler <-ABGLEICH_ANZAHL/2) AdNeutralGier--;
 
#define BALANCE 32
// limit correction effect
if(tmp_long > BALANCE) tmp_long = BALANCE;
if(tmp_long < -BALANCE) tmp_long =-BALANCE;
if(tmp_long2 > BALANCE) tmp_long2 = BALANCE;
if(tmp_long2 <-BALANCE) tmp_long2 =-BALANCE;
// correct current readings
Reading_IntegralGyroPitch -= tmp_long;
Reading_IntegralGyroRoll -= tmp_long2;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// MeasurementCounter is incremented in the isr of analog.c
if(MeasurementCounter >= BALANCE_NUMBER) // averaging number has reached
{
static int16_t cnt = 0;
static int8_t last_n_p, last_n_n, last_r_p, last_r_n;
static int32_t MeanIntegralPitch_old, MeanIntegralRoll_old;
DebugOut.Analog[22] = MittelIntegralRoll / 26;
 
// if not lopping in any direction (this should be alwais the case,
// because the Measurement counter is reset to 0 if looping in any direction is active.)
if(!Looping_Pitch && !Looping_Roll && !FunnelCourse)
{
// Calculate mean value of the gyro integrals
MeanIntegralPitch /= BALANCE_NUMBER;
MeanIntegralRoll /= BALANCE_NUMBER;
GierGyroFehler = 0;
 
// Calculate mean of the acceleration values
IntegralAccPitch = (ParamSet.GyroAccFactor * IntegralAccPitch) / BALANCE_NUMBER;
IntegralAccRoll = (ParamSet.GyroAccFactor * IntegralAccRoll ) / BALANCE_NUMBER;
 
// Pitch ++++++++++++++++++++++++++++++++++++++++++++++++
// Calculate deviation of the averaged gyro integral and the averaged acceleration integral
IntegralErrorPitch = (int32_t)(MeanIntegralPitch - (int32_t)IntegralAccPitch);
CorrectionPitch = IntegralErrorPitch / ParamSet.GyroAccTrim;
AttitudeCorrectionPitch = CorrectionPitch / BALANCE_NUMBER;
// Roll ++++++++++++++++++++++++++++++++++++++++++++++++
// Calculate deviation of the averaged gyro integral and the averaged acceleration integral
IntegralErrorRoll = (int32_t)(MeanIntegralRoll - (int32_t)IntegralAccRoll);
CorrectionRoll = IntegralErrorRoll / ParamSet.GyroAccTrim;
AttitudeCorrectionRoll = CorrectionRoll / BALANCE_NUMBER;
 
if((MaxStickPitch > 32) || (MaxStickRoll > 32) || (abs(PPM_in[ParamSet.ChannelAssignment[CH_YAW]]) > 25))
{
AttitudeCorrectionPitch /= 2;
AttitudeCorrectionRoll /= 2;
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gyro-Drift ermitteln
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// deviation of gyro pitch integral (IntegralPitch is corrected by averaged acc sensor)
IntegralErrorPitch = IntegralPitch2 - IntegralPitch;
Reading_IntegralGyroPitch2 -= IntegralErrorPitch;
// deviation of gyro pitch integral (IntegralPitch is corrected by averaged acc sensor)
IntegralErrorRoll = IntegralRoll2 - IntegralRoll;
Reading_IntegralGyroRoll2 -= IntegralErrorRoll;
 
if(YawGyroDrift > BALANCE_NUMBER/2) AdNeutralYaw++;
if(YawGyroDrift < -BALANCE_NUMBER/2) AdNeutralYaw--;
YawGyroDrift = 0;
/*
DebugOut.Analog[17] = IntegralAccPitch / 26;
DebugOut.Analog[18] = IntegralAccRoll / 26;
DebugOut.Analog[19] = IntegralErrorPitch;// / 26;
DebugOut.Analog[20] = IntegralErrorRoll;// / 26;
DebugOut.Analog[21] = MeanIntegralPitch / 26;
DebugOut.Analog[22] = MeanIntegralRoll / 26;
//DebugOut.Analog[28] = CorrectionPitch;
DebugOut.Analog[29] = CorrectionRoll;
DebugOut.Analog[30] = AttitudeCorrectionRoll * 10;
/*DebugOut.Analog[17] = IntegralAccNick / 26;
DebugOut.Analog[18] = IntegralAccRoll / 26;
DebugOut.Analog[19] = IntegralFehlerNick;// / 26;
DebugOut.Analog[20] = IntegralFehlerRoll;// / 26;
*/
 
#define ERROR_LIMIT (BALANCE_NUMBER * 4)
#define ERROR_LIMIT2 (BALANCE_NUMBER * 16)
#define MOVEMENT_LIMIT 20000
// Pitch +++++++++++++++++++++++++++++++++++++++++++++++++
cnt = 1;// + labs(IntegralErrorPitch) / 4096;
CorrectionPitch = 0;
if(labs(MeanIntegralPitch_old - MeanIntegralPitch) < MOVEMENT_LIMIT)
{
if(IntegralErrorPitch > ERROR_LIMIT2)
{
if(last_n_p)
{
cnt += labs(IntegralErrorPitch) / ERROR_LIMIT2;
CorrectionPitch = IntegralErrorPitch / 8;
if(CorrectionPitch > 5000) CorrectionPitch = 5000;
AttitudeCorrectionPitch += CorrectionPitch / BALANCE_NUMBER;
}
else last_n_p = 1;
}
else last_n_p = 0;
if(IntegralErrorPitch < -ERROR_LIMIT2)
{
if(last_n_n)
{
cnt += labs(IntegralErrorPitch) / ERROR_LIMIT2;
CorrectionPitch = IntegralErrorPitch / 8;
if(CorrectionPitch < -5000) CorrectionPitch = -5000;
AttitudeCorrectionPitch += CorrectionPitch / BALANCE_NUMBER;
}
else last_n_n = 1;
}
else last_n_n = 0;
}
else
{
cnt = 0;
BadCompassHeading = 500;
}
if(cnt > ParamSet.DriftComp) cnt = ParamSet.DriftComp;
// correct Gyro Offsets
if(IntegralErrorPitch > ERROR_LIMIT) AdNeutralPitch += cnt;
if(IntegralErrorPitch < -ERROR_LIMIT) AdNeutralPitch -= cnt;
 
// Roll +++++++++++++++++++++++++++++++++++++++++++++++++
cnt = 1;// + labs(IntegralErrorPitch) / 4096;
CorrectionRoll = 0;
if(labs(MeanIntegralRoll_old - MeanIntegralRoll) < MOVEMENT_LIMIT)
{
if(IntegralErrorRoll > ERROR_LIMIT2)
{
if(last_r_p)
{
cnt += labs(IntegralErrorRoll) / ERROR_LIMIT2;
CorrectionRoll = IntegralErrorRoll / 8;
if(CorrectionRoll > 5000) CorrectionRoll = 5000;
AttitudeCorrectionRoll += CorrectionRoll / BALANCE_NUMBER;
}
else last_r_p = 1;
}
else last_r_p = 0;
if(IntegralErrorRoll < -ERROR_LIMIT2)
{
if(last_r_n)
{
cnt += labs(IntegralErrorRoll) / ERROR_LIMIT2;
CorrectionRoll = IntegralErrorRoll / 8;
if(CorrectionRoll < -5000) CorrectionRoll = -5000;
AttitudeCorrectionRoll += CorrectionRoll / BALANCE_NUMBER;
}
else last_r_n = 1;
}
else last_r_n = 0;
}
else
{
cnt = 0;
BadCompassHeading = 500;
}
// correct Gyro Offsets
if(cnt > ParamSet.DriftComp) cnt = ParamSet.DriftComp;
if(IntegralErrorRoll > ERROR_LIMIT) AdNeutralRoll += cnt;
if(IntegralErrorRoll < -ERROR_LIMIT) AdNeutralRoll -= cnt;
//DebugOut.Analog[21] = MittelIntegralNick / 26;
//MittelIntegralRoll = MittelIntegralRoll;
//DebugOut.Analog[28] = ausgleichNick;
/*
DebugOut.Analog[27] = CorrectionRoll;
DebugOut.Analog[23] = AdNeutralPitch;//10*(AdNeutralPitch - StartNeutralPitch);
DebugOut.Analog[24] = 10*(AdNeutralRoll - StartNeutralRoll);
DebugOut.Analog[29] = ausgleichRoll;
DebugOut.Analog[30] = LageKorrekturRoll * 10;
*/
}
else // looping is active
{
AttitudeCorrectionRoll = 0;
AttitudeCorrectionPitch = 0;
FunnelCourse = 0;
}
 
// if Gyro_I_Factor == 0 , for example at Heading Hold, ignore attitude correction
if(!Gyro_I_Factor)
{
AttitudeCorrectionRoll = 0;
AttitudeCorrectionPitch = 0;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++
MeanIntegralPitch_old = MeanIntegralPitch;
MeanIntegralRoll_old = MeanIntegralRoll;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++
// reset variables used for averaging
IntegralAccPitch = 0;
IntegralAccRoll = 0;
MeanIntegralPitch = 0;
MeanIntegralRoll = 0;
MeasurementCounter = 0;
} // end of averaging
#define FEHLER_LIMIT (ABGLEICH_ANZAHL * 4)
#define FEHLER_LIMIT2 (ABGLEICH_ANZAHL * 16)
#define BEWEGUNGS_LIMIT 20000
// Nick +++++++++++++++++++++++++++++++++++++++++++++++++
cnt = 1;// + labs(IntegralFehlerNick) / 4096;
if(labs(MittelIntegralNick_Alt - MittelIntegralNick) < BEWEGUNGS_LIMIT)
{
if(IntegralFehlerNick > FEHLER_LIMIT2)
{
if(last_n_p)
{
cnt += labs(IntegralFehlerNick) / FEHLER_LIMIT2;
ausgleichNick = IntegralFehlerNick / 8;
if(ausgleichNick > 5000) ausgleichNick = 5000;
LageKorrekturNick += ausgleichNick / ABGLEICH_ANZAHL;
}
else last_n_p = 1;
} else last_n_p = 0;
if(IntegralFehlerNick < -FEHLER_LIMIT2)
{
if(last_n_n)
{
cnt += labs(IntegralFehlerNick) / FEHLER_LIMIT2;
ausgleichNick = IntegralFehlerNick / 8;
if(ausgleichNick < -5000) ausgleichNick = -5000;
LageKorrekturNick += ausgleichNick / ABGLEICH_ANZAHL;
}
else last_n_n = 1;
} else last_n_n = 0;
}
else
{
cnt = 0;
KompassSignalSchlecht = 500;
}
if(cnt > EE_Parameter.Driftkomp) cnt = EE_Parameter.Driftkomp;
if(IntegralFehlerNick > FEHLER_LIMIT) AdNeutralNick += cnt;
if(IntegralFehlerNick < -FEHLER_LIMIT) AdNeutralNick -= cnt;
 
// Roll +++++++++++++++++++++++++++++++++++++++++++++++++
cnt = 1;// + labs(IntegralFehlerNick) / 4096;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Yawing
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(abs(StickYaw) > 15 ) // yaw stick is activated
{
if(!(ParamSet.GlobalConfig & CFG_COMPASS_FIX))
{
UpdateCompassCourse = 1;
CompassCourse = YawGyroHeading;
BadCompassHeading = 250;
}
}
// exponential stick sensitivity in yawring rate
tmp_int = (int32_t) ParamSet.Yaw_P * ((int32_t)StickYaw * abs(StickYaw)) / 512L; // expo y = ax + bx²
tmp_int += (ParamSet.Yaw_P * StickYaw) / 4;
SetPointYaw = tmp_int;
// trimm drift of Reading_IntegralGyroYaw with SetPointYaw(StickYaw)
Reading_IntegralGyroYaw -= tmp_int;
// limit the effect
if(Reading_IntegralGyroYaw > 50000) Reading_IntegralGyroYaw = 50000;
if(Reading_IntegralGyroYaw <-50000) Reading_IntegralGyroYaw =-50000;
ausgleichRoll = 0;
if(labs(MittelIntegralRoll_Alt - MittelIntegralRoll) < BEWEGUNGS_LIMIT)
{
if(IntegralFehlerRoll > FEHLER_LIMIT2)
{
if(last_r_p)
{
cnt += labs(IntegralFehlerRoll) / FEHLER_LIMIT2;
ausgleichRoll = IntegralFehlerRoll / 8;
if(ausgleichRoll > 5000) ausgleichRoll = 5000;
LageKorrekturRoll += ausgleichRoll / ABGLEICH_ANZAHL;
}
else last_r_p = 1;
} else last_r_p = 0;
if(IntegralFehlerRoll < -FEHLER_LIMIT2)
{
if(last_r_n)
{
cnt += labs(IntegralFehlerRoll) / FEHLER_LIMIT2;
ausgleichRoll = IntegralFehlerRoll / 8;
if(ausgleichRoll < -5000) ausgleichRoll = -5000;
LageKorrekturRoll += ausgleichRoll / ABGLEICH_ANZAHL;
}
else last_r_n = 1;
} else last_r_n = 0;
} else
{
cnt = 0;
KompassSignalSchlecht = 500;
}
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Compass
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// compass code is used if Compass option is selected
if((ParamSet.GlobalConfig & CFG_COMPASS_ACTIVE))
{
int16_t w, v, r,correction, error;
if(cnt > EE_Parameter.Driftkomp) cnt = EE_Parameter.Driftkomp;
if(IntegralFehlerRoll > FEHLER_LIMIT) AdNeutralRoll += cnt;
if(IntegralFehlerRoll < -FEHLER_LIMIT) AdNeutralRoll -= cnt;
/*DebugOut.Analog[27] = ausgleichRoll;
DebugOut.Analog[23] = AdNeutralNick;//10*(AdNeutralNick - StartNeutralNick);
DebugOut.Analog[24] = 10*(AdNeutralRoll - StartNeutralRoll);
*/
}
else
{
LageKorrekturRoll = 0;
LageKorrekturNick = 0;
TrichterFlug = 0;
}
if(!IntegralFaktor) { LageKorrekturRoll = 0; LageKorrekturNick = 0;} // z.B. bei HH
// +++++++++++++++++++++++++++++++++++++++++++++++++++++
MittelIntegralNick_Alt = MittelIntegralNick;
MittelIntegralRoll_Alt = MittelIntegralRoll;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++
IntegralAccNick = 0;
IntegralAccRoll = 0;
IntegralAccZ = 0;
MittelIntegralNick = 0;
MittelIntegralRoll = 0;
MittelIntegralNick2 = 0;
MittelIntegralRoll2 = 0;
ZaehlMessungen = 0;
}
//DebugOut.Analog[31] = StickRoll / (26*IntegralFaktor);
 
if(CompassCalState && MotorsOn == 0 )
{
SetCompassCalState();
#ifdef USE_KILLAGREG
MM3_Calibrate();
#endif
}
else
{
#ifdef USE_KILLAGREG
static uint8_t updCompass = 0;
if (!updCompass--)
{
updCompass = 49; // update only at 2ms*50 = 100ms (10Hz)
MM3_Heading();
}
#endif
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gieren
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// if(GasMischanteil < 35) { if(StickGier > 10) StickGier = 10; else if(StickGier < -10) StickGier = -10;};
if(abs(StickGier) > 15) // war 35
{
if(!(EE_Parameter.GlobalConfig & CFG_KOMPASS_FIX))
{
NeueKompassRichtungMerken = 1;
KompassStartwert = ErsatzKompass;
KompassSignalSchlecht = 250;
};
}
tmp_int = (long) EE_Parameter.Gier_P * ((long)StickGier * abs(StickGier)) / 512L; // expo y = ax + bx²
tmp_int += (EE_Parameter.Gier_P * StickGier) / 4;
sollGier = tmp_int;
Mess_Integral_Gier -= tmp_int;
if(Mess_Integral_Gier > 50000) Mess_Integral_Gier = 50000; // begrenzen
if(Mess_Integral_Gier <-50000) Mess_Integral_Gier =-50000;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Kompass
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//DebugOut.Analog[29] = (MaxStickNick + MaxStickRoll);
 
// get maximum attitude angle
w = abs(IntegralPitch/512);
v = abs(IntegralRoll /512);
if(v > w) w = v;
// update compass course
if (w < 25 && UpdateCompassCourse && !BadCompassHeading)
{
BeepTime = 200;
CompassCourse = YawGyroHeading / YAW_GYRO_DEG_FACTOR;
UpdateCompassCourse = 0;
}
// calculate the deviation of the yaw gyro heading and the compass heading
if (CompassHeading < 0) error = 0; // disable yaw drift compensation if compass heading is undefined
else error = ((540 + CompassHeading - (YawGyroHeading / YAW_GYRO_DEG_FACTOR)) % 360) - 180;
correction = w / 8 + 1;
YawGyroHeading += (error * 8) / correction;
w = (w * FCParam.CompassYawEffect) / 64;
w = FCParam.CompassYawEffect - w;
if(w > 0)
{
if(BadCompassHeading)
{ // wait a while
BadCompassHeading--;
}
else
{ //
YawGyroDrift += error;
v = 64 + (MaxStickPitch + MaxStickRoll) / 8;
// calc course deviation
r = ((540 + (YawGyroHeading / YAW_GYRO_DEG_FACTOR) - CompassCourse) % 360) - 180;
v = (r * w) / v; // align to compass course
// limit yaw rate
w = 3 * FCParam.CompassYawEffect;
if (v > w) v = w;
else if (v < -w) v = -w;
Reading_IntegralGyroYaw += v;
}
}
else
{ // ignore compass at extreme attitudes for a while
BadCompassHeading = 250;
}
}
}
if(KompassValue && (EE_Parameter.GlobalConfig & CFG_KOMPASS_AKTIV))
{
int w,v,r,fehler,korrektur;
w = abs(IntegralNick /512); // mit zunehmender Neigung den Einfluss drosseln
v = abs(IntegralRoll /512);
if(v > w) w = v; // grösste Neigung ermitteln
korrektur = w / 8 + 1;
if(w < 25 && NeueKompassRichtungMerken && !KompassSignalSchlecht)
{
beeptime = 200;
// KompassStartwert = KompassValue;
KompassStartwert = (ErsatzKompass/GIER_GRAD_FAKTOR);
NeueKompassRichtungMerken = 0;
}
fehler = ((540 + KompassValue - (ErsatzKompass/GIER_GRAD_FAKTOR)) % 360) - 180;
ErsatzKompass += (fehler * 8) / korrektur;
w = (w * Parameter_KompassWirkung) / 64; // auf die Wirkung normieren
w = Parameter_KompassWirkung - w; // Wirkung ggf drosseln
if(w > 0)
{
if(!KompassSignalSchlecht)
{
GierGyroFehler += fehler;
v = 64 + ((MaxStickNick + MaxStickRoll)) / 8;
r = ((540 + (ErsatzKompass/GIER_GRAD_FAKTOR) - KompassStartwert) % 360) - 180;
// r = KompassRichtung;
v = (r * w) / v; // nach Kompass ausrichten
w = 3 * Parameter_KompassWirkung;
if(v > w) v = w; // Begrenzen
else
if(v < -w) v = -w;
Mess_Integral_Gier += v;
}
if(KompassSignalSchlecht) KompassSignalSchlecht--;
}
else KompassSignalSchlecht = 250; // so lange das Signal taub stellen --> ca. 0,5 sek
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#ifdef USE_KILLAGREG
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// GPS
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(ParamSet.GlobalConfig & CFG_GPS_ACTIVE)
{
GPS_I_Factor = FCParam.UserParam2;
GPS_P_Factor = FCParam.UserParam5;
GPS_D_Factor = FCParam.UserParam6;
if(EmergencyLanding) GPS_Main(230); // enables Comming Home
else GPS_Main(Poti3); // behavior controlled by Poti3
}
else
{
GPS_Pitch = 0;
GPS_Roll = 0;
}
#endif
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Debugwerte zuordnen
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!TimerDebugOut--)
{
TimerDebugOut = 24; // update debug outputs every 25*2ms = 50 ms (20Hz)
DebugOut.Analog[0] = IntegralPitch / ParamSet.GyroAccFactor;
DebugOut.Analog[1] = IntegralRoll / ParamSet.GyroAccFactor;
DebugOut.Analog[2] = Mean_AccPitch;
DebugOut.Analog[3] = Mean_AccRoll;
DebugOut.Analog[4] = Reading_GyroYaw;
DebugOut.Analog[5] = ReadingHeight;
DebugOut.Analog[6] = (Reading_Integral_Top / 512);
DebugOut.Analog[8] = CompassHeading;
DebugOut.Analog[9] = UBat;
DebugOut.Analog[10] = RC_Quality;
DebugOut.Analog[11] = YawGyroHeading / YAW_GYRO_DEG_FACTOR;
DebugOut.Analog[16] = Mean_AccTop;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(!TimerWerteausgabe--)
{
TimerWerteausgabe = 24;
 
DebugOut.Analog[20] = ServoValue;
DebugOut.Analog[0] = IntegralNick / EE_Parameter.GyroAccFaktor;
DebugOut.Analog[1] = IntegralRoll / EE_Parameter.GyroAccFaktor;
DebugOut.Analog[2] = Mittelwert_AccNick;
DebugOut.Analog[3] = Mittelwert_AccRoll;
DebugOut.Analog[4] = MesswertGier;
DebugOut.Analog[5] = HoehenWert;
DebugOut.Analog[6] = (Mess_Integral_Hoch / 512);
DebugOut.Analog[8] = KompassValue;
DebugOut.Analog[9] = UBat;
DebugOut.Analog[11] = ErsatzKompass / GIER_GRAD_FAKTOR;
DebugOut.Analog[10] = SenderOkay;
DebugOut.Analog[16] = Mittelwert_AccHoch;
 
//DebugOut.Analog[17] = FromNaviCtrl_Value.Distance;
//DebugOut.Analog[18] = (int)FromNaviCtrl_Value.OsdBar;
DebugOut.Analog[19] = WinkelOut.CalcState;
DebugOut.Analog[20] = ServoValue;
 
DebugOut.Analog[30] = GPS_Nick;
DebugOut.Analog[31] = GPS_Roll;
 
DebugOut.Analog[30] = GPS_Pitch;
DebugOut.Analog[31] = GPS_Roll;
 
/* DebugOut.Analog[16] = motor_rx[0];
DebugOut.Analog[17] = motor_rx[1];
DebugOut.Analog[18] = motor_rx[2];
DebugOut.Analog[19] = motor_rx[3];
DebugOut.Analog[20] = motor_rx[0] + motor_rx[1] + motor_rx[2] + motor_rx[3];
DebugOut.Analog[20] /= 14;
DebugOut.Analog[21] = motor_rx[4];
DebugOut.Analog[22] = motor_rx[5];
DebugOut.Analog[23] = motor_rx[6];
DebugOut.Analog[24] = motor_rx[7];
DebugOut.Analog[25] = motor_rx[4] + motor_rx[5] + motor_rx[6] + motor_rx[7];
// DebugOut.Analog[19] -= DebugOut.Analog[19]/128;
// if(DebugOut.Analog[19] > 0) DebugOut.Analog[19]--; else DebugOut.Analog[19]++;
 
DebugOut.Analog[9] = Reading_GyroPitch;
DebugOut.Analog[9] = SetPointHeight;
DebugOut.Analog[10] = Reading_IntegralGyroYaw / 128;
/* DebugOut.Analog[16] = motor_rx[0];
DebugOut.Analog[17] = motor_rx[1];
DebugOut.Analog[18] = motor_rx[2];
DebugOut.Analog[19] = motor_rx[3];
DebugOut.Analog[20] = motor_rx[0] + motor_rx[1] + motor_rx[2] + motor_rx[3];
DebugOut.Analog[20] /= 14;
DebugOut.Analog[21] = motor_rx[4];
DebugOut.Analog[22] = motor_rx[5];
DebugOut.Analog[23] = motor_rx[6];
DebugOut.Analog[24] = motor_rx[7];
DebugOut.Analog[25] = motor_rx[4] + motor_rx[5] + motor_rx[6] + motor_rx[7];
*/
// DebugOut.Analog[9] = MesswertNick;
// DebugOut.Analog[9] = SollHoehe;
// DebugOut.Analog[10] = Mess_Integral_Gier / 128;
// DebugOut.Analog[11] = KompassStartwert;
// DebugOut.Analog[10] = Parameter_Gyro_I;
// DebugOut.Analog[10] = EE_Parameter.Gyro_I;
// DebugOut.Analog[9] = KompassRichtung;
// DebugOut.Analog[10] = GasMischanteil;
// DebugOut.Analog[3] = HoeheD * 32;
// DebugOut.Analog[4] = hoehenregler;
}
 
DebugOut.Analog[10] = FCParam.Gyro_I;
DebugOut.Analog[10] = ParamSet.Gyro_I;
DebugOut.Analog[9] = CompassOffCourse;
DebugOut.Analog[10] = ThrustMixFraction;
DebugOut.Analog[3] = HeightD * 32;
DebugOut.Analog[4] = HeightControlThrust;
*/
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Drehgeschwindigkeit und -winkel zu einem Istwert zusammenfassen
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// calculate control feedback from angle (gyro integral) and agular velocity (gyro signal)
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(Looping_Nick) MesswertNick = MesswertNick * GyroFaktor;
else MesswertNick = IntegralNick * IntegralFaktor + MesswertNick * GyroFaktor;
if(Looping_Roll) MesswertRoll = MesswertRoll * GyroFaktor;
else MesswertRoll = IntegralRoll * IntegralFaktor + MesswertRoll * GyroFaktor;
MesswertGier = MesswertGier * (2 * GyroFaktor) + Integral_Gier * IntegralFaktor / 2;
 
if(Looping_Pitch) Reading_GyroPitch = Reading_GyroPitch * Gyro_P_Factor;
else Reading_GyroPitch = IntegralPitch * Gyro_I_Factor + Reading_GyroPitch * Gyro_P_Factor;
if(Looping_Roll) Reading_GyroRoll = Reading_GyroRoll * Gyro_P_Factor;
else Reading_GyroRoll = IntegralRoll * Gyro_I_Factor + Reading_GyroRoll * Gyro_P_Factor;
Reading_GyroYaw = Reading_GyroYaw * (2 * Gyro_P_Factor) + IntegralYaw * Gyro_I_Factor / 2;
DebugOut.Analog[21] = MesswertNick;
DebugOut.Analog[22] = MesswertRoll;
 
DebugOut.Analog[21] = Reading_GyroPitch;
DebugOut.Analog[22] = Reading_GyroRoll;
// Maximalwerte abfangen
#define MAX_SENSOR (4096*STICK_GAIN)
if(MesswertNick > MAX_SENSOR) MesswertNick = MAX_SENSOR;
if(MesswertNick < -MAX_SENSOR) MesswertNick = -MAX_SENSOR;
if(MesswertRoll > MAX_SENSOR) MesswertRoll = MAX_SENSOR;
if(MesswertRoll < -MAX_SENSOR) MesswertRoll = -MAX_SENSOR;
if(MesswertGier > MAX_SENSOR) MesswertGier = MAX_SENSOR;
if(MesswertGier < -MAX_SENSOR) MesswertGier = -MAX_SENSOR;
 
// limit control feedback
#define MAX_SENSOR (4096 * STICK_GAIN)
if(Reading_GyroPitch > MAX_SENSOR) Reading_GyroPitch = MAX_SENSOR;
if(Reading_GyroPitch < -MAX_SENSOR) Reading_GyroPitch = -MAX_SENSOR;
if(Reading_GyroRoll > MAX_SENSOR) Reading_GyroRoll = MAX_SENSOR;
if(Reading_GyroRoll < -MAX_SENSOR) Reading_GyroRoll = -MAX_SENSOR;
if(Reading_GyroYaw > MAX_SENSOR) Reading_GyroYaw = MAX_SENSOR;
if(Reading_GyroYaw < -MAX_SENSOR) Reading_GyroYaw = -MAX_SENSOR;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Höhenregelung
// Die Höhenregelung schwächt lediglich das Gas ab, erhöht es allerdings nicht
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//OCR0B = 180 - (Poti1 + 120) / 4;
//DruckOffsetSetting = OCR0B;
GasMischanteil *= STICK_GAIN;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Height Control
// The height control algorithm reduces the thrust but does not increase the thrust.
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung
{
int tmp_int;
if(EE_Parameter.GlobalConfig & CFG_HOEHEN_SCHALTER) // Regler wird über Schalter gesteuert
{
if(Parameter_MaxHoehe < 50)
{
SollHoehe = HoehenWert - 20; // Parameter_MaxHoehe ist der PPM-Wert des Schalters
HoehenReglerAktiv = 0;
}
else
HoehenReglerAktiv = 1;
}
else
{
SollHoehe = ((int) ExternHoehenValue + (int) Parameter_MaxHoehe) * (int)EE_Parameter.Hoehe_Verstaerkung - 20;
HoehenReglerAktiv = 1;
}
 
ThrustMixFraction *= STICK_GAIN;
if(Notlandung) SollHoehe = 0;
h = HoehenWert;
if((h > SollHoehe) && HoehenReglerAktiv) // zu hoch --> drosseln
{
h = ((h - SollHoehe) * (int) Parameter_Hoehe_P) / (16 / STICK_GAIN); // Differenz bestimmen --> P-Anteil
h = GasMischanteil - h; // vom Gas abziehen
// h -= (HoeheD * Parameter_Luftdruck_D)/(8/STICK_GAIN); // D-Anteil
h -= (HoeheD)/(8/STICK_GAIN); // D-Anteil
tmp_int = ((Mess_Integral_Hoch / 128) * (signed long) Parameter_Hoehe_ACC_Wirkung) / (128 / STICK_GAIN);
if(tmp_int > 70*STICK_GAIN) tmp_int = 70*STICK_GAIN;
else if(tmp_int < -(70*STICK_GAIN)) tmp_int = -(70*STICK_GAIN);
h -= tmp_int;
hoehenregler = (hoehenregler*15 + h) / 16;
if(hoehenregler < EE_Parameter.Hoehe_MinGas * STICK_GAIN) // nicht unter MIN
{
if(GasMischanteil >= EE_Parameter.Hoehe_MinGas * STICK_GAIN) hoehenregler = EE_Parameter.Hoehe_MinGas * STICK_GAIN;
if(GasMischanteil < EE_Parameter.Hoehe_MinGas * STICK_GAIN) hoehenregler = GasMischanteil;
}
if(hoehenregler > GasMischanteil) hoehenregler = GasMischanteil; // nicht mehr als Gas
GasMischanteil = hoehenregler;
}
}
if(GasMischanteil > (MAX_GAS - 20) * STICK_GAIN) GasMischanteil = (MAX_GAS - 20) * STICK_GAIN;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Mischer und PI-Regler
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DebugOut.Analog[7] = GasMischanteil;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Gier-Anteil
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define MUL_G 1.0
GierMischanteil = MesswertGier - sollGier * STICK_GAIN; // Regler für Gier
// GierMischanteil = 0;
#define MIN_GIERGAS (40*STICK_GAIN) // unter diesem Gaswert trotzdem Gieren
if(GasMischanteil > MIN_GIERGAS)
{
if(GierMischanteil > (GasMischanteil / 2)) GierMischanteil = GasMischanteil / 2;
if(GierMischanteil < -(GasMischanteil / 2)) GierMischanteil = -(GasMischanteil / 2);
}
else
{
if(GierMischanteil > (MIN_GIERGAS / 2)) GierMischanteil = MIN_GIERGAS / 2;
if(GierMischanteil < -(MIN_GIERGAS / 2)) GierMischanteil = -(MIN_GIERGAS / 2);
}
tmp_int = MAX_GAS*STICK_GAIN;
if(GierMischanteil > ((tmp_int - GasMischanteil))) GierMischanteil = ((tmp_int - GasMischanteil));
if(GierMischanteil < -((tmp_int - GasMischanteil))) GierMischanteil = -((tmp_int - GasMischanteil));
 
// If height control is activated and no emergency landing is active
if((ParamSet.GlobalConfig & CFG_HEIGHT_CONTROL) && (!EmergencyLanding) )
{
int tmp_int;
// if height control is activated by an rc channel
if(ParamSet.GlobalConfig & CFG_HEIGHT_SWITCH)
{ // check if parameter is less than activation threshold
if(FCParam.MaxHeight < 50)
{
SetPointHeight = ReadingHeight - 20; // update SetPoint with current reading
HeightControlActive = 0; // disable height control
}
else HeightControlActive = 1; // enable height control
}
else // no switchable height control
{
SetPointHeight = ((int16_t) ExternHeightValue + (int16_t) FCParam.MaxHeight) * (int16_t)ParamSet.Height_Gain - 20;
HeightControlActive = 1;
}
// get current height
h = ReadingHeight;
// if current height is above the setpoint reduce thrust
if((h > SetPointHeight) && HeightControlActive)
{
// ThrustMixFraction - HightDeviation * P - HeightChange * D - ACCTop * DACC
// height difference -> P control part
h = ((h - SetPointHeight) * (int16_t) FCParam.Height_P) / (16 / STICK_GAIN);
h = ThrustMixFraction - h; // reduce gas
// height gradient --> D control part
//h -= (HeightD * FCParam.Height_D) / (8 / STICK_GAIN); // D control part
h -= (HeightD) / (8 / STICK_GAIN); // D control part
// acceleration sensor effect
tmp_int = ((Reading_Integral_Top / 128) * (int32_t) FCParam.Height_ACC_Effect) / (128 / STICK_GAIN);
if(tmp_int > 70 * STICK_GAIN) tmp_int = 70 * STICK_GAIN;
else if(tmp_int < -(70 * STICK_GAIN)) tmp_int = -(70 * STICK_GAIN);
h -= tmp_int;
// update height control thrust
HeightControlThrust = (HeightControlThrust*15 + h) / 16;
// limit thrust reduction
if(HeightControlThrust < ParamSet.Height_MinThrust * STICK_GAIN)
{
if(ThrustMixFraction >= ParamSet.Height_MinThrust * STICK_GAIN) HeightControlThrust = ParamSet.Height_MinThrust * STICK_GAIN;
// allows landing also if thrust stick is reduced below min thrust on height control
if(ThrustMixFraction < ParamSet.Height_MinThrust * STICK_GAIN) HeightControlThrust = ThrustMixFraction;
}
// limit thrust to stick setting
if(HeightControlThrust > ThrustMixFraction) HeightControlThrust = ThrustMixFraction;
ThrustMixFraction = HeightControlThrust;
}
}
// limit thrust to parameter setting
if(ThrustMixFraction > (ParamSet.Trust_Max - 20) * STICK_GAIN) ThrustMixFraction = (ParamSet.Trust_Max - 20) * STICK_GAIN;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Mixer and PI-Controller
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DebugOut.Analog[7] = ThrustMixFraction;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Yaw-Fraction
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
YawMixFraction = Reading_GyroYaw - SetPointYaw * STICK_GAIN; // yaw controller
#define MIN_YAWTHRUST (40 * STICK_GAIN) // yaw also below this thrust value
// limit YawMixFraction
if(ThrustMixFraction > MIN_YAWTHRUST)
{
if(YawMixFraction > (ThrustMixFraction / 2)) YawMixFraction = ThrustMixFraction / 2;
if(YawMixFraction < -(ThrustMixFraction / 2)) YawMixFraction = -(ThrustMixFraction / 2);
}
else
{
if(YawMixFraction > (MIN_YAWTHRUST / 2)) YawMixFraction = MIN_YAWTHRUST / 2;
if(YawMixFraction < -(MIN_YAWTHRUST / 2)) YawMixFraction = -(MIN_YAWTHRUST / 2);
}
tmp_int = ParamSet.Trust_Max * STICK_GAIN;
if(YawMixFraction > ((tmp_int - ThrustMixFraction))) YawMixFraction = ((tmp_int - ThrustMixFraction));
if(YawMixFraction < -((tmp_int - ThrustMixFraction))) YawMixFraction = -((tmp_int - ThrustMixFraction));
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Nick-Achse
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffNick = MesswertNick - StickNick; // Differenz bestimmen
if(IntegralFaktor) SummeNick += IntegralNick * IntegralFaktor - StickNick; // I-Anteil bei Winkelregelung
else SummeNick += DiffNick; // I-Anteil bei HH
if(SummeNick > (STICK_GAIN * 16000L)) SummeNick = (STICK_GAIN * 16000L);
if(SummeNick < -(16000L * STICK_GAIN)) SummeNick = -(16000L * STICK_GAIN);
pd_ergebnis = DiffNick + Ki * SummeNick; // PI-Regler für Nick
// Motor Vorn
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64;
if(pd_ergebnis > tmp_int) pd_ergebnis = tmp_int;
if(pd_ergebnis < -tmp_int) pd_ergebnis = -tmp_int;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pitch-Axis
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffPitch = Reading_GyroPitch - StickPitch; // get difference
if(Gyro_I_Factor) SumPitch += IntegralPitch * Gyro_I_Factor - StickPitch; // I-part for attitude control
else SumPitch += DiffPitch; // I-part for head holding
if(SumPitch > (STICK_GAIN * 16000L)) SumPitch = (STICK_GAIN * 16000L);
if(SumPitch < -(STICK_GAIN * 16000L)) SumPitch = -(STICK_GAIN * 16000L);
pd_result = DiffPitch + Ki * SumPitch; // PI-controller for pitch
 
tmp_int = (int32_t)((int32_t)FCParam.DynamicStability * (int32_t)(ThrustMixFraction + abs(YawMixFraction)/2)) / 64;
if(pd_result > tmp_int) pd_result = tmp_int;
if(pd_result < -tmp_int) pd_result = -tmp_int;
 
// Motor Front
MotorValue = ThrustMixFraction + pd_result + YawMixFraction; // Mixer
MotorValue /= STICK_GAIN;
if ((MotorValue < 0)) MotorValue = 0;
else if(MotorValue > ParamSet.Trust_Max) MotorValue = ParamSet.Trust_Max;
if (MotorValue < ParamSet.Trust_Min) MotorValue = ParamSet.Trust_Min;
Motor_Front = MotorValue;
 
// Motor Rear
MotorValue = ThrustMixFraction - pd_result + YawMixFraction; // Mixer
MotorValue /= STICK_GAIN;
if ((MotorValue < 0)) MotorValue = 0;
else if(MotorValue > ParamSet.Trust_Max) MotorValue = ParamSet.Trust_Max;
if (MotorValue < ParamSet.Trust_Min) MotorValue = ParamSet.Trust_Min;
Motor_Rear = MotorValue;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Roll-Axis
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffRoll = Reading_GyroRoll - StickRoll; // get difference
if(Gyro_I_Factor) SumRoll += IntegralRoll * Gyro_I_Factor - StickRoll; // I-part for attitude control
else SumRoll += DiffRoll; // I-part for head holding
if(SumRoll > 16000) SumRoll = 16000;
if(SumRoll < -16000) SumRoll = -16000;
pd_result = DiffRoll + Ki * SumRoll; // PI-controller for roll
tmp_int = (int32_t)((int32_t)FCParam.DynamicStability * (int32_t)(ThrustMixFraction + abs(YawMixFraction)/2)) / 64;
if(pd_result > tmp_int) pd_result = tmp_int;
if(pd_result < -tmp_int) pd_result = -tmp_int;
 
// Motor Left
MotorValue = ThrustMixFraction + pd_result - YawMixFraction; // Mixer
MotorValue /= STICK_GAIN;
if ((MotorValue < 0)) MotorValue = 0;
else if(MotorValue > ParamSet.Trust_Max) MotorValue = ParamSet.Trust_Max;
if (MotorValue < ParamSet.Trust_Min) MotorValue = ParamSet.Trust_Min;
Motor_Left = MotorValue;
 
// Motor Right
MotorValue = ThrustMixFraction - pd_result - YawMixFraction; // Mixer
MotorValue /= STICK_GAIN;
if ((MotorValue < 0)) MotorValue = 0;
else if(MotorValue > ParamSet.Trust_Max) MotorValue = ParamSet.Trust_Max;
if (MotorValue < ParamSet.Trust_Min) MotorValue = ParamSet.Trust_Min;
Motor_Right = MotorValue;
motorwert = GasMischanteil + pd_ergebnis + GierMischanteil; // Mischer
motorwert /= STICK_GAIN;
if ((motorwert < 0)) motorwert = 0;
else if(motorwert > MAX_GAS) motorwert = MAX_GAS;
if (motorwert < MIN_GAS) motorwert = MIN_GAS;
Motor_Vorne = motorwert;
// Motor Heck
motorwert = GasMischanteil - pd_ergebnis + GierMischanteil;
motorwert /= STICK_GAIN;
if ((motorwert < 0)) motorwert = 0;
else if(motorwert > MAX_GAS) motorwert = MAX_GAS;
if (motorwert < MIN_GAS) motorwert = MIN_GAS;
Motor_Hinten = motorwert;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Roll-Achse
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DiffRoll = MesswertRoll - StickRoll; // Differenz bestimmen
if(IntegralFaktor) SummeRoll += IntegralRoll * IntegralFaktor - StickRoll;// I-Anteil bei Winkelregelung
else SummeRoll += DiffRoll; // I-Anteil bei HH
if(SummeRoll > 16000) SummeRoll = 16000;
if(SummeRoll < -16000) SummeRoll = -16000;
pd_ergebnis = DiffRoll + Ki * SummeRoll; // PI-Regler für Roll
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64;
if(pd_ergebnis > tmp_int) pd_ergebnis = tmp_int;
if(pd_ergebnis < -tmp_int) pd_ergebnis = -tmp_int;
// Motor Links
motorwert = GasMischanteil + pd_ergebnis - GierMischanteil;
motorwert /= STICK_GAIN;
if ((motorwert < 0)) motorwert = 0;
else if(motorwert > MAX_GAS) motorwert = MAX_GAS;
if (motorwert < MIN_GAS) motorwert = MIN_GAS;
Motor_Links = motorwert;
// Motor Rechts
motorwert = GasMischanteil - pd_ergebnis - GierMischanteil;
motorwert /= STICK_GAIN;
if ((motorwert < 0)) motorwert = 0;
else if(motorwert > MAX_GAS) motorwert = MAX_GAS;
if (motorwert < MIN_GAS) motorwert = MIN_GAS;
Motor_Rechts = motorwert;
// +++++++++++++++++++++++++++++++++++++++++++++++
}
 
/branches/V0.69k Code Redesign killagreg/fc.h
4,106 → 4,139
 
#ifndef _FC_H
#define _FC_H
 
#include <inttypes.h>
 
#define YAW_GYRO_DEG_FACTOR 1550L // Factor between Yaw Gyro Integral and HeadingAngle in deg
//#define GIER_GRAD_FAKTOR 1450L // Abhängigkeit wzischen GyroIntegral und Winkel
#define GIER_GRAD_FAKTOR 1550L // Abhängigkeit wzischen GyroIntegral und Winkel
#define STICK_GAIN 4
 
typedef struct
{
uint8_t Height_D;
uint8_t MaxHeight;
uint8_t Height_P;
uint8_t Height_ACC_Effect;
uint8_t CompassYawEffect;
uint8_t Gyro_P;
uint8_t Gyro_I;
uint8_t Gier_P;
uint8_t I_Factor;
uint8_t UserParam1;
uint8_t UserParam2;
uint8_t UserParam3;
uint8_t UserParam4;
uint8_t UserParam5;
uint8_t UserParam6;
uint8_t UserParam7;
uint8_t UserParam8;
uint8_t ServoPitchControl;
uint8_t LoopThrustLimit;
uint8_t Yaw_PosFeedback;
uint8_t Yaw_NegFeedback;
uint8_t DynamicStability;
} fc_param_t;
 
extern fc_param_t FCParam;
 
extern volatile uint16_t I2CTimeout;
 
// attitude
extern volatile int32_t IntegralPitch, IntegralRoll, IntegralYaw;
extern volatile int16_t Reading_GyroPitch, Reading_GyroRoll, Reading_GyroYaw;
 
// offsets
extern volatile int16_t AdNeutralPitch, AdNeutralRoll, AdNeutralYaw;
extern volatile int16_t NeutralAccX, NeutralAccY;
extern volatile unsigned int I2CTimeout;
extern unsigned char Sekunde,Minute;
extern long IntegralNick,IntegralNick2;
extern long IntegralRoll,IntegralRoll2;
extern long Mess_IntegralNick,Mess_IntegralNick2;
extern long Mess_IntegralRoll,Mess_IntegralRoll2;
extern long IntegralAccNick,IntegralAccRoll;
extern volatile long Mess_Integral_Hoch;
extern long Integral_Gier,Mess_Integral_Gier,Mess_Integral_Gier2;
extern volatile int KompassValue;
extern volatile int KompassStartwert;
extern volatile int KompassRichtung;
extern long ErsatzKompass;
extern int ErsatzKompassInGrad; // Kompasswert in Grad
extern int HoehenWert;
extern int SollHoehe;
extern volatile int MesswertNick,MesswertRoll,MesswertGier;
extern volatile int AdNeutralNick,AdNeutralRoll,AdNeutralGier, Mittelwert_AccNick, Mittelwert_AccRoll;
extern volatile int NeutralAccX, NeutralAccY,Mittelwert_AccHoch;
extern volatile float NeutralAccZ;
 
 
extern volatile int32_t Reading_Integral_Top; // calculated in analog.c
 
// compass navigation
extern volatile int16_t CompassHeading;
extern volatile int16_t CompassCourse;
extern volatile int16_t CompassOffCourse;
extern volatile uint8_t CompassCalState;
extern int32_t YawGyroHeading;
extern int16_t YawGyroHeadingInDeg;
 
// hight control
extern int ReadingHeight;
extern int SetPointHeight;
 
// mean accelerations
extern volatile int16_t Mean_AccPitch, Mean_AccRoll, Mean_AccTop;
 
// acceleration send to navi board
extern int16_t NaviAccPitch, NaviAccRoll, NaviCntAcc;
 
 
// looping params
extern long TurnOver180Pitch, TurnOver180Roll;
 
// external control
extern int16_t ExternStickPitch, ExternStickRoll, ExternStickYaw;
 
 
void MotorControl(void);
extern long Umschlag180Nick, Umschlag180Roll;
extern signed int ExternStickNick,ExternStickRoll,ExternStickGier;
extern unsigned char Parameter_UserParam1,Parameter_UserParam2,Parameter_UserParam3,Parameter_UserParam4,Parameter_UserParam5,Parameter_UserParam6,Parameter_UserParam7,Parameter_UserParam8;
extern int NaviAccNick,NaviAccRoll,NaviCntAcc;
extern unsigned int modell_fliegt;
void MotorRegler(void);
void SendMotorData(void);
void CalibMean(void);
void Mean(void);
void CalibrierMittelwert(void);
void Mittelwert(void);
void SetNeutral(void);
void Beep(uint8_t numbeeps);
void Piep(unsigned char Anzahl);
extern void DefaultKonstanten(void);
void DefaultKonstanten1(void);
void DefaultKonstanten2(void);
 
extern unsigned char h,m,s;
extern volatile unsigned char Timeout ;
extern unsigned char CosinusNickWinkel, CosinusRollWinkel;
extern volatile int DiffNick,DiffRoll;
extern int Poti1, Poti2, Poti3, Poti4;
extern volatile unsigned char Motor_Vorne,Motor_Hinten,Motor_Rechts,Motor_Links, Count;
extern volatile unsigned char SenderOkay;
extern int StickNick,StickRoll,StickGier;
extern char MotorenEin;
extern void DefaultKonstanten1(void);
extern void DefaultKonstanten2(void);
 
extern int16_t Poti1, Poti2, Poti3, Poti4, Poti5, Poti6, Poti7, Poti8;
#define STRUCT_PARAM_LAENGE 71
struct mk_param_struct
{
unsigned char Kanalbelegung[8]; // GAS[0], GIER[1],NICK[2], ROLL[3], POTI1, POTI2, POTI3
unsigned char GlobalConfig; // 0x01=Höhenregler aktiv,0x02=Kompass aktiv, 0x04=GPS aktiv, 0x08=Heading Hold aktiv
unsigned char Hoehe_MinGas; // Wert : 0-100
unsigned char Luftdruck_D; // Wert : 0-250
unsigned char MaxHoehe; // Wert : 0-32
unsigned char Hoehe_P; // Wert : 0-32
unsigned char Hoehe_Verstaerkung; // Wert : 0-50
unsigned char Hoehe_ACC_Wirkung; // Wert : 0-250
unsigned char Stick_P; // Wert : 1-6
unsigned char Stick_D; // Wert : 0-64
unsigned char Gier_P; // Wert : 1-20
unsigned char Gas_Min; // Wert : 0-32
unsigned char Gas_Max; // Wert : 33-250
unsigned char GyroAccFaktor; // Wert : 1-64
unsigned char KompassWirkung; // Wert : 0-32
unsigned char Gyro_P; // Wert : 10-250
unsigned char Gyro_I; // Wert : 0-250
unsigned char UnterspannungsWarnung; // Wert : 0-250
unsigned char NotGas; // Wert : 0-250 //Gaswert bei Empängsverlust
unsigned char NotGasZeit; // Wert : 0-250 // Zeitbis auf NotGas geschaltet wird, wg. Rx-Problemen
unsigned char UfoAusrichtung; // X oder + Formation
unsigned char I_Faktor; // Wert : 0-250
unsigned char UserParam1; // Wert : 0-250
unsigned char UserParam2; // Wert : 0-250
unsigned char UserParam3; // Wert : 0-250
unsigned char UserParam4; // Wert : 0-250
unsigned char ServoNickControl; // Wert : 0-250 // Stellung des Servos
unsigned char ServoNickComp; // Wert : 0-250 // Einfluss Gyro/Servo
unsigned char ServoNickMin; // Wert : 0-250 // Anschlag
unsigned char ServoNickMax; // Wert : 0-250 // Anschlag
unsigned char ServoNickRefresh; //
unsigned char LoopGasLimit; // Wert: 0-250 max. Gas während Looping
unsigned char LoopThreshold; // Wert: 0-250 Schwelle für Stickausschlag
unsigned char LoopHysterese; // Wert: 0-250 Hysterese für Stickausschlag
unsigned char AchsKopplung1; // Wert: 0-250 Faktor, mit dem Gier die Achsen Roll und Nick koppelt (NickRollMitkopplung)
unsigned char AchsGegenKopplung1; // Wert: 0-250 Faktor, mit dem Gier die Achsen Roll und Nick Gegenkoppelt (NickRollGegenkopplung)
unsigned char WinkelUmschlagNick; // Wert: 0-250 180°-Punkt
unsigned char WinkelUmschlagRoll; // Wert: 0-250 180°-Punkt
unsigned char GyroAccAbgleich; // 1/k (Koppel_ACC_Wirkung)
unsigned char Driftkomp;
unsigned char DynamicStability;
unsigned char UserParam5; // Wert : 0-250
unsigned char UserParam6; // Wert : 0-250
unsigned char UserParam7; // Wert : 0-250
unsigned char UserParam8; // Wert : 0-250
 
// setpoints for motors
extern volatile uint8_t Motor_Front, Motor_Rear, Motor_Right, Motor_Left; //used by twimaster isr
//------------------------------------------------
unsigned char LoopConfig; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt
unsigned char ServoNickCompInvert; // Wert : 0-250 0 oder 1 // WICHTIG!!! am Ende lassen
unsigned char Reserved[4];
char Name[12];
};
 
// current stick values
extern int16_t StickPitch;
extern int16_t StickRoll;
extern int16_t StickYaw;
extern int16_t GPS_Pitch;
extern int16_t GPS_Roll;
 
// current stick elongations
extern int16_t MaxStickPitch, MaxStickRoll, MaxStickYaw;
extern uint8_t MotorsOn;
extern uint8_t EmergencyLanding;
extern uint16_t Model_Is_Flying;
/*
unsigned char ServoNickMax; // Wert : 0-250
unsigned char ServoNickRefresh; //
unsigned char LoopGasLimit; // Wert: 0-250 max. Gas während Looping
unsigned char LoopThreshold; // Wert: 0-250 Schwelle für Stickausschlag
//------------------------------------------------
unsigned char LoopConfig; // Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt
unsigned char ServoNickCompInvert; // Wert : 0-250 0 oder 1 // WICHTIG!!! am Ende lassen
unsigned char Reserved[4];
char Name[12];
*/
extern struct mk_param_struct EE_Parameter;
 
extern unsigned char Parameter_Luftdruck_D;
extern unsigned char Parameter_MaxHoehe;
extern unsigned char Parameter_Hoehe_P;
extern unsigned char Parameter_Hoehe_ACC_Wirkung;
extern unsigned char Parameter_KompassWirkung;
extern unsigned char Parameter_Gyro_P;
extern unsigned char Parameter_Gyro_I;
extern unsigned char Parameter_Gier_P;
extern unsigned char Parameter_ServoNickControl;
extern unsigned char Parameter_AchsKopplung1;
extern unsigned char Parameter_AchsGegenKopplung1;
 
 
#endif //_FC_H
 
/branches/V0.69k Code Redesign killagreg/gps.h
1,15 → 1,7
#ifndef _GPS_H
#define _GPS_H
extern signed int GPS_Nick;
extern signed int GPS_Roll;
extern signed int GPS_Nick2;
extern signed int GPS_Roll2;
 
#include <inttypes.h>
 
extern uint8_t GPS_P_Factor;
extern uint8_t GPS_I_Factor;
extern uint8_t GPS_D_Factor;
 
extern void GPS_Main(uint8_t ctrl);
extern void GPS_SetHomePosition(void);
extern void GPS_ClearHomePosition(void);
 
#endif //_GPS_H
 
void GPS_Neutral(void);
void GPS_BerechneZielrichtung(void);
/branches/V0.69k Code Redesign killagreg/main.c
3,14 → 3,14
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten und nicht-kommerziellen Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten und nicht-kommerziellen Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
// + Verkauf von Luftbildaufnahmen, usw.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
21,21 → 21,21
// + Benutzung auf eigene Gefahr
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * porting to systems other than hardware from www.mikrokopter.de is not allowed
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47,43 → 47,63
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <avr/boot.h>
#include "main.h"
 
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char EEPromArray[E2END+1] EEMEM;
unsigned char PlatinenVersion = 10;
unsigned char SendVersionToNavi = 1;
// -- Parametersatz aus EEPROM lesen ---
// number [0..5]
void ReadParameterSet(unsigned char number, unsigned char *buffer, unsigned char length)
{
if (number > 5) number = 5;
eeprom_read_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * number], length);
}
 
#include "main.h"
#include "timer0.h"
#include "timer2.h"
#include "uart.h"
#if defined (__AVR_ATmega644P__)
#include "uart1.h"
#endif
#include "led.h"
#include "menu.h"
#include "fc.h"
#include "rc.h"
#include "analog.h"
#include "printf_P.h"
#ifdef USE_KILLAGREG
#include "mm3.h"
#endif
#ifdef USE_NAVICTRL
#include "spi.h"
#endif
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
#include "mk3mag.h"
#endif
#include "twimaster.h"
#include "eeprom.h"
#include "_Settings.h"
 
// -- Parametersatz ins EEPROM schreiben ---
// number [0..5]
void WriteParameterSet(unsigned char number, unsigned char *buffer, unsigned char length)
{
if(number > 5) number = 5;
eeprom_write_block(buffer, &EEPromArray[EEPROM_ADR_PARAM_BEGIN + length * number], length);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], number); // diesen Parametersatz als aktuell merken
}
 
uint8_t BoardRelease = 10;
unsigned char GetActiveParamSetNumber(void)
{
unsigned char set;
set = eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET]);
if(set > 5)
{
set = 2;
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], set); // diesen Parametersatz als aktuell merken
}
return(set);
}
 
void CalMk3Mag(void)
{
static unsigned char stick = 1;
 
if(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > -20) stick = 0;
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -70) && !stick)
{
stick = 1;
WinkelOut.CalcState++;
if(WinkelOut.CalcState > 4)
{
// WinkelOut.CalcState = 0; // in Uart.c
beeptime = 1000;
}
else Piep(WinkelOut.CalcState);
}
DebugOut.Analog[19] = WinkelOut.CalcState;
}
 
 
//############################################################################
//Hauptprogramm
int main (void)
91,207 → 111,169
{
unsigned int timer;
 
// disable interrupts global
cli();
 
// get board release
DDRB = 0x00;
PORTB = 0x00;
for(timer = 0; timer < 1000; timer++); // make some delay
if(PINB & (1<<PINB0)) BoardRelease = 11;
else BoardRelease = 10;
 
// set LED ports as output
DDRB |= (1<<DDB1)|(1<<DDB0);
ROT_ON;
GRN_OFF;
 
// disable watchdog
//unsigned int timer2 = 0;
DDRB = 0x00;
PORTB = 0x00;
for(timer = 0; timer < 1000; timer++); // verzögern
if(PINB & 0x01) PlatinenVersion = 11; else PlatinenVersion = 10;
DDRC = 0x81; // SCL
PORTC = 0xff; // Pullup SDA
DDRB = 0x1B; // LEDs und Druckoffset
PORTB = 0x01; // LED_Rot
DDRD = 0x3E; // Speaker & TXD & J3 J4 J5
DDRD |=0x80; // J7
PORTD = 0xF7; // LED
MCUSR &=~(1<<WDRF);
WDTCSR |= (1<<WDCE)|(1<<WDE);
WDTCSR = 0;
 
BeepTime = 2000;
beeptime = 2000;
 
PPM_in[CH_THRUST] = 0;
StickYaw = 0;
StickRoll = 0;
StickPitch = 0;
StickGier = 0; PPM_in[K_GAS] = 0;StickRoll = 0; StickNick = 0;
 
ROT_OFF;
 
// initalize modules
LED_Init();
TIMER0_Init();
TIMER2_Init();
USART0_Init();
 
#if defined (__AVR_ATmega644P__)
if (BoardRelease == 11) USART1_Init();
#endif
 
RC_Init();
Timer_Init();
UART_Init();
rc_sum_init();
ADC_Init();
I2C_Init();
 
#ifdef USE_KILLAGREG
MM3_Init();
#endif
#ifdef USE_NAVICTRL
i2c_init();
SPI_MasterInit();
#endif
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
MK3MAG_Init();
#endif
 
 
// enable interrupts global
sei();
 
VersionInfo.Major = VERSION_MAJOR;
VersionInfo.Minor = VERSION_MINOR;
VersionInfo.PCCompatible = VERSION_COMPATIBLE;
 
printf("\n\rFlightControl\n\rHardware:%d.%d\n\rSoftware:V%d.%d%c ",BoardRelease/10,BoardRelease%10, VERSION_MAJOR, VERSION_MINOR,VERSION_INDEX + 'a');
VersionInfo.Hauptversion = VERSION_HAUPTVERSION;
VersionInfo.Nebenversion = VERSION_NEBENVERSION;
VersionInfo.PCKompatibel = VERSION_KOMPATIBEL;
printf("\n\rFlightControl\n\rHardware:%d.%d\n\rSoftware:V%d.%d%c ",PlatinenVersion/10,PlatinenVersion%10, VERSION_HAUPTVERSION, VERSION_NEBENVERSION,VERSION_INDEX + 'a');
printf("\n\r==============================");
GRN_ON;
 
// Parameter set handling
ParamSet_Init();
#define EE_DATENREVISION 70 // wird angepasst, wenn sich die EEPROM-Daten geändert haben
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_VALID]) != EE_DATENREVISION)
{
printf("\n\rInit. EEPROM: Generiere Default-Parameter...");
DefaultKonstanten1();
for (unsigned char i=0;i<6;i++)
{
if(i==2) DefaultKonstanten2(); // Kamera
if(i==3) DefaultKonstanten3(); // Beginner
if(i>3) DefaultKonstanten2(); // Kamera
WriteParameterSet(i, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
}
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], 3); // default-Setting
eeprom_write_byte(&EEPromArray[EEPROM_ADR_VALID], EE_DATENREVISION);
}
 
if(GetParamWord(PID_ACC_PITCH) > 1023)
if(eeprom_read_byte(&EEPromArray[EEPROM_ADR_ACC_NICK]) > 4)
{
printf("\n\rACC not calibrated!");
printf("\n\rACC nicht abgeglichen!");
}
ReadParameterSet(GetActiveParamSetNumber(), (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
printf("\n\rBenutze Parametersatz %d", GetActiveParamSetNumber());
 
//wait for a short time (otherwise the RC channel check won't work below)
timer = SetDelay(500);
while(!CheckDelay(timer));
 
 
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
printf("\n\rSupport for MK3MAG Compass");
#endif
 
 
if(ParamSet.GlobalConfig & CFG_HEIGHT_CONTROL)
{
printf("\n\rCalibrating air pressure sensor..");
timer = SetDelay(1000);
SearchAirPressureOffset();
if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
{
printf("\n\rAbgleich Luftdrucksensor..");
timer = SetDelay(1000);
SucheLuftruckOffset();
while (!CheckDelay(timer));
printf("OK\n\r");
}
 
#ifdef USE_KILLAGREG
printf("\n\rSupport for MicroMag3 Compass");
#if defined (__AVR_ATmega644P__)
if(BoardRelease == 10)
{
printf("\n\rSupport for GPS at 1st UART");
}
else
{
printf("\n\rSupport for GPS at 2nd UART");
}
#else // (__AVR_ATmega644__)
printf("\n\rSupport for GPS at 1st UART");
#endif
#endif
 
SetNeutral();
 
ROT_OFF;
beeptime = 2000;
ExternControl.Digital[0] = 0x55;
 
BeepTime = 2000;
ExternControl.Digital[0] = 0x55;
 
 
printf("\n\rControl: ");
if (ParamSet.GlobalConfig & CFG_HEADING_HOLD) printf("HeadingHold");
printf("\n\rSteuerung: ");
if (EE_Parameter.GlobalConfig & CFG_HEADING_HOLD) printf("HeadingHold");
else printf("Neutral");
 
printf("\n\n\r");
 
LCD_Clear();
 
LcdClear();
I2CTimeout = 5000;
 
WinkelOut.Orientation = 1;
while (1)
{
if(UpdateMotor) // control interval
{
UpdateMotor=0; // reset Flag, is enabled every 2 ms by isr of timer0
//PORTD |= (1<<PORTD4);
MotorControl();
//PORTD &= ~(1<<PORTD4);
 
SendMotorData();
 
if(UpdateMotor) // ReglerIntervall
{
UpdateMotor=0;
//PORTD |= 0x08;
if(WinkelOut.CalcState) CalMk3Mag();
else MotorRegler();
//PORTD &= ~0x08;
SendMotorData();
ROT_OFF;
 
if(PcAccess) PcAccess--;
else
{
DubWiseKeys[0] = 0;
if(PcZugriff) PcZugriff--;
else
{
DubWiseKeys[0] = 0;
DubWiseKeys[1] = 0;
ExternControl.Config = 0;
ExternStickPitch= 0;
ExternStickNick = 0;
ExternStickRoll = 0;
ExternStickYaw = 0;
}
 
ExternStickGier = 0;
}
if(SenderOkay) SenderOkay--;
if(!I2CTimeout)
{
I2CTimeout = 5;
I2C_Reset();
if((BeepModulation == 0xFFFF) && MotorsOn)
{
BeepTime = 10000; // 1 second
BeepModulation = 0x0080;
}
}
else
{
I2CTimeout--;
ROT_OFF;
}
 
if(SIO_DEBUG && (!UpdateMotor || !MotorsOn))
{
USART0_TransmitTxData();
USART0_ProcessRxData();
}
else USART0_ProcessRxData();
 
if(CheckDelay(timer))
{
if(UBat < ParamSet.LowVoltageWarning)
{
if(BeepModulation == 0xFFFF)
{
BeepTime = 6000; // 0.6 seconds
BeepModulation = 0x0300;
}
I2CTimeout = 5;
i2c_reset();
if((BeepMuster == 0xffff) && MotorenEin)
{
beeptime = 10000;
BeepMuster = 0x0080;
}
}
#ifdef USE_NAVICTRL
SPI_StartTransmitPacket();
SendSPI = 4;
#endif
timer = SetDelay(20); // every 20 ms
}
}
else
{
I2CTimeout--;
ROT_OFF;
}
if(SIO_DEBUG && (!UpdateMotor || !MotorenEin))
{
DatenUebertragung();
BearbeiteRxDaten();
}
else BearbeiteRxDaten();
if(CheckDelay(timer))
{
if(UBat < EE_Parameter.UnterspannungsWarnung)
{
if(BeepMuster == 0xffff)
{
beeptime = 6000;
BeepMuster = 0x0300;
}
}
/* if(SendVersionToNavi)
{
SPI_StartTransmitPacket(SPI_CMD_VERSION);//#
SendVersionToNavi = 0;
}
else SPI_StartTransmitPacket(SPI_CMD_VALUE);//#
*/
SPI_StartTransmitPacket();//#
 
#ifdef USE_NAVICTRL
if(!SendSPI)
{ // SendSPI is decremented in timer0.c with a rate of 9.765 kHz.
// within the SPI_TransmitByte() routine the value is set to 4.
// I.e. the SPI_TransmitByte() is called at a rate of 9.765 kHz/4= 2441.25 Hz,
// and therefore the time of transmission of a complete spi-packet (32 bytes) is 32*4/9.765 kHz = 13.1 ms.
SPI_TransmitByte();
}
#endif
SendSPI = 4;
timer = SetDelay(20);
}
//if(UpdateMotor) DebugOut.Analog[26]++;
}
if(!SendSPI) { SPI_TransmitByte(); }
}
return (1);
return (1);
}
 
/branches/V0.69k Code Redesign killagreg/main.h
1,8 → 1,6
#ifndef _MAIN_H
#define _MAIN_H
#define _MAIN_H
 
#include <avr/io.h>
 
//Hier die Quarz Frequenz einstellen
#if defined (__AVR_ATmega32__)
#define SYSCLK 20000000L //Quarz Frequenz in Hz
10,27 → 8,92
 
#if defined (__AVR_ATmega644__)
#define SYSCLK 20000000L //Quarz Frequenz in Hz
//#define SYSCLK 16000000L //Quarz Frequenz in Hz
#endif
 
#if defined (__AVR_ATmega644P__)
#define SYSCLK 20000000L //Quarz Frequenz in Hz
#endif
// neue Hardware
#define ROT_OFF {if(PlatinenVersion == 10) PORTB &=~0x01; else PORTB |= 0x01;}
#define ROT_ON {if(PlatinenVersion == 10) PORTB |= 0x01; else PORTB &=~0x01;}
#define ROT_FLASH PORTB ^= 0x01
#define GRN_OFF PORTB &=~0x02
#define GRN_ON PORTB |= 0x02
#define GRN_FLASH PORTB ^= 0x02
 
#define F_CPU SYSCLK
//#ifndef F_CPU
//#error ################## F_CPU nicht definiert oder ungültig #############
//#endif
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#define EEPROM_ADR_VALID 1
#define EEPROM_ADR_ACTIVE_SET 2
#define EEPROM_ADR_LAST_OFFSET 3
 
// neue Hardware
#define ROT_OFF {if(BoardRelease == 10) PORTB &=~(1<<PORTB0); else PORTB |= (1<<PORTB0);}
#define ROT_ON {if(BoardRelease == 10) PORTB |= (1<<PORTB0); else PORTB &=~(1<<PORTB0);}
#define ROT_FLASH PORTB ^= (1<<PORTB0)
#define GRN_OFF PORTB &=~(1<<PORTB1)
#define GRN_ON PORTB |= (1<<PORTB1)
#define GRN_FLASH PORTB ^= (1<<PORTB1)
#define EEPROM_ADR_ACC_NICK 4
#define EEPROM_ADR_ACC_ROLL 6
#define EEPROM_ADR_ACC_Z 8
 
#include <inttypes.h>
#define EEPROM_ADR_PARAM_BEGIN 100
 
extern uint8_t BoardRelease;
#define CFG_HOEHENREGELUNG 0x01
#define CFG_HOEHEN_SCHALTER 0x02
#define CFG_HEADING_HOLD 0x04
#define CFG_KOMPASS_AKTIV 0x08
#define CFG_KOMPASS_FIX 0x10
#define CFG_GPS_AKTIV 0x20
#define CFG_ACHSENKOPPLUNG_AKTIV 0x40
#define CFG_DREHRATEN_BEGRENZER 0x80
 
#define CFG_LOOP_OBEN 0x01
#define CFG_LOOP_UNTEN 0x02
#define CFG_LOOP_LINKS 0x04
#define CFG_LOOP_RECHTS 0x08
 
//#define SYSCLK
//extern unsigned long SYSCLK;
extern volatile int i_Nick[20],i_Roll[20],DiffNick,DiffRoll;
extern volatile unsigned char SenderOkay;
extern unsigned char CosinusNickWinkel, CosinusRollWinkel;
extern unsigned char PlatinenVersion;
extern unsigned char SendVersionToNavi;
void ReadParameterSet (unsigned char number, unsigned char *buffer, unsigned char length);
void WriteParameterSet(unsigned char number, unsigned char *buffer, unsigned char length);
extern unsigned char GetActiveParamSetNumber(void);
extern unsigned char EEPromArray[];
 
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/boot.h>
#include <avr/wdt.h>
 
#include "old_macros.h"
 
#include "_Settings.h"
#include "printf_P.h"
#include "timer0.h"
#include "uart.h"
#include "analog.h"
#include "twimaster.h"
#include "menu.h"
#include "rc.h"
#include "fc.h"
#include "gps.h"
#include "spi.h"
 
 
#ifndef EEMEM
#define EEMEM __attribute__ ((section (".eeprom")))
#endif
 
#define DEBUG_DISPLAY_INTERVALL 123 // in ms
 
 
#define DELAY_US(x) ((unsigned int)( (x) * 1e-6 * F_CPU ))
#endif //_MAIN_H
 
 
/branches/V0.69k Code Redesign killagreg/makefile
1,32 → 1,31
#--------------------------------------------------------------------
# MCU name
#MCU = atmega644
MCU = atmega644p
MCU = atmega644
F_CPU = 20000000
#-------------------------------------------------------------------
VERSION_MAJOR = 0
VERSION_MINOR = 69
HAUPT_VERSION = 0
NEBEN_VERSION = 69
VERSION_INDEX = 10
 
VERSION_COMPATIBLE = 7 # PC-Kompatibilität
VERSION_KOMPATIBEL = 7 # PC-Kompatibilität
#-------------------------------------------------------------------
#OPTIONS
# Use on of the extensions für a gps solution
# If no extension is used the support for the MK3MAG only is included.
#EXT = KILLAGREG
#EXT = NAVICTRL
#-------------------------------------------------------------------
 
ifeq ($(MCU), atmega32)
# FUSE_SETTINGS= -u -U lfuse:w:0xff:m -U hfuse:w:0xcf:m
 
HEX_NAME = MEGA32
endif
 
ifeq ($(MCU), atmega644)
FUSE_SETTINGS = -u -U lfuse:w:0xff:m -U hfuse:w:0xdf:m
#FUSE_SETTINGS = -U lfuse:w:0xff:m -U hfuse:w:0xdf:m
# -u bei neuen Controllern wieder einspielen
HEX_NAME = MEGA644_$(EXT)
HEX_NAME = MEGA644
endif
 
ifeq ($(MCU), atmega644p)
FUSE_SETTINGS = -u -U lfuse:w:0xff:m -U hfuse:w:0xdf:m
HEX_NAME = MEGA644p_$(EXT)
HEX_NAME = MEGA644
endif
 
 
45,40 → 44,39
# Target file name (without extension).
 
ifeq ($(VERSION_INDEX), 0)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)a
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)a
endif
ifeq ($(VERSION_INDEX), 1)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)b
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)b
endif
ifeq ($(VERSION_INDEX), 2)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)c
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)c
endif
ifeq ($(VERSION_INDEX), 3)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)d
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)d
endif
ifeq ($(VERSION_INDEX), 4)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)e
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)e
endif
ifeq ($(VERSION_INDEX), 5)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)f
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)f
endif
ifeq ($(VERSION_INDEX), 6)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)g
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)g
endif
ifeq ($(VERSION_INDEX), 7)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)h
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)h
endif
ifeq ($(VERSION_INDEX), 8)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)i
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)i
endif
ifeq ($(VERSION_INDEX), 9)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)j
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)j
endif
ifeq ($(VERSION_INDEX), 10)
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)k
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(HAUPT_VERSION)_$(NEBEN_VERSION)k
endif
 
 
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
85,19 → 83,9
 
##########################################################################################################
# List C source files here. (C dependencies are automatically generated.)
SRC = main.c uart.c printf_P.c timer0.c timer2.c analog.c menu.c led.c
SRC += twimaster.c rc.c fc.c eeprom.c fifo.c
ifeq ($(MCU), atmega644p)
SRC += uart1.c
endif
ifeq ($(EXT), KILLAGREG)
SRC += mm3.c mymath.c gps.c ubx.c
else
SRC += mk3mag.c
endif
ifeq ($(EXT), NAVICTRL)
SRC += spi.c
endif
SRC = main.c uart.c printf_P.c timer0.c analog.c menu.c
SRC += twimaster.c rc.c fc.c GPS.c spi.c
 
##########################################################################################################
 
 
139,18 → 127,9
#CFLAGS += -std=c99
CFLAGS += -std=gnu99
 
CFLAGS += -DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_COMPATIBLE=$(VERSION_COMPATIBLE) -DVERSION_INDEX=$(VERSION_INDEX)
CFLAGS += -DVERSION_HAUPTVERSION=$(HAUPT_VERSION) -DVERSION_NEBENVERSION=$(NEBEN_VERSION) -DVERSION_KOMPATIBEL=$(VERSION_KOMPATIBEL) -DVERSION_INDEX=$(VERSION_INDEX)
 
ifeq ($(EXT), KILLAGREG)
CFLAGS += -DUSE_KILLAGREG
endif
ifeq ($(EXT), NAVICTRL)
CFLAGS += -DUSE_NAVICTRL
endif
 
 
 
 
# Optional assembler flags.
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
/branches/V0.69k Code Redesign killagreg/menu.c
4,31 → 4,15
// + www.MikroKopter.com
// + see the File "License.txt" for further Informations
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <stdlib.h>
#include <inttypes.h>
#include "main.h"
#include "eeprom.h"
#include "timer2.h"
#include "fc.h"
#include "rc.h"
#include "uart.h"
#include "printf_P.h"
#include "analog.h"
#ifdef USE_KILLAGREG
#include "mm3.h"
#include "ubx.h"
#endif
#include "_Settings.h"
 
unsigned int TestInt = 0;
#define ARRAYGROESSE 10
unsigned char Array[ARRAYGROESSE] = {1,2,3,4,5,6,7,8,9,10};
char DisplayBuff[80] = "Hallo Welt";
unsigned char DispPtr = 0;
unsigned char RemoteTasten = 0;
 
#define ARRAYSIZE 10
uint8_t Array[ARRAYSIZE] = {1,2,3,4,5,6,7,8,9,10};
#define DISPLAYBUFFSIZE 80
int8_t DisplayBuff[DISPLAYBUFFSIZE] = "Hello World";
uint8_t DispPtr = 0;
uint8_t RemoteButtons = 0;
 
#define KEY1 0x01
#define KEY2 0x02
#define KEY3 0x04
35,204 → 19,115
#define KEY4 0x08
#define KEY5 0x10
 
/************************************/
/* Clear LCD Buffer */
/************************************/
void LCD_Clear(void)
void LcdClear(void)
{
uint8_t i;
for( i = 0; i < DISPLAYBUFFSIZE; i++) DisplayBuff[i] = ' ';
unsigned char i;
for(i=0;i<80;i++) DisplayBuff[i] = ' ';
}
 
 
/************************************/
/* Update Menu on LCD */
/************************************/
// Display with 20 characters in 4 lines
void LCD_PrintMenu(void)
void Menu(void)
{
#ifdef USE_KILLAGREG
static uint8_t MaxMenuItem = 14;
#else
static uint8_t MaxMenuItem = 11;
#endif
static uint8_t MenuItem=0;
 
// if KEY1 is activated goto previous menu item
if(RemoteButtons & KEY1)
{
if(MenuItem) MenuItem--;
else MenuItem = MaxMenuItem;
LCD_Clear();
RemotePollDisplayLine = -1;
}
// if KEY2 is activated goto next menu item
if(RemoteButtons & KEY2)
{
if (MenuItem == MaxMenuItem) MenuItem = 0;
else MenuItem++;
LCD_Clear();
RemotePollDisplayLine = -1;
}
 
// if KEY1 and KEY2 is activated goto initial menu item
if((RemoteButtons & KEY1) && (RemoteButtons & KEY2)) MenuItem = 0;
 
// print menu item number in the upper right corner
if(MenuItem < 10)
{
LCD_printfxy(17,0,"[%i]",MenuItem);
}
else
{
LCD_printfxy(16,0,"[%i]",MenuItem);
}
 
switch(MenuItem)
{
case 0:// Version Info Menu Item
static unsigned char MaxMenue = 11,MenuePunkt=0;
if(RemoteTasten & KEY1) { if(MenuePunkt) MenuePunkt--; else MenuePunkt = MaxMenue; LcdClear(); RemotePollDisplayLine = -1; }
if(RemoteTasten & KEY2) { MenuePunkt++; LcdClear(); RemotePollDisplayLine = -1;}
if((RemoteTasten & KEY1) && (RemoteTasten & KEY2)) MenuePunkt = 0;
if(MenuePunkt < 10) {LCD_printfxy(17,0,"[%i]",MenuePunkt);} else {LCD_printfxy(16,0,"[%i]",MenuePunkt);};
switch(MenuePunkt)
{
case 0:
LCD_printfxy(0,0,"+ MikroKopter +");
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%d%c",BoardRelease/10,BoardRelease%10,VERSION_MAJOR, VERSION_MINOR,VERSION_INDEX+'a');
LCD_printfxy(0,2,"Setting: %d ", GetActiveParamSet());
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%d%c",PlatinenVersion/10,PlatinenVersion%10,VERSION_HAUPTVERSION, VERSION_NEBENVERSION,VERSION_INDEX+'a');
LCD_printfxy(0,2,"Setting: %d ",GetActiveParamSetNumber());
LCD_printfxy(0,3,"(c) Holger Buss");
// if(RemoteTasten & KEY3) TestInt--;
// if(RemoteTasten & KEY4) TestInt++;
break;
case 1:// Height Control Menu Item
if(ParamSet.GlobalConfig & CFG_HEIGHT_CONTROL)
{
LCD_printfxy(0,0,"Height: %5i",ReadingHeight);
LCD_printfxy(0,1,"Set Point: %5i",SetPointHeight);
LCD_printfxy(0,2,"Air Press.:%5i",ReadingAirPressure);
LCD_printfxy(0,3,"Offset :%5i",PressureSensorOffset);
case 1:
if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
{
LCD_printfxy(0,0,"Hoehe: %5i",HoehenWert);
LCD_printfxy(0,1,"SollHoehe: %5i",SollHoehe);
LCD_printfxy(0,2,"Luftdruck: %5i",MessLuftdruck);
LCD_printfxy(0,3,"Off : %5i",DruckOffsetSetting);
}
else
{
LCD_printfxy(0,1,"No ");
LCD_printfxy(0,2,"Height Control");
else
{
LCD_printfxy(0,1,"Keine ");
LCD_printfxy(0,2,"Höhenregelung");
}
 
break;
case 2:// Attitude Menu Item
LCD_printfxy(0,0,"Attitude");
LCD_printfxy(0,1,"Pitch: %5i",IntegralPitch/1024);
case 2:
LCD_printfxy(0,0,"akt. Lage");
LCD_printfxy(0,1,"Nick: %5i",IntegralNick/1024);
LCD_printfxy(0,2,"Roll: %5i",IntegralRoll/1024);
LCD_printfxy(0,3,"Heading: %5i",CompassHeading);
LCD_printfxy(0,3,"Kompass: %5i",KompassValue);
break;
case 3:// Remote Control Channel Menu Item
LCD_printfxy(0,0,"C1:%4i C2:%4i ",PPM_in[1],PPM_in[2]);
LCD_printfxy(0,1,"C3:%4i C4:%4i ",PPM_in[3],PPM_in[4]);
LCD_printfxy(0,2,"C5:%4i C6:%4i ",PPM_in[5],PPM_in[6]);
LCD_printfxy(0,3,"C7:%4i C8:%4i ",PPM_in[7],PPM_in[8]);
case 3:
LCD_printfxy(0,0,"K1:%4i K2:%4i ",PPM_in[1],PPM_in[2]);
LCD_printfxy(0,1,"K3:%4i K4:%4i ",PPM_in[3],PPM_in[4]);
LCD_printfxy(0,2,"K5:%4i K6:%4i ",PPM_in[5],PPM_in[6]);
LCD_printfxy(0,3,"K7:%4i K8:%4i ",PPM_in[7],PPM_in[8]);
break;
case 4:// Remote Control Mapping Menu Item
LCD_printfxy(0,0,"Pi:%4i Ro:%4i ",PPM_in[ParamSet.ChannelAssignment[CH_PITCH]],PPM_in[ParamSet.ChannelAssignment[CH_ROLL]]);
LCD_printfxy(0,1,"Gs:%4i Ya:%4i ",PPM_in[ParamSet.ChannelAssignment[CH_THRUST]],PPM_in[ParamSet.ChannelAssignment[CH_YAW]]);
LCD_printfxy(0,2,"P1:%4i P2:%4i ",PPM_in[ParamSet.ChannelAssignment[CH_POTI1]],PPM_in[ParamSet.ChannelAssignment[CH_POTI2]]);
LCD_printfxy(0,3,"P3:%4i P4:%4i ",PPM_in[ParamSet.ChannelAssignment[CH_POTI3]],PPM_in[ParamSet.ChannelAssignment[CH_POTI4]]);
case 4:
LCD_printfxy(0,0,"Ni:%4i Ro:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_NICK]],PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]);
LCD_printfxy(0,1,"Gs:%4i Gi:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_GAS]],PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]);
LCD_printfxy(0,2,"P1:%4i P2:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]],PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]]);
LCD_printfxy(0,3,"P3:%4i P4:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]],PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]]);
break;
case 5:// Gyro Sensor Menu Item
case 5:
LCD_printfxy(0,0,"Gyro - Sensor");
if(BoardRelease == 10)
if(PlatinenVersion == 10)
{
LCD_printfxy(0,1,"Pitch %4i (%3i)",AdValueGyrPitch - AdNeutralPitch, AdNeutralPitch);
LCD_printfxy(0,2,"Roll %4i (%3i)",AdValueGyrRoll - AdNeutralRoll, AdNeutralRoll);
LCD_printfxy(0,3,"Yaw %4i (%3i)",Reading_GyroYaw, AdNeutralYaw);
LCD_printfxy(0,1,"Nick %4i (%3i)",AdWertNick - AdNeutralNick, AdNeutralNick);
LCD_printfxy(0,2,"Roll %4i (%3i)",AdWertRoll - AdNeutralRoll, AdNeutralRoll);
LCD_printfxy(0,3,"Gier %4i (%3i)",MesswertGier, AdNeutralGier);
}
else
else
{
LCD_printfxy(0,1,"Pitch %4i (%3i)",AdValueGyrPitch - AdNeutralPitch, AdNeutralPitch/2);
LCD_printfxy(0,2,"Roll %4i (%3i)",AdValueGyrRoll - AdNeutralRoll, AdNeutralRoll/2);
LCD_printfxy(0,3,"Yaw %4i (%3i)",Reading_GyroYaw, AdNeutralYaw/2);
LCD_printfxy(0,1,"Nick %4i (%3i)",AdWertNick - AdNeutralNick, AdNeutralNick/2);
LCD_printfxy(0,2,"Roll %4i (%3i)",AdWertRoll - AdNeutralRoll, AdNeutralRoll/2);
LCD_printfxy(0,3,"Gier %4i (%3i)",MesswertGier, AdNeutralGier/2);
}
break;
case 6:// Acceleration Sensor Menu Item
case 6:
LCD_printfxy(0,0,"ACC - Sensor");
LCD_printfxy(0,1,"Pitch %4i (%3i)",AdValueAccPitch, NeutralAccX);
LCD_printfxy(0,2,"Roll %4i (%3i)",AdValueAccRoll, NeutralAccY);
LCD_printfxy(0,3,"Height %4i (%3i)",Mean_AccTop, (int)NeutralAccZ);
LCD_printfxy(0,1,"Nick %4i (%3i)",AdWertAccNick,NeutralAccX);
LCD_printfxy(0,2,"Roll %4i (%3i)",AdWertAccRoll,NeutralAccY);
LCD_printfxy(0,3,"Hoch %4i (%3i)",Mittelwert_AccHoch/*accumulate_AccHoch / messanzahl_AccHoch*/,(int)NeutralAccZ);
break;
case 7:// Accumulator Voltage / Remote Control Level
LCD_printfxy(0,1,"Voltage: %5i",UBat);
LCD_printfxy(0,2,"RC-Level: %5i",RC_Quality);
case 7:
LCD_printfxy(0,1,"Spannung: %5i",UBat);
LCD_printfxy(0,2,"Empf.Pegel:%5i",SenderOkay);
break;
case 8:// Compass Menu Item
LCD_printfxy(0,0,"Compass ");
LCD_printfxy(0,1,"Course: %5i",CompassCourse);
LCD_printfxy(0,2,"Heading: %5i",CompassHeading);
LCD_printfxy(0,3,"OffCourse: %5i",CompassOffCourse);
case 8:
LCD_printfxy(0,0,"Kompass ");
LCD_printfxy(0,1,"Richtung: %5i",KompassRichtung);
LCD_printfxy(0,2,"Messwert: %5i",KompassValue);
LCD_printfxy(0,3,"Start: %5i",KompassStartwert);
break;
case 9:// Poti Menu Item
LCD_printfxy(0,0,"Po1: %3i Po5: %3i" ,Poti1,Poti5); //PPM24-Extesion
LCD_printfxy(0,1,"Po2: %3i Po6: %3i" ,Poti2,Poti6); //PPM24-Extesion
LCD_printfxy(0,2,"Po3: %3i Po7: %3i" ,Poti3,Poti7); //PPM24-Extesion
LCD_printfxy(0,3,"Po4: %3i Po8: %3i" ,Poti4,Poti8); //PPM24-Extesion
case 9:
LCD_printfxy(0,0,"Poti1: %3i",Poti1);
LCD_printfxy(0,1,"Poti2: %3i",Poti2);
LCD_printfxy(0,2,"Poti3: %3i",Poti3);
LCD_printfxy(0,3,"Poti4: %3i",Poti4);
break;
case 10:// Servo Menu Item
case 10:
LCD_printfxy(0,0,"Servo " );
LCD_printfxy(0,1,"Setpoint %3i",FCParam.ServoPitchControl);
LCD_printfxy(0,2,"Position: %3i",ServoValue);
LCD_printfxy(0,3,"Range:%3i-%3i",ParamSet.ServoPitchMin, ParamSet.ServoPitchMax);
LCD_printfxy(0,1,"Setpoint %3i",Parameter_ServoNickControl);
LCD_printfxy(0,2,"Stellung: %3i",ServoValue);
LCD_printfxy(0,3,"Range:%3i-%3i",EE_Parameter.ServoNickMin,EE_Parameter.ServoNickMax);
break;
case 11://Extern Control
case 11:
LCD_printfxy(0,0,"ExternControl " );
LCD_printfxy(0,1,"Pi:%4i Ro:%4i ",ExternControl.Pitch, ExternControl.Roll);
LCD_printfxy(0,2,"Th:%4i Ya:%4i ",ExternControl.Thrust, ExternControl.Yaw);
LCD_printfxy(0,3,"Hi:%4i Cf:%4i ",ExternControl.Height, ExternControl.Config);
LCD_printfxy(0,1,"Ni:%4i Ro:%4i ",ExternControl.Nick,ExternControl.Roll);
LCD_printfxy(0,2,"Gs:%4i Gi:%4i ",ExternControl.Gas,ExternControl.Gier);
LCD_printfxy(0,3,"Hi:%4i Cf:%4i ",ExternControl.Hight,ExternControl.Config);
break;
 
#ifdef USE_KILLAGREG
case 12://GPS Lat/Lon coords
if (GPSInfo.status == INVALID)
{
LCD_printfxy(0,0,"No GPS data!");
}
else
{
switch (GPSInfo.satfix)
{
case SATFIX_NONE:
LCD_printfxy(0,0,"Sats: %d Fix: No", GPSInfo.satnum);
break;
case SATFIX_2D:
LCD_printfxy(0,0,"Sats: %d Fix: 2D", GPSInfo.satnum);
break;
case SATFIX_3D:
LCD_printfxy(0,0,"Sats: %d Fix: 3D", GPSInfo.satnum);
break;
default:
LCD_printfxy(0,0,"Sats: %d Fix: ??", GPSInfo.satnum);
break;
}
int16_t i1,i2,i3;
i1 = (int16_t)(GPSInfo.longitude/10000000L);
i2 = abs((int16_t)((GPSInfo.longitude%10000000L)/10000L));
i3 = abs((int16_t)(((GPSInfo.longitude%10000000L)%10000L)/10L));
LCD_printfxy(0,1,"Lon: %d.%.3d%.3d deg",i1, i2, i3);
i1 = (int16_t)(GPSInfo.latitude/10000000L);
i2 = abs((int16_t)((GPSInfo.latitude%10000000L)/10000L));
i3 = abs((int16_t)(((GPSInfo.latitude%10000000L)%10000L)/10L));
LCD_printfxy(0,2,"Lat: %d.%.3d%.3d deg",i1, i2, i3);
i1 = (int16_t)(GPSInfo.altitude/1000L);
i2 = abs((int16_t)(GPSInfo.altitude%1000L));
LCD_printfxy(0,3,"Alt: %d.%.3d m",i1, i2);
}
break;
case 13:// MM3 Kompass
LCD_printfxy(0,0,"MM3 Offset");
LCD_printfxy(0,1,"X_Offset: %3i",MM3_calib.X_off);
LCD_printfxy(0,2,"Y_Offset: %3i",MM3_calib.Y_off);
LCD_printfxy(0,3,"Z_Offset: %3i",MM3_calib.Z_off);
break;
case 14://MM3 Range
LCD_printfxy(0,0,"MM3 Range");
LCD_printfxy(0,1,"X_Range: %4i",MM3_calib.X_range);
LCD_printfxy(0,2,"Y_Range: %4i",MM3_calib.Y_range);
LCD_printfxy(0,3,"Z_Range: %4i",MM3_calib.Z_range);
break;
#endif
 
default: MaxMenuItem = MenuItem - 1;
MenuItem = 0;
default: MaxMenue = MenuePunkt - 1;
MenuePunkt = 0;
break;
}
RemoteButtons = 0;
RemoteTasten = 0;
}
/branches/V0.69k Code Redesign killagreg/menu.h
1,16 → 1,6
#ifndef _MENU_H
#define _MENU_H
extern void Menu(void);
extern void LcdClear(void);
extern char DisplayBuff[80];
extern unsigned char DispPtr;
extern unsigned char RemoteTasten;
 
#include <inttypes.h>
 
#define DISPLAYBUFFSIZE 80
 
extern void LCD_PrintMenu(void);
extern void LCD_Clear(void);
extern int8_t DisplayBuff[DISPLAYBUFFSIZE];
extern uint8_t DispPtr;
extern uint8_t RemoteButtons;
 
#endif //_MENU_H
 
 
/branches/V0.69k Code Redesign killagreg/printf_P.c
1,6 → 1,6
// Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist nicht von der Lizenz für den MikroKopter-Teil unterstellt
 
/*
/*
Copyright (C) 1993 Free Software Foundation
 
This file is part of the GNU IO Library. This library is free
86,10 → 86,7
#include <varargs.h>
#endif
 
#include "old_macros.h"
#include "printf_P.h"
#include "menu.h"
#include "uart.h"
#include "main.h"
 
 
//#define LIGHTPRINTF
103,22 → 100,22
}
 
 
void PRINT(const char * ptr, unsigned int len)
void PRINT(const char * ptr, unsigned int len)
{
for(;len;len--) Putchar(*ptr++);
}
 
void PRINTP(const char * ptr, unsigned int len)
void PRINTP(const char * ptr, unsigned int len)
{
for(;len;len--) Putchar(pgm_read_byte(ptr++));
}
 
void PAD_SP(signed char howmany)
void PAD_SP(signed char howmany)
{
for(;howmany>0;howmany--) Putchar(' ');
}
 
void PAD_0(signed char howmany)
void PAD_0(signed char howmany)
{
for(;howmany>0;howmany--) Putchar('0');
}
172,7 → 169,7
 
PrintZiel = ziel; // bestimmt, LCD oder UART
va_start(ap, fmt0);
 
fmt = fmt0;
 
/*
209,7 → 206,7
_ulong = flags&SHORTINT ? (unsigned long)(unsigned short)_d : (unsigned long)_d;
}
}
 
#ifndef LIGHTPRINTF
if(ch==' ') {
/*
293,7 → 290,7
_d=va_arg(ap, int);
_ulong = flags&SHORTINT ? (long)(short)_d : (long)_d;
}
 
if ((long)_ulong < 0) {
_ulong = -_ulong;
sign = '-';
301,7 → 298,7
base = DEC;
goto number;
} else
/*
/*
if (ch=='n') {
if (flags & LONGINT)
*va_arg(ap, long *) = ret;
309,10 → 306,10
*va_arg(ap, short *) = ret;
else
*va_arg(ap, int *) = ret;
continue; // no output
continue; // no output
} else
*/
#ifndef LIGHTPRINTF
#ifndef LIGHTPRINTF
if (ch=='O'||ch=='o') {
if (ch=='O')
flags |= LONGINT;
360,7 → 357,7
size = strlen(cp);
sign = '\0';
} else
#endif /* LIGHTPRINTF */
#endif /* LIGHTPRINTF */
if(ch=='U'||ch=='u') {
if (ch=='U')
flags |= LONGINT;
404,7 → 401,7
_ulong /= base;
} while (notlastdigit);
#ifndef LIGHTPRINTF
// handle octal leading 0
// handle octal leading 0
if (base==OCT && flags & ALT && *cp != '0')
*--cp = '0';
#endif
/branches/V0.69k Code Redesign killagreg/rc.c
1,5 → 1,5
/*#######################################################################################
Decodieren eines RC Summen Signals
Decodieren eines RC Summen Signals
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 04.2007 Holger Buss
8,170 → 8,75
// + see the File "License.txt" for further Informations
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 
#include "rc.h"
#include "main.h"
 
volatile int16_t PPM_in[15]; //PPM24 supports 12 channels per frame
volatile int16_t PPM_diff[15];
volatile uint8_t NewPpmData = 1;
volatile int16_t RC_Quality = 0;
volatile int PPM_in[11];
volatile int PPM_diff[11]; // das diffenzierte Stick-Signal
volatile unsigned char NewPpmData = 1;
 
volatile uint8_t NewRCFrames = 0;
 
 
/***************************************************************/
/* 16bit timer 1 is used to decode the PPM-Signal */
/***************************************************************/
void RC_Init (void)
//############################################################################
//zum decodieren des PPM-Signals wird Timer1 mit seiner Input
//Capture Funktion benutzt:
void rc_sum_init (void)
//############################################################################
{
uint8_t sreg = SREG;
TCCR1B=(1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);//|(1 << WGM12); //timer1 prescale 64
 
// disable all interrupts before reconfiguration
cli();
 
// PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
DDRD &= ~(1<<DDD6);
PORTD |= (1<<PORTD6);
 
// Channel 5,6,7 is decoded to servo signals at pin PD5 (J3), PD4(J4), PD3(J5)
// set as output
DDRD |= (1<<DDD5)|(1<<DDD4);
// low level
PORTD &= ~((1<<PORTD5)|(1<<PORTD4));
 
// PD3 can't be used in FC 1.1 if 2nd UART is activated
// because TXD1 is at that port
if(BoardRelease == 10)
{
DDRD |= (1<<PORTD3);
PORTD &= ~(1<<PORTD3);
}
 
// Timer/Counter1 Control Register A, B, C
 
// Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
// Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
// Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
// Enable input capture noise cancler (bit: ICNC1=1)
// Trigger on positive edge of the input capture pin (bit: ICES1=1),
// Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs
// The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10));
TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12));
TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);
TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B));
 
// Timer/Counter1 Interrupt Mask Register
 
// Enable Input Capture Interrupt (bit: ICIE1=1)
// Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0)
// Enable Overflow Interrupt (bit: TOIE1=0)
TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A));
TIMSK1 |= (1<<ICIE1)|(1<<TOIE1);
 
RC_Quality = 0;
 
SREG = sreg;
// PWM
//TCCR1A = (1 << COM1B1) | (1 << WGM11) | (1 << WGM10);
//TCCR1B |= (1 << WGM12);
//OCR1B = 55;
TIMSK1 |= _BV(ICIE1);
AdNeutralGier = 0;
AdNeutralRoll = 0;
AdNeutralNick = 0;
return;
}
 
//############################################################################
//Diese Routine startet und inizialisiert den Timer für RC
SIGNAL(SIG_INPUT_CAPTURE1)
//############################################################################
 
// happens every 0.209712 s.
// check for at least one new frame per timer overflow (timeout)
ISR(TIMER1_OVF_vect)
{
if (NewRCFrames == 0) RC_Quality -= RC_Quality/8;
NewRCFrames = 0;
}
 
 
/********************************************************************/
/* Every time a positive edge is detected at PD6 */
/********************************************************************/
/* t-Frame
<----------------------------------------------------------------------->
____ ______ _____ ________ ______ sync gap ____
| | | | | | | | | | |
| | | | | | | | | | |
___| |_| |_| |_| |_.............| |________________|
<-----><-------><------><--------> <------> <---
t0 t1 t2 t4 tn t0
 
The PPM-Frame length is 22.5 ms.
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms.
The minimum duration of all channels at minimum value is 8 * 1 ms = 8 ms.
The maximum duration of all channels at maximum value is 8 * 2 ms = 16 ms.
The remaining time of (22.5 - 8 ms) ms = 14.5 ms to (22.5 - 16 ms) ms = 6.5 ms is
the syncronization gap.
*/
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
{
int16_t signal = 0, tmp;
static int16_t index;
static uint16_t oldICR1 = 0;
 
// 16bit Input Capture Register ICR1 contains the timer value TCNT1
// at the time the edge was detected
 
// calculate the time delay to the previous event time which is stored in oldICR1
// calculatiing the difference of the two uint16_t and converting the result to an int16_t
// implicit handles a timer overflow 65535 -> 0 the right way.
signal = (uint16_t) ICR1 - oldICR1;
oldICR1 = ICR1;
 
//sync gap? (3.52 ms < signal < 25.6 ms)
if((signal > 1100) && (signal < 8000))
{
// if a sync gap happens and there where at least 4 channels decoded before
// then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
if(index >= 4)
{
NewPpmData = 0; // Null means NewData for the first 4 channels
NewRCFrames++;
}
// synchronize channel index
index = 1;
}
else // within the PPM frame
{
if(index < 14) // PPM24 supports 12 channels
static unsigned int AltICR=0;
signed int signal = 0,tmp;
static int index;
signal = (unsigned int) ICR1 - AltICR;
AltICR = ICR1;
//Syncronisationspause?
// if((signal > (int) Parameter_UserParam2 * 10) && (signal < 8000))
if((signal > 1100) && (signal < 8000))
{
// check for valid signal length (0.8 ms < signal < 2.1984 ms)
// signal range is from 1.0ms/3.2us = 312 to 2.0ms/3.2us = 625
if((signal > 250) && (signal < 687))
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten
index = 1;
}
else
{
if(index < 10)
{
// shift signal to zero symmetric range -154 to 159
signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
// check for stable signal
if(abs(signal-PPM_in[index]) < 6)
{
if(RC_Quality < 200) RC_Quality +=10;
}
// calculate exponential history for signal
tmp = (3 * (PPM_in[index]) + signal) / 4;
if((signal > 250) && (signal < 687))
{
signal -= 466;
// Stabiles Signal
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
// tmp = (7 * (PPM_in[index]) + signal) / 8;
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
// calculate signal difference on good signal level
if(RC_Quality >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
if(tmp < signal-1) tmp++;
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
else PPM_diff[index] = 0;
PPM_in[index] = tmp; // update channel value
}
index++; // next channel
// demux sum signal for channels 5 to 7 to J3, J4, J5
if(index == 5) PORTD |= (1<<PORTD5); else PORTD &= ~(1<<PORTD5);
if(index == 6) PORTD |= (1<<PORTD4); else PORTD &= ~(1<<PORTD4);
if(BoardRelease == 10)
{
if(index == 7) PORTD |= (1<<PORTD3); else PORTD &= ~(1<<PORTD3);
}
PPM_in[index] = tmp;
}
index++;
if(index == 5) PORTD |= 0x20; else PORTD &= ~0x20; // Servosignal an J3 anlegen
if(index == 6) PORTD |= 0x10; else PORTD &= ~0x10; // Servosignal an J4 anlegen
if(index == 7) PORTD |= 0x08; else PORTD &= ~0x08; // Servosignal an J5 anlegen
}
}
if(RC_Quality) RC_Quality--;
}
 
 
/branches/V0.69k Code Redesign killagreg/rc.h
1,11 → 1,29
/*#######################################################################################
Derkodieren eines RC Summen Signals
#######################################################################################*/
 
#ifndef _RC_H
#define _RC_H
 
#include <inttypes.h>
#if defined (__AVR_ATmega32__)
#define TIMER_TEILER CK64
#define TIMER_RELOAD_VALUE 250
#endif
 
extern void RC_Init (void);
extern volatile int16_t PPM_in[15]; // the RC-Signal
extern volatile int16_t PPM_diff[15]; // the differentiated RC-Signal
extern volatile uint8_t NewPpmData; // 0 indicates a new recieved PPM Frame
extern volatile int16_t RC_Quality; // rc signal quality indicator (0 to 200)
#if defined (__AVR_ATmega644__)
//#define TIMER_TEILER CK64
#define TIMER_RELOAD_VALUE 250
//#define TIMER_TEILER CK256 // bei 20MHz
//#define TIMER_RELOAD_VALUE -78 // bei 20MHz
#endif
 
#define GAS PPM_in[2]
 
 
extern void rc_sum_init (void);
 
extern volatile int PPM_in[11];
extern volatile int PPM_diff[11]; // das diffenzierte Stick-Signal
extern volatile unsigned char NewPpmData;
 
#endif //_RC_H
/branches/V0.69k Code Redesign killagreg/spi.c
1,313 → 1,251
// ######################## SPI - FlightCtrl ###################
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include "_Settings.h"
#include "spi.h"
#include "fc.h"
#include "rc.h"
#include "eeprom.h"
#include "uart.h"
#include "timer0.h"
#include "main.h"
 
#define SPI_TXSYNCBYTE1 0xAA
#define SPI_TXSYNCBYTE2 0x83
#define SPI_RXSYNCBYTE1 0x81
#define SPI_RXSYNCBYTE2 0x55
 
typedef enum
{
SPI_SYNC1,
SPI_SYNC2,
SPI_DATA
} SPI_RXState_t;
//struct str_ToNaviCtrl_Version ToNaviCtrl_Version;
//struct str_FromNaviCtrl_Version FromNaviCtrl_Version;
struct str_ToNaviCtrl ToNaviCtrl;
struct str_FromNaviCtrl FromNaviCtrl;
 
unsigned char SPI_BufferIndex;
unsigned char SPI_RxBufferIndex;
 
// data exchange packets to and From NaviCtrl
ToNaviCtrl_t ToNaviCtrl;
FromNaviCtrl_t FromNaviCtrl;
volatile unsigned char SPI_Buffer[sizeof(FromNaviCtrl)];
unsigned char *SPI_TX_Buffer;
 
// rx packet buffer
#define SPI_RXBUFFER_LEN sizeof(FromNaviCtrl)
uint8_t SPI_RxBuffer[SPI_RXBUFFER_LEN];
uint8_t SPI_RxBufferIndex = 0;
uint8_t SPI_RxBuffer_Request = 0;
unsigned char SPITransferCompleted, SPI_ChkSum;
unsigned char SPI_RxDataValid;
 
// tx packet buffer
#define SPI_TXBUFFER_LEN sizeof(ToNaviCtrl)
uint8_t *SPI_TxBuffer;
uint8_t SPI_TxBufferIndex = 0;
unsigned char SPI_CommandSequence[] = { SPI_CMD_USER, SPI_CMD_STICK, SPI_CMD_USER, SPI_CMD_STICK, SPI_CMD_CAL_COMPASS };
unsigned char SPI_CommandCounter = 0;
 
uint8_t SPITransferCompleted, SPI_ChkSum;
uint8_t SPI_RxDataValid;
 
uint8_t SPI_CommandSequence[] = { SPI_CMD_USER, SPI_CMD_STICK, SPI_CMD_USER, SPI_CMD_STICK, SPI_CMD_CAL_COMPASS };
uint8_t SPI_CommandCounter = 0;
 
#ifdef USE_SPI_COMMUNICATION
 
/*********************************************/
/* Initialize SPI interface to NaviCtrl */
/*********************************************/
//------------------------------------------------------
void SPI_MasterInit(void)
{
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK); // Set MOSI and SCK output, all others input
SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT); // set Slave select port as output port
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK); // Set MOSI and SCK output, all others input
SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(0<<SPR0)|(0<<SPIE); // Enable SPI, Master, set clock rate fck/64
SPSR = 0;//(1<<SPI2X);
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT);
SPITransferCompleted = 1;
//SPDR = 0x00; // dummy write
ToNaviCtrl.Sync1 = 0xAA;
ToNaviCtrl.Sync2 = 0x83;
ToNaviCtrl.Command = SPI_CMD_USER;
ToNaviCtrl.IntegralNick = 0;
ToNaviCtrl.IntegralRoll = 0;
SPI_RxDataValid = 0;
}
 
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(0<<SPR0)|(0<<SPIE); // Enable SPI, Master, set clock rate fck/64
SPSR = 0;//(1<<SPI2X);
//------------------------------------------------------
void SPI_StartTransmitPacket(void)
{
//if ((SLAVE_SELECT_PORT & (1 << SPI_SLAVE_SELECT)) == 0) return; // transfer of prev. packet not completed
if (!SPITransferCompleted) return;
// _delay_us(30);
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave
SPI_TX_Buffer = (unsigned char *) &ToNaviCtrl;
ToNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++];
if (SPI_CommandCounter >= sizeof(SPI_CommandSequence)) SPI_CommandCounter = 0;
SPITransferCompleted = 0;
UpdateSPI_Buffer(); // update buffer
 
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // Deselect Slave
SPI_BufferIndex = 1;
//ebugOut.Analog[16]++;
// -- Debug-Output ---
//----
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
ToNaviCtrl.Chksum = ToNaviCtrl.Sync1;
SPDR = ToNaviCtrl.Sync1; // Start transmission
// SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave
 
SPI_TxBuffer = (uint8_t *) &ToNaviCtrl; // set pointer to tx-buffer
SPITransferCompleted = 1;
// initialize data packet to NaviControl
ToNaviCtrl.Sync1 = SPI_TXSYNCBYTE1;
ToNaviCtrl.Sync2 = SPI_TXSYNCBYTE2;
 
ToNaviCtrl.Command = SPI_CMD_USER;
ToNaviCtrl.IntegralPitch = 0;
ToNaviCtrl.IntegralRoll = 0;
SPI_RxDataValid = 0;
}
 
 
/**********************************************************/
/* Update Data transferd by the SPI from/to NaviCtrl */
/**********************************************************/
void UpdateSPI_Buffer(void)
//------------------------------------------------------
//SIGNAL(SIG_SPI)
void SPI_TransmitByte(void)
{
int16_t tmp;
cli(); // stop all interrupts to avoid writing of new data during update of that packet.
static unsigned char SPI_RXState = 0;
unsigned char rxdata;
static unsigned char rxchksum;
if (SPITransferCompleted) return;
if (!(SPSR & (1 << SPIF))) return;
SendSPI = 4;
// _delay_us(30);
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave
rxdata = SPDR;
switch ( SPI_RXState)
{
case 0:
SPI_RxBufferIndex = 0;
//DebugOut.Analog[17]++;
rxchksum = rxdata;
if (rxdata == 0x81 ) { SPI_RXState = 1; } // 1. Syncbyte ok
break;
 
// update content of packet to NaviCtrl
ToNaviCtrl.IntegralPitch = (int16_t) (IntegralPitch / 108);
ToNaviCtrl.IntegralRoll = (int16_t) (IntegralRoll / 108);
ToNaviCtrl.GyroHeading = YawGyroHeading / YAW_GYRO_DEG_FACTOR;
ToNaviCtrl.GyroPitch = Reading_GyroPitch;
ToNaviCtrl.GyroRoll = Reading_GyroRoll;
ToNaviCtrl.GyroYaw = Reading_GyroYaw;
ToNaviCtrl.AccPitch = (int16_t) ACC_AMPLIFY * (NaviAccPitch / NaviCntAcc);
ToNaviCtrl.AccRoll = (int16_t) ACC_AMPLIFY * (NaviAccRoll / NaviCntAcc);
NaviCntAcc = 0; NaviAccPitch = 0; NaviAccRoll = 0;
 
switch(ToNaviCtrl.Command)
{
case SPI_CMD_USER:
ToNaviCtrl.Param.Byte[0] = FCParam.UserParam1;
ToNaviCtrl.Param.Byte[1] = FCParam.UserParam2;
ToNaviCtrl.Param.Byte[2] = FCParam.UserParam3;
ToNaviCtrl.Param.Byte[3] = FCParam.UserParam4;
ToNaviCtrl.Param.Byte[4] = FCParam.UserParam5;
ToNaviCtrl.Param.Byte[5] = FCParam.UserParam6;
ToNaviCtrl.Param.Byte[6] = FCParam.UserParam7;
ToNaviCtrl.Param.Byte[7] = FCParam.UserParam8;
break;
 
case SPI_CMD_STICK:
tmp = PPM_in[ParamSet.ChannelAssignment[CH_THRUST]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128;
ToNaviCtrl.Param.Byte[0] = (int8_t) tmp;
tmp = PPM_in[ParamSet.ChannelAssignment[CH_YAW]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128;
ToNaviCtrl.Param.Byte[1] = (int8_t) tmp;
tmp = PPM_in[ParamSet.ChannelAssignment[CH_ROLL]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128;
ToNaviCtrl.Param.Byte[2] = (int8_t) tmp;
tmp = PPM_in[ParamSet.ChannelAssignment[CH_PITCH]]; if(tmp > 127) tmp = 127; else if(tmp < -128) tmp = -128;
ToNaviCtrl.Param.Byte[3] = (int8_t) tmp;
ToNaviCtrl.Param.Byte[4] = (uint8_t) Poti1;
ToNaviCtrl.Param.Byte[5] = (uint8_t) Poti2;
ToNaviCtrl.Param.Byte[6] = (uint8_t) Poti3;
ToNaviCtrl.Param.Byte[7] = (uint8_t) Poti4;
ToNaviCtrl.Param.Byte[8] = (uint8_t) RC_Quality;
break;
 
case SPI_CMD_CAL_COMPASS:
if(CompassCalState > 5)
case 1:
if (rxdata == 0x55) { rxchksum += rxdata; SPI_RXState = 2; } // 2. Syncbyte ok
else SPI_RXState = 0;
//DebugOut.Analog[18]++;
break;
case 2:
SPI_Buffer[SPI_RxBufferIndex++]= rxdata; // get data
//DebugOut.Analog[19]++;
if (SPI_RxBufferIndex >= sizeof(FromNaviCtrl))
{
if (rxdata == rxchksum)
{
CompassCalState = 0;
ToNaviCtrl.Param.Byte[0] = 5;
}
else
{
ToNaviCtrl.Param.Byte[0] = CompassCalState;
}
break;
}
unsigned char *ptr = (unsigned char *)&FromNaviCtrl;
memcpy(ptr, (unsigned char *) SPI_Buffer, sizeof(SPI_Buffer));
SPI_RxDataValid = 1;
}
else SPI_RxDataValid = 0;
SPI_RXState = 0;
}
else rxchksum += rxdata;
break;
}
if (SPI_BufferIndex < sizeof(ToNaviCtrl))
{
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
SPDR = SPI_TX_Buffer[SPI_BufferIndex];
ToNaviCtrl.Chksum += SPI_TX_Buffer[SPI_BufferIndex];
// SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave
 
 
sei(); // enable all interrupts
 
// analyze content of packet from NaviCtrl if valid
if (SPI_RxDataValid)
{
// update gps controls
if(abs(FromNaviCtrl.GPS_Pitch) < 512 && abs(FromNaviCtrl.GPS_Roll) < 512 && (ParamSet.GlobalConfig & CFG_GPS_ACTIVE))
{
GPS_Pitch = FromNaviCtrl.GPS_Pitch;
GPS_Roll = FromNaviCtrl.GPS_Roll;
}
// update compass readings
if(FromNaviCtrl.CompassHeading <= 360)
{
CompassHeading = FromNaviCtrl.CompassHeading;
}
if(CompassHeading < 0) CompassOffCourse = 0;
else CompassOffCourse = ((540 + CompassHeading - CompassCourse) % 360) - 180;
// NaviCtrl wants to beep?
if (FromNaviCtrl.BeepTime > BeepTime && !CompassCalState) BeepTime = FromNaviCtrl.BeepTime;
 
switch (FromNaviCtrl.Command)
{
case SPI_CMD_OSD_DATA:
// ToFlightCtrl.Param.Byte[0] = OsdBar;
// ToFlightCtrl.Param.Int[1] = Distance;
break;
 
case SPI_CMD_GPS_POS:
// ToFlightCtrl.Param.Long[0] = GPS_Data.Longitude;
// ToFlightCtrl.Param.Long[1] = GPS_Data.Latitude;
break;
 
case SPI_CMD_GPS_TARGET:
// ToFlightCtrl.Param.Long[0] = GPS_Data.TargetLongitude;
// ToFlightCtrl.Param.Long[1] = GPS_Data.TargetLatitude;
break;
 
default:
break;
}
}
else // no valid data from NaviCtrl
{
// disable GPS control
GPS_Pitch = 0;
GPS_Roll = 0;
}
}
else SPITransferCompleted = 1;
SPI_BufferIndex++;
}
 
 
 
/*********************************************/
/* Start Transmission of packet to NaviCtrl */
/*********************************************/
void SPI_StartTransmitPacket(void)
{
 
if (!SPITransferCompleted) return; // return immediately if transfer is in progress
else // transmission was completed
{
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // Select slave
 
// cyclic commands
ToNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++];
if (SPI_CommandCounter >= sizeof(SPI_CommandSequence)) SPI_CommandCounter = 0;
 
SPITransferCompleted = 0; // tranfer is in progress
UpdateSPI_Buffer(); // update data in ToNaviCtrl
 
SPI_TxBufferIndex = 1; //proceed with 2nd byte
 
// -- Debug-Output ---
//----
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
ToNaviCtrl.Chksum = ToNaviCtrl.Sync1; // init checksum
SPDR = ToNaviCtrl.Sync1; // send first byte
}
}
 
//------------------------------------------------------
// This is the spi data transfer between FlightCtrl and NaviCtrl
// Every time this routine is called within the mainloop one byte of the packet to
// the NaviCtrl and one byte of the packet from the NaviCtrl is possible transfered
 
void SPI_TransmitByte(void)
void UpdateSPI_Buffer(void)
{
static SPI_RXState_t SPI_RXState = SPI_SYNC1;
uint8_t rxdata;
static uint8_t rxchksum;
static unsigned char i =0;
signed int tmp;
cli();
ToNaviCtrl.IntegralNick = (int) (IntegralNick / 108);
ToNaviCtrl.IntegralRoll = (int) (IntegralRoll / 108);
ToNaviCtrl.GyroCompass = ErsatzKompass / GIER_GRAD_FAKTOR;
ToNaviCtrl.AccNick = (int) ACC_AMPLIFY * (NaviAccNick / NaviCntAcc);
ToNaviCtrl.AccRoll = (int) ACC_AMPLIFY * (NaviAccRoll / NaviCntAcc);
NaviCntAcc = 0; NaviAccNick = 0; NaviAccRoll = 0;
// ToNaviCtrl.User8 = Parameter_UserParam8;
// ToNaviCtrl.CalState = WinkelOut.CalcState;
 
if (SPITransferCompleted) return; // return immediatly if transfer was completed
if (!(SPSR & (1 << SPIF))) return; // return if no SPI-IRQ pending
SendSPI = 4; // mait 4 * 0.102 ms for the next call of SPI_TransmitByte() in the main loop
switch(ToNaviCtrl.Command) //
{
case SPI_CMD_USER:
ToNaviCtrl.Param.Byte[0] = Parameter_UserParam1;
ToNaviCtrl.Param.Byte[1] = Parameter_UserParam2;
ToNaviCtrl.Param.Byte[2] = Parameter_UserParam3;
ToNaviCtrl.Param.Byte[3] = Parameter_UserParam4;
ToNaviCtrl.Param.Byte[4] = Parameter_UserParam5;
ToNaviCtrl.Param.Byte[5] = Parameter_UserParam6;
ToNaviCtrl.Param.Byte[6] = Parameter_UserParam7;
break;
 
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave
case SPI_CMD_STICK:
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_GAS]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127;
ToNaviCtrl.Param.Byte[0] = (char) tmp;
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127;
ToNaviCtrl.Param.Byte[1] = (char) tmp;
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127;
ToNaviCtrl.Param.Byte[2] = (char) tmp;
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_NICK]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127;
ToNaviCtrl.Param.Byte[3] = (char) tmp;
ToNaviCtrl.Param.Byte[4] = (unsigned char) Poti1;
ToNaviCtrl.Param.Byte[5] = (unsigned char) Poti2;
ToNaviCtrl.Param.Byte[6] = (unsigned char) Poti3;
ToNaviCtrl.Param.Byte[7] = (unsigned char) Poti4;
ToNaviCtrl.Param.Byte[8] = (unsigned char) SenderOkay;
 
rxdata = SPDR; // save spi data register
break;
case SPI_CMD_CAL_COMPASS:
if(WinkelOut.CalcState > 5)
{
WinkelOut.CalcState = 0;
ToNaviCtrl.Param.Byte[0] = 5;
}
else ToNaviCtrl.Param.Byte[0] = WinkelOut.CalcState;
break;
}
sei();
if (SPI_RxDataValid)
{
if(abs(FromNaviCtrl.GPS_Nick) < 512 && abs(FromNaviCtrl.GPS_Roll) < 512 && (EE_Parameter.GlobalConfig & CFG_GPS_AKTIV))
{
GPS_Nick = FromNaviCtrl.GPS_Nick;
GPS_Roll = FromNaviCtrl.GPS_Roll;
}
if(FromNaviCtrl.CompassValue <= 360) KompassValue = FromNaviCtrl.CompassValue;
KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
if(FromNaviCtrl.BeepTime > beeptime && !WinkelOut.CalcState) beeptime = FromNaviCtrl.BeepTime;
switch (FromNaviCtrl.Command)
{
case SPI_CMD_OSD_DATA:
// ToFlightCtrl.Param.Byte[0] = OsdBar;
// ToFlightCtrl.Param.Int[1] = Distance;
break;
 
switch (SPI_RXState)
{
case SPI_SYNC1: // first sync byte
SPI_RxBufferIndex = 0; // set pointer to start of rx buffer
rxchksum = rxdata; // initialize checksum
if (rxdata == SPI_RXSYNCBYTE1 )
{ // 1st Syncbyte found
SPI_RXState = SPI_SYNC2; // trigger to state for second sync byte
}
break;
case SPI_CMD_GPS_POS:
// ToFlightCtrl.Param.Long[0] = GPS_Data.Longitude;
// ToFlightCtrl.Param.Long[1] = GPS_Data.Latitude;
break;
 
case SPI_SYNC2: // second sync byte
if (rxdata == SPI_RXSYNCBYTE2)
{ // 2nd Syncbyte found
rxchksum += rxdata; // update checksum
SPI_RXState = SPI_DATA; // trigger to state for second sync byte
}
else // 2nd Syncbyte not found
{
SPI_RXState = SPI_SYNC1; // jump back to 1st sync byte
}
break;
case SPI_CMD_GPS_TARGET:
// ToFlightCtrl.Param.Long[0] = GPS_Data.TargetLongitude;
// ToFlightCtrl.Param.Long[1] = GPS_Data.TargetLatitude;
break;
 
case SPI_DATA: // data bytes
SPI_RxBuffer[SPI_RxBufferIndex++] = rxdata; // copy data byte to spi buffer
// if all bytes are received of a packet from the NaviCtrl
if (SPI_RxBufferIndex >= SPI_RXBUFFER_LEN)
{ // last byte transfered is the checksum of the packet
if (rxdata == rxchksum) // checksum matching?
{
// copy SPI_RxBuffer -> FromFlightCtrl
uint8_t *ptr = (uint8_t *)&FromNaviCtrl;
cli();
memcpy(ptr, (uint8_t *) SPI_RxBuffer, sizeof(FromNaviCtrl));
sei();
SPI_RxDataValid = 1;
DebugOut.Analog[18]++;
}
else
{ // checksum does not match
DebugOut.Analog[17]++;
SPI_RxDataValid = 0; // reset valid flag
}
SPI_RXState = SPI_SYNC1; // reset state sync
}
else // not all bytes transfered
{
rxchksum += rxdata; // update checksum
}
break;
}// eof switch(SPI_RXState)
 
// if still some bytes left for transmission to NaviCtrl
if (SPI_TxBufferIndex < SPI_TXBUFFER_LEN)
{
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop");
 
SPDR = SPI_TxBuffer[SPI_TxBufferIndex]; // transmit byte
ToNaviCtrl.Chksum += SPI_TxBuffer[SPI_TxBufferIndex]; // update checksum for everey byte that was sent
SPI_TxBufferIndex++;
}
else
{
//Transfer of all bytes of the packet to NaviCtrl completed
SPITransferCompleted = 1;
}
default:
break;
}
}
else
{
// KompassValue = 0;
// KompassRichtung = 0;
GPS_Nick = 0;
GPS_Roll = 0;
}
}
 
#endif
 
#endif //USE_SPI_COMMUNICATION
 
 
/branches/V0.69k Code Redesign killagreg/spi.h
2,10 → 2,9
#ifndef _SPI_H
#define _SPI_H
 
//#include <util/delay.h>
#include <inttypes.h>
#include <util/delay.h>
 
#define USE_SPI_COMMUNICATION
#define USE_SPI_COMMUNICATION
 
#define SPI_PROTOCOL_COMP 1
 
14,36 → 13,36
#define DD_SS PB4
#define DD_SCK PB7
#define DD_MOSI PB5
#define DD_MISO PB6
#define DD_MISO PB6
 
// for compatibility reasons gcc3.x <-> gcc4.x
#ifndef SPCR
// for compatibility reasons gcc3.x <-> gcc4.x
#ifndef SPCR
#define SPCR SPCR0
#endif
#ifndef SPE
#endif
#ifndef SPE
#define SPE SPE0
#endif
#ifndef MSTR
#endif
#ifndef MSTR
#define MSTR MSTR0
#endif
#ifndef SPR1
#endif
#ifndef SPR1
#define SPR1 SPR01
#endif
#ifndef SPR0
#endif
#ifndef SPR0
#define SPR0 SPR00
#endif
#ifndef SPIE
#endif
#ifndef SPIE
#define SPIE SPIE0
#endif
#ifndef SPDR
#endif
#ifndef SPDR
#define SPDR SPDR0
#endif
#ifndef SPIF
#endif
#ifndef SPIF
#define SPIF SPIF0
#endif
#ifndef SPSR
#endif
#ifndef SPSR
#define SPSR SPSR0
#endif
#endif
// -------------------------
 
#define SLAVE_SELECT_DDR_PORT DDRC
54,69 → 53,65
#define SPI_CMD_USER 10
#define SPI_CMD_STICK 11
#define SPI_CMD_CAL_COMPASS 12
 
typedef struct
struct str_ToNaviCtrl
{
uint8_t Sync1;
uint8_t Sync2;
uint8_t Command;
int16_t IntegralPitch;
int16_t IntegralRoll;
int16_t AccPitch;
int16_t AccRoll;
int16_t GyroHeading;
int16_t GyroPitch;
int16_t GyroRoll;
int16_t GyroYaw;
union
{
int8_t sByte[12];
uint8_t Byte[12];
int16_t Int[6];
int32_t Long[3];
float Float[3];
} Param;
uint8_t Chksum;
} ToNaviCtrl_t;
unsigned char Sync1, Sync2;
unsigned char Command;
signed int IntegralNick;
signed int IntegralRoll;
signed int AccNick;
signed int AccRoll;
signed int GyroCompass;
signed int GyroNick;
signed int GyroRoll;
signed int GyroGier;
union
{ char Byte[12];
int Int[6];
long Long[3];
float Float[3];
} Param;
unsigned char Chksum;
};
 
 
 
#define SPI_CMD_OSD_DATA 100
#define SPI_CMD_GPS_POS 101
#define SPI_CMD_GPS_TARGET 102
 
typedef struct
#define SPI_CMD_GPS_TARGET 102
struct str_FromNaviCtrl
{
uint8_t Command;
int16_t GPS_Pitch;
int16_t GPS_Roll;
int16_t GPS_Yaw;
int16_t CompassHeading;
int16_t Status;
uint8_t BeepTime;
union
{
int8_t Byte[12];
int16_t Int[6];
int32_t Long[3];
float Float[3];
} Param;
uint8_t Chksum;
} FromNaviCtrl_t;
unsigned char Command;
signed int GPS_Nick;
signed int GPS_Roll;
signed int GPS_Gier;
signed int CompassValue;
signed int Status;
unsigned char BeepTime;
union
{ char Byte[12];
int Int[6];
long Long[3];
float Float[3];
} Param;
unsigned char Chksum;
};
 
 
#ifdef USE_SPI_COMMUNICATION
 
extern ToNaviCtrl_t ToNaviCtrl;
extern FromNaviCtrl_t FromNaviCtrl;
extern struct str_ToNaviCtrl ToNaviCtrl;
extern struct str_FromNaviCtrl FromNaviCtrl;
 
//#define SPI_CMD_VALUE 0x03
 
extern void SPI_MasterInit(void);
extern void SPI_StartTransmitPacket(void);
extern void UpdateSPI_Buffer(void);
extern void SPI_TransmitByte(void);
#else
 
 
// -------------------------------- Dummy -----------------------------------------
#define SPI_MasterInit() ;
#define SPI_MasterInit() ;
#define SPI_StartTransmitPacket() ;
#define UpdateSPI_Buffer() ;
#define SPI_TransmitByte() ;
123,4 → 118,4
#endif
 
 
#endif //_SPI_H
#endif
/branches/V0.69k Code Redesign killagreg/timer0.c
1,192 → 1,168
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "eeprom.h"
#include "analog.h"
#include "main.h"
#include "fc.h"
#ifdef USE_KILLAGREG
#include "mm3.h"
#endif
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
#include "mk3mag.h"
#endif
 
volatile uint16_t CountMilliseconds = 0;
volatile uint8_t UpdateMotor = 0;
volatile uint16_t cntKompass = 0;
volatile uint16_t BeepTime = 0;
volatile uint16_t BeepModulation = 0xFFFF;
volatile unsigned int CountMilliseconds = 0;
volatile static unsigned int tim_main;
volatile unsigned char UpdateMotor = 0;
volatile unsigned int cntKompass = 0;
volatile unsigned int beeptime = 0;
volatile unsigned char SendSPI = 0;
 
#ifdef USE_NAVICTRL
volatile uint8_t SendSPI = 0;
#endif
unsigned int BeepMuster = 0xffff;
int ServoValue = 0;
 
enum {
STOP = 0,
CK = 1,
CK8 = 2,
CK64 = 3,
CK256 = 4,
CK1024 = 5,
T0_FALLING_EDGE = 6,
T0_RISING_EDGE = 7
};
 
 
/*****************************************************/
/* Initialize Timer 0 */
/*****************************************************/
// timer 0 is used for the PWM generation to control the offset voltage at the air pressure sensor
// Its overflow interrupt routine is used to generate the beep signal and the flight control motor update rate
void TIMER0_Init(void)
SIGNAL (SIG_OVERFLOW0) // 8kHz
{
uint8_t sreg = SREG;
static unsigned char cnt_1ms = 1,cnt = 0;
unsigned char pieper_ein = 0;
// TCNT0 -= 250;//TIMER_RELOAD_VALUE;
if(SendSPI) SendSPI--;
if(!cnt--)
{
cnt = 9;
cnt_1ms++;
cnt_1ms %= 2;
if(!cnt_1ms) UpdateMotor = 1;
CountMilliseconds++;
}
 
// disable all interrupts before reconfiguration
cli();
if(beeptime > 1)
{
beeptime--;
if(beeptime & BeepMuster)
{
pieper_ein = 1;
}
else pieper_ein = 0;
}
else
{
pieper_ein = 0;
BeepMuster = 0xffff;
}
 
// configure speaker port as output
if(BoardRelease == 10)
{ // Speaker at PD2
DDRD |= (1<<DDD2);
PORTD &= ~(1<<PORTD2);
}
else
{ // Speaker at PC7
DDRC |= (1<<DDC7);
PORTC &= ~(1<<PORTC7);
}
 
// set PB3 and PB4 as output for the PWM used as aoffset for the pressure sensor
DDRB |= (1<<DDB4)|(1<<DDB3);
PORTB &= ~((1<<PORTB4)|(1<<PORTB3));
if(pieper_ein)
{
if(PlatinenVersion == 10) PORTD |= (1<<2); // Speaker an PORTD.2
else PORTC |= (1<<7); // Speaker an PORTC.7
}
else
{
if(PlatinenVersion == 10) PORTD &= ~(1<<2);
else PORTC &= ~(1<<7);
}
if(EE_Parameter.GlobalConfig & CFG_KOMPASS_AKTIV)
{
if(PINC & 0x10)
{
cntKompass++;
}
else
{
if((cntKompass) && (cntKompass < 362))
{
cntKompass += cntKompass / 41;
if(cntKompass > 10) KompassValue = cntKompass - 10; else KompassValue = 0;
}
// if(cntKompass < 10) cntKompass = 10;
// KompassValue = (unsigned long)((unsigned long)(cntKompass-10)*720L + 1L) / 703L;
KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
cntKompass = 0;
}
}
}
 
if(BoardRelease == 10)
{
DDRD |= (1<<DDD2);
PORTD &= ~(1<<PORTD2);
 
}
else
{
DDRC |= (1<<DDC7);
PORTC &= ~(1<<PORTC7);
}
void Timer_Init(void)
{
tim_main = SetDelay(10);
TCCR0B = CK8;
TCCR0A = (1<<COM0A1)|(1<<COM0B1)|3;//fast PWM
OCR0A = 0;
OCR0B = 120;
TCNT0 = (unsigned char)-TIMER_RELOAD_VALUE; // reload
//OCR1 = 0x00;
 
// Timer/Counter 0 Control Register A
TCCR2A=(1<<COM2A1)|(1<<COM2A0)|3;
TCCR2B=(0<<CS20)|(1<<CS21)|(1<<CS22);
// TIMSK2 |= _BV(TOIE2);
TIMSK2 |= _BV(OCIE2A);
 
// Waveform Generation Mode is Fast PWM (Bits WGM02 = 0, WGM01 = 1, WGM00 = 1)
// Clear OC0A on Compare Match, set OC0A at BOTTOM, noninverting PWM (Bits COM0A1 = 1, COM0A0 = 0)
// Clear OC0B on Compare Match, set OC0B at BOTTOM, (Bits COM0B1 = 1, COM0B0 = 0)
TCCR0A &= ~((1<<COM0A0)|(1<<COM0B0));
TCCR0A |= (1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
 
// Timer/Counter 0 Control Register B
 
// set clock devider for timer 0 to SYSKLOCK/8 = 20MHz / 8 = 2.5MHz
// i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz
// hence the timer overflow interrupt frequency is 2.5 MHz / 256 = 9.765 kHz
 
// divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0)
TCCR0B &= ~((1<<FOC0A)|(1<<FOC0B)|(1<<WGM02));
TCCR0B = (TCCR0B & 0xF8)|(0<<CS02)|(1<<CS01)|(0<<CS00);
 
// initialize the Output Compare Register A & B used for PWM generation on port PB3 & PB4
OCR0A = 0; // for PB3
OCR0B = 120; // for PB4
 
// init Timer/Counter 0 Register
TCNT0 = 0;
 
// Timer/Counter 0 Interrupt Mask Register
// enable timer overflow interrupt only
TIMSK0 &= ~((1<<OCIE0B)|(1<<OCIE0A));
TIMSK0 |= (1<<TOIE0);
 
SREG = sreg;
TIMSK0 |= _BV(TOIE0);
OCR2A = 10;
TCNT2 = 0;
}
 
// -----------------------------------------------------------------------
 
 
/*****************************************************/
/* Interrupt Routine of Timer 0 */
/*****************************************************/
ISR(TIMER0_OVF_vect) // 9.765 kHz
unsigned int SetDelay (unsigned int t)
{
static uint8_t cnt_1ms = 1,cnt = 0;
uint8_t Beeper_On = 0;
 
#ifdef USE_NAVICTRL
if(SendSPI) SendSPI--; // if SendSPI is 0, the transmit of a byte via SPI bus to and from The Navicontrol is done
#endif
 
if(!cnt--) // every 10th run (9.765kHz/10 = 976Hz)
{
cnt = 9;
cnt_1ms++;
cnt_1ms %= 2;
if(!cnt_1ms) UpdateMotor = 1; // every 2nd run (976Hz/2 = 488 Hz)
CountMilliseconds++; // increment millisecond counter
}
 
 
// beeper on if duration is not over
if(BeepTime)
{
BeepTime--; // decrement BeepTime
if(BeepTime & BeepModulation) Beeper_On = 1;
else Beeper_On = 0;
}
else // beeper off if duration is over
{
Beeper_On = 0;
BeepModulation = 0xFFFF;
}
 
// if beeper is on
if(Beeper_On)
{
// set speaker port to high
if(BoardRelease == 10) PORTD |= (1<<PORTD2); // Speaker at PD2
else PORTC |= (1<<PORTC7); // Speaker at PC7
}
else // beeper is off
{
// set speaker port to low
if(BoardRelease == 10) PORTD &= ~(1<<PORTD2);// Speaker at PD2
else PORTC &= ~(1<<PORTC7);// Speaker at PC7
}
 
// update compass value if this option is enabled in the settings
if(ParamSet.GlobalConfig & CFG_COMPASS_ACTIVE)
{
#ifdef USE_KILLAGREG
MM3_Update(); // read out mm3 board
#endif
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
MK3MAG_Update(); // read out mk3mag pwm
#endif
}
// TIMSK0 &= ~_BV(TOIE0);
return(CountMilliseconds + t + 1);
// TIMSK0 |= _BV(TOIE0);
}
 
 
 
// -----------------------------------------------------------------------
uint16_t SetDelay (uint16_t t)
char CheckDelay(unsigned int t)
{
return(CountMilliseconds + t + 1);
// TIMSK0 &= ~_BV(TOIE0);
return(((t - CountMilliseconds) & 0x8000) >> 9);
// TIMSK0 |= _BV(TOIE0);
}
 
// -----------------------------------------------------------------------
int8_t CheckDelay(uint16_t t)
void Delay_ms(unsigned int w)
{
return(((t - CountMilliseconds) & 0x8000) >> 9); // check sign bit
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt));
}
 
// -----------------------------------------------------------------------
void Delay_ms(uint16_t w)
void Delay_ms_Mess(unsigned int w)
{
unsigned int t_stop;
t_stop = SetDelay(w);
while (!CheckDelay(t_stop));
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt)) ANALOG_ON;
}
 
// -----------------------------------------------------------------------
void Delay_ms_Mess(uint16_t w)
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Servo ansteuern
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SIGNAL(SIG_OUTPUT_COMPARE2A)
{
uint16_t t_stop;
t_stop = SetDelay(w);
while (!CheckDelay(t_stop)) ADC_Enable();
static unsigned char timer = 10;
if(!timer--)
{
TCCR2A=(1<<COM2A1)|(0<<COM2A0)|3;
ServoValue = Parameter_ServoNickControl;
if(EE_Parameter.ServoNickCompInvert & 0x01) ServoValue += ((long) EE_Parameter.ServoNickComp * (IntegralNick / 128)) / 512;
else ServoValue -= ((long) EE_Parameter.ServoNickComp * (IntegralNick / 128)) / 512;
if(ServoValue < EE_Parameter.ServoNickMin) ServoValue = EE_Parameter.ServoNickMin;
else if(ServoValue > EE_Parameter.ServoNickMax) ServoValue = EE_Parameter.ServoNickMax;
 
OCR2A = ServoValue;// + 75;
timer = EE_Parameter.ServoNickRefresh;
}
else
{
TCCR2A =3;
PORTD&=~0x80;
}
}
 
/branches/V0.69k Code Redesign killagreg/timer0.h
1,21 → 1,17
#ifndef _TIMER0_H
#define _TIMER0_H
 
#include <inttypes.h>
#define TIMER_TEILER CK8
#define TIMER_RELOAD_VALUE 250
 
extern volatile uint16_t CountMilliseconds;
extern volatile uint8_t UpdateMotor;
extern volatile uint16_t cntKompass;
extern volatile uint16_t BeepModulation;
extern volatile uint16_t BeepTime;
#ifdef USE_NAVICTRL
extern volatile uint8_t SendSPI;
#endif
void Timer_Init(void);
void Delay_ms(unsigned int);
void Delay_ms_Mess(unsigned int);
unsigned int SetDelay (unsigned int t);
char CheckDelay (unsigned int t);
 
extern void TIMER0_Init(void);
extern void Delay_ms(uint16_t w);
extern void Delay_ms_Mess(uint16_t w);
extern uint16_t SetDelay (uint16_t t);
extern int8_t CheckDelay (uint16_t t);
 
#endif //_TIMER0_H
extern volatile unsigned int CountMilliseconds;
extern volatile unsigned char UpdateMotor;
extern volatile unsigned int beeptime;
extern volatile unsigned int cntKompass;
extern int ServoValue;
extern unsigned int BeepMuster;
extern volatile unsigned char SendSPI;
/branches/V0.69k Code Redesign killagreg/twimaster.c
1,184 → 1,152
/*############################################################################
############################################################################*/
 
#include <avr/io.h>
#include <avr/interrupt.h>
 
#include "main.h"
#include "twimaster.h"
#include "fc.h"
 
volatile uint8_t twi_state = 0;
volatile uint8_t motor = 0;
volatile uint8_t motor_rx[8];
unsigned char twi_state = 0;
unsigned char motor = 0;
unsigned char motorread = 0;
unsigned char motor_rx[8];
 
/**************************************************/
/* Initialize I2C (TWI) */
/**************************************************/
void I2C_Init(void)
//############################################################################
//Initzialisieren der I2C (TWI) Schnittstelle
void i2c_init(void)
//############################################################################
{
uint8_t sreg = SREG;
cli();
 
// SDA is INPUT
DDRC &= ~(1<<DDC1);
// SCL is output
DDRC |= (1<<DDC0);
// pull up SDA
PORTC |= (1<<PORTC0)|(1<<PORTC1);
 
// TWI Status Register
// prescaler 1 (TWPS1 = 0, TWPS0 = 0)
TWSR &= ~((1<<TWPS1)|(1<<TWPS0));
 
// set TWI Bit Rate Register
TWBR = ((SYSCLK/SCL_CLOCK)-16)/2;
 
SREG = sreg;
TWSR = 0;
TWBR = ((SYSCLK/SCL_CLOCK)-16)/2;
}
 
/****************************************/
/* Start I2C */
/****************************************/
void I2C_Start(void)
//############################################################################
//Start I2C
char i2c_start(void)
//############################################################################
{
// TWI Control Register
// clear TWI interrupt flag (TWINT=1)
// disable TWI Acknowledge Bit (TWEA = 0)
// enable TWI START Condition Bit (TWSTA = 1), MASTER
// disable TWI STOP Condition Bit (TWSTO = 0)
// disable TWI Write Collision Flag (TWWC = 0)
// enable i2c (TWIE = 1)
// enable TWI Interrupt (TWIE = 1)
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT) | (1<<TWIE);
return(0);
}
 
/****************************************/
/* Stop I2C */
/****************************************/
void I2C_Stop(void)
//############################################################################
//Start I2C
void i2c_stop(void)
//############################################################################
{
// TWI Control Register
// clear TWI interrupt flag (TWINT=1)
// disable TWI Acknowledge Bit (TWEA = 0)
// diable TWI START Condition Bit (TWSTA = 1), no MASTER
// enable TWI STOP Condition Bit (TWSTO = 1)
// disable TWI Write Collision Flag (TWWC = 0)
// enable i2c (TWIE = 1)
// disable TWI Interrupt (TWIE = 0)
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);
}
 
/****************************************/
/* Reset I2C */
/****************************************/
void I2C_Reset(void)
void i2c_reset(void)
//############################################################################
{
// stop i2c bus
I2C_Stop();
twi_state = 0;
motor = TWDR; // ??
motor = 0;
TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset
TWAMR = 0;
TWAR = 0;
TWDR = 0;
TWSR = 0;
TWBR = 0;
I2C_Init();
I2C_Start();
I2C_WriteByte(0);
i2c_stop();
twi_state = 0;
motor = TWDR;
motor = 0;
TWCR = 0x80;
TWAMR = 0;
TWAR = 0;
TWDR = 0;
TWSR = 0;
TWBR = 0;
i2c_init();
i2c_start();
i2c_write_byte(0);
}
 
/****************************************/
/* Write to I2C */
/****************************************/
void I2C_WriteByte(int8_t byte)
{
// move byte to send into TWI Data Register
//############################################################################
//Start I2C
char i2c_write_byte(char byte)
//############################################################################
{
TWSR = 0x00;
TWDR = byte;
// clear interrupt flag (TWINT = 1)
// enable i2c bus (TWEN = 1)
// enable intterupt (TWIW = 1)
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
return(0);
}
 
 
/****************************************/
/* Receive byte and send ACK */
/****************************************/
void I2C_ReceiveByte(void)
//############################################################################
//Start I2C
SIGNAL (TWI_vect)
//############################################################################
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
}
 
/****************************************/
/* I2C receive last byte and send no ACK*/
/****************************************/
void I2C_ReceiveLastByte(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
}
 
 
/****************************************/
/* I2C ISR */
/****************************************/
ISR (TWI_vect)
 
{
static uint8_t motorread = 0;
 
switch (twi_state++) // First i2s_start from SendMotorData()
switch (twi_state++)
{
// Master Transmit
case 0: // Send SLA-W
I2C_WriteByte(0x52+(motor*2));
case 0:
i2c_write_byte(0x52+(motor*2));
break;
case 1: // Send Data to Salve
case 1:
switch(motor++)
{
case 0:
I2C_WriteByte(Motor_Front);
i2c_write_byte(Motor_Vorne);
break;
case 1:
I2C_WriteByte(Motor_Rear);
case 1:
i2c_write_byte(Motor_Hinten);
break;
case 2:
I2C_WriteByte(Motor_Right);
i2c_write_byte(Motor_Rechts);
break;
case 3:
I2C_WriteByte(Motor_Left);
i2c_write_byte(Motor_Links);
break;
}
break;
case 2: // repeat case 0+1 for all Slaves
case 2:
i2c_stop();
if (motor<4) twi_state = 0;
I2C_Start(); // Repeated start -> switch salve or switch Master Transmit -> Master Receive
else motor = 0;
i2c_start();
break;
//Liest Daten von Motor
case 3:
i2c_write_byte(0x53+(motorread*2));
break;
 
// Master Receive
case 3: // Send SLA-R
I2C_WriteByte(0x53+(motorread*2));
break;
case 4:
//Transmit 1st byte
I2C_ReceiveByte();
switch(motorread)
{
case 0:
i2c_write_byte(Motor_Vorne);
break;
case 1:
i2c_write_byte(Motor_Hinten);
break;
case 2:
i2c_write_byte(Motor_Rechts);
break;
case 3:
i2c_write_byte(Motor_Links);
break;
}
break;
case 5: //Read 1st byte and transmit 2nd Byte
case 5: //1 Byte vom Motor lesen
motor_rx[motorread] = TWDR;
I2C_ReceiveLastByte();
break;
 
case 6:
//Read 2nd byte
motor_rx[motorread+4] = TWDR;
motorread++;
if (motorread > 3) motorread=0;
 
default:
I2C_Stop();
switch(motorread)
{
case 0:
i2c_write_byte(Motor_Vorne);
break;
case 1:
i2c_write_byte(Motor_Hinten);
break;
case 2:
i2c_write_byte(Motor_Rechts);
break;
case 3:
i2c_write_byte(Motor_Links);
break;
}
break;
case 7: //2 Byte vom Motor lesen
motor_rx[motorread+4] = TWDR;
motorread++;
if (motorread>3) motorread=0;
i2c_stop();
I2CTimeout = 10;
twi_state = 0;
I2CTimeout = 10;
motor = 0;
}
TWCR |= 0x80;
}
/branches/V0.69k Code Redesign killagreg/twimaster.h
1,10 → 1,9
/*############################################################################
############################################################################*/
 
#ifndef _I2C_MASTER_H
#define _I2C_MASTER_H
-#include <inttypes.h>
-
//############################################################################
// I2C Konstanten
@@ -19,15 +18,16 @@
//############################################################################
-extern volatile uint8_t twi_state;
-extern volatile uint8_t motor;
-extern volatile uint8_t motorread;
-extern volatile uint8_t motor_rx[8];
+extern unsigned char twi_state;
+extern unsigned char motor;
+extern unsigned char motorread;
+extern unsigned char motor_rx[8];
-extern void I2C_Init (void); // Initialize I2C
-extern void I2C_Start (void); // Start I2C
-extern void I2C_Stop (void); // Stop I2C
-extern void I2C_WriteByte (int8_t byte); // Write 1 Byte
-extern void I2C_Reset(void); // Reset I2C
+void i2c_reset(void);
+extern void i2c_init (void); // I2C initialisieren
+extern char i2c_start (void); // Start I2C
+extern void i2c_stop (void); // Stop I2C
+extern char i2c_write_byte (char byte); // 1 Byte schreiben
+extern void i2c_reset(void);
#endif
/branches/V0.69k Code Redesign killagreg/uart.c
1,4 → 1,4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 04.2007 Holger Buss
// + only for non-profit use
// + www.MikroKopter.com
5,88 → 5,60
// + see the File "License.txt" for further Informations
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
 
#include "eeprom.h"
#include "main.h"
#include "menu.h"
#include "timer0.h"
#include "uart.h"
#include "fc.h"
#include "_Settings.h"
#include "rc.h"
#ifdef USE_KILLAGREG
#include "ubx.h"
#endif
#if !defined(USE_KILLAGREG) && !defined (USE_NAVICTRL)
#include "mk3mag.h"
#endif
 
unsigned char DebugGetAnforderung = 0,DebugDisplayAnforderung = 0,DebugDataAnforderung = 0,GetVersionAnforderung = 0;
unsigned volatile char SioTmp = 0;
unsigned volatile char SendeBuffer[MAX_SENDE_BUFF];
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
unsigned volatile char NMEABuffer[MAX_EMPFANGS_BUFF];
unsigned volatile char NeuerDatensatzEmpfangen = 0;
unsigned volatile char NeueKoordinateEmpfangen = 0;
unsigned volatile char UebertragungAbgeschlossen = 1;
unsigned volatile char CntCrcError = 0;
unsigned volatile char AnzahlEmpfangsBytes = 0;
unsigned volatile char PC_DebugTimeout = 0;
unsigned char RemotePollDisplayLine = 0;
unsigned char NurKanalAnforderung = 0;
unsigned char DebugTextAnforderung = 255;
unsigned char PcZugriff = 100;
unsigned char MotorTest[4] = {0,0,0,0};
unsigned char DubWiseKeys[4] = {0,0,0,0};
unsigned char MeineSlaveAdresse;
unsigned char ConfirmFrame;
struct str_DebugOut DebugOut;
struct str_ExternControl ExternControl;
struct str_VersionInfo VersionInfo;
struct str_WinkelOut WinkelOut;
 
int Debug_Timer,Kompass_Timer;
 
#define FALSE 0
#define TRUE 1
 
//int8_t test __attribute__ ((section (".noinit")));
uint8_t RequestVerInfo = FALSE;
uint8_t RequestExternalControl = FALSE;
uint8_t RequestDisplay = FALSE;
uint8_t RequestDebugData = FALSE;
uint8_t RequestDebugLabel = 255;
uint8_t RequestChannelOnly = FALSE;
uint8_t RemotePollDisplayLine = 0;
 
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
volatile uint8_t rxd_buffer_locked = FALSE;
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
volatile uint8_t txd_complete = TRUE;
volatile uint8_t ReceivedBytes = 0;
 
 
uint8_t PcAccess = 100;
uint8_t MotorTest[4] = {0,0,0,0};
uint8_t DubWiseKeys[4] = {0,0,0,0};
uint8_t MySlaveAddr = 0;
uint8_t ConfirmFrame;
 
DebugOut_t DebugOut;
ExternControl_t ExternControl;
VersionInfo_t VersionInfo;
 
int16_t Debug_Timer;
 
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
int16_t Compass_Timer;
#endif
 
 
const uint8_t ANALOG_LABEL[32][16] =
const unsigned char ANALOG_TEXT[32][16] =
{
//1234567890123456
"IntegralPitch ", //0
//1234567890123456
"IntegralNick ", //0
"IntegralRoll ",
"AccPitch ",
"AccNick ",
"AccRoll ",
"GyroYaw ",
"ReadingHeight ", //5
"GyroGier ",
"HoehenWert ", //5
"AccZ ",
"Thrust ",
"CompassHeading ",
"Voltage ",
"Receiver Level ", //10
"YawGyroHeading ",
"Motor_Front ",
"Motor_Rear ",
"Motor_Right ",
"Motor_Left ", //15
"Gas ",
"KompassValue ",
"Spannung ",
"Empfang ", //10
"Ersatzkompass ",
"Motor_Vorne ",
"Motor_Hinten ",
"Motor_Links ",
"Motor_Rechts ", //15
"Acc_Z ",
"SPI Error ",
"SPI Ok ",
" ",
"Distance ",
"OsdBar ",
"MK3Mag CalState ",
"Servo ", //20
"Pitch ",
"Nick ",
"Roll ",
" ",
" ",
95,422 → 67,355
" ",
" ",
" ",
"GPS_Pitch ", //30
"GPS_Nick ", //30
"GPS_Roll "
};
 
 
 
/****************************************************************/
/* Initialization of the USART0 */
/****************************************************************/
void USART0_Init (void)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Sende-Part der Datenübertragung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SIGNAL(INT_VEC_TX)
{
uint8_t sreg = SREG;
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * USART0_BAUD) - 1);
 
// disable all interrupts before configuration
cli();
 
// disable RX-Interrupt
UCSR0B &= ~(1 << RXCIE0);
// disable TX-Interrupt
UCSR0B &= ~(1 << TXCIE0);
 
// set direction of RXD0 and TXD0 pins
// set RXD0 (PD0) as an input pin
PORTD |= (1 << PORTD0);
DDRD &= ~(1 << DDD0);
// set TXD0 (PD1) as an output pin
PORTD |= (1 << PORTD1);
DDRD |= (1 << DDD1);
 
// USART0 Baud Rate Register
// set clock divider
UBRR0H = (uint8_t)(ubrr >> 8);
UBRR0L = (uint8_t)ubrr;
 
// USART0 Control and Status Register A, B, C
 
// enable double speed operation in
UCSR0A |= (1 << U2X0);
// enable receiver and transmitter in
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
// set asynchronous mode
UCSR0C &= ~(1 << UMSEL01);
UCSR0C &= ~(1 << UMSEL00);
// no parity
UCSR0C &= ~(1 << UPM01);
UCSR0C &= ~(1 << UPM00);
// 1 stop bit
UCSR0C &= ~(1 << USBS0);
// 8-bit
UCSR0B &= ~(1 << UCSZ02);
UCSR0C |= (1 << UCSZ01);
UCSR0C |= (1 << UCSZ00);
 
// flush receive buffer
while ( UCSR0A & (1<<RXC0) ) UDR0;
 
// enable interrupts at the end
// enable RX-Interrupt
UCSR0B |= (1 << RXCIE0);
// enable TX-Interrupt
UCSR0B |= (1 << TXCIE0);
 
rxd_buffer_locked = FALSE;
txd_complete = TRUE;
 
Debug_Timer = SetDelay(200);
 
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
Compass_Timer = SetDelay(220);
#endif
 
// restore global interrupt flags
SREG = sreg;
static unsigned int ptr = 0;
unsigned char tmp_tx;
if(!UebertragungAbgeschlossen)
{
ptr++; // die [0] wurde schon gesendet
tmp_tx = SendeBuffer[ptr];
if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
{
ptr = 0;
UebertragungAbgeschlossen = 1;
}
UDR = tmp_tx;
}
else ptr = 0;
}
 
/****************************************************************/
/* USART0 transmitter ISR */
/****************************************************************/
ISR(USART0_TX_vect)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Empfangs-Part der Datenübertragung, incl. CRC-Auswertung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SIGNAL(INT_VEC_RX)
{
static uint16_t ptr_txd_buffer = 0;
uint8_t tmp_tx;
if(!txd_complete) // transmission not completed
{
ptr_txd_buffer++; // die [0] wurde schon gesendet
tmp_tx = txd_buffer[ptr_txd_buffer];
// if terminating character or end of txd buffer was reached
if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
{
ptr_txd_buffer = 0; // reset txd pointer
txd_complete = 1; // stop transmission
}
UDR0 = tmp_tx; // send current byte will trigger this ISR again
}
// transmission completed
else ptr_txd_buffer = 0;
}
static unsigned int crc;
static unsigned char crc1,crc2,buf_ptr;
static unsigned char UartState = 0;
unsigned char CrcOkay = 0;
 
/****************************************************************/
/* USART0 receiver ISR */
/****************************************************************/
ISR(USART0_RX_vect)
{
static uint16_t crc;
static uint8_t ptr_rxd_buffer = 0;
uint8_t crc1, crc2;
uint8_t c;
 
c = UDR0; // catch the received byte
 
#ifdef USE_KILLAGREG
// If the FC 1.0 cpu is used the ublox module should be conneced to rxd of the 1st uart.
// The FC 1.1 /1.2 has the ATMEGA644p cpu with a 2nd uart to which the ublox should be connected.
#if defined (__AVR_ATmega644P__)
if(BoardRelease == 10) ubx_parser(c);
#else
ubx_parser(c);
#endif
#endif // USE_KILLAGREG
 
if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
 
// the rxd buffer is unlocked
if((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
{
rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
crc = c; // init crc
}
#if 0
else if (ptr_rxd_buffer == 1) // handle address
{
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
crc += c; // update crc
}
#endif
else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
{
if(c != '\r') // no termination character
{
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
crc += c; // update crc
}
else // termination character was received
{
// the last 2 bytes are no subject for checksum calculation
// they are the checksum itself
crc -= rxd_buffer[ptr_rxd_buffer-2];
crc -= rxd_buffer[ptr_rxd_buffer-1];
// calculate checksum from transmitted data
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
// compare checksum to transmitted checksum bytes
if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1]))
{ // checksum valid
rxd_buffer_locked = TRUE; // lock the rxd buffer
ReceivedBytes = ptr_rxd_buffer; // store number of received bytes
rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
// if 2nd byte is an 'R' enable watchdog that will result in an reset
if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
}
else
{ // checksum invalid
rxd_buffer_locked = FALSE; // unlock rxd buffer
}
ptr_rxd_buffer = 0; // reset rxd buffer pointer
}
}
else // rxd buffer overrun
{
ptr_rxd_buffer = 0; // reset rxd buffer
rxd_buffer_locked = FALSE; // unlock rxd buffer
}
 
SioTmp = UDR;
if(buf_ptr >= MAX_EMPFANGS_BUFF) UartState = 0;
if(SioTmp == '\r' && UartState == 2)
{
UartState = 0;
crc -= RxdBuffer[buf_ptr-2];
crc -= RxdBuffer[buf_ptr-1];
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; CntCrcError++;};
if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet
{
NeuerDatensatzEmpfangen = 1;
AnzahlEmpfangsBytes = buf_ptr;
RxdBuffer[buf_ptr] = '\r';
if(RxdBuffer[2] == 'R') wdt_enable(WDTO_250MS); // Reset-Commando
}
}
else
switch(UartState)
{
case 0:
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet
buf_ptr = 0;
RxdBuffer[buf_ptr++] = SioTmp;
crc = SioTmp;
break;
case 1: // Adresse auswerten
UartState++;
RxdBuffer[buf_ptr++] = SioTmp;
crc += SioTmp;
break;
case 2: // Eingangsdaten sammeln
RxdBuffer[buf_ptr] = SioTmp;
if(buf_ptr < MAX_EMPFANGS_BUFF) buf_ptr++;
else UartState = 0;
crc += SioTmp;
break;
default:
UartState = 0;
break;
}
}
 
 
// --------------------------------------------------------------------------
void AddCRC(uint16_t datalen)
void AddCRC(unsigned int wieviele)
{
uint16_t tmpCRC = 0, i;
for(i = 0; i < datalen; i++)
{
tmpCRC += txd_buffer[i];
}
tmpCRC %= 4096;
txd_buffer[i++] = '=' + tmpCRC / 64;
txd_buffer[i++] = '=' + tmpCRC % 64;
txd_buffer[i++] = '\r';
txd_complete = FALSE;
UDR0 = txd_buffer[0]; // initiates the transmittion (continued in the TXD ISR)
unsigned int tmpCRC = 0,i;
for(i = 0; i < wieviele;i++)
{
tmpCRC += SendeBuffer[i];
}
tmpCRC %= 4096;
SendeBuffer[i++] = '=' + tmpCRC / 64;
SendeBuffer[i++] = '=' + tmpCRC % 64;
SendeBuffer[i++] = '\r';
UebertragungAbgeschlossen = 0;
UDR = SendeBuffer[0];
}
 
 
 
// --------------------------------------------------------------------------
void SendOutData(uint8_t cmd,uint8_t module, uint8_t *snd, uint8_t len)
void SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len)
{
uint16_t pt = 0;
uint8_t a,b,c;
uint8_t ptr = 0;
unsigned int pt = 0;
unsigned char a,b,c;
unsigned char ptr = 0;
 
txd_buffer[pt++] = '#'; // Start character
txd_buffer[pt++] = module; // Address (a=0; b=1,...)
txd_buffer[pt++] = cmd; // Command
SendeBuffer[pt++] = '#'; // Startzeichen
SendeBuffer[pt++] = modul; // Adresse (a=0; b=1,...)
SendeBuffer[pt++] = cmd; // Commando
 
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
txd_buffer[pt++] = '=' + (a >> 2);
txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
txd_buffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt); // add checksum after data block and initates the transmission
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
SendeBuffer[pt++] = '=' + (a >> 2);
SendeBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
SendeBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
SendeBuffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt);
}
 
 
// --------------------------------------------------------------------------
void Decode64(uint8_t *ptrOut, uint8_t len, uint8_t ptrIn, uint8_t max)
void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max) // Wohin mit den Daten; Wie lang; Wo im RxdBuffer
{
uint8_t a,b,c,d;
uint8_t ptr = 0;
uint8_t x,y,z;
while(len)
{
a = rxd_buffer[ptrIn++] - '=';
b = rxd_buffer[ptrIn++] - '=';
c = rxd_buffer[ptrIn++] - '=';
d = rxd_buffer[ptrIn++] - '=';
if(ptrIn > max - 2) break;
unsigned char a,b,c,d;
unsigned char ptr = 0;
unsigned char x,y,z;
while(len)
{
a = RxdBuffer[ptrIn++] - '=';
b = RxdBuffer[ptrIn++] - '=';
c = RxdBuffer[ptrIn++] - '=';
d = RxdBuffer[ptrIn++] - '=';
if(ptrIn > max - 2) break; // nicht mehr Daten verarbeiten, als empfangen wurden
 
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
 
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
 
}
 
 
// --------------------------------------------------------------------------
void USART0_ProcessRxData(void)
void BearbeiteRxDaten(void)
{
// if data in the rxd buffer are not locked immediately return
if(!rxd_buffer_locked) return;
if(!NeuerDatensatzEmpfangen) return;
 
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
uint16_t tmp_int_arr1[1]; // local int buffer
#endif
uint8_t tmp_char_arr2[2]; // local char buffer
 
 
switch(rxd_buffer[2])
{
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
case 'K':// Compass value
Decode64((uint8_t *) &tmp_int_arr1[0], sizeof(tmp_int_arr1), 3, ReceivedBytes);
CompassHeading = tmp_int_arr1[0];
CompassOffCourse = ((540 + CompassHeading - CompassCourse) % 360) - 180;
unsigned int tmp_int_arr1[1];
// unsigned int tmp_int_arr2[2];
// unsigned int tmp_int_arr3[3];
unsigned char tmp_char_arr2[2];
// unsigned char tmp_char_arr3[3];
// unsigned char tmp_char_arr4[4];
//if(!MotorenEin)
switch(RxdBuffer[2])
{
case 'K':// Kompasswert
Decode64((unsigned char *) &tmp_int_arr1[0],sizeof(tmp_int_arr1),3,AnzahlEmpfangsBytes);
KompassValue = tmp_int_arr1[0];
KompassRichtung = ((540 + KompassValue - KompassStartwert) % 360) - 180;
break;
#endif
case 'a':// Labels of the Analog Debug outputs
Decode64((uint8_t *) &tmp_char_arr2[0], sizeof(tmp_char_arr2), 3, ReceivedBytes);
RequestDebugLabel = tmp_char_arr2[0];
PcAccess = 255;
case 'a':// Texte der Analogwerte
Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
DebugTextAnforderung = tmp_char_arr2[0];
PcZugriff = 255;
break;
case 'b': // extern control
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl), 3, ReceivedBytes);
RemoteButtons |= ExternControl.RemoteButtons;
ConfirmFrame = ExternControl.Frame;
case 'b':
Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
RemoteTasten |= ExternControl.RemoteTasten;
ConfirmFrame = ExternControl.Frame;
break;
case 'c':
Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
RemoteTasten |= ExternControl.RemoteTasten;
ConfirmFrame = ExternControl.Frame;
DebugDataAnforderung = 1;
PcZugriff = 255;
break;
case 'h':// x-1 Displayzeilen
Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
RemoteTasten |= tmp_char_arr2[0];
if(tmp_char_arr2[1] == 255) NurKanalAnforderung = 1; else NurKanalAnforderung = 0; // keine Displaydaten
DebugDisplayAnforderung = 1;
break;
case 'c': // extern control with debug request
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl),3,ReceivedBytes);
RemoteButtons |= ExternControl.RemoteButtons;
ConfirmFrame = ExternControl.Frame;
RequestDebugData = TRUE;
PcAccess = 255;
case 't':// Motortest
Decode64((unsigned char *) &MotorTest[0],sizeof(MotorTest),3,AnzahlEmpfangsBytes);
PcZugriff = 255;
break;
case 'h':// x-1 display columns
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,ReceivedBytes);
RemoteButtons |= tmp_char_arr2[0];
if(tmp_char_arr2[1] == 255) RequestChannelOnly = TRUE;
else RequestChannelOnly = FALSE; // keine Displaydaten
RequestDisplay = TRUE;
break;
case 't':// motor test
Decode64((uint8_t *) &MotorTest[0],sizeof(MotorTest),3,ReceivedBytes);
PcAccess = 255;
break;
case 'k':// keys from DubWise
Decode64((uint8_t *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,ReceivedBytes);
case 'k':// Keys von DubWise
Decode64((unsigned char *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,AnzahlEmpfangsBytes);
ConfirmFrame = DubWiseKeys[3];
PcAccess = 255;
PcZugriff = 255;
break;
case 'v': // get version and board release
RequestVerInfo = TRUE;
break;
case 'g':// get external control data
RequestExternalControl = TRUE;
break;
case 'q':// get settings
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,ReceivedBytes);
while(!txd_complete);
if(tmp_char_arr2[0] != 0xff)
{
if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5; // limit to 5
// load requested parameter set
ParamSet_ReadFromEEProm(tmp_char_arr2[0]);
SendOutData('L' + tmp_char_arr2[0] -1,MySlaveAddr,(uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN);
}
else // send active parameter set
SendOutData('L' + GetParamByte(PID_ACTIVE_SET)-1,MySlaveAddr,(uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN);
 
break;
 
case 'l':
case 'm':
case 'n':
case 'o':
case 'p': // save parameterset
Decode64((uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN,3,ReceivedBytes);
ParamSet_WriteToEEProm(rxd_buffer[2] - 'l' + 1);
TurnOver180Pitch = (int32_t) ParamSet.AngleTurnOverPitch * 2500L;
TurnOver180Roll = (int32_t) ParamSet.AngleTurnOverRoll * 2500L;
Beep(GetActiveParamSet());
break;
 
 
}
// unlock the rxd buffer after processing
rxd_buffer_locked = FALSE;
case 'v': // Version-Anforderung und Ausbaustufe
GetVersionAnforderung = 1;
break;
case 'g':// "Get"-Anforderung für Debug-Daten
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
DebugGetAnforderung = 1;
break;
case 'q':// "Get"-Anforderung für Settings
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
while(!UebertragungAbgeschlossen);
if(tmp_char_arr2[0] != 0xff)
{
if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5;
ReadParameterSet(tmp_char_arr2[0], (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
SendOutData('L' + tmp_char_arr2[0] -1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
}
else
SendOutData('L' + GetActiveParamSetNumber()-1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
break;
case 'l':
case 'm':
case 'n':
case 'o':
case 'p': // Parametersatz speichern
Decode64((unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE,3,AnzahlEmpfangsBytes);
WriteParameterSet(RxdBuffer[2] - 'l' + 1, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], RxdBuffer[2] - 'l' + 1); // aktiven Datensatz merken
Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L;
Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L;
Piep(GetActiveParamSetNumber());
break;
}
// DebugOut.AnzahlZyklen = Debug_Timer_Intervall;
NeuerDatensatzEmpfangen = 0;
}
 
//############################################################################
//Routine für die Serielle Ausgabe
int16_t uart_putchar (int8_t c)
int uart_putchar (char c)
//############################################################################
{
if (c == '\n')
uart_putchar('\r');
// wait until previous character was send
loop_until_bit_is_set(UCSR0A, UDRE0);
//Warten solange bis Zeichen gesendet wurde
loop_until_bit_is_set(USR, UDRE);
//Ausgabe des Zeichens
UDR0 = c;
UDR = c;
return (0);
}
 
// --------------------------------------------------------------------------
void WriteProgramData(unsigned int pos, unsigned char wert)
{
//if (ProgramLocation == IN_RAM) Buffer[pos] = wert;
// else eeprom_write_byte(&EE_Buffer[pos], wert);
// Buffer[pos] = wert;
}
 
//############################################################################
//INstallation der Seriellen Schnittstelle
void UART_Init (void)
//############################################################################
{
//Enable TXEN im Register UCR TX-Data Enable & RX Enable
 
UCR=(1 << TXEN) | (1 << RXEN);
// UART Double Speed (U2X)
USR |= (1<<U2X);
// RX-Interrupt Freigabe
UCSRB |= (1<<RXCIE);
// TX-Interrupt Freigabe
UCSRB |= (1<<TXCIE);
 
//Teiler wird gesetzt
UBRR=(SYSCLK / (BAUD_RATE * 8L) - 1);
//UBRR = 33;
//öffnet einen Kanal für printf (STDOUT)
//fdevopen (uart_putchar, 0);
//sbi(PORTD,4);
Debug_Timer = SetDelay(200);
Kompass_Timer = SetDelay(220);
}
 
//---------------------------------------------------------------------------------------------
void USART0_TransmitTxData(void)
void DatenUebertragung(void)
{
if(!txd_complete) return;
if(!UebertragungAbgeschlossen) return;
 
if(RequestExternalControl && txd_complete) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
{
SendOutData('G',MySlaveAddr,(uint8_t *) &ExternControl,sizeof(ExternControl));
RequestExternalControl = FALSE;
}
if(DebugGetAnforderung && UebertragungAbgeschlossen) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
{
SendOutData('G',MeineSlaveAdresse,(unsigned char *) &ExternControl,sizeof(ExternControl));
DebugGetAnforderung = 0;
}
 
#if !defined (USE_KILLAGREG) && !defined (USE_NAVICTRL)
if((CheckDelay(Compass_Timer)) && txd_complete)
{
ToMk3Mag.Attitude[0] = (int16_t) (IntegralPitch / 108); // approx. 0,1 Deg
ToMk3Mag.Attitude[1] = (int16_t) (IntegralRoll / 108); // approx. 0,1 Deg
ToMk3Mag.UserParam[0] = FCParam.UserParam1;
ToMk3Mag.UserParam[1] = FCParam.UserParam2;
ToMk3Mag.CalState = CompassCalState;
SendOutData('w',MySlaveAddr,(uint8_t *) &ToMk3Mag,sizeof(ToMk3Mag));
// the last state is 5 and should be send only once to avoid multiple flash writing
if(CompassCalState > 4) CompassCalState = 0;
Compass_Timer = SetDelay(99);
}
#endif
if((CheckDelay(Kompass_Timer)) && UebertragungAbgeschlossen)
{
WinkelOut.Winkel[0] = (int) (IntegralNick / 108); // etwa in 0,1 Grad
WinkelOut.Winkel[1] = (int) (IntegralRoll / 108); // etwa in 0,1 Grad
WinkelOut.UserParameter[0] = Parameter_UserParam1;
WinkelOut.UserParameter[1] = Parameter_UserParam2;
SendOutData('w',MeineSlaveAdresse,(unsigned char *) &WinkelOut,sizeof(WinkelOut));
if(WinkelOut.CalcState > 4) WinkelOut.CalcState = 6; // wird dann in SPI auf Null gesetzt
Kompass_Timer = SetDelay(99);
}
 
if((CheckDelay(Debug_Timer) || RequestDebugData) && txd_complete)
{
SendOutData('D',MySlaveAddr,(uint8_t *) &DebugOut,sizeof(DebugOut));
RequestDebugData = FALSE;
Debug_Timer = SetDelay(MIN_DEBUG_INTERVALL);
}
 
if(RequestDebugLabel != 255) // Texte für die Analogdaten
if((CheckDelay(Debug_Timer) || DebugDataAnforderung) && UebertragungAbgeschlossen)
{
SendOutData('D',MeineSlaveAdresse,(unsigned char *) &DebugOut,sizeof(DebugOut));
DebugDataAnforderung = 0;
Debug_Timer = SetDelay(MIN_DEBUG_INTERVALL);
}
if(DebugTextAnforderung != 255) // Texte für die Analogdaten
{
SendOutData('A',RequestDebugLabel + '0',(uint8_t *) ANALOG_LABEL[RequestDebugLabel],16);
RequestDebugLabel = 255;
SendOutData('A',DebugTextAnforderung + '0',(unsigned char *) ANALOG_TEXT[DebugTextAnforderung],16);
DebugTextAnforderung = 255;
}
if(ConfirmFrame && txd_complete) // Datensatz ohne CRC bestätigen
if(ConfirmFrame && UebertragungAbgeschlossen) // Datensatz ohne CRC bestätigen
{
txd_buffer[0] = '#';
txd_buffer[1] = ConfirmFrame;
txd_buffer[2] = '\r';
txd_complete = 0;
SendeBuffer[0] = '#';
SendeBuffer[1] = ConfirmFrame;
SendeBuffer[2] = '\r';
UebertragungAbgeschlossen = 0;
ConfirmFrame = 0;
UDR0 = txd_buffer[0];
UDR = SendeBuffer[0];
}
if(RequestDisplay && txd_complete)
if(DebugDisplayAnforderung && UebertragungAbgeschlossen)
{
LCD_PrintMenu();
RequestDisplay = FALSE;
if(++RemotePollDisplayLine == 4 || RequestChannelOnly)
Menu();
DebugDisplayAnforderung = 0;
if(++RemotePollDisplayLine == 4 || NurKanalAnforderung)
{
SendOutData('4',0,(uint8_t *)&PPM_in,sizeof(PPM_in)); // DisplayZeile übertragen
SendOutData('4',0,(unsigned char *)&PPM_in,sizeof(PPM_in)); // DisplayZeile übertragen
RemotePollDisplayLine = -1;
}
else SendOutData('0' + RemotePollDisplayLine,0,(uint8_t *)&DisplayBuff[20 * RemotePollDisplayLine],20); // DisplayZeile übertragen
}
if(RequestVerInfo && txd_complete)
{
SendOutData('V',MySlaveAddr,(uint8_t *) &VersionInfo,sizeof(VersionInfo));
RequestVerInfo = FALSE;
}
else SendOutData('0' + RemotePollDisplayLine,0,(unsigned char *)&DisplayBuff[20 * RemotePollDisplayLine],20); // DisplayZeile übertragen
}
if(GetVersionAnforderung && UebertragungAbgeschlossen)
{
SendOutData('V',MeineSlaveAdresse,(unsigned char *) &VersionInfo,sizeof(VersionInfo));
GetVersionAnforderung = 0;
}
 
}
/branches/V0.69k Code Redesign killagreg/uart.h
1,63 → 1,116
#ifndef _UART_H
#define _UART_H
#ifndef _UART_H
#define _UART_H
 
#define TXD_BUFFER_LEN 150
#define RXD_BUFFER_LEN 150
 
#define MAX_SENDE_BUFF 150
#define MAX_EMPFANGS_BUFF 150
#define DUB_KEY_UP 4
#define DUB_KEY_DOWN 8
#define DUB_KEY_RIGHT 32
#define DUB_KEY_LEFT 16
#define DUB_KEY_RIGHT 32
#define DUB_KEY_FIRE 64
 
#include <inttypes.h>
void BearbeiteRxDaten(void);
 
//Baud rate of the USART
#define USART0_BAUD 57600
extern unsigned char DebugGetAnforderung;
extern unsigned volatile char SendeBuffer[MAX_SENDE_BUFF];
extern unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
extern unsigned volatile char UebertragungAbgeschlossen;
extern unsigned volatile char PC_DebugTimeout;
extern unsigned volatile char NeueKoordinateEmpfangen;
extern unsigned char MeineSlaveAdresse;
extern unsigned char PcZugriff;
extern unsigned char RemotePollDisplayLine;
extern int Debug_Timer,Kompass_Timer;
extern void UART_Init (void);
extern int uart_putchar (char c);
extern void boot_program_page (uint32_t page, uint8_t *buf);
extern void DatenUebertragung(void);
extern void DecodeNMEA(void);
extern void BearbeiteRxDaten(void);
extern unsigned char MotorTest[4];
extern unsigned char DubWiseKeys[4];
struct str_DebugOut
{
unsigned char Digital[2];
signed int Analog[32]; // Debugwerte
};
 
extern struct str_DebugOut DebugOut;
 
extern void USART0_Init (void);
extern void USART0_TransmitTxData(void);
extern void USART0_ProcessRxData(void);
extern int16_t uart_putchar(int8_t c);
struct str_WinkelOut
{
signed int Winkel[2];
unsigned char UserParameter[2];
unsigned char CalcState;
unsigned char Orientation;
};
extern struct str_WinkelOut WinkelOut;
 
extern uint8_t PcAccess;
extern uint8_t RemotePollDisplayLine;
extern uint8_t MotorTest[4];
extern uint8_t DubWiseKeys[4];
struct str_ExternControl
{
unsigned char Digital[2];
unsigned char RemoteTasten;
signed char Nick;
signed char Roll;
signed char Gier;
unsigned char Gas;
signed char Hight;
unsigned char free;
unsigned char Frame;
unsigned char Config;
};
extern struct str_ExternControl ExternControl;
 
typedef struct
struct str_VersionInfo
{
uint8_t Digital[2];
uint16_t Analog[32]; // Debugvalues
} DebugOut_t;
unsigned char Hauptversion;
unsigned char Nebenversion;
unsigned char PCKompatibel;
unsigned char Rserved[7];
};
extern struct str_VersionInfo VersionInfo;
 
extern DebugOut_t DebugOut;
//Die Baud_Rate der Seriellen Schnittstelle ist 9600 Baud
//#define BAUD_RATE 9600 //Baud Rate für die Serielle Schnittstelle
//#define BAUD_RATE 14400 //Baud Rate für die Serielle Schnittstelle
//#define BAUD_RATE 28800 //Baud Rate für die Serielle Schnittstelle
//#define BAUD_RATE 38400 //Baud Rate für die Serielle Schnittstelle
#define BAUD_RATE 57600 //Baud Rate für die Serielle Schnittstelle
 
typedef struct
{
uint8_t Digital[2];
uint8_t RemoteButtons;
int8_t Pitch;
int8_t Roll;
int8_t Yaw;
uint8_t Thrust;
int8_t Height;
uint8_t free;
uint8_t Frame;
uint8_t Config;
} ExternControl_t;
//Anpassen der seriellen Schnittstellen Register wenn ein ATMega128 benutzt wird
#if defined (__AVR_ATmega128__)
# define USR UCSR0A
# define UCR UCSR0B
# define UDR UDR0
# define UBRR UBRR0L
# define EICR EICRB
#endif
 
extern ExternControl_t ExternControl;
#if defined (__AVR_ATmega32__)
# define USR UCSRA
# define UCR UCSRB
# define UBRR UBRRL
# define EICR EICRB
# define INT_VEC_RX SIG_UART_RECV
# define INT_VEC_TX SIG_UART_TRANS
#endif
 
typedef struct
{
uint8_t Major;
uint8_t Minor;
uint8_t PCCompatible;
uint8_t Reserved[7];
} VersionInfo_t;
#if defined (__AVR_ATmega644__)
# define USR UCSR0A
# define UCR UCSR0B
# define UDR UDR0
# define UBRR UBRR0L
# define EICR EICR0B
# define TXEN TXEN0
# define RXEN RXEN0
# define RXCIE RXCIE0
# define TXCIE TXCIE0
# define U2X U2X0
# define UCSRB UCSR0B
# define UDRE UDRE0
# define INT_VEC_RX SIG_USART_RECV
# define INT_VEC_TX SIG_USART_TRANS
#endif
 
extern VersionInfo_t VersionInfo;
 
#endif //_UART_H
/branches/V0.69k Code Redesign killagreg/version.txt
112,8 → 112,8
V0.68c H.Buss 05.01.2008
- Stickauswertung verbessert -> träger und präziser
- Alle Settings angepasst
V0.69g H.Buss 05.05.2008
 
V0.69e H.Buss 05.05.2008
- kleinere Bugs beseitigt
- Schneller Sinkflug jetzt möglich
- Min- und Maxgas in den Settings geändert
125,37 → 125,13
- STICK_GAIN = 4 eingeführt. Das erhöht die Auflösung der Sollwerte. Stick_P und Stick_I müssen nun um Faktor 4 erhöht werden
- SenderOkay auch an das Naviboard übertragen
- Bessere Parameter bei Senderausfall
V0.69j H.Buss 30.05.2008
- Höhere Präzision der Achsenkopplung
 
V0.69j H.Buss 30.05.2008
- Höhere Auflösung der Achsenkopplung
V0.69k H.Buss 31.05.2008
- Bug in SPI.C behoben
- in 0.69h war ein Bug, der zu ungewollten Loopings führen konnte
 
 
Anpassungen bzgl. V0.69k
G.Stobrawa 01.06.2008:
 
- Code stärker modularisiert und restrukturiert
- viele Kommentare zur Erklärug eingefügt
- konsequent englische Variablennamen
- PPM24 Support für bis zu 12 RC-Kanäle.
- 2. Uart wird nun unterstützt (MCU = atmega644p im Makefile)
- Makefile: EXT nicht definiert Unerstützung des MK3MAG direct an FC
- Makefile: EXT=NAVICTRL Unterstützung der SPI Communikation zum Naviboard
- Makefile: EXT=KILLAGREG Unterstützung vom KillagregBoard mit MM3 und Conrad UBLOX Modul
- Ausertung des UBX-Pprotocols an 1. oder 2. Uart
- GPS-Hold-Funktion hinzugefügt
- GPS-Home-Funktion hinzugefügt (wird beim Motorstart gelernt, und bei Motorenstop wieder gelöscht)
- Poti3 steuert die GPS Funktionen (Poti3 < 70:GPS inaktiv, 70<=Poti3<160: GPS Hold, 160<=Poti3: GPS Home)
- LED Steuerung an J16, parametrierbar durch die User Parameter 7 & 8. UserParam7 legt die LEDOnTime in Vielfachen von 2ms fest
und UserParam 8 die LEDOffTime.
- Zusätzliche Punkte im Menü des KopterTool zur Anzeige des GPS-Status und der MM3-Kalibierparameter