Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 1467 → Rev 1687

/NGVideo5_8/tags/v1.33/GPGGA16x16_02_2012a.txt
0,0 → 1,69
MON-VER - 0A 04 46 00 35 2E 30 30 20 20 20 20 4A 61 6E 20 30 39 20 32 30 30 36 20 31 32 3A 30 30 3A 30 30 00 01 30 30 30 34 30 30 30 31 00 00 4D 34 48 31 2E 31 20 20 4A 61 6E 20 30 39 20 32 30 30 36 20 31 35 3A 33 39 3A 35 34 00 00
CFG-ANT - 06 13 04 00 0B 00 0F 38
CFG-DAT - 06 06 02 00 00 00
CFG-FXN - 06 0E 24 00 12 00 00 00 C0 D4 01 00 C0 D4 01 00 C0 27 09 00 C0 27 09 00 00 00 00 00 40 77 1B 00 00 00 00 00 00 00 00 00
CFG-INF - 06 02 08 00 00 00 00 00 00 87 00 00
CFG-INF - 06 02 08 00 01 00 00 00 00 87 00 87
CFG-INF - 06 02 08 00 03 00 00 00 00 00 00 00
CFG-MSG - 06 01 06 00 01 01 00 00 00 00
CFG-MSG - 06 01 06 00 01 02 00 01 00 00
CFG-MSG - 06 01 06 00 01 03 00 00 00 00
CFG-MSG - 06 01 06 00 01 04 00 00 00 00
CFG-MSG - 06 01 06 00 01 06 00 01 00 00
CFG-MSG - 06 01 06 00 01 08 00 01 00 00
CFG-MSG - 06 01 06 00 01 11 00 00 00 00
CFG-MSG - 06 01 06 00 01 12 00 01 00 00
CFG-MSG - 06 01 06 00 01 20 00 00 00 00
CFG-MSG - 06 01 06 00 01 21 00 00 00 00
CFG-MSG - 06 01 06 00 01 22 00 00 00 00
CFG-MSG - 06 01 06 00 01 30 00 00 00 00
CFG-MSG - 06 01 06 00 01 31 00 00 00 00
CFG-MSG - 06 01 06 00 01 32 00 00 00 00
CFG-MSG - 06 01 06 00 02 10 00 00 00 00
CFG-MSG - 06 01 06 00 02 11 00 00 00 00
CFG-MSG - 06 01 06 00 02 20 00 00 00 00
CFG-MSG - 06 01 06 00 02 30 00 00 00 00
CFG-MSG - 06 01 06 00 02 31 00 00 00 00
CFG-MSG - 06 01 06 00 0A 01 00 00 00 00
CFG-MSG - 06 01 06 00 0A 02 00 00 00 00
CFG-MSG - 06 01 06 00 0A 03 00 00 00 00
CFG-MSG - 06 01 06 00 0A 05 00 00 01 00
CFG-MSG - 06 01 06 00 0A 06 00 00 00 00
CFG-MSG - 06 01 06 00 0A 07 00 00 00 00
CFG-MSG - 06 01 06 00 0A 08 00 00 01 00
CFG-MSG - 06 01 06 00 0A 09 00 00 00 00
CFG-MSG - 06 01 06 00 0A 0A 00 00 00 00
CFG-MSG - 06 01 06 00 0B 00 00 00 00 00
CFG-MSG - 06 01 06 00 0B 30 00 00 00 00
CFG-MSG - 06 01 06 00 0B 31 00 00 00 00
CFG-MSG - 06 01 06 00 0D 01 00 00 00 00
CFG-MSG - 06 01 06 00 0D 03 00 00 00 00
CFG-MSG - 06 01 06 00 0D 04 00 00 00 00
CFG-MSG - 06 01 06 00 F0 00 00 01 00 00
CFG-MSG - 06 01 06 00 F0 01 00 00 00 01
CFG-MSG - 06 01 06 00 F0 02 00 00 00 01
CFG-MSG - 06 01 06 00 F0 03 00 00 00 01
CFG-MSG - 06 01 06 00 F0 04 00 00 00 01
CFG-MSG - 06 01 06 00 F0 05 00 00 00 01
CFG-MSG - 06 01 06 00 F0 06 00 00 00 00
CFG-MSG - 06 01 06 00 F0 07 00 00 00 00
CFG-MSG - 06 01 06 00 F0 08 00 00 00 01
CFG-MSG - 06 01 06 00 F0 09 00 00 00 00
CFG-MSG - 06 01 06 00 F0 0A 00 00 00 00
CFG-MSG - 06 01 06 00 F1 00 00 00 00 00
CFG-MSG - 06 01 06 00 F1 01 00 00 00 00
CFG-MSG - 06 01 06 00 F1 03 00 01 00 00
CFG-MSG - 06 01 06 00 F1 04 00 00 00 00
CFG-NAV2 - 06 1A 28 00 05 00 00 00 04 04 10 03 50 C3 00 00 18 14 05 3C 00 03 00 00 FA 00 FA 00 64 00 2C 01 00 00 00 00 00 00 00 00 00 00 00 00
CFG-NMEA - 06 17 04 00 00 23 10 02
CFG-PRT - 06 00 14 00 01 00 00 00 D0 08 00 00 00 E1 00 00 03 00 02 00 00 00 00 00
CFG-PRT - 06 00 14 00 02 00 00 00 D0 08 08 00 00 E1 00 00 07 00 03 00 00 00 00 00
CFG-PRT - 06 00 14 00 03 00 00 00 00 00 00 00 00 00 00 00 03 00 03 00 00 00 00 00
CFG-RATE - 06 08 06 00 C8 00 01 00 00 00
CFG-RXM - 06 11 02 00 02 00
CFG-SBAS - 06 16 08 00 01 03 02 00 51 08 00 00
CFG-TM2 - 06 19 0C 00 00 00 00 00 E8 03 00 00 14 01 00 00
CFG-TM2 - 06 19 0C 00 01 00 00 00 E8 03 00 00 14 01 00 00
CFG-TMODE - 06 1D 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 27 00 00 80 51 01 00 10 27 00 00
CFG-TP - 06 07 14 00 40 42 0F 00 20 A1 07 00 FF 01 00 00 32 00 34 03 00 00 00 00
CFG-USB - 06 1B 6C 00 46 15 A4 01 00 00 01 00 64 00 02 00 75 2D 62 6C 6F 78 20 41 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 4E 54 41 52 49 53 28 72 29 20 34 20 20 2D 20 20 47 50 53 20 52 65 63 65 69 76 65 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
/NGVideo5_8/tags/v1.33/GPGGA_01_2011b.txt
0,0 → 1,69
MON-VER - 0A 04 46 00 35 2E 30 30 20 20 20 20 4A 61 6E 20 30 39 20 32 30 30 36 20 31 32 3A 30 30 3A 30 30 00 01 30 30 30 34 30 30 30 31 00 00 4D 34 48 31 2E 31 20 20 4A 61 6E 20 30 39 20 32 30 30 36 20 31 35 3A 33 39 3A 35 34 00 00
CFG-ANT - 06 13 04 00 0B 00 0F 38
CFG-DAT - 06 06 02 00 00 00
CFG-FXN - 06 0E 24 00 02 00 00 00 C0 D4 01 00 C0 D4 01 00 20 BF 02 00 20 BF 02 00 00 00 00 00 40 77 1B 00 00 00 00 00 00 00 00 00
CFG-INF - 06 02 08 00 00 00 00 00 00 87 00 00
CFG-INF - 06 02 08 00 01 00 00 00 00 87 00 87
CFG-INF - 06 02 08 00 03 00 00 00 00 00 00 00
CFG-MSG - 06 01 06 00 01 01 00 00 00 00
CFG-MSG - 06 01 06 00 01 02 00 01 00 00
CFG-MSG - 06 01 06 00 01 03 00 00 00 00
CFG-MSG - 06 01 06 00 01 04 00 00 00 00
CFG-MSG - 06 01 06 00 01 06 00 01 00 00
CFG-MSG - 06 01 06 00 01 08 00 01 00 00
CFG-MSG - 06 01 06 00 01 11 00 00 00 00
CFG-MSG - 06 01 06 00 01 12 00 01 00 00
CFG-MSG - 06 01 06 00 01 20 00 00 00 00
CFG-MSG - 06 01 06 00 01 21 00 00 00 00
CFG-MSG - 06 01 06 00 01 22 00 00 00 00
CFG-MSG - 06 01 06 00 01 30 00 00 00 00
CFG-MSG - 06 01 06 00 01 31 00 00 00 00
CFG-MSG - 06 01 06 00 01 32 00 00 00 00
CFG-MSG - 06 01 06 00 02 10 00 00 00 00
CFG-MSG - 06 01 06 00 02 11 00 00 00 00
CFG-MSG - 06 01 06 00 02 20 00 00 00 00
CFG-MSG - 06 01 06 00 02 30 00 00 00 00
CFG-MSG - 06 01 06 00 02 31 00 00 00 00
CFG-MSG - 06 01 06 00 0A 01 00 00 00 00
CFG-MSG - 06 01 06 00 0A 02 00 00 00 00
CFG-MSG - 06 01 06 00 0A 03 00 00 00 00
CFG-MSG - 06 01 06 00 0A 05 00 00 01 00
CFG-MSG - 06 01 06 00 0A 06 00 00 00 00
CFG-MSG - 06 01 06 00 0A 07 00 00 00 00
CFG-MSG - 06 01 06 00 0A 08 00 00 01 00
CFG-MSG - 06 01 06 00 0A 09 00 00 00 00
CFG-MSG - 06 01 06 00 0A 0A 00 00 00 00
CFG-MSG - 06 01 06 00 0B 00 00 00 00 00
CFG-MSG - 06 01 06 00 0B 30 00 00 00 00
CFG-MSG - 06 01 06 00 0B 31 00 00 00 00
CFG-MSG - 06 01 06 00 0D 01 00 00 00 00
CFG-MSG - 06 01 06 00 0D 03 00 00 00 00
CFG-MSG - 06 01 06 00 0D 04 00 00 00 00
CFG-MSG - 06 01 06 00 F0 00 00 01 00 00
CFG-MSG - 06 01 06 00 F0 01 00 00 00 01
CFG-MSG - 06 01 06 00 F0 02 00 00 00 01
CFG-MSG - 06 01 06 00 F0 03 00 00 00 01
CFG-MSG - 06 01 06 00 F0 04 00 00 00 01
CFG-MSG - 06 01 06 00 F0 05 00 00 00 01
CFG-MSG - 06 01 06 00 F0 06 00 00 00 00
CFG-MSG - 06 01 06 00 F0 07 00 00 00 00
CFG-MSG - 06 01 06 00 F0 08 00 00 00 01
CFG-MSG - 06 01 06 00 F0 09 00 00 00 00
CFG-MSG - 06 01 06 00 F0 0A 00 00 00 00
CFG-MSG - 06 01 06 00 F1 00 00 00 00 00
CFG-MSG - 06 01 06 00 F1 01 00 00 00 00
CFG-MSG - 06 01 06 00 F1 03 00 01 00 00
CFG-MSG - 06 01 06 00 F1 04 00 00 00 00
CFG-NAV2 - 06 1A 28 00 05 00 00 00 04 04 10 03 50 C3 00 00 18 14 05 3C 00 03 00 00 FA 00 FA 00 64 00 2C 01 00 00 00 00 00 00 00 00 00 00 00 00
CFG-NMEA - 06 17 04 00 00 23 00 02
CFG-PRT - 06 00 14 00 01 00 00 00 D0 08 00 00 00 E1 00 00 03 00 02 00 00 00 00 00
CFG-PRT - 06 00 14 00 02 00 00 00 D0 08 08 00 00 E1 00 00 07 00 03 00 00 00 00 00
CFG-PRT - 06 00 14 00 03 00 00 00 00 00 00 00 00 00 00 00 03 00 03 00 00 00 00 00
CFG-RATE - 06 08 06 00 C8 00 01 00 00 00
CFG-RXM - 06 11 02 00 03 00
CFG-SBAS - 06 16 08 00 01 01 01 00 51 08 00 00
CFG-TM2 - 06 19 0C 00 00 00 00 00 E8 03 00 00 14 01 00 00
CFG-TM2 - 06 19 0C 00 01 00 00 00 E8 03 00 00 14 01 00 00
CFG-TMODE - 06 1D 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 27 00 00 80 51 01 00 10 27 00 00
CFG-TP - 06 07 14 00 40 42 0F 00 20 A1 07 00 FF 01 00 00 32 00 34 03 00 00 00 00
CFG-USB - 06 1B 6C 00 46 15 A4 01 00 00 01 00 64 00 02 00 75 2D 62 6C 6F 78 20 41 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 4E 54 41 52 49 53 28 72 29 20 34 20 20 2D 20 20 47 50 53 20 52 65 63 65 69 76 65 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
/NGVideo5_8/tags/v1.33/Hexfiles/NGVideo_MEGA644.hex
0,0 → 1,2154
:100000000C94FE070C944C110C94A0110C941B083A
:100010000C941B080C941B080C941B080C941B08D4
:100020000C941B080C941B080C941B080C94B9101E
:100030000C941B080C94712B0C941B080C941B083B
:100040000C941B080C941B080C947A280C941B0825
:100050000C94252C0C941B080C941B080C941B0866
:100060000C941B080C941B080C941B080C941B0884
:1000700020201010101020202020181818182020E0
:1000800020201C1C1C1C202020201E1E1E1E202088
:1000900020201F1F1F1F20200608141314080620ED
:1000A000040A200E04040E20200101010101012098
:1000B000201F010101011F20201F030303031F2034
:1000C000201F070707071F20201F0F0F0F0F1F20DC
:1000D000201F1F1F1F1F1F20201010101010102086
:1000E000201F202020201F202001010101010120CC
:1000F000201F101010101F20201F181818181F2064
:10010000201F1C1C1C1C1F20201F1E1E1E1E1F200B
:10011000C012201C80254038004B009600E10000F2
:10012000525353492D4D696E00525353492D4D6121
:100130007800446976657273697479004C434400B1
:100140004156310041563200312E52583A00322E7B
:1001500052583A003235350031303233005365722F
:10016000766F00536572766F203100536572766F3B
:10017000203200536572766F2D54657374005253AC
:100180005349004D4B2D436F636B70697400536589
:1001900072766F2D4879737465722E0042617564B2
:1001A000726174650020203556004E472D566964F3
:1001B000656F2020352E3847487A0A48573A200084
:1001C00020204D2E4265636B46573A20312E333343
:1001D0002020676562616400537072616368650026
:1001E0004465757473636800456E676C6973636812
:1001F000004672616E7A947369736368005A75720F
:1002000081636B0041562D5175656C6C65005258C9
:100210002D4B616E616C00525353492D4B616C69DB
:1002200062722E004D696E20616C6C65204B616EB0
:100230002E005253534920696E766572742E005415
:10024000582065726B656E6E656E005458206D6146
:10025000782D43616C69622E005458206D696E2DB3
:1002600043616C69622E0053656E6465723A2000CA
:100270004B616C69622E0042697474652054582089
:1002800061756620004155530045494E0057656928
:10029000746572206D697420456E746572004B6FD1
:1002A0006E7472617374004C43442D42656C6575C5
:1002B0006368742E004C696368743A0020696D6D40
:1002C0006572206175730020696D6D6572206569C6
:1002D0006E002053656B2E0042617474657269650F
:1002E00000552D4D696E00556E74657273702E2D1C
:1002F000536574757000552D4F6666736574004DB7
:100300004B2D4261747465726965004261742E20E0
:100310004E756D6D6572004261742E204B61706187
:100320007A6974847400492D4F6666736574004958
:100330002D4B6F656666697A69656E7400572D4B43
:100340006F656666697A69656E74004B616C696297
:1003500072696572756E67006C84756674004665B7
:10036000686C6572210053656E646572206E696306
:1003700068742000202020202020416B6B750A200B
:10038000202020656E746C6164656E210053657277
:10039000766F2D4B616C6962722E00536572766FB9
:1003A0002D536368726974746500536572766F20AB
:1003B00031207265762E004B616C69622E31206CA3
:1003C000696E6B73004B616C69622E3120726563DC
:1003D000687473004B616C69622E31204D697474CE
:1003E0006500536572766F2032207265762E004B61
:1003F000616C69622E32206C696E6B73004B616CAC
:1004000069622E3220726563687473004B616C6997
:10041000622E32204D6974746500506572696F6494
:100420006500546573742050756C736C846E6765D9
:10043000005465737420666F72746C6175662E006B
:1004400045696E7A656C736368726974746500419E
:100450006E7A61686C2054657374730050617573B3
:100460006520456E64706F732E0050617573652052
:1004700070726F20496E632E005A84686C65723A00
:100480000053746172742054657374006175730055
:1004900065696E00416E74656E6E65206E6163689D
:1004A000662E00475053206D6974207769323332CD
:1004B000004E4D454120475053005458204F53445F
:1004C0002D446174656E0048797374657265736557
:1004D0000053656E646520466F72646572756E6761
:1004E000004750532D416E7A656967656E006265FD
:1004F000726563686E2E20446174656E00616B7472
:1005000075656C6C6520506F732E00537461727446
:10051000706F736974696F6E00456C656B74722ED1
:100520002057657274650020202020204E6F63687C
:100530000A20206B65696E6520446174656E0A202F
:100540002020656D7066616E67656E210052582DC2
:100550005A6569740053657269656C6C20434F4D30
:10056000002C00332C3356004C616E677561676553
:10057000004765726D616E00456E676C6973680057
:100580004672656E63680052657475726E004156FE
:100590002D536F757263650052582D4368616E6EFE
:1005A000656C00525353492D43616C6962722E0091
:1005B0004D696E20616C6C204368616E2E00525351
:1005C000534920696E7665727400545820696465D9
:1005D0006E74696679005458206D61782D43616CA2
:1005E00069622E005458206D696E2D43616C6962FA
:1005F0002E0053656E6465723A200043616C696237
:100600002E0054582073776974636820004F464663
:10061000004F4E00436F6E74696E756520456E74B1
:10062000657200436F6E7472617374004261636B34
:1006300067722E204C69676874004C696768743A69
:1006400000616C77617973206F66660020616C775A
:10065000617973206F6E00207365632E00426174B0
:100660007465727900552D4D696E004C6F77207658
:100670006F6C7461676500552D4F66667365740015
:100680004D4B2D42617474657279004261742E2065
:100690004E756D626572004261742E204361706117
:1006A0006369747900492D4F666673657400492D3E
:1006B000436F656666696369656E7400572D436FA5
:1006C000656666696369656E740043616C69627230
:1006D0006174696F6E0072756E6E696E6700457247
:1006E000726F7221005472616E736D6974746572F9
:1006F000206E6F742000202020202020416363752D
:100700000A2020202020206C6F772100536572760C
:100710006F2D43616C6962722E00536572766F2D86
:10072000537465707300536572766F203120726563
:10073000762E0043616C69622E31206C6566740010
:1007400043616C69622E312072696768740043618D
:100750006C69622E31206D6964646C65005365724A
:10076000766F2032207265762E0043616C69622EAE
:1007700032206C6566740043616C69622E322072AF
:10078000696768740043616C69622E32206D696428
:10079000646C6500506572696F64650054657374BC
:1007A000205057005465737420636F6E74696E2E09
:1007B0000053696E676C652073746570004E756DCB
:1007C000626572206F662074657374005061757382
:1007D0006520656E6420706F732E005061757365BF
:1007E0002070726F20696E632E00436F756E7465A2
:1007F000723A0053746172742054657374006F66AA
:1008000066006F6E2000547261636B696E6700470B
:1008100050532077697468207769323332004E4D27
:10082000454120475053005458204F53442D4461B4
:100830007461004879737465726573650054726100
:100840006E736D69742064656D616E6400446973D4
:10085000706C6179204750530063616C632E2044B3
:100860006174610063757272656E7420506F732ECF
:1008700000486F6D65706F736974696F6E00456CC9
:100880006963747269632056616C2E0020202020F9
:100890004E6F74207965740A2020202020446174F2
:1008A000610A2020207265636569766564210052C3
:1008B000582D54696D650053657269656C6C2043F1
:1008C0004F4D002E00332E3356004C616E67756518
:1008D00000416C6C656D616E6400416E676C6169AE
:1008E00073004672616E87616973005265746F753B
:1008F000720041562D536F757263650052582D4337
:10090000616E616C00525353492D43616C69627290
:100910002E00546F7574857A82726F00525353495A
:1009200020696E766572740054582064697363653B
:10093000726E6572005458206D61782D43616C6948
:10094000622E005458206D696E2D43616C69622ED1
:100950000054583A200043616C69622E00004574CF
:1009600065696E64726520547800416C6C756D65C4
:1009700072205478004170702E20456E74657200AC
:10098000436F6E74726173746500526574722E20C9
:1009900045636C0045636C61693A00204574656984
:1009A0006E740020546A7273204F4E0020536563AA
:1009B0002E00426174746572696500562D4D696E32
:1009C00000536575696C20416C61726D6500562D30
:1009D0004F6666736574004D4B2D42617474657289
:1009E0006965004261742E206E756D82726F0042DF
:1009F00061742E20636170616369748200492D4FB8
:100A0000666673657400492D436F65666669636940
:100A1000656E7400572D436F656666696369656E20
:100A2000740043616C6962726174696F6E00456E37
:100A300020636F7572730045727265757221004E86
:100A40006F20547800202020204261747465726900
:100A5000650A20202020666169626C65210053656B
:100A600072766F2D43616C696272004E627265200E
:100A700064652050617300496E766572732E205351
:100A80006572766F310043616C2E20476175636833
:100A9000650043616C2E2044726F69746500436188
:100AA0006C2E2043656E74726500496E76657273B4
:100AB0002E20536572766F320043616C2E204761A1
:100AC000756368650043616C2E2044726F697465BC
:100AD0000043616C2E2043656E7472650050827213
:100AE000696F6465004C61726765757220496D704D
:100AF0002E005465737420436F6E74696E750031F7
:100B000020506173004E6F6D62726520546573747E
:100B1000730050617573652066696E616C65005085
:100B200061757365207061722070617300436F6D31
:100B3000707465723A0044826275742054657374EF
:100B4000004F4646004F4E2000547261636B696E41
:100B500067004750532077697468207769323332D1
:100B6000004E4D454120475053005458204F5344A8
:100B70002D4461746100487973746572657369739B
:100B800000446F6E6E8265205472616E736D69658C
:100B9000004166666963686167652047505300439A
:100BA000616C63756C2047505300506F732E206149
:100BB000637475656C6C6500486F6D65706F736903
:100BC00074696F6E00906C826374722E2076616C13
:100BD0002E0020417563756E6520646F6E6E8265B0
:100BE0000A20202020207265877565210052582D2B
:100BF00054656D707300434F4D2E205382726965AA
:100C0000002E00332E335600D801E001E801F10137
:100C1000FD0104020E021702240232023F024B02BF
:100C20005902670270027702850289028D029E02D4
:100C3000A702B502BC02C702D202D802E102E70253
:100C4000F602FF020B03170326032F033D034B039A
:100C500058035E03660374038D039B03AA03B70363
:100C6000C503D403E203EF03FD030C041A042204BA
:100C7000310440044F045C046A04790481048C0448
:100C800090049404A304B104BA04C704D104E10499
:100C9000EE04FD040B05190527054D0555056105F5
:100CA0006305680571057805800587058E0598053B
:100CB000A305B005BE05CA05D605E405F205FB058A
:100CC00002060D061106140623062C063A064106F6
:100CD0004C0657065D0665066B06770680068B0692
:100CE0009706A506AE06BC06CA06D606DE06E506CB
:100CF000F6060C071A072607330740074E075D075D
:100D00006A077707850794079C07A407B107BD0703
:100D1000CC07DB07EA07F307FE07020806080F08FF
:100D20001E08270833083D084D0859086408710853
:100D30007E088C08AF08B708C308C508CA08D108E0
:100D4000DA08E208EB08F208FC08050912091C0998
:100D5000280935094309510956095D095E096A09DF
:100D6000750980098A0994099B09A309AC09B2098C
:100D7000BB09C109CE09D709E309EF09FD09060A34
:100D8000140A220A2E0A370A3F0A450A5E0A6B0A2B
:100D9000770A860A920A9E0AAA0AB90AC50AD10ADD
:100DA000DD0AE50AF20AFF0A050B120B1F0B2D0BD9
:100DB000360B410B450B490B520B610B6A0B760B43
:100DC000810B910B9F0BAA0BB80BC50BD20BED0B34
:100DD000F60B010C030C2001290132013C014001FA
:100DE000440148014E01540158015D0163016B014A
:100DF00073017E0183018E019C01A501AA01C0013E
:100E000030003031003032003033003033310030C8
:100E10003332003033330030333400303335003078
:100E20003335310030333532003034003035003066
:100E30003531003035320030353231003035323224
:100E40000030353233003035323400303533003045
:100E500035333100303533320030353333003035FF
:100E60003334003036003036310030363200303620
:100E700032310030363232003036323300303632E2
:100E800034003036323500303633003036340030FE
:100E900037003037310030373200303800303831E9
:100EA00000303832003038330030383331003038D9
:100EB0003332003038333300303833340030383395
:100EC0003500303900303A00303B00303B310030E3
:100ED0003B3200303B3300303B3400303B350000C8
:100EE0000E2A1F020EED1C050EA41C080E061F0B79
:100EF0000E5B200F0EB820130E4720170E751C1B1B
:100F00000EE11E1F0E371C240EF91B290EBF1B2CD1
:100F10000EC11E2F0ED821330E9E1E370EDD223C31
:100F20000E6923410EF323460E6F244B0E7A1E4F9B
:100F30000ED722540E6323590EED235E0E692463EF
:100F40000E531E660E37226A0E2F1E6E0EB72473C6
:100F50000E2A1B780EFB1A7D0ECC1A820E9D1A8764
:100F60000E591B8B0E881B8F0E121E920E601A9646
:100F70000E211A9A0EF21D9D0EE519A10EB619A5A5
:100F80000ECE1DA90E3826AE0E6719B30E3819B84D
:100F90000E0919BD0EDA18C20E2321C50ED826C8B7
:100FA0000E9E1DCB0ED61FCF0ED61FD30ED61FD72B
:100FB0000ED61FDB0E9D1F010000000A000000641A
:100FC000000000E803000010270000A08601004098
:100FD000420F008096980000E1F50500CA9A3B5543
:100FE00056F732EE1AAB0DDC066F03B801DC006E6B
:100FF0000037001B000E00070003000011241FBE75
:10100000CFEFD0E1DEBFCDBF13E0A0E0B1E0EEE472
:10101000F4E802C005900D92A833B107D9F715E0A6
:10102000A8E3B3E001C01D92AA36B107E1F70E9420
:101030001D080C9425420C940000AF92CF92EF92C1
:10104000FF920F9388EE93E024EF31E0F90131979E
:10105000F1F70197D9F7239A2B9887B18F7387B946
:10106000579896B1907C81E009F480E00E94F308E3
:101070004F9904C0369902C00E94FE0A81B18F6167
:1010800081B984B1876184B980910C010E949E0F5F
:1010900080910C018093850413980E94780B85E061
:1010A00085BD80916E00816080936E0083E08093A7
:1010B000B100809170008160809370008AB1837F5D
:1010C0008AB9809169008A608093690080913A03AF
:1010D0000E94220B8AB180638AB98091A70388237A
:1010E00019F084E10E946B29809186046091650467
:1010F00040E020E00E9412280E94400B80E790E030
:1011000067E00E9451270E94671682E06EE10E940C
:101110006F0C789480910D018E3F21F410920D0197
:101120000E94BF1B0E9414180E94F4110E94FF111C
:101130000E94541280913E038823B1F780E20E94FE
:101140004429882329F081E0809388040E942A1F83
:1011500080910C0190E061E070E047E050E020E019
:1011600000E03BE4E32E33E1F32ECC24C394AA2425
:101170000E94CD1590910C01891721F080930C01EC
:101180000E949E0F80E20E944C29882369F2809180
:10119000A703843049F60E947036C6CF0E94002A09
:1011A000BC017695679580E00E94C22A81E060E0EC
:1011B00070E00E94C22A08958091A7038350823074
:1011C00068F4E0912B01F0E0EE0FFF1FE05FFE4FAF
:1011D0002591359145915491C90102C080E091EE6D
:1011E0000E94ED2B0895EF92FF920F931F93DF93D0
:1011F000CF9300D000D00F92CDB7DEB7F82E80E0AD
:1012000090E00E94D941E82E8E010F5F1F4FC80168
:1012100061E070E045E050E00E94C941E8E8F3E198
:101220003197F1F78E2D893499F4FF2041F080E059
:1012300091E0B8010E943541009709F4D4C080E0E4
:1012400091E0BE016F5F7F4F0E9435410097B9F07A
:1012500080E090E069E40E94F74186E090E060E081
:101260000E94F74187E090E060E10E94F74180E052
:1012700091E061E070E045E050E00E94ED4188E0DF
:1012800090E06FE10E94F74189E090E065E50E94FF
:10129000F7418AE090E060EC73E00E940D428CE040
:1012A00090E060E00E94F7418DE090E061E00E94F4
:1012B000F7418EE090E060E00E94F7418FE090E01F
:1012C0006EEF0E94F74100E110E08EE091E0B8017E
:1012D00048E050E00E94ED41085F1F4FE0E0083415
:1012E0001E0799F788E490E060E971E00E940D42E2
:1012F0008AE490E064EF71E00E940D428CE490E09B
:1013000060E00E94F7418AE191E06DE470E047E01F
:1013100050E00E94ED4181E291E064E570E047E039
:1013200050E00E94ED418BE590E064E10E94F741BE
:101330008CE590E060E00E94F7418DE590E060E090
:101340000E94F7418EE590E061E00E94F7418FE551
:1013500090E06AE00E94F74180E690E060E00E9441
:10136000F74181E690E060E00E94F74182E690E07C
:1013700068E20E94F74183E690E060E00E94F74156
:1013800084E690E065E00E94F74183EB93E065E638
:1013900070E046E050E00E94ED418BE690E060E0B6
:1013A0000E94F7410CE610E089E792E0B80149E0BD
:1013B00050E00E94ED41075F1F4FF0E0063C1F0721
:1013C00099F786EC90E068E00E94F74187EC90E0A6
:1013D00060E50E94F74188EC90E060E50E94F741EB
:1013E0001092C103B4C088E090E00E94D94180937C
:1013F000080189E090E00E94D941809309018AE0C8
:1014000090E00E94E74190930B0180930A018CE0E9
:1014100090E00E94D941809339038DE090E00E94D2
:10142000D94180930C018EE090E00E94D9418093D5
:101430003A038FE090E00E94D94180930D0188E447
:1014400090E00E94E74190931701809316018AE48F
:1014500090E00E94E74190931901809318018CE479
:1014600090E00E94D9418093C1038AE191E06DE44C
:1014700070E047E050E00E94C94181E291E064E5FC
:1014800070E047E050E00E94C9418BE590E00E9487
:10149000D941809328018DE590E00E94D941809345
:1014A0003B038EE590E00E94D941809329018FE5AE
:1014B00090E00E94D94180932A0180E690E00E944A
:1014C000D94180933C0381E690E00E94D94180930A
:1014D000A70382E690E00E94D9418093750283E6DB
:1014E00090E00E94D9418093A80384E690E00E9496
:1014F000D94180932B0183EB93E065E670E046E0F1
:1015000050E00E94C9418BE690E00E94D94180934F
:10151000B20369E0869FB001112464597F4F89E7C7
:1015200092E049E050E00E94C94186EC90E00E94C0
:10153000D9418093760287EC90E00E94D941809354
:10154000770288EC90E00E94D9418093780286E08F
:1015500090E00E94D9418093860487E090E00E9449
:10156000D9418093650480910A0190910B01909379
:1015700069048093680480913A03809382040AE1AD
:1015800011E0FF248F2DF80160810E940D2AF801DF
:10159000618172818F2D0E941C2AF8016381748100
:1015A0008F2D0E943B2AF801658176818F2D0E9444
:1015B000592AF394095F1F4FFF2DF23019F70E944B
:1015C000CE0881E0809364040E94DC088091A70328
:1015D0000E94B62D80917C0290917D029093B10380
:1015E0008093B0030F900F900F900F900F90CF91BA
:1015F000DF911F910F91FF90EF90089580918604E5
:10160000813021F41092860480E104C081E080934F
:1016100086048CE08093650486E090E06091860407
:101620000E94F74187E090E0609165040E94F741D5
:1016300008951498109267040895149A81E0809395
:10164000670408951F93182F813041F0813018F0FE
:10165000823079F409C08DB38C7F08C08DB38C7F44
:101660008DBB0E941D0B05C08DB383608DBB0E9496
:10167000190B812F1F910895109238032F98089508
:1016800080913803882371F42091BE033091BF0309
:101690008091080190E02817390720F481E08093B9
:1016A00038032F9A089580913803813001F5809195
:1016B0000801882319F40E943C0B08958F31B8F477
:1016C000F8948091BE039091BF0301969093BF035D
:1016D0008093BE0378942091BE033091BF03809124
:1016E000080190E02817390710F00E943C0B08957C
:1016F00080E480937C0087E080937A0080917A0078
:10170000806880937A0080917A00806480937A0068
:1017100080917A0086FDFCCF8091780090917900CD
:10172000089590917C008F71907E892B80937C002E
:1017300080917A00806480937A0080917A0086FD9F
:10174000FCCF2091780030917900C90108950E9462
:10175000910B9C0180913903882331F08FEF91E048
:10176000AC01421B530B9A01C90108954F925F923D
:101770006F927F928F929F92AF92BF92CF92DF92A1
:10178000EF92FF920F931F93CF93DF93882E962EA5
:101790006A01C0E0D0E0442455243201EE24FF2445
:1017A000870128E8A22E23E1B22E16C0882D0E94C0
:1017B000A70BA0E0B0E0E80EF91E0A1F1B1F892D41
:1017C0000E94A70BA0E0B0E0480E591E6A1E7B1EC7
:1017D000C5010197F1F72196CC15DD0538F34601D7
:1017E000AA24BB24C801B701A50194010E944E3F61
:1017F000E22EC32EC301B201A50194010E944E3F07
:10180000C9016E2D7C2DDF91CF911F910F91FF901B
:10181000EF90DF90CF90BF90AF909F908F907F9090
:101820006F905F904F900895AF92BF92CF92DF92EA
:10183000EF92FF920F931F932C9A682F70E080E035
:1018400090E00E94E33D5B016C0120E030E44CE954
:1018500055E40E94993E7B018C017F2D912F20E061
:1018600030E040E85FE30E94463D87FD29C06E2DD1
:101870007F2D802F912F20E03FEF4FE757E40E940C
:10188000953E1816B4F4C601B50120E030E040E200
:1018900051E40E94993E0E94B73D24EF31E005C01B
:1018A000C9010197F1F76150704061157105C1F7E9
:1018B0000CC06E2D7F2D802F912F0E94B73D02C04E
:1018C00061E070E0CB010197F1F72C981F910F9127
:1018D000FF90EF90DF90CF90BF90AF9008959F92D0
:1018E000AF92BF92CF92DF92EF92FF920F931F932E
:1018F000DF93CF930F92CDB7DEB7982E69830E9406
:10190000140C698170E080E090E00E94E33D5B018F
:101910006C0120E030E44CE955E40E94993E7B01E3
:101920008C017F2D912F20E030E040E85FE30E94A2
:10193000463D87FD29C06E2D7F2D802F912F20E001
:101940003FEF4FE757E40E94953E1816B4F4C601E6
:10195000B50120E030E040E251E40E94993E0E944F
:10196000B73D24EF31E005C0C9010197F1F761509F
:10197000704061157105C1F70CC06E2D7F2D802F51
:10198000912F0E94B73D02C061E070E0CB0101974A
:10199000F1F7892D0E94140C0F90CF91DF911F91C8
:1019A0000F91FF90EF90DF90CF90BF90AF909F90FE
:1019B00008950F93BC0180E090E044E022E001E054
:1019C0000E94F22D0E94C5270F9108950F93BC012C
:1019D00080E090E045E022E002E00E94F22D0E94CB
:1019E000C52786E50E9412270F9108958F929F9236
:1019F000AF92BF92CF92DF92EF92FF920F931F931D
:101A0000882E87E00E94910B9C0140E050E060E04E
:101A100070E080E090E0F0EFAF2EE9EABE2ECC243B
:101A2000DD24EE24FF2400E010E00E94353BF22E7E
:101A3000132FE42ED52EC62EB72EA82E992E209128
:101A4000090130E040E050E060E070E080E090E0CC
:101A50000DE00E94703C2F0DA1E02F1508F0A0E0D2
:101A6000E12FE30FF1E0E11708F0F0E03A2F3E0F2D
:101A7000A1E03E1708F0A0E0FA2BAE2DA40FE1E0A4
:101A8000AE1508F0E0E04F2F4A0FF1E04A1708F0DA
:101A9000F0E0EF2BAD2DA50FF1E0AD1508F0F0E073
:101AA0005E2F5A0FE1E05A1708F0E0E0FE2BAC2D54
:101AB000A60FE1E0AC1508F0E0E06F2F6A0FF1E04F
:101AC0006A1708F0F0E0EF2BAB2DA70FF1E0AB1594
:101AD00008F0F0E07E2F7A0FE1E07A1708F0E0E0FE
:101AE000FE2BAA2DA80FE1E0AA1508F0E0E08F2F49
:101AF0008A0FF1E08A1708F0F0E0EF2B990D9E0FA6
:101B00000DE00E94FF3B7901209168043091690447
:101B10002E153F05F0F180913E03882311F5809149
:101B20000A0190910B014496909369048093680494
:101B30008091A703823011F40E941B380E946E2707
:101B400087E290E00E94EF130E94C52781E0809316
:101B50003E0384E10E94140C80EF80934B031092AB
:101B60004C03882D813021F580914C0310914B035B
:101B7000982F9F5F90934C038117D0F084E10E94CF
:101B8000140C133018F0169510934B0310924C035D
:101B90000FC080910A0190910B018217930740F4C6
:101BA00010923E0390936904809368040E94141875
:101BB000C7011F910F91FF90EF90DF90CF90BF90E2
:101BC000AF909F908F900895CF93DF9381E00E9414
:101BD000F60CEC0180913E03882339F48BE060E041
:101BE0000E94A327CE010E94D90CDF91CF910895C6
:101BF0008F929F92BF92CF92DF92EF92FF920F93BC
:101C00001F93CF93DF93B82E6B01EA017A0100E0B6
:101C100010E09B0140E050E06C177D07C8F4C8015C
:101C2000B70117E0660F771F881F991F1A95D1F724
:101C30000E944E3F309313012093120180E890E000
:101C400090931501809314014E01EC2EC92C19C0FC
:101C5000CA01B901B7E0660F771F881F991FBA95AF
:101C6000D1F7A80197010E944E3F309315012093B0
:101C7000140180E890E09093130180931201EC2C02
:101C8000CD2CCB2DD0E02197A3E0CC0FDD1FAA9562
:101C9000E1F76091120170911301CE018C5E9F4FAC
:101CA0000E940D426091140170911501CE018A5E6F
:101CB0009F4F0E940D428E2D9C2DDF91CF911F9141
:101CC0000F91FF90EF90DF90CF90BF909F908F90FB
:101CD0000895FF920F931F93DF93CF93CDB7DEB795
:101CE00062970FB6F894DEBF0FBECDBFF82E0E94EC
:101CF0006E2783E290E00E94EF1360E00E94EB27E2
:101D0000FF2041F186E090E00E94EF13BC018E01BC
:101D10000F5F1F4FC8010E943E41C80165E071E09E
:101D20000E942A41F80101900020E9F73197E01B59
:101D3000D801AE0FB11D8F2D805D8C93EF5FC80170
:101D40008E0F911DFC011082C80161E00E94EB27FB
:101D500062E001C061E084E290E06A8B0E94EF13D0
:101D60006A890E94EB2762960FB6F894DEBF0FBE19
:101D7000CDBFCF91DF911F910F91FF9008951F93D9
:101D8000182F0E946E2785E290E00E94EF1360E01A
:101D90000E94EB2786E290E00E94EF1361E00E9430
:101DA000EB27812F90E00E94EF1362E00E94EB2767
:101DB0008EE10E9410301F9108950F931F938C01A4
:101DC00060910C0170E083E0660F771F8A95E1F760
:101DD000685F7F4F8EE091E048E050E00E94C9418B
:101DE00080910E0190910F010F9720911001309179
:101DF0001101821B930B6BE070E00E94273F862F3E
:101E0000A62FB0E0202F312FF90120E030E090E044
:101E100040910E0150910F01421B530B419351937E
:101E20009F5F2A0F3B1F9C3099F765E00E941B3F84
:101E30001F910F910895CF93DF93EC0180E00E94F2
:101E4000690E85E066E048EE53E00E94B60B9B0108
:101E5000AC01640F751F80911601909117016817EE
:101E60007907E0F480910C01B9010E94F80DBC01E2
:101E700080910C0190E023E0880F991F2A95E1F7EB
:101E8000865F9F4F0E940D4284E06EE10E946F0CBE
:101E9000CE010E94DD0E8093660403C081E10E94A2
:101EA000BF0EDF91CF9108950F931F93CF93DF93D0
:101EB000182FEB0101E0811100E0812F0E94690ED3
:101EC000002311F010910C0185E066E048EE53E02C
:101ED0000E94B60B9B01AC01640F751F8091180125
:101EE0009091190186179707E0F4812FB9010E949C
:101EF000F80DBC01812F90E033E0880F991F3A95CF
:101F0000E1F7885F9F4F0E940D42002379F084E043
:101F10006EE10E946F0CCE010E94DD0E809366047C
:101F200005C0002329F080E10E94BF0E81E001C0BE
:101F300080E0DF91CF911F910F9108958150282F5C
:101F4000277092B1922B92B995B1922B95B9886F67
:101F500092B1982392B995B1982395B98AE694E005
:101F60000E94DD0E809366040895EF92FF920F9316
:101F70001F93DF93CF93CDB7DEB72C970FB6F894AE
:101F8000DEBF0FBECDBF8E010F5F1F4FFC01D8011A
:101F90003FEF74E02BE0703239F0E080F180E4161E
:101FA000F50610F4232F70E27D933F5F32963B30AD
:101FB00091F727FD18C0332727FD3095F901EE0F63
:101FC000FF1FE80FF91F80819181841B950B70E042
:101FD0000E94273FFE013196E20FF31F60836530B8
:101FE00010F084E080834DE0E42EF12CEC0EFD1E19
:101FF000F80181918F010E9412270E151F05C1F76C
:102000002C960FB6F894DEBF0FBECDBFCF91DF91F7
:102010001F910F91FF90EF900895CF92DF92EF9272
:10202000FF920F931F93CF93DF93182F6B01042F11
:1020300085E00E94A70BBC0180E090E02091120196
:102040003091130140E050E00E94FC3EF7E096958D
:10205000879577956795FA95D1F77B0186E00E9481
:10206000A70BBC0180E090E0209114013091150194
:1020700040E050E00E94FC3EE7E09695879577951A
:102080006795EA95D1F7EB011230F1F4E616F70601
:1020900068F410924903809183048F3FB9F48091D2
:1020A00061048F3F99F40E94190B10C081E0809366
:1020B0004903809183048F3F49F4809161048F3FED
:1020C00029F40E941D0B02C010934903002309F458
:1020D00045C01230E9F4909162048091840498170D
:1020E00089F0909183048091610489238F3F51F09E
:1020F0009091620481E0992309F480E080934A037F
:1021000003E707C08091490380934A0304E601C0B6
:102110000BEFF601808191818E159F0520F48C17BD
:102120009D0708F400E282E061E00E94A327C60157
:1021300060916604A7010E94B50F82E062E00E94F0
:10214000A327C60160916604AE010E94B50F12304C
:1021500029F480914A03602F0E94E217809149037D
:10216000DF91CF911F910F91FF90EF90DF90CF9073
:1021700008951F920F920FB60F9211242F938F93F1
:102180009F93AF93BF9384E68093B20080918304C2
:102190008F3F29F0809183048F5F80938304809127
:1021A00061048F3F29F0809161048F5F8093610407
:1021B00080915B0490915C0420E2803D920748F49A
:1021C00080915B0490915C04019690935C048093F1
:1021D0005B04809140038823D9F080917E02909126
:1021E0007F02A0918002B091810280362AEA920794
:1021F0002BEDA20720E0B20758F40196A11DB11DF6
:1022000080937E0290937F02A0938002B09381021C
:102210008091A703823029F480913F03882339F409
:1022200031C0843079F580916404882359F5809118
:1022300067048823A1F08091450390914603A09103
:102240004703B09148030196A11DB11D809345033A
:1022500090934603A0934703B093480313C0809123
:10226000410390914203A0914303B091440301962E
:10227000A11DB11D8093410390934203A09343039A
:10228000B0934403BF91AF919F918F912F910F9085
:102290000FBE0F901F9018951F920F920FB60F92BE
:1022A00011242F933F934F935F936F937F938F935B
:1022B0009F93AF93BF93EF93FF93809183048F34E9
:1022C000A0F080918304823580F4109262048091A2
:1022D0006704882399F0809161048F3F79F40E940C
:1022E000190B81E08093840409C081E0809362042B
:1022F00080918404882311F40E941D0B9091620444
:1023000080918404981749F480918204882319F4F9
:102310000E94190B02C00E941D0B10928304FF91B2
:10232000EF91BF91AF919F918F917F916F915F914D
:102330004F913F912F910F900FBE0F901F901895C6
:102340001F920F920FB60F9211242F933F934F932A
:102350005F936F937F938F939F93AF93BF93EF930D
:10236000FF93809161048F34A0F0809161048235E5
:1023700080F41092840480916704882399F48091FA
:1023800083048F3F79F40E941D0B81E080936204E7
:1023900009C081E08093840480916204882311F451
:1023A0000E94190B9091620480918404981749F45B
:1023B00080918204882319F40E94190B02C00E94A4
:1023C0001D0B10926104FF91EF91BF91AF919F910E
:1023D0008F917F916F915F914F913F912F910F90CE
:1023E0000FBE0F901F90189580915D04882331F0E7
:1023F000F89410925D0478940E94E40D0895809101
:10240000C003882389F0F8941092C003789441E0C7
:1024100080913E03811140E080913A036AE674E0C6
:102420000E940D108093820408958091C403882334
:1024300099F0F8941092C403789480913A036AE674
:1024400074E040E00E940D10809382048091A70305
:10245000833011F40E94EC3708958091BB038823E8
:10246000A9F0F8941092BB0378948091A70382306E
:1024700019F40E94193604C0843011F40E943037D8
:1024800080913D03853011F40E94C51708950E9484
:10249000400B80915F04882331F0F89410925F0420
:1024A00078940E94530B08950E9415120E942D12D9
:1024B0000E9447128091A703813011F40E94C73017
:1024C00008950F93BC0180E090E044E022E002E038
:1024D0000E94F22D0E94C5270F9108950F9322E3C9
:1024E00030E0829FB001839F700D929F700D112488
:1024F00080E090E044E020E000E00E94F22D0E94A5
:10250000C5278CE291E00E94C5270F9108950F9393
:10251000BC0180E090E043E020E000E00E94F22D6A
:102520000E94C5270F9108950F938A30910568F096
:10253000BC0180E090E043E021E001E00E94F22D48
:102540000E94C52780E391E00EC024E630E0AC0194
:10255000429FC001439F900D529F900D11240E94F5
:10256000871283E391E00E94C5270F9108950F938E
:102570001F93CF93DF93EC010E94002A96958795D5
:10258000BE01681B790B882777FD8095982F44E062
:1025900020E000E00E94F22D0E94C5278091870470
:1025A000BE010E94592A109187040E94002ABC0192
:1025B00076956795812F0E94C22ADF91CF911F9156
:1025C0000F910895CF93DF93EC010E9487128091C1
:1025D0008704BE010E941C2A8091870490E0FC01C0
:1025E00033E0EE0FFF1F3A95E1F7E81BF90BE65ECB
:1025F000FE4F8081882321F00E94002ABC0102C086
:1026000060E070E0809187040E94C22ADF91CF9140
:1026100008950F931F93CF93DF938C010E94002A9C
:10262000EC01C8010E94871280918704B8010E94C2
:102630003B2A80918704282F30E0F90143E0EE0F18
:10264000FF1F4A95E1F7E21BF30BE65EFE4F908118
:10265000992311F0C0E0D0E0BE010E94C22ADF91B0
:10266000CF911F910F9108950F93992787FD909512
:1026700005979C01B901882777FD8095982F44E044
:1026800021E001E00E94F22D0E94C52781E40E9412
:1026900012270F9108950F931F93DF93CF93CDB718
:1026A000DEB72E970FB6F894DEBF0FBECDBF8C01FC
:1026B000DE011196E6ECF1E08EE001900D92815082
:1026C000E1F7802F805D0E94122786E391E00E944F
:1026D000C527F8013197EE0FFF1FEC0FFD1F818119
:1026E00092810E94C52789E391E00E94C5272E961A
:1026F0000FB6F894DEBF0FBECDBFCF91DF911F9113
:102700000F9108950F931F93DF93CF93CDB7DEB74B
:1027100027970FB6F894DEBF0FBECDBFFC01EE0FBA
:10272000FF1FE05FFE4F85919591A591B491BC018B
:1027300080E090E08E010F5F1F4FA8012AE030E09B
:102740000E948D41C80161E00E94EB2727960FB6D9
:10275000F894DEBF0FBECDBFCF91DF911F910F91D7
:102760000895DF93CF930F92CDB7DEB7682F6983BB
:102770000E9487128091860469810E948A270F90A7
:10278000CF91DF9108950F931F93CF93DF938091A3
:102790004D018823F9F0C0E0D0E08E01000F111F39
:1027A000000F111FF801E152F14F259134918DE492
:1027B00091E0B9010E941541009741F40F51114F6A
:1027C000F80185919491FC01099504C02196C633C6
:1027D000D10519F7DF91CF911F910F9108958D3495
:1027E000910540F0FC01EE0FFF1FE45CF24F2591D4
:1027F00034911BC020910D01213031F0FC01EE0F0E
:10280000FF1F223071F408C0FC01EE0FFF1FEE55D0
:10281000F34F2591349109C0E45CF24F2591349136
:1028200004C0E85FF34F259134918EE593E0B90140
:102830000E941E418EE593E00895DF93CF9300D070
:102840000F92CDB7DEB7DE011196E4E8F1E023E0A8
:1028500001900D922150E1F7FE01E80FF91F8181EF
:1028600090E00E94EF1361E00E94EB270F900F9021
:102870000F90CF91DF910895CF93DF93EC010097F4
:1028800041F48BE390E00E94EF1361E00E94EB279C
:102890000AC085E061E00E94A327CE010E94871252
:1028A00080E20E941227DF91CF910895CF93DF93AA
:1028B000EC010E943C14209741F088E061E00E9406
:1028C000A32783E391E00E94C527DF91CF9108956C
:1028D0000F931F93CF93DF93EC010E943C148DE084
:1028E00090E00E94EF13FC01DC010D900020E9F75D
:1028F000CD0101978E1B62E00E94A32785E00E9414
:10290000A70B8C0186E00E94A70B080F191FC017A8
:10291000D10718F48BE390E002C08CE390E00E94B2
:10292000EF130E94C527DF91CF911F910F9108955A
:10293000009719F488E590E002C089E590E00E94D4
:10294000EF130E94C5270895DF93CF9300D0CDB732
:10295000DEB725E5298326E52A83FE01E80FF91F66
:10296000818190E00E94EF1361E00E94EB270F90BD
:102970000F90CF91DF910895009719F48BE390E0C9
:1029800002C08CE390E00E94EF130E94C5270895D7
:102990000F931F93DF93CF9300D000D00F92CDB74A
:1029A000DEB7009721F08F31910539F403C086E13D
:1029B00090E01DC087E190E01AC09C01220F331FF8
:1029C00043E0880F991F4A95E1F7820F931F8E010C
:1029D0000F5F1F4FB8014AE050E00E946C4180E257
:1029E0000E941227C8010E94C52788E190E00E943A
:1029F000EF130E94C5270E9478270F900F900F9029
:102A00000F900F90CF91DF911F910F910895DF9359
:102A1000CF9300D0CDB7DEB72BE3298322E42A83FE
:102A2000FE01E80FF91F818190E00E94EF1361E041
:102A30000E94EB270F900F90CF91DF910895DF93C5
:102A4000CF9300D000D00F92CDB7DEB7DE01119644
:102A5000EBE9F1E025E001900D922150E1F7FE0154
:102A6000E80FF91F818190E00E94EF1361E00E945E
:102A7000EB270F900F900F900F900F90CF91DF9159
:102A80000895DF93CF9300D00F92CDB7DEB7DE016C
:102A90001196E0EAF1E023E001900D922150E1F778
:102AA000FE01E80FF91F818190E00E94EF1361E0C1
:102AB0000E94EB270F900F900F90CF91DF91089518
:102AC000EF92FF920F931F93CF93DF938C01FC0142
:102AD00080818823F1F0C0E0D0E07E01EE0CFF1C85
:102AE000EE0CFF1CF701E152F14F25913491C80122
:102AF000B9010E941541009741F4F701EF51F14FE0
:102B000085919491FC01099504C02196C633D105A5
:102B100021F7DF91CF911F910F91FF90EF900895D2
:102B20000E94541280E00E94F60C80E20E944C2920
:102B3000882321F480913E03882321F010924D01D7
:102B400081E0089580E008950F931F93CF93DF9362
:102B5000EC01662319F0162F115001C0188100E016
:102B600082E0602F0E94A327FE01E10FF11D818109
:102B700090E00E94EF130E94C5270E947827888169
:102B8000181710F41F5F01C010E00F5F033041F70A
:102B9000DF91CF911F910F9108956F927F928F9245
:102BA0009F92AF92CF92EF92FF920F931F93CF938A
:102BB000DF93EC013B014A01122F80E40E942E2991
:102BC000882329F480E40E943929882389F0C815D4
:102BD000D90528F421968A2D0E94512902C0C110DE
:102BE000E301812F602F0E94A327CE01F7010995F1
:102BF00080E80E942E29882329F480E80E94392940
:102C0000882389F06C167D0628F421978A2D0E946E
:102C1000512902C0C110E401812F602F0E94A32717
:102C2000CE01F7010995CE01DF91CF911F910F9150
:102C3000FF90EF90CF90AF909F908F907F906F908C
:102C400008950F931F93182F90E00E94EF13DC015B
:102C50000D900020E9F71197A81BA031E0F420E1C6
:102C600030E02A1B310935952795022F2230A0F03C
:102C7000822F825060E00E94A3278DE391E00E94A2
:102C8000C527812F90E00E94EF130E94C52780E2A4
:102C90000E94122716C000E080E060E00E94A32797
:102CA0008AE20E941227802F60E00E94A327812FD2
:102CB00090E00E94EF130E94C5278FE060E00E9421
:102CC000A3278AE20E9412271F910F91089580E0A6
:102CD00060E00E94A32780E690E00E94EF130E942C
:102CE000C52780918604882319F48CE490E002C003
:102CF0008FE590E00E94EF130E94C52781E690E0E7
:102D00000E94EF130E94C5278EE10E9410300E949E
:102D10006E27089510924E03EFE4F3E087E081936D
:102D200093E0ED35F907D9F786E080935D03CF0195
:102D30000F970895DF92EF92FF920F931F93CF9317
:102D4000DF938C017B01D42E0E948A16EC0198013E
:102D500017FF04C022273327201B310BC901E3E0F2
:102D6000880F991FEA95E1F7821B930BB7010E9428
:102D70003B3F462FE62FFF27E7FDF095EE9DC00174
:102D8000EF9D900DFE9D900D112469EF7FEF0E9445
:102D90003B3F620F731F23E230E0629FC001639FDD
:102DA000900D729F900D1124B7010E943B3F65303A
:102DB0000CF064E017FF0DC088E0841B16167CF44D
:102DC000E82FFF27E7FDF095EC0FFD1F319760839B
:102DD00006C016161CF4EC0FFD1F608788E0E82F74
:102DE000FF27E7FDF095EC0FFD1F80E095E002C0A6
:102DF00091938F5F8417E4F380E06D2D0E94A327E9
:102E000000E189910E9412270150D9F7DF91CF91FB
:102E10001F910F91FF90EF90DF900895EF92FF9236
:102E2000CF93DF93E091890497FF0DC0E901C61BA2
:102E3000D70BE130A9F41092890488EA90E065E0AC
:102E40000E9451270DC0EA01C21BD30BEE2341F4AF
:102E500088EE90E065E00E94512781E0809389042C
:102E6000CE01DF91CF91FF90EF900895CF92DF9246
:102E7000EF92FF920F931F93DF93CF9300D00F92A7
:102E8000CDB7DEB77C01DE011196E3E3F1E083E02C
:102E900001900D928150E1F780918704B7010E9463
:102EA000992A8091C10390E0FC01EE0FFF1FE80F0B
:102EB000F91FEE0FFF1FE250FE4F2481358187017D
:102EC000021B130B6081718142815381C8010E94F2
:102ED0000E176C01C801B60142E00E949A16B801B3
:102EE000882777FD8095982F28EE33E040E050E06A
:102EF0000E94FC3E9601442737FD4095542F0E94C6
:102F0000703F690181E061E00E94A327C7010E9430
:102F1000D9298C0183E0083E180750F485E789839E
:102F200080E491E00E94C527C8010E9487120AC070
:102F3000B80180E090E045E023E003E00E94F22D3C
:102F40000E94C527CE0101960E94C52788E061E056
:102F50000E94A327B601882777FD8095982F46E029
:102F600021E001E00E94F22D0E94C52785E20E9427
:102F700012270F900F900F90CF91DF911F910F911B
:102F8000FF90EF90DF90CF90089586E061E00E947F
:102F9000A327609141037091420380914303909174
:102FA00044030E94883086E062E00E94A32760917B
:102FB00045037091460380914703909148030E9416
:102FC000883008950F931F93182F062F823078F4BE
:102FD00062E0681B8FE00E94A32780E20E94122714
:102FE000612F6F5F8FE00E94A327802F0CC08FE0BE
:102FF00061E00E94A32780E20E9412278FE062E036
:103000000E94A32780E20E9412271F910F9108952A
:1030100080913A03823010F46BEF01C064E6809136
:1030200082040E94E217089510924D010E946E27BB
:1030300080913E038823A1F40E946E2780910C01A9
:1030400090E00E944B138FE060E00E94A32783E48E
:1030500091E00E94C5270E9408180E94E40D08957F
:1030600087E290E00E94EF1360E00E94EB27089552
:10307000823058F08150E82FF0E0E35BFE4F808112
:10308000805380938804108208950E941418089534
:103090002F923F924F925F926F927F928F929F9268
:1030A000AF92BF92CF92DF92EF92FF920F931F9356
:1030B000DF93CF9300D00F92CDB7DEB79B838A8387
:1030C0001B012A013801FC0180809180122F1F70A2
:1030D000812F61E029830E94A327C401F301099590
:1030E00080914D0129818823D1F48DE491E069E438
:1030F00071E00E943E41298112C0EA81FB818081FA
:103100009181B101A201212F01E07301CB2CAD2CE3
:103110000E94CD15EA81FB819183808306C080E403
:10312000B82EB22200E8D02ED22280E20E9444299A
:10313000882341F40E949015882321F480914D0347
:103140008823D9F20E946E2780914D03882339F09D
:1031500010924D03EA81FB81918280820CC08DE444
:1031600091E0FC0101900020E9F7CF0101978D5417
:1031700091400E94381881E0EA81FB8120813181F1
:103180008216930609F480E00F900F900F90CF9174
:10319000DF911F910F91FF90EF90DF90CF90BF9044
:1031A000AF909F908F907F906F905F904F903F90E7
:1031B0002F9008950F931F93DF93CF9300D0CDB737
:1031C000DEB782E20E9421168091780289831A82FA
:1031D000CE0101966EE170E048EC50E026E801E691
:1031E00012E10E944818882359F06981609378029F
:1031F00088EC90E00E94F74184E06EE10E946F0C41
:103200000E94C3130F900F90CF91DF911F910F91E8
:1032100008950F931F93DF93CF9300D0CDB7DEB700
:1032200081E20E9421168091770289831A82CE0161
:1032300001966EE170E048EC50E026E801E612E10C
:103240000E944818882359F069816093770287ECBF
:1032500090E00E94F74184E06EE10E946F0C0E94B2
:10326000C3130F900F90CF91DF911F910F9108958D
:103270000F931F93DF93CF9300D0CDB7DEB780E2DB
:103280000E9421168091760289831A82CE010196CE
:1032900060E070E044E150E025E804E313E10E94BF
:1032A0004818882359F069816093760286EC90E093
:1032B0000E94F74184E06EE10E946F0C0E94C313EC
:1032C0000F900F90CF91DF911F910F910895EF9282
:1032D000FF920F931F93DF93CF9300D0CDB7DEB74C
:1032E0008FE10E94211680917A0290917B0222E365
:1032F000E22EF12CB7010E94273F7A836983CE0129
:10330000019664E170E048E750E025E80EE612E13E
:103310000E9448188823F9F029813A812E9DC00126
:103320002F9D900D3E9D900D112490937B028093D4
:103330007A026091B20389E0689FB0011124645958
:103340007F4F89E792E049E050E00E94ED4184E040
:103350006EE10E946F0C0E94C3130F900F90CF91EB
:10336000DF911F910F91FF90EF9008950F931F939E
:10337000DF93CF9300D0CDB7DEB78CE10E9421164A
:103380008091090189831A82CE01019660E070E084
:1033900048EC50E024E806EE1CE00E944818882320
:1033A00059F069816093090189E090E00E94F7413A
:1033B00084E06EE10E946F0C0E94C3130F900F9087
:1033C000CF91DF911F910F9108950F931F93DF937A
:1033D000CF9300D0CDB7DEB78AE10E94211680914D
:1033E0000A0190910B019A838983CE01019666E2CE
:1033F00072E048E755E024E806EE1CE00E94481819
:103400008823B1F069817A8170930B0160930A017E
:103410008AE090E00E940D4280910A0190910B0198
:10342000909369048093680484E06EE10E946F0CBD
:103430000E94C3130F900F90CF91DF911F910F91B6
:1034400008950F931F93DF93CF9300D0CDB7DEB7CE
:1034500084E10E94211680E061E00E94A32785E1BB
:1034600090E00E94EF130E94C52780910801898394
:103470001A82CE01019660E070E04FE150E026E84C
:1034800008EC14E10E944818882389F06981609350
:10349000080188E090E00E94F74184E06EE10E941C
:1034A0006F0C80910801882311F40E943C0B0E944C
:1034B000C3130F900F90CF91DF911F910F9108953B
:1034C0000F931F93DF93CF9300D0CDB7DEB780E586
:1034D0000E94211682E061E00E94A32783E190E030
:1034E0000E94EF130E94C52786E391E00E94C52742
:1034F0008091650489831A82CE01019660E070E0B4
:103500004EE150E02BE001EB13E10E9448188823C4
:1035100059F069816093650487E090E00E94F7416B
:1035200084E06EE10E946F0C0E94C3130F900F9015
:10353000CF91DF911F910F9108950F931F93DF9308
:10354000CF9300D0CDB7DEB788E30E9421168091DB
:103550003C0389831A82CE01019660E070E048EC5A
:1035600050E025E806E514E10E944818882359F048
:10357000698160933C0380E690E00E94F74184E01B
:103580006EE10E946F0C0E94C3130F900F90CF91B9
:10359000DF911F910F9108950F931F93DF93CF93A6
:1035A00000D0CDB7DEB787E30E94211680912A01B3
:1035B00089831A82CE01019664E070E044E150E014
:1035C00025E804E912E10E944818882359F069812E
:1035D00060932A018FE590E00E94F74184E06EE15C
:1035E0000E946F0C0E94C3130F900F90CF91DF9138
:1035F0001F910F9108950F931F93DF93CF9300D0E6
:10360000CDB7DEB786E30E94211680912901898318
:103610001A82CE01019661E070E044E650E025E8B0
:1036200007E812E10E944818882359F069816093E5
:1036300029018EE590E00E94F74184E06EE10E944E
:103640006F0C0E94C3130F900F90CF91DF911F91C9
:103650000F9108950F931F93DF93CF9300D0CDB7B1
:10366000DEB785E30E94211680913B0389831A828D
:10367000CE01019660E070E044E150E025E80CE303
:1036800014E10E944818882359F0698160933B0334
:103690008DE590E00E94F74184E06EE10E946F0C9E
:1036A0000E94C3130F900F90CF91DF911F910F9144
:1036B00008950F931F93DF93CF9300D0CDB7DEB75C
:1036C00087E50E9421168091870489831A82CE01A2
:1036D000019660E070E041E050E024E008E914E188
:1036E0000E944818882359F06981609387048CE50B
:1036F00090E00E94F74184E06EE10E946F0C0E940E
:10370000C3130F900F90CF91DF911F910F910895E8
:103710000F931F93DF93CF9300D0CDB7DEB782E333
:103720000E94211688E061E00E94A32783E391E0D4
:103730000E94C5278091280189831A82CE010196B3
:103740006AE070E04EE150E025E807E812E10E94EF
:103750004818882359F06981609328018BE590E02F
:103760000E94F74184E06EE10E946F0C0E94C31337
:103770000F900F90CF91DF911F910F9108950F93AC
:103780001F93DF93CF9300D0CDB7DEB780E00E94C8
:10379000211680910D0189831A828FE090E00E94AA
:1037A000D94180930D01CE01019660E070E042E0C6
:1037B00050E023E00DE114E10E94481869817A810C
:1037C00080910D0190E06817790751F060930D0129
:1037D0008FE090E00E94F74184E06EE10E946F0C60
:1037E0000E94C3130F900F90CF91DF911F910F9103
:1037F00008950F931F93DF93CF9300D0CDB7DEB71B
:103800008BE00E94211680E062E00E94A3278DE0F9
:1038100090E00E94EF130E94C527809116019091BD
:1038200017019A838983CE01019666E970E047EE1D
:1038300053E025E808E614E10E944818882371F057
:1038400069817A81709317016093160188E490E092
:103850000E940D4284E06EE10E946F0C0E94C3132F
:103860000F900F90CF91DF911F910F9108950F93BB
:103870001F93DF93CF9300D0CDB7DEB78CE00E94CB
:10388000211680E062E00E94A3278DE090E00E9474
:10389000EF130E94C52780911801909119019A8316
:1038A0008983CE01019666E970E047EE53E025E892
:1038B00008E614E10E944818882371F069817A8132
:1038C00070931901609318018AE490E00E940D4200
:1038D00084E06EE10E946F0C0E94C3130F900F9062
:1038E000CF91DF911F910F9108950F931F93DF9355
:1038F000CF9300D0CDB7DEB789E00E94211680912A
:10390000390389831A82CE01019660E070E041E0BC
:1039100050E026E00CEB14E10E944818882359F08F
:103920006981609339038CE090E00E94F74184E064
:103930006EE10E946F0C0E94C3130F900F90CF9105
:10394000DF911F910F9108950F931F93DF93CF93F2
:1039500000D0CDB7DEB786E00E94211680910C0121
:1039600089831A82CE01019661E070E047E050E061
:1039700023E00BE413E10E944818882341F480916E
:10398000850490E029813A8128173907E9F0698197
:1039900060930C01609385048DE090E00E94F741F4
:1039A00084E06EE10E946F0C80910C010E949E0FDA
:1039B00080914D01882341F460E00E94A32780910B
:1039C0000C0190E00E944B130E94C3130F900F90C4
:1039D000CF91DF911F910F9108950F931F93DF9364
:1039E000CF9300D0CDB7DEB785E00E94211680913D
:1039F0003A0389831A82CE01019660E070E042E0CA
:103A000050E023E001E415E10E9448188823C9F042
:103A1000F894698160933A038EE090E00E94F74148
:103A200084E06EE10E946F0C80913A030E94220BA9
:103A30008093820480914D01882311F40E9408181C
:103A400078940E94C3130F900F90CF91DF911F9134
:103A50000F9108951F93CF93DF93EC01162F0E94CF
:103A60006E2780E061E00E94A3278CEF0E9412275E
:103A700023C080E40E942E29882329F480E40E9438
:103A80003929882349F0112311F0115001C0188100
:103A9000CE01612F0E94A41580E80E942E29882360
:103AA00029F480E80E943929882351F08881181769
:103AB00010F41F5F01C010E0CE01612F0E94A41519
:103AC00080E20E944429882341F40E9490158823B3
:103AD00021F480914D03882361F20E946E2780912A
:103AE0004D03882319F01093880422C0EDE4F1E01F
:103AF00001900020E9F73197ED54F1408E2F11230A
:103B000011F0EE2319F40E94381812C091E090933E
:103B10008804AE2FB0E0A35BBE4F105D1C938F5F97
:103B2000E82FF0E0E35BFE4F108281E00E94140C6E
:103B300010924D03DF91CF911F910895DF93CF93A2
:103B4000CDB7DEB727970FB6F894DEBF0FBECDBF57
:103B5000DE011196E3E5F1E087E001900D928150DE
:103B6000E1F78091A703843021F4898389E48E836F
:103B700004C0823011F083E08983CE010196609108
:103B800088040E942A1D0E94C31327960FB6F8943A
:103B9000DEBF0FBECDBFCF91DF910895DF93CF93EE
:103BA000CDB7DEB727970FB6F894DEBF0FBECDBFF7
:103BB000DE011196EAE5F1E087E001900D92815077
:103BC000E1F7CE010196609188040E942A1D0E94AF
:103BD000C31327960FB6F894DEBF0FBECDBFCF91AB
:103BE000DF910895DF93CF9300D000D00F92CDB72F
:103BF000DEB7DE011196E1E6F1E085E001900D927D
:103C00008150E1F7CE010196609188040E942A1D3F
:103C10000E94C3130F900F900F900F900F90CF91B1
:103C2000DF910895DF93CF9300D000D0CDB7DEB7FA
:103C300082E0898384E08A8383E18B8384E18C83BF
:103C4000CE010196609188040E942A1D0E94C31330
:103C50000F900F900F900F90CF91DF910895DF9309
:103C6000CF93CDB7DEB727970FB6F894DEBF0FBE60
:103C7000CDBFDE011196E6E6F1E087E001900D92FE
:103C80008150E1F7CE010196609188040E942A1DBF
:103C90000E94C31327960FB6F894DEBF0FBECDBFA8
:103CA000CF91DF910895DF93CF9300D000D000D063
:103CB000CDB7DEB7DE011196EDE6F1E086E00190CA
:103CC0000D928150E1F7CE010196609188040E9427
:103CD0002A1D8CE590E00E94D941809387040E94C0
:103CE000C31326960FB6F894DEBF0FBECDBFCF919B
:103CF000DF910895DF93CF9300D000D000D0CDB7EF
:103D0000DEB7DE011196E3E7F1E086E001900D9267
:103D10008150E1F7CE010196609188040E942A1D2E
:103D200081E0809387040E94C31326960FB6F8940F
:103D3000DEBF0FBECDBFCF91DF910895DF93CF934C
:103D400000D000D000D0CDB7DEB7DE011196E9E794
:103D5000F1E086E001900D928150E1F7CE010196ED
:103D6000609188040E942A1D109287040E94C31348
:103D700026960FB6F894DEBF0FBECDBFCF91DF9170
:103D80000895DF93CF9300D000D00F92CDB7DEB768
:103D9000DE011196EFE7F1E085E001900D92815090
:103DA000E1F7CE010196609188040E942A1D0E94CD
:103DB000C3130F900F900F900F900F90CF91DF9142
:103DC0000895DF93CF9300D000D000D0CDB7DEB7F9
:103DD000CE01019626E0FC0111922A95E9F722E036
:103DE000298324E02A832CE02B832BE02C83609111
:103DF00088040E942A1D0E94C31326960FB6F894C9
:103E0000DEBF0FBECDBFCF91DF910895DF93CF937B
:103E1000CDB7DEB727970FB6F894DEBF0FBECDBF84
:103E2000DE011196E7E8F1E087E001900D92815004
:103E3000E1F7CE010196609188040E942A1D0E943C
:103E4000C31327960FB6F894DEBF0FBECDBFCF9138
:103E5000DF910895DF93CF93CDB7DEB72D970FB6DF
:103E6000F894DEBF0FBECDBFDE011196EEE8F1E0A3
:103E70008DE001900D928150E1F78091A70382308F
:103E800079F0833018F48130C9F405C0833089F0AB
:103E90008430A1F40BC08DE58C8789818F5F04C0CD
:103EA00080E48C8789818E5F898308C089818F5FD8
:103EB000898389818F5F89838AE48C878DE491E08F
:103EC00069E471E00E943E41CE0101966091880450
:103ED0000E942A1D0E94C3132D960FB6F894DEBFD0
:103EE0000FBECDBFCF91DF91089580E20E9444299B
:103EF000882341F40E949015882321F480914D037A
:103F0000882399F30E946E2780914D01882319F42C
:103F10000E94141803C081E00E94140C80914D018E
:103F2000882331F081E090E020914D03222311F0AD
:103F300080E090E010924D03089589E40E942116DC
:103F400080E061E00E94A32783E590E00E94EF13E8
:103F50000E94C52780E062E00E94A32784E590E0EC
:103F60000E94EF130E94C5270E94C5178091A703E6
:103F7000843021F480913D03843011F085E001C04C
:103F800084E08093880485E080933D030E94751F40
:103F9000882339F0EDE4F1E001900020E9F7329751
:103FA000108210923D030E94C3130895CF93DF93B4
:103FB000CDE4D1E009900020E9F72197CD54D1401C
:103FC0009E012150C22FD0E0FE01E35BFE4F8081B5
:103FD000805380933D039091A703943029F484305B
:103FE00019F485E3808316C08093880491E0909350
:103FF0006304843031F088E490E00E94EF130E9463
:10400000C5270E94751F882319F0C35BDE4F1882F5
:1040100010923D030E94C313DF91CF910895FF9248
:104020000F931F93DF93CF93CDB7DEB764970FB68F
:10403000F894DEBF0FBECDBFF82E8FE090E00E9457
:10404000EF13BC018E010F5F1F4FC8010E943E415C
:104050008F2D90E00E94EF13BC01C8010E942A41FD
:10406000C80161E00E94EB2782E190E00E94EF131B
:1040700062E00E94EB2764960FB6F894DEBF0FBE95
:10408000CDBFCF91DF911F910F91FF9008958EE4E6
:104090000E94211681E10E940F200E94751F882333
:1040A00039F08AE694E00E941B0F0E9414180895CC
:1040B0000E94C31308958DE40E94211680E10E949E
:1040C0000F200E94751F882341F080E06AE674E0AB
:1040D0000E94540F0E94141808950E94C31308955B
:1040E000EF92FF920F931F93DF93CF93CDB7DEB77D
:1040F00061970FB6F894DEBF0FBECDBF7C010E9462
:104100006E278EE090E00E94EF13BC018E010F5FDE
:104110001F4FC8010E943E41C8016BE471E00E943C
:104120002A4185E290E00E94EF13BC01C8010E9481
:104130002A41C80160E00E94EB2786E090E00E94DF
:10414000EF1361E00E94EB27C70162E00E94EB27BA
:104150008EE10E94103061960FB6F894DEBF0FBE5C
:10416000CDBFCF91DF911F910F91FF90EF900895F8
:10417000DF92EF92FF920F931F93DF93CF93CDB710
:10418000DEB72F970FB6F894DEBF0FBECDBF88E025
:104190000E94211680E10E940F200E94751F882333
:1041A000C1F1FF24F394EE248E010F5F1F4F3CE218
:1041B000D32E8F2D0E949E0F8F2D6AE674E00E94F1
:1041C000540F882361F4F801EE0DF11D8F2D805DF1
:1041D0008083E394F801EE0DF11DD082E394F39413
:1041E0008F2D883031F780910C010E949E0F84E062
:1041F0006EE10E946F0CEE2049F0EA94CE01019628
:10420000FC01EE0DF11D10820E9470200E94141816
:1042100002C00E94C3132F960FB6F894DEBF0FBEE4
:10422000CDBFCF91DF911F910F91FF90EF90DF9065
:1042300008958091A703882329F484E00E94103018
:104240000E94932A08950F931F93DF93CF9300D07A
:10425000CDB7DEB78DE30E9421168091A703898335
:104260001A82CE01019660E070E044E050E023E065
:104270000FE115E10E944818882399F1F89489818B
:104280008093A703789481E690E06091A7030E9451
:10429000F74184E06EE10E946F0C8091A7030E94B9
:1042A000B62D81E080936404109241031092420382
:1042B0001092430310924403109245031092460358
:1042C00010924703109248030E94CE088091A703E2
:1042D000882319F084E10E946B290E9419210E9411
:1042E000DC080E94C3130F900F90CF91DF911F91B4
:1042F0000F910895EF92FF920F931F93CF93DF9347
:10430000E82ECAE1D1E00DE410E0FF2449815A8192
:104310002B813C818D819E81EE2089F456954795B5
:10432000569547955A83498336952795369527950F
:104330003C832B83969587959695879511C0440F5E
:10434000551F440F551F5A834983220F331F220FD5
:10435000331F3C832B83880F991F880F991F039667
:104360009E838D8369817A818F2D0E941C2A6B81A7
:104370007C818F2D0E943B2A6D817E818F2D0E9432
:10438000592ACE01B80147E050E00E94ED41F39474
:104390002796095F1F4F8F2D823009F0B7CF0E94FB
:1043A000CE08DF91CF911F910F91FF90EF9008956C
:1043B0000F931F93DF93CF9300D0CDB7DEB789E281
:1043C0000E94211688E061E00E94A3278091C1032A
:1043D00089831A82CE01019660E070E041E050E0EE
:1043E00025E004EA14E10E9448188823B1F0F8940B
:1043F00069816093C1038CE490E00E94F741809151
:10440000C1030E947A2184E10E946B2978940E9462
:10441000192184E06EE10E946F0C0E94C3130F907B
:104420000F90CF91DF911F910F9108951F931091DD
:10443000A7031092A7030E946B2980E060E00E940E
:10444000A327812F1F910895DF93CF930F92CDB7AC
:10445000DEB789830E94CE0889818093A7030E94DA
:1044600019210E94C3130F90CF91DF910895FF92FD
:104470000F931F93DF93CF9300D0CDB7DEB780911A
:1044800028010E941622F82E88EA90E068E00E9437
:1044900051271092890483E30E9421168091C10361
:1044A00090E0FC01EE0FFF1FE80FF91FEE0FFF1F5A
:1044B000E250FE4F848195819A8389836081718166
:1044C00042815381CE01019624E806E317E10E9460
:1044D000481880E790E067E00E945127F89484E153
:1044E0000E946B2978948F2D0E9424220F900F90A8
:1044F000CF91DF911F910F91FF900895FF920F933D
:104500001F93DF93CF9300D0CDB7DEB784E10E9435
:104510001622F82E8091870490E0FC0103E0EE0F54
:10452000FF1F0A95E1F7E81BF90BE65EFE4F80815D
:1045300089831A82CE01019660E070E041E050E08C
:1045400026E00CEB14E10E944818882329F18091A1
:1045500087046981282F30E0F90113E0EE0FFF1F77
:104560001A95E1F7E21BF30BE65EFE4F60830E94B3
:104570000D2A9091870487E0989FC0011124BC0107
:10458000635B7F4F865E9E4F47E050E00E94ED41A7
:1045900084E06EE10E946F0C8F2D0E9424220F9008
:1045A0000F90CF91DF911F910F91FF9008958EE2B0
:1045B0000E9421160E947E2208958AE20E942116FE
:1045C0000E947E220895FF920F931F93DF93CF9353
:1045D00000D0CDB7DEB784E10E941622F82E1091EC
:1045E00087040E94002ABC01812F0E94C22A809168
:1045F000870490E0FC0173E0EE0FFF1F7A95E1F76E
:10460000E81BF90BE65EFE4F838194819A838983D0
:104610008091C10390E0FC01EE0FFF1FE80FF91F2E
:10462000EE0FFF1FEE0FFF1FEA51FE4F64817581F1
:1046300046815781CE01019626E809E013E10E94E8
:1046400048188823A9F180918704282F30E0F901C8
:1046500043E0EE0FFF1F4A95E1F7E21BF30BE65E26
:10466000FE4F29813A813483238397E0899FC001DB
:104670001124BC01635B7F4F865E9E4F47E050E094
:104680000E94ED4180918704282F30E0F90193E0EA
:10469000EE0FFF1F9A95E1F7E21BF30BE65EFE4F6C
:1046A000658176810E94592A84E06EE10E946F0C38
:1046B0008F2D0E9424220F900F90CF91DF911F9198
:1046C0000F91FF9008958FE20E9421160E94E3222D
:1046D00008958BE20E9421160E94E3220895FF9222
:1046E0000F931F93DF93CF9300D0CDB7DEB784E154
:1046F0000E941622F82E8091870460E070E00E94EC
:10470000C22A8091870490E0FC0123E0EE0FFF1F96
:104710002A95E1F7E81BF90BE65EFE4F8181928155
:104720009A8389838091C10390E0FC01EE0FFF1F03
:10473000E80FF91FEE0FFF1FEE0FFF1FEA51FE4FAC
:104740006081718142815381CE01019626E802EE9B
:1047500012E10E9448188823A9F180918704282F2C
:1047600030E0F901B3E0EE0FFF1FBA95E1F7E21B6D
:10477000F30BE65EFE4F29813A813283218397E075
:10478000899FC0011124BC01635B7F4F865E9E4FF1
:1047900047E050E00E94ED4180918704282F30E0EF
:1047A000F901A3E0EE0FFF1FAA95E1F7E21BF30B5F
:1047B000E65EFE4F658176810E94592A84E06EE1B3
:1047C0000E946F0C8F2D0E9424220F900F90CF918A
:1047D000DF911F910F91FF90089580E30E942116B1
:1047E0000E946F2308958CE20E9421160E946F237D
:1047F0000895FF920F931F93DF93CF9300D0CDB70F
:10480000DEB784E10E941622F82E109187040E94E0
:10481000002ABC0176956795812F0E94C22A80915B
:10482000870490E0FC0173E0EE0FFF1F7A95E1F73B
:10483000E81BF90BE65EFE4F858196819A8389839A
:104840008091C10390E0FC01EE0FFF1FE80FF91FFC
:10485000EE0FFF1FEE0FFF1FEA51FE4F60857185BF
:1048600042855385CE01019625E807EB12E10E94AF
:104870004818882319F180918704282F30E0F90126
:1048800043E0EE0FFF1F4A95E1F7E21BF30BE65EF4
:10489000FE4F29813A813683258397E0899FC001A5
:1048A0001124BC01635B7F4F865E9E4F47E050E062
:1048B0000E94ED4184E06EE10E946F0C8F2D0E94FA
:1048C00024220F900F90CF91DF911F910F91FF90B5
:1048D000089581E30E9421160E94F92308958DE234
:1048E0000E9421160E94F9230895282F30E02330DA
:1048F000310514F48F5F01C080E0265F3D4FF90160
:10490000A081B0E0AA0FBB1FA60FB71FE82FF0E0F1
:10491000E65FFD4FE081F0E0EE0FFF1FE60FF71FAF
:104920002D913C911197808191818217930714F00A
:1049300081E008958FEF08950F931F93182F82E061
:1049400062E00E94A32789E390E00E94EF130E9497
:10495000C527612F70E080E090E044E020E000E0B7
:104960000E94F22D0E94C5271F910F9108952F924A
:104970003F924F925F926F927F928F929F92AF92EF
:10498000BF92CF92DF92EF92FF920F931F93DF932C
:10499000CF9300D000D000D0CDB7DEB780912801F2
:1049A0000E941622882E88EA90E068E00E94512733
:1049B0001092890484E30E942116809129010E94AB
:1049C0009C241A8219820E94002A969587959C83BE
:1049D0008B830E94002A9E838D8380E08E010F5F6F
:1049E0001F4FB8010E947524A82EE0910A02F0E042
:1049F000EE0FFF1FE00FF11FC080D18090902901C2
:104A0000FF24F3941801A3C02B813C818601021B73
:104A1000130B69817A814D815E81C8010E940E1756
:104A2000BC01C80141E00E949A1680918704B6013A
:104A30000E94C22AEF2DF0E0E65FFD4FE081F0E03A
:104A4000EE0FFF1FE20DF31D00811181C016D1068C
:104A500009F466C020913B033A2D3203C0011124B2
:104A60008C0D9D1DA7FE04C08017910744F005C062
:104A7000AA2019F00817190714F021118C01809150
:104A8000280160913C0370E0680F711D6F5F7F4FDC
:104A9000882777FD8095982F0E94E53D2B013C01EA
:104AA00020E030E44CE955E40E94993EC62EE72E02
:104AB000D82EB92E20E030E040E85FE30E94463D6A
:104AC00087FD28C06C2D7E2D8D2D9B2D20E03FEF86
:104AD0004FE757E40E94953E1816ACF4C301B201AB
:104AE00020E030E040E251E40E94993E0E94B73D50
:104AF00006C084EF91E00197F1F7615070406115B5
:104B00007105B9F723C06C2D7E2D8D2D9B2D0E9434
:104B1000B73D02C061E070E0CB010197F1F716C02C
:104B20008F2DB1010E947524A82E8F2D833040F463
:104B3000FF2021F49A94892D0E949C24F39401C0B3
:104B4000FF2480912A010E9410308601680180E2D2
:104B50000E944429882339F40E949015882319F46F
:104B6000992009F051CF0E946E2780914D01882332
:104B700019F40E9414180CC08DE491E0FC0101901E
:104B80000020E9F7CF0101978D5491400E94381819
:104B900080E790E067E00E945127F89484E10E944A
:104BA0006B297894882D0E94242226960FB6F894BB
:104BB000DEBF0FBECDBFCF91DF911F910F91FF9050
:104BC000EF90DF90CF90BF90AF909F908F907F90AD
:104BD0006F905F904F903F902F9008950F931F9389
:104BE000DF93CF9300D0CDB7DEB78EE10E942116C0
:104BF0008091B20390E001969A838983CE01019659
:104C000061E070E04AE050E025E807E812E10E9428
:104C10004818882331F169817A81615070407A8324
:104C200069836093B2038BE690E00E94F741609144
:104C3000B20389E0689FB001112464597F4F89E76E
:104C400092E049E050E00E94C94180917C0290913D
:104C50007D029093B1038093B00384E06EE10E94E3
:104C60006F0C0F900F90CF91DF911F910F910895CE
:104C70000E94EE250E94C31308950F931F93DF93A4
:104C8000CF9300D0CDB7DEB781E40E94211680918A
:104C9000750289831A82CE01019660E070E044E6D5
:104CA00050E027E807E812E10E944818882359F0ED
:104CB00069816093750282E690E00E94F74184E08A
:104CC0006EE10E946F0C0E94C3130F900F90CF9162
:104CD000DF911F910F9108950F931F93DF93CF934F
:104CE00000D0CDB7DEB780E40E9421168091A803E2
:104CF00089831A82CE01019660E070E041E050E0C5
:104D000023E007E015E10E944818882359F06981E3
:104D10006093A80383E690E00E94F74184E06EE18F
:104D20000E946F0C0E94C3130F900F90CF91DF91E0
:104D30001F910F9108950F931F93DF93CF9300D08E
:104D4000CDB7DEB78EE50E94211680912B018983B5
:104D50001A82CE01019660E070E046E050E023E068
:104D600002E813E10E9448188823C9F06981609322
:104D70002B0184E690E00E94F74184E06EE10E94FE
:104D80006F0CE0912B01F0E0EE0FFF1FE05FFE4F94
:104D90002591359145915491C9010E94ED2B0E94B6
:104DA000C3130F900F90CF91DF911F910F91089532
:104DB0008091A703823059F0833018F4813061F478
:104DC00003C0853048F406C00E943D2608950E9425
:104DD0006C2608950E949B26089528B1982F9F70F5
:104DE000922B98B998B1806F892388B9459A8DE044
:104DF0008A95F1F7459888EC8A95F1F708951F9305
:104E0000182F82958F700E94ED26812F0E94ED262B
:104E10001F91089544980E94FF260895449A0E9485
:104E2000FF2608950E940E2780918A048F5F809349
:104E30008A04803310F010928A040895EF92FF9252
:104E40000F931F93DF93CF9300D0CDB7DEB7182F0A
:104E500088E269837A830E940A27110F110F110FCC
:104E600069817A81462F572F7A0100E0802F810FC8
:104E700080640E940A27F70184910E9412270F5F25
:104E80000894E11CF11C083089F789E20E940A2786
:104E90000F900F90CF91DF911F910F91FF90EF90A6
:104EA0000895EF92FF920F931F93CF93DF93162FE6
:104EB000E82EE7017E01F92EE70100E006C0802F11
:104EC000BE010E941E270F5F28960117C0F3DF91D5
:104ED000CF911F910F91FF90EF90089581E00E9474
:104EE0000A2710928A0480E197E20197F1F708956A
:104EF0001F9310918A041F7031F080E20E940E27E8
:104F00001F5F1031D1F780918A0480680E940A27C0
:104F10001F9108950F931F93062F813011F014E510
:104F200001C010E589E20E940A27802F8F708067F8
:104F30000E940A27802F82958370812B0E940A2766
:104F40001F910F910895813108F080E0643008F0DE
:104F500060E06295607F680F60938A04862F8068A6
:104F60000E940A2708951F93682F80E00E94A327BC
:104F700010E180E20E940E271150D9F780918A0437
:104F800080680E940A271F910895EF92FF921F9355
:104F9000CF93DF9310918A0412951F70E82EE701DA
:104FA0007E01F92EE7010EC08A3051F4133010F45F
:104FB0001F5F01C010E080E0612F0E94A32702C0A4
:104FC0000E9412278991882379F7DF91CF911F9151
:104FD000FF90EF9008951F93DF93CF9300D0CDB74C
:104FE000DEB7182F862F69839A830E94B327212F5B
:104FF0009A81392FF90101900020E9F72E1B3F0B10
:105000002F5E3F4F36952795822F69810E94A327F7
:10501000812F9A810E94C5270F900F90CF91DF9129
:105020001F9108950F931F93DF93CF9300D000D06B
:10503000CDB7DEB7162F279A3D9A3C9A97B19F605D
:1050400097B94598E0E9F1E064EF71E0DB01119771
:10505000F1F73197D9F7813021F094E50EE635E18B
:1050600003C090E50CE63DE1449883E02C8339834E
:105070004B839A830E94ED26E0E1F7E23197F1F746
:1050800083E30E94ED2682E30E940A2789E20E94C0
:105090000A273981832F0E940A27812F8F7080670A
:1050A0000E940A27812F829583709A81892B0E9402
:1050B0000A27802F0E940A2788E20E940A272C8153
:1050C000822F81708C604B8150E041705070440F92
:1050D000551F842B0E940A270E946E2786E00E949B
:1050E0000A270F900F900F900F90CF91DF911F9193
:1050F0000F9108951F920F920FB60F9211242F93C4
:105100003F938F939F938DE386BD26B189B13091F4
:10511000600490E080789070959587959595879537
:10512000207C282B2095232780919503822380952E
:1051300080939503909194039223982790939403DE
:105140002823292380916004822780936004809122
:105150005E04909160049223982B90935E0480915A
:105160005E04807E51F01092BF031092BE0388EE61
:1051700093E09093D5018093D40180916004807E68
:1051800049F482E38093930384E18093C30386E030
:105190008093BC0380919303815080939303882371
:1051A00061F48091C303809393039091C203809133
:1051B0006004807E892B8093C2038091920381508A
:1051C00080939203882331F482E38093920381E0F9
:1051D00080935D0480919103815080939103882393
:1051E00031F484E18093910381E08093C003809146
:1051F0009003815080939003882331F482E0809360
:10520000900381E08093C40380918F038150809349
:105210008F03882331F48AE080938F0381E08093A9
:10522000BB038091D4019091D50101979093D50152
:105230008093D401009749F488EE93E09093D501D0
:105240008093D40181E080935F049F918F913F917F
:105250002F910F900FBE0F901F901895F89490917A
:105260005E04892390915E04982790935E0478945D
:105270000895F8949091C20389239091C2039827CE
:105280009093C20378940895F89490916004909557
:1052900089230E942E2908950E9439290E942E29CF
:1052A00008958823B9F08091BC03882341F0F894D5
:1052B0008091BC0381508093BC03789408958091C1
:1052C000C303843038F0F8948091C30382508093F4
:1052D000C30378940895EF92FF920F931F939091D8
:1052E0006F009D7F90936F009091C103992309F007
:1052F00057C0909181009C7F909381009091810094
:1053000094609093810090E190938B0490E290934D
:1053100097041092A4041092A304E82EFF2400E046
:1053200010E0E091C103F0E083E0EE0FFF1F8A95EB
:10533000E1F7EA52FE4F2681378140E050E060E01D
:105340007DE281E391E00E944E3FC801B7010E94D7
:10535000FC3E0E94E33D2FE632E143E85AE30E941F
:10536000993E0E94B73D9B017093A6046093A504EB
:105370004091880050918900952F80E0840F911D05
:10538000820F931F909389008093880080916F0013
:10539000826080936F001F910F91FF90EF900895AE
:1053A000909181009B7F9093810090918100936008
:1053B000A8CFE091C103F0E023E0EE0FFF1F2A9594
:1053C000E1F7EA52FE4F26813781829FB001839F29
:1053D000700D929F700D112480E090E00E94E33DDB
:1053E00020E030E040EA51E40E944A3D20E030E015
:1053F00040E05FE30E94E23C0E94B73DCB0108958C
:10540000E091C103F0E033E0EE0FFF1F3A95E1F7C2
:10541000EA52FE4F84819581089590E0FC01EE0FE1
:10542000FF1FE80FF91FEE0FFF1FEE0FFF1FE557DD
:10543000FB4F61706383089590E0FC01EE0FFF1F46
:10544000E80FF91FEE0FFF1FEE0FFF1FE557FB4F91
:10545000A091C103B0E083E0AA0FBB1F8A95E1F7DA
:10546000AA52BE4F12968D919C911397680F791F87
:1054700075836483089590E0FC01EE0FFF1FE80F31
:10548000F91FEE0FFF1FEE0FFF1FE557FB4FA09117
:10549000C103B0E033E0AA0FBB1F3A95E1F7AA526F
:1054A000BE4F8D919C911197861B970B9783868396
:1054B000089590E0FC01EE0FFF1FE80FF91FEE0FBB
:1054C000FF1FEE0FFF1FE557FB4F73876287248195
:1054D0003581A091C103B0E083E0AA0FBB1F8A957C
:1054E000E1F7AA52BE4F14968D919C911597909515
:1054F00081959F4F821B930B46815781840F951F87
:10550000660F771F860F971F73E0880F991F7A9594
:10551000E1F764E0969587956A95E1F7820F931F0E
:10552000918780870895EFE6F0E080818D7F80830A
:10553000089590E0FC01EE0FFF1FE80FF91FEE0F3A
:10554000FF1FEE0FFF1FE557FB4F44815581262FAC
:10555000372F2417350708F49A01FC01EE0FFF1FBF
:10556000E80FF91FEE0FFF1FEE0FFF1FE557FB4F70
:1055700046815781C9014217530708F4CA01928333
:1055800081830895AF92BF92CF92DF92EF92FF9204
:105590001F93CF93DF93182F9B0190E0FC01EE0F38
:1055A000FF1FE80FF91FEE0FFF1FEE0FFF1FE5575C
:1055B000FB4F4381442381F0E091C103F0E0B3E06D
:1055C000EE0FFF1FBA95E1F7EA52FE4F4481558175
:1055D000BA01621B730B9B01E091C103F0E0A3E0F1
:1055E000EE0FFF1FAA95E1F7EA52FE4FC480D58067
:1055F000A60156954795FC01EE0FFF1FEE24FF24F0
:1056000024173507E8F4E80FF91FEE0FFF1FEE0F20
:10561000FF1FE557FB4FC481D581608571856C1BE9
:105620007D0B80E090E0660F771F881F991F40E098
:1056300050E00E94FC3EA70196010E94703F1FC0EF
:10564000E80FF91FEE0FFF1FEE0FFF1FE557FB4F8F
:10565000A084B184668177816A197B0980E090E03B
:10566000660F771F881F991F241B350B40E050E001
:105670000E94FC3EA70196010E944E3FE501C20F29
:10568000D31F812FBE010E94992ADF91CF911F91D4
:10569000FF90EF90DF90CF90BF90AF9008951F9351
:1056A000182F882777FD8095982FE091C103F0E0AF
:1056B000A3E0EE0FFF1FAA95E1F7EA52FE4F248107
:1056C000358140E050E00E94FC3E24EB30E040E0B9
:1056D00050E00E944E3F812FB9010E94C22A1F91C3
:1056E00008951F920F920FB60F9211242F933F939C
:1056F0004F935F938F939F93EF93FF932091960324
:10570000223090F43BB1822F90E0FC01EE0FFF1F9E
:10571000E80FF91FEE0FFF1FEE0FFF1FE557FB4FBE
:105720008081809583238BB9822F8F5F809396032E
:105730008230C9F0833010F0109296032BB1809123
:10574000960390E0FC01EE0FFF1FE80FF91FEE0F2C
:10575000FF1FEE0FFF1FE557FB4F8081282B2BB952
:10576000818192810AC08091A5049091A604209124
:10577000A3043091A404821B930B409188005091A4
:105780008900352F20E0240F311D280F391F309359
:105790008900209388002091A3043091A404280F4D
:1057A000391F3093A4042093A3048091A504909101
:1057B000A6042817390720F01092A4041092A3041D
:1057C000FF91EF919F918F915F914F913F912F9119
:1057D0000F900FBE0F901F9018959C0140E050E075
:1057E00084E0220F331F441F551F8A95D1F760E0D4
:1057F0007DE281E391E00E944E3F215030403093A2
:10580000C5002093C40088E98093C10086E080939E
:10581000C20008959091C00095FFFCCF8093C60010
:105820000895EF92FF92CF93DF93E82EE7017E0178
:10583000F92EE70102C00E940A2C89918823D9F72A
:10584000DF91CF91FF90EF9008951F920F920FB6C6
:105850000F9211242F938F939F93EF93FF93209197
:10586000C60080919703882309F06AC0809198034D
:10587000281771F480911102882351F010921102BF
:1058800087EA94E09093100280930F0210923E05F5
:1058900080911102882309F053C0E0910F02F0912A
:1058A0001002208380913E058F5F80933E0580919A
:1058B0003D058823B1F080919903281789F581E08F
:1058C0008093110290913E05933050F19091A9047C
:1058D000913430F19B3520F58093BD039F34F1F076
:1058E0001FC080913E05823029F4213019F081E0FB
:1058F0008093110280913E05833021F4223010F014
:1059000086E001C085E080930E0290913E05809173
:105910000E02981729F481E0809311028093970377
:1059200080910F0290911002019690931002809343
:105930000F0280913E05863919F481E080931102AF
:10594000FF91EF919F918F912F910F900FBE0F902C
:105950001F9018950F931F9330E046C0E42FEF5F20
:10596000F0E0E955FB4F50815D53E42FEE5FF0E02E
:10597000E955FB4F1081E42FED5FF0E0E955FB4F57
:105980007081DC01A30FB11D052F02950F70E42F6C
:10599000F0E0E955FB4F20812D53220F220F202BE1
:1059A0002C93613021F1212F2D53E32FEF5FDC0188
:1059B000AE0FB11DFD015295507FA22FA695A69561
:1059C0005A2B5083623099F04C5F6350532F5E5FC7
:1059D000FC01E50FF11D2295220F220F207C572F8D
:1059E0005D53252B20833D5F662309F0B7CF1F91C0
:1059F0000F91089580919703882309F441C060E0D6
:105A000080E090E007C049555B4FFA012081820F8A
:105A1000911D6F5F462F50E020913E0530E02350EE
:105A20003040421753077CF39C013F70E0913E05E4
:105A300046E0359527954A95E1F7235CF0E0EC5573
:105A4000FB4F30812317E1F4E0913E058F73907096
:105A5000835CF0E0EB55FB4F9081891789F46091EE
:105A60003E05665085EC93E043E00E94AA2C8091AD
:105A7000A904F89410925C0410925B04789401C01D
:105A800080E0109297030895982F80538A3050F049
:105A90008153863020F0892F8154863010F4865F40
:105AA000089580E00895EF92FF920F931F93CF9394
:105AB000DF9380919703813009F043C080913E05C8
:105AC000882309F43EC081E0FF2402C0F9268F5FDD
:105AD00090913E05891738F4E82FF0E0E955FB4F27
:105AE00090819A3299F7C82FD0E08E010E5F1F4F38
:105AF00080913E0590E0081719071CF5C955DB4F4A
:105B000089810E94442DE82EF801E955FB4F8081E0
:105B10000E94442DE29450EFE522E82AEF1489F424
:105B2000188285EC93E068EA74E00E943E4181E0CF
:105B30008093BD03F89410925C0410925B047894F7
:105B400001C080E020915B0430915C0494E02C3E25
:105B5000390718F491E09093BD0310929703DF91F9
:105B6000CF911F910F91FF90EF900895823019F01F
:105B7000843081F405C083E2809398038DE004C0F3
:105B800084E2809398038AE08093990381E0809374
:105B90003D05089580E88093980310923D0508958F
:105BA00020913E05225020933E05209197032130FD
:105BB00091F420E009C0DC01A20FB11DF0E0E9552D
:105BC000FB4F30813C932F5FE22FE60F30913E0573
:105BD000231788F302C010923E051092970380911C
:105BE0003E0508952F923F924F925F926F927F925F
:105BF0008F929F92AF92BF92CF92DF92EF92FF92DD
:105C00000F931F93CF93DF936B017C01742E122FA0
:105C1000242E3324F101E656FC4F1082021798F42B
:105C2000E22FF0E0E01BF109EE0FFF1FEE0FFF1F68
:105C3000E954F04F25913591459154910E94703F60
:105C400069017A01102FF7FE0BC0F094E094D09414
:105C5000C094C11CD11CE11CF11C6624639401C0DA
:105C6000662420E030E001E003C00F5F0A3091F0CD
:105C70002F5F3F4FF901EE0FFF1FEE0FFF1FE9549B
:105C8000F04F85919591A591B491C816D906EA0671
:105C9000FB065CF761100F5F11110F5F07191016FB
:105CA0000CF0E7C0202F332727FD3095812F90E09F
:105CB0002817390751F0AC014F5F5F4F24173507A4
:105CC00009F062C0112309F45FC0212F30E0F9010F
:105CD000EE0FFF1FEE0FFF1FED54F04F85919591D2
:105CE000A591B491F901EE0FFF1FEE0FFF1FE954CC
:105CF000F04F85909590A590B4909C01AD0162E025
:105D0000220F331F441F551F6A95D1F7280F391FE3
:105D10004A1F5B1F2C0D3D1D4E1D5F1DCA01B901A1
:105D2000A50194010E94703F49015A0120E030E032
:105D300041E003C04F5F4A3091F02F5F3F4FF901C0
:105D4000EE0FFF1FEE0FFF1FE954F04F8591959165
:105D5000A591B49188169906AA06BB065CF7842F14
:105D6000992787FD9095860D911D281639060CF010
:105D70007DC0C701B6012AE030E040E050E00E945B
:105D8000703F69017A0174C0281739070CF060C0B0
:105D9000A02FBB27A7FDB095FD01EE0FFF1FEE0F53
:105DA000FF1FED54F04F2591359145915491CA0153
:105DB000B901E2E0660F771F881F991FEA95D1F7B6
:105DC000620F731F841F951F6C0D7D1D8E1D9F1DFF
:105DD000FD01EE0FFF1FEE0FFF1FE954F04F25915D
:105DE0003591459154910E94703F69017A0160E0BC
:105DF00070E08824839404C08394882D8A3091F0C5
:105E00006F5F7F4FFB01EE0FFF1FEE0FFF1FE95487
:105E1000F04F85919591A591B491281739074A07BC
:105E20005B0754F7882D992787FD9095860D911D66
:105E3000281639065CF01150CA01B9012AE030E099
:105E400040E050E00E94703F69017A01101B11C0D0
:105E50007A94E72DFF27E7FDF095E556FC4F8AE29F
:105E600002C082937A9477FEFCCF59C07501640119
:105E700010E0072D0150C02FDD27C7FDD095C65675
:105E8000DC4F462C55248AE0882E912CA12CB12C75
:105E900008942108310826C0112379F09101211BB3
:105EA00031098217930749F48BE490E00E94EF13C5
:105EB000FC018081888310E013C0C701B601A501F1
:105EC00094010E94703F605D688369017A01C1148A
:105ED000D104E104F10421F4112311F4015008C0AC
:105EE00001502197CE018A59934084159505A4F657
:105EF000662049F0E02FFF27E7FDF095E656FC4FBE
:105F00008DE280830150E02FFF27E7FDF095E556F5
:105F1000FC4F80E202C08293015007FFFCCF8AE968
:105F200093E0DF91CF911F910F91FF90EF90DF9061
:105F3000CF90BF90AF909F908F907F906F905F9029
:105F40004F903F902F900895AF92BF92DF92EF92C3
:105F5000FF920F931F93DF93CF9300D0CDB7DEB79F
:105F60007A018B01BE016F5F7F4F4AE050E00E94D3
:105F7000C23F9B01AC01E981FA8180818E3251F5EB
:105F80005F010894A11CB11C1AC0CA01B9012AE022
:105F900030E040E050E00E94FC3E9B01AC018D2DC2
:105FA00090E0C097AA2797FDA095BA2F280F391F18
:105FB0004A1F5B1F0894E108F10801091109F50166
:105FC000D1905F01DD2031F0E114F10401051105EC
:105FD000E1F618C0E114F1040105110599F0F7018B
:105FE000EE0FFF1FEE0FFF1FE954F04FE590F59005
:105FF00005911491CA01B9019701A8010E94FC3EC4
:106000009B01AC01B901CA010F900F90CF91DF91B4
:106010001F910F91FF90EF90DF90BF90AF90089588
:1060200090E044EF51E009C028EE33E0FA013197E7
:10603000F1F721503040D1F79F5F9817A8F30895EA
:10604000DF92EF92FF920F931F93CF93DF93EC01B8
:10605000CB01BA01022F2CE330E040E050E00E9477
:106060004E3F122FF32EE42ED52EC00FD11D2AE065
:1060700030E040E050E00E944E3F205D2883605DAC
:106080006983612F7F2D8E2D9D2DDF91CF911F91E3
:106090000F91FF90EF90DF9008950F931F93DF9380
:1060A000CF93CDB7DEB727970FB6F894DEBF0FBEFC
:1060B000CDBFAB01BC011F8277FF0BC057FF03C0F0
:1060C000509541955F4F662757FD6095762F8DE27D
:1060D00001C080E289838E010F5F1F4FC80124E059
:1060E0000E942030AB01BC018AE38C83C80121E00F
:1060F0000E942030C8010E94C52727960FB6F89449
:10610000DEBF0FBECDBFCF91DF911F910F910895DC
:10611000FF920F931F93DF93CF93CDB7DEB72997ED
:106120000FB6F894DEBF0FBECDBF20EA3FE040E0DF
:1061300050E00E944E3FF42FE52F19868E010F5F2D
:106140001F4FC801A9016F2F7E2F26E00E9420302B
:10615000AB01BC018AE3F82EFE82C80123E00E9455
:106160002030AB01BC01FB82C80120E00E9420303E
:10617000C8010E94C52729960FB6F894DEBF0FBE4E
:10618000CDBFCF91DF911F910F91FF900895CF93D5
:10619000DF9385E00E94A70BBC0180E090E0209196
:1061A00012013091130140E050E00E94FC3E37E0C4
:1061B00096958795779567953A95D1F7EB0186E0A7
:1061C0000E94A70BBC0180E090E020911401309167
:1061D000150140E050E00E94FC3E27E0969587952F
:1061E000779567952A95D1F78091AF038823B1F40D
:1061F000C617D70740F48091AD039091AE03009786
:1062000011F101971CC080917502680F711D6C1708
:106210007D0750F581E08093AF0326C06C177D07A2
:10622000D0F4C091AD03D091AE030E94002AC817EC
:10623000D90748F48091AD039091AE0301969093F5
:10624000AE038093AD036091AD037091AE0380E027
:106250000E94C22A09C080917502C80FD11DC617BD
:10626000D70710F41092AF03DF91CF91089580917A
:106270003E038823B9F580914D01882399F581E08B
:1062800060E00E94A3278091BD038823B9F080912C
:10629000AC03863020F41092AB0385E010C08091EF
:1062A000AB03882371F481E08093AB0380913F05B9
:1062B0008A3014F4805D03C088E501C08AE30E943F
:1062C00012272091AC03822F64E10E941B3F992387
:1062D00011F41092BD032F5F2093AC032C3011F406
:1062E0001092AC0308954F925F926F927F928F92BB
:1062F0009F92AF92BF92CF92DF92EF92FF920F9355
:106300001F93DF93CF93CDB7DEB72A970FB6F894DC
:10631000DEBF0FBECDBFFB01C0905305D09054052A
:10632000E0905505F090560540905705509058055F
:106330006090590570905A0580809180A280B3804A
:1063400024813581468157812F83388749875A8731
:10635000CA01B901640D751D861D971D20E03DE23F
:1063600041E351E00E94703FC9010E94F2398C0163
:10637000C701B601681979098A099B092AE030E04A
:1063800040E050E00E94703FCA01B9012FE435E0BF
:1063900040E050E00E94FC3E9801442737FD4095C4
:1063A000542F0E94FC3E20E836E948E950E00E9464
:1063B000703FF22E032F142FE52EC301B2012F815F
:1063C000388549855A85621B730B840B950B29E52B
:1063D00034E040E050E00E94FC3E20E137E240E043
:1063E00050E00E94703FD22EC32EB42EA52E6F2DEA
:1063F000702F812F9E2D0E94373A4C016F2D702FE8
:10640000812F9E2D2F2D302F412F5E2D0E94FC3E7F
:106410007B018C016D2D7C2D8B2D9A2D2D2D3C2DEE
:106420004B2D5A2D0E94FC3EE60EF71E081F191F29
:10643000C801B7010E94AD398C0120E030E009832A
:106440001A832B833C83C401845E9D4F68E671E010
:106450000E943B3F8D839E83202F3A814B815C813C
:10646000BC0180E090E02A960FB6F894DEBF0FBE24
:10647000CDBFCF91DF911F910F91FF90EF90DF90F3
:10648000CF90BF90AF909F908F907F906F905F90D4
:106490004F900895EF92FF920F93CF93DF937A017D
:1064A000E9010E94A327C7010E94C527CE010E94CF
:1064B000C527002319F0802F0E941227DF91CF916A
:1064C0000F91FF90EF900895CF92DF92EF92FF929D
:1064D0000F93CF93DF9390913D03992309F404C266
:1064E00080916404882319F0943009F0FDC19091E3
:1064F0003E03992309F0F8C190916304992331F088
:10650000882321F4109263040E946E2780913D033A
:10651000823009F496C0833020F4813009F0E4C160
:1065200007C0833009F4CDC0843009F0DDC117C144
:1065300060915F0570916005882777FD8095982FA1
:1065400043E020E000E00E94F22D9C0180E060E04A
:1065500042E152E00FED0E944A3260914D05709188
:106560004E0580914F059091500543E021E001E0F8
:106570000E94F22D9C0188E060E047E152E00DE6C8
:106580000E944A326091510570915205882777FD2B
:106590008095982F43E020E000E00E94F22D9C01BE
:1065A00080E061E04CE152E00FED0E944A326091E0
:1065B00048057091490580914A0590914B052091BD
:1065C0005B0530915C0540915D0550915E05621B55
:1065D000730B840B950B43E023E001E00E94F22D46
:1065E0009C0188E061E041E252E00DE60E944A32FF
:1065F0006091610570916205882777FD8095982FDD
:1066000043E020E000E00E94F22D9C0180E062E087
:1066100046E252E00FED0E944A32609163057091AC
:106620006405882777FD8095982F43E020E000E0FF
:106630000E94F22D9C0188E062E04BE252E00FEDF7
:106640003DC0609140057091410580914205909157
:1066500043054BE027E007E00E94F22D9C0180E01B
:1066600060E040E352E000E00E944A32609144055D
:106670007091450580914605909147054BE027E0D4
:1066800007E00E94F22D9C0180E061E046E352E0C9
:1066900000E00E944A32609148057091490580915E
:1066A0004A0590914B054BE023E001E00E94F22D5A
:1066B0009C0180E062E04CE352E000E00E944A323C
:1066C00013C16091530570915405809155059091C7
:1066D00056054BE027E007E00E94F22D9C0180E088
:1066E00060E042E452E000E00E944A3260915705C7
:1066F000709158058091590590915A054BE027E01B
:1067000007E00E94F22D9C0180E061E048E452E045
:1067100000E00E944A3260915B0570915C058091B7
:106720005D0590915E054BE023E001E00E94F22DB3
:106730009C0180E062E04EE452E000E00E944A32B8
:1067400080E40E942E29882331F480E80E942E29BB
:10675000882309F4C9C081E080936404C5C06091B6
:10676000650570E080E090E044E021E001E00E94F7
:10677000F22D9C0180E060E044E552E006E50E94D5
:106780004A326091B0037091B10380E090E044E040
:1067900020E000E00E94F22D9C0188E060E047E5E7
:1067A00052E00E944A32609166057091670580E070
:1067B00090E044E021E001E00E94F22D9C0180E0A5
:1067C00061E04AE552E001E40E944A322091B703B9
:1067D0003091B8032115310509F441C040E050E083
:1067E0006091B3037091B4038091B5039091B603A7
:1067F0000E944E3FE9012097C1F160917A027091A9
:106800007B0280E090E02091B0033091B10340E042
:1068100050E0621B730B840B950B24E230E040E0E8
:1068200050E00E94FC3E9E0140E050E00E94703F1C
:1068300069017A01C90137FF03C0909581959F4F87
:106840006EE080319607DCF057FF13C051EFC52E84
:1068500051EFD52E5FEFE52E5FEFF52E10C0CC2463
:10686000DD247601C0E0D0E00AC0CC24DD2476012E
:1068700006C04FE0C42E4EE0D42EE12CF12CBE0118
:1068800080E090E044E021E001E00E94F22D9C01D4
:1068900088E061E04DE552E001E40E944A3280E088
:1068A00062E00E94A3278AE10E94122760917E0283
:1068B00070917F02809180029091810220EA3FE0F6
:1068C00040E050E00E944E3FCA01B9010E944D30A5
:1068D00088E062E00E94A32780E692E00E94C5273C
:1068E000C701B6010E944D300E943731DF91CF9130
:1068F0000F91FF90EF90DF90CF900895EF92FF926D
:106900000F931F93DF93CF9300D000D000D0CDB76B
:10691000DEB783E595E060E475E00E94733129837A
:106920003A834B835C836D837E83ADE4B5E0FE01E7
:10693000319686E001900D928150E1F76091480513
:106940007091490580914A0590914B0520915B0516
:1069500030915C0540915D0550915E05621B730BA3
:10696000840B950B24E630E040E050E00E94703F3D
:10697000E0904D05F0904E0500914F0510915005A7
:10698000CA01B901A80197010E94373A90936405A2
:106990008093630580914D0590914E05A0914F0520
:1069A000B091500588329105A105B1054CF08C33AA
:1069B0009105A105B10584F58091AA03882361F1B1
:1069C00080915F05909160059093520580935105E9
:1069D0008091480590914905A0914A05B0914B05D9
:1069E00020915B0530915C0540915D0550915E05FD
:1069F000821B930BA40BB50B803A2FE0920720E08B
:106A0000A20720E0B20724F41092640510926305F7
:106A100081E08093AA0302C01092AA0380915105DD
:106A2000909152058E539E4F20915F0530916005E5
:106A3000821B930B68E671E00E943B3F90936205D6
:106A400080936105209163053091640537FF04C090
:106A500010926405109263052091630530916405DE
:106A6000253B310534F024EB30E03093640520936E
:106A70006305843B910594F0845B9040909362059C
:106A80008093610584EB90E020916305309164056B
:106A9000821B930B9093640580936305609161055D
:106AA0007091620580E00E944F2B609163057091A8
:106AB000640581E00E944F2B26960FB6F894DEBF46
:106AC0000FBECDBFCF91DF911F910F91FF90EF903F
:106AD00008956F927F928F929F92AF92BF92CF92C2
:106AE000DF92EF92FF921F93CF93DF93EC010E940E
:106AF000FA2C8F3409F073C0E5ECF3E0F983E883F6
:106B0000A0E4B5E031968DE001900D928150E1F75F
:106B1000E880F980F701EC5BFF4F1081111F11270E
:106B2000111F60915B0570915C0580915D059091EE
:106B30005E050E94E53D5B016C01F70163A974A944
:106B4000882777FD8095982F20EA3FE040E050E0CD
:106B50000E94FC3E0E94E53D20E030E044EB51E421
:106B60000E944A3D3B014C016091480570914905E6
:106B700080914A0590914B050E94E53D9B01AC0137
:106B8000C401B3010E94E23CA60195010E94E13CD0
:106B900020E030E040EA50E40E944A3D9B01AC0115
:106BA000C601B5010E94E23C0E94B23D60934805D7
:106BB0007093490580934A0590934B05F701ED5B6F
:106BC000FF4F8081817080933F03888199810E946B
:106BD0009238E881F98182A980933F051BC080919A
:106BE000A8038823B1F080915B0490915C04F1E0EC
:106BF000853A9F0770F082E692E00E94112C809106
:106C00005B0490915C0420E2803D920711F40E94A5
:106C10001B3810E0812FDF91CF911F91FF90EF90F3
:106C2000DF90CF90BF90AF909F908F907F906F90AC
:106C30000895DF93CF9300D0CDB7DEB78091A9033D
:106C4000882309F048C081E08093A903CE01019612
:106C50000E9469358823D9F1809164048823A9F1C1
:106C6000E981FA81DF01AD5BBF4F8C9183FF2FC0BB
:106C7000878D90A1A1A1B2A1809353059093540553
:106C8000A0935505B093560583A194A1A5A1B6A1E3
:106C90008093570590935805A0935905B0935A05D2
:106CA00087A190A5A1A5B2A580935B0590935C05F3
:106CB000A0935D05B0935E0586AD97AD909360059A
:106CC00080935F051092640402C00E947E340E948B
:106CD00064321092A9030F900F90CF91DF91089525
:106CE00080916404882341F480915105909152056C
:106CF0009093600580935F050895AF92BF92CF9205
:106D0000DF92EF92FF920F931F93CF93DF93EB01EC
:106D1000FC0130812AE0329F900111244181240F2F
:106D2000311D205132405901CC24B7FCC094DC2CD9
:106D3000029646E050E060E070E00E94A42F7B01E4
:106D40008C01C601B50120E836E948E950E00E940F
:106D5000FC3E5B016C01C801B70126E030E040E079
:106D600050E00E94703F2A0D3B1D4C1D5D1D888127
:106D7000833539F450954095309521953F4F4F4FCD
:106D80005F4FB901CA01DF91CF911F910F91FF9021
:106D9000EF90DF90CF90BF90AF900895AF92BF92E9
:106DA000CF92DF92EF92FF920F931F93CF93DF93D7
:106DB000FC01EB01228130E02051324090818AE0D9
:106DC000989FC00111244181840F911D805E9140E4
:106DD000AC01440F551F63E0880F991F6A95E1F7D6
:106DE000480F591F240F351F5901CC24B7FCC094FC
:106DF000DC2CCF01039646E050E060E070E00E949A
:106E0000A42F7B018C01C601B50120E836E948E9D1
:106E100050E00E94FC3E5B016C01C801B70126E016
:106E200030E040E050E00E94703F2A0D3B1D4C1DB9
:106E30005D1D8881873539F45095409530952195B1
:106E40003F4F4F4F5F4FB901CA01DF91CF911F9163
:106E50000F91FF90EF90DF90CF90BF90AF9008958B
:106E6000AF92BF92CF92DF92EF92FF920F931F9358
:106E70000E94532D882309F4A4C085EC93E06DE6AD
:106E800072E00E9425416FE672E00E943541009752
:106E900009F097C080E090E06DE672E00E94254125
:106EA00080E090E06DE672E00E9425417C0180E088
:106EB00090E06DE672E00E942541BC01C7010E948E
:106EC0007D365B016C0180E090E06DE672E00E942F
:106ED00025417C0180E090E06DE672E00E94254152
:106EE000BC01C7010E94CE367B018C0180E090E09E
:106EF0006DE672E00E942541FC018081803309F437
:106F000060C080E090E06DE672E00E9425410E9442
:106F1000EF4080933F0580E090E06DE672E00E94D4
:106F2000254180E090E06DE672E00E94254143E05B
:106F300050E060E070E00E94A42F609348057093D9
:106F4000490580934A0590934B05A0924405B09261
:106F50004505C0924605D0924705E0924005F09263
:106F600041050093420510934305209164042223B8
:106F700031F120913F05263014F1E0925305F09253
:106F800054050093550510935605A0925705B092ED
:106F90005805C0925905D0925A0560935B057093CD
:106FA0005C0580935D0590935E05109260051092DC
:106FB0005F051092640488E760EF0E946F0C0E94E6
:106FC0007E340E9464321F910F91FF90EF90DF900A
:106FD000CF90BF90AF90089585EC93E062E00E945F
:106FE000D02D882339F18091C503843019F5809123
:106FF000C70390E09695982F8827979587952091BD
:10700000C80330E0822B932B64E170E00E94273F9D
:107010006C33710530F06C537040653B710520F4A2
:1070200005C060E070E002C064EB70E08091C603D0
:107030000E944F2B0895CF93DF938091B203C82F06
:10704000D0E0CE0173E0880F991F7A95E1F78C0F9D
:107050009D1F8F589F4F0E94E1419B01AC011092F0
:10706000400380917E0290917F02A0918002B091B6
:107070008102281739074A075B0709F450C080913D
:107080003F03882341F48091B0039091B103909322
:107090007D0280937C02CE0163E0880F991F6A9580
:1070A000E1F78C0F9D1F84599F4F609179020E94D8
:1070B000F7412091B20330E0C90153E0880F991FD6
:1070C0005A95E1F7820F931F60917C0270917D02C7
:1070D00081599F4F0E940D422091B20330E0C901B7
:1070E00043E0880F991F4A95E1F7820F931F409163
:1070F0007E0250917F0260918002709181028F58D0
:107100009F4F0E94054283EB93E065E670E046E006
:1071100050E00E94ED4184E06EE10E946F0CDF912F
:10712000CF910895AF92BF92CF92DF92EF92FF92EC
:107130000F931F93DF93CF9300D000D000D0CDB733
:10714000DEB77C01FC0141AD4093650580913F03B2
:10715000882309F04AC0E25BFF4F8081918187302C
:10716000910508F042C0442309F43FC080917902A0
:10717000481718F44093790238C0242F30E090E08B
:107180000496821793078CF540937902109240037E
:107190001092B1031092B00310927D0210927C0203
:1071A00010927E0210927F02109280021092810251
:1071B0000E946E278E010F5F1F4FC8016DE471E0C2
:1071C0000E943E410E94EE258DE491E0B8010E94AC
:1071D0003E4180914D01882319F40E94141803C088
:1071E00081E080934D030E941B3881E0809340032F
:1071F0000091B7031091B803F6E401351F07E8F1D9
:107200002091B3033091B4034091B5035091B6037C
:10721000CA01B901A3E0660F771F881F991FAA95BD
:10722000D1F7620F731F841F951FFAE0AF2EB12CA8
:10723000C12CD12CA60195010E944E3F2093B3038F
:107240003093B4034093B5035093B60320E030E08D
:10725000C901B801E3E0660F771F881F991FEA95FF
:10726000D1F7600F711F821F931FA60195010E9425
:107270004E3F3093B8032093B703F701E25BFF4F13
:107280006081718165307105C8F16550704080E0A2
:1072900090E02091770230E040E050E00E94FC3E18
:1072A00024E630E040E050E00E944E3F80917602BC
:1072B00090E0820F931F9093670580936605A0E08E
:1072C000B0E02091B3033091B4034091B5035091E5
:1072D000B603820F931FA41FB51F8093B30390932F
:1072E000B403A093B503B093B6038091B703909114
:1072F000B80301969093B8038093B7036091780226
:1073000070E080E090E0F701E05BFF4F2081318189
:1073100040E050E00E94FC3E24E630E040E050E0D7
:107320000E944E3F80917C0290917D02820F931FBC
:107330009093B1038093B00326960FB6F894DEBF06
:107340000FBECDBFCF91DF911F910F91FF90EF90B6
:10735000DF90CF90BF90AF900895AF92BF92CF9241
:10736000DF92EF92FF920F931F93CF93DF935B0116
:107370006C019FE0E92EF12C00E010E8C0E0D0E8BD
:10738000169507959E0140E050E0CA01B9010E94A0
:10739000FC3EA616B706C806D90618F4C01BD10BCA
:1073A00002C0C00FD11F0894E108F108E114F104F4
:1073B00039F79E0140E050E0CA01B9010E94FC3E4D
:1073C000A616B706C806D90608F42197CE01DF91A4
:1073D000CF911F910F91FF90EF90DF90CF90BF90D2
:1073E000AF9008954AE550E0481B590B57FF05C080
:1073F000509541955F4FEFEF01C0E1E028E631E0A5
:10740000CA01B9010E943B3F8B359105E4F0AC0104
:107410004B5550404A35510538F424EB30E0A90172
:10742000481B590BCA010FC0BC01655B70406A352F
:10743000710518F4845B904004C0A901481B590BE6
:10744000CA014FEF01C041E04E02A0011124FC012E
:10745000EE0FFF1FEE57FD4F80819181489F9001F5
:10746000499F300D589F300D1124C90108952F9266
:107470003F924F925F926F927F928F929F92AF92C4
:10748000BF92CF92DF92EF92FF920F931F93DF9301
:10749000CF93CDB7DEB728970FB6F894DEBF0FBEF7
:1074A000CDBF69837A838B839C8319012A01E9808C
:1074B000FA80F7FE04C0F094E194F108F3940027F9
:1074C000F7FC0095102FE114F1040105110529F4D2
:1074D00057FEAFC024EB30E0AEC0510137FE04C010
:1074E000B094A194B108B394CC24B7FCC094DC2C24
:1074F000AE14BF04C006D10688F4C601B5012CEE57
:107500003DE640E050E00E94FC3EA80197010E9449
:10751000703F8CEE9DE6A0E0B0E014C0C801B7015A
:107520002CEE3DE640E050E00E94FC3EA6019501B5
:107530000E944E3F822F932FA42FB52F2CEE3DE6B5
:1075400040E050E060E070E0AA24BB24650139010E
:107550004A01062E04C096948794779467940A94FF
:10756000D2F77C018D01062E04C015950795F7947E
:10757000E7940A94D2F7ED82FE820F831887FB010D
:10758000EE0FFF1FB7FF13C02E193F09400B510B21
:10759000860D971DA81DB91DE152F04FE590F4909E
:1075A00000E010E0AE18BF08C00AD10A16C0ED8096
:1075B000FE800F8118852E0D3F1D401F511F86191B
:1075C0009709A809B909E152F04FE590F49000E05D
:1075D00010E0AE0CBF1CC01ED11E6F5F7F4F6D3020
:1075E000710509F0B4CFC601B5012BEE31E040E0E2
:1075F00050E00E944E3F121413041404150464F06A
:1076000084EB90E0A0E0B0E07C018D01E21AF30A87
:10761000040B150BA801970189819A81AB81BC816C
:10762000181619061A061B0634F0309521953F4F9F
:1076300002C020E030E0C90128960FB6F894DEBF02
:107640000FBECDBFCF91DF911F910F91FF90EF90B3
:10765000DF90CF90BF90AF909F908F907F906F9072
:107660005F904F903F902F900895ACE2B0E0EBE335
:10767000FBE30C948B3F29833A834B835C836D83BC
:107680007E838F839887A986BA86CB86DC86ED8633
:10769000FE860F87188B69807A808B809C8069A218
:1076A0007AA28BA29CA2840173018FEF9FEFA0E0CE
:1076B000B0E0E822F9220A231B23140144245524B4
:1076C00069847A848B849C846DA27EA28FA298A602
:1076D00064015301A822B922CA22DB223401882482
:1076E0009924C601B501A80197010E94FC3E69A733
:1076F0007AA78BA79CA7C401B3010E94FC3E7B0123
:107700008C01C601B501A20191010E94FC3E5B0102
:107710006C01C401B3010E94FC3E9B01AC01EA0C68
:10772000FB1C0C1D1D1D69A47AA48BA49CA4C40180
:10773000AA27BB27E80EF91E0A1F1B1FEA14FB0429
:107740000C051D0520F4205030404F4F5F4FC801FD
:10775000AA27BB27820F931FA41FB51F8D8F9E8F53
:10776000AF8FB8A38701FF24EE2429A53AA54BA526
:107770005CA540705070E20EF31E041F151FE98EC9
:10778000FA8E0B8F1C8FDE2CAA8CCB8C6C8C8D8B85
:107790008E8D8E8B8F8D8F8B88A1888F2D853E85CA
:1077A0004F85588969A17AA18BA19CA10E94FC3EBA
:1077B0007B018C012D813E814F8158856DA17EA179
:1077C0008FA198A50E94FC3EE60EF71E081F191F08
:1077D0006D897E898F89988D6E0D7F1D801F911F09
:1077E0006D8B7E8B8F8B988F7E892D2D3A2D4C2D16
:1077F000562D8F89988DAC96E2E10C94A73F0F939C
:10780000DF93CF93CDB7DEB760970FB6F894DEBFA6
:107810000FBECDBF002309F459C029833A834B839F
:107820005C836D837E838F839887E0E2E01B2D81EC
:107830003E814F8158851E16BCF01D861E861F8610
:10784000188A8E2F992787FD9095909581959F4F47
:1078500004C056954795379527958A95D2F729877D
:107860003A874B875C872AC0CA01B901002E04C041
:1078700096958795779567950A94D2F76D877E8759
:107880008F87988BDA01C90104C0880F991FAA1F3E
:10789000BB1FEA95D2F729813A814B815C8104C0F4
:1078A00056954795379527950A95D2F7822B932BB6
:1078B000A42BB52B89879A87AB87BC8729853A8506
:1078C0004B855C856D857E858F85988960960FB622
:1078D000F894DEBF0FBECDBFCF91DF910F91089519
:1078E0000F93DF93CF93CDB7DEB760970FB6F894C1
:1078F000DEBF0FBECDBF002309F459C029833A83F0
:107900004B835C836D837E838F839887E0E2E01BEB
:1079100029813A814B815C811E16BCF019861A863A
:107920001B861C868E2F992787FD909590958195B3
:107930009F4F04C0220F331F441F551F8A95D2F753
:107940002D873E874F87588B2AC0CA01B901002E68
:1079500004C0660F771F881F991F0A94D2F76987A2
:107960007A878B879C87DA01C90104C0B695A795F1
:1079700097958795EA95D2F72D813E814F8158855D
:1079800004C0220F331F441F551F0A95D2F7822BC4
:10799000932BA42BB52B8D879E87AF87B88B29851A
:1079A0003A854B855C856D857E858F859889609647
:1079B0000FB6F894DEBF0FBECDBFCF91DF910F9110
:1079C00008955058BB27AA270ED075C166D130F054
:1079D0006BD120F031F49F3F11F41EF45BC10EF423
:1079E000E095E7FB51C1E92F77D180F3BA17620721
:1079F00073078407950718F071F49EF58FC10EF494
:107A0000E0950B2EBA2FA02D0B01B90190010C01AE
:107A1000CA01A0011124FF27591B99F0593F50F4C6
:107A2000503E68F11A16F040A22F232F342F44271E
:107A3000585FF3CF469537952795A795F040539516
:107A4000C9F77EF41F16BA0B620B730B840BBAF0E6
:107A50009150A1F0FF0FBB1F661F771F881FC2F751
:107A60000EC0BA0F621F731F841F48F48795779565
:107A70006795B795F7959E3F08F0B3CF9395880F1C
:107A800008F09927EE0F979587950895D9D008F4B7
:107A900081E008950CD00FC107D140F0FED030F046
:107AA00021F45F3F19F0F0C0511139C1F3C014D176
:107AB00098F39923C9F35523B1F3951B550BBB27B5
:107AC000AA2762177307840738F09F5F5F4F220F62
:107AD000331F441FAA1FA9F333D00E2E3AF0E0E85B
:107AE00030D091505040E695001CCAF729D0FE2FA7
:107AF00027D0660F771F881FBB1F26173707480739
:107B0000AB07B0E809F0BB0B802DBF01FF279358EE
:107B10005F4F2AF09E3F510568F0B6C000C15F3F3D
:107B2000ECF3983EDCF3869577956795B795F795D6
:107B30009F5FC9F7880F911D9695879597F90895CE
:107B4000E1E0660F771F881FBB1F6217730784076A
:107B5000BA0720F0621B730B840BBA0BEE1F88F779
:107B6000E095089504D06894B111D9C00895BCD0AF
:107B700088F09F5790F0B92F9927B751A0F0D1F016
:107B8000660F771F881F991F1AF0BA95C9F712C0A0
:107B9000B13081F0C3D0B1E00895C0C0672F782F15
:107BA0008827B85F39F0B93FCCF38695779567950C
:107BB000B395D9F73EF490958095709561957F4F78
:107BC0008F4F9F4F0895E89409C097FB3EF490951E
:107BD0008095709561957F4F8F4F9F4F9923A9F0A6
:107BE000F92F96E9BB279395F69587957795679535
:107BF000B795F111F8CFFAF4BB0F11F460FF1BC079
:107C00006F5F7F4F8F4F9F4F16C0882311F096E90B
:107C100011C0772321F09EE8872F762F05C06623B9
:107C200071F096E8862F70E060E02AF09A95660F72
:107C3000771F881FDAF7880F9695879597F908952B
:107C4000990F0008550FAA0BE0E8FEEF161617066D
:107C5000E807F907C0F012161306E407F50798F0D5
:107C6000621B730B840B950B39F40A2661F0232BEE
:107C7000242B252B21F408950A2609F4A140A6956A
:107C80008FEF811D811D089597F99F6780E870E04F
:107C900060E008959FEF80EC089500240A94161682
:107CA000170618060906089500240A9412161306EA
:107CB000140605060895092E0394000C11F4882378
:107CC00052F0BB0F40F4BF2B11F460FF04C06F5F94
:107CD0007F4F8F4F9F4F089557FD9058440F551F6A
:107CE00059F05F3F71F04795880F97FB991F61F03E
:107CF0009F3F79F087950895121613061406551FB5
:107D0000F2CF4695F1DF08C0161617061806991F20
:107D1000F1CF86957105610508940895E894BB2715
:107D200066277727CB0197F908958ADF08F48FEF4C
:107D300008950BD0C0CFB1DF28F0B6DF18F095233F
:107D400009F0A2CFA7CF1124EACFC6DFA0F3959FF9
:107D5000D1F3950F50E0551F629FF001729FBB2732
:107D6000F00DB11D639FAA27F00DB11DAA1F649FDE
:107D70006627B00DA11D661F829F2227B00DA11D91
:107D8000621F739FB00DA11D621F839FA00D611D17
:107D9000221F749F3327A00D611D231F849F600D38
:107DA000211D822F762F6A2F11249F5750408AF071
:107DB000E1F088234AF0EE0FFF1FBB1F661F771FFD
:107DC000881F91505040A9F79E3F510570F05CCF3D
:107DD000A6CF5F3FECF3983EDCF3869577956795E9
:107DE000B795F795E7959F5FC1F7FE2B880F911D1B
:107DF0009695879597F90895629FD001739FF0013A
:107E0000829FE00DF11D649FE00DF11D929FF00D2A
:107E1000839FF00D749FF00D659FF00D9927729F61
:107E2000B00DE11DF91F639FB00DE11DF91FBD01EC
:107E3000CF0111240895991B79E004C0991F96176A
:107E400008F0961B881F7A95C9F780950895AA1B9C
:107E5000BB1B51E107C0AA1FBB1FA617B70710F035
:107E6000A61BB70B881F991F5A95A9F78095909567
:107E7000BC01CD01089597FB092E07260AD077FD96
:107E800004D0E5DF06D000201AF4709561957F4F8D
:107E90000895F6F7909581959F4F0895A1E21A2EC7
:107EA000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F9E
:107EB000A217B307E407F50720F0A21BB30BE40BEE
:107EC000F50B661F771F881F991F1A9469F7609535
:107ED0007095809590959B01AC01BD01CF010895EF
:107EE00097FB092E05260ED057FD04D0D7DF0AD008
:107EF000001C38F450954095309521953F4F4F4FD9
:107F00005F4F0895F6F790958095709561957F4F36
:107F10008F4F9F4F08952F923F924F925F926F9293
:107F20007F928F929F92AF92BF92CF92DF92EF9209
:107F3000FF920F931F93CF93DF93CDB7DEB7CA1B8A
:107F4000DB0B0FB6F894DEBF0FBECDBF09942A88B5
:107F5000398848885F846E847D848C849B84AA845D
:107F6000B984C884DF80EE80FD800C811B81AA81EA
:107F7000B981CE0FD11D0FB6F894DEBF0FBECDBFB5
:107F8000ED0108952F923F924F925F927F928F92D0
:107F90009F92AF92BF92CF92DF92EF92FF920F9398
:107FA0001F93CF93DF934B01EA016115710519F01F
:107FB000FB0180839183209739F09E01225030404D
:107FC0002332310508F0F4C0A82EB92EF501119125
:107FD0005F017F01812F90E00E940D410097B1F772
:107FE0001D3229F4F50111917F0101E006C01B3219
:107FF00019F4F50111917F0100E0209719F0C031CB
:10800000D105B9F4103381F4F7018081883711F07C
:10801000883551F4F701118182E090E0E80EF91EF5
:108020000260C0E1D0E005C0209719F41033C1F41C
:1080300022C0C830D105F9F0C930D10524F4C230CE
:10804000D10509F507C0CA30D10551F0C031D105BD
:10805000D1F427C0A12CB12CC12CF0E4DF2E26C016
:10806000CAE0D0E0ECECAE2EECECBE2EECECCE2E6A
:10807000ECE0DE2E1BC0C8E0D0E0A12CB12CC12C5E
:1080800070E1D72E13C09E01442737FD4095542F31
:1080900060E070E080E090E80E944E3F59016A0184
:1080A00005C0A12CB12CC12C68E0D62E40E060E0C8
:1080B00070E0CB011E01442437FC4094542C50ED59
:1080C000752E710EE72DEA3070F0212F21542A31E0
:1080D00018F439EC732E06C0212F21562A3130F5C1
:1080E00029EA722E710E272D30E02C173D07F4F48B
:1080F00047FD18C0A616B706C806D90680F0A2012B
:1081000091010E94FC3E670D711D811D911D613022
:10811000F0E07F07F0E08F07F0E89F0710F04FEFE7
:1081200001C041E0F70111917F01C9CF8114910491
:1081300091F0442339F00894E108F108F401F18248
:10814000E08209C001FF1BC0970122503040F401BA
:108150003183208314C047FF12C000FF05C060E0D8
:1081600070E080E090E804C06FEF7FEF8FEF9FE753
:1081700022E230E0309369052093680516C000FFC5
:1081800008C090958095709561957F4F8F4F9F4F58
:108190000CC097FF0AC082E290E09093690580933B
:1081A00068056FEF7FEF8FEF9FE79B01AC0103C086
:1081B00020E030E0A901B901CA01DF91CF911F9100
:1081C0000F91FF90EF90DF90CF90BF90AF909F9076
:1081D0008F907F905F904F903F902F900895FC017B
:1081E00088279927E89421912032E9F3293010F06B
:1081F0002E30C8F32B3241F02D3239F4689404C08C
:108200000E94C141820F911D219120532A30C0F359
:108210001EF4909581959F4F0895911103C180326E
:1082200019F089508550D0F70895FB01DC018D913C
:10823000059080190110D9F3990B0895FB01DC0119
:1082400005900D920020E1F7089549EB53E00E945C
:1082500045410895FB01DC010D900020E9F71197DD
:1082600001900D920020E1F70895FB01DC018D9152
:10827000019080190110D9F3990B0895FB01DC01DD
:1082800001900D920020E1F70895FA01A191B081CB
:10829000009719F41097E1F0CD01DC01CD010D90AC
:1082A000002011F4C00113C0FB012191222319F019
:1082B0002015D9F7F3CFFB012191201519F41E9257
:1082C000119606C02223C1F70D900020A1F7D0011E
:1082D000FA01A193B0830895FB019F01E894423015
:1082E000C4F04532B4F44A3029F497FB1EF490955B
:1082F00081959F4F642F77270E94273F805D8A33A7
:108300000CF0895D8193CB010097A1F716F45DE233
:1083100051931082C9010C941542FA01CF93FF9337
:10832000EF93223044F1253234F5C22FE894CA305D
:1083300049F497FB3EF490958095709561957F4F39
:108340008F4F9F4F2C2F332744275527FF93EF93B1
:108350000E944E3FEF91FF91605D6A330CF0695DC2
:108360006193B901CA01605070408040904051F75C
:1083700016F4CDE2C19310828F919F91CF910C940E
:1083800015427AE0979F902D879F802D910D1124A3
:108390000895DC01CB01FC01F999FECF06C0F2BDC6
:1083A000E1BDF89A319600B40D9241505040B8F7B3
:1083B0000895F999FECF92BD81BDF89A992780B5AD
:1083C0000895A6E1B0E044E050E00C94CB41A8E170
:1083D000B0E042E050E00C94CB41DC01CB0103C0A3
:1083E0002D910E94F84141505040D0F70895262F1A
:1083F000F999FECF1FBA92BD81BD20BD0FB6F8948A
:10840000FA9AF99A0FBE01960895242F0E94F84116
:10841000252F0E94F8410C940D420E94F741272F0E
:108420000C94F841992788270895DC01FC01672FF7
:1084300071917723E1F7329704C07C916D9370833B
:0E8440006291AE17BF07C8F30895F894FFCFFE
:10844E00312E3333003A20001F55C00301FECC01FC
:10845E004B00800080009001F401002D002D007F64
:10846E0000002D002D007F0014010A056D416800EB
:10847E007320006D73003A20004D487A002A2000C8
:10848E00202000560A310A320030002D0030000044
:10849E000000000504444546474905041E1F2021DF
:1084AE002203041B1C1D05043A35363738040433E9
:1084BE0034573204042E2F303104042A2B2C2D0372
:1084CE000429585901020305044D084E090A0904EE
:1084DE0005060700285A50193D00433B5B3E5C3FA2
:1084EE0051524F3537343000353736300035373846
:1084FE0030003538303000353832300035383430D1
:10850E00003538363000A301A801AD01B201B70124
:10851E00BC01C101E803D3001A00FF0000014C03A7
:10852E006800FF0340000000640000006400660065
:10853E00980000009001000090019B0163024A0028
:10854E00A000750029018102D5010100010206A7D4
:10855E0004014469723A004469733A004265613A13
:10856E0000416C743A0050616E3A0054696C3A00E6
:10857E00614C6F6E3A00614C61743A0061416C74EB
:10858E003A00684C6F6E3A00684C61743A0068416C
:10859E006C743A00553A00573A00493A00EE3A00E8
:1085AE00520023636F3F5D3D3D45480D002C004753
:1085BE00504747410028085050FFC40900000000F2
:1085CE00000000008F001E01AD013B02CA025803DD
:1085DE00E603740402058F051B06A7063307BE07C4
:1085EE004808D2085B09E3096B0AF20A780BFD0B07
:1085FE00810C040D860D070E870E060F840F0010DA
:10860E007B10F5106E11E5115B12CF124213B313EE
:10861E0023149214FE146A15D3153B16A1160517D2
:10862E006717C81727188318DE1837198E19E3191C
:10863E00361A871AD61A231B6E1BB61BFD1B411C3E
:10864E00831CC31C001D3C1D751DAB1DE01D121EA1
:10865E00421E6F1E9A1EC31EE91E0D1F2E1F4D1F9A
:10866E00691F841F9B1FB01FC31FD31FE11FEC1F69
:08867E00F51FFB1FFF1F002088
:00000001FF
/NGVideo5_8/tags/v1.33/Hexfiles
Property changes:
Added: bugtraq:number
+true
\ No newline at end of property
/NGVideo5_8/tags/v1.33/KurzanleitungFW.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/NGVideo5_8/tags/v1.33/NGVideo_5_8GHz.pnproj
0,0 → 1,0
<Project name="NGVideo_5_8GHz"><File path="config.h"></File><File path="dogm.c"></File><File path="dogm.h"></File><File path="keys.c"></File><File path="keys.h"></File><File path="lipo.c"></File><File path="lipo.h"></File><File path="main.c"></File><File path="makefile"></File><File path="menue.c"></File><File path="menue.h"></File><File path="messages.c"></File><File path="messages.h"></File><File path="mk.h"></File><File path="ngvideo.c"></File><File path="ngvideo.h"></File><File path="servo.c"></File><File path="servo.h"></File><File path="tools.c"></File><File path="tools.h"></File><File path="tracking.c"></File><File path="tracking.h"></File><File path="usart.c"></File><File path="usart.h"></File><File path="mymath.c"></File><File path="mymath.h"></File></Project>
/NGVideo5_8/tags/v1.33/NGVideo_5_8GHz.pnps
0,0 → 1,0
<pd><ViewState><e p="NGVideo_5_8GHz" x="true"></e></ViewState></pd>
/NGVideo5_8/tags/v1.33/config.h
0,0 → 1,195
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* Tabs: 2 */
/* */
/****************************************************************/
 
#ifndef CONFIG_H_
#define CONFIG_H_
 
/* PINA */
#define VBAT 7 // ADC
#define RSSI1 6 // ADC
#define RSSI0 5 // ADC
#define MUX_IN 4 // OUT
#define MUX_EN 3 // OUT
#define CHANNel_12 2 // OUT
#define CHANNel_11 1 // OUT
#define CHANNel_10 0 // OUT
 
/* PINB */
#define LCD_BACKLIGHT 7 // OUT
#define BEEPER 4 // OUT
#define POWER 3 // OUT
#define CHANNel_02 2 // OUT
#define CHANNel_01 1 // OUT
#define CHANNel_00 0 // OUT
 
/* PINC */
#define KEY_MINUS 7 // IN
#define KEY_PLUS 6 // IN
#define LCD_ENABLE 5 // OUT
#define LCD_REGSELECT 4 // OUT
#define LCD_DATA7 3 // OUT
#define LCD_DATA6 2 // OUT
#define LCD_DATA5 1 // OUT
#define LCD_DATA4 0 // OUT
 
/* PIND */
#define KEY_ENTER 7 // IN
#define HSYNC 6 // IN
#define SERVO1 5 // OUT PWM
#define SERVO2 4 // OUT PWM
#define VSYNC1 3 // IN Int1
#define VSYNC0 2 // IN Int0
#define TX 1 // OUT USART
#define RX 0 // IN USART
/* PORT - DDR */
/* LCD */
#define LCD_BACKLIGHT_PORT PORTB
#define LCD_BACKLIGHT_DDR DDRB
#define LCD_E_PORT PORTC
#define LCD_E_DDR DDRC
#define LCD_RS_PORT PORTC
#define LCD_RS_DDR DDRC
#define LCD_DATA_PORT PORTC
#define LCD_DATA_DDR DDRC
 
#define LCD_LINES 3
#define LCD_COLS 16
 
/* SWITCH */
#define KEY_MP_DDR DDRC
#define KEY_MP_PORT PORTC
#define KEY_MP_PIN PINC
#define KEY_ENTER_DDR DDRD
#define KEY_ENTER_PORT PORTD
#define KEY_ENTER_PIN PIND
 
#define SW_MINUS 7
#define SW_PLUS 6
#define SW_ENTER 5
#define REPEAT_MASK (1<<SW_MINUS | 1<<SW_PLUS | 1<<SW_ENTER)
 
/* zusätzliche Timer in Abhängikeit vom Interrupttimer 0 - Keys */
#define TIMER0_1 50 // x * 10ms für Anzeige UBat
#define TIMER0_2 20 // x * 10ms für Bargraph und Diversity
#define TIMER0_3 2 // x * 10ms für RSSI Diversity
#define TIMER0_4 10 // x * 10ms für wi232 Nachführung Antenne
#define TIMER0_5 1000 // x * 10ms Hintergrundbeleuchtung 10 sekunden Schritte
#define BLINK_PERIOD 12 // abhängig von Tracking_GPS() in Task_0_4(void)
#define T2SECDIV 4000 // Divisor für Timer 2 - Ergebnis in Sekunden
#define M59S59 3599 // 3599 sind 59 Minuten und 59 Sekunden
#define T2PROD_M59S59 (uint32_t)T2SECDIV*M59S59
/* initiale Anfangswerte der Einstellungen */
#define EEP_INITB 73 // irgend ein Wert um beschriebenen EEPROM zu erkennen 75
#define VERSION "1.33"
#define CONTRAST3V 16 // 16 bei LCD 3,3V Bias 1/5 default Wert
#define CONTRAST5V 12 // 12 bei LCD 5V Bias 1/4
#define CONTRAST_MIN 0
#define CONTRAST_MAX 30
#define BACKGR_LIGHT 31 // Hintergrundbeleuchtung immer an
#define BACKGR_LIGHT_MIN 0 // Hintergrundbeleuchtung immer aus
#define BACKGR_LIGHT_MAX 31 // Hintergrundbeleuchtung immer an, z.Z.: Max = 5 Minuten
#define U_OFFSET 85 // um type float o. double zu vermeiden *100
#define U_OFFSET_MIN 0
#define U_OFFSET_MAX 200
#define U_MIN 960 // um type float o. double zu vermeiden *100
#define U_MIN_MIN 550 // auch für Lipo 2s
#define U_MIN_MAX 1400
#define CHANNEL 1 // default Wert
#define CHANNEL_MIN 1
#define CHANNEL_MAX 7
#define AV_SOURCE 0 // av1, av2, diversity
#define AV_SOURCE_MIN 0
#define AV_SOURCE_MAX 2
/* Toleranzen bei den RSSI-Spannungen ausgleichen */
#define UDBM_MIN 460 // RSSI geringste Feldstärke
#define UDBM_MAX 75 // RSSI größte Feldstärke
#define UDBM_KORR_FA 128 // Korrekturfaktor 1 * 128 RSSI1 korrigieren
 
#define RSSI_INV 0 // 0 kein invertiertes RSSI-Signal, 1 invertiert
/* Schwellwert-Einstellungen für Erkennung Sender ein/aus */
#define TX_VALUE_OFF 500 // RSSI > Wert ==> wahr, Sender ist aus
#define TX_VALUE_OFF_MIN 150 // TX-Schwellen für RSSI-min.-Kalibrierung 400/500
#define TX_VALUE_OFF_MAX 999
#define TX_VALUE_ON 400 // RSSI < Wert ==> wahr, Sender ist an
#define TX_VALUE_ON_MIN 150 // TX-Schwellen für RSSI-max.-Kalibrierung 200/400
#define TX_VALUE_ON_MAX 999
/* Servo */
#define SERVO_PAN 0
#define SERVO_TILT 1
#define SERVO_NUM_CHANNELS 2 // Anzahl der angeschlossen Servos max. 2!!!
/* Servokalibrierungen derzeit zu SERVO_STEPS = 255 skaliert */
//prescaler 256
#define SERVO_I0_RIGHT 45 // default Wert, ca. 0,9ms
#define SERVO_I0_RIGHT_MIN 0 // Servokalibrierung Grenze der linken Position
#define SERVO_I0_RIGHT_MAX 100 // SERVO_MIN + SERVO_RIGHT
#define SERVO_I0_LEFT 45 // default Wert, ca. 2,1ms
#define SERVO_I0_LEFT_MIN 0 // Servokalibrierung Grenze der rechten Position
#define SERVO_I0_LEFT_MAX 100 // SERVO_MAX - SERVO_LEFT
#define SERVO_I0_MIDDLE SERVO_STEPS/2
#define SERVO_I0_MIDDLE_MIN SERVO_STEPS/2 - 25
#define SERVO_I0_MIDDLE_MAX SERVO_STEPS/2 + 25
//prescaler 64
#define SERVO_I1_RIGHT 180 // default Wert, ca. 0,9ms
#define SERVO_I1_RIGHT_MIN 0 // Servokalibrierung Grenze der linken Position
#define SERVO_I1_RIGHT_MAX 400 // SERVO_MIN + SERVO_RIGHT
#define SERVO_I1_LEFT 180 // default Wert, ca. 2,1ms
#define SERVO_I1_LEFT_MIN 0 // Servokalibrierung Grenze der rechten Position
#define SERVO_I1_LEFT_MAX 400 // SERVO_MAX - SERVO_LEFT
//#define SERVO_I1_MIDDLE ((SERVO_STEPS + 1) * 4 - 1)/2
#define SERVO_I1_MIDDLE_MIN ((SERVO_STEPS + 1) * 4 - 1)/2 - 100
#define SERVO_I1_MIDDLE_MAX ((SERVO_STEPS + 1) * 4 - 1)/2 + 100
 
#define SERVO_REV 0 // kein Reverse
/* Test Servo */
#define SERVO_PERIODE 20 // default Angabe in ms
#define SERVO_PERIODE_MIN 10 // 10ms
#define SERVO_PERIODE_MAX 30 // 30ms
#define SINGLE_STEP 0 // Einzelschritt aus
#define SINGLE_STEP_MIN 0
#define SINGLE_STEP_MAX 20 // bei prescaler 256, sonst * 4 (von links nach rechts in 9 Abschnitte)
// zwischen den Schritten muss Pause > der Servoperiode sein, sonst keine Aktualisierung
 
#define REPEAT 1
#define REPEAT_MIN 1
#define REPEAT_MAX 100
#define PAUSE 10
#define PAUSE_MIN 4 // mindestens 400ms, da mechanischer Servo-Lauf zur Position berücksichtigt werden muss
#define PAUSE_MAX 20 // Pause pro Links-, Mittel- und Rechtsposition 10*100ms
#define PAUSE_STEP 0
#define PAUSE_STEP_MIN 0 // Pause bei jeden Servoschritt in ms
#define PAUSE_STEP_MAX 200
/* Antennen-Nachführung */
#define TRACKING_MIN 0 // aus, TRACKING_RSSI, TRACKING_GPS, TRACKING_MKCOCKPIT, TRACKING_NMEA
#define TRACKING_MAX 4
/* Antennen-Nachführung per RSSI */
#define TRACKING_HYSTERESE 40 // Hysterese bevor Tracking bei Richtungswechsel anspricht
#define TRACKING_HYST_MIN 0
#define TRACKING_HYST_MAX 100
/* MK Akku-Kapazität */
#define AKKU_NR_MIN 0
#define AKKU_NR_MAX 9
#define AKKU_CAPACITY 2500 // in mAh für Ermittlung verbleibende Flugzeit
#define AKKU_CAPACITY_MIN 1000
#define AKKU_CAPACITY_MAX 6000
#define MK_I_OFFSET 8 // Standart 0.3
#define MK_I_OFFSET_MIN 0 // -0.5 (+0,5A ist auch der vom MK gesendete konstante Offset)
#define MK_I_OFFSET_MAX 20
#define MK_I_OFFSET_5 5 // entspricht -0.5
#define MK_I_FAKTOR 80
#define MK_I_FAKTOR_MIN 30 // Angabe * 100
#define MK_I_FAKTOR_MAX 200
#define MK_W_FAKTOR 80
#define MK_W_FAKTOR_MIN 30
#define MK_W_FAKTOR_MAX 200
 
#endif /* CONFIG_H_ */
/NGVideo5_8/tags/v1.33/dogm.c
0,0 → 1,299
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* using DOGM-Library 1.0. */
/* Copyright (C) 2010-averyfarwaydate Luca Bertoncello */
/* Hartigstrasse, 12 - 01127 Dresden Deutschland */
/* E-Mail: lucabert@lucabert.de, lucabert@lucabert.com */
/* http://www.lucabert.de/ http://www.lucabert.com/ */
/****************************************************************/
 
#include <util/delay.h>
 
#include "config.h"
#include "dogm.h"
#include <avr/pgmspace.h>
#include <string.h>
 
// Instruktionen mit ST7036 4 Bit Mode im "Extension mode"
#define CLEAR_DISPLAY 0b00000001
#define FUNCTION_SET_INIT_0 0b00110011 // 0x30 & 0x30 als nibble
#define FUNCTION_SET_INIT_1 0b00110010 // 0x30 & 0x20 als nibble
#define FUNCTION_SET_INIT_2 0b00101001 // 0x29 4-bit, 2 Zeilen, kein DoubleHeight, InstructionTable1
#define INSTRUCTION_Table_0 0b00101000 // Instruction table 0
#define INSTRUCTION_Table_1 0b00101001 // Instruction table 1
#define SET_CGRAM 0b01000000 // für user defined Char
#define BIAS_SET 0b00010101 // table 1 DB3=Bias 1/4, DB0=3 Zeilen 0b00011101
#define FOLLOWER_CONTROL 0b01101110 // nach Datenblattbsp. 3,3V DOGM bei 5V 0b01101100
#define CONTRAST_SET 0b01110000 // Kontrastwert Bit3 bis Bit0
#define POWER_CONTRAST 0b01010100 // Bit1 und Bit0 entspricht Kontrastwert Bit5 und Bit4 3,3V 0b0101 0100 5V 0b0101 0000
#define DISPLAY_ON 0b00001100
#define ENTRY_MODE 0b00000110 // Cursor Auto-Increment
#define SET_DDRAM_ADDR 0b10000000 // Bit7 bis Bit0 Adresse
#define BS 3 // 0 - 1/5 bias // 1 - 1/4 bias
#define RAB1 1 // select follower amplified ratio
#define BON 2 // set booster circuit on/off bei Power_Contrast
 
#define lcdSetEnable() LCD_E_PORT |= (1<<LCD_ENABLE);
#define lcdClearEnable() LCD_E_PORT &= ~(1<<LCD_ENABLE);
#define lcdSetRegSelect() LCD_RS_PORT |= (1<<LCD_REGSELECT)
#define lcdClearRegSelect() LCD_RS_PORT &= ~(1<<LCD_REGSELECT)
 
uint8_t CursorPos; // ersetzt lesen der aktuellen LCD-CursorPosition
 
/************************************************************************************/
/* sendet ein Nibble (4 Bit) zum LCD-Controller */
/* Parameter: */
/* char data :Byte */
/* */
/************************************************************************************/
void lcdSendNibble(char data)
{
LCD_DATA_PORT |= (data & 0x0f);
LCD_DATA_PORT &= (data | 0xf0);
lcdSetEnable();
_delay_us(2);
lcdClearEnable();
_delay_us(30); // nach Datenblatt > 26,3µs
}
 
/************************************************************************************/
/* sendet 8 Bit (2 Nibble) zum LCD-Controller */
/* Parameter: */
/* char data :Byte */
/* */
/************************************************************************************/
void lcdSendByte(char data)
{
lcdSendNibble(data>>4);
lcdSendNibble(data);
}
 
/************************************************************************************/
/* sendet instruction zum LCD-Controller */
/* Parameter: */
/* char instruction :Byte */
/* */
/************************************************************************************/
void lcdSendInstruction(char instruction)
{
lcdClearRegSelect(); // LCD-RS für Instruktionen
lcdSendByte(instruction);
}
 
/************************************************************************************/
/* sendet ein Zeichen zum LCD-Display */
/* Parameter: */
/* char c :Zeichen */
/* */
/************************************************************************************/
void lcdSendC(char c)
{
lcdSetRegSelect(); // LCD-RS für Daten
lcdSendByte(c);
}
 
/************************************************************************************/
/* sendet ein Zeichen zum LCD-Display */
/* Parameter: */
/* char c :Zeichen */
/* */
/************************************************************************************/
void lcdPutc(char c)
{
lcdSendC(c);
CursorPos++;
if (CursorPos >= (LCD_LINES * LCD_COLS)) CursorPos = 0;
}
 
/************************************************************************************/
/* sendet einen String zum LCD-Display */
/* Parameter: */
/* char *str :Zeichenkette */
/* */
/************************************************************************************/
void lcdPuts(char *str)
{ uint8_t pos = CursorPos / LCD_COLS;
 
while (*str) {
if (*str == '\n') {
if (pos >= LCD_LINES)
pos = 0;
else
pos++;
lcdGotoXY(0, pos);
}
else
lcdPutc(*str);
str++;
}
}
 
/************************************************************************************/
/* stellt eine String mittig auf Display dar */
/* Parameter: */
/* char *str : darzustellende Zeichenkette */
/* uint8_t zle : Display-Zeile */
/* */
/************************************************************************************/
void lcdPutStrMid(char *str, uint8_t zle)
{ int8_t x;
 
lcdClearLine(zle);
x = (LCD_COLS - strlen(str))/2; // Array-String mittig schreiben
lcdGotoXY(x,zle);
lcdPuts(str);
}
 
/************************************************************************/
/* Definieren eines Sonderzeichen */
/* Parameter: */
/* uint8_t lcd_addr : Adresse, 1.Adresse 0 */
/* char *lcd_zeichen: Zeiger auf das 1. Byte der Zeichendefinition */
/* */
/************************************************************************/
void lcdWriteCGRAM(uint8_t lcd_addr, char *lcdChr)
{ int8_t i;
 
lcdSendInstruction(INSTRUCTION_Table_0);
for(i = 0; i < 8; i++)
{
lcdSendInstruction(SET_CGRAM | (lcd_addr * 8 + i)); // CG RAM Adresse
//lcdPutc(lcdChr[i]); // Data Write 8x Pixelzeile
lcdPutc(pgm_read_byte(&lcdChr[i])); // array im Flash
}
lcdSendInstruction(INSTRUCTION_Table_1);
}
 
/************************************************************************/
/* Definieren von n <= 8 Sonderzeichen */
/* Parameter: */
/* SpecialChr_t lcdChr : Array mit Sonderzeichen */
/* uint8_t quantity : Anzahl der zu übertragenen Sonderzeichen */
/* */
/************************************************************************/
void lcdWriteCGRAM_Array(SpecialChr_t *lcdChr, uint8_t quantity)
{
for (uint8_t i = 0; i < quantity; i++)
lcdWriteCGRAM(i, lcdChr[i]); // Sonderzeichen in CGRAM der LCD schreiben
}
 
/************************************************************************************/
/* Löscht Inhalt auf LCD-Display */
/* */
/************************************************************************************/
void lcdClear()
{
lcdSendInstruction(CLEAR_DISPLAY);
CursorPos = 0;
_delay_ms(2);
}
 
/************************************************************************************/
/* Löscht Inhalt ab Cursorposition bis Zeilenende auf LCD-Display */
/* CursorPos bleibt auf ab zu löschenden Zeichen */
/* */
/************************************************************************************/
void lcdClearEOL()
{ uint8_t cp = CursorPos % LCD_COLS;
if (cp > 0) //falls letztes Zeichen auf letzte Spalte geschrieben, nicht nächste Zeile löschen
for (; cp < LCD_COLS; cp++) lcdSendC(' ');
lcdSendInstruction(SET_DDRAM_ADDR | CursorPos);
}
 
/************************************************************************************/
/* Löscht Inhalt der angegebenen Zeile auf LCD-Display */
/* CursorPos bleibt auf Zeilenanfang */
/* */
/************************************************************************************/
void lcdClearLine(uint8_t y)
{
lcdGotoXY(0, y);
for (uint8_t x = 0; x < LCD_COLS; x++) lcdSendC(' ');
lcdSendInstruction(SET_DDRAM_ADDR | CursorPos);
}
 
/************************************************************************************/
/* Setzt Kontrast auf LCD-Display */
/* Parameter: */
/* uint8_t contrast :Wert vo 0 bis max 63 */
/* */
/************************************************************************************/
void lcdContrast(uint8_t dogm, uint8_t contrast)
{ uint8_t power_contrast = POWER_CONTRAST;
 
if(dogm == DOGM5V) {
power_contrast &= ~(1<<BON);
}
lcdSendInstruction(INSTRUCTION_Table_1);
lcdSendInstruction(CONTRAST_SET | (contrast & 0x0F));
lcdSendInstruction(power_contrast | ((contrast>>4) & 0x03));
}
 
//***********************************************************************************/
/* Setzt setzt den Cursor zur Position x/y */
/* Parameter: */
/* uint8_t x, :Position Spalte */
/* uint8_t y, :Position Zeile */
/* */
/************************************************************************************/
void lcdGotoXY(uint8_t x, uint8_t y)
{
if(x > LCD_COLS) x = 0;
if(y > LCD_LINES) y = 0;
CursorPos = y * LCD_COLS + x;
lcdSendInstruction(SET_DDRAM_ADDR | CursorPos);
}
 
/************************************************************************************/
/* Initialisiert den LCD-Controller und der Atmega-Ausgänge */
/* Parameter: */
/* uint8_t dogm :0=3,3V oder 1=5V DOGM */
/* uint8_t contrast :Wert vo 0 bis max 63 */
/* uint8_t cursor :Darstellung des Cursors ein oder 0 aus */
/* uint8_t blink :Cursor blinken, 0 kein blinken */
/* */
/************************************************************************************/
void lcdInit(uint8_t dogm, uint8_t contrast, uint8_t cursor, uint8_t blink)
{ uint8_t bias_set = BIAS_SET;
uint8_t follower_ctrl = FOLLOWER_CONTROL;
uint8_t power_contrast = POWER_CONTRAST;
 
LCD_BACKLIGHT_DDR |= (1<<LCD_BACKLIGHT);
LCD_E_DDR |= (1<<LCD_ENABLE);
LCD_RS_DDR |= (1<<LCD_REGSELECT);
LCD_DATA_DDR |= (1<<LCD_DATA7) | (1<<LCD_DATA6) | (1<<LCD_DATA5) | (1<<LCD_DATA4);
 
lcdClearEnable();
_delay_ms(40); // lt. Datenblatt muss > 40ms nach Power On or ext. Reset
 
if(dogm == DOGM5V) {
follower_ctrl &= ~(1<<RAB1);
bias_set |= (1 << BS);
power_contrast &= ~(1<<BON);
}
 
//Initialisierung für DOGM (mit ST7036) 4 Bit Mode
lcdClearRegSelect(); // LCD-RS für Instruktionen
lcdSendNibble(FUNCTION_SET_INIT_0>>4);
_delay_ms(2); // lt. Datenblatt muss > 1,6ms Pause nach ersten Nibble
lcdSendNibble(FUNCTION_SET_INIT_0);
lcdSendInstruction(FUNCTION_SET_INIT_1);
lcdSendInstruction(FUNCTION_SET_INIT_2);
lcdSendInstruction(bias_set);
lcdSendInstruction(CONTRAST_SET | (contrast & 0x0F));
lcdSendInstruction(power_contrast | ((contrast>>4) & 0x03));
lcdSendInstruction(follower_ctrl);
lcdSendInstruction(INSTRUCTION_Table_0);
lcdSendInstruction(DISPLAY_ON | (cursor & 0x01) << 1 | (blink & 0x01));
lcdClear();
lcdSendInstruction(ENTRY_MODE);
}
/NGVideo5_8/tags/v1.33/dogm.h
0,0 → 1,44
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* using DOGM-Library 1.0. */
/* Copyright (C) 2010-averyfarwaydate Luca Bertoncello */
/* Hartigstrasse, 12 - 01127 Dresden Deutschland */
/* E-Mail: lucabert@lucabert.de, lucabert@lucabert.com */
/* http://www.lucabert.de/ http://www.lucabert.com/ */
/****************************************************************/
 
#ifndef DOGM_H_
#define DOGM_H_
 
#include <avr/io.h>
 
#define DOGM3V 0 // 3,3V DOGM
#define DOGM5V 1 // 5V DOGM
 
typedef char SpecialChr_t[8];
 
void lcdWriteCGRAM(uint8_t lcd_addr, char *lcdChr); // write a char string to CGRAM
void lcdWriteCGRAM_Array(SpecialChr_t *lcdChr, uint8_t quantity); // write a array of char string to CGRAM
void lcdSendInstruction(char instruction);
void lcdPutc(char c);
void lcdPuts(char *str);
void lcdPutStrMid(char *str, uint8_t zle);
void lcdClear(void);
void lcdClearEOL(void);
void lcdClearLine(uint8_t y);
void lcdContrast(uint8_t dogm, uint8_t contrast);
void lcdGotoXY(uint8_t x, uint8_t y);
void lcdInit(uint8_t dogm, uint8_t contrast, uint8_t cursor, uint8_t blink);
 
#define lcdBacklightOn() LCD_BACKLIGHT_PORT |= (1<<LCD_BACKLIGHT);
#define lcdBacklightOff() LCD_BACKLIGHT_PORT &= ~(1<<LCD_BACKLIGHT);
 
#endif /* DOGM_H_ */
/NGVideo5_8/tags/v1.33/keys.c
0,0 → 1,135
 
/************************************************************************/
/* */
/* Debouncing 8 Keys */
/* Sampling 4 Times */
/* With Repeat Function */
/* */
/* Author: Peter Dannegger */
/* danni@specs.de */
/* */
/* Ergänzt: gebad, beschschleunigende Tastenwiederholung */
/* */
/************************************************************************/
 
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 
#include "keys.h"
#include "config.h"
 
ISR( TIMER0_OVF_vect ) // every 10ms
{
static uint8_t ct0, ct1, rpt, timer0_1, timer0_2, timer0_3, timer0_4;
static uint16_t timer0_5 = TIMER0_5;
uint8_t i, key_pin;
 
TCNT0 = 256 - (F_CPU / 1024 * 10e-3) + 0.5; // preload for 10ms 8bit-Timer
 
key_pin = (KEY_MP_PIN & ( (1<<KEY_MINUS) | (1<<KEY_PLUS)));
key_pin |= (KEY_ENTER_PIN & (1<<KEY_ENTER)) >> 2;// move enter bit to sw_enter bit
i = key_state ^ ~key_pin; // key changed ?
ct0 = ~( ct0 & i ); // reset or count ct0
ct1 = ct0 ^ (ct1 & i); // reset or count ct1
i &= ct0 & ct1; // count until roll over ?
key_state ^= i; // then toggle debounced state
key_press |= key_state & i; // 0->1: key press detect
if (key_press & REPEAT_MASK) { // da bei mir alle Tasten in REPEAT_MASK
light_count = 0; // wenn keine Taste gedrückt beginnt Zähler für Hintergrundbeleuchtung aus
timer0_5 = TIMER0_5;
}
if( (key_state & REPEAT_MASK) == 0 ) { // check repeat function
rpt = REPEAT_START; // start delay
key_repeat_next = REPEAT_NEXT; // Wert bestimmt Tasten-Beschleunigung/-Wiederholrate beginnt, mit 200ms
key_counter = REPEAT_ACC_N; // wenn V_REPEAT, nach dem angegebenen Zeichen beschleunigen
}
if( --rpt == 0 ){
rpt = key_repeat_next; // repeat delay
key_rpt |= key_state & REPEAT_MASK;
}
if ( --timer0_1 == 0) {
timer0_1 = TIMER0_1;
task_timer0_1 = 1;
}
if ( --timer0_2 == 0) {
timer0_2 = TIMER0_2;
task_timer0_2 = 1;
}
if ( --timer0_3 == 0) {
timer0_3 = TIMER0_3;
task_timer0_3 = 1;
}
if ( --timer0_4 == 0) {
timer0_4 = TIMER0_4;
task_timer0_4 = 1;
}
if ( --timer0_5 == 0) {
timer0_5 = TIMER0_5;
task_timer0_5 = 1;
}
}
 
///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed. Each pressed key is reported
// only once
//
uint8_t Get_Key_Press( uint8_t key_mask )
{
cli(); // read and clear atomic !
key_mask &= key_press; // read key(s)
key_press ^= key_mask; // clear key(s)
sei();
return key_mask;
}
 
///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed long enough such that the
// key repeat functionality kicks in. After a small setup delay
// the key is reported beeing pressed in subsequent calls
// to this function. This simulates the user repeatedly
// pressing and releasing the key.
//
uint8_t Get_Key_Rpt( uint8_t key_mask )
{
cli(); // read and clear atomic !
key_mask &= key_rpt; // read key(s)
key_rpt ^= key_mask; // clear key(s)
sei();
return key_mask;
}
 
///////////////////////////////////////////////////////////////////
//
uint8_t Get_Key_Short( uint8_t key_mask )
{
cli(); // read key state and key press atomic !
return Get_Key_Press( ~key_state & key_mask );
}
 
///////////////////////////////////////////////////////////////////
//
uint8_t Get_Key_Long( uint8_t key_mask )
{
return Get_Key_Press( Get_Key_Rpt( key_mask ));
}
 
void Key_Speedup_rpt( uint8_t speedup )
{
if (speedup) {
if (key_counter > 0) { // nach x Zeichen wird Wiederholrate kontinuierlich erhöht
cli();
key_counter--;
sei();
}
else {
if (key_repeat_next > 3) { // jetzt beschleunigen, Wert bestimmt die max. Beschleunigung/Wiederholrate
cli(); // kann jedoch nicht kleiner 10ms sein
key_repeat_next -= 2; // noch etwas schneller
sei();
}
}
}
}
/NGVideo5_8/tags/v1.33/keys.h
0,0 → 1,43
 
/************************************************************************/
/* */
/* Debouncing 8 Keys */
/* Sampling 4 Times */
/* With Repeat Function */
/* */
/* Author: Peter Dannegger */
/* danni@specs.de */
/* */
/* Ergänzt: gebad, beschschleunigende Tastenwiederholung */
/* */
/************************************************************************/
 
#ifndef KEYS_H_
#define KEYS_H_
 
#define REPEAT_START 50 // after 500ms
#define REPEAT_NEXT 20 // every 200ms
#define REPEAT_ACC_N 6 // wenn V_REPEAT, nach dem angegebenen Zeichen beschleunigen
 
volatile uint8_t key_state; // debounced and inverted key state:
// bit = 1: key pressed
volatile uint8_t key_press; // key press detect
volatile uint8_t key_rpt; // key long press and repeat
volatile uint8_t key_repeat_next;
volatile uint8_t key_counter;
 
volatile uint8_t task_timer0_1;
volatile uint8_t task_timer0_2;
volatile uint8_t task_timer0_3;
volatile uint8_t task_timer0_4;
volatile uint8_t task_timer0_5;
 
uint8_t Get_Key_Press( uint8_t key_mask );
uint8_t Get_Key_Rpt( uint8_t key_mask );
uint8_t Get_Key_Short( uint8_t key_mask );
uint8_t Get_Key_Long( uint8_t key_mask );
void Key_Speedup_rpt( uint8_t speedup );
 
volatile uint16_t light_count; // muss bei jeden Tastendruck auf 0 gesetzt werdwn
 
#endif /* KEYS_H_ */
/NGVideo5_8/tags/v1.33/lipo.c
0,0 → 1,91
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <avr/eeprom.h>
#include <stdlib.h>
#include <string.h>
#include "ngvideo.h"
#include "dogm.h"
#include "menue.h"
#include "mk.h"
 
uint8_t mk_UBat; // Battery Voltage in 0.1 Volts
uint16_t mk_dUsedCapacity = 0;
uint16_t mk_Ikorr;
 
uint8_t mk_akku_nr = AKKU_NR_MIN;
uint8_t mk_i_offset = MK_I_OFFSET;
uint8_t mk_i_faktor = MK_I_FAKTOR;
uint8_t mk_w_faktor = MK_W_FAKTOR;
mk_current_t mk_current = {0, 0};
mk_lipo_t mk_lipo = {0xff, AKKU_CAPACITY, 0, 0}; // Umk 255 ==> erste Inbetriebnahme keine Nachfrage Akku-Nr.
 
 
void store_LipoData(void)
{ uint32_t tmp_time_on;
 
tmp_time_on = eeprom_read_dword(&ep_mk_lipo[mk_akku_nr].time_on);
mk_timer = 0;
if (tmp_time_on != mk_lipo.time_on) {
if (!MK_Motor_run) mk_lipo.UsedCapacity = mk_dUsedCapacity;
eeprom_write_byte(&ep_mk_lipo[mk_akku_nr].Umk, mk_lipo.Umk);
eeprom_write_word(&ep_mk_lipo[mk_akku_nr].UsedCapacity, mk_lipo.UsedCapacity);
eeprom_write_dword(&ep_mk_lipo[mk_akku_nr].time_on, mk_lipo.time_on);
eeprom_write_block(&mk_current,&ep_mk_current,sizeof(mk_current_t));
Double_Beep(DBEEPWR, DBEEPWRP);
}
}
 
 
#define I_MOTOR_OFF 6 // IR=280mA gemessen; IR vom MK Akku voll 500mA; I Motoren an 1,3A; Grenzwert für Erkennung Akkuwechsel zwischen 500 und 1200mA
void MK_ProcessLipo(NaviData_t *navi_data)
{ char tmp_pmenu[sizeof(pmenu)];
mk_UBat = navi_data->UBat;
// Spannung, Strom, Leistung sofort (ohne Motorstart) lesen
if ((!MK_Motor_run) && (navi_data->Current <= I_MOTOR_OFF) && (mk_UBat > 0)) {
if (mk_UBat < mk_lipo.Umk)
mk_lipo.Umk = mk_UBat; // Bei Ruhestrom, da je nach Last mk_UBat schwankend
else
if (mk_UBat > (mk_lipo.Umk + 4)) { // Bei Ruhestrom kleiner 501mA Akku gewechselt? IR=280mA gemessen, 400mV Hysterese
// Akku des MK wurde gegen einen geladenen ausgetauscht
mk_lipo.Umk = mk_UBat;
mk_timer = 0;
mk_dUsedCapacity = 0;
mk_lipo.UsedCapacity = 0;
mk_lipo.time_on = 0;
lcdClear();
// Funktion wird innhalb Task ausgeführt, auch innerhalb eines anderen Menüpunkes oder Eingabeaufforderung
strcpy(tmp_pmenu, pmenu); // da bei Change_Value(...) ein Menüpunkt zurück
Menu_MK_BatteryChangeNr(); // eingeschobenes Menü, danach aber wieder zur ursprünglichen Anzeige! GPS ruft sich hier noch mal selbst auf!
strcpy(pmenu, tmp_pmenu); // Sonst müsste vorherige aktuelle LCD-Anzeige zwischengespeichert werden.
/* irgendeine Eingabe-While-Schleife (Menue, Change..) zum Verlassen zwingen und mit Jump_Menu(pmenu)
den gleichen Menüpunkt wieder aufrufen */
if (pmenu[0] == '\0')
Displ_Main_Disp();
else
exit_while = 1; // wird nach möglichen while, innerhalb der Fkt. wieder auf 0 gesetzt
store_LipoData();
}
}
mk_timer = 1; // MK-Timer auf on stellen
if (mk_current.Count > 18000) { // ungefär 30 Minuten Mittelwert
mk_current.Sum = (mk_current.Sum * 9)/10; // um 10% verkleinern
mk_current.Count = ((uint32_t)mk_current.Count * 9)/10;
}
if (navi_data->Current >= MK_I_OFFSET_5) { // keine negativen Zwischenergebnisse zulassen
mk_Ikorr = mk_i_offset + (uint32_t)(navi_data->Current - MK_I_OFFSET_5) * mk_i_faktor / 100;
mk_current.Sum += mk_Ikorr;
mk_current.Count++;
}
mk_dUsedCapacity = mk_lipo.UsedCapacity + (uint32_t)navi_data->UsedCapacity * mk_w_faktor / 100;
}
/NGVideo5_8/tags/v1.33/lipo.h
0,0 → 1,33
#ifndef _LIPO_H_
#define _LIPO_H_
 
#include "mk.h"
 
typedef struct {
uint8_t Umk;
uint16_t Capacity;
uint16_t UsedCapacity;
uint32_t time_on;
}mk_lipo_t;
 
typedef struct {
uint32_t Sum;
uint16_t Count;
}mk_current_t;
 
 
extern uint8_t mk_UBat; // Battery Voltage in 0.1 Volts
extern uint16_t mk_dUsedCapacity;
extern uint16_t mk_Ikorr;
 
extern mk_current_t mk_current;
extern uint8_t mk_akku_nr;
extern mk_lipo_t mk_lipo;
extern uint8_t mk_i_offset;
extern uint8_t mk_i_faktor;
extern uint8_t mk_w_faktor;
 
void store_LipoData(void);
void MK_ProcessLipo(NaviData_t *navi_data);
 
#endif
/NGVideo5_8/tags/v1.33/main.c
0,0 → 1,111
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <string.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
#include "ngvideo.h"
#include "menue.h"
#include "servo.h"
#include "config.h"
#include "dogm.h"
#include "keys.h"
#include "usart.h"
#include "tracking.h"
#include "mymath.h"
 
int main(void)
{ uint8_t ep_reset = 1;
uint8_t val;
 
_delay_ms(100); // Einschaltstörungen unterdrücken
 
DDRB |= (1<<POWER);
PORTB &= ~(1<<POWER); //NOT(SHDN) LT1776
 
// switch init
KEY_MP_DDR &= ~((1<<KEY_MINUS) | (1<<KEY_PLUS));
KEY_ENTER_DDR &= ~((1<<KEY_ENTER));
// auf default rücksetzen - Tasten direkt lesen, da noch kein Interrupt
if( !(KEY_MP_PIN & ((1<<KEY_MINUS) | (1<<KEY_PLUS))))
--ep_reset;
 
Init_EEPROM(ep_reset);
 
// auf DOGM 5V/3,3V rück-/setzen - Tasten direkt lesen, da noch kein Interrupt
if(!((KEY_ENTER_PIN & (1<<KEY_ENTER)) || (KEY_MP_PIN & (1<<KEY_PLUS))))
Set_DOGM_Version();
 
DDRA |= (1<<CHANNel_12) | (1<<CHANNel_11) | (1<<CHANNel_10) | (1<<MUX_IN) | (1<<MUX_EN);
DDRB |= (1<<BEEPER) | (1<<CHANNel_02) | (1<<CHANNel_01) | (1<<CHANNel_00);
Set_Channel(channel);
ch_stored = channel;
PORTA &= ~(1<<MUX_EN); // MUX enable
 
ADC_Init();
// Timer 0 für Tasten und Anzeigen(Task's)
TCCR0B = (1<<CS02)|(1<<CS00); // divide by 1024
TIMSK0 |= 1<<TOIE0; // 8 bit Timer/Counter0 Overflow Interrupt aktiviert
 
// Timer 2 für Diversity vSync und GPS-Tracking MK Datensatz senden
TCCR2B = (1<<CS21) | (1<<CS20); // divide by 64
TIMSK2 |= 1<<TOIE2; // 8 bit Timer/Counter2 Overflow Interrupt aktiviert
 
// Interrupt für sync - RX-Umschaltung bei Diversity
DDRD &= ~((1<<VSYNC1) | (1<<VSYNC0));
//EICRA |= (1<<ISC11) | (1<<ISC10) | (1<<ISC01) | (1<<ISC00);// interrupt on INT0 and INT1 pin rising edge
EICRA |= (1<<ISC11) | (1<<ISC01); // interrupt on INT0 and INT1 pin falling edge
Set_AV_Source(av_source); // MUX auf av-x setzen; EIMSK Int0 und Int1 für Sync-Diversity ein
 
DDRD |= (1<<SERVO1) | (1<<SERVO2); // Servoports als Ausgang
if (tracking > TRACKING_MIN) // Servos sind nur bei Tracking und Servokalibrierung zugeschaltet
servoInit(SERVO_PERIODE);
 
// LCD init
lcdInit(dogm_vers, contrast, 0, 0);
lcd_BackgrLight_On();
lcdWriteCGRAM_Array(lcdSpecialChr, 7);
 
Displ_Version();
Double_Beep(DBEEPVERS, DBEEPVERSP);
 
sei();
 
if (language == NO_LANGUAGE) {
language = GERMAN; // Beim Einschalten pmenu[] vordefiniert mit "0"
Menu_Language();
}
 
Displ_Main_Disp();
 
while(1)
{
Task_0_1();
Task_0_2();
Tasks_invisible();
if (!bat_low) {
if (Get_Key_Short( 1<<SW_ENTER )) {
m_pkt = 1; // 0 wäre "zurück", so aber ins Untermenü immer erster Menüpunkt
Menu_Main();
}
val = Change_Value_plmi(channel, CHANNEL_MIN, CHANNEL_MAX, 0, 0, Displ_Channels, 1, C_REPEAT);
if (val != channel) { // nicht bei jeden Schleifendurchlauf Set_Channel()
channel = val;
Set_Channel(channel);
}
if (Get_Key_Long( 1<<SW_ENTER ) && tracking == TRACKING_NMEA) setNMEAdir(); // direction
}
}
}
/NGVideo5_8/tags/v1.33/makefile
0,0 → 1,412
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
# Released to the Public Domain
# Please read the make user manual!
#
# Additional material for this makefile was submitted by:
# Tim Henigan
# Peter Fleury
# Reiner Patommel
# Sander Pool
# Frederik Rouleau
# Markus Pfaff
#
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
#
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
# 4.07 or greater).
#
# make program = Download the hex file to the device, using avrdude. Please
# customize the avrdude settings below first!
#
# make filename.s = Just compile filename.c into the assembler code only
#
# To rebuild project do "make clean" then "make all".
#
 
# MCU name
MCU = atmega644
 
## 16500000 is for attiny45/85/461/861 only (RC+PLL mode)
#CLK = 12000000UL
#CLK = 15000000UL
#CLK = 16000000UL
#CLK = 16500000UL
CLK = 20000000UL
#CLK = 18432000UL
 
#Fuse settings for ATmega644
ifeq ($(MCU), atmega644)
FUSE_BITS = -u -U lfuse:w:0xef:m -U hfuse:w:0xd9:m -U efuse:w:0xfd:m
HEX_FILE_NAME = MEGA644
endif
 
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
 
# Target file name (without extension).
TARGET = Hexfiles/NGVideo_$(HEX_FILE_NAME)
 
# 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
 
# If there is more than one source file, append them above, or modify and
# uncomment the following:
SRC = main.c ngvideo.c menue.c dogm.c keys.c servo.c usart.c tools.c tracking.c lipo.c mymath.c
 
 
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
 
 
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
EXTRAINCDIRS =
 
 
# Optional compiler flags.
# -g: generate debugging information (for GDB, or for COFF conversion)
# -O*: optimization level
# -f...: tuning, see gcc manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create assembler listing
CFLAGS = -O$(OPT) \
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
-Wall -Wstrict-prototypes \
-Wa,-adhlns=$(<:.c=.lst) \
$(patsubst %,-I%,$(EXTRAINCDIRS))
 
 
# Set a "language standard" compiler flag.
# Unremark just one line below to set the language standard to use.
# gnu99 = C99 + GNU extensions. See GCC manual for more information.
#CFLAGS += -std=c89
#CFLAGS += -std=gnu89
#CFLAGS += -std=c99
CFLAGS += -std=gnu99
 
 
 
# Optional assembler flags.
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
 
 
 
# Optional linker flags.
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
 
 
 
# Additional libraries
 
# Minimalistic printf version
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
 
# Floating point printf version (requires -lm below)
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
 
# -lm = math library
LDFLAGS += -lm
 
 
 
 
# Programming support using avrdude. Settings and variables.
 
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
 
#AVRDUDE_PROGRAMMER = AVR910
#AVRDUDE_PROGRAMMER = stk200
AVRDUDE_PROGRAMMER = USBasp
 
AVRDUDE_PORT = usb # programmer connected to USB port
#AVRDUDE_PORT = com1 # programmer connected to serial device
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port
 
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex $(FUSE_BITS)
AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
 
#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -b 115200 -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
 
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE += -y
 
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_FLAGS += -V
 
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_FLAGS += -v -v
 
 
 
 
# ---------------------------------------------------------------------------
 
# Define directories, if needed.
DIRAVR = c:/WinAVR
#DIRAVR = C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR Toolchain\avr
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib
 
 
# Define programs and commands.
SHELL = sh
 
CC = avr-gcc
 
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
 
 
# Programming support using avrdude.
AVRDUDE = avrdude
 
 
REMOVE = rm -f
COPY = cp
 
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
 
 
 
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
 
 
 
 
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
 
# Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
 
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -DF_CPU=$(CLK) -I. $(CFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
 
 
 
# Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
$(TARGET).lss $(TARGET).sym sizeafter finished end
 
 
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
 
finished:
@echo $(MSG_ERRORS_NONE)
 
end:
@echo $(MSG_END)
@echo
 
 
# Display size of file.
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
 
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
 
 
 
# Display compiler version information.
gccversion :
@$(CC) --version
 
 
 
 
# Convert ELF to COFF for use in debugging / simulating in
# AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
 
 
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
 
 
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
 
 
 
 
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
 
 
 
 
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
 
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
 
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
 
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
avr-nm -n $< > $@
 
 
 
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
 
 
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
 
 
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
 
 
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
 
 
 
 
 
 
# Target: clean project.
clean: begin clean_list finished end
 
clean_list :
@echo
@echo $(MSG_CLEANING)
# $(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
 
 
# Automatically generate C source code dependencies.
# (Code originally taken from the GNU make user manual and modified
# (See README.txt Credits).)
#
# Note that this will work with sh (bash) and sed that is shipped with WinAVR
# (see the SHELL variable defined above).
# This may not work with other shells or other seds.
#
%.d: %.c
set -e; $(CC) -MM $(ALL_CFLAGS) $< \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
[ -s $@ ] || rm -f $@
 
 
# Remove the '-' if you want to see the dependency files generated.
-include $(SRC:.c=.d)
 
 
 
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
clean clean_list program
 
/NGVideo5_8/tags/v1.33/menue.c
0,0 → 1,1860
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>
 
#include "config.h"
#include "ngvideo.h"
#include "keys.h"
#include "menue.h"
#include "servo.h"
#include "tracking.h"
#include "messages.c"
#include "dogm.h"
#include "tools.h"
#include "usart.h"
#include "ngvideo.h"
 
typedef uint8_t scr_menu_t[SCROLL_MAIN_MAX];
char pmenu[6] = {"0"}; // Zuordnung Menü Programmgliederung zu hinterlegten Funktionen
uint8_t m_pkt; // um bei Rücksprung auf ursprünglichen Arrayeintrag(Menüpunkt), Scroll_Menu zeigen
uint8_t servo_nr; // zwischen Servo 1 und 2 wird nur mit global servo_nr unterschieden
uint8_t chrxs; // zum Laden lcdSpecialChrLs oder lcdSpecialChrRs
uint8_t exit_while = 0; // unabhängige Task (z.B: Menu_MK_BatteryChangeNr() - Aufruf) kann Eingabe while-Schleife beenden, wenn 1
 
// Menügliederung im Flash belassen
const char cmdStr0[] PROGMEM = "0";
const char cmdStr01[] PROGMEM = "01";
const char cmdStr02[] PROGMEM = "02";
const char cmdStr03[] PROGMEM = "03";
const char cmdStr031[] PROGMEM = "031";
const char cmdStr032[] PROGMEM = "032";
const char cmdStr033[] PROGMEM = "033";
const char cmdStr034[] PROGMEM = "034";
const char cmdStr035[] PROGMEM = "035";
const char cmdStr0351[] PROGMEM = "0351";
const char cmdStr0352[] PROGMEM = "0352";
const char cmdStr04[] PROGMEM = "04";
const char cmdStr05[] PROGMEM = "05";
const char cmdStr051[] PROGMEM = "051";
const char cmdStr052[] PROGMEM = "052"; // zwischen Servo 1 und 2 wird danach
const char cmdStr0521[] PROGMEM = "0521"; // mit global servo_nr unterschieden
const char cmdStr0522[] PROGMEM = "0522";
const char cmdStr0523[] PROGMEM = "0523";
const char cmdStr0524[] PROGMEM = "0524";
const char cmdStr053[] PROGMEM = "053";
const char cmdStr0531[] PROGMEM = "0531";
const char cmdStr0532[] PROGMEM = "0532";
const char cmdStr0533[] PROGMEM = "0533";
const char cmdStr0534[] PROGMEM = "0534";
const char cmdStr06[] PROGMEM = "06";
const char cmdStr061[] PROGMEM = "061";
const char cmdStr062[] PROGMEM = "062";
const char cmdStr0621[] PROGMEM = "0621";
const char cmdStr0622[] PROGMEM = "0622";
const char cmdStr0623[] PROGMEM = "0623";
const char cmdStr0624[] PROGMEM = "0624";
const char cmdStr0625[] PROGMEM = "0625";
const char cmdStr063[] PROGMEM = "063";
const char cmdStr064[] PROGMEM = "064";
const char cmdStr07[] PROGMEM = "07";
const char cmdStr071[] PROGMEM = "071";
const char cmdStr072[] PROGMEM = "072";
const char cmdStr08[] PROGMEM = "08";
const char cmdStr081[] PROGMEM = "081";
const char cmdStr082[] PROGMEM = "082";
const char cmdStr083[] PROGMEM = "083";
const char cmdStr0831[] PROGMEM = "0831";
const char cmdStr0832[] PROGMEM = "0832";
const char cmdStr0833[] PROGMEM = "0833";
const char cmdStr0834[] PROGMEM = "0834";
const char cmdStr0835[] PROGMEM = "0835";
const char cmdStr09[] PROGMEM = "09";
const char cmdStr0d[] PROGMEM = "0:"; // wird nur bei Tracking RSSI oder GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
const char cmdStr0e[] PROGMEM = "0;"; // wird nur bei Tracking GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
const char cmdStr0e1[] PROGMEM = "0;1"; // nach '9' (0x39) folgt ':' (0x3a) ';' (0x3b)
const char cmdStr0e2[] PROGMEM = "0;2";
const char cmdStr0e3[] PROGMEM = "0;3";
const char cmdStr0e4[] PROGMEM = "0;4";
const char cmdStr0e5[] PROGMEM = RXTimeStr;
 
command_table_t command_table[] PROGMEM = // Befehls-Tabelle
{
{cmdStr0, Menu_Main},
{cmdStr01, Menu_AV_Source},
{cmdStr02, Menu_RX_Channel},
{cmdStr03, Menu_RSSI_Calibr},
{cmdStr031, Menu_RSSI_min},
{cmdStr032, Menu_RSSI_min_all},
{cmdStr033, Menu_RSSI_max},
{cmdStr034, Menu_RSSI_invert},
{cmdStr035, Menu_TX_identyfy},
{cmdStr0351, Menu_TX_status_off},
{cmdStr0352, Menu_TX_status_on},
{cmdStr04, Menu_Language},
{cmdStr05, Menu_Servo_Calibr},
{cmdStr051, Menu_Servo_Steps},
{cmdStr052, Menu_Servo1}, // zwischen Servo 1 und 2 wird danach
{cmdStr0521, Menu_Servo1_rev}, // mit global servo_nr unterschieden
{cmdStr0522, Menu_Servo1_left},
{cmdStr0523, Menu_Servo1_right},
{cmdStr0524, Menu_Servo1_middle},
{cmdStr053, Menu_Servo2},
{cmdStr0531, Menu_Servo2_rev},
{cmdStr0532, Menu_Servo2_left},
{cmdStr0533, Menu_Servo2_right},
{cmdStr0534, Menu_Servo2_middle},
{cmdStr06, Menu_Servo_Test},
{cmdStr061, Menu_Test_PulseWidth},
{cmdStr062, Menu_Test_Continuous},
{cmdStr0621, Menu_Test_Start},
{cmdStr0622, Menu_Test_SingleStep},
{cmdStr0623, Menu_Test_Repeat},
{cmdStr0624, Menu_Test_Pause},
{cmdStr0625, Menu_Test_Pause_Step},
{cmdStr063, Menu_Test_ServoNr},
{cmdStr064, Menu_Test_Frame},
{cmdStr07, Menu_lcd},
{cmdStr071, Menu_lcd_Contrast},
{cmdStr072, Menu_lcd_Backgr_Light},
{cmdStr08, Menu_Battery},
{cmdStr081, Menu_Low_U_Setup},
{cmdStr082, Menu_U_Offset},
{cmdStr083, Menu_MK_Battery},
{cmdStr0831, Menu_MK_BatteryNr},
{cmdStr0832, Menu_MK_BatteryCapacity},
{cmdStr0833, Menu_MK_I_Offset},
{cmdStr0834, Menu_MK_I_Faktor},
{cmdStr0835, Menu_MK_W_Faktor},
{cmdStr09, Menu_Tracking_Ant},
{cmdStr0d, Menu_Tracking_Option}, // wird nur bei Tracking RSSI oder GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
{cmdStr0e, Menu_GPS_Display}, // wird nur bei Tracking GPS oder NMEA eingeblendet - SCROLL_MAIN_MAX wird geändert
{cmdStr0e1, Menu_GPS_Display_FLAG}, // nach '9' (0x39) folgt ':' (0x3a)
{cmdStr0e2, Menu_GPS_Display_FLAG},
{cmdStr0e3, Menu_GPS_Display_FLAG},
{cmdStr0e4, Menu_GPS_Display_FLAG},
{cmdStr0e5, Menu_GPS_Displ_RX_Time} // bei NMEA wird dieser Menüpunkt um 1 vorgezogen (anstelle GPS_MISC)
};
 
 
uint8_t Change_Value(uint16_t *val, uint16_t min_val, uint16_t max_val, uint8_t fl_pos, Displ_Fnct_t Displ_Fnct);
 
 
/**************************************************************/
/* */
/* Steuerung der Menüs */
/* */
/**************************************************************/
 
/************************************************************************************/
/* sucht nach übergebenen String in der Kommandotabelle und springt zum daneben */
/* stehenden Menü-Programm */
/* Parameter: */
/* char *pmenu :zu suchender String in Kommandotabelle */
/* */
/************************************************************************************/
void Jump_Menu(char *pmenu)
{ uint8_t i;
void (*func)(void);
 
if (pmenu[0] != '\0'){
for (i=0; i < sizeof(command_table) / sizeof(command_table_t); i++) {
// Ist das der gesuchte String?
if (!(strcmp_P(pmenu, (char*)pgm_read_word(&(command_table[i].menu_nr))))) {
func = (void(*)(void))pgm_read_word(&(command_table[i].fp));
func();
break;
}
}
}
}
 
/************************************************************************************/
/* */
/* Abfrage Short- oder Long-Enter */
/* verbleibt in Abfrage bis Enter betätigt; Rückgabe => Short-Enter True/False */
/* */
/************************************************************************************/
uint8_t Long_Enter(void)
{
Tasks_invisible(); // Dadurch ist Doppelaufruf von MK-GPS möglich!!! Nur bei Menu_MK_BatteryChangeNr()
// falls Akku leer ==> Menü verlassen und Anzeige __ACCU_LOW
U_Messen_cmp(DISABLE_BTIMER);
if (Get_Key_Long( 1<<SW_ENTER ) || bat_low) {
pmenu[0] ='\0'; // direkt in das Hauptprogramm
return 1;
}
else return 0;
}
 
uint8_t Short_Enter(void)
{ uint8_t ret;
 
// bis Short- oder Long-Enter, auch Akku leer
while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && !exit_while);
lcdClear();
if (pmenu[0] == '\0') Displ_Main_Disp(); else Beep(BEEPENTER); // bei ShortEnter Beep
ret = (pmenu[0] != '\0') && !exit_while;
exit_while = 0;
return(ret); // ShortEnter bringt 1 zurück
}
 
/************************************************************************************/
/* */
/* Unterprogramm vom Scroll_Menu(...) stellt Menüpunkte dar */
/* Parameter: */
/* scr_menu_t scr_menu : Array mit Strings der Menüanzeige */
/* uint8_t scr_idx : ausgewählter Menüpunkt */
/* uint8_t scroll_max : scrollen bis Wert */
/* */
/************************************************************************************/
void Displ_Scroll_Menu(scr_menu_t scr_menu, uint8_t scr_idx)
{ uint8_t i;
if (scr_idx > 0) scr_idx--; else scr_idx = scr_menu[0];
for (i = 0; i < LCD_LINES; i++) {
lcdGotoXY(2, i); // LCD Beginn x-Position, 2 Zeichen rechts eingerückt
lcdPuts(Msg(scr_menu[scr_idx + 1]));
lcdClearEOL(); // ab Stringende bis zum Zeilenende löschen; LCD löschen flackert sonst zu sehr
if (scr_idx < scr_menu[0]) scr_idx++; else scr_idx = 0;
}
}
 
/************************************************************************************/
/* */
/* Unterprogramm vom Scroll_Menu(...) und Change_Value(...) */
/* bei Rücksprung auf ursprünglichen Menüpunkt zeigen */
/* Parameter: */
/* uint8_t l : Strinlänge von pmenue */
/* */
/************************************************************************************/
void return_m_pkt(uint8_t l)
{
if (l > 1) { // bei l=1 und Subtraktion 1 wird sowieso Displ_Main_Disp() ausgeführt und dort pmenu[0] = '\0' gesetzt
l--;
m_pkt = pmenu[l] - '0'; // um bei Rücksprung auf ursprünglichen Arrayeintrag(Menüpunkt) zeigen
pmenu[l] ='\0'; // auf letztes Zeichen Stringende schreiben
}
else Displ_Main_Disp();
}
 
/************************************************************************************/
/* */
/* scrollt Menü über Mehrzeilige LCD */
/* */
/* Taste<Enter> lang springt in Hauptanzeige, kurz geht in den angewälten Menüpunkt*/
/* Taste<+> eine Zeile nach oben */
/* Taste<-> eine Zeile nach unten */
/* Parameter: */
/* scr_menu_t scr_menu : Array mit Strings der Menüanzeige */
/* uint8_t scroll_max : scrollen bis Wert */
/* uint8_t scr_idx : Index für array von Displ_Scroll_Menu(...) */
/* */
/************************************************************************************/
void Scroll_Menu(scr_menu_t scr_menu, uint8_t scr_idx)
{ uint8_t l;
 
lcdClear();
lcdGotoXY(0, 1);
lcdPutc(MARKER_SELECT); // '>>'
Displ_Scroll_Menu(scr_menu, scr_idx);
// bis Menueeingabe bestätigt oder zum vorherigen Menue
while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && !exit_while)
{
// >> Menueauswahl nach oben
if( Get_Key_Press( 1<<SW_PLUS ) || Get_Key_Rpt( 1<<SW_PLUS )) {
if (scr_idx > 0) scr_idx--; else scr_idx = scr_menu[0];
Displ_Scroll_Menu(scr_menu, scr_idx);
}
// >> Menueauswahl nach unten
if( Get_Key_Press( 1<<SW_MINUS ) || Get_Key_Rpt( 1<<SW_MINUS )) {
if (scr_idx < scr_menu[0]) scr_idx++; else scr_idx = 0;
Displ_Scroll_Menu(scr_menu, scr_idx);
}
}
 
lcdClear();
if (exit_while) // wegen Aufruf Menu_MK_BatteryChangeNr() in Task
m_pkt = scr_idx; // nach Task Menu_MK_BatteryChangeNr() wieder zum ursprünlichen Anzeigepunkt
else {
l = strlen(pmenu);
if ((scr_idx == 0) || (l == 0)) // long Enter wird durch l == 0 brücksichtigt
return_m_pkt(l); // um bei Rücksprung auf ursprünglichen Menüpunkt zu zeigen oder Displ_Main_Disp()
else {
m_pkt = 1; // 0 wäre "zurück", so aber ins Untermenü immer erster Menüpunkt
pmenu[l] = scr_idx + '0'; // nächsten MenueIndex anhängen 1 oder 2 oder ...
pmenu[++l] ='\0';
Beep(BEEPENTER);
}
}
exit_while = 0;
}
 
/************************************************************************************/
/* */
/* Ändern der Werte mit Tasten +,- und Anzeige */
/* z.B. für U-Offset, Batterie leer Eingabe ... */
/* */
/* Parameter: */
/* uint16_t val :zu ändernter Wert */
/* uint16_t min_val, max_val :min, max Grenze Wert ändern darf */
/* uint8_t posX, posY :Darstellung Wert xPos, YPos auf LCD */
/* Displ_Fnct_t Displ_Fnct :Pointer auf Funktion Addr. Display(val) */
/* uint8_t cycle :0 begrenzt Anzeige bei man_val, bzw. max_val */
/* :1 springt nach max_val auf min_val und umgedreht */
/* uint8_t vrepeat :beschleunigte Repeat-Funktion aus/ein */
/* uint16_t Change_Value_plmi(...) :Rückgabe geänderter Wert */
/* */
/************************************************************************************/
uint16_t Change_Value_plmi(uint16_t val, uint16_t min_val, uint16_t max_val, uint8_t posX, uint8_t posY, \
Displ_Fnct_t Displ_Fnct, uint8_t cycle, uint8_t vrepeat)
{
// >> Menueauswahl nach oben
if( Get_Key_Press( 1<<SW_PLUS ) || Get_Key_Rpt( 1<<SW_PLUS )){
if (val < max_val) {
val++;
Key_Speedup_rpt(vrepeat); // beschleunigte Repeat-Funktion
}
else
if (cycle) val = min_val;
lcdGotoXY(posX, posY); // lcd Position Wert
Displ_Fnct(val); // geänderten Wert darstellen, je nach Menüpunkt
}
// >> Menueauswahl nach unten
if( Get_Key_Press( 1<<SW_MINUS ) || Get_Key_Rpt( 1<<SW_MINUS )) {
if (val > min_val) {
val--;
Key_Speedup_rpt(vrepeat); // beschleunigte Repeat-Funktion
}
else
if (cycle) val = max_val;
lcdGotoXY(posX, posY); // noch einmal lcd Position, sonst zum Teil + und - gleichzeitig, Anzeige verrutscht
Displ_Fnct(val); // geänderten Wert darstellen, je nach Menüpunkt
}
return(val);
}
 
/************************************************************************************/
/* */
/* Ändern der Werte mit Tasten +,- repetierend; (long)Entertaste und Anzeige */
/* z.B. für U-Offset, Batterie leer Eingabe ... */
/* */
/* Parameter: */
/* uint16_t *val :zu ändernter Wert */
/* uint16_t min_val, max_val :min, max Grenze Wert ändern darf */
/* uint8_t fl_pos :Bit 7 beschleunigte Repeat-Funktion aus/ein */
/* Bit 6 zyklische Werteänderung aus/ein */
/* Bit 4-5 z.Z. ohne Funktion */
/* Bit 0-3 Wert xPos auf LCD */
/* Displ_Fnct_t Displ_Fnct :Pointer auf Funktion Addr. Display(val) */
/* uint8_t Change_Value(...) :Rückgabe geändert ergibt TRUE */
/* */
/************************************************************************************/
// Bei Bedarf könnte einfach innerhalp fl_pos auch noch pos_y (Bit 4-5) übergeben werden
uint8_t Change_Value(uint16_t *val, uint16_t min_val, uint16_t max_val, uint8_t fl_pos, Displ_Fnct_t Displ_Fnct)
{ uint16_t tmp_val;
 
tmp_val = *val;
lcdGotoXY(fl_pos & POSXMASK, ZLE_VAL); // Position Wert
Displ_Fnct(tmp_val); // initiale Wertdarstellung, je nach Menüpunkt
if (pmenu[0] =='\0') strcpy(pmenu, "0"); // sonst wird eventuell nachfolgende while-Schleife nicht ausgeführt
// bis Menueeingabe bestätigt oder zum vorherigen Menue
while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && !exit_while)
*val = Change_Value_plmi(*val, min_val, max_val, fl_pos & POSXMASK, ZLE_VAL, Displ_Fnct, fl_pos & (1<<CYCLE), fl_pos & (1<<V_REPEAT));
lcdClear();
if (exit_while) {
exit_while = 0;
*val = tmp_val;
}
else
return_m_pkt(strlen(pmenu)); // um bei Rücksprung auf ursprünglichen Menüpunkt zeigen oder Displ_Main_Disp()
return(tmp_val != *val);
}
 
/**************************************************************/
/* */
/* LCD-Darstellungen der Menüs */
/* Zur Unterstützung der Auswahl werden einige Einstellungen */
/* sofort ausgeführt. Z.B.: Kontrast, Servo-Endausschlag */
/* */
/**************************************************************/
 
/************************************************************************************/
/* zeigt Menü- * Überschrift * auf erste Zeile mittig auf Display an */
/* Parameter: */
/* uint8_t message : index (MSG_) der darzustellenden Zeichenkette */
/* */
/************************************************************************************/
void Displ_Title(uint8_t message)
{ uint8_t l;
uint8_t x = 0;
 
l = strlen(Msg(message));
if ( LCD_COLS > l) x = (LCD_COLS - l)/2;
if (x > 1) {
lcdGotoXY(x - 2, 0);
lcdPuts("* ");
lcdPuts(Msg(message));
lcdPutc(' ');
}
else {
lcdGotoXY(0, 0);
lcdPutc('*');
lcdGotoXY(x, 0);
lcdPuts(Msg(message));
lcdGotoXY(LCD_COLS - 1, 0);
}
lcdPutc('*');
}
 
/************************************************************************************/
/* zeigt bei Programmstart Firmware- und DOGM-Version auf Display an */
/* */
/************************************************************************************/
void Displ_Version(void)
{
lcdGotoXY(0, 0);
lcdPuts(Msg(MSG_VERSION1));
if (dogm_vers == DOGM3V)
lcdPuts(Msg(MSG_UHW33V));
else
lcdPuts(Msg(MSG_UHW5V));
lcdPuts(Msg(MSG_VERSION2));
delay_ms100x(30);
lcdClear();
}
 
/************************************************************************************/
/* zeigt auszuwählenden/-gewählten Kanal und Frequenz auf Display an */
/* Parameter: */
/* uint16_t k :Index anzuzeigender Wert = Kanal + 0x30 als Char, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Channels(uint16_t k)
{ char *channels[] = {"5740", "5760","5780", "5800", "5820", "5840", "5860"};
 
lcdPutc(k+0x30);
lcdPuts(": ");
lcdPuts(channels[k-1]);
lcdPuts("MHz");
}
 
/************************************************************************************/
/* zeigt Source AV1, AV2 oder Diversity zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t q :Index anzuzeigender Wert, */
/* unint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_AV_Source(uint16_t q)
{ uint8_t av_src_table[] = {MSG_AV1, MSG_AV2, MSG_DIVERSITY};
 
lcdPutStrMid(Msg(av_src_table[q]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt Tracking-Varianten zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t q :Index anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_sel_Tracking(uint16_t q)
{ uint8_t track_sel_table[] = {MSG_OFF, MSG_TRACK_RSSI, MSG_TRACK_GPS, MSG_TRACK_MKCOCKPIT, MSG_TRACK_NMEA};
 
lcdPutStrMid(Msg(track_sel_table[q]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt Senden der OSD-Daten Anforderung zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t q :Index anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_track_TX(uint16_t q)
{ uint8_t track_TX_table[] = {MSG_OFF, MSG_TRACK_TX_ON};
 
lcdPutStrMid(Msg(track_TX_table[q]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt einen max. 3-stelligen Integerwert auf Display an */
/* Parameter: */
/* uint16_t val :anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Format_Int(uint16_t val)
{
lcdPuts(my_itoa(val, 3, 0, 0));
}
 
/************************************************************************************/
/* zeigt den Kontrastwert auf Display an mit sofortiger Änderung */
/* Parameter: */
/* uint16_t val :anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Set_Contrast(uint16_t val)
{
Displ_Format_Int(val);
lcdContrast(dogm_vers, val);
}
 
/************************************************************************************/
/* zeigt die Zeit zur Abschaltung der LCD-Hintergrundbeleuchtung an */
/* Parameter: */
/* uint16_t val :anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Backgr_Light(uint16_t val)
{ char str[5];
 
switch(val) {
case BACKGR_LIGHT_MIN : lcdPuts(Msg(MSG_LIGHT_OFF));
break;
case BACKGR_LIGHT_MAX : lcdPuts(Msg(MSG_LIGHT_ON));
break;
default : itoa (val * 10, str, 10);
lcdPutc(' ');
lcdPuts(str);
lcdPuts(Msg(MSG_SEC));
}
lcdClearEOL();
}
 
/************************************************************************************/
/* zeigt ein oder aus zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t val :0 = aus oder 1 = ein, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Off_On(uint16_t val)
{
if (val == 0) lcdPuts(Msg(MSG_OFF)); else lcdPuts(Msg(MSG_ON));
}
 
/************************************************************************************/
/* zeigt Servoschritte zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t val :0 = 255 oder 1 = 1023, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Steps(uint16_t val)
{ uint8_t servo_step_table[] = {MSG_STEPS_255, MSG_STEPS_1023};
 
lcdPutStrMid(Msg(servo_step_table[val]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt Servo-Anschlagposition links auf Display an */
/* mit sofortiger Wirkung auf Servo */
/* Parameter: */
/* uint16_t val :anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Min(uint16_t val)
{ uint16_t steps = 0;
 
Displ_Format_Int(val);
servoSet_min(servo_nr, val); // Wert setzen damit nachfolgend die
if (servo[servo_nr].rev) steps = ServoSteps();
servoSetPosition(servo_nr, steps); // Änderung direkt am Servo sichtbar ist
}
 
/************************************************************************************/
/* zeigt Servo-Anschlagposition rechts auf Display an */
/* mit sofortiger Wirkung auf Servo */
/* Parameter: */
/* uint16_t val :anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Max(uint16_t val)
{ uint16_t steps = ServoSteps();
 
Displ_Format_Int(val);
servoSet_max(servo_nr, val); // Wert setzen damit nachfolgend die
if (servo[servo_nr].rev) steps = 0;
servoSetPosition(servo_nr, steps); // Änderung direkt am Servo sichtbar ist
}
 
/************************************************************************************/
/* zeigt Servo-Anschlagposition Mitte auf Display an */
/* mit sofortiger Wirkung auf Servo */
/* Parameter: */
/* uint16_t val :anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Mid(uint16_t val)
{ int16_t mid_val;
mid_val = val - ServoSteps()/2;
lcdPuts(my_itoa(mid_val, 4, 0, 0));
servoSet_mid(servo_nr, val); // Wert setzen damit nachfolgend die
servoSetPosition(servo_nr, ServoSteps()/2); // Änderung direkt am Servo sichtbar ist
}
 
/************************************************************************************/
/* zeigt zu testende Servonummer zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t val :0 = Servo 1 oder 1 = Servo 2, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_ServoNr(uint16_t val)
{
if (val == 0) lcdPuts(Msg(MSG_SERVO1)); else lcdPuts(Msg(MSG_SERVO2));
}
 
 
/************************************************************************************/
/* zeigt Servoausschlag in ms, in % und als Bargraph auf Display an */
/* Parameter: */
/* int16_t PosProzent : aktuell eingestellte Position vom 0-Punkt (Mitte) aus */
/* int16_t range : maximaler absoluter Ausschlag vom 0-Punkt aus */
/* */
/************************************************************************************/
// leerer Rahmen für Bar
char* empty_Bar(void)
{ static char tmp_empty[LCD_COLS];
uint8_t i;
tmp_empty[0] = '\0'; // '['
for (i = 1; i < 15; i++)
tmp_empty[i] = '\x07';
tmp_empty[i] = '\x06'; // ']'
return(tmp_empty);
}
 
void draw_bar(int16_t PosProzent, int16_t range, uint8_t zle)
{ int8_t i, sp_quad, sp_ch;
int8_t lz = 8;
char* bar;
bar = empty_Bar(); // leerer Rahmen für Bar
sp_quad = abs(PosProzent) * 7 / range; // Anzahl der vollen Kästchen
 
sp_ch = (abs(PosProzent) -(range * sp_quad / 7)) * 35 / range; // Unterteilung Kästchen in 6 senkrechte Striche
if (sp_ch > 4) sp_ch = 4; // bei 28 (7*4) wäre keine Korrektur erforderlich aber so kontinuierlicher
if (PosProzent < 0){
lz -= sp_quad; // Position für volles Kästchen bei Linksausschlag
if (sp_ch > 0) bar[lz-1] = sp_ch; // vor erstes volles Kästchen Kästchenunterteilung schreiben
} // Unterteilung Kästchen der 4 senkrechte Striche nach Bar (0 und 5 entfallen)
else
if (sp_ch > 0) bar[lz+sp_quad] = sp_ch;// nach lezten vollen Kästchen Kästchenunterteilung schreiben
 
for (i = 0; i < sp_quad; i++)
bar[i+lz] = '\x05'; // volle Kästchen schreiben
lcdGotoXY(0,zle);
for (uint8_t i = 0; i < LCD_COLS; i++) lcdPutc(bar[i]);// kpl. Bar zum Display
}
 
uint16_t calc_range(int16_t PosProzent, int16_t min, int16_t max, int16_t mid)
{ uint16_t range;
 
if (PosProzent < 0) {
range = mid - min;
if (chrxs == CHRRS) { // falls Richtung geändert, anderen Zeichensatz laden
chrxs = CHRLS;
lcdWriteCGRAM_Array(lcdSpecialChrLs, 5);// LCD-Char mit Rahmensymbole vom Graph
}
}
else {
range = max - mid;
if (chrxs == CHRLS) { // falls Richtung geändert, anderen Zeichensatz laden
lcdWriteCGRAM_Array(lcdSpecialChrRs, 5);// LCD-Char mit Rahmensymbole vom Graph
chrxs = CHRRS;
}
}
return(range);
}
 
void Displ_PulseWidth(uint16_t val)
{ int16_t PosProzent, range;
uint16_t Pos_us;
char me[3] = {"ms"};
 
servoSetPositionRaw(servo_nr, val);
PosProzent = val - steps_pw[sIdxSteps].mid;
range = calc_range(PosProzent, steps_pw[sIdxSteps].min, steps_pw[sIdxSteps].max, steps_pw[sIdxSteps].mid);
draw_bar(PosProzent, range, 2); // auf 3. Display-Zeile
PosProzent = (int32_t)1000 * PosProzent / range;
lcdGotoXY(1, 1);
Pos_us = pw_us(val); // Zeit in µs bei x Servoschritte
if (Pos_us < 1000) {
me[0] = 'u'; // soll 'µ' => programmierbarer Zeichensatz zu klein
lcdPuts(" ");
Displ_Format_Int(Pos_us);
}
else {
lcdPuts(my_itoa(Pos_us, 5, 3, 3));
}
lcdPuts(me);
lcdGotoXY(8, 1);
lcdPuts(my_itoa(PosProzent, 6, 1, 1));
lcdPutc('%');
}
 
/************************************************************************************/
/* zeigt Pausenlänge der Links-, Mittel- und Rechtsposition auf Display an */
/* Parameter: */
/* uint16_t val : Zeit in 1ms * 100 */
/* */
/************************************************************************************/
void Displ_Pause(uint16_t val)
{
if (val > 9) {
lcdPuts(my_itoa(val, 3, 1, 1));
lcdPuts("s ");
}
else {
Displ_Format_Int(val * 100);
lcdPuts("ms");
}
}
 
/************************************************************************************/
/* zeigt aus oder Integerwert auf Display an */
/* Parameter: */
/* uint16_t val : val = 0 ==> aus, sont Integerwert */
/* */
/************************************************************************************/
void Displ_Off_Format_Int(uint16_t val)
{
if (val == 0)
lcdPutStrMid(Msg(MSG_OFF), ZLE_VAL);
else {
lcdGotoXY(5,ZLE_VAL);
Displ_Format_Int(val);
lcdPutc(' ');
}
}
 
/************************************************************************************/
/* zeigt aus oder Pausenzeit zwischen 2 Servoschritte auf Display an */
/* Parameter: */
/* uint16_t val : val = 0 ==> aus, sont Integerwert */
/* */
/************************************************************************************/
void Displ_Pause_Step(uint16_t val)
{
Displ_Off_Format_Int(val);
if (val > 0) {
lcdGotoXY(8,ZLE_VAL);
lcdPuts("ms");
}
}
/************************************************************************************/
/* zeigt Baudrate für COM bei MKCockpit zur Auswahl auf Display an */
/* Parameter: */
/* uint16_t q :Index anzuzeigender Wert, */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Baudrate(uint16_t q)
{ char str[7];
 
ltoa(getBaud(q), str, 10);
lcdPutStrMid(str, ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt aktive Empfängerzeiten auf Display an */
/* */
/************************************************************************************/
void Displ_RX_Time(void)
{
lcdGotoXY(6, 1);
Displ_TimeHMS(rxcount0);
lcdGotoXY(6, 2);
Displ_TimeHMS(rxcount1);
}
 
/************************************************************************************/
/* zeigt eingestellte Akku-Kapazität des MK auf Display an */
/* Parameter: */
/* uint16_t val :Akku-Kapazität in 50mAh Schritte */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_MK_Capacity(uint16_t val)
{
lcdPuts(my_itoa(val * 50, 4, 0, 0));
lcdPuts("mAh");
}
 
/************************************************************************************/
/* zeigt Offset (Korrektur Ruhestrom) für Strom des MK auf Display an */
/* Parameter: */
/* uint16_t val :Korrekturfaktor */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_I_Offset(uint16_t val)
{
lcdPuts(my_itoa((int8_t)val - MK_I_OFFSET_5,4,1,1));
lcdPutc('A');
}
 
 
/************************************************************************************/
/* zeigt Korrekturfaktor für Strom und Arbeit des MK auf Display an */
/* Parameter: */
/* uint16_t val :Korrekturfaktor */
/* uint16_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Faktor_2Nk(uint16_t val)
{
lcdPuts(my_itoa(val,4,2,2));
}
 
/************************************************************************************/
/* zeigt den Marker in Hauptdarstellung auf selektierten RX an */
/* d Diversity, << fester RX */
/* Parameter: */
/* uint8_t p :x-Position des Markers */
/* uint8_t marker :Markerzeichen z.B.:'' oder 'd' oder 's' */
/* */
/************************************************************************************/
void Displ_AV_Mark(uint8_t p, char marker)
{
if (p < 2) {
lcdGotoXY(15,2 - p); // da p immer neue Position 0 oder 1
lcdPutc(' '); // bisherigen AVx-, Diversity-Marker löschen
lcdGotoXY(15,p + 1); // an neuer Positon
lcdPutc(marker); // übergebenes Markerzeichen darstellen
}
else { // falls beim Einschalten Diversity auf aktiv, keine Marker
lcdGotoXY(15,1);
lcdPutc(' ');
lcdGotoXY(15,2);
lcdPutc(' ');
}
}
 
/************************************************************************************/
/* Hauptanzeige unter Berücksichtigung von VBat */
/* */
/************************************************************************************/
void SetAndDispl_AV_Mark(void)
{ char marker;
 
marker = av_source < DIVERSITY? MARKER_AV : MARKER_RSSI; // wird nur bei gesetzten Diversity überschrieben
Displ_AV_Mark(sw_avx, marker);
}
 
void Displ_Main_Disp(void)
{
pmenu[0] ='\0'; // bei Direktansprung z.B. von Menu_RSSI_min() erforderlich
lcdClear();
if (!bat_low) {
lcdClear();
Displ_Channels(channel);
lcdGotoXY(LCD_COLS - 1, 0);
lcdPuts("V\n1\n2");
SetAndDispl_AV_Mark();
Displ_VBat(); // muss zuletzt stehen
}
else {
lcdPutStrMid(Msg(MSG_ACCU_LOW), 0);
}
}
 
 
 
/**************************************************************/
/* */
/* Menüs */
/* */
/**************************************************************/
 
/**************************/
/* */
/* Haupmenü */
/* */
/**************************/
void Menu_Main(void)
{ scr_menu_t scr_main_menu = {SCROLL_MAIN_MAX-4, MSG_RETURN, MSG_AV_SOURCE, MSG_RX_CHANNEL, MSG_RSSI_CALIBR, MSG_LANGUAGE, \
MSG_SERVO_CALIBR, MSG_TEST_SERVO, MSG_LCD , MSG_BATTERY, MSG_TRACKING, 0, MSG_GPS_DISPLAY};
 
switch(tracking) {
case TRACKING_RSSI: scr_main_menu[11] = MSG_TRACK_SERVO_HYTERESE;
scr_main_menu[0]++; // SCROLL_MAIN_MAX erhöhen
break;
case TRACKING_GPS: scr_main_menu[11] = MSG_TRACK_TX_OSD_DATA;
scr_main_menu[0] += 2; // SCROLL_MAIN_MAX erhöhen, zusätzliche Anzeige zu GPS MSG_GPS_DISPLAY
break;
case TRACKING_NMEA: scr_main_menu[0]++; // SCROLL_MAIN_MAX erhöhen, zusätzliche Anzeige zu GPS
case TRACKING_MKCOCKPIT: scr_main_menu[0]++; // SCROLL_MAIN_MAX erhöhen
scr_main_menu[11] = MSG_COM;
break;
}
strcpy(pmenu, "0");
Scroll_Menu(scr_main_menu, m_pkt); // pmenu global
Jump_Menu(pmenu); //gewähltes Untermenü anspringen oder nur Return
}
 
/**************************/
/* */
/* AV-Quelle */
/* */
/**************************/
void Menu_AV_Source(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_AV_SOURCE);
tmp_val = av_source;
if (Change_Value(&tmp_val, AV_SOURCE_MIN, AV_SOURCE_MAX, 3, Displ_AV_Source)) { // pmenu global
cli();
av_source = tmp_val;
eeprom_write_byte(&ep_av_source, av_source);
Double_Beep(DBEEPWR, DBEEPWRP);
sw_avx = Set_AV_Source(av_source);
if (pmenu[0] == '\0') // sonst ist AV-Source marker bei long Enter im Hauptdisplay nicht aktuallisiert
SetAndDispl_AV_Mark();
sei();
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Kanal */
/* */
/**************************/
void Menu_RX_Channel(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_RX_CHANNEL);
tmp_val = channel;
if (Change_Value(&tmp_val, CHANNEL_MIN, CHANNEL_MAX, 3, Displ_Channels) || (tmp_val != ch_stored)) { // pmenu global
channel = tmp_val;
ch_stored = tmp_val;
eeprom_write_byte(&ep_channel, channel);
Double_Beep(DBEEPWR, DBEEPWRP);
Set_Channel(channel);
if (pmenu[0] == '\0') { // sonst ist channel im Hauptdisplay nicht aktuallisiert
lcdGotoXY(0,0);
Displ_Channels(channel); // da erst jetzt die Variable für main_display geändert ist!
}
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* RSSI */
/* */
/**************************/
void Menu_RSSI_Calibr(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_7] = {SCROLL_MAX_7-2, MSG_RETURN, MSG_RSSI_MIN, MSG_RSSI_MIN_ALL, MSG_RSSI_MAX, MSG_RSSI_INVERT, MSG_TX_IDENTIFY};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void AdviceTX(uint8_t msg)
{ char str[20];
 
strcpy(str, Msg(MSG_TX));
strcat(str, Msg(msg));
lcdPutStrMid(str, 1);
lcdPutStrMid(Msg(MSG_CONTINUE), 2);
}
 
void Menu_RSSI_min(void)
{
Displ_Title(MSG_RSSI_MIN);
AdviceTX(MSG_TX_OFF);
if (Short_Enter()) { // pmenu global
RSSI_Min_Calibrate(0, bar_udbm);
Displ_Main_Disp(); // da erst jetzt die Variable für main_display geändert ist!
}
else
Jump_Menu(pmenu);
}
 
void Displ_RSSImin_allError(char *str_ch)
{ char str[LCD_COLS + 1];
lcdClear();
strcpy(str, Msg(MSG_CALIB));
strcat(str, "-");
strcat(str, Msg(MSG_ERROR));
lcdPutStrMid(str,0);
lcdPutStrMid(Msg(MSG_RX_CHANNEL),1);
lcdPutStrMid(str_ch, 2);
delay_ms100x(30);
}
 
void Menu_RSSI_min_all(void)
{ char not_cal[15];
uint8_t f = 0;
 
Displ_Title(MSG_RSSI_MIN_ALL);
AdviceTX(MSG_TX_OFF);
if (Short_Enter()) { // pmenu global
for ( uint8_t i = 1; i <= CHANNEL_MAX; i++) {
Set_Channel(i);
if (!RSSI_Min_Calibrate(i, bar_udbm)) {
not_cal[f++] = i + 0x30;
not_cal[f++] = ',';
}
}
Set_Channel(channel);
Double_Beep(DBEEPWR, DBEEPWRP);
if (f > 0) { // Konnten einige Kanäle nicht auf RSSI-Min kalibiert werden?
not_cal[--f] = '\0'; // letzes Komma durch Stringende ersetzen
Displ_RSSImin_allError(not_cal);
}
Displ_Main_Disp();
}
else
Jump_Menu(pmenu);
}
 
void Menu_RSSI_max(void)
{
Displ_Title(MSG_RSSI_MAX);
AdviceTX(MSG_TX_ON);
if (Short_Enter()) { // pmenu global
RSSI_Max_Calibrate(bar_udbm);
Displ_Main_Disp();
}
else
Jump_Menu(pmenu);
}
 
 
/* Wichtig bei invertierten RX-RSSI */
void Menu_RSSI_invert(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_RSSI_INVERT);
tmp_val = rssi_inv;
if (Change_Value(&tmp_val, 0, 1, 6, Displ_Off_On)) { // pmenu global; RSSI invertieren gibt es nur 0=off, 1=on
rssi_inv = tmp_val;
eeprom_write_byte(&ep_rssi_inv, rssi_inv);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
 
}
 
 
/* Schwellwert-Einstellungen für Erkennung Sender ein/aus */
void Displ_TX_status(uint16_t val) // für Min_Calibrate
{
Displ_Off_Format_Int(val);
lcdGotoXY(strlen(Msg(MSG_TX_STATUS)), 2);
if (ADC_Read_inv(RSSI0) + ADC_Read_inv(RSSI1) > val)
lcdPuts(Msg(MSG_OFF));
else
lcdPuts(Msg(MSG_ON));
}
 
void Menu_TX_identyfy(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_6] = {SCROLL_MAX_4-2, MSG_RETURN, MSG_TX_STATUS_OFF, MSG_TX_STATUS_ON};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_TX_status_off(void) // für Min_Calibrate
{ uint16_t tmp_val;
 
Displ_Title(MSG_TX_STATUS_OFF);
lcdGotoXY(0, 2);
lcdPuts(Msg(MSG_TX_STATUS));
tmp_val = tx_value_off;
if (Change_Value(&tmp_val, TX_VALUE_OFF_MIN, TX_VALUE_OFF_MAX, 5|(1<<V_REPEAT), Displ_TX_status)) { // pmenu global
tx_value_off = tmp_val;
eeprom_write_word(&ep_tx_value_off, tx_value_off);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_TX_status_on(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_TX_STATUS_ON);
lcdGotoXY(0, 2);
lcdPuts(Msg(MSG_TX_STATUS));
tmp_val = tx_value_on;
if (Change_Value(&tmp_val, TX_VALUE_ON_MIN, TX_VALUE_ON_MAX, 5|(1<<V_REPEAT), Displ_TX_status)) { // pmenu global
tx_value_on = tmp_val;
eeprom_write_word(&ep_tx_value_on, tx_value_on);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Sprache */
/* */
/**************************/
void Displ_Language(uint16_t i)
{ uint8_t lanuage_table[3] = {MSG_GERMAN, MSG_ENGLISH, MSG_FRENCH};
 
lcdPutStrMid(Msg(lanuage_table[i]), ZLE_VAL);
}
 
void Menu_Language(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_LANGUAGE);
tmp_val = language;
language = eeprom_read_byte(&ep_language); // damit bei Erstinbetriebnahme Sprache gespeichert wird NO_LANGUAGE
Change_Value(&tmp_val, GERMAN, LAST_LANG, 3, Displ_Language); // pmenu global
if (tmp_val != language) {
language = tmp_val;
eeprom_write_byte(&ep_language, language);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Servo-Einstellungen */
/* */
/**************************/
void Menu_Servo_Calibr(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_5] = {SCROLL_MAX_5 - 2, MSG_RETURN, MSG_SERVO_STEPS, MSG_SERVO1, MSG_SERVO2};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void NoTracking_ServosOff(void)
{
if (tracking == TRACKING_MIN) {
delay_ms100x(4); // sonst werden Impulse bereits vor erreichen der Servo-default-Stellung abgeschaltet
servoOff(); // Servos sind nur zum Tracking oder bei Kalibrierung eingeschaltet
}
}
 
void Servo_NewValues(uint8_t idx_presc)
{
for (uint8_t i = 0; i < SERVO_NUM_CHANNELS; i++) {
if (idx_presc == STEPS_255) { // Werte umrechnen für Prescaler = 256
servo[i].min /= 4;
servo[i].max /= 4;
servo[i].mid /= 4;
}
else { // Werte umrechnen für Prescaler = 64
servo[i].min *= 4;
servo[i].max *= 4;
servo[i].mid = (servo[i].mid + 1) * 4 - 1;
}
servoSet_min(i, servo[i].min);
servoSet_max(i, servo[i].max);
servoSet_mid(i, servo[i].mid);
eeprom_write_block(&servo[i],&ep_servo[i],sizeof(servo_t));
}
// Vorberechnung von ServoChannels[channel].duty
servoSetDefaultPos(); // Ausgangsstellung beider Servos
}
 
void Menu_Servo_Steps(void)
{ uint16_t tmp_val;
Displ_Title(MSG_SERVO_STEPS);
lcdGotoXY(8, ZLE_VAL);
tmp_val = sIdxSteps;
if (Change_Value(&tmp_val, STEPS_255, STEPS_1023, 5, Displ_Servo_Steps)) { // pmenu global
cli();
sIdxSteps = tmp_val;
eeprom_write_byte(&ep_sIdxSteps, sIdxSteps);
Servo_NewValues(sIdxSteps); // hier ist der neue Index anzugeben!
servoInit(SERVO_PERIODE);
sei();
NoTracking_ServosOff();
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Servo1(void)
{ uint8_t scr_servo_menu[SCROLL_MAX_6] = {SCROLL_MAX_6 - 2, MSG_RETURN, MSG_SERVO1_REVERSE, MSG_CALIB1_LEFT, MSG_CALIB1_RIGHT, MSG_CALIB1_MIDDLE};
Scroll_Menu(scr_servo_menu, m_pkt); // pmenu global
servo_nr = 0;
Jump_Menu(pmenu);
}
 
void Menu_Servo2(void)
{ uint8_t scr_servo_menu[SCROLL_MAX_6] = {SCROLL_MAX_6 - 2, MSG_RETURN, MSG_SERVO2_REVERSE, MSG_CALIB2_LEFT, MSG_CALIB2_RIGHT, MSG_CALIB2_MIDDLE};
Scroll_Menu(scr_servo_menu, m_pkt); // pmenu global
servo_nr = 1;
Jump_Menu(pmenu);
}
 
uint8_t Servo_tmp_on(uint8_t servo_period)
{ uint8_t tmp_tracking = tracking;
 
tracking = 0; // Servopositionierung durch tracking abschalten
if (tracking == TRACKING_MIN) servoInit(servo_period); // falls aus, Servos einschalten
lcdGotoXY(0, 0); // lcd Cursor vorpositionieren
return(tmp_tracking);
}
 
void Servo_tmp_Original(uint8_t track)
{
servoSetDefaultPos();
tracking = track; // ursprünglicher Wert Tracking aus, RSSI oder GPS
NoTracking_ServosOff(); // Servos sind nur zum Tracking oder bei Kalibrierung eingeschaltet
Jump_Menu(pmenu);
}
 
void Menu_Servo_rev(void)
{ uint16_t tmp_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
tmp_val = servo[servo_nr].rev;
if (Change_Value(&tmp_val , 0, 1, 6, Displ_Off_On)) { // pmenu global; reverse gibt es nur 0=off, 1=on
servo[servo_nr].rev = tmp_val ;
servoSet_rev(servo_nr, tmp_val );
eeprom_write_block(&servo[servo_nr],&ep_servo[servo_nr],sizeof(servo_t));
Double_Beep(DBEEPWR, DBEEPWRP);
}
Servo_tmp_Original(tmp_tracking);
}
 
void Menu_Servo1_rev(void)
{
Displ_Title(MSG_SERVO1_REVERSE);
Menu_Servo_rev();
}
 
void Menu_Servo2_rev(void)
{
Displ_Title(MSG_SERVO2_REVERSE);
Menu_Servo_rev();
}
 
void Menu_Servo_left(void)
{ uint16_t tmp_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
servoSetPosition(servo_nr, ServoSteps()); // Linkssanschlag um Kalibrierung am Servo zu sehen
tmp_val = servo[servo_nr].max;
if (Change_Value(&tmp_val, servo_limit[sIdxSteps][LEFT].min, servo_limit[sIdxSteps][LEFT].max, 6|(1<<V_REPEAT), Displ_Servo_Max)) { // pmenu global
servo[servo_nr].max = tmp_val;
eeprom_write_block(&servo[servo_nr],&ep_servo[servo_nr],sizeof(servo_t));
servoSet_mid(servo_nr, servo[servo_nr].mid); // Mittelposition muss sich bei Ausschlagsänderung verschieben
Double_Beep(DBEEPWR, DBEEPWRP);
}
Servo_tmp_Original(tmp_tracking);
}
 
void Menu_Servo1_left(void)
{
Displ_Title(MSG_CALIB1_LEFT);
Menu_Servo_left();
}
 
void Menu_Servo2_left(void)
{
Displ_Title(MSG_CALIB2_LEFT);
Menu_Servo_left();
}
 
void Menu_Servo_right(void)
{ uint16_t tmp_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
servoSetPosition(servo_nr, 0); // Rechtsanschlag um Kalibrierung am Servo zu sehen
tmp_val = servo[servo_nr].min;
if (Change_Value(&tmp_val, servo_limit[sIdxSteps][RIGHT].min, servo_limit[sIdxSteps][RIGHT].max, 6|(1<<V_REPEAT), Displ_Servo_Min)) { // pmenu global
servo[servo_nr].min = tmp_val;
eeprom_write_block(&servo[servo_nr],&ep_servo[servo_nr],sizeof(servo_t));
servoSet_mid(servo_nr, servo[servo_nr].mid); // Mittelposition muss sich bei Ausschlagsänderung verschieben
Double_Beep(DBEEPWR, DBEEPWRP);
}
Servo_tmp_Original(tmp_tracking);
}
 
void Menu_Servo1_right(void)
{
Displ_Title(MSG_CALIB1_RIGHT);
Menu_Servo_right();
}
 
void Menu_Servo2_right(void)
{
Displ_Title(MSG_CALIB2_RIGHT);
Menu_Servo_right();
}
 
void Menu_Servo_middle(void)
{ uint16_t tmp_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on(SERVO_PERIODE);
servoSetPosition(servo_nr, ServoSteps()/2); // Mittelposition um Kalibrierung am Servo zu sehen
tmp_val = servo[servo_nr].mid;
if (Change_Value(&tmp_val, servo_limit[sIdxSteps][MIDDLE].min, servo_limit[sIdxSteps][MIDDLE].max, 5|(1<<V_REPEAT), Displ_Servo_Mid)) { // pmenu global
servo[servo_nr].mid = tmp_val;
eeprom_write_block(&servo[servo_nr], &ep_servo[servo_nr], sizeof(servo_t));
Double_Beep(DBEEPWR, DBEEPWRP);
}
Servo_tmp_Original(tmp_tracking);
}
 
void Menu_Servo1_middle(void)
{
Displ_Title(MSG_CALIB1_MIDDLE);
Menu_Servo_middle();
}
 
void Menu_Servo2_middle(void)
{
Displ_Title(MSG_CALIB2_MIDDLE);
Menu_Servo_middle();
}
 
/**************************/
/* */
/* Servos-Tests */
/* */
/**************************/
void Menu_Servo_Test(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_6] = {SCROLL_MAX_6 - 2, MSG_RETURN, MSG_PULSE_WIDTH, MSG_CONTINOUS, MSG_SERVO, MSG_FRAME};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
servo_nr = eeprom_read_byte(&ep_servo_nr);
Jump_Menu(pmenu);
}
 
void Menu_Test_Frame(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_FRAME);
lcdGotoXY(8, ZLE_VAL);
lcdPuts("ms");
tmp_val = servo_frame;
if (Change_Value(&tmp_val, SERVO_PERIODE_MIN, SERVO_PERIODE_MAX, 5|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu global
servo_frame = tmp_val;
eeprom_write_byte(&ep_servo_frame, servo_frame);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Test_ServoNr(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_SERVO);
tmp_val = servo_nr;
if (Change_Value(&tmp_val, 0, 1, 4, Displ_ServoNr)) { // pmenu global; es gibt nur 0=Servo1, 1=Servo2
servo_nr = tmp_val;
eeprom_write_byte(&ep_servo_nr, servo_nr);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
// Dieser Test im raw-Modus ohne Anschlagkalibrierung (normiert) z.B.: für Modelleinstellungen ohne Empfänger
void Menu_Test_PulseWidth(void)
{ uint8_t tmp_tracking;
uint16_t tmp_val;
tmp_tracking = Servo_tmp_on(servo_frame);
lcdWriteCGRAM_Array(lcdSpecialChrLs, 8); // LCD-Char mit Rahmensymbole vom Graph
chrxs = CHRLS; // verhindert wiederholtes Lesen bereits geladener LCD-Char
Displ_Title(MSG_PULSE_WIDTH);
tmp_val = steps_pw[sIdxSteps].mid;
Change_Value(&tmp_val, steps_pw[sIdxSteps].min, steps_pw[sIdxSteps].max, 4|(1<<V_REPEAT), Displ_PulseWidth); // pmenu global
lcdWriteCGRAM_Array(lcdSpecialChr, 7); // LCD-Char für Bargraph zurückschreiben
cli();
servoInit(SERVO_PERIODE);
sei();
Servo_tmp_Original(tmp_tracking);
}
 
void Menu_Test_Continuous(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_7] = {SCROLL_MAX_7 - 2, MSG_RETURN, MSG_START, MSG_SINGLE_STEP, MSG_REPEAT, MSG_PAUSE, MSG_PAUSE_STEP};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_Test_SingleStep(void)
{uint16_t tmp_val;
 
Displ_Title(MSG_SINGLE_STEP);
tmp_val = single_step;
if (Change_Value(&tmp_val, SINGLE_STEP_MIN, SINGLE_STEP_MAX, 5|(1<<V_REPEAT), Displ_Off_Format_Int)) { // pmenu global
single_step = tmp_val;
eeprom_write_byte(&ep_single_step, single_step);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Test_Repeat(void)
{uint16_t tmp_val;
 
Displ_Title(MSG_REPEAT);
tmp_val = repeat;
if (Change_Value(&tmp_val, REPEAT_MIN, REPEAT_MAX, 5|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu global
repeat = tmp_val;
eeprom_write_byte(&ep_repeat, repeat);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Test_Pause(void)
{uint16_t tmp_val;
 
Displ_Title(MSG_PAUSE);
tmp_val = pause;
if (Change_Value(&tmp_val, PAUSE_MIN, PAUSE_MAX, 5|(1<<V_REPEAT), Displ_Pause)) { // pmenu global
pause = tmp_val;
eeprom_write_byte(&ep_pause, pause);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Test_Pause_Step(void)
{uint16_t tmp_val;
 
Displ_Title(MSG_PAUSE_STEP);
tmp_val = pause_step;
if (Change_Value(&tmp_val, PAUSE_STEP_MIN, PAUSE_STEP_MAX, 5|(1<<V_REPEAT), Displ_Pause_Step)) { // pmenu global
pause_step = tmp_val;
eeprom_write_byte(&ep_pause_step, pause_step);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
int8_t calc_dir(uint8_t idx, int16_t *Position)
{ uint8_t nextIdx;
int8_t nextDir = 1;
 
nextIdx = idx;
if ((idx + 1) < POSIDX_MAX)
nextIdx++;
else
nextIdx = 0;
if (Position[PosIdx[idx]] > Position[PosIdx[nextIdx]]) nextDir = -1;
return(nextDir);
}
 
void Displ_LoopCounter(uint8_t val)
{
lcdGotoXY(2,2);
lcdPuts(Msg(MSG_COUNTER));
lcdPuts(my_itoa(val, 4, 0, 0));
}
 
// Test über Scalierung der Servos mit Anschlagkalibrierung
void Menu_Test_Start(void)
{ uint8_t tmp_tracking, idx, rep;
int8_t dir;
int16_t sPos;
int16_t Position[3];
int16_t range;
tmp_tracking = Servo_tmp_on(servo_frame);
lcdWriteCGRAM_Array(lcdSpecialChrLs, 8); // LCD-Char mit Rahmensymbole vom Graph
chrxs = CHRLS; // Flag, welche Kästchensymbole geladen
Displ_Title(MSG_CONTINOUS);
Displ_LoopCounter(repeat);
Position[0] = 0; // skalierte Servoposition aber unterschiedliche Schrittanzahl möglich
Position[1] = ServoSteps()/2;
Position[2] = ServoSteps();
// init Einzelschritt
idx = 0;
dir = calc_dir(idx, Position);
sPos = Position[PosIdx[idx]];
idx++;
rep = repeat;
// Test bis Ende der Wiederholungen oder irgendein Enter
while( !Get_Key_Short( 1<<SW_ENTER ) && !Long_Enter() && (rep > 0)) {
range = calc_range(sPos - Position[1], Position[0], Position[2], Position[1]);
draw_bar(sPos - Position[1], range, 1); // eingerahmter Balkengraph auf 2. Display-Zeile
servoSetPosition(servo_nr, sPos);
 
if ( sPos != Position[PosIdx[idx]]) { // Links-, Mittel- oder Rechtsposotion erreicht?
sPos += (single_step * dir); // variable Schrittweite subtrahieren oder addieren
if (((dir < 0) && (sPos < Position[PosIdx[idx]])) || ((dir > 0) && (sPos > Position[PosIdx[idx]])) || !(single_step))
sPos = Position[PosIdx[idx]]; // Überlauf bei variabler Schrittweite berücksichtigen oder Einzelschritt
_delay_ms(servo_frame + 1 + pause_step);// Bei Schrittweite um 1 würden welche übersprungen, zusätzlich pro Servoschritt verzögert
}
else {
dir = calc_dir(idx, Position); // Richtungsänderung
if (idx < (POSIDX_MAX - 1)) {
if (idx == 0) {
rep--; // bei jeden vollen Durchlauf Wiederholzähler verringern
Displ_LoopCounter(rep);
}
idx++; // Index für nächsten Positionswert ==> Array PosIdx[] bestimmt Anschlagreihenfolge
}
else
idx = 0;
delay_ms100x(pause); // variable Pause bei Links-, Mittel- und Rechtsposotion Mindestzeit 400ms (Servolauf)
}
}
 
lcdClear();
if (pmenu[0] == '\0')
Displ_Main_Disp();
else
return_m_pkt(strlen(pmenu)); // um bei Rücksprung auf ursprünglichen Menüpunkt zeigen oder Displ_Main_Disp()
lcdWriteCGRAM_Array(lcdSpecialChr, 7); // LCD-Char für Bargraph zurückschreiben
cli();
servoInit(SERVO_PERIODE);
sei();
Servo_tmp_Original(tmp_tracking);
}
 
 
/**************************/
/* */
/* LCD */
/* */
/**************************/
void Menu_lcd(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_4] = {SCROLL_MAX_4 - 2, MSG_RETURN, MSG_CONTRAST, MSG_BACKGR_LIGHT};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_lcd_Contrast(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_LCD);
lcdGotoXY(2, ZLE_VAL);
lcdPuts(Msg(MSG_CONTRAST));
lcdPuts(": ");
tmp_val = contrast;
if (Change_Value(&tmp_val, CONTRAST_MIN, CONTRAST_MAX, 11, Displ_Set_Contrast)) { // pmenu global
contrast = tmp_val;
eeprom_write_byte(&ep_contrast, contrast);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_lcd_Backgr_Light(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_BACKGR_LIGHT);
lcdGotoXY(0, ZLE_VAL);
lcdPuts(Msg(MSG_LIGHT));
tmp_val = light_time;
if (Change_Value(&tmp_val, BACKGR_LIGHT_MIN, BACKGR_LIGHT_MAX, 6|(1<<V_REPEAT), Displ_Backgr_Light)) { // pmenu global
light_time = tmp_val;
eeprom_write_byte(&ep_light_time, light_time);
Double_Beep(DBEEPWR, DBEEPWRP);
if (light_time == BACKGR_LIGHT_MIN) lcdSet_BackgrLight_Off(); // Hintergrundbeleuchtung immer aus ==> sofort schalten
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Batterie */
/* */
/**************************/
void Menu_Battery(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_5] = {SCROLL_MAX_5 - 2, MSG_RETURN, MSG_U_SETUP, MSG_U_OFFSET, MSG_MK_BATTERY};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
/*****************/
/* NG-Video Akku */
/*****************/
void Menu_Low_U_Setup(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_U_MIN);
tmp_val = u_min;
if (Change_Value(&tmp_val, U_MIN_MIN, U_MIN_MAX, 4|(1<<V_REPEAT), Displ_U_2Nk)) { // pmenu global
u_min = tmp_val;
eeprom_write_word(&ep_u_min, u_min);
hyst_u_min = u_min;
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_U_Offset(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_U_OFFSET);
tmp_val = u_offset;
if (Change_Value(&tmp_val, U_OFFSET_MIN, U_OFFSET_MAX, 4|(1<<V_REPEAT), Displ_U_2Nk)) { // pmenu global
u_offset = tmp_val;
eeprom_write_byte(&ep_u_offset, u_offset);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
/******************/
/* MK-Akku(s) */
/******************/
void Menu_MK_Battery(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_7] = {SCROLL_MAX_7 - 2, MSG_RETURN, MSG_MK_BAT_NR, MSG_MK_BAT_CAPACITY, MSG_MK_I_OFFSET, MSG_MK_I_FAKTOR, MSG_MK_W_FAKTOR};
 
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
// für Nutzung verschiedener Akku's unterschiedlicher Kapazität
// könnte auch für Statistik Ladezyklen erweitert werden aber sinnlos bei Verwendung gleicher Akku's in anderen Modellen
void Menu_MK_BatteryChangeNr(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_MK_BAT_NR);
tmp_val = mk_akku_nr+1;
if (Change_Value(&tmp_val, AKKU_NR_MIN+1, AKKU_NR_MAX+1, 5|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu global
mk_akku_nr = --tmp_val;
eeprom_write_byte(&ep_mk_akku_nr, mk_akku_nr);
eeprom_read_block(&mk_lipo,&ep_mk_lipo[mk_akku_nr],sizeof(mk_lipo_t));
mk_dUsedCapacity = mk_lipo.UsedCapacity;
Double_Beep(DBEEPWR, DBEEPWRP);
}
}
 
void Menu_MK_BatteryNr(void)
{
Menu_MK_BatteryChangeNr();
Jump_Menu(pmenu);
}
 
void Menu_MK_BatteryCapacity(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_MK_BAT_CAPACITY);
tmp_val = mk_lipo.Capacity/50;
if (Change_Value(&tmp_val, AKKU_CAPACITY_MIN/50, AKKU_CAPACITY_MAX/50, 5|(1<<V_REPEAT), Displ_MK_Capacity)) { // pmenu global
mk_lipo.Capacity = tmp_val * 50;
eeprom_write_block(&mk_lipo,&ep_mk_lipo[mk_akku_nr],sizeof(mk_lipo_t));
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_MK_I_Offset(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_MK_I_OFFSET);
tmp_val = mk_i_offset;
if (Change_Value(&tmp_val, MK_I_OFFSET_MIN, MK_I_OFFSET_MAX, 5|(1<<V_REPEAT), Displ_I_Offset)) { // pmenu global
mk_i_offset = tmp_val;
eeprom_write_byte(&ep_mk_i_offset, mk_i_offset);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_MK_I_Faktor(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_MK_I_FAKTOR);
tmp_val = mk_i_faktor;
if (Change_Value(&tmp_val, MK_I_FAKTOR_MIN, MK_I_FAKTOR_MAX, 6|(1<<V_REPEAT), Displ_Faktor_2Nk)) { // pmenu global
mk_i_faktor = tmp_val;
eeprom_write_byte(&ep_mk_i_faktor, mk_i_faktor);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_MK_W_Faktor(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_MK_W_FAKTOR);
tmp_val = mk_w_faktor;
if (Change_Value(&tmp_val, MK_W_FAKTOR_MIN, MK_W_FAKTOR_MAX, 6|(1<<V_REPEAT), Displ_Faktor_2Nk)) { // pmenu global
mk_w_faktor = tmp_val;
eeprom_write_byte(&ep_mk_w_faktor, mk_w_faktor);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
 
/**************************/
/* */
/* Antennennachführung */
/* */
/**************************/
void Menu_Tracking_Ant(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_TRACKING);
tmp_val = tracking;
if (Change_Value(&tmp_val, TRACKING_MIN, TRACKING_MAX, 3, Displ_sel_Tracking)) { // pmenu global
cli();
tracking = tmp_val;
sei();
eeprom_write_byte(&ep_tracking, tracking);
Double_Beep(DBEEPWR, DBEEPWRP);
USART_RX_Mode(tracking); // Unterschied Datenempfang GPS/MKCockpit/NMEA
coldstart = 1;
rxcount0 = 0;
rxcount1 = 0;
servoSetDefaultPos(); // Ausgangsstellung beider Servos
if (tracking > TRACKING_MIN)
servoInit(SERVO_PERIODE);
NoTracking_ServosOff();
USART_Init_Baudrate();
}
Jump_Menu(pmenu);
}
 
/**************************/
/* Optionen */
/* Antennennachführung */
/* */
/**************************/
void Menu_Tracking_HYST(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_HYSTERESE);
tmp_val = track_hyst;
if (Change_Value(&tmp_val, TRACKING_HYST_MIN, TRACKING_HYST_MAX, 7|(1<<V_REPEAT), Displ_Format_Int)) { // pmenu gloabal
track_hyst = tmp_val;
eeprom_write_byte(&ep_track_hyst, track_hyst);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Tracking_TXOSD(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_TRACK_TX_OSD_DATA);
tmp_val = track_tx;
if (Change_Value(&tmp_val, 0, 1, 3, Displ_track_TX)) { // pmenu global; Senden gibt es nur 0=off, 1=on
track_tx = tmp_val;
eeprom_write_byte(&ep_track_tx, track_tx);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Baudrate(void)
{ uint16_t tmp_val;
 
Displ_Title(MSG_BAUDRATE);
tmp_val = baudrate;
if (Change_Value(&tmp_val, BAUDRATE_MIN, BAUDRATE_MAX, 3, Displ_Baudrate)) { // pmenu global
baudrate = tmp_val;
eeprom_write_byte(&ep_baudrate, baudrate);
Double_Beep(DBEEPWR, DBEEPWRP);
USART_Init(getBaud(baudrate));
}
Jump_Menu(pmenu);
}
 
void Menu_Tracking_Option(void)
{ // im Menü ist dies der gleiche Gliederungspunkt aber mit geänderter Auswahl
switch(tracking) {
case TRACKING_RSSI: Menu_Tracking_HYST();
break;
case TRACKING_GPS: Menu_Tracking_TXOSD();
break;
case TRACKING_MKCOCKPIT:
case TRACKING_NMEA: Menu_Baudrate();
break;
}
}
 
/**************************/
/* */
/* Anzeige GPS */
/* */
/**************************/
void Menu_GPS_Display(void)
{ uint8_t scr_sub_menu[SCROLL_MAX_7] = {SCROLL_MAX_7 - 2, MSG_RETURN, MSG_GPS_CALCULATE, MSG_GPS_CURRENT, MSG_GPS_HOME, \
MSG_GPS_MISC, MSG_RX_TIME};
 
if (tracking == TRACKING_NMEA) { // Manipulierung der Menüanzeige/-ausführung
scr_sub_menu[0] = SCROLL_MAX_7 - 3; // Only show MISC in GPS mode, not NMEA
scr_sub_menu[5] = MSG_RX_TIME;
}
else
if (tracking != TRACKING_GPS) scr_sub_menu[0] = SCROLL_MAX_7 - 4;
Scroll_Menu(scr_sub_menu, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_GPS_Display_FLAG(void) // ist Flag in tracking.c Tracking_GPS(void)
{ uint8_t slen;
slen = strlen(pmenu) - 1;
gps_display = pmenu[slen] - '0'; // char to byte 1 bis 3 im String enthalten
if ((tracking == TRACKING_NMEA) && (gps_display == GPS_MISC))
pmenu[slen] = RXTimeChr[0]; // Manipulierung der Menüausführung
else {
m_pkt = gps_display;
gps_disp_clear = 1; // damit Text "...keine Daten empf..." nach Datenempfang gelöscht wird
if (gps_display != GPS_MISC) lcdPuts(Msg(MSG_GPS_NO_DATA));
if (Short_Enter()) // pmenu global
pmenu[slen] = '\0'; // Menüpunkt zurück
gps_display = GPS_DISP_NONE; // nach Tastaturabfrage keine Anzeige GPS, sondern normales Menü
}
Jump_Menu(pmenu);
}
 
void Menu_GPS_Displ_RX_Time(void)
{
Displ_Title(MSG_RX_TIME);
lcdGotoXY(0, 1);
lcdPuts(Msg(MSG_RX1));
lcdGotoXY(0, 2);
lcdPuts(Msg(MSG_RX2));
Displ_RX_Time();
// bei Menüpunktmanipulatin TRACKING_NMEA und vorgezogen Menu_GPS_Displ_RX_Time ist Rücksprung real GPS_MISC
m_pkt = ((tracking == TRACKING_NMEA) && (gps_display == GPS_MISC))? GPS_MISC: GPS_RX_COUNT;
gps_display = GPS_RX_COUNT;
if (Short_Enter()) // pmenu global
pmenu[strlen(pmenu) - 1] = '\0';// Menüpunkt zurück
gps_display = GPS_DISP_NONE; // nach Tastaturabfrage keine Anzeige GPS, sondern normales Menü
Jump_Menu(pmenu);
}
/NGVideo5_8/tags/v1.33/menue.h
0,0 → 1,107
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#ifndef _MENUE_H_
#define _MENUE_H_
 
#define SCROLL_MAIN_MAX 13 // index array Scroll_Menu scr_main_menu[] = {....}
#define SCROLL_MAX_4 4 // später SCROLL_MAX_N - 2, da array[0] Scrollwert und
#define SCROLL_MAX_5 5 // for-Schleifen mit Zählen 0 beginnen
#define SCROLL_MAX_6 6
#define SCROLL_MAX_7 7
 
#define SCROLL_SERVO_MAX 4 // index array Scroll_Menu scr_servo_menu[] = {....} Anzahl-1, da Beginn bei 0
 
/* bei Change_Value(....) */
#define ZLE_VAL 1 // DOGM Zeile des zu ändernten Wertes, einfache generelle bessere Gestaltung
 
#define C_REPEAT 0 // konstante repeat Geschwindigkeit
#define POSXMASK 0b00001111 // separiert pos_x für lcdGotoXY()
#define CYCLE 6 // Bit bei Erreichen Endwert wird Anfangswert dargestellt ("kreisförmige Auswahl")
#define V_REPEAT 7 // Bit sich ändernte repeat Geschwindigkeit
#define CHRLS 0 // Flag überladener Zeichensatz lcdSpecialChrLs
#define CHRRS 1 // Flag überladener Zeichensatz lcdSpecialChrRs
 
#define RXTimeChr "5"
#define RXTimeStr "0;"RXTimeChr
 
typedef void (*Displ_Fnct_t)( uint16_t );
 
extern char pmenu[6]; // Zuordnung Menü Programmgliederung zu hinterlegten Funktionen
extern uint8_t m_pkt;
extern uint8_t exit_while;
 
typedef struct {
const char *menu_nr; // Stringzeiger auf Befehlsnamen
void (*fp)(void); // Zeiger auf auszuführende Funktion
}command_table_t;
void Menu_Main (void);
void Menu_AV_Source (void);
void Menu_RX_Channel (void);
void Menu_RSSI_Calibr (void);
void Menu_RSSI_min (void);
void Menu_RSSI_min_all (void);
void Menu_RSSI_max (void);
void Menu_RSSI_invert (void);
void Menu_TX_identyfy (void);
void Menu_TX_status_off (void);
void Menu_TX_status_on (void);
void Menu_Language (void);
void Menu_Servo_Calibr (void);
void Menu_Servo_Steps (void);
void Menu_Servo1 (void);
void Menu_Servo2 (void);
void Menu_Servo1_rev (void);
void Menu_Servo1_left (void);
void Menu_Servo1_right (void);
void Menu_Servo1_middle (void);
void Menu_Servo2_rev (void);
void Menu_Servo2_left (void);
void Menu_Servo2_right (void);
void Menu_Servo2_middle (void);
void Menu_Servo_Test (void);
void Menu_Test_Frame (void);
void Menu_Test_ServoNr (void);
void Menu_Test_PulseWidth (void);
void Menu_Test_Continuous (void);
void Menu_Test_SingleStep (void);
void Menu_Test_Repeat (void);
void Menu_Test_Pause (void);
void Menu_Test_Pause_Step (void);
void Menu_Test_Start (void);
void Menu_lcd (void);
void Menu_lcd_Contrast (void);
void Menu_lcd_Backgr_Light (void);
void Menu_Battery (void);
void Menu_Low_U_Setup (void);
void Menu_U_Offset (void);
void Menu_MK_Battery (void);
void Menu_MK_BatteryNr (void);
void Menu_MK_BatteryCapacity(void);
void Menu_MK_I_Offset (void);
void Menu_MK_I_Faktor (void);
void Menu_MK_W_Faktor (void);
void Menu_Tracking_Ant (void);
void Menu_Tracking_Option (void);
void Menu_GPS_Display (void);
void Menu_GPS_Display_FLAG (void);
void Menu_GPS_Displ_RX_Time (void);
 
void Displ_Version(void);
void Displ_Main_Disp(void);
void Displ_AV_Mark(uint8_t p, char marker);
void Displ_RX_Time(void);
void Displ_Channels(uint16_t k);
void Menu_MK_BatteryChangeNr(void);
 
#endif /* _MENUE_H */
/NGVideo5_8/tags/v1.33/messages.c
0,0 → 1,558
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* using */
/* http://www.avrfreaks.net/ */
/* index.php?name=PNphpBB2&file=viewtopic&t=71985&view=previous*/
/* */
/****************************************************************/
 
#include "messages.h"
 
#define MSG_TABLE(l,n) mt ## l ## _ ## n
#define MSG_STRING(l,n,s) \
const char mt ## l ## _ ## n [] PROGMEM = s ;
 
MSG_STRING(INTERNAT, MSG_RSSI_MIN, INTERNAT_RSSI_MIN)
MSG_STRING(INTERNAT, MSG_RSSI_MAX, INTERNAT_RSSI_MAX)
MSG_STRING(INTERNAT, MSG_DIVERSITY, INTERNAT_DIVERSITY)
MSG_STRING(INTERNAT, MSG_LCD, INTERNAT_LCD)
MSG_STRING(INTERNAT, MSG_AV1, INTERNAT_AV1)
MSG_STRING(INTERNAT, MSG_AV2, INTERNAT_AV2)
MSG_STRING(INTERNAT, MSG_RX1, INTERNAT_RX1)
MSG_STRING(INTERNAT, MSG_RX2, INTERNAT_RX2)
MSG_STRING(INTERNAT, MSG_STEPS_255, INTERNAT_STEPS_255)
MSG_STRING(INTERNAT, MSG_STEPS_1023, INTERNAT_STEPS_1023)
MSG_STRING(INTERNAT, MSG_SERVO, INTERNAT_SERVO)
MSG_STRING(INTERNAT, MSG_SERVO1, INTERNAT_SERVO1)
MSG_STRING(INTERNAT, MSG_SERVO2, INTERNAT_SERVO2)
MSG_STRING(INTERNAT, MSG_TEST_SERVO, INTERNAT_TEST_SERVO)
MSG_STRING(INTERNAT, MSG_TRACK_RSSI, INTERNAT_TRACK_RSSI)
MSG_STRING(INTERNAT, MSG_TRACK_MKCOCKPIT, INTERNAT_TRACK_MKCOCKPIT)
MSG_STRING(INTERNAT, MSG_TRACK_SERVO_HYTERESE, INTERNAT_TRACK_SERVO_HYTERESE)
MSG_STRING(INTERNAT, MSG_BAUDRATE, INTERNAT_BAUDRATE)
MSG_STRING(INTERNAT, MSG_UHW5V, INTERNAT_UHW5V)
MSG_STRING(INTERNAT, MSG_VERSION1, INTERNAT_VERSION1)
MSG_STRING(INTERNAT, MSG_VERSION2, INTERNAT_VERSION2)
 
MSG_STRING(GERMAN, MSG_LANGUAGE, GERMAN_LANGUAGE)
MSG_STRING(GERMAN, MSG_GERMAN, GERMAN_GERMAN)
MSG_STRING(GERMAN, MSG_ENGLISH, GERMAN_ENGLISH)
MSG_STRING(GERMAN, MSG_FRENCH, GERMAN_FRENCH)
MSG_STRING(GERMAN, MSG_RETURN, GERMAN_RETURN)
MSG_STRING(GERMAN, MSG_AV_SOURCE, GERMAN_AV_SOURCE)
MSG_STRING(GERMAN, MSG_RX_CHANNEL, GERMAN_RX_CHANNEL)
MSG_STRING(GERMAN, MSG_RSSI_CALIBR, GERMAN_RSSI_CALIBR)
MSG_STRING(GERMAN, MSG_RSSI_MIN_ALL, GERMAN_RSSI_MIN_ALL)
MSG_STRING(GERMAN, MSG_RSSI_INVERT, GERMAN_RSSI_INVERT)
MSG_STRING(GERMAN, MSG_TX_IDENTIFY, GERMAN_TX_IDENTIFY)
MSG_STRING(GERMAN, MSG_TX_STATUS_ON, GERMAN_TX_STATUS_ON)
MSG_STRING(GERMAN, MSG_TX_STATUS_OFF, GERMAN_TX_STATUS_OFF)
MSG_STRING(GERMAN, MSG_TX_STATUS, GERMAN_TX_STATUS)
MSG_STRING(GERMAN, MSG_CALIB, GERMAN_CALIB)
MSG_STRING(GERMAN, MSG_TX, GERMAN_TX)
MSG_STRING(GERMAN, MSG_TX_OFF, GERMAN_TX_OFF)
MSG_STRING(GERMAN, MSG_TX_ON, GERMAN_TX_ON)
MSG_STRING(GERMAN, MSG_CONTINUE, GERMAN_CONTINUE)
MSG_STRING(GERMAN, MSG_CONTRAST, GERMAN_CONTRAST)
MSG_STRING(GERMAN, MSG_BACKGR_LIGHT, GERMAN_BACKGR_LIGHT)
MSG_STRING(GERMAN, MSG_LIGHT, GERMAN_LIGHT)
MSG_STRING(GERMAN, MSG_LIGHT_OFF, GERMAN_LIGHT_OFF)
MSG_STRING(GERMAN, MSG_LIGHT_ON, GERMAN_LIGHT_ON)
MSG_STRING(GERMAN, MSG_SEC, GERMAN_SEC)
MSG_STRING(GERMAN, MSG_BATTERY, GERMAN_BATTERY)
MSG_STRING(GERMAN, MSG_U_MIN, GERMAN_U_MIN)
MSG_STRING(GERMAN, MSG_U_SETUP, GERMAN_U_SETUP)
MSG_STRING(GERMAN, MSG_U_OFFSET, GERMAN_U_OFFSET)
MSG_STRING(GERMAN, MSG_MK_BATTERY, GERMAN_MSG_MK_BATTERY)
MSG_STRING(GERMAN, MSG_MK_BAT_NR, GERMAN_MSG_MK_BAT_NR)
MSG_STRING(GERMAN, MSG_MK_BAT_CAPACITY, GERMAN_MSG_MK_BAT_CAPACITY)
MSG_STRING(GERMAN, MSG_MK_I_OFFSET, GERMAN_MSG_MK_I_OFFSET)
MSG_STRING(GERMAN, MSG_MK_I_FAKTOR, GERMAN_MSG_MK_I_FAKTOR)
MSG_STRING(GERMAN, MSG_MK_W_FAKTOR, GERMAN_MSG_MK_W_FAKTOR)
MSG_STRING(GERMAN, MSG_CALIBRATION, GERMAN_CALIBRATION)
MSG_STRING(GERMAN, MSG_RUNNING, GERMAN_RUNNING)
MSG_STRING(GERMAN, MSG_ERROR, GERMAN_ERROR)
MSG_STRING(GERMAN, MSG_TX_NOT, GERMAN_TX_NOT)
MSG_STRING(GERMAN, MSG_ACCU_LOW, GERMAN_ACCU_LOW)
MSG_STRING(GERMAN, MSG_SERVO_CALIBR, GERMAN_SERVO_CALIBR)
MSG_STRING(GERMAN, MSG_SERVO_STEPS, GERMAN_SERVO_STEPS)
MSG_STRING(GERMAN, MSG_SERVO1_REVERSE, GERMAN_SERVO1_REVERSE)
MSG_STRING(GERMAN, MSG_CALIB1_LEFT, GERMAN_CALIB1_LEFT)
MSG_STRING(GERMAN, MSG_CALIB1_RIGHT, GERMAN_CALIB1_RIGHT)
MSG_STRING(GERMAN, MSG_CALIB1_MIDDLE, GERMAN_CALIB1_MIDDLE)
MSG_STRING(GERMAN, MSG_SERVO2_REVERSE, GERMAN_SERVO2_REVERSE)
MSG_STRING(GERMAN, MSG_CALIB2_LEFT, GERMAN_CALIB2_LEFT)
MSG_STRING(GERMAN, MSG_CALIB2_RIGHT, GERMAN_CALIB2_RIGHT)
MSG_STRING(GERMAN, MSG_CALIB2_MIDDLE, GERMAN_CALIB2_MIDDLE)
MSG_STRING(GERMAN, MSG_FRAME, GERMAN_FRAME)
MSG_STRING(GERMAN, MSG_PULSE_WIDTH, GERMAN_PULSE_WIDTH)
MSG_STRING(GERMAN, MSG_CONTINOUS, GERMAN_CONTINOUS)
MSG_STRING(GERMAN, MSG_SINGLE_STE, GERMAN_SINGLE_STEP)
MSG_STRING(GERMAN, MSG_REPEAT, GERMAN_REPEAT)
MSG_STRING(GERMAN, MSG_PAUSE, GERMAN_PAUSE)
MSG_STRING(GERMAN, MSG_PAUSE_STEP, GERMAN_PAUSE_STEP)
MSG_STRING(GERMAN, MSG_COUNTER, GERMAN_COUNTER)
MSG_STRING(GERMAN, MSG_START, GERMAN_START)
MSG_STRING(GERMAN, MSG_OFF, GERMAN_OFF)
MSG_STRING(GERMAN, MSG_ON, GERMAN_ON)
MSG_STRING(GERMAN, MSG_TRACKING, GERMAN_TRACKING)
MSG_STRING(GERMAN, MSG_TRACK_GPS, GERMAN_TRACK_GPS)
MSG_STRING(GERMAN, MSG_TRACK_NMEA, GERMAN_TRACK_NMEA)
MSG_STRING(GERMAN, MSG_TRACK_TX_OSD_DATA, GERMAN_TRACK_TX_OSD_DATA)
MSG_STRING(GERMAN, MSG_HYSTERESE, GERMAN_HYSTERESE)
MSG_STRING(GERMAN, MSG_TRACK_TX_ON, GERMAN_TRACK_TX_ON)
MSG_STRING(GERMAN, MSG_GPS_DISPLAY, GERMAN_GPS_DISPLAY)
MSG_STRING(GERMAN, MSG_GPS_CALCULATE, GERMAN_GPS_CALCULATE)
MSG_STRING(GERMAN, MSG_GPS_CURRENT, GERMAN_GPS_CURRENT)
MSG_STRING(GERMAN, MSG_GPS_HOME, GERMAN_GPS_HOME)
MSG_STRING(GERMAN, MSG_GPS_MISC, GERMAN_GPS_MISC)
MSG_STRING(GERMAN, MSG_GPS_NO_DATA, GERMAN_GPS_NO_DATA)
MSG_STRING(GERMAN, MSG_RX_TIME, GERMAN_RX_TIME)
MSG_STRING(GERMAN, MSG_COM, GERMAN_COM)
MSG_STRING(GERMAN, MSG_KOMMA, GERMAN_KOMMA)
MSG_STRING(GERMAN, MSG_UHW33V, GERMAN_UHW33V)
 
MSG_STRING(ENGLISH, MSG_LANGUAGE, ENGLISH_LANGUAGE)
MSG_STRING(ENGLISH, MSG_GERMAN, ENGLISH_GERMAN)
MSG_STRING(ENGLISH, MSG_ENGLISH, ENGLISH_ENGLISH)
MSG_STRING(ENGLISH, MSG_FRENCH, ENGLISH_FRENCH)
MSG_STRING(ENGLISH, MSG_RETURN, ENGLISH_RETURN)
MSG_STRING(ENGLISH, MSG_AV_SOURCE, ENGLISH_AV_SOURCE)
MSG_STRING(ENGLISH, MSG_RX_CHANNEL, ENGLISH_RX_CHANNEL)
MSG_STRING(ENGLISH, MSG_RSSI_CALIBR, ENGLISH_RSSI_CALIBR)
MSG_STRING(ENGLISH, MSG_RSSI_MIN_ALL, ENGLISH_RSSI_MIN_ALL)
MSG_STRING(ENGLISH, MSG_RSSI_INVERT, ENGLISH_RSSI_INVERT)
MSG_STRING(ENGLISH, MSG_TX_IDENTIFY, ENGLISH_TX_IDENTIFY)
MSG_STRING(ENGLISH, MSG_TX_STATUS_ON, ENGLISH_TX_STATUS_ON)
MSG_STRING(ENGLISH, MSG_TX_STATUS_OFF, ENGLISH_TX_STATUS_OFF)
MSG_STRING(ENGLISH, MSG_TX_STATUS, ENGLISH_TX_STATUS)
MSG_STRING(ENGLISH, MSG_CALIB, ENGLISH_CALIB)
MSG_STRING(ENGLISH, MSG_TX, ENGLISH_TX)
MSG_STRING(ENGLISH, MSG_TX_OFF, ENGLISH_TX_OFF)
MSG_STRING(ENGLISH, MSG_TX_ON, ENGLISH_TX_ON)
MSG_STRING(ENGLISH, MSG_CONTINUE, ENGLISH_CONTINUE)
MSG_STRING(ENGLISH, MSG_CONTRAST, ENGLISH_CONTRAST)
MSG_STRING(ENGLISH, MSG_BACKGR_LIGHT, ENGLISH_BACKGR_LIGHT)
MSG_STRING(ENGLISH, MSG_LIGHT, ENGLISH_LIGHT)
MSG_STRING(ENGLISH, MSG_LIGHT_OFF, ENGLISH_LIGHT_OFF)
MSG_STRING(ENGLISH, MSG_LIGHT_ON, ENGLISH_LIGHT_ON)
MSG_STRING(ENGLISH, MSG_SEC, ENGLISH_SEC)
MSG_STRING(ENGLISH, MSG_BATTERY, ENGLISH_BATTERY)
MSG_STRING(ENGLISH, MSG_U_MIN, ENGLISH_U_MIN)
MSG_STRING(ENGLISH, MSG_U_SETUP, ENGLISH_U_SETUP)
MSG_STRING(ENGLISH, MSG_U_OFFSET, ENGLISH_U_OFFSET)
MSG_STRING(ENGLISH, MSG_MK_BATTERY, ENGLISH_MSG_MK_BATTERY)
MSG_STRING(ENGLISH, MSG_MK_BAT_NR, ENGLISH_MSG_MK_BAT_NR)
MSG_STRING(ENGLISH, MSG_MK_BAT_CAPACITY, ENGLISH_MSG_MK_BAT_CAPACITY)
MSG_STRING(ENGLISH, MSG_MK_I_OFFSET, ENGLISH_MSG_MK_I_OFFSET)
MSG_STRING(ENGLISH, MSG_MK_I_FAKTOR, ENGLISH_MSG_MK_I_FAKTOR)
MSG_STRING(ENGLISH, MSG_MK_W_FAKTOR, ENGLISH_MSG_MK_W_FAKTOR)
MSG_STRING(ENGLISH, MSG_CALIBRATION, ENGLISH_CALIBRATION)
MSG_STRING(ENGLISH, MSG_RUNNING, ENGLISH_RUNNING)
MSG_STRING(ENGLISH, MSG_ERROR, ENGLISH_ERROR)
MSG_STRING(ENGLISH, MSG_TX_NOT, ENGLISH_TX_NOT)
MSG_STRING(ENGLISH, MSG_ACCU_LOW, ENGLISH_ACCU_LOW)
MSG_STRING(ENGLISH, MSG_SERVO_CALIBR, ENGLISH_SERVO_CALIBR)
MSG_STRING(ENGLISH, MSG_SERVO_STEPS, ENGLISH_SERVO_STEPS)
MSG_STRING(ENGLISH, MSG_SERVO1_REVERSE, ENGLISH_SERVO1_REVERSE)
MSG_STRING(ENGLISH, MSG_CALIB1_LEFT, ENGLISH_CALIB1_LEFT)
MSG_STRING(ENGLISH, MSG_CALIB1_RIGHT, ENGLISH_CALIB1_RIGHT)
MSG_STRING(ENGLISH, MSG_CALIB1_MIDDLE, ENGLISH_CALIB1_MIDDLE)
MSG_STRING(ENGLISH, MSG_SERVO2_REVERSE, ENGLISH_SERVO2_REVERSE)
MSG_STRING(ENGLISH, MSG_CALIB2_LEFT, ENGLISH_CALIB2_LEFT)
MSG_STRING(ENGLISH, MSG_CALIB2_RIGHT, ENGLISH_CALIB2_RIGHT)
MSG_STRING(ENGLISH, MSG_CALIB2_MIDDLE, ENGLISH_CALIB2_MIDDLE)
MSG_STRING(ENGLISH, MSG_FRAME, ENGLISH_FRAME)
MSG_STRING(ENGLISH, MSG_PULSE_WIDTH, ENGLISH_PULSE_WIDTH)
MSG_STRING(ENGLISH, MSG_CONTINOUS, ENGLISH_CONTINOUS)
MSG_STRING(ENGLISH, MSG_SINGLE_STE, ENGLISH_SINGLE_STEP)
MSG_STRING(ENGLISH, MSG_REPEAT, ENGLISH_REPEAT)
MSG_STRING(ENGLISH, MSG_PAUSE, ENGLISH_PAUSE)
MSG_STRING(ENGLISH, MSG_PAUSE_STEP, ENGLISH_PAUSE_STEP)
MSG_STRING(ENGLISH, MSG_COUNTER, ENGLISH_COUNTER)
MSG_STRING(ENGLISH, MSG_START, ENGLISH_START)
MSG_STRING(ENGLISH, MSG_OFF, ENGLISH_OFF)
MSG_STRING(ENGLISH, MSG_ON, ENGLISH_ON)
MSG_STRING(ENGLISH, MSG_TRACKING, ENGLISH_TRACKING)
MSG_STRING(ENGLISH, MSG_TRACK_GPS, ENGLISH_TRACK_GPS)
MSG_STRING(ENGLISH, MSG_TRACK_NMEA, ENGLISH_TRACK_NMEA)
MSG_STRING(ENGLISH, MSG_TRACK_TX_OSD_DATA, ENGLISH_TRACK_TX_OSD_DATA)
MSG_STRING(ENGLISH, MSG_HYSTERESE, ENGLISH_HYSTERESE)
MSG_STRING(ENGLISH, MSG_TRACK_TX_ON, ENGLISH_TRACK_TX_ON)
MSG_STRING(ENGLISH, MSG_GPS_DISPLAY, ENGLISH_GPS_DISPLAY)
MSG_STRING(ENGLISH, MSG_GPS_CALCULATE, ENGLISH_GPS_CALCULATE)
MSG_STRING(ENGLISH, MSG_GPS_CURRENT, ENGLISH_GPS_CURRENT)
MSG_STRING(ENGLISH, MSG_GPS_HOME, ENGLISH_GPS_HOME)
MSG_STRING(ENGLISH, MSG_GPS_MISC, ENGLISH_GPS_MISC)
MSG_STRING(ENGLISH, MSG_GPS_NO_DATA, ENGLISH_GPS_NO_DATA)
MSG_STRING(ENGLISH, MSG_RX_TIME, ENGLISH_RX_TIME)
MSG_STRING(ENGLISH, MSG_COM, ENGLISH_COM)
MSG_STRING(ENGLISH, MSG_KOMMA, ENGLISH_KOMMA)
MSG_STRING(ENGLISH, MSG_UHW33V, ENGLISH_UHW33V)
 
MSG_STRING(FRENCH, MSG_LANGUAGE, FRENCH_LANGUAGE)
MSG_STRING(FRENCH, MSG_GERMAN, FRENCH_GERMAN)
MSG_STRING(FRENCH, MSG_ENGLISH, FRENCH_ENGLISH)
MSG_STRING(FRENCH, MSG_FRENCH, FRENCH_FRENCH)
MSG_STRING(FRENCH, MSG_RETURN, FRENCH_RETURN)
MSG_STRING(FRENCH, MSG_AV_SOURCE, FRENCH_AV_SOURCE)
MSG_STRING(FRENCH, MSG_RX_CHANNEL, FRENCH_RX_CHANNEL)
MSG_STRING(FRENCH, MSG_RSSI_CALIBR, FRENCH_RSSI_CALIBR)
MSG_STRING(FRENCH, MSG_RSSI_MIN_ALL, FRENCH_RSSI_MIN_ALL)
MSG_STRING(FRENCH, MSG_RSSI_INVERT, FRENCH_RSSI_INVERT)
MSG_STRING(FRENCH, MSG_TX_IDENTIFY, FRENCH_TX_IDENTIFY)
MSG_STRING(FRENCH, MSG_TX_STATUS_ON, FRENCH_TX_STATUS_ON)
MSG_STRING(FRENCH, MSG_TX_STATUS_OFF, FRENCH_TX_STATUS_OFF)
MSG_STRING(FRENCH, MSG_TX_STATUS, FRENCH_TX_STATUS)
MSG_STRING(FRENCH, MSG_CALIB, FRENCH_CALIB)
MSG_STRING(FRENCH, MSG_TX, FRENCH_TX)
MSG_STRING(FRENCH, MSG_TX_OFF, FRENCH_TX_OFF)
MSG_STRING(FRENCH, MSG_TX_ON, FRENCH_TX_ON)
MSG_STRING(FRENCH, MSG_CONTINUE, FRENCH_CONTINUE)
MSG_STRING(FRENCH, MSG_CONTRAST, FRENCH_CONTRAST)
MSG_STRING(FRENCH, MSG_BACKGR_LIGHT, FRENCH_BACKGR_LIGHT)
MSG_STRING(FRENCH, MSG_LIGHT, FRENCH_LIGHT)
MSG_STRING(FRENCH, MSG_LIGHT_OFF, FRENCH_LIGHT_OFF)
MSG_STRING(FRENCH, MSG_LIGHT_ON, FRENCH_LIGHT_ON)
MSG_STRING(FRENCH, MSG_SEC, FRENCH_SEC)
MSG_STRING(FRENCH, MSG_BATTERY, FRENCH_BATTERY)
MSG_STRING(FRENCH, MSG_U_MIN, FRENCH_U_MIN)
MSG_STRING(FRENCH, MSG_U_SETUP, FRENCH_U_SETUP)
MSG_STRING(FRENCH, MSG_U_OFFSET, FRENCH_U_OFFSET)
MSG_STRING(FRENCH, MSG_MK_BATTERY, FRENCH_MSG_MK_BATTERY)
MSG_STRING(FRENCH, MSG_MK_BAT_NR, FRENCH_MSG_MK_BAT_NR)
MSG_STRING(FRENCH, MSG_MK_BAT_CAPACITY, FRENCH_MSG_MK_BAT_CAPACITY)
MSG_STRING(FRENCH, MSG_MK_I_OFFSET, FRENCH_MSG_MK_I_OFFSET)
MSG_STRING(FRENCH, MSG_MK_I_FAKTOR, FRENCH_MSG_MK_I_FAKTOR)
MSG_STRING(FRENCH, MSG_MK_W_FAKTOR, FRENCH_MSG_MK_W_FAKTOR)
MSG_STRING(FRENCH, MSG_CALIBRATION, FRENCH_CALIBRATION)
MSG_STRING(FRENCH, MSG_RUNNING, FRENCH_RUNNING)
MSG_STRING(FRENCH, MSG_ERROR, FRENCH_ERROR)
MSG_STRING(FRENCH, MSG_TX_NOT, FRENCH_TX_NOT)
MSG_STRING(FRENCH, MSG_ACCU_LOW, FRENCH_ACCU_LOW)
MSG_STRING(FRENCH, MSG_SERVO_CALIBR, FRENCH_SERVO_CALIBR)
MSG_STRING(FRENCH, MSG_SERVO_STEPS, FRENCH_SERVO_STEPS)
MSG_STRING(FRENCH, MSG_SERVO1_REVERSE, FRENCH_SERVO1_REVERSE)
MSG_STRING(FRENCH, MSG_CALIB1_LEFT, FRENCH_CALIB1_LEFT)
MSG_STRING(FRENCH, MSG_CALIB1_RIGHT, FRENCH_CALIB1_RIGHT)
MSG_STRING(FRENCH, MSG_CALIB1_MIDDLE, FRENCH_CALIB1_MIDDLE)
MSG_STRING(FRENCH, MSG_SERVO2_REVERSE, FRENCH_SERVO2_REVERSE)
MSG_STRING(FRENCH, MSG_CALIB2_LEFT, FRENCH_CALIB2_LEFT)
MSG_STRING(FRENCH, MSG_CALIB2_RIGHT, FRENCH_CALIB2_RIGHT)
MSG_STRING(FRENCH, MSG_CALIB2_MIDDLE, FRENCH_CALIB2_MIDDLE)
MSG_STRING(FRENCH, MSG_FRAME, FRENCH_FRAME)
MSG_STRING(FRENCH, MSG_PULSE_WIDTH, FRENCH_PULSE_WIDTH)
MSG_STRING(FRENCH, MSG_CONTINOUS, FRENCH_CONTINOUS)
MSG_STRING(FRENCH, MSG_SINGLE_STE, FRENCH_SINGLE_STEP)
MSG_STRING(FRENCH, MSG_REPEAT, FRENCH_REPEAT)
MSG_STRING(FRENCH, MSG_PAUSE, FRENCH_PAUSE)
MSG_STRING(FRENCH, MSG_PAUSE_STEP, FRENCH_PAUSE_STEP)
MSG_STRING(FRENCH, MSG_COUNTER, FRENCH_COUNTER)
MSG_STRING(FRENCH, MSG_START, FRENCH_START)
MSG_STRING(FRENCH, MSG_OFF, FRENCH_OFF)
MSG_STRING(FRENCH, MSG_ON, FRENCH_ON)
MSG_STRING(FRENCH, MSG_TRACKING, FRENCH_TRACKING)
MSG_STRING(FRENCH, MSG_TRACK_GPS, FRENCH_TRACK_GPS)
MSG_STRING(FRENCH, MSG_TRACK_NMEA, FRENCH_TRACK_NMEA)
MSG_STRING(FRENCH, MSG_TRACK_TX_OSD_DATA, FRENCH_TRACK_TX_OSD_DATA)
MSG_STRING(FRENCH, MSG_HYSTERESE, FRENCH_HYSTERESE)
MSG_STRING(FRENCH, MSG_TRACK_TX_ON, FRENCH_TRACK_TX_ON)
MSG_STRING(FRENCH, MSG_GPS_DISPLAY, FRENCH_GPS_DISPLAY)
MSG_STRING(FRENCH, MSG_GPS_CALCULATE, FRENCH_GPS_CALCULATE)
MSG_STRING(FRENCH, MSG_GPS_CURRENT, FRENCH_GPS_CURRENT)
MSG_STRING(FRENCH, MSG_GPS_HOME, FRENCH_GPS_HOME)
MSG_STRING(FRENCH, MSG_GPS_MISC, FRENCH_GPS_MISC)
MSG_STRING(FRENCH, MSG_GPS_NO_DATA, FRENCH_GPS_NO_DATA)
MSG_STRING(FRENCH, MSG_RX_TIME, FRENCH_RX_TIME)
MSG_STRING(FRENCH, MSG_COM, FRENCH_COM)
MSG_STRING(FRENCH, MSG_KOMMA, FRENCH_KOMMA)
MSG_STRING(FRENCH, MSG_UHW33V, FRENCH_UHW33V)
 
PGM_P MessageTableGerman[LAST_NAT_MESSAGE+1] PROGMEM = {
MSG_TABLE(GERMAN, MSG_LANGUAGE),
MSG_TABLE(GERMAN, MSG_GERMAN),
MSG_TABLE(GERMAN, MSG_ENGLISH),
MSG_TABLE(GERMAN, MSG_FRENCH),
MSG_TABLE(GERMAN, MSG_RETURN),
MSG_TABLE(GERMAN, MSG_AV_SOURCE),
MSG_TABLE(GERMAN, MSG_RX_CHANNEL),
MSG_TABLE(GERMAN, MSG_RSSI_CALIBR),
MSG_TABLE(GERMAN, MSG_RSSI_MIN_ALL),
MSG_TABLE(GERMAN, MSG_RSSI_INVERT),
MSG_TABLE(GERMAN, MSG_TX_IDENTIFY),
MSG_TABLE(GERMAN, MSG_TX_STATUS_ON),
MSG_TABLE(GERMAN, MSG_TX_STATUS_OFF),
MSG_TABLE(GERMAN, MSG_TX_STATUS),
MSG_TABLE(GERMAN, MSG_CALIB),
MSG_TABLE(GERMAN, MSG_TX),
MSG_TABLE(GERMAN, MSG_TX_OFF),
MSG_TABLE(GERMAN, MSG_TX_ON),
MSG_TABLE(GERMAN, MSG_CONTINUE),
MSG_TABLE(GERMAN, MSG_CONTRAST),
MSG_TABLE(GERMAN, MSG_BACKGR_LIGHT),
MSG_TABLE(GERMAN, MSG_LIGHT),
MSG_TABLE(GERMAN, MSG_LIGHT_OFF),
MSG_TABLE(GERMAN, MSG_LIGHT_ON),
MSG_TABLE(GERMAN, MSG_SEC),
MSG_TABLE(GERMAN, MSG_BATTERY),
MSG_TABLE(GERMAN, MSG_U_MIN),
MSG_TABLE(GERMAN, MSG_U_SETUP),
MSG_TABLE(GERMAN, MSG_U_OFFSET),
MSG_TABLE(GERMAN, MSG_MK_BATTERY),
MSG_TABLE(GERMAN, MSG_MK_BAT_NR),
MSG_TABLE(GERMAN, MSG_MK_BAT_CAPACITY),
MSG_TABLE(GERMAN, MSG_MK_I_OFFSET),
MSG_TABLE(GERMAN, MSG_MK_I_FAKTOR),
MSG_TABLE(GERMAN, MSG_MK_W_FAKTOR),
MSG_TABLE(GERMAN, MSG_CALIBRATION),
MSG_TABLE(GERMAN, MSG_RUNNING),
MSG_TABLE(GERMAN, MSG_ERROR),
MSG_TABLE(GERMAN, MSG_TX_NOT),
MSG_TABLE(GERMAN, MSG_ACCU_LOW),
MSG_TABLE(GERMAN, MSG_SERVO_CALIBR),
MSG_TABLE(GERMAN, MSG_SERVO_STEPS),
MSG_TABLE(GERMAN, MSG_SERVO1_REVERSE),
MSG_TABLE(GERMAN, MSG_CALIB1_LEFT),
MSG_TABLE(GERMAN, MSG_CALIB1_RIGHT),
MSG_TABLE(GERMAN, MSG_CALIB1_MIDDLE),
MSG_TABLE(GERMAN, MSG_SERVO2_REVERSE),
MSG_TABLE(GERMAN, MSG_CALIB2_LEFT),
MSG_TABLE(GERMAN, MSG_CALIB2_RIGHT),
MSG_TABLE(GERMAN, MSG_CALIB2_MIDDLE),
MSG_TABLE(GERMAN, MSG_FRAME),
MSG_TABLE(GERMAN, MSG_PULSE_WIDTH),
MSG_TABLE(GERMAN, MSG_CONTINOUS),
MSG_TABLE(GERMAN, MSG_SINGLE_STE),
MSG_TABLE(GERMAN, MSG_REPEAT),
MSG_TABLE(GERMAN, MSG_PAUSE),
MSG_TABLE(GERMAN, MSG_PAUSE_STEP),
MSG_TABLE(GERMAN, MSG_COUNTER),
MSG_TABLE(GERMAN, MSG_START),
MSG_TABLE(GERMAN, MSG_OFF),
MSG_TABLE(GERMAN, MSG_ON),
MSG_TABLE(GERMAN, MSG_TRACKING),
MSG_TABLE(GERMAN, MSG_TRACK_GPS),
MSG_TABLE(GERMAN, MSG_TRACK_NMEA),
MSG_TABLE(GERMAN, MSG_TRACK_TX_OSD_DATA),
MSG_TABLE(GERMAN, MSG_HYSTERESE),
MSG_TABLE(GERMAN, MSG_TRACK_TX_ON),
MSG_TABLE(GERMAN, MSG_GPS_DISPLAY),
MSG_TABLE(GERMAN, MSG_GPS_CALCULATE),
MSG_TABLE(GERMAN, MSG_GPS_CURRENT),
MSG_TABLE(GERMAN, MSG_GPS_HOME),
MSG_TABLE(GERMAN, MSG_GPS_MISC),
MSG_TABLE(GERMAN, MSG_GPS_NO_DATA),
MSG_TABLE(GERMAN, MSG_RX_TIME),
MSG_TABLE(GERMAN, MSG_COM),
MSG_TABLE(GERMAN, MSG_KOMMA),
MSG_TABLE(GERMAN, MSG_UHW33V),
};
 
PGM_P MessageTableEnglish[LAST_NAT_MESSAGE+1] PROGMEM = {
MSG_TABLE(ENGLISH, MSG_LANGUAGE),
MSG_TABLE(ENGLISH, MSG_GERMAN),
MSG_TABLE(ENGLISH, MSG_ENGLISH),
MSG_TABLE(ENGLISH, MSG_FRENCH),
MSG_TABLE(ENGLISH, MSG_RETURN),
MSG_TABLE(ENGLISH, MSG_AV_SOURCE),
MSG_TABLE(ENGLISH, MSG_RX_CHANNEL),
MSG_TABLE(ENGLISH, MSG_RSSI_CALIBR),
MSG_TABLE(ENGLISH, MSG_RSSI_MIN_ALL),
MSG_TABLE(ENGLISH, MSG_RSSI_INVERT),
MSG_TABLE(ENGLISH, MSG_TX_IDENTIFY),
MSG_TABLE(ENGLISH, MSG_TX_STATUS_ON),
MSG_TABLE(ENGLISH, MSG_TX_STATUS_OFF),
MSG_TABLE(ENGLISH, MSG_TX_STATUS),
MSG_TABLE(ENGLISH, MSG_CALIB),
MSG_TABLE(ENGLISH, MSG_TX),
MSG_TABLE(ENGLISH, MSG_TX_OFF),
MSG_TABLE(ENGLISH, MSG_TX_ON),
MSG_TABLE(ENGLISH, MSG_CONTINUE),
MSG_TABLE(ENGLISH, MSG_CONTRAST),
MSG_TABLE(ENGLISH, MSG_BACKGR_LIGHT),
MSG_TABLE(ENGLISH, MSG_LIGHT),
MSG_TABLE(ENGLISH, MSG_LIGHT_OFF),
MSG_TABLE(ENGLISH, MSG_LIGHT_ON),
MSG_TABLE(ENGLISH, MSG_SEC),
MSG_TABLE(ENGLISH, MSG_BATTERY),
MSG_TABLE(ENGLISH, MSG_U_MIN),
MSG_TABLE(ENGLISH, MSG_U_SETUP),
MSG_TABLE(ENGLISH, MSG_U_OFFSET),
MSG_TABLE(ENGLISH, MSG_MK_BATTERY),
MSG_TABLE(ENGLISH, MSG_MK_BAT_NR),
MSG_TABLE(ENGLISH, MSG_MK_BAT_CAPACITY),
MSG_TABLE(ENGLISH, MSG_MK_I_OFFSET),
MSG_TABLE(ENGLISH, MSG_MK_I_FAKTOR),
MSG_TABLE(ENGLISH, MSG_MK_W_FAKTOR),
MSG_TABLE(ENGLISH, MSG_CALIBRATION),
MSG_TABLE(ENGLISH, MSG_RUNNING),
MSG_TABLE(ENGLISH, MSG_ERROR),
MSG_TABLE(ENGLISH, MSG_TX_NOT),
MSG_TABLE(ENGLISH, MSG_ACCU_LOW),
MSG_TABLE(ENGLISH, MSG_SERVO_CALIBR),
MSG_TABLE(ENGLISH, MSG_SERVO_STEPS),
MSG_TABLE(ENGLISH, MSG_SERVO1_REVERSE),
MSG_TABLE(ENGLISH, MSG_CALIB1_LEFT),
MSG_TABLE(ENGLISH, MSG_CALIB1_RIGHT),
MSG_TABLE(ENGLISH, MSG_CALIB1_MIDDLE),
MSG_TABLE(ENGLISH, MSG_SERVO2_REVERSE),
MSG_TABLE(ENGLISH, MSG_CALIB2_LEFT),
MSG_TABLE(ENGLISH, MSG_CALIB2_RIGHT),
MSG_TABLE(ENGLISH, MSG_CALIB2_MIDDLE),
MSG_TABLE(ENGLISH, MSG_FRAME),
MSG_TABLE(ENGLISH, MSG_PULSE_WIDTH),
MSG_TABLE(ENGLISH, MSG_CONTINOUS),
MSG_TABLE(ENGLISH, MSG_SINGLE_STE),
MSG_TABLE(ENGLISH, MSG_REPEAT),
MSG_TABLE(ENGLISH, MSG_PAUSE),
MSG_TABLE(ENGLISH, MSG_PAUSE_STEP),
MSG_TABLE(ENGLISH, MSG_COUNTER),
MSG_TABLE(ENGLISH, MSG_START),
MSG_TABLE(ENGLISH, MSG_OFF),
MSG_TABLE(ENGLISH, MSG_ON),
MSG_TABLE(ENGLISH, MSG_TRACKING),
MSG_TABLE(ENGLISH, MSG_TRACK_GPS),
MSG_TABLE(ENGLISH, MSG_TRACK_NMEA),
MSG_TABLE(ENGLISH, MSG_TRACK_TX_OSD_DATA),
MSG_TABLE(ENGLISH, MSG_HYSTERESE),
MSG_TABLE(ENGLISH, MSG_TRACK_TX_ON),
MSG_TABLE(ENGLISH, MSG_GPS_DISPLAY),
MSG_TABLE(ENGLISH, MSG_GPS_CALCULATE),
MSG_TABLE(ENGLISH, MSG_GPS_CURRENT),
MSG_TABLE(ENGLISH, MSG_GPS_HOME),
MSG_TABLE(ENGLISH, MSG_GPS_MISC),
MSG_TABLE(ENGLISH, MSG_GPS_NO_DATA),
MSG_TABLE(ENGLISH, MSG_RX_TIME),
MSG_TABLE(ENGLISH, MSG_COM),
MSG_TABLE(ENGLISH, MSG_KOMMA),
MSG_TABLE(ENGLISH, MSG_UHW33V),
};
 
PGM_P MessageTableFrench[LAST_NAT_MESSAGE+1] PROGMEM = {
MSG_TABLE(FRENCH, MSG_LANGUAGE),
MSG_TABLE(FRENCH, MSG_GERMAN),
MSG_TABLE(FRENCH, MSG_ENGLISH),
MSG_TABLE(FRENCH, MSG_FRENCH),
MSG_TABLE(FRENCH, MSG_RETURN),
MSG_TABLE(FRENCH, MSG_AV_SOURCE),
MSG_TABLE(FRENCH, MSG_RX_CHANNEL),
MSG_TABLE(FRENCH, MSG_RSSI_CALIBR),
MSG_TABLE(FRENCH, MSG_RSSI_MIN_ALL),
MSG_TABLE(FRENCH, MSG_RSSI_INVERT),
MSG_TABLE(FRENCH, MSG_TX_IDENTIFY),
MSG_TABLE(FRENCH, MSG_TX_STATUS_ON),
MSG_TABLE(FRENCH, MSG_TX_STATUS_OFF),
MSG_TABLE(FRENCH, MSG_TX_STATUS),
MSG_TABLE(FRENCH, MSG_CALIB),
MSG_TABLE(FRENCH, MSG_TX),
MSG_TABLE(FRENCH, MSG_TX_OFF),
MSG_TABLE(FRENCH, MSG_TX_ON),
MSG_TABLE(FRENCH, MSG_CONTINUE),
MSG_TABLE(FRENCH, MSG_CONTRAST),
MSG_TABLE(FRENCH, MSG_BACKGR_LIGHT),
MSG_TABLE(FRENCH, MSG_LIGHT),
MSG_TABLE(FRENCH, MSG_LIGHT_OFF),
MSG_TABLE(FRENCH, MSG_LIGHT_ON),
MSG_TABLE(FRENCH, MSG_SEC),
MSG_TABLE(FRENCH, MSG_BATTERY),
MSG_TABLE(FRENCH, MSG_U_MIN),
MSG_TABLE(FRENCH, MSG_U_SETUP),
MSG_TABLE(FRENCH, MSG_U_OFFSET),
MSG_TABLE(FRENCH, MSG_MK_BATTERY),
MSG_TABLE(FRENCH, MSG_MK_BAT_NR),
MSG_TABLE(FRENCH, MSG_MK_BAT_CAPACITY),
MSG_TABLE(FRENCH, MSG_MK_I_OFFSET),
MSG_TABLE(FRENCH, MSG_MK_I_FAKTOR),
MSG_TABLE(FRENCH, MSG_MK_W_FAKTOR),
MSG_TABLE(FRENCH, MSG_CALIBRATION),
MSG_TABLE(FRENCH, MSG_RUNNING),
MSG_TABLE(FRENCH, MSG_ERROR),
MSG_TABLE(FRENCH, MSG_TX_NOT),
MSG_TABLE(FRENCH, MSG_ACCU_LOW),
MSG_TABLE(FRENCH, MSG_SERVO_CALIBR),
MSG_TABLE(FRENCH, MSG_SERVO_STEPS),
MSG_TABLE(FRENCH, MSG_SERVO1_REVERSE),
MSG_TABLE(FRENCH, MSG_CALIB1_LEFT),
MSG_TABLE(FRENCH, MSG_CALIB1_RIGHT),
MSG_TABLE(FRENCH, MSG_CALIB1_MIDDLE),
MSG_TABLE(FRENCH, MSG_SERVO2_REVERSE),
MSG_TABLE(FRENCH, MSG_CALIB2_LEFT),
MSG_TABLE(FRENCH, MSG_CALIB2_RIGHT),
MSG_TABLE(FRENCH, MSG_CALIB2_MIDDLE),
MSG_TABLE(FRENCH, MSG_FRAME),
MSG_TABLE(FRENCH, MSG_PULSE_WIDTH),
MSG_TABLE(FRENCH, MSG_CONTINOUS),
MSG_TABLE(FRENCH, MSG_SINGLE_STE),
MSG_TABLE(FRENCH, MSG_REPEAT),
MSG_TABLE(FRENCH, MSG_PAUSE),
MSG_TABLE(FRENCH, MSG_PAUSE_STEP),
MSG_TABLE(FRENCH, MSG_COUNTER),
MSG_TABLE(FRENCH, MSG_START),
MSG_TABLE(FRENCH, MSG_OFF),
MSG_TABLE(FRENCH, MSG_ON),
MSG_TABLE(FRENCH, MSG_TRACKING),
MSG_TABLE(FRENCH, MSG_TRACK_GPS),
MSG_TABLE(FRENCH, MSG_TRACK_NMEA),
MSG_TABLE(FRENCH, MSG_TRACK_TX_OSD_DATA),
MSG_TABLE(FRENCH, MSG_HYSTERESE),
MSG_TABLE(FRENCH, MSG_TRACK_TX_ON),
MSG_TABLE(FRENCH, MSG_GPS_DISPLAY),
MSG_TABLE(FRENCH, MSG_GPS_CALCULATE),
MSG_TABLE(FRENCH, MSG_GPS_CURRENT),
MSG_TABLE(FRENCH, MSG_GPS_HOME),
MSG_TABLE(FRENCH, MSG_GPS_MISC),
MSG_TABLE(FRENCH, MSG_GPS_NO_DATA),
MSG_TABLE(FRENCH, MSG_RX_TIME),
MSG_TABLE(FRENCH, MSG_COM),
MSG_TABLE(FRENCH, MSG_KOMMA),
MSG_TABLE(FRENCH, MSG_UHW33V),
};
 
PGM_P MessageTableInternational[MESSAGE_LAST_MESSAGE+1] PROGMEM = {
MSG_TABLE(INTERNAT, MSG_RSSI_MIN),
MSG_TABLE(INTERNAT, MSG_RSSI_MAX),
MSG_TABLE(INTERNAT, MSG_DIVERSITY),
MSG_TABLE(INTERNAT, MSG_LCD),
MSG_TABLE(INTERNAT, MSG_AV1),
MSG_TABLE(INTERNAT, MSG_AV2),
MSG_TABLE(INTERNAT, MSG_RX1),
MSG_TABLE(INTERNAT, MSG_RX2),
MSG_TABLE(INTERNAT, MSG_STEPS_255),
MSG_TABLE(INTERNAT, MSG_STEPS_1023),
MSG_TABLE(INTERNAT, MSG_SERVO),
MSG_TABLE(INTERNAT, MSG_SERVO1),
MSG_TABLE(INTERNAT, MSG_SERVO2),
MSG_TABLE(INTERNAT, MSG_TEST_SERVO),
MSG_TABLE(INTERNAT, MSG_TRACK_RSSI),
MSG_TABLE(INTERNAT, MSG_TRACK_MKCOCKPIT),
MSG_TABLE(INTERNAT, MSG_TRACK_SERVO_HYTERESE),
MSG_TABLE(INTERNAT, MSG_BAUDRATE),
MSG_TABLE(INTERNAT, MSG_UHW5V),
MSG_TABLE(INTERNAT, MSG_VERSION1),
MSG_TABLE(INTERNAT, MSG_VERSION2)
};
 
char* Msg(MessageType Message)
{ static char Str[LCD_LINES * LCD_COLS + 1];
 
if (Message > LAST_NAT_MESSAGE)
strcpy_P(Str, (const char*)( pgm_read_word( &(MessageTableInternational[Message - LAST_NAT_MESSAGE - 1]))));
else
switch (language) {
case ENGLISH: strcpy_P(Str, (const char*)( pgm_read_word( &(MessageTableEnglish[Message]))));
break;
case FRENCH : strcpy_P(Str, (const char*)( pgm_read_word( &(MessageTableFrench[Message]))));
break;
default: strcpy_P(Str, (const char*)( pgm_read_word( &(MessageTableGerman[Message]))));
}
return(Str);
}
/NGVideo5_8/tags/v1.33/messages.h
0,0 → 1,407
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* using */
/* http://www.avrfreaks.net/ */
/* index.php?name=PNphpBB2&file=viewtopic&t=71985&view=previous*/
/* */
/****************************************************************/
 
#ifndef _MESSAGES_H_
#define _MESSAGES_H_
 
#include <avr/pgmspace.h>
 
/* International */
#define INTERNAT_RSSI_MIN "RSSI-Min"
#define INTERNAT_RSSI_MAX "RSSI-Max"
#define INTERNAT_DIVERSITY "Diversity"
#define INTERNAT_LCD "LCD"
#define INTERNAT_AV1 "AV1"
#define INTERNAT_AV2 "AV2"
#define INTERNAT_RX1 "1.RX:"
#define INTERNAT_RX2 "2.RX:"
#define INTERNAT_STEPS_255 "255"
#define INTERNAT_STEPS_1023 "1023"
#define INTERNAT_SERVO "Servo"
#define INTERNAT_SERVO1 "Servo 1"
#define INTERNAT_SERVO2 "Servo 2"
#define INTERNAT_TEST_SERVO "Servo-Test"
#define INTERNAT_TRACK_RSSI "RSSI"
#define INTERNAT_TRACK_MKCOCKPIT "MK-Cockpit"
#define INTERNAT_TRACK_SERVO_HYTERESE "Servo-Hyster."
#define INTERNAT_BAUDRATE "Baudrate"
#define INTERNAT_UHW5V " 5V"
#define INTERNAT_VERSION1 "NG-Video 5.8GHz\nHW: "
#define INTERNAT_VERSION2 " M.Beck""FW: "VERSION " gebad"
 
#define GERMAN_LANGUAGE "Sprache"
#define GERMAN_GERMAN "Deutsch"
#define GERMAN_ENGLISH "Englisch"
#define GERMAN_FRENCH "Franz""\x94""sisch"
#define GERMAN_RETURN "Zur""\x81""ck"
#define GERMAN_AV_SOURCE "AV-Quelle"
#define GERMAN_RX_CHANNEL "RX-Kanal"
#define GERMAN_RSSI_CALIBR "RSSI-Kalibr."
#define GERMAN_RSSI_MIN_ALL "Min alle Kan."
#define GERMAN_RSSI_INVERT "RSSI invert."
#define GERMAN_TX_IDENTIFY "TX erkennen"
#define GERMAN_TX_STATUS_ON "TX max-Calib."
#define GERMAN_TX_STATUS_OFF "TX min-Calib."
#define GERMAN_TX_STATUS "Sender: "
#define GERMAN_TX "Bitte TX auf "
#define GERMAN_TX_OFF "AUS"
#define GERMAN_TX_ON "EIN"
#define GERMAN_CONTINUE "Weiter mit Enter"
#define GERMAN_CONTRAST "Kontrast"
#define GERMAN_BACKGR_LIGHT "LCD-Beleucht."
#define GERMAN_LIGHT "Licht:"
#define GERMAN_LIGHT_OFF " immer aus"
#define GERMAN_LIGHT_ON " immer ein"
#define GERMAN_SEC " Sek."
#define GERMAN_BATTERY "Batterie"
#define GERMAN_U_MIN "U-Min"
#define GERMAN_U_SETUP "Untersp.-Setup"
#define GERMAN_U_OFFSET "U-Offset"
#define GERMAN_MSG_MK_BATTERY "MK-Batterie"
#define GERMAN_MSG_MK_BAT_NR "Bat. Nummer"
#define GERMAN_MSG_MK_BAT_CAPACITY "Bat. Kapazit""\x84""t"
#define GERMAN_MSG_MK_I_OFFSET "I-Offset"
#define GERMAN_MSG_MK_I_FAKTOR "I-Koeffizient"
#define GERMAN_MSG_MK_W_FAKTOR "W-Koeffizient"
#define GERMAN_CALIBRATION "Kalibrierung"
#define GERMAN_RUNNING "l""\x84""uft"
#define GERMAN_ERROR "Fehler!"
#define GERMAN_TX_NOT "Sender nicht "
#define GERMAN_ACCU_LOW " Akku\n entladen!"
#define GERMAN_SERVO_CALIBR "Servo-Kalibr."
#define GERMAN_SERVO_STEPS "Servo-Schritte"
#define GERMAN_CALIB "Kalib."
#define GERMAN_LEFT "links"
#define GERMAN_RIGHT "rechts"
#define GERMAN_MIDDLE "Mitte"
#define GERMAN_REVERSE "rev."
#define GERMAN_SERVO1_REVERSE INTERNAT_SERVO1 " " GERMAN_REVERSE
#define GERMAN_CALIB1_LEFT GERMAN_CALIB "1 " GERMAN_LEFT
#define GERMAN_CALIB1_RIGHT GERMAN_CALIB "1 " GERMAN_RIGHT
#define GERMAN_CALIB1_MIDDLE GERMAN_CALIB "1 " GERMAN_MIDDLE
#define GERMAN_SERVO2_REVERSE INTERNAT_SERVO2 " " GERMAN_REVERSE
#define GERMAN_CALIB2_LEFT GERMAN_CALIB "2 " GERMAN_LEFT
#define GERMAN_CALIB2_RIGHT GERMAN_CALIB "2 " GERMAN_RIGHT
#define GERMAN_CALIB2_MIDDLE GERMAN_CALIB "2 " GERMAN_MIDDLE
#define GERMAN_FRAME "Periode"
#define GERMAN_PULSE_WIDTH "Test Pulsl""\x84""nge"
#define GERMAN_CONTINOUS "Test fortlauf."
#define GERMAN_SINGLE_STEP "Einzelschritte"
#define GERMAN_REPEAT "Anzahl Tests"
#define GERMAN_PAUSE "Pause Endpos."
#define GERMAN_PAUSE_STEP "Pause pro Inc."
#define GERMAN_COUNTER "Z""\x84""hler:"
#define GERMAN_START "Start Test"
#define GERMAN_OFF "aus"
#define GERMAN_ON "ein"
#define GERMAN_TRACKING "Antenne nachf."
#define GERMAN_TRACK_GPS "GPS mit wi232"
#define GERMAN_TRACK_NMEA "NMEA GPS"
#define GERMAN_TRACK_TX_OSD_DATA "TX OSD-Daten"
#define GERMAN_HYSTERESE "Hysterese"
#define GERMAN_TRACK_TX_ON "Sende Forderung"
#define GERMAN_GPS_DISPLAY "GPS-Anzeigen"
#define GERMAN_GPS_CALCULATE "berechn. Daten"
#define GERMAN_GPS_CURRENT "aktuelle Pos."
#define GERMAN_GPS_HOME "Startposition"
#define GERMAN_GPS_MISC "Elektr. Werte"
#define GERMAN_GPS_NO_DATA " Noch\n keine Daten\n empfangen!"
#define GERMAN_RX_TIME "RX-Zeit"
#define GERMAN_COM "Seriell COM"
#define GERMAN_KOMMA ","
#define GERMAN_UHW33V "3,3V"
 
#define ENGLISH_LANGUAGE "Language"
#define ENGLISH_GERMAN "German"
#define ENGLISH_ENGLISH "English"
#define ENGLISH_FRENCH "French"
#define ENGLISH_RETURN "Return"
#define ENGLISH_AV_SOURCE "AV-Source"
#define ENGLISH_RX_CHANNEL "RX-Channel"
#define ENGLISH_RSSI_CALIBR "RSSI-Calibr."
#define ENGLISH_RSSI_MIN_ALL "Min all Chan."
#define ENGLISH_RSSI_INVERT "RSSI invert"
#define ENGLISH_TX_IDENTIFY "TX identify"
#define ENGLISH_TX_STATUS_ON "TX max-Calib."
#define ENGLISH_TX_STATUS_OFF "TX min-Calib."
#define ENGLISH_TX_STATUS "Sender: "
#define ENGLISH_TX "TX switch "
#define ENGLISH_TX_OFF "OFF"
#define ENGLISH_TX_ON "ON"
#define ENGLISH_CONTINUE "Continue Enter"
#define ENGLISH_CONTRAST "Contrast"
#define ENGLISH_BACKGR_LIGHT "Backgr. Light"
#define ENGLISH_LIGHT "Light:"
#define ENGLISH_LIGHT_OFF "always off"
#define ENGLISH_LIGHT_ON " always on"
#define ENGLISH_SEC " sec."
#define ENGLISH_BATTERY "Battery"
#define ENGLISH_U_MIN "U-Min"
#define ENGLISH_U_SETUP "Low voltage"
#define ENGLISH_U_OFFSET "U-Offset"
#define ENGLISH_MSG_MK_BATTERY "MK-Battery"
#define ENGLISH_MSG_MK_BAT_NR "Bat. Number"
#define ENGLISH_MSG_MK_BAT_CAPACITY "Bat. Capacity"
#define ENGLISH_MSG_MK_I_OFFSET "I-Offset"
#define ENGLISH_MSG_MK_I_FAKTOR "I-Coefficient"
#define ENGLISH_MSG_MK_W_FAKTOR "W-Coefficient"
#define ENGLISH_CALIBRATION "Calibration"
#define ENGLISH_RUNNING "running"
#define ENGLISH_ERROR "Error!"
#define ENGLISH_TX_NOT "Transmitter not "
#define ENGLISH_ACCU_LOW " Accu\n low!"
#define ENGLISH_SERVO_CALIBR "Servo-Calibr."
#define ENGLISH_SERVO_STEPS "Servo-Steps"
#define ENGLISH_CALIB "Calib."
#define ENGLISH_LEFT "left"
#define ENGLISH_RIGHT "right"
#define ENGLISH_MIDDLE "middle"
#define ENGLISH_REVERSE "rev."
#define ENGLISH_SERVO1_REVERSE INTERNAT_SERVO1 " " ENGLISH_REVERSE
#define ENGLISH_CALIB1_LEFT ENGLISH_CALIB "1 " ENGLISH_LEFT
#define ENGLISH_CALIB1_RIGHT ENGLISH_CALIB "1 " ENGLISH_RIGHT
#define ENGLISH_CALIB1_MIDDLE ENGLISH_CALIB "1 " ENGLISH_MIDDLE
#define ENGLISH_SERVO2_REVERSE INTERNAT_SERVO2 " " ENGLISH_REVERSE
#define ENGLISH_CALIB2_LEFT ENGLISH_CALIB "2 " ENGLISH_LEFT
#define ENGLISH_CALIB2_RIGHT ENGLISH_CALIB "2 " ENGLISH_RIGHT
#define ENGLISH_CALIB2_MIDDLE ENGLISH_CALIB "2 " ENGLISH_MIDDLE
#define ENGLISH_FRAME "Periode"
#define ENGLISH_PULSE_WIDTH "Test PW"
#define ENGLISH_CONTINOUS "Test contin."
#define ENGLISH_SINGLE_STEP "Single step"
#define ENGLISH_REPEAT "Number of test"
#define ENGLISH_PAUSE "Pause end pos."
#define ENGLISH_PAUSE_STEP "Pause pro inc."
#define ENGLISH_COUNTER "Counter:"
#define ENGLISH_START "Start Test"
#define ENGLISH_OFF "off"
#define ENGLISH_ON "on "
#define ENGLISH_TRACKING "Tracking"
#define ENGLISH_TRACK_GPS "GPS with wi232"
#define ENGLISH_TRACK_NMEA "NMEA GPS"
#define ENGLISH_TRACK_TX_OSD_DATA "TX OSD-Data"
#define ENGLISH_HYSTERESE "Hysterese"
#define ENGLISH_TRACK_TX_ON "Transmit demand"
#define ENGLISH_GPS_DISPLAY "Display GPS"
#define ENGLISH_GPS_CALCULATE "calc. Data"
#define ENGLISH_GPS_CURRENT "current Pos."
#define ENGLISH_GPS_HOME "Homeposition"
#define ENGLISH_GPS_MISC "Elictric Val."
#define ENGLISH_GPS_NO_DATA " Not yet\n Data\n received!"
#define ENGLISH_RX_TIME "RX-Time"
#define ENGLISH_COM "Seriell COM"
#define ENGLISH_KOMMA "."
#define ENGLISH_UHW33V "3.3V"
 
#define FRENCH_LANGUAGE "Langue"
#define FRENCH_GERMAN "Allemand"
#define FRENCH_ENGLISH "Anglais"
#define FRENCH_FRENCH "Fran""\x87""ais"
#define FRENCH_RETURN "Retour"
#define FRENCH_AV_SOURCE "AV-Source"
#define FRENCH_RX_CHANNEL "RX-Canal"
#define FRENCH_RSSI_CALIBR "RSSI-Calibr."
#define FRENCH_RSSI_MIN_ALL "Tout""\x85""z""\x82""ro"
#define FRENCH_RSSI_INVERT "RSSI invert"
#define FRENCH_TX_IDENTIFY "TX discerner"
#define FRENCH_TX_STATUS_ON "TX max-Calib."
#define FRENCH_TX_STATUS_OFF "TX min-Calib."
#define FRENCH_TX_STATUS "TX: "
#define FRENCH_TX ""
#define FRENCH_TX_OFF "Eteindre Tx"
#define FRENCH_TX_ON "Allumer Tx"
#define FRENCH_CONTINUE "App. Enter"
#define FRENCH_CONTRAST "Contraste"
#define FRENCH_BACKGR_LIGHT "Retr. Ecl"
#define FRENCH_LIGHT "Eclai:"
#define FRENCH_LIGHT_OFF " Eteint"
#define FRENCH_LIGHT_ON " Tjrs ON"
#define FRENCH_SEC " Sec."
#define FRENCH_BATTERY "Batterie"
#define FRENCH_U_MIN "V-Min"
#define FRENCH_U_SETUP "Seuil Alarme"
#define FRENCH_U_OFFSET "V-Offset"
#define FRENCH_MSG_MK_BATTERY "MK-Batterie"
#define FRENCH_MSG_MK_BAT_NR "Bat. num""\x82""ro"
#define FRENCH_MSG_MK_BAT_CAPACITY "Bat. capacit""\x82"
#define FRENCH_MSG_MK_I_OFFSET "I-Offset"
#define FRENCH_MSG_MK_I_FAKTOR "I-Coefficient"
#define FRENCH_MSG_MK_W_FAKTOR "W-Coefficient"
#define FRENCH_CALIBRATION "Calibration"
#define FRENCH_RUNNING "En cours"
#define FRENCH_ERROR "Erreur!"
#define FRENCH_TX_NOT "No Tx"
#define FRENCH_ACCU_LOW " Batterie\n faible!"
#define FRENCH_SERVO_CALIBR "Servo-Calibr"
#define FRENCH_SERVO_STEPS "Nbre de Pas"
#define FRENCH_CALIB "Calib."
#define FRENCH_LEFT "Gauche"
#define FRENCH_RIGHT "Droit"
#define FRENCH_MIDDLE "Milieu"
#define FRENCH_REVERSE "Inversion"
#define FRENCH_SERVO1_REVERSE "Invers. Servo1"
#define FRENCH_CALIB1_LEFT "Cal. Gauche"
#define FRENCH_CALIB1_RIGHT "Cal. Droite"
#define FRENCH_CALIB1_MIDDLE "Cal. Centre"
#define FRENCH_SERVO2_REVERSE "Invers. Servo2"
#define FRENCH_CALIB2_LEFT "Cal. Gauche"
#define FRENCH_CALIB2_RIGHT "Cal. Droite"
#define FRENCH_CALIB2_MIDDLE "Cal. Centre"
#define FRENCH_FRAME "P""\x82""riode"
#define FRENCH_PULSE_WIDTH "Largeur Imp."
#define FRENCH_CONTINOUS "Test Continu"
#define FRENCH_SINGLE_STEP "1 Pas"
#define FRENCH_REPEAT "Nombre Tests"
#define FRENCH_PAUSE "Pause finale"
#define FRENCH_PAUSE_STEP "Pause par pas"
#define FRENCH_COUNTER "Compter:"
#define FRENCH_START "D""\x82""but Test"
#define FRENCH_OFF "OFF"
#define FRENCH_ON "ON "
#define FRENCH_TRACKING "Tracking"
#define FRENCH_TRACK_GPS "GPS with wi232"
#define FRENCH_TRACK_NMEA "NMEA GPS"
#define FRENCH_TRACK_TX_OSD_DATA "TX OSD-Data"
#define FRENCH_HYSTERESE "Hysteresis"
#define FRENCH_TRACK_TX_ON "Donn""\x82""e Transmie"
#define FRENCH_GPS_DISPLAY "Affichage GPS"
#define FRENCH_GPS_CALCULATE "Calcul GPS"
#define FRENCH_GPS_CURRENT "Pos. actuelle"
#define FRENCH_GPS_HOME "Homeposition"
#define FRENCH_GPS_MISC "\x90""l""\x82""ctr. val."
#define FRENCH_GPS_NO_DATA " Aucune donn""\x82""e\n re""\x87""ue!"
#define FRENCH_RX_TIME "RX-Temps"
#define FRENCH_COM "COM. S""\x82""rie"
#define FRENCH_KOMMA "."
#define FRENCH_UHW33V "3.3V"
 
 
/* Languages */
#define GERMAN 0
#define ENGLISH 1
#define FRENCH 2
#define LAST_LANG 2
#define INTERNAT LAST_LANG + 1
#define NO_LANGUAGE 254 // für Sprachabfrage bei Erstinbetriebnahme NGVideo
 
/* Message languages */
#define MSG_LANGUAGE 0
#define MSG_GERMAN 1
#define MSG_ENGLISH 2
#define MSG_FRENCH 3
#define MSG_RETURN 4
#define MSG_AV_SOURCE 5
#define MSG_RX_CHANNEL 6
#define MSG_RSSI_CALIBR 7
#define MSG_RSSI_MIN_ALL 8
#define MSG_RSSI_INVERT 9
#define MSG_TX_IDENTIFY 10
#define MSG_TX_STATUS_ON 11
#define MSG_TX_STATUS_OFF 12
#define MSG_TX_STATUS 13
#define MSG_CALIB 14
#define MSG_TX 15
#define MSG_TX_OFF 16
#define MSG_TX_ON 17
#define MSG_CONTINUE 18
#define MSG_CONTRAST 19
#define MSG_BACKGR_LIGHT 20
#define MSG_LIGHT 21
#define MSG_LIGHT_OFF 22
#define MSG_LIGHT_ON 23
#define MSG_SEC 24
#define MSG_BATTERY 25
#define MSG_U_MIN 26
#define MSG_U_SETUP 27
#define MSG_U_OFFSET 28
#define MSG_MK_BATTERY 29
#define MSG_MK_BAT_NR 30
#define MSG_MK_BAT_CAPACITY 31
#define MSG_MK_I_OFFSET 32
#define MSG_MK_I_FAKTOR 33
#define MSG_MK_W_FAKTOR 34
#define MSG_CALIBRATION 35
#define MSG_RUNNING 36
#define MSG_ERROR 37
#define MSG_TX_NOT 38
#define MSG_ACCU_LOW 39
#define MSG_SERVO_CALIBR 40
#define MSG_SERVO_STEPS 41
#define MSG_SERVO1_REVERSE 42
#define MSG_CALIB1_LEFT 43
#define MSG_CALIB1_RIGHT 44
#define MSG_CALIB1_MIDDLE 45
#define MSG_SERVO2_REVERSE 46
#define MSG_CALIB2_LEFT 47
#define MSG_CALIB2_RIGHT 48
#define MSG_CALIB2_MIDDLE 49
#define MSG_FRAME 50
#define MSG_PULSE_WIDTH 51
#define MSG_CONTINOUS 52
#define MSG_SINGLE_STEP 53
#define MSG_REPEAT 54
#define MSG_PAUSE 55
#define MSG_PAUSE_STEP 56
#define MSG_COUNTER 57
#define MSG_START 58
#define MSG_OFF 59
#define MSG_ON 60
#define MSG_TRACKING 61
#define MSG_TRACK_GPS 62
#define MSG_TRACK_NMEA 63
#define MSG_TRACK_TX_OSD_DATA 64
#define MSG_HYSTERESE 65
#define MSG_TRACK_TX_ON 66
#define MSG_GPS_DISPLAY 67
#define MSG_GPS_CALCULATE 68
#define MSG_GPS_CURRENT 69
#define MSG_GPS_HOME 70
#define MSG_GPS_MISC 71
#define MSG_GPS_NO_DATA 72
#define MSG_RX_TIME 73
#define MSG_COM 74
#define MSG_KOMMA 75
#define MSG_UHW33V 76
#define LAST_NAT_MESSAGE 76
 
/* International */
#define MSG_RSSI_MIN 0 + LAST_NAT_MESSAGE + 1
#define MSG_RSSI_MAX 1 + LAST_NAT_MESSAGE + 1
#define MSG_DIVERSITY 2 + LAST_NAT_MESSAGE + 1
#define MSG_LCD 3 + LAST_NAT_MESSAGE + 1
#define MSG_AV1 4 + LAST_NAT_MESSAGE + 1
#define MSG_AV2 5 + LAST_NAT_MESSAGE + 1
#define MSG_RX1 6 + LAST_NAT_MESSAGE + 1
#define MSG_RX2 7 + LAST_NAT_MESSAGE + 1
#define MSG_STEPS_255 8 + LAST_NAT_MESSAGE + 1
#define MSG_STEPS_1023 9 + LAST_NAT_MESSAGE + 1
#define MSG_SERVO 10 + LAST_NAT_MESSAGE + 1
#define MSG_SERVO1 11 + LAST_NAT_MESSAGE + 1
#define MSG_SERVO2 12 + LAST_NAT_MESSAGE + 1
#define MSG_TEST_SERVO 13 + LAST_NAT_MESSAGE + 1
#define MSG_TRACK_RSSI 14 + LAST_NAT_MESSAGE + 1
#define MSG_TRACK_MKCOCKPIT 15 + LAST_NAT_MESSAGE + 1
#define MSG_TRACK_SERVO_HYTERESE 16 + LAST_NAT_MESSAGE + 1
#define MSG_BAUDRATE 17 + LAST_NAT_MESSAGE + 1
#define MSG_UHW5V 18 + LAST_NAT_MESSAGE + 1
#define MSG_VERSION1 19 + LAST_NAT_MESSAGE + 1
#define MSG_VERSION2 20 + LAST_NAT_MESSAGE + 1
#define MESSAGE_LAST_MESSAGE 20
 
typedef uint16_t MessageType;
char* Msg(MessageType Message);
 
#endif /* _MESSAGES_H_ */
/NGVideo5_8/tags/v1.33/mk.h
0,0 → 1,59
#ifndef _MK_H_
#define _MK_H_
 
// Orginal H&I MK-Software
typedef struct {
int32_t Longitude; // in 1E-7 deg
int32_t Latitude; // in 1E-7 deg
int32_t Altitude; // in mm
uint8_t Status; // validity of data
} __attribute__((packed)) GPS_Pos_t;
 
 
typedef struct {
uint16_t Distance; // distance to target in dm
int16_t Bearing; // course to target in deg
} __attribute__((packed)) GPS_PosDev_t;
 
 
#define FC_FLAG_MOTOR_RUN 0x01
#define FC_FLAG_FLY 0x02
#define FC_FLAG_CALIBRATE 0x04
#define FC_FLAG_MOTOR_START 0x08
 
#define NC_FLAG_GPS_OK 0x80
 
typedef struct {
uint8_t Version; // version of the data structure
GPS_Pos_t CurrentPosition; // see ubx.h for details
GPS_Pos_t TargetPosition;
GPS_PosDev_t TargetPositionDeviation;
GPS_Pos_t HomePosition;
GPS_PosDev_t HomePositionDeviation;
uint8_t WaypointIndex; // index of current waypoints running from 0 to WaypointNumber-1
uint8_t WaypointNumber; // number of stored waypoints
uint8_t SatsInUse; // number of satellites used for position solution
int16_t Altimeter; // hight according to air pressure
int16_t Variometer; // climb(+) and sink(-) rate
uint16_t FlyingTime; // in seconds
uint8_t UBat; // Battery Voltage in 0.1 Volts
uint16_t GroundSpeed; // speed over ground in cm/s (2D)
int16_t Heading; // current flight direction in ° as angle to north
int16_t CompassHeading; // current compass value in °
int8_t AngleNick; // current Nick angle in 1°
int8_t AngleRoll; // current Rick angle in 1°
uint8_t RC_Quality; // RC_Quality
uint8_t FCStatusFlags; // Flags from FC
uint8_t NCFlags; // Flags from NC
uint8_t Errorcode; // 0 --> okay
uint8_t OperatingRadius; // current operation radius around the Home Position in m
int16_t TopSpeed; // velocity in vertical direction in cm/s
uint8_t TargetHoldTime; // time in s to stay at the given target, counts down to 0 if target has been reached
uint8_t RC_RSSI; // Receiver signal strength (since version 2 added)
int16_t SetpointAltitude; // setpoint for altitude
uint8_t Gas; // for future use
uint16_t Current; // actual current in 0.1A steps
uint16_t UsedCapacity; // used capacity in mAh
} __attribute__((packed)) NaviData_t;
 
#endif
/NGVideo5_8/tags/v1.33/mymath.c
0,0 → 1,184
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <avr/pgmspace.h>
 
#include "mymath.h"
 
// http://www.mikrocontroller.net/articles/AVR_Arithmetik#avr-gcc_Implementierung_.2832_Bit.29
unsigned int sqrt32(uint32_t q)
{ uint16_t r, mask;
uint16_t i = 8*sizeof (r) -1;
r = mask = 1 << i;
for (; i > 0; i--) {
mask >>= 1;
if (q < (uint32_t) r*r)
r -= mask;
else
r += mask;
}
if (q < (uint32_t) r*r)
r -= 1;
return r;
}
 
// aus Orginal MK source code
// sinus with argument in degree at an angular resolution of 1 degree and a discretisation of 13 bit.
const uint16_t sinlookup[91] = {0, 143, 286, 429, 571, 714, 856, 998, 1140, 1282, 1423, 1563, 1703, \
1843, 1982, 2120, 2258, 2395, 2531, 2667, 2802, 2936, 3069, 3201, 3332, \
3462, 3591, 3719, 3846, 3972, 4096, 4219, 4341, 4462, 4581, 4699, 4815, \
4930, 5043, 5155, 5266, 5374, 5482, 5587, 5691, 5793, 5893, 5991, 6088, \
6183, 6275, 6366, 6455, 6542, 6627, 6710, 6791, 6870, 6947, 7022, 7094, \
7165, 7233, 7299, 7363, 7424, 7484, 7541, 7595, 7648, 7698, 7746, 7791, \
7834, 7875, 7913, 7949, 7982, 8013, 8041, 8068, 8091, 8112, 8131, 8147, \
8161, 8172, 8181, 8187, 8191, 8192};
 
//double c_cos_8192(int16_t angle)
int16_t c_cos_8192(int16_t angle)
{
int8_t m,n;
int16_t sinus;
 
angle = 90 - angle;
// avoid negative angles
if (angle < 0)
{
m = -1;
angle = -angle;
}
else m = +1;
 
// fold angle to interval 0 to 359
angle %= 360;
 
// check quadrant
if (angle <= 90) n = 1; // first quadrant
else if ((angle > 90) && (angle <= 180)) {angle = 180 - angle; n = 1;} // second quadrant
else if ((angle > 180) && (angle <= 270)) {angle = angle - 180; n = -1;} // third quadrant
else {angle = 360 - angle; n = -1;} //fourth quadrant
// get lookup value
sinus = sinlookup[angle];
// calculate sinus value
return (sinus * m * n);
}
 
/* ----------------------------------------------------------------------------------------------
 
atan2.S
 
Author: Reiner Patommel
atan2.S uses CORDIC, an algorithm which was developed in 1956 by Jack Volder.
CORDIC can be used to calculate trigonometric, hyperbolic and linear
functions and is until today implemented in most pocket calculators.
The algorithm makes only use of simple integer arithmetic.
 
The CORDIC equations in vectoring mode for trigonometric functions are:
Xi+1 = Xi - Si * (Yi * 1 / 2^i)
Yi+1 = Yi + Si * (Xi * 1 / 2^i)
Zi+1 = Zi - Si * atan(1 / 2^i)
where Si = +1 if Yi < 0 else Si = -1
The rotation angles are limited to -PI/2 and PI/2 i.e.
-90 degrees ... +90 degrees
 
For the calculation of atan2(x,y) we need a small pre-calculated table of
angles or radians with the values Tn = atan(1/2^i).
We rotate the vector(Xo,Yo) in steps to the x-axis i.e. we drive Y to 0 and
accumulate the rotated angles or radians in Z. The direction of the rotation
will be positive or negative depending on the sign of Y after the previous
rotation and the rotation angle will decrease from step to step. (The first
step is 45 degrees, the last step is 0.002036 degrees for n = 15).
 
After n rotations the variables will have the following values:
Yn = ideally 0
Xn = c*sqrt(Xo^2+Yo^2) (magnitude of the vector)
Zn = Zo+atan(Yo/Xo) (accumulated rotation angles or radians)
 
c, the cordic gain, is the product Pn of sqrt(1+2^(-2i)) and amounts to
approx. 1.64676 for n = 15.
 
In order to represent X, Y and Z as integers we introduce a scaling factor Q
which is chosen as follows:
1. We normalize Xo and Yo (starting values) to be less than or equal to 1*Q and
set Zo = 0 i.e. Xomax = 1*Q, Yomax = 1*Q, Zo = 0.
2. With Xo = 1*Q and Yo = 1*Q, Xn will be Xnmax = Q*c*sqrt(2) = 2.329*Q
3. In order to boost accuracy we only cover the rotation angles between 0 and PI/2
i.e. X and Z are always > 0 and therefore can be unsigned.
(We do the quadrant correction afterwards based on the initial signs of x and y)
4. If X is an unsigned int, Xnmax = 65536, and Q = 65536/2.329 = 28140.
i.e.
Xnmax = 65536 --> unsigned int
Ynmax = +/- 28140 --> signed int
Znmax = PI/2 * 28140 = 44202 --> unsigned int
The systematic error is 90/44202 = 0.002036 degrees or 0.0000355 rad.
Below is atan2 and atan in C: */
 
#define getAtanVal(x) (uint16_t)pgm_read_word(&atantab[x])
//uint16_t atantab[T] PROGMEM = {22101,13047,6894,3499,1756,879,440,220,110,55,27,14,7,3,2,1}; // T 16
// Genauigkeit etwas eingeschränkt, da Servos nur in 1° Abständen positioniert werden
uint16_t atantab[T] PROGMEM = {22101,13047,6894,3499,1756,879,440,220,110,55,27,14,7,3};
 
// max. Wert für y oder x ist 76314
int16_t my_atan2(int32_t y, int32_t x)
{ unsigned char i;
uint32_t x1;
int32_t y1;
uint32_t angle = 0;
uint32_t tmp;
 
x1 = abs(x);
y1 = abs(y);
 
if (y1 == 0) {
if (x < 0)
return (180);
else
return 0;
}
if (x1 < y1) {
x1 = SCALED(x1) / y1;
y1 = Q;
}
else {
y1 = SCALED(y1) / x1;
x1 = Q;
}
for (i = 0; i < T-1; i++) {
tmp = x1 >> i;
if (y1 < 0) {
x1 -= y1 >> i;
y1 += tmp;
angle -= getAtanVal(i);
}
else {
x1 += y1 >> i;
y1 -= tmp;
angle += getAtanVal(i);
}
}
 
angle = angle/RQ; // RAD_TO_DEG * angle / Q
if (x <= 0)
angle = 180 - angle;
if (y <= 0)
return(-angle);
return(angle);
}
/NGVideo5_8/tags/v1.33/mymath.h
0,0 → 1,16
#ifndef _MYMATH_H_
#define _MYMATH_H_
 
#include <avr/io.h>
 
#define T 14 //16
#define Q 28140
#define SCALED(X) ((int32_t)((X) * Q))
#define RAD_TO_DEG 57.2957795 // radians to degrees = 180 / PI
#define RQ (uint16_t)(Q / RAD_TO_DEG)
 
uint16_t sqrt32(uint32_t qzahl);
int16_t c_cos_8192(int16_t angle);
int16_t my_atan2(int32_t y, int32_t x);
 
#endif
/NGVideo5_8/tags/v1.33/ngvideo.avrgccproj
0,0 → 1,170
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>5.0</ProjectVersion>
<ProjectGuid>c0066cc9-6e35-4d76-9ffe-a4af66a2de41</ProjectGuid>
<avrdevice>ATmega644A</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>C</Language>
<OutputFile>ngvideo.elf</OutputFile>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<UseGlobalToolchain>False</UseGlobalToolchain>
<ToolchainDirPath>C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR Toolchain\bin</ToolchainDirPath>
<MakeDirPath>C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR Toolchain\bin</MakeDirPath>
<GlobalToolchainPath>C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR ToolChain\bin</GlobalToolchainPath>
<AvrGccProjectExtensions>
</AvrGccProjectExtensions>
<avrtool>com.atmel.avrdbg.tool.simulator</avrtool>
<preserveEEPROM>True</preserveEEPROM>
<avrtoolinterface>JTAG</avrtoolinterface>
<com_atmel_avrdbg_tool_avrdragon>
<ToolType>com.atmel.avrdbg.tool.avrdragon</ToolType>
<ToolName>AVR Dragon</ToolName>
<ToolNumber>00A200005843</ToolNumber>
<Channel>
<host>127.0.0.1</host>
<port>9042</port>
<ssl>False</ssl>
</Channel>
<ToolOptions>
<InterfaceName>JTAG</InterfaceName>
<InterfaceProperties>
<JtagDbgClock>200000</JtagDbgClock>
<JtagProgClock>1000000</JtagProgClock>
<IspClock>150000</IspClock>
<JtagInChain>false</JtagInChain>
<JtagEnableExtResetOnStartSession>false</JtagEnableExtResetOnStartSession>
<JtagDevicesBefore>0</JtagDevicesBefore>
<JtagDevicesAfter>0</JtagDevicesAfter>
<JtagInstrBitsBefore>0</JtagInstrBitsBefore>
<JtagInstrBitsAfter>0</JtagInstrBitsAfter>
</InterfaceProperties>
</ToolOptions>
</com_atmel_avrdbg_tool_avrdragon>
<com_atmel_avrdbg_tool_simulator>
<ToolType xmlns="">com.atmel.avrdbg.tool.simulator</ToolType>
<ToolName xmlns="">AVR Simulator</ToolName>
<ToolNumber xmlns="">
</ToolNumber>
<Channel xmlns="">
<host>127.0.0.1</host>
<port>1486</port>
<ssl>False</ssl>
</Channel>
</com_atmel_avrdbg_tool_simulator>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'default' ">
<OutputPath>bin\default\</OutputPath>
<MemorySettings>
<MemorySegments>
<InitialStack IsEnabled="0">
<Address>0x1000</Address>
</InitialStack>
</MemorySegments>
</MemorySettings>
<ToolchainSettings>
<AvrGcc>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.miscellaneous.OtherFlags>-gdwarf-2 -std=gnu99 </avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcc.assembler.general.AssemblerFlags>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</avrgcc.assembler.general.AssemblerFlags>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g2)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc>
</ToolchainSettings>
<UsesExternalMakeFile>True</UsesExternalMakeFile>
<ExternalMakeFilePath>D:\Daten\Entwicklung\FW NGVideo-5.8GHz\tags\ngvideo\makefile</ExternalMakeFilePath>
<GenerateHexFile>True</GenerateHexFile>
<OutputDirectory>D:\Daten\Entwicklung\FW NGVideo-5.8GHz\tags\ngvideo</OutputDirectory>
</PropertyGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\AvrGCC.targets" />
<ItemGroup>
<Compile Include="config.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="dogm.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="dogm.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="keys.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="keys.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="lipo.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="lipo.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="main.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="menue.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="menue.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="messages.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="messages.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="mk.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="mymath.c">
<SubType>compile</SubType>
<Link>mymath.c</Link>
</Compile>
<Compile Include="mymath.h">
<SubType>compile</SubType>
<Link>mymath.h</Link>
</Compile>
<Compile Include="ngvideo.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="ngvideo.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="servo.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="servo.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="tools.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="tools.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="tracking.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="tracking.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="usart.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="usart.h">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="makefile">
<SubType>compile</SubType>
</None>
</ItemGroup>
</Project>
/NGVideo5_8/tags/v1.33/ngvideo.avrsln
0,0 → 1,17

Microsoft Visual Studio Solution File, Format Version 11.00
# AvrStudio Solution File, Format Version 11.00
Project("{D1100916-62DA-4D80-A9B4-55A1E7CCEEB3}") = "ngvideo", "ngvideo.avrgccproj", "{C0066CC9-6E35-4D76-9FFE-A4AF66A2DE41}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
default|AVR = default|AVR
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C0066CC9-6E35-4D76-9FFE-A4AF66A2DE41}.default|AVR.ActiveCfg = default|AVR
{C0066CC9-6E35-4D76-9FFE-A4AF66A2DE41}.default|AVR.Build.0 = default|AVR
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
/NGVideo5_8/tags/v1.33/ngvideo.avrsuo
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/NGVideo5_8/tags/v1.33/ngvideo.aws
0,0 → 1,0
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATMEGA644"/><Files><File00000 Name="C:\Source\atmel4\ngvideo\tracking.c" Position="354 210 1296 580" LineCol="157 0" State="Maximized"/><File00001 Name="C:\Source\atmel4\ngvideo\usart.c" Position="262 99 1370 654" LineCol="238 0" State="Maximized"/><File00002 Name="C:\Source\atmel4\ngvideo\usart.h" Position="288 144 1212 496" LineCol="41 4" State="Maximized"/></Files></AVRWorkspace>
/NGVideo5_8/tags/v1.33/ngvideo.c
0,0 → 1,855
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <util/delay.h>
 
#include "config.h"
#include "dogm.h"
#include "messages.h"
#include "ngvideo.h"
#include "menue.h"
#include "servo.h"
#include "tools.h"
#include "keys.h"
#include "usart.h"
#include "tracking.h"
 
// LCD selbst definierte Sonderzeichen, RSSI-Balken und wi232 Empfang Daten im Flash
// deshalb in dogm.c lcdPutc(pgm_read_byte(&lcdChr[i]));
SpecialChr_t lcdSpecialChr[7] PROGMEM = {{32,32,16,16,16,16,32,32},
{32,32,24,24,24,24,32,32},
{32,32,28,28,28,28,32,32},
{32,32,30,30,30,30,32,32},
{32,32,31,31,31,31,32,32},
{6,8,20,19,20,8,6,32},
{4,10,32,14,4,4,14,32}}; // Antenne und Imax
 
SpecialChr_t lcdSpecialChrLs[8] PROGMEM = {{32,1,1,1,1,1,1,32},
{32,31,1,1,1,1,31,32},
{32,31,3,3,3,3,31,32},
{32,31,7,7,7,7,31,32},
{32,31,15,15,15,15,31,32},
{32,31,31,31,31,31,31,32},
{32,16,16,16,16,16,16,32},
{32,31,32,32,32,32,31,32}};
 
SpecialChr_t lcdSpecialChrRs[5] PROGMEM = {{32,1,1,1,1,1,1,32},
{32,31,16,16,16,16,31,32},
{32,31,24,24,24,24,31,32},
{32,31,28,28,28,28,31,32},
{32,31,30,30,30,30,31,32}};
 
/**************************************************************/
/* */
/* EEPROM */
/* */
/**************************************************************/
uint8_t ep_eep_init EEPROM;
char ep_version[sizeof(VERSION)] EEPROM;
uint8_t ep_dogm_vers EEPROM;
uint8_t ep_contrast EEPROM;
uint8_t ep_light_time EEPROM;
uint8_t ep_u_offset EEPROM;
uint16_t ep_u_min EEPROM;
uint8_t ep_rssi_inv EEPROM;
uint8_t ep_channel EEPROM;
uint8_t ep_av_source EEPROM;
uint8_t ep_language EEPROM;
udbm_t ep_udbm[CHANNEL_MAX] EEPROM;
uint16_t ep_tx_value_on EEPROM;
uint16_t ep_tx_value_off EEPROM;
uint8_t ep_sIdxSteps EEPROM;
servo_t ep_servo[SERVO_NUM_CHANNELS] EEPROM;
uint8_t ep_servo_frame EEPROM;
uint8_t ep_servo_nr EEPROM;
uint8_t ep_single_step EEPROM;
uint8_t ep_repeat EEPROM;
uint8_t ep_pause EEPROM;
uint8_t ep_pause_step EEPROM;
uint8_t ep_tracking EEPROM;
uint8_t ep_track_hyst EEPROM;
uint8_t ep_track_tx EEPROM;
uint8_t ep_baudrate EEPROM;
mk_current_t ep_mk_current EEPROM;
uint8_t ep_mk_akku_nr EEPROM;
mk_lipo_t ep_mk_lipo[AKKU_NR_MAX+1] EEPROM;
uint8_t ep_mk_i_offset EEPROM;
uint8_t ep_mk_i_faktor EEPROM;
uint8_t ep_mk_w_faktor EEPROM;
 
/**************************************************************/
// Working variables of EEPROM contents
uint8_t dogm_vers;
uint8_t contrast;
uint8_t light_time = BACKGR_LIGHT_MAX;
uint8_t backgr_light = OFF;
uint8_t u_offset = U_OFFSET;
uint16_t u_min = U_MIN;
uint8_t rssi_inv = RSSI_INV;
uint8_t channel = CHANNEL;
uint8_t av_source = AV_SOURCE;
uint8_t language = NO_LANGUAGE;
udbm_t udbm = {UDBM_MIN, UDBM_MAX, UDBM_KORR_FA, UDBM_KORR_FA};
uint16_t tx_value_on = TX_VALUE_ON;
uint16_t tx_value_off = TX_VALUE_OFF;
uint16_t hyst_u_min;
servo_t servo[SERVO_NUM_CHANNELS] = {{SERVO_REV, SERVO_I0_RIGHT, SERVO_I0_LEFT, SERVO_I0_MIDDLE},\
{SERVO_REV, SERVO_I0_RIGHT, SERVO_I0_LEFT, SERVO_I0_MIDDLE}};
uint8_t servo_frame = SERVO_PERIODE;
uint8_t single_step = SINGLE_STEP;
uint8_t repeat = REPEAT;
uint8_t pause = PAUSE;
uint8_t pause_step = PAUSE_STEP;
uint8_t baudrate = BAUDRATE;
 
/**************************************************************/
uint8_t coldstart; // Flag erstmaliger MK-Start(Motore) nur nach GPS-Fix
uint8_t ch_stored; // Flag zur Speicherung, wenn Wert im Hauptdisplay geändert
 
uint8_t gps_display = 0;
uint8_t gps_disp_clear;
 
uint16_t bar_udbm[12]; // RSSI-Bargraph
uint8_t wudbm; // Differenz/Abstand benachbarter udbm[i] für differenzierteren Bargraphen
uint8_t bat_low = 0;
uint8_t sw_avx; // steuert über Set_AV_Source() oder rssi_diversity(av_source) Marker-Position und RX-Umschaltung
uint8_t mux_X; // berücksichtigt Schaltung auf Grund Synchronisation und RSSI (sw_avx meist RSSI) RX-Zählung
uint8_t MK_Motor_run = 0; // Flag für RX Time-Counter Start/Stop
uint8_t mk_timer = 0; // Zeitzähler lipo.time_on auf aus
 
const uint16_t PROGMEM baud[8] = {4800, 7200, 9600, 14400, 19200, 38400, 57600};
 
volatile uint8_t vsync0;
volatile uint8_t vsync1;
volatile uint8_t vscount0;
volatile uint8_t vscount1;
volatile uint32_t rxcount0 = 0;
volatile uint32_t rxcount1 = 0;
 
 
/************************************************************************************/
/* initialisiert den EEPROM mit default Werten, bzw. liest EEPROM gespeicherte */
/* Werte in gloabale Variablen. */
/* Parameter: */
/* uint8_t ep_reset :0 = zwangsweises Rückstetzen auf default-Werte */
/* */
/************************************************************************************/
void Init_EEPROM(uint8_t ep_reset)
{ char ver[sizeof(VERSION)];
uint8_t eep_init;
eep_init = eeprom_read_byte(&ep_eep_init);
eeprom_read_block(&ver, &ep_version, sizeof(VERSION));
_delay_ms(1);
 
if ((eep_init != EEP_INITB) || (ep_reset == 0) || strcmp(VERSION, ver))
{
// nur bei Erstinitialisierung DOGM auf default 3,3V setzen
if ((eep_init != EEP_INITB) || strcmp(VERSION, ver)){
eeprom_write_byte(&ep_eep_init, EEP_INITB);
eeprom_write_byte(&ep_dogm_vers, DOGM3V);
eeprom_write_byte(&ep_contrast, CONTRAST3V);
eeprom_write_block(&VERSION, &ep_version, sizeof(VERSION));
}
eeprom_write_byte(&ep_light_time, BACKGR_LIGHT_MAX);
eeprom_write_byte(&ep_u_offset, U_OFFSET);
eeprom_write_word(&ep_u_min, U_MIN);
eeprom_write_byte(&ep_rssi_inv, RSSI_INV);
eeprom_write_byte(&ep_channel, CHANNEL);
eeprom_write_byte(&ep_av_source, AV_SOURCE);
eeprom_write_byte(&ep_language, NO_LANGUAGE);
for (uint8_t i = 0; i < CHANNEL_MAX; i++)
eeprom_write_block(&udbm,&ep_udbm[i],sizeof(udbm_t));
eeprom_write_word(&ep_tx_value_on, TX_VALUE_ON);
eeprom_write_word(&ep_tx_value_off, TX_VALUE_OFF);
eeprom_write_byte(&ep_sIdxSteps, STEPS_255);
eeprom_write_block(&servo[0],&ep_servo[0],sizeof(servo_t));
eeprom_write_block(&servo[1],&ep_servo[1],sizeof(servo_t));
eeprom_write_byte(&ep_servo_frame, SERVO_PERIODE);
eeprom_write_byte(&ep_servo_nr, 0); // nur bei Test-Servo
eeprom_write_byte(&ep_single_step, SINGLE_STEP); // nur bei Test-Servo
eeprom_write_byte(&ep_repeat, REPEAT); // nur bei Test-Servo
eeprom_write_byte(&ep_pause, PAUSE); // nur bei Test-Servo
eeprom_write_byte(&ep_pause_step, PAUSE_STEP); // nur bei Test-Servo
eeprom_write_byte(&ep_tracking, TRACKING_MIN);
eeprom_write_byte(&ep_track_hyst, TRACKING_HYSTERESE);
eeprom_write_byte(&ep_track_tx, 0);
eeprom_write_byte(&ep_baudrate, BAUDRATE);
eeprom_write_block(&mk_current,&ep_mk_current,sizeof(mk_current_t));
eeprom_write_byte(&ep_mk_akku_nr, AKKU_NR_MIN);
for (uint8_t i = 0; i <= AKKU_NR_MAX; i++)
eeprom_write_block(&mk_lipo,&ep_mk_lipo[i],sizeof(mk_lipo_t));
eeprom_write_byte(&ep_mk_i_offset, MK_I_OFFSET);
eeprom_write_byte(&ep_mk_i_faktor, MK_I_FAKTOR);
eeprom_write_byte(&ep_mk_w_faktor, MK_W_FAKTOR);
sIdxSteps = STEPS_255;
}
else
{
light_time = eeprom_read_byte(&ep_light_time);
u_offset = eeprom_read_byte(&ep_u_offset);
u_min = eeprom_read_word(&ep_u_min);
rssi_inv = eeprom_read_byte(&ep_rssi_inv);
channel = eeprom_read_byte(&ep_channel);
av_source = eeprom_read_byte(&ep_av_source);
language = eeprom_read_byte(&ep_language);
tx_value_on = eeprom_read_word(&ep_tx_value_on);
tx_value_off = eeprom_read_word(&ep_tx_value_off);
sIdxSteps = eeprom_read_byte(&ep_sIdxSteps);
eeprom_read_block(&servo[0],&ep_servo[0],sizeof(servo_t));
eeprom_read_block(&servo[1],&ep_servo[1],sizeof(servo_t));
servo_frame = eeprom_read_byte(&ep_servo_frame); // nur bei Test-Servo
single_step = eeprom_read_byte(&ep_single_step); // nur bei Test-Servo
repeat = eeprom_read_byte(&ep_repeat); // nur bei Test-Servo
pause = eeprom_read_byte(&ep_pause); // nur bei Test-Servo
pause_step = eeprom_read_byte(&ep_pause_step); // nur bei Test-Servo
tracking = eeprom_read_byte(&ep_tracking);
track_hyst = eeprom_read_byte(&ep_track_hyst);
track_tx = eeprom_read_byte(&ep_track_tx);
baudrate = eeprom_read_byte(&ep_baudrate);
eeprom_read_block(&mk_current,&ep_mk_current,sizeof(mk_current_t));
mk_akku_nr = eeprom_read_byte(&ep_mk_akku_nr);
eeprom_read_block(&mk_lipo,&ep_mk_lipo[mk_akku_nr],sizeof(mk_lipo_t));
mk_i_offset = eeprom_read_byte(&ep_mk_i_offset);
mk_i_faktor = eeprom_read_byte(&ep_mk_i_faktor);
mk_w_faktor = eeprom_read_byte(&ep_mk_w_faktor);
}
dogm_vers = eeprom_read_byte(&ep_dogm_vers);
contrast = eeprom_read_byte(&ep_contrast);
hyst_u_min = u_min;
sw_avx = av_source;
for (uint8_t i = 0; i < SERVO_NUM_CHANNELS; i++) {
servoSet_rev(i, servo[i].rev);
servoSet_min(i, servo[i].min);
servoSet_max(i, servo[i].max);
servoSet_mid(i, servo[i].mid);
}
// Vorberechnung von ServoChannels[channel].duty
servoSetDefaultPos(); // Ausgangsstellung beider Servos
coldstart = 1;
USART_Init_Baudrate();
USART_RX_Mode(tracking);
mk_dUsedCapacity = mk_lipo.UsedCapacity;
}
 
void servoSetDefaultPos(void)
{
servoSetPosition(SERVO_PAN, ServoSteps()/2); // Ausgangsstellung SERVO_PAN
servoSetPosition(SERVO_TILT, 0); // Ausgangsstellung SERVO_TILT
}
 
void USART_Init_Baudrate(void)
{
if (tracking == TRACKING_MKCOCKPIT || tracking == TRACKING_NMEA)
USART_Init(getBaud(baudrate));
else
USART_Init(57600);
}
 
/************************************************************************************/
/* setzt Flag für 3,3V oder 5V DOGM */
/* Parameter: */
/* uint8_t dogm :Version */
/* */
/************************************************************************************/
void Set_DOGM_Version(void)
{
if(dogm_vers == DOGM5V) {
dogm_vers = DOGM3V;
contrast = CONTRAST3V;
}
else {
dogm_vers = DOGM5V;
contrast = CONTRAST5V;
}
eeprom_write_byte(&ep_dogm_vers, dogm_vers);
eeprom_write_byte(&ep_contrast, contrast);
}
 
/************************************************************************************/
/* setzt den RX-Kanal von 1 bis 7 */
/* Parameter: */
/* uint8_t channel :Kanal */
/* */
/************************************************************************************/
void Set_Channel(uint8_t channel)
{ uint8_t tmp;
 
channel--;
tmp = channel & 0b00000111; // Kanal 1 bis 7 Werte 0 bis 6 setzen
PORTA |= tmp;
PORTB |= tmp;
tmp = channel | 0b11111000;
PORTA &= tmp;
PORTB &= tmp;
wudbm = RSSI_Calc_UdBm(bar_udbm); // Vergleichstabelle für dBm-Balken berechnen
}
 
/************************************************************************************/
/* schaltet den MUX auf AV1 oder AV2 ohne Darstellung und en-/disabled Interrupt */
/* wird nur in main.c (Initialisierung) und Menü Sourceumschaltung eingesetzt */
/* deswegen cli() und sei() nur in Menu_AV_Source(void) */
/* Parameter: */
/* uint8_t src :0-AV1, 1-AV2 */
/* */
/************************************************************************************/
void SetMux0(void) {
SET_MUX_0;
mux_X = 0; // für Erkennung RX Zeitzähler
}
 
void SetMux1(void) {
SET_MUX_1;
mux_X = 1; // für Erkennung RX Zeitzähler
}
 
uint8_t Set_AV_Source(uint8_t src)
{
switch(src) {
case AV1: CLEAR_INT10; // Interrupt für Sync ausschalten
SetMux0();
break;
case AV2: CLEAR_INT10; // Interrupt für Sync ausschalten
SetMux1();
break;
case DIVERSITY: SET_INT10; // External Interrupt Mask Register ein
SetMux0();
break;
}
return(src);
}
 
 
/**************************************************************/
/* */
/* LCD-Backlight */
/* */
/**************************************************************/
 
void lcdSet_BackgrLight_Off(void)
{
backgr_light = OFF;
lcdBacklightOff();
}
 
void lcd_BackgrLight_On(void)
{ // ...&& (light_count < light_time)) ==> sonst wird Beleuchtung laufend wieder eingeschaltet
if ((backgr_light == OFF) && (light_count < light_time)) {
backgr_light = ON;
lcdBacklightOn();
}
}
 
void lcd_BackgrLight(void)
{
if (backgr_light == ON) { // nur wenn Beleuchtung an
if (light_time == BACKGR_LIGHT_MIN) // Hintergrundbeleuchtung immer aus?
lcdSet_BackgrLight_Off();
else
if (light_time < BACKGR_LIGHT_MAX) { // Hintergrundbeleuchtung immer an?
cli();
light_count++;
sei();
if (light_count >= light_time) lcdSet_BackgrLight_Off();
}
}
}
 
/**************************************************************/
/* */
/* ADC */
/* */
/* http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial */
/* */
/**************************************************************/
 
void ADC_Init(void)
{
uint16_t result;
ADMUX = (0<<REFS1) | (1<<REFS0); // AVcc als Referenz benutzen, da an AREF 4,8 V
ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler Prescaler 128
ADCSRA |= (1<<ADEN); // ADC aktivieren
/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
/* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
Wandlung nicht übernommen. */
result = ADCW;
}
 
/* ADC Einzelmessung */
uint16_t ADC_Read( uint8_t channel )
{
// Kanal waehlen, ohne andere Bits zu beeinflußen
ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
return ADCW; // ADC auslesen und zurückgeben
}
 
/* falls Rx mit invertierter RSSI-Spannung eingesetzt wird */
uint16_t ADC_Read_inv( uint8_t channel )
{ uint16_t result;
 
result = ADC_Read(channel);
if (rssi_inv)
result = 0x1ff - result; // 10 bit ADC, 1bit Vorzeichen; 9bit Wert
return result;
}
 
/* ADC Mehrfachmessung mit Mittelwertbbildung */
adc_avg_t ADC_Read_Avg(uint8_t channel0, uint8_t channel1, uint16_t average )
{ adc_avg_t result;
uint32_t u0 = 0;
uint32_t u1 = 0;
 
for (uint16_t i = 0; i < average; ++i){
u0 += ADC_Read_inv( channel0 );
u1 += ADC_Read_inv( channel1 );
_delay_ms(1);
}
result.u0 = u0/average;
result.u1 = u1/average;
return(result);
}
 
/**************************************************************/
/* */
/* Beeper */
/* */
/* Bei AVR-Studio 5 ist in delay.h */
/* #define __DELAY_BACKWARD_COMPATIBLE__ */
/* zu setzen */
/* */
/**************************************************************/
 
void Beep(uint8_t time)
{
PORTB |= (1<<BEEPER);
_delay_ms(time);
PORTB &= ~(1<<BEEPER);
}
 
void Double_Beep(uint8_t time, uint8_t pause)
{
Beep(time);
_delay_ms(pause);
Beep(time);
}
 
/**************************************************************/
/* */
/* U-Batterie */
/* */
/**************************************************************/
 
// uint16_t u, da bei Displ_Fnct[fu_index](val) der größte Wert UBat gleich 16 Bit
void Displ_1Nk(uint16_t u)
{
// 4 => 2 Ziffern vor Komma + 1 Komma + eine Ziffer Nachkomma darstellen, 2 Festkomma
lcdPuts(my_itoa(u,4,2,1));
}
 
void Displ_U_2Nk(uint16_t u)
{
lcdPuts(my_itoa(u,5,2,2));
lcdPutc('V');
}
 
// uint8_t beep_timer :Akku-leer-Beeper nur mit Task_0_1()-Intervalle bei Menü-Rücksprung
uint16_t U_Messen_cmp(uint8_t beep_timer)
{ uint16_t ubat;
static struct
{ uint8_t time;
uint8_t count;
} beep_low;
 
/* ubat = ((ADC_Read(VBAT) * Vref * (R104 + R103)) /(1024 * R103)) + UD10 (UD10 ist Offset)
Verhältniswert * 100 *8192 ( Verhältniswert = realer Korrekturwert;
mal 100 da alle Werte 2 Nachkommastellen berücksichtigt, aber ohne gerechnet wird
mal 8192 => ohne Bruch gerechnet aber dabei mehr Kommastellen berücksichtigt) */
ubat = (ADC_Read(VBAT) * (uint64_t)43504 + (uint64_t)u_offset * 8192)/ 8192;
if ( ubat <= hyst_u_min )
{
if (!bat_low) { // nicht laufend Display neu schreiben
hyst_u_min = u_min + 20; // 200mV Hysterese - beruhigt Anzeige
if (tracking == TRACKING_GPS)
store_LipoData(); // wenigstens von GPS-Statisik UsedCapacity, time_on usw. speichern
lcdClear();
lcdPuts(Msg(MSG_ACCU_LOW));
bat_low = 1;
Beep(BEEPBAT);
// da derzeit Fkt. aller 500ms aufgerufen, mit 2 Min Abstand beginnen
beep_low.time = BEEP_LOW_TIME;
beep_low.count = 0;
}
// Akku leer, in immer kürzeren Intervallen Beep
if ((beep_timer == 1) && (beep_low.count++ >= beep_low.time)){
Beep(BEEPBAT);
if (beep_low.time > 2)
beep_low.time /= 2;
beep_low.count = 0;
}
}
else {
if (hyst_u_min > u_min) { // falls Anzeige von Batterie leer
bat_low = 0; // und zurück geschaltet wird,
hyst_u_min = u_min; // dann Main_Disp wieder darstellen
Displ_Main_Disp();
}
}
return(ubat);
}
 
void Displ_VBat(void) // da u_offset globale Variable
{ uint16_t ubat;
ubat = U_Messen_cmp(ENABLE_BTIMER);
if (!bat_low) { // würde sonst Anzeige Akku leer überschreiben
lcdGotoXY(11, 0);
Displ_1Nk(ubat);
}
}
 
 
/**************************************************************/
/* */
/* RSSI */
/* */
/**************************************************************/
 
/* RSSI Werte Korrekturfaktor berechnen */
uint16_t RSSI_Calc_Korr(uint8_t nchannel, uint16_t u0, uint16_t u1)
{ uint16_t u_max;
 
// immer nur den kleineren Wert vergrößern
if (u0 < u1) {
udbm.korr_1 = (((uint32_t)u1 * UDBM_KORR_FA) / u0); // nur mit Integer und 2 Nachkommastellen rechnen
udbm.korr_2 = UDBM_KORR_FA;
u_max = u1;
}
else {
udbm.korr_2 = (((uint32_t)u0 * UDBM_KORR_FA) / u1); // nur mit Integer und 2 Nachkommastellen rechnen
udbm.korr_1 = UDBM_KORR_FA;
u_max = u0;
}
eeprom_write_word(&ep_udbm[nchannel - 1].korr_1, udbm.korr_1);
eeprom_write_word(&ep_udbm[nchannel - 1].korr_2, udbm.korr_2);
return(u_max);
}
 
void Displ_Calibr_Aktiv(uint8_t nchannel)
{ char str[LCD_COLS + 1];
uint8_t l;
uint8_t zle = 1;
 
// Anzeige für nur einen Kanal oder wenn in Schleife, Kanalnr. des z.Z. kalbrierenden Kanals
lcdClear();
lcdPutStrMid(Msg(MSG_CALIBRATION),0);
if (nchannel > 0) { // Anzeige aller RX-Kanäle min. kalibrieren?
strcpy(str, Msg(MSG_RX_CHANNEL));
strcat(str, ": ");
l = strlen(str);
str[l] = nchannel + 0x30; // gerade zu kalibrierender Kanal, String zusammen stellen
str[++l] = '\0';
lcdPutStrMid(str,1);
zle = 2;
}
lcdPutStrMid(Msg(MSG_RUNNING),zle);
}
 
void Displ_Error_TX(uint8_t message)
{
lcdClear();
lcdPutStrMid(Msg(MSG_ERROR), 0);
lcdPutStrMid(Msg(MSG_TX_NOT), 1);
lcdPutStrMid(Msg(message), 2);
delay_ms100x(30);
}
 
uint8_t RSSI_Min_Calibrate(uint8_t nchannel, uint16_t *pbar_udbm)
{ adc_avg_t rssi_avg;
uint16_t udbm_min;
uint8_t one_channel = !nchannel;
 
Displ_Calibr_Aktiv(nchannel);
if (one_channel) nchannel = channel;
rssi_avg = ADC_Read_Avg(RSSI0, RSSI1, 1000 ); //1000 Wiederholungen mit Mittelwertbildung
// Plausibilitätsprüfung ob Sender ausgeschaltet
if (rssi_avg.u0 + rssi_avg.u1 > tx_value_off) {
udbm_min = RSSI_Calc_Korr(nchannel, rssi_avg.u0, rssi_avg.u1); // ist real die größere Spannung, aber der kleinere dbm Wert
eeprom_write_word(&ep_udbm[nchannel - 1].min, udbm_min);
if (one_channel) {
Double_Beep(DBEEPWR, DBEEPWRP);
wudbm = RSSI_Calc_UdBm(pbar_udbm);
}
}
else
if (one_channel)
Displ_Error_TX(MSG_TX_OFF);
else
return(0); // Fehleranzeige wird in menue.c gesammelt ausgewertet
return(1); // kein Fehler, da bei einen Kanal bereits Fehler angezeigt wurde
}
 
void RSSI_Max_Calibrate(uint16_t *pbar_udbm)
{ adc_avg_t rssi_avg;
uint16_t udbm_max;
 
Displ_Calibr_Aktiv(0);
rssi_avg = ADC_Read_Avg(RSSI0, RSSI1, 1000 ); //1000 Wiederholungen mit Mittelwertbildung
// Plausibilitätsprüfung ob Sender in der Nähe eingeschaltet
if (rssi_avg.u0 + rssi_avg.u1 < tx_value_on) {
udbm_max = RSSI_Calc_Korr(channel, rssi_avg.u0, rssi_avg.u1); // ist real die kleinere Spannung, aber der größere dbm Wert
eeprom_write_word(&ep_udbm[channel - 1].max, udbm_max);
Double_Beep(DBEEPWR, DBEEPWRP);
wudbm = RSSI_Calc_UdBm(pbar_udbm);
}
else Displ_Error_TX(MSG_TX_ON);
}
 
// Vergleichstabelle für RSSI-Bargraph berechnen, vermeidet laufend gleiche Berechnung
uint8_t RSSI_Calc_UdBm(uint16_t *pbar_udbm)
{ uint8_t n;
 
eeprom_read_block(&udbm,&ep_udbm[channel - 1],sizeof(udbm_t));
// -15 um Ende dBm Skala sicher zu erreichen; ohne verfeinerten Bahrgraph war Wert -3
n = (udbm.min - udbm.max -15)/11;
for (uint8_t i = 0; i < 12; i++)
pbar_udbm[i] = (udbm.min - i * n);
return(n / 5); // da 5 Pixel Breite pro Display-Zeichen; Anzeigebalken pro Pixel differenzieren
}
 
void Displ_RSSI_Bargraph(uint16_t *pbar_udbm, uint8_t wudbm, uint16_t uadc)
{ char charBar[12];
uint8_t i;
int8_t lz = 11;
char b = 4;
// Balken zeichnen - udbm
for (i = 0; i < 12; i++) {
if ((b != ' ') && (uadc > pbar_udbm[i])) {
b = ' ';
lz = i - 1;
}
charBar[i] = b;
}
if (lz >= 0) {
charBar[lz] = (pbar_udbm[lz] - uadc) / wudbm ;// Anzeigebalken pro Pixel-"Breite" differenzieren
// bei Teilung 4 wäre richtig und keine Korr. erforderlich, so aber gleichmäßigerer Balkenverlauf
if (charBar[lz] > 4) charBar[lz] = 4;
}
for (i = 0; i < 12; i++)// lcdPuts (ist auch for) funktioniert hier nicht, da Char'\0' für Zeichen auch Stringende
lcdPutc(charBar[i]);
}
 
uint8_t RSSI_Diversity(uint8_t src, uint16_t *pbar_udbm, uint8_t visible)
{ uint16_t u0, u1;
static uint8_t div_flag, ret_div_flag;
char marker;
 
u0 = (ADC_Read_inv(RSSI0) * (uint32_t)udbm.korr_1)/UDBM_KORR_FA;
u1 = (ADC_Read_inv(RSSI1) * (uint32_t)udbm.korr_2)/UDBM_KORR_FA;
// falls beide RX gleich gut/schlecht synchronisieren
// Achtung! Niedrigere Spannung - größere Feldstärke
if (src == DIVERSITY) {
if (u0 < u1) {
ret_div_flag = AV1;
if ((vscount0 == 255) && (vscount1 == 255)) SetMux0(); // egal wann RSSI schaltet ==> es ist kein sync vorhanden
}
else {
ret_div_flag = AV2;
if ((vscount0 == 255) && (vscount1 == 255)) SetMux1(); // egal wann RSSI schaltet ==> es ist kein sync vorhanden
}
}
else ret_div_flag = src; // sonst leerer Returnwert
if (visible) {
if (src == DIVERSITY) {
// Synchronisation vorrangig zur Feldstärke
if ((vsync0 != vsync1) && ((vscount0 & vscount1) < 255)) {
// ist nur zur Anzeige - Sync-MUX wird über Interrupt gesteuert
div_flag = vsync0 == 0? AV1: AV2;
marker = MARKER_SYNC;
}
else {
div_flag = ret_div_flag;
marker = MARKER_RSSI;
}
}
else marker = MARKER_AV;
// wäre unschön - keine RSSI-Anzeige, aber Marker springt
if ((u0 > pbar_udbm[0]) && (u1 > pbar_udbm[0])) marker = ' ';
lcdGotoXY(2, 1);
Displ_RSSI_Bargraph(pbar_udbm, wudbm, u0);
lcdGotoXY(2, 2);
Displ_RSSI_Bargraph(pbar_udbm, wudbm, u1);
if (src == DIVERSITY) Displ_AV_Mark(div_flag, marker);
}
return(ret_div_flag);
}
 
/**************************************************************/
/* */
/* Diversity v-Synchronisation Interruptroutinen */
/* */
/**************************************************************/
 
/* Impulszähler für V-Synchronisation 0 und 1
wird durch Interrupt des jewiligen vSync einzeln zurückgesetzt. 8-bit Timer*/
ISR(TIMER2_OVF_vect)
{
TCNT2 = (int8_t)(int16_t)-(F_CPU / 64 * 500e-6); // preload
if (vscount0 < 255) ++vscount0; // Überlauf von vscount vermeiden
if (vscount1 < 255) ++vscount1; // Überlauf von vscount vermeiden
if (rx_timeout < RX_TIME_END) ++rx_timeout; // veranlasst bei GPS-Tracking MK Datensatz senden
if ((mk_timer) && (mk_lipo.time_on < T2PROD_M59S59)) ++mk_lipo.time_on; // T2PRODM59S59 = 3599 * 4000
if (((tracking == TRACKING_GPS) && (MK_Motor_run)) || ((tracking == TRACKING_NMEA) && !coldstart)) { // MK-Motoren müssen laufen
if (mux_X)
rxcount1++; // kein Test auf Überlauf ==> Counter groß genug - bis Stunden
else
rxcount0++;
}
}
 
/* Messung von Impulsabstand v-Synchronisation 0
Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
ISR(INT0_vect)
{
if ((vscount0 >= 79) && (vscount0 <= 81)) {
vsync0 = 0;
if ((mux_X) && (vscount1 == 255)) {
SetMux0();
vsync1 = 1;
}
}
else {
vsync0 = 1;
if (vsync1 == 0)
SetMux1();
}
if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
if (sw_avx == AV1) {
SetMux0();
}
else
SetMux1();
}
vscount0 = 0;
}
 
/* Messung von Impulsabstand v-Synchronisation 1
Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
ISR(INT1_vect)
{
if ((vscount1 >= 79) && (vscount1 <= 81)) {
vsync1 = 0;
if (!(mux_X) && (vscount0 == 255)) {
SetMux1();
vsync0 = 1;
}
}
else {
vsync1 = 1;
if (vsync0 == 0)
SetMux0();
}
if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
if (sw_avx == AV1) {
SetMux0();
}
else
SetMux1();
}
vscount1 = 0;
}
 
/**************************************************************/
/* */
/* Tasks */
/* ermöglicht unterschiedliche Zeiten f. UBat, Sync... */
/* */
/**************************************************************/
 
void Task_0_1(void)
{
if (task_timer0_1) {
cli();
task_timer0_1 = 0;
sei();
Displ_VBat();
}
}
 
void Task_0_2(void)
{
if (task_timer0_2) {
cli();
task_timer0_2 = 0;
sei();
sw_avx = RSSI_Diversity(av_source, bar_udbm, !bat_low);
}
}
 
void Task_0_3(void)
{
if (task_timer0_3) {
cli();
task_timer0_3 = 0;
sei();
sw_avx = RSSI_Diversity(av_source, bar_udbm, 0);
if (tracking == TRACKING_MKCOCKPIT) Tracking_MKCockpit();
}
}
 
void Task_0_4(void)
{
if (task_timer0_4) {
cli();
task_timer0_4 = 0;
sei();
if (tracking == TRACKING_GPS)
Tracking_GPS();
else if (tracking == TRACKING_NMEA)
Tracking_NMEA();
if (gps_display == GPS_RX_COUNT) Displ_RX_Time(); // aktualisieren der Empfängerzeiten
}
}
 
void Task_0_5(void) // Nur für Tasten-Beschleunigung/-Wiederholrate! Hintergrund: Rücksetzung.
{ // Hintergrund: Rücksetzung. Beginnt nach jeden Tastendruck neu zu zählen.
lcd_BackgrLight_On(); // muss bei beliebiger Taste sofort eingeschaltet werden
if (task_timer0_5) {
cli();
task_timer0_5 = 0;
sei();
lcd_BackgrLight();
}
}
 
void Tasks_invisible(void) // wird in main.c und menue.c aufgerufen
{
Task_0_3();
Task_0_4();
Task_0_5();
if (tracking == TRACKING_RSSI) Tracking_RSSI();
}
/NGVideo5_8/tags/v1.33/ngvideo.h
0,0 → 1,215
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#ifndef NGVIDEO_H_
#define NGVIDEO_H_
 
#include "config.h"
#include "messages.h"
#include "servo.h"
#include "dogm.h"
#include "menue.h"
#include "lipo.h"
 
/* Indexwerte für av_source bzw. zur Auswertung von av_source */
#define AV1 0
#define AV2 1
#define DIVERSITY 2
 
#define MARKER_SELECT 0xfc // 0xfc enspricht '>>' Menue-Marker
#define MARKER_AV 0xfb // 0xfb enspricht '<<' Diversity AV-Marker
#define MARKER_RSSI 'd' // Diversity, wenn RX umschaltet mittels RSSI-Wert
#define MARKER_SYNC 's' // Diversity, wenn RX umschaltet auf Grund der Bildsynchronisation
 
#define SET_MUX_0 PORTA &= ~(1<<MUX_IN); // MUX SxA enabled
#define SET_MUX_1 PORTA |= (1<<MUX_IN); // MUX SxB enabled
#define CLEAR_INT10 EIMSK &= ~((1<<INT1) | (1<<INT0));// Interrupt für Sync ausschalten
#define SET_INT10 EIMSK |= (1<<INT1) | (1<<INT0); // External Interrupt Mask Register ein
 
/* Beep Verzögerungszeitein */
#define DBEEPVERS 2 // Beep on nach Versionsanzeige
#define DBEEPVERSP 30 // Beep Pause nach Versionsanzeige
#define BEEPENTER 1 // Beep on nach Enter kurz Scroll_Menu() und Select_Menu()
#define DBEEPWR 4 // Beep on nach geänderten Werte ROM schreiben
#define DBEEPWRP 30 // Beep Pause nach geänderten Werte ROM schreiben
#define BEEPBAT 20 // Beep on bei Akku low
#define BEEP_LOW_TIME 240 // TIMER0_1 aller 500ms aufgerufen, BeepIntervall Akku leer mit 2 Min Abstand beginnen
#define DBEEPNMEAFIX 120 // Beep on nach NMEA SAT-FIX
#define DBEEPMEAFIXP 240 // Beep Pause nach NMEA SAT-FIX
 
#define ENABLE_BTIMER 1 // damit Intervall Beeper für Akku leer mit TIMER0_1 gesteuert wird
#define DISABLE_BTIMER 0
 
#define GPS_DISP_NONE 0 // Anzeigen bei Antennennachführung per WI232 und GPS
#define GPS_DISP_CALC 1
#define GPS_DISP_CURRENT 2
#define GPS_DISP_HOME 3
#define GPS_MISC 4
#define GPS_RX_COUNT 5
 
#define BAUDRATE 5 // für Antennennachführung mittels MKCockpit
#define BAUDRATE_MIN 0
#define BAUDRATE_MAX 6
 
#define getBaud(x) (uint16_t)pgm_read_dword(&baud[x])
extern const uint16_t PROGMEM baud[8];
 
#define POLOLU_CMD 2
 
#define OFF 0
#define ON 1
 
#define EEPROM __attribute__ ((section(".eeprom")))
 
typedef struct {
uint8_t rev;
uint16_t min;
uint16_t max;
uint16_t mid;
} servo_t;
 
typedef struct {
uint16_t min;
uint16_t max;
uint16_t korr_1;
uint16_t korr_2;
} udbm_t;
 
typedef struct {
uint16_t u0;
uint16_t u1;
} adc_avg_t;
 
/**************************************************************/
/* */
/* EEPROM */
/* */
/**************************************************************/
extern uint8_t ep_eep_init EEPROM;
extern char ep_version[sizeof(VERSION)] EEPROM;
extern uint8_t ep_dogm_vers EEPROM;
extern uint8_t ep_contrast EEPROM;
extern uint8_t ep_light_time EEPROM;
extern uint8_t ep_u_offset EEPROM;
extern uint16_t ep_u_min EEPROM;
extern uint8_t ep_rssi_inv EEPROM;
extern uint8_t ep_channel EEPROM;
extern uint8_t ep_av_source EEPROM;
extern uint8_t ep_language EEPROM;
extern udbm_t ep_udbm[CHANNEL_MAX] EEPROM;
extern uint16_t ep_tx_value_on EEPROM;
extern uint16_t ep_tx_value_off EEPROM;
extern uint8_t ep_sIdxSteps EEPROM;
extern servo_t ep_servo[SERVO_NUM_CHANNELS] EEPROM;
extern uint8_t ep_servo_frame EEPROM;
extern uint8_t ep_servo_nr EEPROM;
extern uint8_t ep_single_step EEPROM;
extern uint8_t ep_repeat EEPROM;
extern uint8_t ep_pause EEPROM;
extern uint8_t ep_pause_step EEPROM;
extern uint8_t ep_tracking EEPROM;
extern uint8_t ep_track_hyst EEPROM;
extern uint8_t ep_track_tx EEPROM;
extern uint8_t ep_baudrate EEPROM;
extern mk_current_t ep_mk_current EEPROM;
extern uint8_t ep_mk_akku_nr EEPROM;
extern mk_lipo_t ep_mk_lipo[AKKU_NR_MAX+1] EEPROM;
extern uint8_t ep_mk_i_offset EEPROM;
extern uint8_t ep_mk_i_faktor EEPROM;
extern uint8_t ep_mk_w_faktor EEPROM;
 
/**************************************************************/
// Working variables of EEPROM contents
extern uint8_t eep_init;
extern char version[sizeof(VERSION)];
extern uint8_t dogm_vers;
extern uint8_t contrast;
extern uint8_t light_time;
extern uint8_t u_offset;
extern uint16_t u_min;
extern uint8_t rssi_inv;
extern uint8_t channel;
extern uint8_t av_source;
extern uint8_t language;
extern udbm_t udbm;
extern uint16_t tx_value_on;
extern uint16_t tx_value_off;
extern uint8_t sIdxSteps;
extern servo_t servo[SERVO_NUM_CHANNELS];
extern uint8_t servo_frame;
extern uint8_t servo_nr;
extern uint8_t single_step;
extern uint8_t repeat;
extern uint8_t pause;
extern uint8_t pause_step;
extern uint8_t tracking;
extern uint8_t track_hyst;
extern uint8_t track_tx;
extern uint8_t baudrate;
extern uint8_t ch_stored; // Flag zur Speicherung, wenn Wert im Hauptdisplay geändert
 
/**************************************************************/
extern uint8_t coldstart; // Flag erstmaliger MK-Start(Motore) nur nach GPS-Fix
extern uint8_t bat_low;
extern uint16_t hyst_u_min;
extern uint8_t gps_display;
extern uint8_t gps_disp_clear;
extern uint8_t sw_avx;
extern uint16_t bar_udbm[12];
 
extern uint8_t MK_Motor_run; // Flag für RX Time-Counter Start/Stop
extern uint8_t mk_timer; // Zeitzähler lipo.time_on auf aus
 
extern volatile uint32_t rxcount0;
extern volatile uint32_t rxcount1;
 
extern SpecialChr_t lcdSpecialChr[7];
extern SpecialChr_t lcdSpecialChrLs[8];
extern SpecialChr_t lcdSpecialChrRs[5];
 
void Init_EEPROM(uint8_t ep_reset);
void servoSetDefaultPos(void);
void Set_DOGM_Version(void);
void Set_Channel(uint8_t channel);
uint8_t Set_AV_Source(uint8_t src);
 
void lcdSet_BackgrLight_Off(void);
void lcd_BackgrLight_On(void);
void lcd_BackgrLight(void);
 
void ADC_Init(void);
uint16_t ADC_Read( uint8_t channel );
uint16_t ADC_Read_inv( uint8_t channel );
 
void Beep(uint8_t time);
void Double_Beep(uint8_t time, uint8_t pause);
 
void Displ_VBat(void);
void Displ_U_2Nk(uint16_t u);
 
uint8_t RSSI_Calc_UdBm(uint16_t *pbar_udbm);
uint8_t RSSI_Min_Calibrate(uint8_t nchannel, uint16_t *pbar_udbm);
void RSSI_Max_Calibrate(uint16_t *pbar_udbm);
 
void USART_Init_Baudrate(void);
void Double_Beep(uint8_t time, uint8_t pause);
uint16_t Change_Value_plmi(uint16_t val, uint16_t min_val, uint16_t max_val, uint8_t posX, uint8_t posY, Displ_Fnct_t Displ_Fnct, uint8_t cycle, uint8_t vrepeat);
uint16_t U_Messen_cmp(uint8_t beep_timer);
 
void Task_0_1(void);
void Task_0_2(void);
void Task_0_3(void);
void Task_0_4(void);
void Task_0_5(void);
void Tasks_invisible(void);
 
#endif /* NGVIDEO_H_ */
/NGVideo5_8/tags/v1.33/servo.c
0,0 → 1,207
 
/********************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* using */
/*! \file servo.c \brief Interrupt-driven RC Servo function library.*/
/* */
/*File Name : 'servo.c' */
/*Title : Interrupt-driven RC Servo function library */
/*Author : Pascal Stang - Copyright (C) 2002 */
/*Created : 7/31/2002 */
/*Revised : 8/02/2002 */
/*Version : 1.0 */
/*Target MCU : Atmel AVR Series */
/*Editor Tabs : 2 */
/* */
/*This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/********************************************************************/
 
#include <avr/interrupt.h>
#include <avr/io.h>
 
#include "servo.h"
#include "config.h"
 
// Global variables
uint16_t ServoPosTics;
uint16_t ServoPeriodTics;
 
// servo channel registers
ServoChannelType ServoChannels[SERVO_NUM_CHANNELS];
 
const ServoConst_t ServoConst[2] = {{SERVO_MAX, SERVO_MIN, SERVO_STEPS, SERVO_PRESCALER},
{SERVO_MAX * 4, SERVO_MIN * 4, (SERVO_STEPS + 1) * 4 - 1, SERVO_PRESCALER / 4}};
 
// Servo limits (depend on hardware)
const servo_limit_t servo_limit[2][3] = {{{SERVO_I0_RIGHT_MIN, SERVO_I0_RIGHT_MAX},
{SERVO_I0_LEFT_MIN, SERVO_I0_LEFT_MAX},
{SERVO_I0_MIDDLE_MIN, SERVO_I0_MIDDLE_MAX}},
{{SERVO_I1_RIGHT_MIN, SERVO_I1_RIGHT_MAX},
{SERVO_I1_LEFT_MIN, SERVO_I1_LEFT_MAX},
{SERVO_I1_MIDDLE_MIN, SERVO_I1_MIDDLE_MAX}}};
 
// Servopositionen normiert für 950µs, 2,05ms und 1,5ms ==> Ergebnis Schritte. Da Zeit in µs ist F_CPU*e-1
const steps_pw_t steps_pw[2] = {{(uint64_t)950*F_CPU*1e-6/SERVO_PRESCALER + 0.5, (uint64_t)2050*F_CPU*1e-6/SERVO_PRESCALER + 0.5, (uint64_t)1500*F_CPU*1e-6/SERVO_PRESCALER + 0.5},
{(uint64_t)950*4*F_CPU*1e-6/SERVO_PRESCALER + 0.5, (uint64_t)2050*4*F_CPU*1e-6/SERVO_PRESCALER + 0.5, (uint64_t)1500*4*F_CPU*1e-6/SERVO_PRESCALER + 0.5}};
 
// anzufahrende Servopositionen 0=MIN, 1=MID, 2=MAX
const uint8_t PosIdx[POSIDX_MAX] = {1, 0, 1, 2 };
 
// functions
 
//! initializes software PWM system 16-bit Timer
// normaler Weise wird ein Serv-PWM Signal aller 20ms wiederholt
// Werte: rev, min, max, mid vorher über servoSet...() initialisieren und einmal servoSetPosition(...) ausführen!!!
void servoInit(uint8_t servo_period)
{ uint16_t OCValue; // set initial interrupt time
 
// disble Timer/Counter1, Output Compare A Match Interrupt
TIMSK1 &= ~(1<<OCIE1A);
// set the prescaler for timer1
if (sIdxSteps == STEPS_255) {
TCCR1B &= ~((1<<CS11) | (1<<CS10));
TCCR1B |= (1<<CS12); // prescaler 256, Servo-Schritte 185 bei 180 grd Winkel
}
else {
TCCR1B &= ~(1<<CS12);
TCCR1B |= (1<<CS11) | (1<<CS10); // prescaler 64, Servo-Schritte 740 bei 180 grd Winkel
}
// attach the software PWM service routine to timer1 output compare A
// timerAttach(TIMER1OUTCOMPAREA_INT, servoService);
// enable channels
for(uint8_t channel=0; channel < SERVO_NUM_CHANNELS; channel++) {
// set default pins assignments SERVO2 Pin 4; SERVO1 Pin 5
ServoChannels[channel].pin = (1 << (SERVO2 + channel));
}
ServoPosTics = 0; // set PosTics
// set PeriodTics
ServoPeriodTics = F_CPU / ServoConst[sIdxSteps].prescaler * servo_period * 1e-3;
// read in current value of output compare register OCR1A
OCValue = OCR1AL; // read low byte of OCR1A
OCValue += (OCR1AH << 8); // read high byte of OCR1A
OCValue += ServoPeriodTics; // increment OCR1A value by nextTics
// set future output compare time to this new value
OCR1AH = OCValue >> 8; // write high byte
OCR1AL = OCValue & 0x00FF; // write low byte
TIMSK1 |= (1<<OCIE1A); // enable the timer1 output compare A interrupt
}
 
uint16_t pw_us(uint16_t Steps)
{
return(Steps * ServoConst[sIdxSteps].prescaler/(F_CPU * 1e-6) + 0.5); // Zeit pro Schritt (Wert * e-1) in µs
}
 
uint16_t ServoSteps(void)
{
return(ServoConst[sIdxSteps].steps);
}
 
void servoSet_rev(uint8_t channel, uint8_t val)
{
ServoChannels[channel].rev = val & 0x01;
}
 
void servoSet_min(uint8_t channel, uint16_t min)
{
ServoChannels[channel].min = ServoConst[sIdxSteps].min + min;
}
 
void servoSet_max(uint8_t channel, uint16_t max)
{
ServoChannels[channel].max = ServoConst[sIdxSteps].max - max;
}
 
void servoSet_mid(uint8_t channel, uint16_t mid)
{
ServoChannels[channel].mid = mid;
// Faktor 16, bzw. 16/2 um mit einer Nachkommastelle zu Rechnen
ServoChannels[channel].mid_scaled = (8 * (ServoChannels[channel].max - ServoChannels[channel].min) + \
(16 * mid - 8 * ServoConst[sIdxSteps].steps))/16 + ServoChannels[channel].min;
}
 
//! turns off software PWM system
void servoOff(void)
{
// disable the timer1 output compare A interrupt
TIMSK1 &= ~(1<<OCIE1A);
}
 
//! set servo position on channel (raw unscaled format)
void servoSetPositionRaw(uint8_t channel, uint16_t position)
{
// bind to limits
if (position < ServoChannels[channel].min) position = ServoChannels[channel].min;
if (position > ServoChannels[channel].max) position = ServoChannels[channel].max;
// set position
ServoChannels[channel].duty = position;
}
 
//! set servo position on channel
// input should be between 0 and ServoSteps() (entspricht Maximalausschlag)
void servoSetPosition(uint8_t channel, uint16_t position)
{ uint16_t pos_scaled;
// calculate scaled position
if (ServoChannels[channel].rev != 0) position = ServoConst[sIdxSteps].steps - position;
if (position < ServoConst[sIdxSteps].steps/2)
//bei Position < Servomittelstellung Position*(Mitte - Min)/(Servoschritte/2)
pos_scaled = ServoChannels[channel].min + ((int32_t)position*2*(ServoChannels[channel].mid_scaled-ServoChannels[channel].min))/ \
ServoConst[sIdxSteps].steps;
else
//bei Position >= Servomittelstellung
pos_scaled = ServoChannels[channel].mid_scaled + (uint32_t)(position - ServoConst[sIdxSteps].steps / 2) \
* 2 * (ServoChannels[channel].max-ServoChannels[channel].mid_scaled)/ServoConst[sIdxSteps].steps;
// set position
servoSetPositionRaw(channel, pos_scaled);
}
 
// Umrechnung Winkel in Servoschritte
void servoSetAngle(uint8_t servo_nr, int16_t angle)
{
servoSetPosition(servo_nr, (uint16_t)((uint32_t)angle * ServoConst[sIdxSteps].steps / 180));
}
 
//Interruptroutine
ISR(TIMER1_COMPA_vect)
{ static uint8_t ServoChannel;
uint16_t nextTics;
uint16_t OCValue; // schedule next interrupt
 
if(ServoChannel < SERVO_NUM_CHANNELS) {
PORTD &= ~ServoChannels[ServoChannel].pin; // turn off current channel
}
ServoChannel++; // next channel
if(ServoChannel != SERVO_NUM_CHANNELS) {
// loop to channel 0 if needed
if(ServoChannel > SERVO_NUM_CHANNELS) ServoChannel = 0;
// turn on new channel
PORTD |= ServoChannels[ServoChannel].pin;
// schedule turn off time
nextTics = ServoChannels[ServoChannel].duty;
}
else {
// ***we could save time by precalculating this
// schedule end-of-period
nextTics = ServoPeriodTics-ServoPosTics;
}
// read in current value of output compare register OCR1A
OCValue = OCR1AL; // read low byte of OCR1A
OCValue += (OCR1AH <<8); // read high byte of OCR1A
OCValue += nextTics; // increment OCR1A value by nextTics
// set future output compare time to this new value
OCR1AH = OCValue >> 8; // write high byte
OCR1AL = OCValue & 0x00FF; // write low byte
 
ServoPosTics += nextTics; // set our new tic position
if(ServoPosTics >= ServoPeriodTics) ServoPosTics = 0;
}
 
/NGVideo5_8/tags/v1.33/servo.h
0,0 → 1,129
/*********************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/* using */
/*! \file servo.c \brief Interrupt-driven RC Servo function library. */
/* */
/*File Name : 'servo.c' */
/*Title : Interrupt-driven RC Servo function library */
/*Author : Pascal Stang - Copyright (C) 2002 */
/*Created : 7/31/2002 */
/*Revised : 8/02/2002 */
/*Version : 1.0 */
/*Target MCU : Atmel AVR Series */
/*Editor Tabs : 4 */
/* */
/*ingroup driver_sw */
/*defgroup servo Interrupt-driven RC Servo Function Library (servo.c)*/
/*code #include "servo.h" \endcode */
/*par Overview */
/* */
/*This code is distributed under the GNU Public License */
/*which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/*********************************************************************/
 
#ifndef SERVO_H
#define SERVO_H
 
// The numbers below good for parallax servos at an F_CPU of 20.000MHz.
// Da einige Servo's auch eien Winkel von 180 grd zulassen, Wertebereich
// entgegen den sonst üblichen. Einschränkung mit default Kalibrierung
// auf 0,9ms (45) bis 2,1ms(45) gesetzt. Je nach Servo, entspricht einen
// Winkel von etwa 180grd
// Periode default 20ms
 
#define SERVO_MAX 211 // 2,7 ms bei prescaler 256, bei prescaler 64 SERVO_MAX * 4
#define SERVO_MIN 26 // 0,33ms bei prescaler 256, bei prescaler 64 SERVO_MIN * 4
#define SERVO_STEPS 255 // Servo-Schritte von links nach rechts, Anschlagkalibrierung spielt keine Rolle
#define SERVO_PRESCALER 256 // bei prescaler 256, bei prescaler 64 SERVO_PRESCALER / 4
#define STEPS_255 0 // Servo-Schritte von links nach rechts, Anschlagkalibrierung spielt keine Rolle
#define STEPS_1023 1 // Servo-Schritte von links nach rechts, Anschlagkalibrierung spielt keine Rolle
 
typedef struct //Servo-Konstante je nach Prescaler
{
uint16_t max;
uint16_t min;
uint16_t steps;
uint16_t prescaler;
}ServoConst_t;
 
typedef struct //struct_ServoChannel
{
uint8_t pin; // hardware I/O port and pin for this channel
uint16_t duty; // PWM duty setting which corresponds to servo position
uint8_t rev; // Parameter, wie on/off; reverse; range
uint16_t min; // SERVO_MIN + Parameter min
uint16_t max; // SERVO_MAX - Parameter max
uint16_t mid_scaled; // skalierte Servomitte
int16_t mid; // Servomitte = SERVO_STEPS/2 +/- x Schritte; bei Pescaler 256 wird nur uint8_t benötigt aber bei 64
}ServoChannelType;
 
uint8_t sIdxSteps; // 0 für 255 und 1 für 1023 Schritte; Prescaler 256 oder 64
 
// Define servo limits (depend on hardware)
typedef struct {
uint16_t min;
uint16_t max;
}servo_limit_t;
 
extern const servo_limit_t servo_limit[2][3];
 
// Define servo positions (depend on hardware)
typedef struct {
uint16_t min;
uint16_t max;
uint16_t mid;
}steps_pw_t;
 
// Servopositionen für 950µs, 2,05ms und 1,5ms ==> Ergebnis Schritte. Da Zeit in µs ist F_CPU*e-1
extern const steps_pw_t steps_pw[2];
 
#define RIGHT 0 // Servopostionen, welche vom Einbau abhängig sind
#define LEFT 1
#define MIDDLE 2
 
#define POSIDX_MAX 4
extern const uint8_t PosIdx[POSIDX_MAX]; // anzufahrende Servopositionen 0=MIN, 1=MID, 2=MAX
 
// functions
 
// initializes servo system
// You must run this to begin servo control
void servoInit(uint8_t servo_period);
 
// turns off servo system
// This stops controlling the servos and
// returns control of the SERVOPORT to your code
void servoOff(void);
 
// set servo position on a given channel
// servoSetPosition() commands the servo on <channel> to the position you
// desire. The position input must lie between 0 and POSITION_MAX and
// will be automatically scaled to raw positions between SERVO_MIN and
// SERVO_MAX
void servoSetPosition(uint8_t channel, uint16_t position);
 
// set raw servo position on a given channel
// Works like non-raw commands but position is not scaled. Position must
// be between SERVO_MIN and SERVO_MAX
void servoSetPositionRaw(uint8_t channel, uint16_t position);
 
// set servo to a specific angle
void servoSetAngle(uint8_t servo_nr, int16_t angle);
 
// vor servoInit(), oder vor sei() ServoWerte mit servoSet...() initialisieren, einschließlich servoSetPosition(...)!
void servoSet_rev(uint8_t channel, uint8_t val);
void servoSet_min(uint8_t channel, uint16_t min);
void servoSet_max(uint8_t channel, uint16_t max);
void servoSet_mid(uint8_t channel, uint16_t mid);
uint16_t pw_us(uint16_t Steps); // gibt Zeit in µs bei x Servoschritte
uint16_t ServoSteps(void); // gibt "Konstante" derzeitiger Servoschritte zürück
 
#endif /* SERVO_H */
/NGVideo5_8/tags/v1.33/tools.c
0,0 → 1,195
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <stdlib.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
 
#include "config.h"
#include "dogm.h"
#include "tools.h"
#include "messages.h"
 
#define MAX_POWER 10
#define getPower(x) (int32_t)pgm_read_dword(&powers[x])
const int32_t PROGMEM powers[MAX_POWER] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
 
/* Funktion zur Umwandlung einer vorzeichenbehafteten Integer
32-Bit "Festkomma-Zahl"(gedachtes Komma in Integer) in einen String
vereinfacht Variablenübergabe funktion change_value(uint16_t x),
kein printf, double oder float
siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik
len: max 13, Gesamtlänge des Resultats inklusive Vorzeichen und Komma, Rest wird mit ' ' aufgefüllt
fixedPoint: Position des Kommas im Integer-Wert. Bei Wert in mm und Anzeige in m ist das z.B. 3
afterPoint: Ziffern nach dem Komma = wieviele der fixedPoint Ziffern angezeigt werden sollen
 
Ist nicht genug Platz für die Zahl vorhanden werden nur '*' Zeichen ausgegeben!
makefile derzeit somit auch ohne! Minimalistic printf version*/
char *my_itoa(int32_t value, uint8_t len, uint8_t fixedPoint, uint8_t afterPoint)
{ int8_t i;
int8_t digits, digitsNeeded;
uint8_t neg = 0;
int32_t tmpvalue;
static char str[13];
// Terminate string
str[len] = '\0';
 
// Reduce precision of value if we're not supposed to show all of the mantissa
if (fixedPoint > afterPoint) {
value /= getPower(fixedPoint - afterPoint);
fixedPoint = afterPoint;
}
 
// Handle negative values
if (value < 0) {
value = -value;
neg = 1;
}
 
// Check how many digits we've got in total and if it fits in our space
for (digits = 1; digits < MAX_POWER && value >= getPower(digits); digits++);
if (neg) digits++; // We also need space for the sign
if (fixedPoint) digits++; // Plus space for decimal point
digitsNeeded = digits - len;
if (digitsNeeded > 0) {
// Not enough space, do something
if (digitsNeeded == fixedPoint || (digitsNeeded == fixedPoint + 1 && fixedPoint)) { // +1 = space for decimal point that we can get rid of
// If space is just big enough for integer part then simply don't show mantissa BUT ROUND CORRECTLY
tmpvalue = (value + 5 * getPower(fixedPoint - 1)) / getPower(fixedPoint);
for (digits = 1; digits < MAX_POWER && tmpvalue >= getPower(digits); digits++);
// wird durch Rundung Länge Darstellung überschritten?
if (digits + neg <= len)
value = tmpvalue;
else
value /= 10;
fixedPoint = 0;
}
else
if (digitsNeeded < fixedPoint) {
// We can reduce precision to make it fit (round correctly)
value = (value + 5 * getPower(digitsNeeded - 1)) / getPower(digitsNeeded);
for (digits = 1; digits < MAX_POWER && value >= getPower(digits); digits++);
// wird durch Rundung Länge Darstellung überschritten?
if (digits + neg <= len) {
--fixedPoint;
value /= 10;
}
fixedPoint -= digitsNeeded;
}
else {
// Error, cannot display value! Let's show stars
for (i = len - 1; i >= 0; --i) str[i] = '*';
return str;
}
}
 
for (i = len - 1; i >= neg; --i) {
if (fixedPoint && i == len - fixedPoint - 1) {
// Insert decimal point at the right location
str[i] = Msg(MSG_KOMMA)[0];
fixedPoint = 0; // Now in integer part
} else {
str[i] = (value % 10) + '0';
value /= 10;
// Break if we're in integer part and there are only zeros from this point on
if (value == 0 && fixedPoint == 0) {
--i;
break;
}
}
}
// Insert sign
if (neg) str[i--] = '-';
// Rest is blank
for (; i >= 0; --i)
str[i] = ' ';
 
return str;
}
 
 
// Trying to avoid floating point maths here. Converts a floating point string to an integer with a smaller unit
// i.e. floatStrToInt("4.5", 2) = 4.5 * 1E2 = 450
int32_t floatStrToInt(const char *s, int32_t power1)
{ char *endPtr;
int32_t v = strtol(s, &endPtr, 10);
 
if (*endPtr == '.') {
for (s = endPtr + 1; *s && power1; s++) {
v = v * 10 + (*s - '0');
--power1;
}
}
if (power1) {
// Table to avoid multiple multiplications
v = v * getPower(power1);
}
return v;
}
 
 
// Delay helper
void delay_ms100x(uint8_t delay)
{
for ( uint8_t i=0; i<delay; i++)
_delay_ms(100);
}
 
 
/************************************************************************************/
/* */
/* Zeitanzeige */
/* */
/************************************************************************************/
 
uint32_t TimeBase60(char *str, uint32_t time, uint8_t idx)
{ uint32_t tmp = time % 60;
 
str[idx] = (tmp / 10) + '0';
str[idx + 1] = (tmp % 10) + '0';
return time / 60;
}
 
void Displ_TimeMS(int32_t time)
{ char str[7];
 
str[6] = '\0';
if (time < 0) {
time = abs(time);
str[0] = '-';
}
else
str[0] = ' ';
time = TimeBase60(str, time, 4);
str[3] = ':';
TimeBase60(str, time, 1);
lcdPuts(str);
}
 
void Displ_TimeHMS(uint32_t time)
{ char str[9];
 
time /= T2SECDIV; // Zähler aller 500µs
str[8] = '\0';
time = TimeBase60(str, time, 6);
str[5] = ':';
time = TimeBase60(str, time, 3);
str[2] = ':';
TimeBase60(str, time, 0);
lcdPuts(str);
}
/NGVideo5_8/tags/v1.33/tools.h
0,0 → 1,15
#ifndef _TOOLS_H_
#define _TOOLS_H_
 
#include <avr/io.h>
 
//char *my_itoa(int32_t value, uint8_t sign, uint8_t len, uint8_t fixedPoint, uint8_t afterPoint);
char *my_itoa(int32_t value, uint8_t len, uint8_t fixedPoint, uint8_t afterPoint);
int32_t floatStrToInt(const char *s, int32_t power1);
 
void delay_ms100x(uint8_t delay);
 
void Displ_TimeMS(int32_t time);
void Displ_TimeHMS(uint32_t time);
 
#endif
/NGVideo5_8/tags/v1.33/tracking.c
0,0 → 1,398
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
#include "tracking.h"
#include "ngvideo.h"
#include "servo.h"
#include "tools.h"
#include "usart.h"
#include "config.h"
#include "mk.h"
#include "keys.h"
#include "mymath.h"
 
HomePos_t MK_pos; // Home position of station
GPS_Pos_t currentPos; // Current position of flying object
int8_t satsInUse; // Number of satelites currently in use
 
uint8_t tracking = TRACKING_MIN;
uint8_t track_hyst = TRACKING_HYSTERESE;
uint8_t track_tx = 0;
 
geo_t geo;
int16_t anglePan, angleTilt;
 
/**************************************************************/
/* */
/* RSSI Tracking */
/* */
/**************************************************************/
 
void Tracking_RSSI(void)
{ uint16_t u0, u1;
static uint8_t direction;
static uint16_t servo1pos;
u0 = (ADC_Read_inv(RSSI0) * (uint32_t)udbm.korr_1)/UDBM_KORR_FA;
u1 = (ADC_Read_inv(RSSI1) * (uint32_t)udbm.korr_2)/UDBM_KORR_FA;
 
if (direction == DLEFT) {
if (u0 < u1) {
if ( servo1pos > 0) --servo1pos; // Servo Endposition?
servoSetPosition(SERVO_PAN, servo1pos); // beibehaltene Richtung ==> sofort ausführen
}
else
if (u0 > (u1 + track_hyst)) direction = DRIGHT; // Richtungwechsel, wenn Hysterese überschritten
}
else {
if (u0 > u1) {
if ( servo1pos < ServoSteps()) ++servo1pos; // Servo Endposition?
servoSetPosition(SERVO_PAN, servo1pos); // beibehaltene Richtung ==> sofort ausführen
}
else
if ((track_hyst + u0) < u1) direction = DLEFT; // Richtungwechsel, wenn Hysterese überschritten
}
}
 
/**************************************************************/
/* */
/* GPS Tracking */
/* */
/**************************************************************/
 
// Datenempfang vom MK ==> blinkt Antennensymbol
void Displ_wiRX(void)
{ static uint8_t timer = 0;
static uint8_t picturedSats;
if (!bat_low && (pmenu[0] == '\0')) { // nicht im Menü und nicht bei Akku leer blinken
lcdGotoXY(1, 0);
if (wi232RX) { // Datensatz vom MK empfangen?
if (timer < BLINK_PERIOD/2) {
picturedSats = 0;
lcdPutc(5); // Antennensymbol darstellen
}
else {
if (!picturedSats) { // Änderung Satelittenanzahl innerhalb dieser Periode nicht anzeigen
picturedSats = 1;
// aktuell empfangene Satellitenanzahl, Anzeige einstellig, da kein Platz auf Display
lcdPutc(satsInUse > 9? 'X': satsInUse + '0');
}
}
}
else
lcdPutc(':');
if (timer % 20 == 0) wi232RX = 0; // mehr Zeit für nächsten Datensatz lassen
if (++timer == BLINK_PERIOD) timer = 0;
}
}
 
// Berechnung von Distanz und Winkel aus GPS-Daten home(MK eingeschaltet)
// zur aktuellen Position(nach Motorstart)
geo_t calc_geo(HomePos_t *home, GPS_Pos_t *pos)
{ int32_t lat1, lon1, lat2, lon2;
int32_t d1, dlat;
geo_t geo;
lon1 = MK_pos.Home_Lon;
lat1 = MK_pos.Home_Lat;
lon2 = pos->Longitude;
lat2 = pos->Latitude;
 
// Formel verwendet von http://www.kompf.de/gps/distcalc.html
// 111.3 km = Abstand zweier Breitenkreise und/oder zweier Längenkreise am Äquator
// es wird jedoch in dm Meter weiter gerechnet
// (tlon1 - tlon2)/10) sonst uint32_t-Überlauf bei cos(0) gleich 1
d1 = (1359 * (int32_t)(c_cos_8192((lat1 + lat2) / 20000000)) * ((lon1 - lon2)/10))/ 10000000;
dlat = 1113 * (lat1 - lat2) / 10000;
geo.bearing = (my_atan2(d1, dlat) + 540) % 360; // 360 +180 besserer Vergleich mit MkCockpit
geo.distance = sqrt32(d1 * d1 + dlat * dlat);
return(geo);
}
 
// Anzeige eines GPS-Wertes auf LCD
void Displ_Format_Data(uint8_t x, uint8_t y, char *description, char *data, char measure)
{
lcdGotoXY(x, y);
lcdPuts(description);
lcdPuts(data);
if (measure != '\0')
lcdPutc(measure);
}
 
 
//void Displ_GPS(int anglePan, int angleTilt, geo_t *geo)
void Displ_GPS(void)
{ uint16_t dDCurrent = 0;
// int32_t time_remaining = M59S59;
int32_t time_remaining = 0;
 
if (gps_display > GPS_DISP_NONE && (!coldstart || gps_display == GPS_MISC) && !bat_low) {
if (gps_disp_clear && !coldstart) {
gps_disp_clear = 0;
lcdClear();
}
// makefile ohne! Minimalistic printf version
switch (gps_display) {
case GPS_DISP_CALC:
Displ_Format_Data(0, 0, "Dir:", my_itoa(MK_pos.direction, 3, 0, 0), '\xdf'); // '\xdf' entspricht '°'
Displ_Format_Data(8, 0, "Dis:", my_itoa((uint32_t)geo.distance, 3, 1, 1), 'm');
Displ_Format_Data(0, 1, "Bea:", my_itoa((uint32_t)geo.bearing, 3, 0, 0), '\xdf');
Displ_Format_Data(8, 1, "Alt:", my_itoa(currentPos.Altitude - MK_pos.Home_Alt, 3, 3, 1), 'm');
Displ_Format_Data(0, 2, "Pan:", my_itoa(anglePan, 3, 0, 0), '\xdf');
Displ_Format_Data(8, 2, "Til:", my_itoa(angleTilt, 3, 0, 0), '\xdf');
break;
case GPS_DISP_CURRENT:
Displ_Format_Data(0, 0, "aLon:", my_itoa(currentPos.Longitude, 11, 7, 7), '\0');
Displ_Format_Data(0, 1, "aLat:", my_itoa(currentPos.Latitude, 11, 7, 7), '\0');
Displ_Format_Data(0, 2, "aAlt:", my_itoa(currentPos.Altitude, 11, 3, 1), '\0');
break;
case GPS_DISP_HOME:
Displ_Format_Data(0, 0, "hLon:", my_itoa(MK_pos.Home_Lon, 11, 7, 7), '\0');
Displ_Format_Data(0, 1, "hLat:", my_itoa(MK_pos.Home_Lat, 11, 7, 7), '\0');
Displ_Format_Data(0, 2, "hAlt:", my_itoa(MK_pos.Home_Alt, 11, 3, 1), '\0');
// >> Menueauswahl nach oben
if (Get_Key_Press( 1<<SW_PLUS ) || Get_Key_Press( 1<<SW_MINUS )) coldstart = 1;
break;
case GPS_MISC:
Displ_Format_Data(0, 0, "U:", my_itoa(mk_UBat, 4, 1, 1), 'V');
Displ_Format_Data(8, 0, "W:", my_itoa(mk_dUsedCapacity, 4, 0, 0), '\0');
Displ_Format_Data(0, 1, "I:", my_itoa(mk_Ikorr, 4, 1, 1), 'A');
if (mk_current.Count > 0) {
dDCurrent = mk_current.Sum / mk_current.Count;
if (dDCurrent > 0) {
time_remaining = ((int32_t)mk_lipo.Capacity - mk_dUsedCapacity) * 36 / dDCurrent;
if (abs(time_remaining) > M59S59)
time_remaining = time_remaining < 0? -M59S59: M59S59; // M59S59 sind 59 Minuten und 59 Sekunden
}
}
Displ_Format_Data(8, 1, "\xee:", my_itoa(dDCurrent, 4, 1, 1), 'A');// Durchschnittszeichen
lcdGotoXY(0,2);
lcdPutc('\x1a'); // Summenzeichen
Displ_TimeMS(mk_lipo.time_on / T2SECDIV);
lcdGotoXY(8,2);
lcdPuts("R");
Displ_TimeMS(time_remaining);
break;
}
}
Displ_wiRX();
}
 
void do_tracking(void)
{ static uint8_t hysteresis = 0;
 
geo = calc_geo(&MK_pos, &currentPos);
angleTilt = my_atan2((currentPos.Altitude - MK_pos.Home_Alt) / 100, geo.distance);
if (geo.distance < 40 || (geo.distance < 60 && hysteresis)) { // < 4m ==> Pan-Servo in Mittelstellung. Hysterese bis 6m, damit Servo im Grenzbereich nicht wild rumschlägt
geo.bearing = MK_pos.direction;
if (currentPos.Altitude - MK_pos.Home_Alt < 4000) angleTilt = 0; // man fliegt nicht direkt über Kopf
hysteresis = 1;
}
else {
hysteresis = 0;
}
 
// egal wo der Übergangspunkt 359, 360, 1grd ist => Winkelübergangspunkt auf 0 bzw. 180grd des Servos bringen
// 360 grd negative Winkelwerte als positive
anglePan = (geo.bearing + 450 - MK_pos.direction) % 360; // 450 = 360 + 90
 
if (angleTilt < 0) angleTilt = 0;
if (angleTilt > 180) angleTilt = 180;
 
if (anglePan >= 180) { // zwecks 360grd-Abdeckung flipt Pan-/Tilt-Servo
anglePan = anglePan - 180;
angleTilt = 180 - angleTilt;
}
 
servoSetAngle(0, anglePan);
servoSetAngle(1, angleTilt);
}
 
 
/**************************************************************/
/* */
/* MK GPS Tracking */
/* */
/**************************************************************/
 
// MK OSD-Daten lesen und verifizieren
uint8_t OSD_Data_valid(NaviData_t **navi_data)
{ uint8_t ret = 0;
char *tx_osd = {"#co?]==EH\r"};
// char interval[2] = {10, '\0'};
if (rx_line_decode() == 'O') { // OSD-Datensatz prüfen/dekodieren
*navi_data = (NaviData_t*)data_decode; // dekodierte Daten mit Struktur OSD-Daten versehen
currentPos = (*navi_data)->CurrentPosition;
if ((*navi_data)->NCFlags & NC_FLAG_GPS_OK)
ret = 1;
// aus MkCockpit http://forum.mikrokopter.de/topic-post216136.html#post216136
// (4 * (........))/5 ==> Wichtung Luftdruck-Höhe zu GPS
currentPos.Altitude = MK_pos.Home_Alt + (4000 * (int32_t)((*navi_data)->Altimeter) / AltFaktor + currentPos.Altitude - MK_pos.Home_Alt) / 5;
// currentPos.Altitude = MK_pos.Home_Alt + 1000 * (int32_t)(*navi_data)->Altimeter / AltFaktor;
MK_Motor_run = (*navi_data)->FCStatusFlags & FC_FLAG_MOTOR_RUN;
MK_ProcessLipo(*navi_data);
satsInUse = (*navi_data)->SatsInUse;
}
else
// ca. 210ms keine OSD-Daten empfangen ==> sende neue Anforderung an MK
if ((track_tx) && (rx_timeout > RX_TIMEOUT)) {
USART_send_Str(tx_osd); // 420 * 0.5ms interval
// tx_Mk(NC_ADDRESS, 'o', interval, 1); // 420 * 0.5ms interval
if (rx_timeout == RX_TIME_END) store_LipoData();// ca. 4 Sekunden nach Signalverlust
}
return ret;
}
 
 
// MK eingeschaltet und GPS-ok, danach Motoren gestartet ==> Berechnung horizontaler/vertikaler Servowinkel
// Hauptprogramm von GPS Antennen-Nachführung
void Tracking_GPS(void)
{ NaviData_t *navi_data;
static uint8_t track_running = 0;
 
if (!track_running) {
track_running = 1; // verhindert doppelten Aufruf, wenn in Eingabeschleife Menu_MK_BatteryChangeNr() !!!
if (OSD_Data_valid(&navi_data)) {
if (coldstart) {
// erst nach Neustart NGVideo und beim Motorstart werden Daten vom MK übernommen
if (navi_data->FCStatusFlags & FC_FLAG_MOTOR_START) {
MK_pos.Home_Lon = navi_data->HomePosition.Longitude;
MK_pos.Home_Lat = navi_data->HomePosition.Latitude;
MK_pos.Home_Alt = navi_data->HomePosition.Altitude;
MK_pos.direction = navi_data->CompassHeading;
coldstart = 0;
}
}
else {
do_tracking();
}
}
Displ_GPS(); // letzte empfangene Daten auch bei ausgeschalteten MK sichtbar
track_running = 0;
}
}
 
/**************************************************************/
/* */
/* NMEA GPS Tracking */
/* */
/**************************************************************/
 
void setNMEAdir(void)
{
if (!coldstart)
MK_pos.direction = geo.bearing;
}
 
// NMEA latitudes are in the form ddmm.mmmmm, we want an integer in 1E-7 degree steps
int32_t getLatitude(const char *s, const char *NS)
{ int32_t deg = (s[0] - '0') * 10 + s[1] - '0'; // First 2 chars are full degrees
int32_t min = floatStrToInt(&s[2], 6) / 6; // Minutes * 1E5 * 100 / 60 = Minutes * 1E6 / 6 = 1E-7 degree steps
 
deg = deg * 10000000 + min;
if (*NS == 'S') deg = -deg;
return deg;
}
 
 
// NMEA longitudes are in the form dddmm.mmmmm, we want an integer in 1E-7 degree steps
int32_t getLongitude(const char *s, const char *WE)
{ int32_t deg = ((s[0] - '0') * 10 + s[1] - '0') * 10 + s[2] - '0'; // First 3 chars are full degrees
int32_t min = floatStrToInt(&s[3], 6) / 6; // Minutes * 1E5 * 100 / 60 = Minutes * 1E6 / 6 = 1E-7 degree steps
 
deg = deg * 10000000 + min;
if (*WE == 'W') deg = -deg;
return deg;
}
 
 
void Tracking_NMEA(void)
{ char *token;
int32_t latitude, longitude;
 
if (decodeNMEA()) {
token = strtok((char*)data_decode, ",");
// http://de.wikipedia.org/wiki/NMEA_0183
if (!strcmp(token, "GPGGA")) {
// $GPGGA,220613.400,4843.5080,N,00922.9583,E,1,7,2.23,287.1,M,48.0,M,,
// Skip time
strtok(0, ",");
// Latitude
latitude = getLatitude(strtok(0, ","), strtok(0, ","));
// Longitude
longitude = getLongitude(strtok(0, ","), strtok(0, ","));
// Signal valid? (Position Fix Indicator)
if (*strtok(0, ",") != '0') {
// Satellites in use
satsInUse = atoi(strtok(0, ","));
// Skip dilution
strtok(0, ",");
// Altitude
currentPos.Altitude = floatStrToInt(strtok(0, ","), 3);
currentPos.Latitude = latitude;
currentPos.Longitude = longitude;
 
if ((coldstart) && (satsInUse > 5)) {
// First position after reboot (or change of mode) will be the home position (facing north)
MK_pos.Home_Lon = currentPos.Longitude;
MK_pos.Home_Lat = currentPos.Latitude;
MK_pos.Home_Alt = currentPos.Altitude;
MK_pos.direction = 0;
coldstart = 0;
Double_Beep(DBEEPNMEAFIX, DBEEPMEAFIXP);
}
do_tracking();
}
}
}
Displ_GPS(); // letzte empfangene Daten auch bei ausgeschalteter NMEA sichtbar
}
 
 
/************************************************************************/
/* */
/* MKCockPit Tracking */
/* */
/* http://www.pololu.com/file/download/ssc03a_guide.pdf?file_id=0J37 */
/* */
/************************************************************************/
 
void Tracking_MKCockpit(void)
{ uint16_t ServoPos;
 
if (Get_Pololu_cmd(data_decode, POLOLU_CMD)) {
switch (data_decode[0]) {
// Command 0: Set Parameters(1 data byte)
case 0x00: ;
break;
// Command 1: Set Speed (1 data byte)
case 0x01: ;
break;
// Command 4: Set Position,Absollute(2 data bytes) - angepasst für default MKCockPit
case 0x04: ServoPos = data_decode[2];
ServoPos = ((ServoPos << 7) | data_decode[3]) / 20; // ServoPos * ServoSteps() sonst zu groß
 
if (ServoPos >= 60) ServoPos -= 60; else ServoPos = 0;
if (ServoPos > 180) ServoPos = 180;
servoSetAngle(data_decode[1], ServoPos);
}
}
}
/NGVideo5_8/tags/v1.33/tracking.h
0,0 → 1,31
#ifndef _TRACKING_H_
#define _TRACKING_H_
 
#define TRACKING_RSSI 1
#define TRACKING_GPS 2
#define TRACKING_MKCOCKPIT 3
#define TRACKING_NMEA 4
 
#define DLEFT 0
#define DRIGHT 1
#define AltFaktor 22.5
 
typedef struct {
int32_t distance;
int16_t bearing;
}geo_t;
 
typedef struct {
int32_t Home_Lon; // in 1E-7 degrees
int32_t Home_Lat; // in 1E-7 degrees
int32_t Home_Alt; // in mm
int16_t direction; // ermittelte Konstante aus Mittelposition Antenne geo.bearing - navi_data.CompassHeading
}__attribute__((packed)) HomePos_t;
 
void Tracking_MKCockpit(void);
void Tracking_GPS(void);
void Tracking_NMEA(void);
void Tracking_RSSI(void);
void setNMEAdir(void);
 
#endif
/NGVideo5_8/tags/v1.33/usart.c
0,0 → 1,302
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include "usart.h"
#include "tracking.h"
 
/********************************************************************************************************************/
/* */
/* MK Protokoll */
/* http://www.mikrokopter.de/ucwiki/en/SerialCommands?highlight=(command) */
/* http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol) */
/* */
/* Slave-Address Part */
/* 1 FC */
/* 2 NC */
/* 3 MK3MAG */
/* */
/* Auszug von Commands, nur OSD verwendet: */
/* Received by NC | ent by NC */
/* | since NC */
/* Description ID Address Data | ID Address Data Firmware */
/* Debug Request 'd' AnyAddr u8 AutoSendInterval. Value is | 'D' SlaveAddr Debug Data Struct */
/* multiplied by 10 in receiver and , | */
/* then used as milliseconds. Subsciption | */
/* needs to be renewed every 4s. | */
/* Request OSD 'o' NC-Addr 1 byte sending interval (in 10ms steps)| 'O' NC-Addr NaviDataStruct 0.12h */
/* Data | */
/* Redirect UART 'u' NC-Addr 1 byte param for uart selector (0=FC, | - - - 0.12h */
/* 1=MK3MAG, 2=MKGPS), can be switched | */
/* back to NC debug by sending the magic | */
/* packet "0x1B,0x1B,0x55,0xAA,0x00" | */
/* Set 3D-Data 'c' AnyAddr u8 Interval | 'C' NC-Addr struct Data3D 0.14a */
/* Interval */
/* */
/********************************************************************************************************************/
 
char rx_buffer[RXD_BUFFER_SIZE];
 
volatile uint8_t rx_len;
volatile uint8_t rx_ready = 0;
uint8_t rx_GPS;
static char start;
static char end;
 
/**************************************************************/
/* */
/* USART */
/* 8 Datenbits, 1 Stopbit, keine Parität */
/* */
/**************************************************************/
 
void USART_Init(unsigned int baud)
{ uint16_t ubrx;
 
ubrx = F_CPU/(baud * 16L) - 1;
/* Set baud rate */
UBRR0H = (unsigned char)(ubrx>>8);
UBRR0L = (unsigned char)ubrx;
/* RX Complete Interrupt Enable, Enable receiver and transmitter */
UCSR0B = (1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0);
/* Asynchronous USART, no Parity, Set frame format: 8data, 1stop bit */
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); // 8data Bit
}
 
void USART_send_Chr(unsigned char data)
{
/* Wait for empty transmit Puffer */
while ( !( UCSR0A & (1<<UDRE0)) ) ;
/* Put data into Puffer, sends the data */
UDR0 = data;
}
 
void USART_send_Str(char *str )
{
while (*str) {
USART_send_Chr(*str);
str++;
}
}
 
/*
// verwendet Orginal H&I MK-Software http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)
// kann auch vereinfacht werden ==> gleich kodierten String senden char *tx_osd = {"#co?]==EH\r\0"}
// Funktion getestet und funktioniert
void tx_Mk(unsigned char addr, char cmd, char *data, uint8_t len)
{ char tx_buffer[TXD_BUFFER_SIZE];
uint8_t tx_i = 0;
uint8_t i = 0;
unsigned char a,b,c;
unsigned int tmpCRC = 0;
 
tx_buffer[tx_i++] = '#'; // Start-Byte
tx_buffer[tx_i++] = 'a' + addr; // Adress
tx_buffer[tx_i++] = cmd; // Command
// code64
while (len) {
if (len) { a = data[i++]; len--;} else a = 0;
if (len) { b = data[i++]; len--;} else b = 0;
if (len) { c = data[i++]; len--;} else c = 0;
tx_buffer[tx_i++] = '=' + (a >> 2);
tx_buffer[tx_i++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
tx_buffer[tx_i++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
tx_buffer[tx_i++] = '=' + (c & 0x3f);
}
// add crc
for (i = 0; i < tx_i; i++) {
tmpCRC += tx_buffer[i];
}
tmpCRC %= 4096;
tx_buffer[i++] = '=' + tmpCRC / 64;
tx_buffer[i++] = '=' + tmpCRC % 64;
tx_buffer[i++] = '\r'; // End-Byte
 
tx_buffer[i++] = '\0'; // USART_send_Str(...) ==> End-while
USART_send_Str(tx_buffer);
} */
 
ISR(USART0_RX_vect)
{ const char ID[] = ID_LIST; // einfache Erweiterung für andere IDs möglich
uint8_t ID_found;
char received;
static uint8_t line_flag = 1;
static char* ptr_write = rx_buffer;
static uint8_t frame = 6;
 
received = UDR0;
if (!rx_ready) {
if ((received == start) && line_flag) { // start '#', '$' or 0x80
line_flag = 0; // New line has begun
ptr_write = rx_buffer; // Begin at start of buffer
rx_len = 0;
}
if (!line_flag) { // Are we receiving a line?
*ptr_write = received; // Add current byte
rx_len++;
 
// GPS Datensatzende
if (rx_GPS) {
if (received == end) { // End of MK-GPS or NMEA-line?
line_flag = 1; // Yes, start new line
if (TRACKING_GPS) {
// für Blinken des Antennenzeichens, MK antwortet immer mit cmd Großbuchstaben
if ((rx_len > 2) && (rx_buffer[2] >= 'A') && (rx_buffer[2] <= 'Z')) {
wi232RX = 1;
// nicht benötigte Datensätze bereits jetzt verwerfen
for (ID_found=0; ID_found < sizeof(ID) && rx_buffer[2] == ID[ID_found]; ID_found++)
rx_ready = ID_found < sizeof(ID); // MK Lock buffer "rx_ready > 0" until line has been processed
}
}
else rx_ready = 1; // NMEA Lock buffer until line has been processed
}
}
// Pololu Micro Serial very reduced/simplified; rx_len-checks 1 higher ==> already incremented
else {
if ((rx_len == 2) && (received != 0x01)) line_flag = 1; // device
if ((rx_len == 3) && (received > 0x01)) frame = 6; else frame = 5; // command
if (rx_len == frame) {
line_flag = 1;
rx_ready = 1; // Lock buffer until line has been processed
}
}
 
ptr_write++;
if(rx_len == RXD_BUFFER_SIZE) line_flag = 1; // Line too long? Try again
}
}
}
 
// verwendet aus Orginal H&I MK-Software http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)
void Decode64(char *ptrOut, uint8_t len, uint8_t ptrIn)
{ unsigned char a,b,c,d;
unsigned char ptr = 0;
unsigned char x,y,z;
while(len)
{
a = rx_buffer[ptrIn++] - '=';
b = rx_buffer[ptrIn++] - '=';
c = rx_buffer[ptrIn++] - '=';
d = rx_buffer[ptrIn++] - '=';
 
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;
}
}
 
// eingearbeitet Original H&I MK-Software mkprotocol.h und mkprotocol.c
char rx_line_decode(void)
{ uint8_t ret = 0;
uint8_t crc1,crc2;
int tmpCRC = 0;
// rx_ready gleichzeitig usart rx_buffer schreiben gesperrt
if (rx_ready) {
// Checksumme
// verwendet http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)
for(uint8_t i = 0; i < rx_len - 3;i++) {
tmpCRC += rx_buffer[i];
}
tmpCRC %= 4096;
crc1 = '=' + tmpCRC / 64;
crc2 = '=' + tmpCRC % 64;
if ((crc1 == rx_buffer[rx_len-3]) && (crc2 == rx_buffer[rx_len-2])) {
Decode64(data_decode, rx_len - 6, 3); // Daten ohne Satzzeichen, header und crc
ret = rx_buffer[2];
cli();
rx_timeout = 0; // wenn kein gültiger Datensatz rx_ID ==> Counter wird nicht mehr rückgesetzt
sei();
}
}
// Puffer Schreiben entsperren, neuer MK-Datensatz kann wieder empfangen/gepuffert werden
rx_ready = 0;
return(ret);
}
 
uint8_t hexDigitToInt(uint8_t digit)
{
if (digit >= '0' && digit <= '9') return digit - '0';
if (digit >= 'a' && digit <= 'f') return digit - 'a' + 10;
if (digit >= 'A' && digit <= 'F') return digit - 'A' + 10;
return 0;
}
 
uint8_t decodeNMEA(void)
{ uint8_t ret = 0;
uint8_t crc;
uint8_t tmpCRC = 0;
uint8_t i;
 
if (rx_ready == 1 && rx_len > 0) {
// Calculate checksum
for (i = 1; i < rx_len && rx_buffer[i] != '*'; i++) {
tmpCRC ^= rx_buffer[i];
}
if (rx_len >= i + 3) {
crc = hexDigitToInt(rx_buffer[i + 1]) << 4 | hexDigitToInt(rx_buffer[i + 2]);
if (crc == tmpCRC) {
rx_buffer[i] = 0;
strcpy(data_decode, &rx_buffer[1]); // Data without $, crc
ret = 1;
wi232RX = 1; // So antenna-symbol will blink
cli();
rx_timeout = 0; // Got valid data, reset counter
sei();
}
}
}
if (rx_timeout < RX_TIME_OLD) wi232RX = 1;
rx_ready = 0; // Unlock buffer, next NMEA string can be received
return ret;
}
 
void USART_RX_Mode(uint8_t tracking)
{
switch (tracking) {
case TRACKING_GPS:
start = '#';
end = '\r';
rx_GPS = 1;
break;
case TRACKING_NMEA:
start = '$';
end = '\n';
rx_GPS = 1;
break;
default:
start = 0x80;
rx_GPS = 0;
break;
}
}
 
uint8_t Get_Pololu_cmd(char *ptrOut, uint8_t ptrIn)
{
rx_len -=2; // ohne Start-Char und device
if (rx_ready == 1) {
for (uint8_t i = 0; i < rx_len; i++)
ptrOut[i] = rx_buffer[ptrIn++]; // ab Pololu-Command
}
else
rx_len = 0;
rx_ready = 0; // Puffer Schreiben entsperren, neuer Pololu-Datensatz kann wieder empfangen/gepuffert werden
return(rx_len);
}
/NGVideo5_8/tags/v1.33/usart.h
0,0 → 1,48
 
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
 
#ifndef USART_H_
#define USART_H_
 
#define RXD_BUFFER_SIZE 150 // Puffergröße in Byte
#define TXD_BUFFER_SIZE 20
 
#define RX_TIMEOUT 420 // 210ms
#define RX_TIME_OLD 3 * RX_TIMEOUT // Grenze, Datensatz viel zu alt
#define RX_TIME_END 20* RX_TIMEOUT // Zählerbegrenzung und lipo speichern
 
//volatile unsigned char buffercounter;
 
char data_decode[RXD_BUFFER_SIZE];
volatile uint16_t rx_timeout;
 
void USART_Init(unsigned int baud);
void USART_send_Str(char *str);
char rx_line_decode(void);
 
// tx_Mk addresses
#define ANY_ADDRESS 0
#define FC_ADDRESS 1
#define NC_ADDRESS 2
 
#define ID_LIST {'O'}
 
//void tx_Mk(unsigned char addr, char cmd, char *data, uint8_t len);
 
uint8_t wi232RX; // Statusflag für Empfangszeichen auf lcd
 
void USART_RX_Mode(uint8_t tracking);
uint8_t Get_Pololu_cmd(char *ptrOut, uint8_t ptrIn);
uint8_t decodeNMEA(void);
 
#endif /* USART_H_ */
 
/NGVideo5_8/tags/v1.33
Property changes:
Added: bugtraq:number
+true
\ No newline at end of property