Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 958 → Rev 957

/C-OSD/trunk/tags/v1.00/Hexfiles/NGVideo_MEGA644.hex
0,0 → 1,1781
:100000000C943A050C9445070C9475070C9457050D
:100010000C9457050C9457050C9457050C945705F0
:100020000C9457050C9457050C9457050C94100725
:100030000C9457050C94F0270C9457050C94570515
:100040000C9457050C9457050C9444240C945705B4
:100050000C949E280C9457050C9457050C94570546
:100060000C9457050C9457050C9457050C945705A0
:10007000084AD73B3BCE016E84BCBFFDC12F3D6C0F
:1000800074319ABD56833DDA3D00C77F11BED9E475
:10009000BB4C3E916BAAAABE000000803F05A84C55
:1000A000CDB2D44EB93836A9020C50B99186880821
:1000B0003CA6AAAA2ABE000000803F525353492DF5
:1000C0004D696E00525353492D4D61780044697655
:1000D000657273697479004C4344004156310041A4
:1000E0005632003235350031303233005365727686
:1000F0006F203100536572766F203200525353499E
:10010000004D4B2D436F636B7069740053657276BD
:100110006F2D4879737465722E0042617564726147
:1001200074650020203556004E472D566964656F72
:100130002020352E3847487A0A48573A2000202098
:100140004D2E4265636B46573A20312E30302020C9
:10015000676562616400537072616368650044653D
:10016000757473636800456E676C697363680046F5
:1001700072616E7A947369736368005A75728163F1
:100180006B0041562D5175656C6C650052582D4BB6
:10019000616E616C00525353492D4B616C69627200
:1001A0002E004269747465205458206175662000E1
:1001B0004155530045494E00576569746572206D7D
:1001C000697420456E746572004B6F6E7472617352
:1001D00074004C43442D42656C65756368742E0051
:1001E0004C696368743A0020696D6D6572206175B1
:1001F000730020696D6D65722065696E002053651E
:100200006B2E00426174746572696500552D4D69ED
:100210006E00556E74657273702E2D536574757013
:1002200000552D4F6666736574004B616C69627290
:10023000696572756E67006C8475667400466568E2
:100240006C6572210053656E646572206E69636827
:10025000742000202020202020416B6B750A202074
:100260002020656E746C6164656E21005365727642
:100270006F2D4B616C6962722E00536572766F2D23
:10028000536368726974746500536572766F2031C8
:10029000207265762E004B616C69622E31206C698C
:1002A0006E6B73004B616C69622E312072656368FE
:1002B0007473004B616C69622E31204D69747465F2
:1002C00000536572766F2032207265762E004B6186
:1002D0006C69622E32206C696E6B73004B616C69C5
:1002E000622E3220726563687473004B616C6962C0
:1002F0002E32204D69747465006175730065696EF6
:1003000000416E74656E6E65206E616368662E00D6
:10031000475053206D697420776932333200545846
:10032000204F53442D446174656E004879737465A1
:10033000726573650053656E646520466F7264650F
:1003400072756E67004750532D416E7A6569676517
:100350006E006265726563686E2E20446174656E1E
:1003600000616B7475656C6C6520506F732E005363
:1003700074617274706F736974696F6E00202020ED
:1003800020204E6F63680A20206B65696E652044EB
:100390006174656E0A202020656D7066616E676508
:1003A0006E210053657269656C6C20434F4D002CC3
:1003B00000332C3356004C616E67756167650047EA
:1003C00065726D616E00456E676C69736800467298
:1003D000656E63680052657475726E0041562D53E8
:1003E0006F757263650052582D4368616E6E656C5F
:1003F00000525353492D43616C6962722E00545868
:100400002073776974636820004F4646004F4E00A2
:10041000436F6E74696E756520456E746572004336
:100420006F6E7472617374004261636B67722E2029
:100430004C69676874004C696768743A00616C774E
:10044000617973206F66660020616C776179732033
:100450006F6E00207365632E00426174746572795B
:1004600000552D4D696E004C6F7720766F6C74616E
:10047000676500552D4F66667365740043616C694E
:1004800062726174696F6E0072756E6E696E67007C
:100490004572726F7221005472616E736D6974746B
:1004A0006572206E6F742000202020202020416380
:1004B00063750A2020202020206C6F77210053656F
:1004C00072766F2D43616C6962722E00536572768D
:1004D0006F2D537465707300536572766F203120F1
:1004E0007265762E0043616C69622E31206C656600
:1004F000740043616C69622E312072696768740010
:1005000043616C69622E31206D6964646C650053CF
:100510006572766F2032207265762E0043616C69B9
:10052000622E32206C6566740043616C69622E3203
:100530002072696768740043616C69622E32206DB5
:100540006964646C65006F6666006F6E20005472AB
:1005500061636B696E670047505320776974682048
:100560007769323332005458204F53442D4461741C
:100570006100487973746572657365005472616EC9
:10058000736D69742064656D616E64004469737095
:100590006C6179204750530063616C632E20446185
:1005A00074610063757272656E7420506F732E00F3
:1005B000486F6D65706F736974696F6E00202020DD
:1005C000204E6F74207965740A2020202020446119
:1005D00074610A2020207265636569766564210074
:1005E00053657269656C6C20434F4D002E00332EAD
:1005F0003356004C616E67756500416C6C656D61CA
:100600006E6400416E676C616973004672616E874B
:10061000616973005265746F75720041562D536F96
:10062000757263650052582D43616E616C005253C0
:1006300053492D43616C6962722E000045746569EF
:100640006E64726520547800416C6C756D65722023
:100650005478004170702E20456E74657200436FAF
:100660006E74726173746500526574722E204563F6
:100670006C0045636C61693A0020457465696E746D
:100680000020546A7273204F4E00205365632E0081
:10069000426174746572696500562D4D696E005330
:1006A0006575696C20416C61726D6500562D4F66F1
:1006B000667365740043616C6962726174696F6E20
:1006C00000456E20636F75727300457272657572B6
:1006D00021004E6F20547800202020204261747445
:1006E000657269650A20202020666169626C652157
:1006F00000536572766F2D43616C696272004E62C1
:1007000072652064652050617300496E766572736E
:100710002E20536572766F310043616C2E20476145
:10072000756368650043616C2E2044726F6974655F
:100730000043616C2E2043656E74726500496E76CD
:100740006572732E20536572766F320043616C2E92
:10075000204761756368650043616C2E2044726FA9
:100760006974650043616C2E2043656E7472650088
:100770004F4646004F4E2000547261636B696E67AE
:10078000004750532077697468207769323332000C
:100790005458204F53442D44617461004879737458
:1007A00065726573697300446F6E6E826520547262
:1007B000616E736D6965004166666963686167654E
:1007C000204750530043616C63756C2047505300C1
:1007D000506F732E2061637475656C6C6500486F93
:1007E0006D65706F736974696F6E00204175637514
:1007F0006E6520646F6E6E82650A20202020207254
:10080000658775652100434F4D2E205382726965BF
:10081000002E00332E33560056015E0166016F0133
:100820007B0182018C019501A201B001B401B801E4
:10083000C901D201E001E701F201FD0103020C024E
:10084000120221022A0237023D02450253026C02C3
:100850007A0289029602A402B302C102CE02DC022D
:10086000EB02F902FD02010310031E032B03350303
:100870004503520361036F037D03A303AF03B10379
:10088000B603BF03C603CE03D503DC03E603F103BF
:10089000FE0309040D0410041F04280436043D045B
:1008A0004804530459046104670473047C048804F5
:1008B00090049704A804BE04CC04D804E504F20410
:1008C00000050F051C052905370546054A054E0597
:1008D0005705660572057C058C059805A305B005CE
:1008E000BD05E005EC05EE05F305FA0503060B066C
:1008F00014061B0625062E063B063C064806530634
:100900005E0668067206790681068A0690069906D2
:100910009F06AC06B506C106CA06D206D806F10681
:10092000FE060A071907250731073D074C07580738
:100930006407700774077807810790079C07A7076B
:10094000B707C507D007DE07EB070608110813082D
:10095000BB00C400CD00D700DB00DF00E300E700F0
:10096000EC00F400FC0001010C011A012301280134
:100970003E016E616E00696E660000407A10F35AA7
:1009800000A0724E18090010A5D4E80000E87648CF
:10099000170000E40B54020000CA9A3B000000E17B
:1009A000F505000080969800000040420F0000000E
:1009B000A08601000000102700000000E8030000EE
:1009C00000006400000000000A00000000000100B8
:1009D000000000002C76D888DC674F0823DFC1DFD9
:1009E000AE59E1B1B796E5E3E453C63AE6519976DC
:1009F00096E8E6C28426EB898C9B62ED407C6FFC16
:100A0000EFBC9C9F40F2BAA56FA5F490055A2AF757
:100A10005C936B6CF9676DC11BFCE0E40D47FEF560
:100A200020E6B500D0ED902E0300943577050080C8
:100A3000841E080000204E0A000000C80C33333327
:100A4000330F986E12831141EF8D2114893BE655C7
:100A500016CFFEE6DB18D1844B381BF77C1D901DAA
:100A6000A4BBE424203284725E228100C9F124EC0C
:100A7000A1E53D2711241FBECFEFD0E1DEBFCDBFE2
:100A800013E0A0E0B1E0E4E9FCE602C005900D92BD
:100A9000A838B107D9F715E0A8E8B3E001C01D9266
:100AA000A23BB107E1F70E9455220C9448360C9402
:100AB00000008150282F277092B1922B92B995B1E6
:100AC000292B25B9886F92B1982392B995B18923C2
:100AD00085B90895982F813041F0813018F0823027
:100AE00069F408C08DB38C7F07C08DB38C7F8DBB3C
:100AF000149A04C08DB383608DBB1498892F089518
:100B0000109288032F980895809188038823B1F468
:100B10008091B801882391F02091420430914304E0
:100B200090E02817390750F4F8941092430410927B
:100B30004204789481E0809388032F9A08958091ED
:100B40008803813009F54091B801442321F41092C3
:100B500088032F9808954F31B8F4F8948091420497
:100B600090914304019690934304809342047894B7
:100B70002091420430914304842F90E028173907D4
:100B800018F0109288032F98089580E480937C00D9
:100B900087E080937A0080917A00806880937A0061
:100BA00080917A00806480937A0080917A0086FD3B
:100BB000FCCF8091780090917900089590917C000D
:100BC0008F71907E892B80937C0080917A00806465
:100BD00080937A0080917A0086FDFCCF2091780086
:100BE00030917900C90108959F92AF92BF92CF9240
:100BF000DF92EF92FF920F931F93CF93DF93982E84
:100C00006B01EE24FF248701C0E0D0E088E8A82E25
:100C100083E1B82E0DC0892D0E94DE05A0E0B0E072
:100C2000E80EF91E0A1F1B1FC5010197F1F7219657
:100C3000CC15DD0580F3960140E050E0C801B70116
:100C40000E944233C901DF91CF911F910F91FF9014
:100C5000EF90DF90CF90BF90AF909F900895AF92AC
:100C6000BF92CF92DF92EF92FF920F931F931C9A45
:100C70001C9890E0A0E0B0E0BC01CD010E94D8300B
:100C80005B016C0120E030E44CE955E40E944F32F6
:100C90007B018C0120E030E040E85FE30E943830C7
:100CA00088231CF461E070E024C0C801B70120E093
:100CB0003FEF4FE757E40E9444321816B4F4C601E0
:100CC000B50120E030E040E251E40E944F320E9442
:100CD000AC3084EF91E005C0FC013197F1F7615031
:100CE000704061157105C1F707C0C801B7010E94C6
:100CF000AC30CB010197F1F71C9A1C981F910F9112
:100D0000FF90EF90DF90CF90BF90AF9008959F92AB
:100D1000AF92BF92CF92DF92EF92FF920F931F9309
:100D2000982EE62E0E942F06FF2400E010E0C80156
:100D3000B7010E94D8305B016C0120E030E44CE93F
:100D400055E40E944F327B018C0120E030E040E806
:100D50005FE30E94383088231CF461E070E024C017
:100D6000C801B70120E03FEF4FE757E40E9444324B
:100D70001816B4F4C601B50120E030E040E251E4B9
:100D80000E944F320E94AC3084EF91E005C0FC011C
:100D90003197F1F76150704061157105C1F707C0D7
:100DA000C801B7010E94AC30CB010197F1F7892D42
:100DB0000E942F061F910F91FF90EF90DF90CF9030
:100DC000BF90AF909F900895CF93DF93EC018091F7
:100DD000C0019091C10103972091C2013091C301DC
:100DE000821B930B6BE070E00E942E3370E040E0BA
:100DF00050E020E030E0FE01E20FF31F8091C001DF
:100E00009091C101841B950B91838083460F571FDE
:100E10002E5F3F4F2831310571F7DF91CF91089553
:100E20001F920F920FB60F9211242F938F939F93BF
:100E300084E68093B2008091F6048F3F29F0809180
:100E4000F6048F5F8093F6048091E7038F3F29F0CB
:100E50008091E7038F5F8093E7038091E504909191
:100E6000E6048C5E944048F48091E5049091E60499
:100E700001969093E6048093E5049F918F912F91C2
:100E80000F900FBE0F901F9018951F920F920FB6E4
:100E90000F9211248F939F938091F6048F3438F032
:100EA0008091F604823518F41092EA0308C081E0BC
:100EB0008093EA038091F804882309F4149A9091AE
:100EC000EA038091F804981739F480914E0488233E
:100ED00011F4149801C0149A1092F6049F918F9106
:100EE0000F900FBE0F901F9018951F920F920FB684
:100EF0000F9211248F939F938091E7038F3438F0E2
:100F00008091E703823518F41092F80408C081E05C
:100F10008093F8048091EA03882309F4149890914F
:100F2000EA038091F804981739F480914E048823DD
:100F300011F4149801C0149A1092E7039F918F91B5
:100F40000F900FBE0F901F9018950E9484058091FE
:100F5000FB04882331F0F8941092FB0478940E94EB
:100F60009F0508958091FA04813021F41092FA04CB
:100F700080E104C081E08093FA048CE08093440413
:100F800086E090E06091FA040E941D3687E090E0D0
:100F9000609144040E941D36089580918A03833035
:100FA00061F4E091D701F0E0EE0FFF1FEE0FFF1F9D
:100FB000E856FE4F8081918104C08091B0019091EC
:100FC000B1010E946C2808951F9310918A0310921A
:100FD0008A030E944E2580E060E00E94AF23812FAB
:100FE0001F9108950E94B225BC017695679580E017
:100FF0000E949B2681E060E070E00E949B2608959D
:101000009F92AF92BF92CF92DF92EF92FF920F9397
:101010001F93982E7B010E94B2255C010027F7FCEC
:101020000095102FC801B7010E94DA307B018C01B6
:10103000CC24DD24C601B5010E94D8309B01AC014F
:10104000C801B7010E944F3220E030E044E353E48E
:101050000E943F300E94AC309B01AC01892DB90148
:101060000E949B261F910F91FF90EF90DF90CF90F1
:10107000BF90AF909F9008950F931F93CF93DF93EE
:1010800085E00E94DE05A0E0B0E02091C40130912F
:10109000C50140E050E0BC01CD010E940F3347E0A4
:1010A00096958795779567954A95D1F7EB0186E0F8
:1010B0000E94DE05A0E0B0E02091C6013091C7019A
:1010C00040E050E0BC01CD010E940F3337E096951F
:1010D0008795779567953A95D1F78091C5038823D1
:1010E000B1F4C617D70740F48091C3039091C403AD
:1010F000009711F101971CC08091D601680F711DF6
:101100006C177D0750F581E08093C50326C06C17EE
:101110007D07D0F40091C3031091C4030E94B2254F
:101120000817190748F48091C3039091C4030196EE
:101130009093C4038093C3036091C3037091C4036D
:1011400080E00E949B2609C08091D601C80FD11D66
:10115000C617D70710F41092C503DF91CF911F91E6
:101160000F910895EF92FF920F931F93CF93DF9308
:10117000E82EC8ECD1E00AE110E0FF2489819A81D1
:101180002B813C814D815E81EE2089F49695879577
:10119000969587959A8389833695279536952795D1
:1011A0003C832B83569547955695479510C0880FDD
:1011B000991F880F991F9A838983220F331F220F4B
:1011C000331F3C832B83440F551F440F551F5E83F1
:1011D0004D8369817A818F2D0E94CE256B817C8120
:1011E0008F2D0E94EB256D817E818F2D0E940A2616
:1011F000CE01B80147E050E00E941336F3942796E1
:101200000F5C1F4F82E0F81609F0B8CF0E94F2077A
:10121000DF91CF911F910F91FF90EF9008950F9361
:101220001F93182F062F823078F462E0681B8FE03E
:101230000E94AF2380E20E943F231F5F8FE0612F57
:101240000E94AF23802F0CC08FE061E00E94AF238B
:1012500080E20E943F238FE062E00E94AF2380E2A1
:101260000E943F231F910F910895EF92FF920F93D9
:101270001F93DF93CF93CDB7DEB72E970FB6F894B9
:10128000DEBF0FBECDBF7B018C01DE011196E3E610
:10129000F3E08EE001900D928150E1F78E2D805D9C
:1012A0000E943F2380E091E00E94BD230894E10862
:1012B000F10801091109F701EE0FFF1FEC0FFD1FE7
:1012C000818192810E94BD2383E091E00E94BD2331
:1012D0002E960FB6F894DEBF0FBECDBFCF91DF9133
:1012E0001F910F91FF90EF900895EF92FF920F934F
:1012F0001F93F82EE92E062F80E00E94AF2310E006
:1013000080E20E943F231F5F1031D1F7EF2DFE2DA9
:10131000DF010D900020E9F7EA1BFB0B7196F695B3
:10132000E7958E2F602F0E94AF238F2D9E2D0E9458
:10133000BD231F910F91FF90EF900895EF92FF92C0
:101340000F931F93CF93DF937C018B01C0E0D0E01C
:10135000F701EC0FFD1F808191810817190710F428
:1013600080E001C080E20E943F232296C831D1056F
:1013700079F7DF91CF911F910F91FF90EF90089532
:10138000CF92DF92EF92FF920F931F93CF93DF9351
:10139000082F6B01142F85E00E94DE05A0E0B0E06D
:1013A0002091C4013091C50140E050E0BC01CD0165
:1013B0000E940F3337E096958795779567953A9514
:1013C000D1F77B0186E00E94DE05A0E0B0E020912D
:1013D000C6013091C70140E050E0BC01CD010E9440
:1013E0000F3327E096958795779567952A95D1F7DE
:1013F000EB010230E1F4E616F70660F41092BE034A
:101400008091F6048F3FA9F48091E7038F3F89F420
:1014100014980FC081E08093BE038091F6048F3F43
:1014200041F48091E7038F3F21F4149A02C00093A6
:10143000BE03112309F443C0023011F01BEF1EC09C
:101440009091EA038091F804981799F09091F6042E
:101450008091E70389238F3F61F08091EA0388231D
:1014600019F41092BF0303C081E08093BF0313E718
:1014700005C08091BE038093BF0314E6F60180810E
:1014800091818E159F0520F48C179D0708F410E2BA
:1014900082E061E00E94AF23C601B7010E949E096D
:1014A00082E062E00E94AF23C601BE010E949E0955
:1014B000023029F48091BF03612F0E940F098091AF
:1014C000BE03DF91CF911F910F91FF90EF90DF90BE
:1014D000CF90089580914504882381F0F89410926C
:1014E000450478946091D8017091D9018091890365
:1014F0004091DA010E94C00980934E0408958091C2
:10150000DA01882341F18091DB01882321F581E014
:1015100060E00E94AF238091ED03882371F08091F9
:10152000C203863010F481E009C0809122048A3021
:1015300010F088E503C0805D01C080E20E943F2377
:101540001092ED038091C2038F5F8093C2038C30B1
:1015500011F41092C20308950F931F93DF93CF935A
:10156000CDB7DEB727970FB6F894DEBF0FBECDBF5D
:10157000DC01CB01880F991F880F991F88569E4F59
:10158000FC0160817181828193818E010F5F1F4F09
:10159000A8012AE030E00E94F734C80161E00E940F
:1015A000750927960FB6F894DEBF0FBECDBFCF9159
:1015B000DF911F910F910895EF92FF920F931F9368
:1015C000DF93CF9300D000D000D0CDB7DEB77B0142
:1015D0000E94B225969587958701081B190BC801B3
:1015E0000996439718F480E20E943F2317FD03C039
:1015F00080E20E943F23C8018E010F5F1F4FB80198
:101600004AE050E00E94D634C8010E94BD2380E227
:101610000E943F238091E903B7010E940A2610919E
:10162000E9030E94B225BC0176956795812F0E943F
:101630009B2626960FB6F894DEBF0FBECDBFCF9186
:10164000DF911F910F91FF90EF900895EF92FF921D
:101650000F931F93DF93CF9300D000D0CDB7DEB7A9
:101660007B018C0184E6E816F1040105110560F4A4
:1016700080E20E943F238AE0E816F104010511058B
:1016800018F480E20E943F23C7018E010F5F1F4FB5
:10169000B8014AE050E00E942B35C8010E94BD23EA
:1016A0000F900F900F900F90CF91DF911F910F919E
:1016B000FF90EF900895EF92FF920F931F93CF93B7
:1016C000DF937B018C010E94B225EC01C801B701B8
:1016D0000E94260B8091E903B7010E94EB2520911F
:1016E000E903822F90E0FC0173E0EE0FFF1F7A9573
:1016F000E1F7E81BF90BE853FE4F8081882311F0D6
:10170000C0E0D0E0822FBE010E949B26DF91CF91E6
:101710001F910F91FF90EF900895EF92FF920F931A
:101720001F937B018C010E94260B8091E903B70176
:101730000E94CE258091E90390E0FC01A3E0EE0F2A
:10174000FF1FAA95E1F7E81BF90BE853FE4F8081D4
:10175000882319F460E070E003C00E94B225BC0148
:101760008091E9030E949B261F910F91FF90EF90BB
:1017700008951F93162F0E94260B8091FA04612F63
:101780000E9496231F9108954F925F926F927F92CD
:101790008F92AF92BF92CF92DF92EF92FF920F9310
:1017A0001F93DF93CF9300D000D0CDB7DEB72B01CE
:1017B0003C0129833A834B835C83DE88BF8880E4C5
:1017C0000E94F824882329F480E40E9403258823BA
:1017D00021F14E145F046006710648F40894411C20
:1017E000511C611C711C8B2D0E94342506C0DD200C
:1017F00021F049805A806B807C808C2D6A2D0E945C
:10180000AF23E82DF0E0EE0FFF1FE251FD4F0190F6
:10181000F081E02DC301B201099580E80E94F8240F
:10182000882329F480E80E940325882331F18981E7
:101830009A81AB81BC8184159505A605B70548F44E
:10184000089441085108610871088B2D0E943425C5
:1018500004C0DD2011F0270138018C2D6A2D0E9473
:10186000AF23E82DF0E0EE0FFF1FE251FD4F019096
:10187000F081E02DC301B2010995B201C3010F90BF
:101880000F900F900F90CF91DF911F910F91FF90CC
:10189000EF90DF90CF90BF90AF908F907F906F9040
:1018A0005F904F900895CF92DF92FF920F931F9316
:1018B000DF93CF9300D0CDB7DEB7FC019A83898345
:1018C0008081882321F1CE01019667E071E00E94BA
:1018D000BE346C01FF2401C0F3940F2D10E0F80119
:1018E000EE0FFF1FEE0FFF1FE259FD4F8081918128
:1018F000B6010E948534892B79F7000F111F000F64
:10190000111F00591D4FD801ED91FC9109950F90C1
:101910000F90CF91DF911F910F91FF90DF90CF90AB
:1019200008951F93182F8091E903882319F060E030
:1019300070E005C00E94B225BC0176956795809144
:10194000E9030E949B2610938A03112389F420E067
:1019500044EF51E008C0FA013197F1F70197D9F748
:101960002F5F223019F080ED97E0F5CF0E94952689
:101970008BED91E00E94530C1F91089584339105E3
:1019800040F0FC01EE0FFF1FE851F74F6591749195
:101990001CC02091BF01213029F0880F991F2230EF
:1019A00079F408C0FC01EE0FFF1FE058F74F659176
:1019B00074910BC0FC01E851F74F6591749105C01B
:1019C000FC01E85EF74F659174918DE893E00E9409
:1019D00073348DE893E00895DF93CF9300D00F9296
:1019E000CDB7DEB7DE011196ECE2F3E023E0019023
:1019F0000D922150E1F7FE01E60FF71F818190E083
:101A00000E94BE0C61E00E9475090F900F900F902C
:101A1000CF91DF910895DF93CF9300D0CDB7DEB79C
:101A20002AE329832BE32A83FE01E60FF71F818136
:101A300090E00E94BE0C61E00E9475090F900F902B
:101A4000CF91DF910895611571058105910519F414
:101A500085E290E002C086E290E00E94BE0C0E9407
:101A6000BD230895DF92EF92FF920F931F93DF93B0
:101A7000CF9300D000D00F92CDB7DEB77B018C01A1
:101A80008EE090E00E94BE0CFC0101900020E9F77E
:101A90003197DE2ED81AE114F1040105110539F051
:101AA0008FE1E816F1040105110529F510C08FE05A
:101AB00090E00E94BE0CFC0101900020E9F73197F4
:101AC000E81BF90B1D2D1E0F8FE090E00FC080E189
:101AD00090E00E94BE0CFC0101900020E9F73197D4
:101AE000E81BF90B1D2D1E0F80E190E00E94BE0C3B
:101AF0000E94BD2337C0C801B7012AE030E040E0B2
:101B000050E00E940F33DC01CB017E010894E11C00
:101B1000F11CB7014AE050E00E94D63480E20E94F6
:101B20003F23C7010E94BD2381E190E00E94BE0CCB
:101B30000E94BD23F70101900020E9F78F010150B9
:101B400010400E191F0981E190E00E94BE0CDC01DB
:101B50000D900020E9F71197A81BB90B1D2D100F50
:101B60001F5F1A0F00E1011B10E004C080E20E9419
:101B70003F231F5F1017D0F30F900F900F900F901F
:101B80000F90CF91DF911F910F91FF90EF90DF9019
:101B90000895DF93CF9300D0CDB7DEB725E2298338
:101BA0002BE22A83FE01E60FF71F818190E00E945D
:101BB000BE0C61E00E9475090F900F90CF91DF91EC
:101BC0000895DF93CF9300D000D0CDB7DEB725E2E4
:101BD00029832EE32A8328E22B832FE32C83FE0123
:101BE000E60FF71F818190E00E94BE0C61E00E9429
:101BF00075090F900F900F900F90CF91DF9108957E
:101C0000DF93CF9300D00F92CDB7DEB7DE011196F0
:101C1000EDE3F3E023E001900D922150E1F7FE01A6
:101C2000E60FF71F818190E00E94BE0C61E00E94E8
:101C300075090F900F900F90CF91DF91089580E07C
:101C400060E00E94AF2383E490E00E94BE0C0E94FB
:101C5000BD238091FA04882319F483E390E002C045
:101C600082E490E00E94BE0C0E94BD2384E490E0D8
:101C70000E94BE0C0E94BD2320E044EF51E008C04A
:101C8000FA013197F1F70197D9F72F5F2F3119F04A
:101C900088EE93E0F5CF0E948E2308950F931F9353
:101CA000082F90E00E94BE0CFC0101900020E9F793
:101CB0003197E81BE031D8F480E190E08E1B910968
:101CC00095958795182F823098F0825060E00E9499
:101CD000AF2389E091E00E94BD23802F90E00E9415
:101CE000BE0C0E94BD2380E20E943F2316C010E07C
:101CF00080E060E00E94AF238AE20E943F23812FB0
:101D000060E00E94AF23802F90E00E94BE0C0E94F2
:101D1000BD238FE060E00E94AF238AE20E943F2350
:101D20001F910F910895CF92DF92EF92FF920F9340
:101D30001F93CF93DF93EC01D42E662311F4F42E7E
:101D400002C0F62EFA94EE24EEE0CE2E82E06E2D46
:101D50000E94AF238E010F0D111DF801808190E0CC
:101D60000E94BE0C0E94BD23F801808190E00E9479
:101D7000BE0CFC0101900020E9F73197E81BF90B3C
:101D80000C2D0E1B04C080E20E943F230150101650
:101D9000D4F3FD1410F0FF2401C0F394E394F3E0B6
:101DA000EF16A1F6DF91CF911F910F91FF90EF9069
:101DB000DF90CF9008951F93182F0E948E2388E103
:101DC00090E00E94BE0C60E00E94750989E190E0FD
:101DD0000E94BE0C61E00E947509812F90E00E9474
:101DE000BE0C62E00E94750920E044EF51E008C09B
:101DF000FA013197F1F70197D9F72F5F2F3119F0D9
:101E000088EE93E0F5CF1F9108950E948E2386E11E
:101E100090E00E94BE0C60E00E94750987E190E0AE
:101E20000E94BE0C61E00E9475090895BF92CF9296
:101E3000DF92EF92FF920F931F93DF93CF9300D027
:101E40000F92CDB7DEB76B017C01B42E24E630E0F3
:101E500040E050E00E94423389012A30310518F4F5
:101E600080E20E943F23C8018E010F5F1F4FB8011F
:101E70004AE050E00E942B35C8010E94BD2382E356
:101E800090E00E94BE0C0E94BD23C701B6012AE06B
:101E900030E040E050E00E944233605D6A83C70159
:101EA000B6012AE030E040E050E00E944233CA012F
:101EB000B9012AE030E040E050E00E944233605D2A
:101EC0006983F801EB0DF11D1082C8010E94BD234A
:101ED0000F900F900F90CF91DF911F910F91FF9076
:101EE000EF90DF90CF90BF90089542E00E94160FD0
:101EF00086E50E943F23089541E00E94160F089551
:101F00007F928F929F92AF92BF92CF92DF92EF9289
:101F1000FF920F931F93DF93CF930F92CDB7DEB74E
:101F2000782E87E00E94DE059C0140E050E060E0F2
:101F300070E080E090E0A0EFAA2EF9EABF2ECC245A
:101F4000DD24EE24FF2400E010E00E94F129122F8E
:101F5000F32ED42EC52EB62EA72E982EE92E209124
:101F6000B90130E040E050E060E070E080E090E0F7
:101F70000DE00E946B2B892E210FE1E0211708F064
:101F8000E0E03F0DF1E03F1508F0F0E0FE2EF30E2B
:101F9000E1E0F31608F0E0E0FE2B4D0DA1E04D1559
:101FA00008F0A0E00F2F040FE1E0041708F0E0E0D4
:101FB000AE2B5C0DF1E05C1508F0F0E01A2F150F68
:101FC000E1E0151708F0E0E0FE2B6B0DA1E06B15CA
:101FD00008F0A0E0BF2FB60FE1E0B61708F0E0E090
:101FE000AE2B7A0DF1E07A1508F0F0E0A70FE1E0F2
:101FF000A71708F0E0E0FE2B890D91E0891508F0A5
:1020000090E0F80FE1E0F81708F0E0E09E2BE80C14
:102010003F2DA8016B2F7A2F8F2F9E0D0DE00E9470
:10202000EC2A79018A018091490490914A04A09197
:102030004B04B0914C048E159F05A007B10708F41E
:1020400043C08091DA01882329F18091BA019091EF
:10205000BB01A091BC01B091BD014496A11DB11D71
:102060008093490490934A04A0934B04B0934C048A
:102070000E948E238AE190E00E94BE0C0E94BD2344
:102080001092DA0184E10E942F0680EF8093C00352
:102090001092C10381E0781689F58091C103909177
:1020A000C0038F5F8093C1038150891738F184E1A9
:1020B00099830E942F069981933018F096959093FA
:1020C000C0031092C1031AC02091BA013091BB0124
:1020D0004091BC015091BD01281739074A075B07A1
:1020E00068F481E08093DA012093490430934A0434
:1020F00040934B0450934C040E94A910B701C801AF
:102100000F90CF91DF911F910F91FF90EF90DF9093
:10211000CF90BF90AF909F908F907F900895EF9257
:10212000FF920F931F9381E00E94800F7B018C012F
:102130008091DA01882341F08BE060E00E94AF23B8
:10214000C801B7010E947C0F1F910F91FF90EF9083
:1021500008950E948E238091DA018823F9F00E946D
:102160008E236091BE0170E080E090E00E9435090E
:102170008FE060E00E94AF238CE091E00E94BD23DD
:1021800080918903823010F064E601C06BEF80918A
:102190004E040E940F090E948F1008958AE190E07A
:1021A0000E94BE0C60E00E94750908958091F504BC
:1021B000882331F0F8941092F50478940E948F10DF
:1021C0000895CF92DF92EF92FF920F931F93CF93D8
:1021D000DF936C01EB017B0100E010E09C0140E02B
:1021E00050E08617970718F587E0EE0CFF1C001FDC
:1021F000111F8A95D1F7C801B7010E944233CA0165
:10220000B9010E94D83020E030E040E05FE30E9456
:10221000722F0E94AC307093C5016093C40180E8B6
:1022200090E09093C7018093C6018E0124C0B7E06F
:10223000220F331F441F551FBA95D1F7CA01B901A8
:10224000A80197010E944233CA01B9010E94D83007
:1022500020E030E040E05FE30E94722F0E94AC304B
:102260007093C7016093C60180E890E09093C50128
:102270008093C40186016091C4017091C50185E11C
:1022800090E00E9433366091C6017091C70187E1EA
:1022900090E00E943336C801DF91CF911F910F91DA
:1022A000FF90EF90DF90CF9008950F931F93CF93FF
:1022B000DF938C010E94050F85E068EE73E00E94B9
:1022C000F405EC0186E068EE73E00E94F405BC01C1
:1022D0008C0F9D1F80599140A0F4CE010E94E11007
:1022E000BC019093C3018093C20183E190E00E94FE
:1022F000333684E06EE10E948706C8010E94E4063E
:1023000003C08AE00E94DB0EDF91CF911F910F91F5
:1023100008950F931F93CF93DF938C010E94050FB5
:1023200085E068EE73E00E94F405EC0186E068EE5B
:1023300073E00E94F405BC018C0F9D1F855F9140E6
:10234000A0F0CE010E94E110BC019093C1018093E6
:10235000C00181E190E00E94333684E06EE10E948A
:102360008706C8010E94E40603C089E00E94DB0ED4
:10237000DF91CF911F910F910895EF92FF920F93EC
:102380001F93DF93CF9300D000D00F92CDB7DEB76D
:10239000082F80E090E00E94FF35182F7E010894FE
:1023A000E11CF11CC70161E070E045E050E00E94D3
:1023B000EF3588E893E10197F1F71B3499F4002396
:1023C00041F082E191E0B7010E94A334009709F443
:1023D00085C082E191E0BE016F5F7F4F0E94A33410
:1023E0000097B9F080E090E06BE40E941D3686E033
:1023F00090E060E00E941D3687E090E060E10E947E
:102400001D3682E191E061E070E045E050E00E941D
:10241000133688E090E06FE10E941D3689E090E07D
:1024200065E50E941D368AE090E040EC53E060E0F4
:1024300070E00E942B368EE090E061E00E941D3635
:102440008FE090E060E00E941D3680E190E06EEF4A
:102450000E941D3681E190E06CEC71E00E94333601
:1024600083E190E06BE470E00E94333685E190E018
:1024700060E870E00E94333687E190E060E870E049
:102480000E94333689E190E060E00E941D3688ECBE
:1024900091E06AE170E047E050E00E9413368FEC73
:1024A00091E06BE470E047E050E00E9413368CE767
:1024B00090E060E00E941D368DE790E068E20E94A7
:1024C0001D368EE790E060E00E941D368FE790E0B9
:1024D00065E00E941D361092460478C088E090E0C6
:1024E0000E94FF358093B80189E090E00E94FF359B
:1024F0008093B9018AE090E00E9407366093BA01A8
:102500007093BB018093BC019093BD018EE090E07D
:102510000E94FF358093BE018FE090E00E94FF355E
:102520008093890380E190E00E94FF358093BF0192
:1025300081E190E00E940D369093C1018093C0012B
:1025400083E190E00E940D369093C3018093C20115
:1025500085E190E00E940D369093C5018093C401FF
:1025600087E190E00E940D369093C7018093C601E9
:1025700089E190E00E94FF358093460488EC91E069
:102580006AE170E047E050E00E94EF358FEC91E0A7
:102590006BE470E047E050E00E94EF358CE790E09C
:1025A0000E94FF3580938A038DE790E00E94FF35FB
:1025B0008093D6018EE790E00E94FF3580938B03D5
:1025C0008FE790E00E94FF358093D70186E090E08E
:1025D0000E94FF358093FA0487E090E00E94FF3567
:1025E000809344048091BA019091BB01A091BC01F9
:1025F000B091BD018093490490934A04A0934B0489
:10260000B0934C048091D8019091D9010E94E406C6
:102610008091890380934E0480E06091C8010E94FC
:10262000BF256091C9017091CA0180E00E94CE254A
:102630006091CB017091CC0180E00E94EB2560910C
:10264000CD017091CE0180E00E940A2681E0609168
:10265000CF010E94BF256091D0017091D10181E02E
:102660000E94CE256091D2017091D30181E00E9439
:10267000EB256091D4017091D50181E00E940A267A
:102680000E94F20781E08093EF030E94CD078091C2
:102690008A030E94C0290F900F900F900F900F9007
:1026A000CF91DF911F910F91FF90EF9008959F922E
:1026B000AF92BF92CF92DF92EF92FF920F931F9350
:1026C000CF93DF938FE494E062E00E94CE298823C9
:1026D00009F449C080914F04843009F044C08091CE
:1026E000510490E09695982F88279795879520918B
:1026F000520430E0822B932B64E170E00E942E3371
:102700006C33710518F4C0E0D0E007C0EB01EC9722
:10271000C53BD10510F0C4EBD0E0909050040E946E
:10272000B2257C01BE0180E090E00E94D8305B01C0
:102730006C0100E010E0C801B7010E94D8309B0195
:10274000AC01C601B5010E944F3220E030E044E305
:1027500053E40E943F300E94AC309B01AC01892DB4
:10276000B9010E949B26DF91CF911F910F91FF909D
:10277000EF90DF90CF90BF90AF909F9008958091A1
:102780004D048823A9F0F89410924D047894609138
:10279000D8017091D9018091890340E00E94C0095D
:1027A00080934E0480918A03833011F40E94571362
:1027B00008951F938FE40E945A298823B1F0A0EF57
:1027C000B3E0EFE4F4E082E501900D928150E1F78F
:1027D0008091E5049091E6048C5E944030F4809101
:1027E000340487FF02C011E001C010E080918B0328
:1027F000882359F08091E5049091E604855A914030
:1028000020F087E191E00E949128812F1F91089587
:102810002F923F924F925F926F927F928F929F92F0
:10282000AF92BF92CF92DF92EF92FF920F931F93DE
:10283000DF93CF93CDB7DEB766970FB6F894DEBFC0
:102840000FBECDBFC986DA86EB86FC860D871E8754
:102850002F87388B6D847E848F8498886FA578A9A4
:1028600089A99AA90E94DA3020E836E948E15BE4B8
:102870000E943F305B016C01C401B301A6019501C8
:102880000E94722F20E030E040E05FE30E944F3270
:1028900029E33AEF4EE85CE30E944F320E943C305D
:1028A00020E032E649ED57E40E944F327B018C0173
:1028B0006BA57CA58DA59EA50E94DA3020E836E99F
:1028C00048E15BE40E943F309B01AC0169857A8559
:1028D0008B859C850E94712F9B01AC01C801B701BB
:1028E0000E944F321B012C01C401B301A6019501C6
:1028F0000E94712F20E032E649ED57E40E944F32EA
:102900005B016C01C201B101A60195010E94E52F96
:1029100021EE3EE245E652E40E944F3220E030E0F4
:1029200044E353E40E94722F20E030E044EB53E490
:102930000E941C317B018C0137014801C801B7019D
:1029400020E030E044EB53E40E944432181654F483
:10295000C801B70120E030E044EB53E40E94712F3E
:102960003B014C01C201B101A20191010E944F3211
:102970007B018C01C601B501A60195010E944F3271
:102980009B01AC01C801B7010E94722F0E94B632B0
:1029900069837A838B839C836D827E828F82988603
:1029A00029813A814B815C816D817E818F819885FF
:1029B00066960FB6F894DEBF0FBECDBFCF91DF9104
:1029C0001F910F91FF90EF90DF90CF90BF90AF904D
:1029D0009F908F907F906F905F904F903F902F903F
:1029E00008952F923F924F925F926F927F928F92B3
:1029F0009F92AF92BF92CF92DF92EF92FF920F938E
:102A00001F93DF93CF93CDB7DEB7AE970FB6F89491
:102A1000DEBF0FBECDBF0E94D913882309F48AC33D
:102A20008091EF03882309F44FC08091330483FF22
:102A300081C360910F0470911004809111049091F2
:102A400012040E94DA3020E836E948E15BE40E9493
:102A50003F306093E7047093E8048093E904909317
:102A6000EA0460911304709114048091150490910C
:102A700016040E94DA3020E836E948E15BE40E945F
:102A80003F306093EB047093EC048093ED049093DB
:102A9000EE048091170490911804A0911904B0914C
:102AA0001A048093EF049093F004A093F104B09380
:102AB000F20480912E0490912F049093F40480935B
:102AC000F3041092EF0336C32DB73EB72D503040BC
:102AD0000FB6F8943EBF0FBE2DBFADB7BEB711966F
:102AE000E1EFF3E08DE001900D928150E1F7C090AD
:102AF000E704D090E804E090E904F090EA04009143
:102B0000EB041091EC042091ED043091EE0440911F
:102B1000EF045091F0046091F1047091F2048091FF
:102B2000F3049091F4040E9408142FA338A749A736
:102B30005AA76BA77CA78DA79EA7DE011196FE0161
:102B4000B79688E001900D928150E1F72D803E808C
:102B50004F80588469807A808B809C80E090F90354
:102B6000F090FA030091FB031091FC03A090EF0496
:102B7000B090F004C090F104D090F2048DB79EB7ED
:102B80000D960FB6F8949EBF0FBE8DBFC401B30162
:102B900020E030E040E850E40E94383087FD1CC05F
:102BA000EA18FB080C091D09C801B7010E94DA30B8
:102BB00020E030E04AE754E40E943F30A401930152
:102BC0000E94E52F21EE3EE245E652E40E944F329C
:102BD0000E94A7306B010EC06091F3047091F40461
:102BE000882777FD8095982F0E94DA301B012C01F1
:102BF000CC24DD246091F3047091F404882777FDE0
:102C00008095982F0E94DA309B01AC01C201B1017E
:102C10000E94712F20E030E044EB53E40E94722FB9
:102C200020E030E044EB52E40E94722F20E030E0DC
:102C300044EB53E40E941C319B01AC01CA01B90171
:102C40000E94A7307B0199E6E91691E0F90624F08D
:102C5000A8E9BEEFEA0EFB1ED7FE03C0CC24DD249C
:102C600007C0B5EBCB16D1041CF044EBC42ED12C1D
:102C7000E4EBEE16F10454F02CE43FEFE20EF31E09
:102C800084EB90E0DC01AC19BD096D0180E0B70177
:102C90000E94000881E0B6010E94000880918C0328
:102CA000882309F447C28091DA01882309F442C2DB
:102CB0008091EE03882321F01092EE030E948E2370
:102CC00080918C03823009F4C7C0833009F488C135
:102CD000813009F02FC200D000D000D0EDB7FEB790
:102CE00031968E01075F1F4FADB7BEB712961C938A
:102CF0000E93119782E291E0938382838091F30493
:102D00009091F404958384830E946D35EDB7FEB7EE
:102D100036960FB6F894FEBF0FBEEDBF80E060E0C0
:102D20000E94AF23C8010E94BD232DB73EB7285093
:102D300030400FB6F8943EBF0FBE2DBFEDB7FEB7C3
:102D40003196ADB7BEB712961C930E9311978AE2D7
:102D500091E09383828364827582868297820E9447
:102D60006D35EDB7FEB738960FB6F894FEBF0FBEBF
:102D7000EDBF88E060E00E94AF23C8010E94BD2340
:102D80002DB73EB7285030400FB6F8943EBF0FBE67
:102D90002DBFEDB7FEB73196ADB7BEB712961C93F7
:102DA0000E93119784E391E093838283248235828A
:102DB000468257820E946D35EDB7FEB738960FB642
:102DC000F894FEBF0FBEEDBF80E061E00E94AF232C
:102DD000C8010E94BD2300D000D000D0EDB7FEB7DF
:102DE0003196ADB7BEB712961C930E9311978EE332
:102DF00091E093838283F582E4820E946D35EDB782
:102E0000FEB736960FB6F894FEBF0FBEEDBF80E05A
:102E100062E00E94AF23C8010E94BD2300D000D011
:102E200000D0EDB7FEB73196ADB7BEB712961C9382
:102E30000E93119786E491E093838283D582C482B6
:102E40000E946D35EDB7FEB736960FB6F894FEBF0B
:102E50000FBEEDBF88E068C12DB73EB728503040A7
:102E60000FB6F8943EBF0FBE2DBF0DB71EB70F5F54
:102E70001F4F39E0E32EF12CEC0EFD1EADB7BEB7AF
:102E80001296FC92EE9211978EE491E0F8019383F2
:102E900082836091F1037091F2038091F30390912A
:102EA000F4030E94DA3020E836E948E15BE40E944E
:102EB0003F30D80114966D937D938D939C93179713
:102EC0000E946D35EDB7FEB738960FB6F894FEBF89
:102ED0000FBEEDBF80E060E00E94AF23C7010E94FB
:102EE000BD232DB73EB7285030400FB6F8943EBFF3
:102EF0000FBE2DBF0DB71EB70F5F1F4FADB7BEB7CB
:102F00001296FC92EE9211978AE591E0F801938374
:102F100082836091F5037091F6038091F70390919D
:102F2000F8030E94DA3020E836E948E15BE40E94C9
:102F30003F30D80114966D937D938D939C93179792
:102F40000E946D35EDB7FEB738960FB6F894FEBF08
:102F50000FBEEDBF80E061E00E94AF23C7010E9479
:102F6000BD232DB73EB7285030400FB6F8943EBF72
:102F70000FBE2DBF0DB71EB70F5F1F4FADB7BEB74A
:102F80001296FC92EE92119786E691E0F8019383F7
:102F900082836091F9037091FA038091FB03909111
:102FA000FC030E94DA3020E030E04AE754E40E945B
:102FB0003F30D80114966D937D938D939C93179712
:102FC0000E946D35EDB7FEB738960FB6F894FEBF88
:102FD0000FBEEDBF80E062E00E94AF23C701A8C032
:102FE0002DB73EB7285030400FB6F8943EBF0FBE05
:102FF0002DBFEDB7FEB731968E01075F1F4FADB7FE
:10300000BEB712961C930E93119782E791E09383BB
:1030100082838091E7049091E804A091E904B09143
:10302000EA0484839583A683B7830E946D35EDB748
:10303000FEB738960FB6F894FEBF0FBEEDBF80E026
:1030400060E00E94AF23C8010E94BD232DB73EB7A8
:10305000285030400FB6F8943EBF0FBE2DBFEDB7DD
:10306000FEB73196ADB7BEB712961C930E9311976B
:103070008EE791E0938382838091EB049091EC043E
:10308000A091ED04B091EE0484839583A683B78369
:103090000E946D35EDB7FEB738960FB6F894FEBFB7
:1030A0000FBEEDBF80E061E00E94AF23C8010E9427
:1030B000BD232DB73EB7285030400FB6F8943EBF21
:1030C0000FBE2DBFEDB6FEB60894E11CF11CADB7E6
:1030D000BEB712961C930E9311978AE891E0F70100
:1030E000938382836091EF047091F0048091F104E6
:1030F0009091F2040E94DA3020E030E04AE754E494
:103100000E943F30D70114966D937D938D939C93CD
:1031100017970E946D35EDB7FEB738960FB6F89445
:10312000FEBF0FBEEDBF80E062E00E94AF23C8018A
:103130000E94BD230E947F0AAE960FB6F894DEBFB0
:103140000FBECDBFCF91DF911F910F91FF90EF90F8
:10315000DF90CF90BF90AF909F908F907F906F90B7
:103160005F904F903F902F9008958091E8038823BF
:1031700051F0F8941092E803789480918A03823099
:1031800011F40E94F11408950E94BF130E94B51813
:103190000E94A50780918A03813011F40E943C08A7
:1031A00008952F923F924F925F926F927F928F92EB
:1031B0009F92AF92BF92CF92DF92EF92FF920F93C6
:1031C0001F93DF93CF9300D000D000D0CDB7DEB7F0
:1031D000D62EB72E982E392E29833A834B835C83C3
:1031E00027013801CD822A2C8E828C2D61E00E942D
:1031F000AF23EA2DF0E0EE0FFF1FE251FD4F0190EB
:10320000F081E02D6D2D7B2D892D932D09952EC0FC
:1032100000D0EDB7FEB711828E8182836D2D7B2D9C
:10322000892D932D29813A814B815C818301720123
:10323000CD80AA24A394822C0E94C40BD62EB72E34
:10324000982E392E0F900F9080E20E941E25882321
:1032500011F01092DB010E94C41880E00E94800FE0
:103260008091DA01882311F41092DB0180E20E9440
:103270000E25882321F48091DB01882349F60E94E2
:103280008E23EBEDF1E001900020E9F73197EB5D43
:10329000F1408E2FEE2359F08150E82FF0E0E552F7
:1032A000FE4F808180538093EC03108202C00E9405
:1032B000A9106D2D7B2D892D932D26960FB6F89490
:1032C000DEBF0FBECDBFCF91DF911F910F91FF9059
:1032D000EF90DF90CF90BF90AF909F908F907F90B6
:1032E0006F905F904F903F902F9008958F92AF9284
:1032F000CF92EF92FF920F931F9381E40E944E0EA4
:103300006091D70170E080E090E020E030E040E0A4
:1033100050E0A6E0EA2EF12C012D112DF3E0CF2E86
:10332000EEE0AE2E88240E94D1189B01AC01809162
:10333000D70190E0A0E0B0E0281739074A075B0703
:10334000C1F02093D7018FE790E0622F0E941D36D5
:1033500084E06EE10E948706E091D701F0E0EE0F75
:10336000FF1FEE0FFF1FE856FE4F808191810E94E4
:103370006C288BED91E00E94530C1F910F91FF90F0
:10338000EF90CF90AF908F9008958F92AF92CF92A1
:10339000EF92FF920F931F9389E20E944E0E60916D
:1033A0008B0370E080E090E020E030E040E050E00F
:1033B000F1E0EF2EF12C012D112DE3E0CE2EBDE03A
:1033C000AB2E88240E94D1189B01AC0180918B0305
:1033D00090E0A0E0B0E0281739074A075B0759F0F2
:1033E00020938B038EE790E0622F0E941D3684E0CD
:1033F0006EE10E9487068BED91E00E94530C1F91B5
:103400000F91FF90EF90CF90AF908F9008958F9293
:10341000AF92CF92EF92FF920F931F938AE20E9496
:103420004E0E6091D60170E080E090E020E030E048
:1034300040E050E0E4E6EE2EF12C012D112DB7E036
:10344000CB2EABE0AA2E882483940E94D1189B0136
:10345000AC018091D60190E0A0E0B0E028173907D8
:103460004A075B0759F02093D6018DE790E0622F61
:103470000E941D3684E06EE10E9487068BED91E08C
:103480000E94530C1F910F91FF90EF90CF90AF903F
:103490008F90089580918A03823039F0833041F013
:1034A000813041F40E94071A08950E94C5190895B9
:1034B0000E94761908958F92AF92CF92EF92FF9269
:1034C0000F931F9387E20E944E0E60918A0370E073
:1034D00080E090E020E030E040E050E0B3E0EB2E10
:1034E000F12C012D112DA3E0CA2EFCE0AF2E882473
:1034F0000E94D1189B01AC0180918A0390E0A0E06A
:10350000B0E0281739074A075B0781F1F894622F6A
:1035100020938A0378948CE790E00E941D3684E023
:103520006EE10E94870680918A030E94C02981E093
:103530008093EF030E94F20780918A03882321F48D
:1035400020E044EF51E00BC00E944E250DC0FA016F
:103550003197F1F70197D9F72F5F223019F080EDFD
:1035600097E0F5CF0E9495260E94CD078BED91E064
:103570000E94530C1F910F91FF90EF90CF90AF904E
:103580008F9008958F92AF92CF92EF92FF920F9308
:103590001F9385E10E944E0E6091B90170E080E0BA
:1035A00090E020E030E040E050E0F8ECEF2EF12C2D
:1035B000012D112DE4E0CE2EAA24882483940E94AC
:1035C000D1189B01AC018091B90190E0A0E0B0E07E
:1035D000281739074A075B0759F02093B90189E09A
:1035E00090E0622F0E941D3684E06EE10E94870603
:1035F0008BED91E00E94530C1F910F91FF90EF9083
:10360000CF90AF908F9008958F92AF92CF92EF921C
:10361000FF920F931F9383E10E944E0E6091BA01B7
:103620007091BB018091BC019091BD0126E232E016
:1036300040E050E0B8E7EB2EB5E0FB2E012D112D58
:10364000A4E0CA2EAA24882483940E94D118AB0136
:10365000BC018091BA019091BB01A091BC01B091D5
:10366000BD01481759076A077B0701F14093BA016A
:103670005093BB016093BC017093BD018AE090E060
:103680000E942B368091BA019091BB01A091BC01A0
:10369000B091BD018093490490934A04A0934B04D8
:1036A000B0934C0484E06EE10E9487068BED91E0BC
:1036B0000E94530C1F910F91FF90EF90CF90AF900D
:1036C0008F9008958F92AF92CF92EF92FF920F93C7
:1036D0001F938DE00E944E0E80E061E00E94AF23B8
:1036E0008EE090E00E94BE0C0E94BD236091B80164
:1036F00070E080E090E020E030E040E050E0AFE1BA
:10370000EA2EF12C012D112DF6E0CF2EE2E0AE2EA7
:10371000882483940E94D1189B01AC018091B80148
:1037200090E0A0E0B0E0281739074A075B0791F066
:103730002093B80188E090E0622F0E941D3684E05B
:103740006EE10E9487068091B801882319F41092D7
:1037500088032F988BED91E00E94530C1F910F91DD
:10376000FF90EF90CF90AF908F9008958F92AF928F
:10377000CF92EF92FF920F931F9387E30E944E0E1A
:1037800082E061E00E94AF238CE090E00E94BE0CDA
:103790000E94BD2380E091E00E94BD23609144041B
:1037A00070E080E090E020E030E040E050E0EEE1CA
:1037B000EE2EF12C012D112DBBE0CB2EAA24A394CB
:1037C00088240E94D1189B01AC018091440490E0B0
:1037D000A0E0B0E0281739074A075B0759F02093AB
:1037E000440487E090E0622F0E941D3684E06EE181
:1037F0000E9487068BED91E00E94530C1F910F9160
:10380000FF90EF90CF90AF908F9008958F92AF92EE
:10381000CF92DF92EF92FF920F931F930E94E407E3
:10382000D82E1091E9030E94B225BC0176956795C8
:10383000812F0E949B262091460430E08091E9036D
:1038400090E0FC0113E0EE0FFF1F1A95E1F7E81B73
:10385000F90BE853FE4F6581768180E090E0F90135
:10386000EE0FFF1FE20FF31FEE0FFF1FEE0FFF1F04
:10387000E052FE4F2085318540E050E0E284F38441
:1038800000E010E0E6E0CE2EBAE0AB2E8824839470
:103890000E94D118AB01BC018091E903282F30E0D0
:1038A000F901A3E0EE0FFF1FAA95E1F7E21BF30B6E
:1038B000E853FE4F85819681A0E0B0E04817590794
:1038C0006A077B07B1F05683458381E390E0289F28
:1038D000B001299F700D389F700D1124665E7F4FD7
:1038E000CF0147E050E00E94133684E06EE10E9471
:1038F00087068D2D0E94910C1F910F91FF90EF90E4
:10390000DF90CF90AF908F90089584E20E944E0E8A
:103910000E94061C089580E20E944E0E0E94061C22
:1039200008958F92AF92CF92DF92EF92FF920F9312
:103930001F930E94E407D82E8091E90360E070E0B5
:103940000E949B262091460430E08091E90390E09C
:10395000FC0103E0EE0FFF1F0A95E1F7E81BF90BEE
:10396000E853FE4F6181728180E090E0F901EE0F33
:10397000FF1FE20FF31FEE0FFF1FEE0FFF1FDF0110
:10398000A052BE4F2D913C9140E050E0EE51FE4FD1
:10399000E080F18000E010E0E6E0CE2EB8E0AB2E53
:1039A000882483940E94D118AB01BC018091E90363
:1039B000282F30E0F901A3E0EE0FFF1FAA95E1F7F1
:1039C000E21BF30BE853FE4F81819281A0E0B0E04F
:1039D000481759076A077B0741F15283418381E306
:1039E00090E0289FB001299F700D389F700D112421
:1039F000665E7F4FCF0147E050E00E941336809112
:103A0000E903282F30E0F90193E0EE0FFF1F9A95AC
:103A1000E1F7E21BF30BE853FE4F658176810E94CC
:103A20000A2684E06EE10E9487068D2D0E94910C8B
:103A30001F910F91FF90EF90DF90CF90AF908F90FC
:103A4000089583E20E944E0E0E94911C08958FE11A
:103A50000E944E0E0E94911C08958F92AF92CF92B9
:103A6000DF92EF92FF920F931F930E94E407D82EEC
:103A70001091E9030E94B225BC01812F0E949B2670
:103A80002091460430E08091E90390E0FC0103E0DE
:103A9000EE0FFF1F0A95E1F7E81BF90BE853FE4F05
:103AA0006381748180E090E0F901EE0FFF1FE20F67
:103AB000F31FEE0FFF1FEE0FFF1FDF01AC51BE4FD4
:103AC0002D913C9140E050E0E052FE4FE680F780BF
:103AD00000E010E0E6E0CE2EB9E0AB2E882483941F
:103AE0000E94D118AB01BC018091E903282F30E07E
:103AF000F901A3E0EE0FFF1FAA95E1F7E21BF30B1C
:103B0000E853FE4F83819481A0E0B0E04817590745
:103B10006A077B0741F15483438381E390E0289F48
:103B2000B001299F700D389F700D1124665E7F4F84
:103B3000CF0147E050E00E9413368091E903282F1F
:103B400030E0F90193E0EE0FFF1F9A95E1F7E21BD9
:103B5000F30BE853FE4F658176810E940A2684E0CC
:103B60006EE10E9487068D2D0E94910C1F910F918E
:103B7000FF90EF90DF90CF90AF908F90089582E20A
:103B80000E944E0E0E942D1D08958EE10E944E0E41
:103B90000E942D1D08958F92AF92CF92DF92EF92E7
:103BA000FF920F931F930E94E407D82E8091E903A0
:103BB00090E0FC01B3E0EE0FFF1FBA95E1F7E81BC0
:103BC000F90BE853FE4F608170E080E090E020E068
:103BD00030E040E050E0A1E0EA2EF12C012D112D63
:103BE000F6E0CF2EE5E0AE2E88240E94D1189B018E
:103BF000AC016091E903862F90E0FC0173E0EE0FC9
:103C0000FF1F7A95E1F7E81BF90BE853FE4F80811F
:103C100090E0A0E0B0E0281739074A075B0729F1D8
:103C20002083862F622F0E94BF252091E90330E078
:103C3000C90143E0880F991F4A95E1F7821B930B56
:103C400041E350E0249FB001259F700D349F700D1B
:103C50001124665E7F4F88539E4F47E050E00E94DC
:103C6000133684E06EE10E9487068D2D0E94910C30
:103C70001F910F91FF90EF90DF90CF90AF908F90BA
:103C8000089581E20E944E0E0E94CB1D08958DE1A1
:103C90000E944E0E0E94CB1D08958F92AF92CF923C
:103CA000EF92FF920F931F938CE10E944E0E88E0DB
:103CB00061E00E94AF236091460470E080E090E0F4
:103CC00020E030E040E050E0A1E0EA2EF12C012DB0
:103CD000112DF5E0CF2EE7E0AE2E88240E94D118FA
:103CE0009B01AC018091460490E0A0E0B0E0281771
:103CF00039074A075B0799F0F8942093460489E155
:103D000090E0622F0E941D36809146040E94B20806
:103D10000E944E25789484E06EE10E9487068BED28
:103D200091E00E94530C1F910F91FF90EF90CF9064
:103D3000AF908F9008958F92AF92CF92EF92FF92B3
:103D40000F931F9380E00E944E0E6091BF0170E0C0
:103D500080E090E020E030E040E050E0F2E0EF2E44
:103D6000F12C012D112DE3E0CE2EB6E0AB2E8824F0
:103D70000E94D1187B018C0180E190E00E94FF3508
:103D80008093BF0190E0A0E0B0E0E816F9060A07D2
:103D90001B0759F0E092BF0180E190E06E2D0E9478
:103DA0001D3684E06EE10E9487068BED91E00E9453
:103DB000530C1F910F91FF90EF90CF90AF908F9089
:103DC00008958F92AF92CF92EF92FF920F931F932D
:103DD00086E00E944E0E6091BE0170E080E090E0AF
:103DE00021E030E040E050E0E7E0EE2EF12C012D44
:103DF000112DB3E0CB2EA3E0AA2E88240E94D11867
:103E00009B01AC018091BE0190E0A0E0B0E02817DA
:103E100039074A075B0751F48091F90490E0A0E06C
:103E2000B0E0281739074A075B07F9F02093BE0175
:103E30002093F9048EE090E0622F0E941D3684E00A
:103E40006EE10E9487068091BE010E945905809113
:103E5000DB01882351F460E00E94AF236091BE0132
:103E600070E080E090E00E9435098BED91E00E94C7
:103E7000530C1F910F91FF90EF90CF90AF908F90C8
:103E800008958F92AF92CF92EF92FF920F931F936C
:103E900085E00E944E0E6091890370E080E090E022
:103EA00020E030E040E050E0B2E0EB2EF12C012DBC
:103EB000112DA3E0CA2EF4E0AF2E88240E94D11861
:103EC0009B01AC018091890390E0A0E0B0E028174D
:103ED00039074A075B0711F1F894209389038FE0B3
:103EE00090E0622F0E941D3684E06EE10E948706FA
:103EF000809189030E946A05982F80934E048091D7
:103F0000DB01882351F480918903823010F064E64C
:103F100001C06BEF892F0E940F0978948BED91E01F
:103F20000E94530C1F910F91FF90EF90CF90AF9094
:103F30008F9008951F9311E015C080E20E941E2506
:103F4000882311F411E003C01092DB0110E00E94FD
:103F5000C41880E00E94800F8091DA01882311F458
:103F60001092DB0180E20E940E25882311F41123B8
:103F700021F70E948E23112319F081E00E942F0661
:103F80008091DB01882311F40E94A910812F1F91D9
:103F90000895CF93DF93EBEDF1E001900020E9F776
:103FA0003197EB5DF140E150CE2FD0E0C552DE4FAE
:103FB0008881805380938C038093EC0381E080930D
:103FC000EE0380E390E00E94BE0C0E94BD230E949D
:103FD0009A1F8111188210928C038BED91E00E9440
:103FE000530CDF91CF9108950F931F93DF93CF93DD
:103FF000CDB7DEB764970FB6F894DEBF0FBECDBF66
:1040000085E30E944E0E88E090E00E94BE0CBC0149
:104010008E010F5F1F4FC8010E94AC348AE090E010
:104020000E94BE0CBC01C8010E949834C80161E026
:104030000E9475098BE090E00E94BE0C62E00E9435
:1040400075090E949A1F882359F08091D801909198
:10405000D9010E9455111092DB010E94A91004C0E1
:104060008BED91E00E94530C64960FB6F894DEBF7E
:104070000FBECDBFCF91DF911F910F9108950F9388
:104080001F93DF93CF93CDB7DEB764970FB6F89445
:10409000DEBF0FBECDBF84E30E944E0E88E090E0ED
:1040A0000E94BE0CBC018E010F5F1F4FC8010E9411
:1040B000AC3489E090E00E94BE0CBC01C8010E94B3
:1040C0009834C80161E00E9475098BE090E00E947D
:1040D000BE0C62E00E9475090E949A1F882359F065
:1040E0008091D8019091D9010E9489111092DB0131
:1040F0000E94A91004C08BED91E00E94530C6496BD
:104100000FB6F894DEBF0FBECDBFCF91DF911F91E8
:104110000F910895EF92FF920F931F93CF93DF9328
:10412000EC01F62E042F8091DC01882309F5909193
:104130008A03892F81508330D8F4F394913029F485
:10414000FE01EF0DF11D80E4808380918A038230AF
:1041500031F4FE01EF0DF11D89E28083F39480912B
:104160008A03833029F4FE01EF0DF11D81E3808382
:104170000E948E2380E061E00E94AF238CEF0E94BA
:104180003F23CE01602F4F2D0E94930E3AC080E452
:104190000E94F824882329F480E40E9403258823C0
:1041A00051F0002311F40F2D01C00150CE01602FFA
:1041B0004F2D0E94930E80E80E94F824882329F452
:1041C00080E80E940325882351F00F1510F000E0CD
:1041D00001C00F5FCE01602F4F2D0E94930E80E231
:1041E0000E941E25E82E0E94C41880E00E94800FC5
:1041F0008091DA01882311F410E004C010E0EE2071
:1042000009F411E080E20E940E25882319F411239D
:1042100009F0BDCF0E948E23112321F1EBEDF1E0D7
:1042200001900020E9F73197EB5DF140002361F048
:1042300081E08093EC03F0E0E552FE4F005D0083E7
:1042400011820E942F0612C08E2F8150E82FF0E0BD
:10425000E552FE4F908190539093EC031082882397
:1042600029F402C01092DB010E94A910DF91CF91C6
:104270001F910F91FF90EF900895DF93CF9300D09F
:1042800000D0CDB7DEB784E089838DE28A838EE2E9
:104290008B838FE28C83CE01019663E04091EC0327
:1042A0000E948A208BED91E00E94530C0F900F909A
:1042B0000F900F90CF91DF910895DF93CF9300D0AF
:1042C0000F92CDB7DEB7DE011196ECE1F3E083E0AB
:1042D00001900D928150E1F7CE01019662E040918C
:1042E000EC030E948A208BED91E00E94530C0F900A
:1042F0000F900F90CF91DF910895DF93CF9300D06F
:104300000F92CDB7DEB7DE011196EFE1F3E083E067
:1043100001900D928150E1F7CE01019662E040914B
:10432000EC030E948A208BED91E00E94530C0F90C9
:104330000F900F90CF91DF910895DF93CF9300D02E
:1043400000D00F92CDB7DEB7DE011196E2E2F3E0C6
:1043500085E001900D928150E1F7CE01019664E075
:104360004091EC030E948A2081E08093E9038BED69
:1043700091E00E94530C0F900F900F900F900F90B0
:10438000CF91DF910895DF93CF9300D000D00F92AB
:10439000CDB7DEB7DE011196E7E2F3E085E00190EC
:1043A0000D928150E1F7CE01019664E04091EC035B
:1043B0000E948A201092E9038BED91E00E94530C39
:1043C0000F900F900F900F900F90CF91DF91089565
:1043D000DF93CF9300D000D0CDB7DEB784E08983E0
:1043E0008CE18A838CE38B838DE38C83CE010196F1
:1043F00063E04091EC030E948A208BED91E00E94E3
:10440000530C0F900F900F900F90CF91DF91089564
:10441000DF93CF9300D00F92CDB7DEB7DE011196B8
:10442000EFE2F3E083E001900D928150E1F7CE01DD
:10443000019662E04091EC030E948A208BED91E0AE
:104440000E94530C0F900F900F90CF91DF91089521
:10445000DF93CF93CDB7DEB72B970FB6F894DEBFBF
:104460000FBECDBFDE011196E2E3F3E08BE00190D9
:104470000D928150E1F78BED91E066E971E00E94C9
:10448000AC34CE01019668E04091EC030E948A2092
:104490008BED91E00E94530C2B960FB6F894DEBF83
:1044A0000FBECDBFCF91DF9108958F92AF92CF9283
:1044B000DF92EF92FF920F931F93DF93CF93CDB7CD
:1044C000DEB760970FB6F894DEBF0FBECDBF88EEA3
:1044D00093E024EF31E0F9013197F1F70197D9F733
:1044E000DE011196ECE0F3E080E101900D92815045
:1044F000E1F7239A2B9887B18F7387B9579886B1C4
:1045000090E0807C09F091E0892F0E94BD114F99C5
:1045100004C0369902C00E94B20781B18F6181B98F
:1045200084B1876184B98091BE010E945905809150
:10453000BE018093F90413980E94C50585E085BDEE
:1045400080916E00816080936E0083E08093B10063
:10455000809170008160809370008AB1837F8AB9F6
:10456000809169008A6080936900809189030E942C
:104570006A058AB180638AB980918A03882311F021
:104580000E944E258091FA046091440440E020E0AE
:104590000E94DF230E948405CE01019662E00E9402
:1045A00071230E941F0E82E06EE10E9487067894BC
:1045B0008091BF018E3F21F41092BF010E949B1E8B
:1045C0001092DB010E94A910DD24D3940E94D61022
:1045D0000E946A0A0E94C4188091DA018823B1F30C
:1045E00080E20E940E25882321F0D092EC030E94E5
:1045F000282200D06091BE0170E080E090E0EDB72D
:10460000FEB7D182128221E030E040E050E0F7E0D6
:10461000EF2EF12C012D112DCC24AA24E3E08E2EB7
:104620000E94C40B0F900F908091BE01681771F229
:104630006093BE01862F0E945905C8CF28B1982FDC
:104640009F70922B98B998B1806F982398B9459A2A
:104650008DE08A95F1F7459888EC8A95F1F70895F1
:104660001F93182F82958F700E941E23812F0E9406
:104670001E231F91089544980E9430230895449A60
:104680000E9430230895EF92FF920F931F93CF93D0
:10469000DF93182F7B0188E20E943B23012F10E05B
:1046A00083E0000F111F8A95E1F7C0E0D0E09E0182
:1046B000200F822F80640E943B23F701EC0FFD1F27
:1046C00080810E943F232196C830D10581F789E27D
:1046D0000E943B23DF91CF911F910F91FF90EF90AC
:1046E0000895EF92FF920F931F93CF93DF937C0176
:1046F000062F10E0C0E0D0E008C0B7016C0F7D1FAE
:10470000812F0E9443231F5F28961017B0F3DF917B
:10471000CF911F910F91FF90EF90089581E00E943B
:104720003B2380E197E20197F1F708950F931F93E0
:10473000162F813011F400E501C004E589E20E94E2
:104740003B23812F8F7080670E943B23129513704B
:10475000802F812B0E943B231F910F91089581315F
:1047600008F080E0643008F060E06295607F680FD8
:10477000862F80680E943B2308950F931F93CF9349
:10478000DF93EC0100E010E00FC08A3051F41330E9
:1047900010F010E001C01F5F80E0612F0E94AF2386
:1047A00002C00E943F230F5FFE01E00FF11D8081D8
:1047B000882359F7DF91CF911F910F910895CF92E0
:1047C000DF92EF92FF920F931F93582F162FC42E54
:1047D000022F279A3D9A3C9A87B18F6087B94598F6
:1047E00080E991E024EF31E0F9013197F1F7019789
:1047F000D9F7513039F4EDE1FE2E7CE6D72E60E595
:10480000E62E06C055E1F52E4EE6D42E34E5E32E15
:10481000449883E00E941E2380E197E20197F1F71C
:1048200083E30E941E2382E30E943B2389E20E94CD
:104830003B238F2D0E943B23812F8F7080670E9426
:104840003B23129513708E2D812B0E943B238D2DBF
:104850000E943B2388E20E943B2301700C608C2D58
:1048600090E081709070880F991F802B0E943B23ED
:104870000E948E2386E00E943B231F910F91FF90A0
:10488000EF90DF90CF9008951F920F920FB60F9286
:1048900011242F933F938F939F938DE386BD26B171
:1048A00089B13091FC0490E080789070959587955F
:1048B00095958795207C282B209523278091CC03E4
:1048C000822380958093CC039091CB0392239827E9
:1048D0009093CB03822389239091FC049827909393
:1048E000FC042091F7049091FC048923822B80938F
:1048F000F7048091F704807E51F0109243041092E7
:10490000420488EE93E09093720380937103809148
:10491000FC04807E49F482E38093CA0384E180939F
:10492000480486E08093EB038091CA038150809312
:10493000CA03882361F4809148048093CA0390914C
:1049400047048091FC04807E892B809347048091EA
:10495000C90381508093C903882331F482E3809393
:10496000C90381E08093F5048091C803815080934E
:10497000C803882331F484E18093C80381E08093E5
:1049800045048091C70381508093C703882331F485
:1049900082E08093C70381E080934D048091C60339
:1049A00081508093C603882331F48AE08093C60344
:1049B00081E08093E80380917103909172030197E5
:1049C0009093720380937103892B49F488EE93E0EE
:1049D000909372038093710381E08093FB049F9115
:1049E0008F913F912F910F900FBE0F901F901895B0
:1049F000F8949091F70489239091F7049827909365
:104A0000F70478940895F89490914704892390913D
:104A1000470498279093470478940895F8949091C8
:104A2000FC04F8942091F7049095892382239091B7
:104A3000F70498279093F70478940895982FF894A2
:104A400080914704982380914704892780934704E5
:104A50007894F8948091F70489239091F70498272B
:104A60009093F704789408958823B9F08091EB032C
:104A7000882341F0F8948091EB0381508093EB03FD
:104A80007894089580914804843038F0F8948091A7
:104A900048048250809348047894089580916F0070
:104AA0008D7F80936F00E0914604EE2309F051C0A2
:104AB000809181008C7F809381008091810084604F
:104AC0008093810080E18093FD0480E2809309055A
:104AD0001092160510921505F0E083E0EE0FFF1F0F
:104AE0008A95E1F7ED58FC4F2681378140E050E090
:104AF00060E07DE281E391E00E944233CA01B901A6
:104B000024E130E040E050E00E940F330E94D830B2
:104B10002FE632E143E85AE30E944F320E94AC3064
:104B2000AB017093180560931705309188002091B0
:104B30008900922F80E0830F911D840F951F909321
:104B400089008093880080916F00826080936F005D
:104B50000895809181008B7F8093810080918100F6
:104B60008360AECFE0914604F0E093E0EE0FFF1FCC
:104B70009A95E1F7E958FC4F80819181089590E082
:104B8000FC01EE0FFF1FE80FF91FEE0FFF1FEE0FE6
:104B9000FF1FE350FB4F61706383089590E0DC01D9
:104BA000AA0FBB1FA80FB91FAA0FBB1FAA0FBB1FBD
:104BB000AF5FBA4FE0914604F0E043E0EE0FFF1F15
:104BC0004A95E1F7EB58FC4F80819181860F971F42
:104BD0008D939C93089590E0DC01AA0FBB1FA80F52
:104BE000B91FAA0FBB1FAA0FBB1FA350BB4FE09159
:104BF0004604F0E083E0EE0FFF1F8A95E1F7ED58E1
:104C0000FC4F80819181861B970B17969C938E9306
:104C1000169708954F925F926F927F928F929F9214
:104C2000AF92BF92CF92DF92EF92FF920F931F93BA
:104C30007B0190E0EDEFF4E09C01220F331F280F81
:104C4000391F4901880C991C880C991C8E0E9F1ED7
:104C5000D4011B96FC92EE921A972F5F3F4F220FC2
:104C6000331F220F331FE20FF31FA080B18016966F
:104C70006D917C9117976A197B0980E090E00E9402
:104C8000D83020E030E040E05FE30E944F322B015B
:104C90003C0100E010E0C801B7010E94D8307B0160
:104CA0008C01E0914604F0E033E0EE0FFF1F3A95EF
:104CB000E1F7E958FC4F6081718180E090E00E944B
:104CC000D83020E030E040E05FEB0E944F329B01A3
:104CD000AC01C801B7010E94722F9B01AC01C30156
:104CE000B2010E94722F7B018C01CC24DD24C6010D
:104CF000B5010E94D8309B01AC01C801B7010E94E8
:104D0000722F0E94AC30F401718760871F910F9160
:104D1000FF90EF90DF90CF90BF90AF909F908F90DB
:104D20007F906F905F904F900895EFE6F0E0808164
:104D30008D7F808308952F923F924F925F926F9262
:104D40007F928F929F92AF92BF92CF92DF92EF921B
:104D5000FF920F931F93DF93CF9300D000D000D02A
:104D6000CDB7DEB7282F30E03E832D83F901EE0F5B
:104D7000FF1FE20FF31FEE0FFF1FEE0FFF1FE350A9
:104D8000FB4F8381882381F0E0914604F0E0B3E09B
:104D9000EE0FFF1FBA95E1F7E958FC4F8081918132
:104DA000AC01461B570BBA01E0914604F0E0A3E0CA
:104DB000EE0FFF1FAA95E1F7E958FC4F8081918122
:104DC000CD80DE80CC0CDD1C1B01442455249C01CD
:104DD00040E050E029833A834B835C839695879526
:104DE0006817790708F047C00D811E810C0D1D1D45
:104DF000000F111F000F111FF801EF5FFA4FA08085
:104E0000B180220C331C441C551CC201B1010E940C
:104E1000D8303B014C0103501B4FF8016085718570
:104E20006A197B0980E090E00E94D8309B01AC01B8
:104E3000C401B3010E944F327B018C0169817A81E8
:104E40008B819C810E94D8309B01AC01C801B701C5
:104E50000E943F307B018C01CC24DD24C601B501CA
:104E60000E94D8309B01AC01C801B7010E94722F8B
:104E70000E94AC3048C069817A818B819C810E94FC
:104E8000D8304B015C012D813E81C20ED31ECC0C6B
:104E9000DD1CCC0CDD1C4DEF54E0C40ED51EF6011C
:104EA00060847184C201B1010E94D8307B018C0101
:104EB000C501B40120E030E040E05FEB0E944F32DA
:104EC0009B01AC01C801B7010E94722F9B01AC018C
:104ED0000E94722F7B018C01F60166817781661931
:104EE000770980E090E00E94D8309B01AC01C801B6
:104EF000B7010E944F32A50194010E943F300E94E9
:104F0000AC30660D771DED81FE81EE0FFF1F2D8108
:104F10003E81E20FF31FEE0FFF1FEE0FFF1FEF5F4B
:104F2000FA4F0190F081E02D6E177F0708F4BF0162
:104F3000ED81FE81EE0FFF1F4D815E81E40FF51FB5
:104F4000EE0FFF1FEE0FFF1FE350FB4F868197818F
:104F50008617970708F4BC017283618326960FB603
:104F6000F894DEBF0FBECDBFCF91DF911F910F919F
:104F7000FF90EF90DF90CF90BF90AF909F908F9079
:104F80007F906F905F904F903F902F900895482FA3
:104F900050E0FA01EE0FFF1FE40FF51FEE0FFF1FA9
:104FA000EE0FFF1FEF5FFA4F0190F081E02DCB0174
:104FB0006E177F0708F4CF01FA01EE0FFF1FE40F11
:104FC000F51FEE0FFF1FEE0FFF1FE350FB4F268173
:104FD00037812817390708F4C9019283818308951E
:104FE0001F920F920FB60F9211242F933F934F935E
:104FF0005F938F939F93EF93FF933091CD03323064
:1050000090F42BB1832F90E0FC01EE0FFF1FE80F0F
:10501000F91FEE0FFF1FEE0FFF1FE350FB4F8081C4
:10502000809582238BB9832F8F5F8093CD0382304D
:10503000C9F0833010F01092CD032BB18091CD03D5
:1050400090E0FC01EE0FFF1FE80FF91FEE0FFF1FAE
:10505000EE0FFF1FE350FB4F8081282B2BB94181BE
:1050600052810AC04091170550911805809115058D
:1050700090911605481B590B3091880020918900AA
:10508000922F80E0830F911D840F951F90938900CC
:10509000809388008091150590911605840F951FC7
:1050A00090931605809315052091170530911805EA
:1050B0008217930720F01092160510921505FF91A4
:1050C000EF919F918F915F914F913F912F910F9011
:1050D0000FBE0F901F9018959C0140E050E084E0B7
:1050E000220F331F441F551F8A95D1F760E07DE2E0
:1050F00081E391E00E944233215030403093C5005B
:105100002093C40088E98093C10086E08093C200A8
:105110000895982F8091C00085FFFCCF9093C60022
:105120000895FC0107C08091C00085FFFCCF9093DB
:10513000C600319690819923B1F708951F920F927E
:105140000FB60F9211242F938F939F93EF93FF939A
:105150002091C6008091CE03882309F052C080912F
:10516000B005281771F480918603882351F01092BE
:10517000860389E195E090938503809384031092E0
:10518000B105809186038823E1F5E0918403F091D5
:10519000850320838091B1058F5F8093B105809155
:1051A000AF05882319F02D3001F51AC08091B105A3
:1051B000823029F4213019F081E0809386038091B8
:1051C000B105833021F4223010F086E001C085E083
:1051D000809383039091B10580918303981729F4FC
:1051E00081E0809386038093CE033196F09385030C
:1051F000E09384038091B105863919F481E08093AE
:105200008603FF91EF919F918F912F910F900FBE89
:105210000F901F901895CF93DF93EC0130E044C0BE
:105220004F5FE42FF0E0E75EFA4F20812D534F5F90
:10523000E42FF0E0E75EFA4F70814F5FE42FF0E07B
:105240004350E75EFA4F5081DE01A30FB11D922F4C
:1052500092959F70E42FF0E0E75EFA4F80818D53C6
:10526000880F880F892B8C93613009F1972F9D53FC
:105270003F5FFE01E30FF11D31502295207F892F02
:1052800086958695282B2083623089F04C5F635089
:105290003E5FFE01E30FF11D9295990F990F907CEF
:1052A0005D53952B90833F5F662309F0B9CFDF9163
:1052B000CF910895982F8091CE03813009F04BC093
:1052C0008091B105882309F446C080911B05891798
:1052D00009F041C040E050E020E006C0E75EFA4F30
:1052E0008081480F511D2F5FE22FF0E08091B105C2
:1052F00090E00397E817F9078CF3CA019F70E091DB
:10530000B10526E0959587952A95E1F7835CF0E055
:10531000EA5EFA4F20818217B1F4E091B1054F7334
:105320005070942F935CF0E0E95EFA4F80819817FB
:1053300051F46091B10566508FE494E043E00E941F
:105340000B2921E001C020E0F8941092E6041092AD
:10535000E504789401C020E08091E5049091E60492
:105360008C5E944048F480911B05813428F08B3585
:1053700018F481E08093ED031092CE03822F0895FC
:1053800090E0823009F491E09093AF05992311F0F9
:1053900083E201C080E88093B0050895AC0180915C
:1053A000B10582508093B1058091CE03813091F494
:1053B00020E009C0FA01E20FF11DB0E0A75EBA4F8C
:1053C0008C9180832F5FA22FA60F8091B1052817A3
:1053D00088F302C01092B1051092CE038091B105FE
:1053E0000895A0E3B0E0E7EFF9E20C946433A8E09D
:1053F0004E010894811C911CF401BA2F1192BA95A8
:10540000E9F729833A834B835C836D837E838F83A3
:105410009887CE010996FC011192AA95E9F7A98611
:10542000BA86CB86DC86ED86FE860F87188B2981AF
:105430003A814B815C812DA73EA74FA758AB7901DC
:105440008A018FEF9FEFA0E0B0E0E822F9220A2363
:105450001B231A014424552429853A854B855C85F4
:1054600029A73AA74BA75CA759016A01A822B9222C
:10547000CA22DB223A0188249924C601B501A80179
:1054800097010E940F336DA37EA38FA398A7C40139
:10549000B3010E940F3369A37AA38BA39CA3C60117
:1054A000B501A20191010E940F337B018C01C4015F
:1054B000B3010E940F335B016C0189A19AA1ABA1DA
:1054C000BCA18E0D9F1DA01FB11F89A39AA3ABA3E2
:1054D000BCA32DA13EA14FA158A5CA01AA27BB2755
:1054E00029A13AA14BA15CA1280F391F4A1F5B1FBC
:1054F00029A33AA34BA35CA32E153F0540075107F0
:1055000040F480E090E0A1E0B0E0A80EB91ECA1E11
:10551000DB1E89A19AA1ABA1BCA19D0144275527FF
:105520002A0D3B1D4C1D5D1D2D8F3E8F4F8F58A3A7
:105530006C01BB24AA248DA19EA1AFA1B8A5A07027
:10554000B070A80EB91ECA1EDB1EA98EBA8ECB8EF5
:10555000DC8E9A8C8B8C7C8C9E8D6F8D78A1FE015D
:10556000719688E0DF011D928A95E9F72D8B9E8B5D
:105570006F8B788F2D853E854F8558896DA57EA5CB
:105580008FA598A90E940F337B018C012D813E814C
:105590004F81588569A57AA58BA59CA50E940F33DC
:1055A000E60EF71E081F191F6D897E898F89988D59
:1055B0006E0D7F1D801F911F6D8B7E8B8F8B988F43
:1055C000EE892A2D392D482D572D7E2F8F89988DC4
:1055D000E096E2E10C948033EF92FF920F93DF9319
:1055E000CF93CDB7DEB760970FB6F894DEBF0FBE8E
:1055F000CDBFA82F002309F461C07E010894E11CEF
:10560000F11C88E0F70111928A95E9F729833A8322
:105610004B835C836D837E83AF83988780E2801B9E
:10562000E82FFF27E7FDF0954D815E816F8178853A
:10563000181684F01D861E861F86188A88279927CB
:105640008E1B9F0B04C076956795579547958A9555
:10565000D2F728C0202F332727FD3095DB01CA0160
:10566000022E04C0B695A795979587950A94D2F710
:105670008D879E87AF87B88B04C0440F551F661F68
:10568000771FEA95D2F789819A81AB81BC8104C0EA
:10569000B695A795979587952A95D2F7482B592BBC
:1056A0006A2B7B2B49875A876B877C8729853A85AC
:1056B0004B855C856D857E85AF8598898A2F609640
:1056C0000FB6F894DEBF0FBECDBFCF91DF910F9123
:1056D000FF90EF900895EF92FF920F93DF93CF9397
:1056E000CDB7DEB760970FB6F894DEBF0FBECDBF63
:1056F000A82F002309F461C07E010894E11CF11C6D
:1057000088E0F70111928A95E9F729833A834B8360
:105710005C836D837E83AF83988780E2801BE82F54
:10572000FF27E7FDF09549815A816B817C8118162E
:1057300084F019861A861B861C86882799278E1B5B
:105740009F0B04C0440F551F661F771F8A95D2F721
:1057500028C0202F332727FD3095DB01CA01022EF8
:1057600004C0880F991FAA1FBB1F0A94D2F789870C
:105770009A87AB87BC8704C0769567955795479500
:10578000EA95D2F78D819E81AF81B88504C0880FDC
:10579000991FAA1FBB1F2A95D2F7482B592B6A2B9A
:1057A0007B2B4D875E876F87788B29853A854B8564
:1057B0005C856D857E85AF8598898A2F60960FB64A
:1057C000F894DEBF0FBECDBFCF91DF910F91FF9058
:1057D000EF900895A1E1B0E0E0EFFBE20C946433B8
:1057E0003C017F876E876A01FC01178216828381E4
:1057F00081FD03C06FEF7FEF6FC39E012F5F3F4FAF
:10580000398B288BF3012381EE85FF8523FD85915C
:1058100023FF8191FF87EE87882309F45AC38532DD
:1058200051F4EE85FF8523FD859123FF8191FF874C
:10583000EE87853229F490E0B3010E944135E2CF32
:10584000982F10E0882499241032B0F49B3269F02C
:105850009C3228F4903251F0933271F40BC09D3297
:1058600039F0903349F4116028C01260146025C0EB
:10587000186023C0106121C017FD2AC0892F8053F2
:105880008A3078F416FF06C0FAE09F9E902C11240F
:10589000980E13C03AE0839E802C1124880E10626B
:1058A0000CC09E3221F416FD14C3106406C09C3651
:1058B00011F4106802C0983659F4EE85FF8523FD77
:1058C000959123FF9191FF87EE87992309F0BCCF33
:1058D000892F8554833020F4812F8061905E07C02A
:1058E000892F8556833008F09FC1812F8F7E86FDDA
:1058F00002C076E0972E6FE3F62EF822953619F463
:10590000F0E4FF2A07C0963619F420E8F22A02C014
:1059100091109A94F7FE0AC03BE3391518F45CE342
:10592000B52E02C0B92CB39427E009C047E0491551
:1059300020F4BB2447E0942EF7CF292DBB24C601C9
:1059400004969D878C87F6016081718182819381A5
:10595000AE014F5F5F4F0B2D0E949B336C0109819D
:10596000202E332400FF04C003FD02C01DE209C045
:10597000F1FE02C01BE205C0F2FC02C010E001C053
:1059800010E2C1018C709070892BB9F1112311F4D0
:1059900083E001C084E0881510F088240AC0881ACA
:1059A000F3FC07C080E290E0B3010E9441358A9485
:1059B000C9F7112329F0812F90E0B3010E944135EE
:1059C00023FE03C002E719E00EC006E719E00BC092
:1059D000E114F10409F0805290E0B3010E944135D6
:1059E0000F5F1F4F05C0EF2CFF24F0E1EF22FF24D3
:1059F000F8018491882361F714C1F7FE12C0BC0C32
:105A000024FE04C08A81813309F4BA941B141CF06B
:105A1000BB24B3942DC0F8E0FB1550F538E0B32E4D
:105A200027C0F6FC25C0892D90E08C159D054CF013
:105A30002CEFC2162FEFD20624F030E8F32A01C073
:105A40009A94992049F0E2E0F0E0EC0FFD1FE90D97
:105A5000F11D80818033A1F3F7FE0AC0B92CB39405
:105A6000892D90E0C816D90614F0992401C09C181D
:105A7000F7FC03C025E030E009C01C141D041CF035
:105A800021E030E003C096012F5F3F4F112311F05A
:105A90002F5F3F4F992029F0892D90E00196280F24
:105AA000391F882D90E02817390714F0882401C089
:105AB000821A4F2C5524C20189709070892B39F0BD
:105AC00008C080E290E0B3010E9441358A948820AA
:105AD000C1F7112329F0812F90E0B3010E944135D5
:105AE00043FE07C008C080E390E0B3010E94413547
:105AF0008A948820C1F7F7FE46C08601D7FE02C00F
:105B000000E010E076010894E11CF11CE01AF10AB3
:105B100041E050E04C0F5D1FE40EF51E26014B18CE
:105B20005108892D90E0AA24BB24A81AB90A5FEF76
:105B30000F3F150729F48EE290E0B3010E94413532
:105B4000C016D10634F0401651061CF4F7018081CE
:105B500001C080E3015010400894E11CF11C0A15BB
:105B60001B052CF090E0B3010E944135E0CF0C15ED
:105B70001D0539F49A81963318F4953311F424FEF7
:105B800081E390E04BC08A81813309F00F7E90E081
:105B9000B3010E9441359920A1F08EE290E0B3015B
:105BA0000E94413512E0E1E0F0E0EC0FFD1FE10F53
:105BB000F11D1F5F808190E0B3010E9441359A94EE
:105BC00091F744FC03C085E690E002C085E490E0D4
:105BD000B3010E944135D7FC05C0C114D10441F482
:105BE00004FF06C0D094C194D108D3948DE201C0C3
:105BF0008BE290E0B3010E94413580E305C08F5FE6
:105C000026EF3FEFC20ED31E3AE0C316D104BCF715
:105C100090E0B3010E944135C601C096B3010E94D5
:105C20004135CC84DD8452C1933631F0933799F0FD
:105C3000933509F059C023C0F601808189835E0144
:105C40000894A11CB11C22E030E0C20ED31E21E05A
:105C5000E22EF12C12C0F601A080B18016FD03C027
:105C60006FEF7FEF02C0692D70E022E030E0C20EDE
:105C7000D31EC5010E94B3347C011F7713C0F60107
:105C8000A080B18016FD03C06FEF7FEF02C0692DC9
:105C900070E022E030E0C20ED31EC5010E947A34CB
:105CA0007C01106813FF07C01BC080E290E0B301C5
:105CB0000E9441358A94882D90E0E816F906A8F3F1
:105CC0000FC0F50117FD859117FF81915F0190E0ED
:105CD000B3010E94413581108A940894E108F108CB
:105CE000E114F10471F7F2C0943611F0993689F598
:105CF00017FF08C0F601208131814281538184E081
:105D000090E00AC0F601808191819C01442737FD13
:105D10004095542F82E090E0C80ED91E9FE6F92EE0
:105D2000F12257FF09C050954095309521953F4F7E
:105D30004F4F5F4F90E8F92ACA01B901AE014F5F9A
:105D40005F4F2AE030E00E949135E82EE889EE1A94
:105D500041C0953721F41F7E2AE030E01CC0197F36
:105D60009F3661F0903720F4983509F0B2C00FC02B
:105D7000903739F0983709F0ACC004C028E030E023
:105D80000AC0106114FD146020E130E004C014FD6D
:105D9000166020E132E017FF08C0F60160817181D2
:105DA0008281938144E050E008C0F60180819181B6
:105DB000BC0180E090E042E050E0C40ED51EAE0190
:105DC0004F5F5F4F0E949135E82E5889E51A8FE7A3
:105DD000F82EF122F6FE0BC08EEFF822E91438F40B
:105DE000F4FE07C0F2FC05C09FEEF92202C01E2D92
:105DF00001C0192DF4FE0DC0FE01EE0DF11D8081D4
:105E0000803319F4E9EEFE2208C01F5FF2FE05C0E0
:105E100003C08F2D867809F01F5F0F2DF3FC14C08F
:105E2000F0FE0FC0181510F09E2C0BC09E2C980C85
:105E3000911A182D06C080E290E0B3010E9441350E
:105E40001F5F1815C0F304C0181510F4811A01C0A3
:105E5000882404FF0FC080E390E0B3010E94413525
:105E600002FF1DC001FD03C088E790E00EC088E579
:105E700090E00BC0802F867891F001FF02C08BE28A
:105E800001C080E2F7FC8DE290E0B3010E94413551
:105E900006C080E390E0B3010E9441359A94E91472
:105EA000C0F3EA94E1E0F0E0EC0FFD1FEE0DF11D10
:105EB000808190E0B3010E944135EE2091F706C049
:105EC00080E290E0B3010E9441358A948820C1F7B6
:105ED00099CCF30166817781CB016196E2E10C9464
:105EE00080335058BB27AA270ED083C24CD230F043
:105EF00051D220F031F49F3F11F41EF41CC20EF475
:105F0000E095E7FB04C2E92F96D280F3BA17620747
:105F100073078407950718F071F49EF5AEC20EF46E
:105F2000E0950B2EBA2FA02D0B01B90190010C01A9
:105F3000CA01A0011124FF27591B99F0593F50F4C1
:105F4000503E68F11A16F040A22F232F342F442719
:105F5000585FF3CF469537952795A795F040539511
:105F6000C9F77EF41F16BA0B620B730B840BBAF0E1
:105F70009150A1F0FF0FBB1F661F771F881FC2F74C
:105F80000EC0BA0F621F731F841F48F48795779560
:105F90006795B795F7959E3F08F0B3CF9395880F17
:105FA00008F09927EE0F979587950895ECD158F052
:105FB00080E891E009F49EEFEDD128F040E851E04F
:105FC00059F45EEF09C0B7C158C2E92FE07833D267
:105FD00068F3092E052AC1F3261737074807590722
:105FE00038F00E2E07F8E02569F0E025E0640AC0DD
:105FF000EF6307F8009407FADB01B9019D01DC01AA
:10600000CA01AD01EF934AD0F4D10AD05F91552374
:1060100031F02BED3FE049E450FD49EC63CF0895AA
:10602000DF93DD27B92FBF7740E85FE31616170629
:1060300048075B0710F4D92F2BD29F938F937F9340
:106040006F93D2D2E0E7F0E079D1D3D12F913F9195
:106050004F915F9130D2DD2349F09058A2EA2AEDAA
:106060003FE049EC5FE3D0785D274DDFDF91C1C1B0
:106070002AD108F481E0089595D1E395CBC10CD0E5
:10608000B8C188D140F07FD130F021F45F3F19F0E2
:106090003EC15111F3C14FC1CED198F39923C9F339
:1060A0005523B1F3951B550BBB27AA27621773071E
:1060B000840738F09F5F5F4F220F331F441FAA1FD2
:1060C000A9F333D00E2E3AF0E0E830D09150504092
:1060D000E695001CCAF729D0FE2F27D0660F771F40
:1060E000881FBB1F261737074807AB07B0E809F022
:1060F000BB0B802DBF01FF2793585F4F2AF09E3FB7
:10610000510568F004C1BAC15F3FECF3983EDCF37F
:10611000869577956795B795F7959F5FC9F7880F2F
:10612000911D9695879597F90895E1E0660F771F81
:10613000881FBB1F621773078407BA0720F0621B12
:10614000730B840BBA0BEE1F88F7E095089504D00B
:106150006894B11193C1089576D188F09F5790F05B
:10616000B92F9927B751A0F0D1F0660F771F881F7C
:10617000991F1AF0BA95C9F712C0B13081F07DD1DC
:10618000B1E008957AC1672F782F8827B85F39F07A
:10619000B93FCCF3869577956795B395D9F73EF4DB
:1061A00090958095709561957F4F8F4F9F4F089583
:1061B000E89409C097FB3EF49095809570956195A1
:1061C0007F4F8F4F9F4F9923A9F0F92F96E9BB2757
:1061D0009395F695879577956795B795F111F8CFD3
:1061E000FAF4BB0F11F460FF1BC06F5F7F4F8F4F3E
:1061F0009F4F16C0882311F096E911C0772321F034
:106200009EE8872F762F05C0662371F096E8862FCB
:1062100070E060E02AF09A95660F771F881FDAF722
:10622000880F9695879597F90895ADD018F011F0DD
:10623000B1D038F480C022C1E92FFDD0B0F355238E
:10624000C9F3E7FB6217730784079507A8F199F371
:10625000E92FFF2788232AF03197660F771F881FC1
:10626000DAF7952F5527442332F091505040220FF2
:10627000331F441FD2F7BB27E91BF50B621B730BBF
:10628000840BB109C1F222F4620F731F841FB11D88
:1062900031972AF0660F771F881FBB1FEFCF9150F1
:1062A00050405AF041F0882332F0660F771F881F64
:1062B00091505040C1F7939530C08695779567957A
:1062C0009F5FD9F7F8CF990F0008550FAA0BE0E8A8
:1062D000FEEF16161706E807F907C0F012161306A8
:1062E000E407F50798F0621B730B840B950B39F4E8
:1062F0000A2661F0232B242B252B21F408950A264E
:1063000009F4A140A6958FEF811D811D089597F98D
:106310009F6780E870E060E008959F3F31F0915002
:1063200020F4879577956795B795880F911D969579
:10633000879597F908959FEF80EC0895DF93CF93A9
:106340001F930F93FF92EF92DF927B018C01689471
:1063500005C0DA2EEF01AFD0FE01E894A59125919A
:10636000359145915591AEF3EF01CDDDFE019701D9
:10637000A801DA9479F7DF90EF90FF900F911F91C9
:10638000CF91DF91089500240A9416161706180677
:106390000906089500240A94121613061406050629
:1063A0000895C9CF50D0E8F3E894E0E0BB279F57A9
:1063B000F0F02AED3FE049EC06C0EE0FBB0F661F80
:1063C000771F881F28F0B23A62077307840728F006
:1063D000B25A620B730B840BE3959A9572F780386F
:1063E00030F49A95BB0F661F771F881FD2F790482D
:1063F00096CF092E0394000C11F4882352F0BB0FA2
:1064000040F4BF2B11F460FF04C06F5F7F4F8F4FCC
:106410009F4F0895EF93E0FF06C0A2EA2AED3FE008
:1064200049EC5FEB70DDE5DF0F90039401FC9058C1
:10643000EDE9F0E0E3C057FD9058440F551F59F0C7
:106440005F3F71F04795880F97FB991F61F09F3F61
:1064500079F087950895121613061406551FF2CF8A
:106460004695F1DF08C0161617061806991FF1CFDA
:1064700086957105610508940895E894BB27662701
:106480007727CB0197F908951EDF08F48FEF089561
:106490009B01AC0160E070E080E89FE3F0CD0BD0A1
:1064A000A8CF71DF28F076DF18F0952309F02FCF01
:1064B00042CF1124E3CFBFDFA0F3959FD1F3950F17
:1064C00050E0551F629FF001729FBB27F00DB11D78
:1064D000639FAA27F00DB11DAA1F649F6627B00D08
:1064E000A11D661F829F2227B00DA11D621F739FF1
:1064F000B00DA11D621F839FA00D611D221F749FFF
:106500003327A00D611D231F849F600D211D822F45
:10651000762F6A2F11249F5750408AF0E1F088238C
:106520004AF0EE0FFF1FBB1F661F771F881F915099
:106530005040A9F79E3F510570F0E9CE9FCF5F3FD5
:10654000ECF3983EDCF3869577956795B795F795CC
:10655000E7959F5FC1F7FE2B880F911D9695879554
:1065600097F9089511F40EF4E6CED7CE6CDFD0F390
:106570009923D9F3CEF39F57550B87FF38D00024CA
:10658000A0E640EA900180585695979528F4805CE3
:10659000660F771F881F20F026173707480730F44B
:1065A000621B730B840B202931294A2BA695179463
:1065B0000794202531254A2758F7660F771F881F33
:1065C00020F026173707480730F4620B730B840B53
:1065D000200D311D411DA09581F7B901842F9158DF
:1065E000880F9695879508959B01AC0158CF9150DF
:1065F0005040660F771F881FD2F708959F938F939F
:106600007F936F93FF93EF939B01AC0148DFEF9172
:10661000FF9194DE2F913F914F915F9140CF629F08
:10662000D001739FF001829FE00DF11D649FE00D8A
:10663000F11D929FF00D839FF00D749FF00D659FEB
:10664000F00D9927729FB00DE11DF91F639FB00DEA
:10665000E11DF91FBD01CF0111240895AA1BBB1B29
:1066600051E107C0AA1FBB1FA617B70710F0A61B52
:10667000B70B881F991F5A95A9F780959095BC0173
:10668000CD010895A1E21A2EAA1BBB1BFD010DC06E
:10669000AA1FBB1FEE1FFF1FA217B307E407F507D2
:1066A00020F0A21BB30BE40BF50B661F771F881FAE
:1066B000991F1A9469F760957095809590959B0144
:1066C000AC01BD01CF0108952F923F924F925F928E
:1066D0006F927F928F929F92AF92BF92CF92DF92F2
:1066E000EF92FF920F931F93CF93DF93CDB7DEB757
:1066F000CA1BDB0B0FB6F894DEBF0FBECDBF0994EB
:106700002A88398848885F846E847D848C849B8441
:10671000AA84B984C884DF80EE80FD800C811B814F
:10672000AA81B981CE0FD11D0FB6F894DEBF0FBE7E
:10673000CDBFED010895283008F027E03327DA01B6
:10674000990F311D87FD916000966105710539F43F
:1067500032602E5F3D9330E32A95E1F708959F3F25
:1067600030F080387105610509F03C5F3C5F3D9376
:10677000913008F08068911DDF93CF931F930F93A2
:10678000FF92EF92192F987F9695E92F96959695FF
:10679000E90FFF27EC52F64F99273327EE24FF2409
:1067A000A701E70105900894079428F4360FE71E27
:1067B000F81E491F511D660F771F881F991F0694E9
:1067C000A1F70590079428F4E70EF81E491F561FFD
:1067D000C11D770F881F991F661F0694A1F70590AA
:1067E000079428F4F80E491F561FC71FD11D880FA4
:1067F000991F661F771F0694A1F70590079420F450
:10680000490F561FC71FD81F990F661F771F881F74
:106810000694A9F784911095177041F0D695C79505
:1068200057954795F794E7941A95C1F7EAE7F9E089
:1068300068941590159135916591959105907FE239
:106840007395E118F10A430B560BC90BD009C0F739
:10685000E10CF11E431F561FC91FD01D7EF470337B
:1068600011F48A95E6CFE894015030F0080F0AF44D
:106870000027021708F4202F2395022F7A3328F0DF
:1068800079E37D932A95E9F710C07D932A9589F6DF
:10689000069497956795379517951794E118F10A1F
:1068A000430B560BC90BD00998F023957E91739535
:1068B0007A3308F070E37C932013B8F77E9170610F
:1068C0007D9330F0839571E37D9370E32A95E1F732
:1068D0001124EF90FF900F911F91CF91DF91992795
:1068E00087FD90950895FB01DC0105900D92002035
:1068F000E1F70895FC010590615070400110D8F750
:10690000809590958E0F9F1F0895FB01DC018D915E
:1069100081341CF08B350CF4805E619161341CF085
:106920006B350CF4605E861B611189F3990B089539
:10693000FB01DC010D900020E9F7119701900D9209
:106940000020E1F70895FB01DC018D910190801991
:106950000110D9F3990B0895FB01DC0101900D9210
:106960000020E1F70895FC01615070400190011092
:10697000D8F7809590958E0F9F1F0895FC01A081F8
:10698000B181AD01109681F03D91FB01019003169C
:106990000110E1F7C9F7002011F4D00102C01E92E6
:1069A0001196FC01A083B183CA010895FB019F01E8
:1069B000E8944230C4F04532B4F44A3029F497FBED
:1069C0001EF4909581959F4F642F77270E942E3358
:1069D000805D8A330CF0895D8193CB010097A1F72C
:1069E00016F45DE251931082C9010C943836FA0115
:1069F000CF93FF93EF93223044F1253234F5C22F29
:106A0000E894CA3049F497FB3EF4909580957095D0
:106A100061957F4F8F4F9F4F2C2F3327442755274A
:106A2000FF93EF930E944233EF91FF91605D6A33D1
:106A30000CF0695D6193B901CA01605070408040FB
:106A4000904051F716F4CDE2C19310828F919F913F
:106A5000CF910C943836FB019F01423074F04532DF
:106A600064F4642F77270E942E33805D8A330CF004
:106A7000895D8193CB010097A1F71082C9010C9425
:106A800038360F931F93CF93DF938C01EB018B81EB
:106A900081FF1BC082FF0DC02E813F818C819D81B3
:106AA0002817390764F4E881F9810193F983E883B1
:106AB00006C0E885F985802F0995892B31F48E81F0
:106AC0009F8101969F838E8302C00FEF1FEFC80145
:106AD000DF91CF911F910F910895AEE0B0E0E3E711
:106AE000F5E30C9472330D891E8986E08C831A833A
:106AF00009838FEF9FE79E838D839E01275E3F4F23
:106B0000CE0101966F89788DA9010E94EA2B2F8111
:106B10003885020F131FF80110822E96E4E00C94C2
:106B20008E33FA01AA27283051F1203181F1E894FF
:106B30006F936E7F6E5F7F4F8F4F9F4FAF4FB1E070
:106B40003ED0B4E03CD0670F781F891F9A1FA11D6B
:106B5000680F791F8A1F911DA11D6A0F711D811D6C
:106B6000911DA11D20D009F468943F912AE0269F31
:106B700011243019305D3193DEF6CF010895462F90
:106B80004770405D4193B3E00FD0C9F7F6CF462F71
:106B90004F70405D4A3318F0495D31FD40524193DA
:106BA00002D0A9F7EACFB4E0A69597958795779597
:106BB0006795BA95C9F700976105710508959B011E
:106BC000AC010A2E06945795479537952795BA95A7
:106BD000C9F7620F731F841F951FA01D0895DC0164
:106BE000CB01FC01F999FECF06C0F2BDE1BDF89AD8
:106BF000319600B40D9241505040B8F70895F9997C
:106C0000FECF92BD81BDF89A992780B50895A6E17F
:106C1000B0E044E050E00C94F135A8E1B0E042E08F
:106C200050E00C94F135DC01CB0103C02D910E94A2
:106C30001E3641505040D0F70895262FF999FECFC7
:106C40001FBA92BD81BD20BD0FB6F894FA9AF99A89
:106C50000FBE01960895242F0E941E36252F0E94F4
:106C60001E360C9433360E941D36272F0C941E3688
:106C7000DC01FC01672F71917723E1F7329704C0A3
:106C80007C916D9370836291AE17BF07C8F308952E
:046C9000F894FFCFA6
:106C94003A20004D487A002C002A2000560A310A76
:106CA4003200312E30300023636F3F5D3D3D454857
:106CB4000D004469723A253364004469733A2534FB
:106CC4002E3166004265613A25352E3166005061E9
:106CD4006E3A2533640054696C3A25336400614C80
:106CE4006F6E3A2531302E366600614C61743A2558
:106CF40031302E36660061416C743A2531302E31C4
:106D04006600684C6F6E3A2531302E366600684C4A
:106D140061743A2531302E36660068416C743A2528
:106D240031302E3166003000C0120000201C0000FB
:106D34008025000040380000004B00000096000051
:106D440000E10000000000001F55C003000001FE28
:106D5400CC014B0080008000002D002D007F00003E
:106D64002D002D007F002805CF0301300000000016
:106D740000006400000064006600980000009001B8
:106D8400000090019B016302303100303200303347
:106D940000303331003033320030340030350030CD
:106DA4003531003035320030353231003035323251
:106DB4000030353233003035323400303533003072
:106DC400353331003035333200303533330030352C
:106DD400333400303600303631003036320030374C
:106DE400003037310030373200303800303900306D
:106DF4003A00303A3100303A3200303A33009601EA
:106E04002822F801411FFB01E11EFE0108220102B4
:106E14003F200502F41F09029B1E0C02E8210F0209
:106E24004D1E1302C3211702471E1C02C51D210259
:106E3400271D26028B1C2B029D212F02411E34028A
:106E4400BF1D3902211D3E02851C43027D214602DD
:106E5400B61B4A02621B4E025D215102041B5502FD
:106E6400C21A59025B1A5C024A1A5F023D2162028D
:106E7400C91F6602C91F6A02C91F00000000750FFE
:106E8400B90B320D3509000E230DEC0C0B0D8D0BD7
:106E94005B0BDC0A260BE10DC90DAC0A20201F1F79
:106EA4001F1F2020060814131408062004141504B8
:106EB4000C0D0421222324041D1E1F20010203049F
:106EC400343504050607001B371227002C383936E1
:106ED4003537343000353736300035373830003503
:106EE40038303000353832300035383430003538F9
:106EF400363000400345034A034F03540359035EED
:106F040003E803D3001A00FF0000014C036800FFEC
:086F140003400006190501000D
:04000005008005B0C2
:00000001FF
/C-OSD/trunk/tags/v1.00/KurzanleitungFW.doc
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
/C-OSD/trunk/tags/v1.00/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
/C-OSD/trunk/tags/v1.00/NGVideo_5_8GHz.pnproj
0,0 → 1,0
<Project name="NGVideo_5_8GHz"><File path="makefile"></File><File path="main.c"></File><File path="dogm.c"></File><File path="dogm.h"></File><File path="config.h"></File><File path="keys.c"></File><File path="servo.c"></File><File path="servo.h"></File><File path="ngvideo.h"></File><File path="keys.h"></File><File path="usart.c"></File><File path="usart.h"></File><File path="tracking.c"></File><File path="ngvideo.c"></File><File path="menue.c"></File><File path="messages.c"></File><File path="messages.h"></File><File path="menue.h"></File></Project>
/C-OSD/trunk/tags/v1.00/NGVideo_5_8GHz.pnps
0,0 → 1,0
<pd><ViewState><e p="NGVideo_5_8GHz" x="true"></e></ViewState></pd>
/C-OSD/trunk/tags/v1.00/config.h
0,0 → 1,149
/****************************************************************/
/* */
/* 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 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
 
/* PORTC */
#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
 
/* PORTD */
#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_DATA_PIN PINC
 
#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)
/* initiale Anfangswerte der Einstellungen */
#define EEP_INITB 75 // irgend ein Wert um beschriebenen EEPROM zu erkennen
#define VERSION "1.00"
#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
/* Servokalibrierungen derzeit zu SERVO_STEPS = 255 skaliert */
#define SERVO_PAN 0
#define SERVO_TILT 1
#define SERVO_NUM_CHANNELS 2 // Anzahl der angeschlossen Servos max. 2!!!
#define SERVO_PERIODE 20 // default Angabe in ms
//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
/* Antennen-Nachführung */
#define TRACKING_MIN 0 // aus, TRACKING_RSSI, TRACKING_GPS, TRACKING_MKCOCKPIT
#define TRACKING_MAX 3
/* 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
 
 
#endif /* CONFIG_H_ */
/C-OSD/trunk/tags/v1.00/dogm.c
0,0 → 1,245
 
/****************************************************************/
/* */
/* 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"
 
// 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)
 
 
 
/************************************************************************/
/* 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
}
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
}
 
/************************************************************************************/
/* 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 lcdPutc(char c)
{
lcdSetRegSelect(); // LCD-RS für Daten
lcdSendByte(c);
}
 
/************************************************************************************/
/* sendet einen String zum LCD-Display */
/* Parameter: */
/* char *str :Zeichenkette */
/* */
/************************************************************************************/
void lcdPuts(char *str)
{
uint8_t l;
uint8_t pos = 0;
 
for(l = 0; str[l] != 0; l++)
// funtioniert nur von Zeile 0 an, da aktuelle Zeile nicht bekannt! Kein read!
// man könnte pos bei lcdSendByte, lcdGotoXY und lcdClear abhängig von Steuerung mitzählen
if(str[l] == '\n')
{
if (pos >= LCD_LINES)
pos = 0;
else
pos++;
lcdGotoXY(0, pos);
}
else
lcdPutc(str[l]);
}
 
/************************************************************************************/
/* Löscht Inhalt auf LCD-Display */
/* */
/************************************************************************************/
void lcdClear()
{
lcdSendInstruction(CLEAR_DISPLAY);
_delay_ms(2);
}
 
/************************************************************************************/
/* 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)
{ uint8_t pos;
 
if(x > LCD_COLS) x = 0;
if(y > LCD_LINES) y = 0;
pos = y * LCD_COLS + x;
lcdSendInstruction(SET_DDRAM_ADDR | pos);
}
 
/************************************************************************************/
/* 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);
}
/C-OSD/trunk/tags/v1.00/dogm.h
0,0 → 1,42
 
/****************************************************************/
/* */
/* 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[2][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 lcdSendByte(char data);
void lcdSendInstruction(char instruction);
void lcdPutc(char c);
void lcdPuts(char *str);
void lcdClear(void);
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_ */
/C-OSD/trunk/tags/v1.00/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 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms
 
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 begint Zähler für Hintergrindbeleuchtung 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) { // Wert bestimmt die max. Beschleunigung/Wiederholrate
cli(); // kann jedoch nicht kleiner 10ms sein
key_repeat_next -= 2;
sei();
}
}
}
}
/C-OSD/trunk/tags/v1.00/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_ */
/C-OSD/trunk/tags/v1.00/main.c
0,0 → 1,112
 
/****************************************************************/
/* */
/* 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 "servo.h"
#include "config.h"
#include "dogm.h"
#include "keys.h"
#include "ngvideo.c"
#include "menue.c"
#include "usart.h"
 
 
int main(void)
{ uint8_t ep_reset = 1;
uint8_t val;
 
_delay_ms(100); // Einschaltstörungen unterdrücken
 
// LCD selbst definierte Sonderzeichen, RSSI-Balken und wi232 Empfang Daten
SpecialChr_t lcdSpecialChr= {{32,32,31,31,31,31,32,32},{6,8,20,19,20,8,6,32}};
 
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();
 
// LCD init
lcdInit(dogm_vers, contrast, 0, 0);
lcd_BackgrLight_On();
lcdWriteCGRAM_Array(lcdSpecialChr, 2);
 
Displ_Version();
Double_Beep(DBEEPVERS, DBEEPVERSP);
 
sei();
 
if (language == NO_LANGUAGE) {
language = GERMAN; // Beim Einschalten pmenu[] vordefiniert mit "0"
Menu_Language();
}
pmenu[0] = '\0'; // falls GPS-Antennennachführung ==> Empfang blinken
 
Displ_Main_Disp();
 
while(1)
{
Task_0_1();
Task_0_2();
Tasks_unvisible();
if (bat_low != 0) {
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, IDX_DISPL_CHANNEL, 1, C_REPEAT);
if (val != channel) { // nicht bei jeden Schleifendurchlauf Set_Channel()
channel = val;
Set_Channel(channel);
}
}
}
}
/C-OSD/trunk/tags/v1.00/makefile
0,0 → 1,411
# 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 dogm.c keys.c servo.c usart.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 = -g -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-20090313
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
 
/C-OSD/trunk/tags/v1.00/menue.c
0,0 → 1,1211
 
/****************************************************************/
/* */
/* 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 <util/delay.h>
 
#include "config.h"
#include "ngvideo.h"
#include "keys.h"
#include "menue.h"
#include "servo.h"
#include "messages.c"
 
typedef uint8_t scr_menu_t[SCROLL_MAIN_MAX + 3]; // einmal, da Index mit 0 beginnt plus Vergrößerung für 2 zusätzlich eingeblendete Punkte
uint8_t m_pkt; // um bei Rücksprung auf ursprünglichen Arrayeintrag(Menüpunkt) zeigen
uint8_t servo_nr; // zwischen Servo 1 und 2 wird nur mit global servo_nr unterschieden
 
COMMAND_STRUCTUR COMMAND_TABELLE[] = // Befehls-Tabelle
{
{"0", Menu_Main},
{"01", Menu_AV_Source},
{"02", Menu_RX_Channel},
{"03", Menu_RSSI_Calibr},
{"031", Menu_RSSI_min},
{"032", Menu_RSSI_max},
{"04", Menu_Language},
{"05", Menu_Servo_Calibr},
{"051", Menu_Servo_Steps},
{"052", Menu_Servo1}, // zwischen Servo 1 und 2 wird danach
{"0521", Menu_Servo1_rev}, // mit global servo_nr unterschieden
{"0522", Menu_Servo1_left},
{"0523", Menu_Servo1_right},
{"0524", Menu_Servo1_middle},
{"053", Menu_Servo2},
{"0531", Menu_Servo2_rev},
{"0532", Menu_Servo2_left},
{"0533", Menu_Servo2_right},
{"0534", Menu_Servo2_middle},
{"06", Menu_lcd},
{"061", Menu_lcd_Contrast},
{"062", Menu_lcd_Backgr_Light},
{"07", Menu_Battery},
{"071", Menu_Low_U_Setup},
{"072", Menu_U_Offset},
{"08", Menu_Tracking_Ant},
{"09", Menu_Tracking_Option}, // wird nur bei Tracking RSSI oder GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
{"0:", Menu_GPS_Display}, // wird nur bei Tracking GPS eingeblendet - SCROLL_MAIN_MAX wird geändert
{"0:1", Menu_GPS_Display_FLAG}, // nach '9' (0x39) folgt ':' (0x3a)
{"0:2", Menu_GPS_Display_FLAG},
{"0:3", Menu_GPS_Display_FLAG},
{NULL,NULL}
};
 
 
uint32_t Change_Value(uint32_t val, uint32_t min_val, uint32_t max_val, uint8_t pos, uint8_t fu_index, uint8_t vrepeat);
 
void Displ_AV_Source(uint32_t q);
void Displ_Channels(uint32_t k);
void Displ_Set_Contrast(uint32_t val);
void Displ_Backgr_Light(uint32_t val);
void Displ_U_2Nk(uint32_t u);
void Displ_Off_On(uint32_t val);
void Displ_Language(uint32_t q);
void DISPL_Servo_Steps(uint32_t val);
void Displ_Servo_Min(uint32_t val);
void Displ_Servo_Max(uint32_t val);
void Displ_Servo_Mid(uint32_t val);
void Displ_Format_Int(uint32_t val);
void Displ_sel_Tracking(uint32_t q);
void Displ_track_TX(uint32_t q);
void Displ_Baudrate(uint32_t q);
typedef void (*Displ_Ptr_Fnct)( uint32_t );
Displ_Ptr_Fnct Displ_Fnct[] = {Displ_U_2Nk, Displ_Set_Contrast, Displ_Backgr_Light, Displ_Channels, Displ_AV_Source, \
Displ_Off_On, Displ_Language, DISPL_Servo_Steps, Displ_Servo_Min, Displ_Servo_Max, \
Displ_Servo_Mid, Displ_Format_Int, Displ_sel_Tracking, Displ_track_TX, Displ_Baudrate};
 
 
/**************************************************************/
/* */
/* Steuerung der Menüs */
/* */
/**************************************************************/
 
/************************************************************************************/
/* sucht nach übergebenen String in der Kommandotabelle und springt zum daneben */
/* stehenden Menü-Programm */
/* Parameter: */
/* char *string_pointer :zu suchender String in Kommandotabelle */
/* */
/************************************************************************************/
void Jump_Menu(char *string_pointer)
{
//Stringzeiger;
char *string_pointer_tmp;
unsigned char menu_index = 0;
 
if (strlen(string_pointer) > 0)
{
string_pointer_tmp = strsep(&string_pointer,",");
//Kommando in Tabelle suchen
while(strcasecmp(COMMAND_TABELLE[menu_index].menu_nr,string_pointer_tmp))
{
//Abruch Whileschleife und Unterprogramm verlassen
if (COMMAND_TABELLE[++menu_index].menu_nr == 0);
}
COMMAND_TABELLE[menu_index].fp(); //Kommando ausführen
}
}
 
/************************************************************************************/
/* */
/* Unterprogramm von 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 scroll_max)
{
uint8_t i;
const uint8_t p = 2; // LCD Beginn x-Position
if (scr_idx > 0) scr_idx--; else scr_idx = scroll_max;
for (i = 0; i < LCD_LINES; i++) {
lcdGotoXY(p, i);
lcdPuts(Msg(scr_menu[scr_idx]));
// ab Stringende bis zum Zeilenende löschen; LCD löschen flackert sonst zu sehr
for (int8_t n = LCD_COLS - strlen(Msg(scr_menu[scr_idx])) - p; n > 0; n--)
lcdPutc(' ');
if (scr_idx < scroll_max) scr_idx++; else scr_idx = 0;
}
}
 
/************************************************************************************/
/* */
/* 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 scroll_max, uint8_t scr_idx, char *str)
void Scroll_Menu(scr_menu_t scr_menu, uint8_t scroll_max, uint8_t scr_idx)
{ uint8_t l;
uint8_t end = 1; // false
 
// pmenu[1] == '\0' entspricht <wenn Hauptmenue>, da jetzt nur noch Servo x für Scrollemenue (rev,min,max,mid)
if ((pmenu[1] == '\0') && ((tracking == TRACKING_RSSI) || (tracking == TRACKING_GPS) || (tracking == TRACKING_MKCOCKPIT))) {
++scroll_max;
if (tracking == TRACKING_RSSI) scr_menu[scroll_max] = MSG_TRACK_SERVO_HYTERESE;
if (tracking == TRACKING_GPS) {
scr_menu[scroll_max] = MSG_TRACK_TX_OSD_DATA;
++scroll_max; // zusätzliche Anzeige zu GPS
}
if (tracking == TRACKING_MKCOCKPIT) scr_menu[scroll_max] = MSG_COM;
}
lcdClear();
lcdGotoXY(0, 1);
lcdPutc(MARKER_SELECT); // '>>'
Displ_Scroll_Menu(scr_menu, scr_idx, scroll_max);
// bis Menueeingabe bestätigt oder zum vorherigen Menue
while( !Get_Key_Short( 1<<SW_ENTER ) && end)
{
// >> 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 = scroll_max;
Displ_Scroll_Menu(scr_menu, scr_idx, scroll_max);
}
// >> Menueauswahl nach unten
if( Get_Key_Press( 1<<SW_MINUS ) || Get_Key_Rpt( 1<<SW_MINUS ))
{
if (scr_idx < scroll_max) scr_idx++; else scr_idx = 0;
Displ_Scroll_Menu(scr_menu, scr_idx, scroll_max);
}
// direkt in das Hauptprogramm
if (Get_Key_Long( 1<<SW_ENTER )) end = 0;
Tasks_unvisible();
// falls Akku leer ==> Menü verlassen und Anzeige __ACCU_LOW
U_Messen_cmp(DISABLE_BTIMER);
if (bat_low == 0) end = 0;
}
lcdClear();
if (end) {
l = strlen(pmenu);
if (scr_idx > 0) {
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 + 1] ='\0';
Beep(BEEPENTER);
}
else {
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
if (l == 0) Displ_Main_Disp();
}
}
else {
pmenu[0] = '\0';
Displ_Main_Disp();
}
}
 
/************************************************************************************/
/* */
/* Abfrage Short- oder Long-Enter */
/* verbleibt in Abfrage bis Enter betätigt; Rückgabe => Short-Enter True/False */
/* */
/************************************************************************************/
uint8_t Short_Enter(void)
{ uint8_t ShortEnter = 1;
 
// bis Enter
while( !Get_Key_Short( 1<<SW_ENTER ) && (ShortEnter > 0)) {
// direkt in das Hauptprogramm
if (Get_Key_Long( 1<<SW_ENTER )) {
ShortEnter = 0;
pmenu[0] ='\0';
}
Tasks_unvisible();
// falls Akku leer ==> Menü verlassen und Anzeige __ACCU_LOW
U_Messen_cmp(DISABLE_BTIMER);
if (bat_low == 0) pmenu[0] ='\0';
}
lcdClear();
if (ShortEnter) Beep(BEEPENTER);
if (pmenu[0] == '\0') Displ_Main_Disp();
return(ShortEnter);
}
 
/************************************************************************************/
/* */
/* Ändern der Werte mit Tasten +,- und Anzeige */
/* z.B. für U-Offset, Batterie leer Eingabe ... */
/* */
/* Parameter: */
/* uint32_t val :zu ändernter Wert */
/* uint32_t min_val, max_val :min, max Grenze Wert ändern darf */
/* uint8_t posX, posY :Darstellung Wert xPos, YPos auf LCD */
/* uint8_t fu_index :Index um Adresse der Display Funktion aufzurufen */
/* 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 */
/* uint32_t Change_Value_plmi(...) :Rückgabe geänderter Wert */
/* */
/************************************************************************************/
uint32_t Change_Value_plmi(uint32_t val, uint32_t min_val, uint32_t max_val, uint8_t posX, uint8_t posY, \
uint8_t fu_index, 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[fu_index](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[fu_index](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: */
/* uint32_t val :zu ändernter Wert */
/* uint32_t min_val, max_val :min, max Grenze Wert ändern darf */
/* uint8_t pos :Darstellung Wert xPos auf LCD */
/* uint8_t fu_index :Index um Adresse der Display Funktion aufzurufen */
/* uint8_t vrepeat :beschleunigte Repeat-Funktion aus/ein */
/* uint32_t Change_Value(...) :Rückgabe geänderter Wert */
/* */
/************************************************************************************/
uint32_t Change_Value(uint32_t val, uint32_t min_val, uint32_t max_val, uint8_t pos, uint8_t fu_index, \
uint8_t vrepeat)
{ uint8_t l;
 
lcdGotoXY(pos, ZLE_VAL); // Position Wert
Displ_Fnct[fu_index](val); // initiale Wertdarstellung, je nach Menüpunkt
// bis Menueeingabe bestätigt oder zum vorherigen Menue
while( !Get_Key_Short( 1<<SW_ENTER ) && (strlen(pmenu) > 0))
{
val = Change_Value_plmi(val, min_val, max_val, pos, ZLE_VAL, fu_index, 0, vrepeat);
// direkt in das Hauptprogramm zurück
if (Get_Key_Long( 1<<SW_ENTER )) pmenu[0] ='\0';
Tasks_unvisible();
// falls Akku leer ==> Menü verlassen und Anzeige MSG_ACCU_LOW
U_Messen_cmp(DISABLE_BTIMER);
if (bat_low == 0) pmenu[0] ='\0';
}
lcdClear();
l = strlen(pmenu);
if (l > 0) {
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();
return(val);
}
 
 
 
/**************************************************************/
/* */
/* LCD-Darstellungen der Menüs */
/* Zur Unterstützung der Auswahl werden einige Einstellungen */
/* sofort ausgeführt. Z.B.: Kontrast, Servo-Endausschlag */
/* */
/**************************************************************/
 
/************************************************************************************/
/* stellt eine String mittig auf Display dar */
/* Parameter: */
/* char *str : darzustellende Zeichenkette */
/* uint8_t zle : Display-Zeile */
/* */
/************************************************************************************/
void Disp_Str_mid(char *str, uint8_t zle)
{ int8_t x;
 
lcdGotoXY(0,zle);
for (x = 0; x < LCD_COLS; x++) lcdPutc(' '); // Zeile löschen
x = (LCD_COLS - strlen(str))/2; // Array-String mittig schreiben
lcdGotoXY(x,zle);
lcdPuts(str);
}
 
/************************************************************************************/
/* zeigt Menü- * Überschrift * auf erste Zeile mittig auf Display an */
/* Parameter: */
/* uint8_t message : index (MSG_) der darzustellenden Zeichenkette */
/* */
/************************************************************************************/
void Disp_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));
for ( uint8_t i=0; i<=30;i++)
_delay_ms(100);
lcdClear();
}
 
/************************************************************************************/
/* zeigt auszuwählenden/-gewählten Kanal und Frequenz auf Display an */
/* Parameter: */
/* uint32_t k :Index anzuzeigender Wert = Kanal + 0x30 als Char, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Channels(uint32_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: */
/* uint32_t q :Index anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_AV_Source(uint32_t q)
{ uint8_t av_src_table[] = {MSG_AV1, MSG_AV2, MSG_DIVERSITY};
 
Disp_Str_mid(Msg(av_src_table[q]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt Tracking-Varianten zur Auswahl auf Display an */
/* Parameter: */
/* uint32_t q :Index anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_sel_Tracking(uint32_t q)
{ uint8_t track_sel_table[] = {MSG_OFF, MSG_TRACK_RSSI, MSG_TRACK_GPS, MSG_TRACK_MKCOCKPIT};
 
Disp_Str_mid(Msg(track_sel_table[q]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt Senden der OSD-Daten Anforderung zur Auswahl auf Display an */
/* Parameter: */
/* uint32_t q :Index anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_track_TX(uint32_t q)
{ uint8_t track_TX_table[] = {MSG_OFF, MSG_TRACK_TX_ON};
 
Disp_Str_mid(Msg(track_TX_table[q]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt einen max. 3-stelligen Integerwert auf Display an */
/* Parameter: */
/* uint32_t val :anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Format_Int(uint32_t val)
{ char s[4];
if (val < 100) lcdPutc(' ');
if (val < 10) lcdPutc(' ');
utoa(val ,s ,10 );
lcdPuts(s);
}
 
/************************************************************************************/
/* zeigt den Kontrastwert auf Display an mit sofortiger Änderung */
/* Parameter: */
/* uint32_t val :anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Set_Contrast(uint32_t val)
{
Displ_Format_Int(val);
lcdContrast(dogm_vers, val);
}
 
/************************************************************************************/
/* zeigt die Zeit zur Abschaltung der LCD-Hintergrundbeleuchtung an */
/* Parameter: */
/* uint32_t val :anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Backgr_Light(uint32_t val)
{ char str[5];
uint8_t l;
l = strlen(Msg(MSG_LIGHT)); // etwas Aufwand um Zeilenende sauber zu löschen
switch(val) {
case BACKGR_LIGHT_MIN : l += strlen(Msg(MSG_LIGHT_OFF));
lcdPuts(Msg(MSG_LIGHT_OFF));
break;
case BACKGR_LIGHT_MAX : l += strlen(Msg(MSG_LIGHT_ON));
lcdPuts(Msg(MSG_LIGHT_ON));
break;
default : itoa (val * 10, str, 10);
lcdPutc(' ');
lcdPuts(str);
lcdPuts(Msg(MSG_SEC));
l += 1 + strlen(str) + strlen(Msg(MSG_SEC));
}
l = LCD_COLS - l;
for (uint8_t x = 0; x < l; x++) lcdPutc(' '); // Zeilenende löschen
}
 
/************************************************************************************/
/* zeigt ein oder aus zur Auswahl auf Display an */
/* Parameter: */
/* uint32_t val :0 = aus oder 1 = ein, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Off_On(uint32_t val)
{
if (val == 0) lcdPuts(Msg(MSG_OFF)); else lcdPuts(Msg(MSG_ON));
}
 
/************************************************************************************/
/* zeigt Servoschritte zur Auswahl auf Display an */
/* Parameter: */
/* uint32_t val :0 = 255 oder 1 = 1023, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void DISPL_Servo_Steps(uint32_t val)
{ uint8_t servo_step_table[] = {MSG_STEPS_255, MSG_STEPS_1023};
 
Disp_Str_mid(Msg(servo_step_table[val]), ZLE_VAL);
}
 
/************************************************************************************/
/* zeigt Servo-Anschlagposition links auf Display an */
/* mit sofortiger Wirkung auf Servo */
/* Parameter: */
/* uint32_t val :anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Min(uint32_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: */
/* uint32_t val :anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Max(uint32_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: */
/* uint32_t val :anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Servo_Mid(uint32_t val)
{ char s[6];
int16_t mid_val;
mid_val = val - ServoSteps()/2;
if (abs(mid_val) < 10) lcdPutc(' '); // einstellige Ausgabe eins nach rechts rücken
if (mid_val > -1) lcdPutc(' '); // ohne Vorzeichen Ausgabe eins nach rechts rücken
itoa(mid_val ,s ,10 );
lcdPuts(s);
lcdPutc(' '); // nach Werten > 99 letzte 0 wieder löschen
servoSet_mid(servo_nr, val); // Wert setzen damit nachfolgend die
servoSetPosition(servo_nr, ServoSteps()/2);// Änderung direkt am Servo sichtbar ist
}
 
/************************************************************************************/
/* zeigt Baudrate für COM bei MKCockpit zur Auswahl auf Display an */
/* Parameter: */
/* uint32_t q :Index anzuzeigender Wert, */
/* unint32_t wegen Vereinheitlichung f. Funktionsaufrauf */
/* */
/************************************************************************************/
void Displ_Baudrate(uint32_t q)
{ char str[7];
 
ltoa(baud[q], str, 10);
Disp_Str_mid(str, ZLE_VAL);
}
 
/************************************************************************************/
/* 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 Displ_Main_Disp(void)
{ char marker;
 
lcdClear();
if (bat_low != 0) {
lcdClear();
Displ_Channels(channel);
lcdGotoXY(LCD_COLS - 1, 0);
lcdPuts("V\n1\n2");
if (av_source < DIVERSITY)
marker = MARKER_AV; // wird nur bei gesetzten Diversity überschrieben
else
marker = MARKER_RSSI; // nur Schönheit, damit man sofort Umschaltung sieht
Displ_AV_Mark(sw_avx, marker);
Displ_VBat(); // muss zuletzt stehen
}
else {
Disp_Str_mid(Msg(MSG_ACCU_LOW), 0);
}
}
 
 
 
/**************************************************************/
/* */
/* Menüs */
/* */
/**************************************************************/
 
/**************************/
/* */
/* Haupmenü */
/* */
/**************************/
void Menu_Main(void)
{ scr_menu_t scr_main_menu = {MSG_RETURN, MSG_AV_SOURCE, MSG_RX_CHANNEL, MSG_RSSI_CALIBR, MSG_LANGUAGE, MSG_SERVO_CALIBR, \
MSG_LCD , MSG_BATTERY, MSG_TRACKING, 0, MSG_GPS_DISPLAY};
 
strcpy(pmenu, "0");
Scroll_Menu(scr_main_menu, SCROLL_MAIN_MAX, m_pkt); // pmenu global
Jump_Menu(pmenu); //gewähltes Untermenü anspringen oder nur Return
}
 
/**************************/
/* */
/* AV-Quelle */
/* */
/**************************/
void Menu_AV_Source(void)
{ char marker;
uint32_t eep_val;
 
Disp_Title(MSG_AV_SOURCE);
eep_val = Change_Value(av_source, AV_SOURCE_MIN, AV_SOURCE_MAX, 3, IDX_DISPL_AV_SOURCE, C_REPEAT); // pmenu global
if (eep_val != av_source) {
cli();
av_source = eep_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 im Hauptdisplay nicht aktuallisiert
if (av_source < DIVERSITY)
marker = MARKER_AV; // wird nur bei gesetzten Diversity überschrieben
else
marker = MARKER_RSSI; // nur Schönheit, damit man sofort Umschaltung sieht
Displ_AV_Mark(sw_avx, marker);// da erst jetzt die Variable für main_display geändert ist!
}
sei();
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Kanal */
/* */
/**************************/
void Menu_RX_Channel(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_RX_CHANNEL);
eep_val = Change_Value(channel, CHANNEL_MIN, CHANNEL_MAX, 3, IDX_DISPL_CHANNEL, C_REPEAT); // pmenu global
if ((eep_val != channel) || (eep_val != ch_stored)) { // oder Channel wurde im Hauptdisplay geändert
channel = eep_val;
ch_stored = eep_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[3] = {MSG_RETURN, MSG_RSSI_MIN, MSG_RSSI_MAX};
 
Scroll_Menu(scr_sub_menu, 2, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_RSSI_min(void)
{ char str[20];
 
Disp_Title(MSG_RSSI_MIN);
strcpy(str, Msg(MSG_TX));
strcat(str, Msg(MSG_TX_OFF));
Disp_Str_mid(str, 1);
Disp_Str_mid(Msg(MSG_CONTINUE), 2);
if (Short_Enter()) { // pmenu global
RSSI_Min_Calibrate(pudbm);
pmenu[0] = '\0'; // zur Hauptdarstellung
Displ_Main_Disp(); // da erst jetzt die Variable für main_display geändert ist!
}
else
Jump_Menu(pmenu);
}
 
void Menu_RSSI_max(void)
{ char str[20];
 
Disp_Title(MSG_RSSI_MAX);
strcpy(str, Msg(MSG_TX));
strcat(str, Msg(MSG_TX_ON));
Disp_Str_mid(str, 1);
Disp_Str_mid(Msg(MSG_CONTINUE), 2);
if (Short_Enter()) { // pmenu global
RSSI_Max_Calibrate(pudbm);
pmenu[0] = '\0'; // zur Hauptdarstellung
Displ_Main_Disp(); // da erst jetzt die Variable für main_display geändert ist!
}
else
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Sprache */
/* */
/**************************/
void Displ_Language(uint32_t i)
{ uint8_t lanuage_table[3] = {MSG_GERMAN, MSG_ENGLISH, MSG_FRENCH};
 
Disp_Str_mid(Msg(lanuage_table[i]), ZLE_VAL);
}
 
void Menu_Language(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_LANGUAGE);
eep_val = Change_Value(language, GERMAN, LAST_LANG, 3, IDX_DISPL_LANGUAGE, C_REPEAT); // pmenu global
language = eeprom_read_byte(&ep_language); // damit bei Erstinbetriebnahme Sprache gespeichert wird NO_LANGUAGE
if (eep_val != language) {
language = eep_val;
eeprom_write_byte(&ep_language, language);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Servos */
/* */
/**************************/
void Menu_Servo_Calibr(void)
{ uint8_t scr_sub_menu[4] = {MSG_RETURN, MSG_SERVO_STEPS, MSG_SERVO1, MSG_SERVO2};
 
Scroll_Menu(scr_sub_menu, 3, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
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 *= 4;
}
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)
{ uint32_t eep_val;
 
Disp_Title(MSG_SERVO_STEPS);
lcdGotoXY(8, ZLE_VAL);
eep_val = Change_Value(sIdxSteps, STEPS_255, STEPS_1023, 5, IDX_DISPL_SERVO_STEPS, C_REPEAT); // pmenu global
if (eep_val != sIdxSteps) {
cli();
sIdxSteps = eep_val;
eeprom_write_byte(&ep_sIdxSteps, sIdxSteps);
Servo_NewValues(sIdxSteps); // hier ist der neue Index anzugeben!
servoInit();
sei();
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Servo1(void)
{ uint8_t scr_servo_menu[5] = {MSG_RETURN, MSG_SERVO1_REVERSE, MSG_CALIB1_LEFT, MSG_CALIB1_RIGHT, MSG_CALIB1_MIDDLE};
Scroll_Menu(scr_servo_menu, SCROLL_SERVO_MAX, m_pkt); // pmenu global
servo_nr = 0;
Jump_Menu(pmenu);
}
 
void Menu_Servo2(void)
{ uint8_t scr_servo_menu[5] = {MSG_RETURN, MSG_SERVO2_REVERSE, MSG_CALIB2_LEFT, MSG_CALIB2_RIGHT, MSG_CALIB2_MIDDLE};
Scroll_Menu(scr_servo_menu, SCROLL_SERVO_MAX, m_pkt); // pmenu global
servo_nr = 1;
Jump_Menu(pmenu);
}
 
uint8_t Servo_tmp_on(void)
{ uint8_t tmp_tracking = tracking;
 
tracking = 0; // Servopositionierung durch tracking abschalten
if (tracking == TRACKING_MIN) servoInit(); // falls aus, Servos einschalten
lcdGotoXY(0, 0); // lcd Cursor vorpositionieren
return(tmp_tracking);
}
 
void Servo_tmp_Original(uint8_t track)
{ uint16_t steps;
 
if (servo_nr == SERVO_PAN)
steps = ServoSteps()/2; // PAN auf Mittelstellung
else
steps = 0; // Tilt auf Endausschlag
servoSetPosition(servo_nr, steps); // Bei PAN auf ServoSteps/2 und bei Tilt auf 0 oder ServoSteps NICHT!!! reverse beachten
tracking = track; // ursprünglicher Wert Tracking aus, RSSI oder GPS
if (tracking == TRACKING_MIN) {
for (uint8_t i = 0; i < 2; i++)
_delay_ms(200); // sonst werden Impulse bereits vor erreichen der Servo-default-Stellung abgeschaltet
servoOff(); // Servos sind nur zum Tracking oder bei Kalibrierung eingeschaltet
}
Jump_Menu(pmenu);
}
 
void Menu_Servo_rev(void)
{ uint32_t eep_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on();
eep_val = Change_Value(servo[servo_nr].rev, 0, 1, 6, IDX_DISPL_OFF_ON, C_REPEAT); // pmenu global; reverse gibt es nur 0=off, 1=on
if (eep_val != servo[servo_nr].rev) {
servo[servo_nr].rev = eep_val;
servoSet_rev(servo_nr, eep_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)
{
Disp_Title(MSG_SERVO1_REVERSE);
Menu_Servo_rev();
}
 
void Menu_Servo2_rev(void)
{
Disp_Title(MSG_SERVO2_REVERSE);
Menu_Servo_rev();
}
 
void Menu_Servo_left(void)
{ uint32_t eep_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on();
servoSetPosition(servo_nr, ServoSteps()); // Linkssanschlag um Kalibrierung am Servo zu sehen
eep_val = Change_Value(servo[servo_nr].max, servo_limit[sIdxSteps][LEFT].min, servo_limit[sIdxSteps][LEFT].max, 6, IDX_DISPL_SERVO_MAX, V_REPEAT); // pmenu global
if (eep_val != servo[servo_nr].max) {
servo[servo_nr].max = eep_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)
{
Disp_Title(MSG_CALIB1_LEFT);
Menu_Servo_left();
}
 
void Menu_Servo2_left(void)
{
Disp_Title(MSG_CALIB2_LEFT);
Menu_Servo_left();
}
 
void Menu_Servo_right(void)
{ uint32_t eep_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on();
servoSetPosition(servo_nr, 0); // Rechtsanschlag um Kalibrierung am Servo zu sehen
eep_val = Change_Value(servo[servo_nr].min, servo_limit[sIdxSteps][RIGHT].min, servo_limit[sIdxSteps][RIGHT].max, 6, IDX_DISPL_SERVO_MIN, V_REPEAT); // pmenu global
if (eep_val != servo[servo_nr].min) {
servo[servo_nr].min = eep_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)
{
Disp_Title(MSG_CALIB1_RIGHT);
Menu_Servo_right();
}
 
void Menu_Servo2_right(void)
{
Disp_Title(MSG_CALIB2_RIGHT);
Menu_Servo_right();
}
 
void Menu_Servo_middle(void)
{ uint32_t eep_val;
uint8_t tmp_tracking;
 
tmp_tracking = Servo_tmp_on();
servoSetPosition(servo_nr, ServoSteps()/2); // Mittelposition um Kalibrierung am Servo zu sehen
eep_val = Change_Value(servo[servo_nr].mid, servo_limit[sIdxSteps][MIDDLE].min, servo_limit[sIdxSteps][MIDDLE].max, 6, IDX_DISPL_SERVO_MID, V_REPEAT); // global
if (eep_val != servo[servo_nr].mid) {
servo[servo_nr].mid = eep_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)
{
Disp_Title(MSG_CALIB1_MIDDLE);
Menu_Servo_middle();
}
 
void Menu_Servo2_middle(void)
{
Disp_Title(MSG_CALIB2_MIDDLE);
Menu_Servo_middle();
}
 
/**************************/
/* */
/* LCD */
/* */
/**************************/
void Menu_lcd(void)
{ uint8_t scr_sub_menu[3] = {MSG_RETURN, MSG_CONTRAST, MSG_BACKGR_LIGHT};
 
Scroll_Menu(scr_sub_menu, 2, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_lcd_Contrast(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_LCD);
lcdGotoXY(2, ZLE_VAL);
lcdPuts(Msg(MSG_CONTRAST));
lcdPuts(": ");
eep_val = Change_Value(contrast, CONTRAST_MIN, CONTRAST_MAX, 11, IDX_DISPL_SET_CONTRAST, C_REPEAT); // pmenu global
if (eep_val != contrast) {
contrast = eep_val;
eeprom_write_byte(&ep_contrast, contrast);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_lcd_Backgr_Light(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_BACKGR_LIGHT);
lcdGotoXY(0, ZLE_VAL);
lcdPuts(Msg(MSG_LIGHT));
eep_val = Change_Value(light_time, BACKGR_LIGHT_MIN, BACKGR_LIGHT_MAX, 6, IDX_DISPL_BACKGR_LIGHT, V_REPEAT); // pmenu global
if (eep_val != light_time) {
light_time = eep_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[3] = {MSG_RETURN, MSG_U_SETUP, MSG_U_OFFSET};
 
Scroll_Menu(scr_sub_menu, 2, m_pkt); // pmenu global
Jump_Menu(pmenu);
}
 
void Menu_Low_U_Setup(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_U_MIN);
eep_val = Change_Value(u_min, U_MIN_MIN, U_MIN_MAX, 4, IDX_DISPL_U_2Nk, V_REPEAT); // pmenu global
if (eep_val != u_min) {
u_min = eep_val;
eeprom_write_dword(&ep_u_min, u_min);
hyst_u_min = u_min;
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_U_Offset(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_U_OFFSET);
eep_val = Change_Value(u_offset, U_OFFSET_MIN, U_OFFSET_MAX, 4, IDX_DISPL_U_2Nk, V_REPEAT); // pmenu global
if (eep_val != u_offset) {
u_offset = eep_val;
eeprom_write_byte(&ep_u_offset, u_offset);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
/**************************/
/* */
/* Antennennachführung */
/* */
/**************************/
void Menu_Tracking_Ant(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_TRACKING);
eep_val = Change_Value(tracking, TRACKING_MIN, TRACKING_MAX, 3, IDX_DISPL_SEL_TRACKING, C_REPEAT); // pmenu global
if (eep_val != tracking) {
cli();
tracking = eep_val;
sei();
eeprom_write_byte(&ep_tracking, tracking);
Double_Beep(DBEEPWR, DBEEPWRP);
USART_RX_Mode(tracking); // Unterschied Datenempfang GPS/MKCockpit
coldstart = 1;
servoSetDefaultPos(); // Ausgangsstellung beider Servos
if (tracking > TRACKING_MIN)
servoInit();
else {
for (uint8_t i = 0; i < 2; i++)
_delay_ms(200); // sonst wird Impuls bereits vor erreichen der Mittelstellung abgeschaltet
servoOff();
}
USART_Init_Baudrate();
}
Jump_Menu(pmenu);
}
 
/**************************/
/* Optionen */
/* Antennennachführung */
/* */
/**************************/
void Menu_Tracking_HYST(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_HYSTERESE);
eep_val = Change_Value(track_hyst, TRACKING_HYST_MIN, TRACKING_HYST_MAX, 7, IDX_DISPL_FORMAT_INT, V_REPEAT); // pmenu gloabal
if (eep_val != track_hyst) {
track_hyst = eep_val;
eeprom_write_byte(&ep_track_hyst, track_hyst);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Tracking_TXOSD(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_TRACK_TX_OSD_DATA);
eep_val = Change_Value(track_tx, 0, 1, 3, IDX_DISPL_TRACK_TX, C_REPEAT); // pmenu global; Senden gibt es nur 0=off, 1=on
if (eep_val != track_tx) {
track_tx = eep_val;
eeprom_write_byte(&ep_track_tx, track_tx);
Double_Beep(DBEEPWR, DBEEPWRP);
}
Jump_Menu(pmenu);
}
 
void Menu_Baudrate(void)
{ uint32_t eep_val;
 
Disp_Title(MSG_BAUDRATE);
eep_val = Change_Value(baudrate, BAUDRATE_MIN, BAUDRATE_MAX, 3, IDX_DISPL_BAUDRATE, C_REPEAT); // pmenu global; Senden gibt es nur 0=off, 1=on
if (eep_val != baudrate) {
baudrate = eep_val;
eeprom_write_byte(&ep_baudrate, baudrate);
Double_Beep(DBEEPWR, DBEEPWRP);
USART_Init(baud[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: Menu_Baudrate();
}
}
 
/**************************/
/* */
/* Anzeige GPS */
/* */
/**************************/
void Menu_GPS_Display(void)
{ uint8_t scr_sub_menu[4] = {MSG_RETURN, MSG_GPS_CALCULATE, MSG_GPS_CURRENT, MSG_GPS_HOME};
 
Scroll_Menu(scr_sub_menu, 3, 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
m_pkt = gps_display;
gps_disp_clear = 1; // damit Text "...keine Daten empf..." nach Datenempfang gelöscht wird
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);
}
/C-OSD/trunk/tags/v1.00/menue.h
0,0 → 1,108
 
/****************************************************************/
/* */
/* 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_
 
/* Indexwerte für Funktions-Pointer in menue.c
typedef void (*Displ_Ptr_Fnct)( uint32_t );
Displ_Ptr_Fnct Displ_Fnct[] = {Displ_U_2Nk, Displ_Set_Contrast, Displ_Backgr_Light, Displ_Channels, Displ_AV_Source, \
Displ_Off_On, Displ_Language, DISPL_Servo_Steps, Displ_Servo_Min, Displ_Servo_Max, \
Displ_Servo_Mid, Displ_Format_Int, Displ_sel_Tracking, Displ_track_TX, Displ_Baudrate};
*/
#define IDX_DISPL_U_2Nk 0
#define IDX_DISPL_SET_CONTRAST 1
#define IDX_DISPL_BACKGR_LIGHT 2
#define IDX_DISPL_CHANNEL 3
#define IDX_DISPL_AV_SOURCE 4
#define IDX_DISPL_OFF_ON 5
#define IDX_DISPL_LANGUAGE 6
#define IDX_DISPL_SERVO_STEPS 7
#define IDX_DISPL_SERVO_MIN 8 // für Servo linke maximale Position
#define IDX_DISPL_SERVO_MAX 9 // für Servo rechte maximale Position
#define IDX_DISPL_SERVO_MID 10
#define IDX_DISPL_FORMAT_INT 11
#define IDX_DISPL_SEL_TRACKING 12
#define IDX_DISPL_TRACK_TX 13
#define IDX_DISPL_BAUDRATE 14
 
#define SCROLL_MAIN_MAX 8 // index array Scroll_Menu scr_main_menu[] = {....} Anzahl-1, da Beginn bei 0
#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
 
#define C_REPEAT 0 // konstante repeat Geschwindigkeit
#define V_REPEAT 1 // sich ändernte repeat Geschwindigkeit
 
typedef struct
{
char* menu_nr; // Stringzeiger auf Befehlsnamen
void(*fp)(void); // Zeiger auf auszuführende Funktion
} COMMAND_STRUCTUR;
unsigned char jump_menu (char *);
 
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_max (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_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_Tool (void);
void Menu_Tracking_Ant (void);
void Menu_Tracking_Option (void);
void Menu_GPS_Display (void);
void Menu_GPS_Display_FLAG (void);
 
/*char amenu[5] = {"0"};
char* pmenu = amenu;*/
char pmenu[5] = {"0"};
uint8_t ch_stored; // Flag zur Speicherung, wenn Wert im Hauptdisplay geändert
uint8_t coldstart;
 
void Displ_Main_Disp(void);
void Displ_AV_Mark(uint8_t p, char marker);
void Disp_Str_mid(char *str, uint8_t zle);
 
#define RIGHT 0
#define LEFT 1
#define MIDDLE 2
 
typedef struct
{
uint16_t min;
uint16_t max;
} servo_limit_t;
 
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}}};
 
#endif /* _MENUE_H */
/C-OSD/trunk/tags/v1.00/messages.c
0,0 → 1,218
 
/****************************************************************/
/* */
/* 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"
 
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_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_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_OFF),
MSG_TABLE(GERMAN, MSG_ON),
MSG_TABLE(GERMAN, MSG_TRACKING),
MSG_TABLE(GERMAN, MSG_TRACK_GPS),
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_NO_DATA),
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_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_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_OFF),
MSG_TABLE(ENGLISH, MSG_ON),
MSG_TABLE(ENGLISH, MSG_TRACKING),
MSG_TABLE(ENGLISH, MSG_TRACK_GPS),
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_NO_DATA),
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_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_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_OFF),
MSG_TABLE(FRENCH, MSG_ON),
MSG_TABLE(FRENCH, MSG_TRACKING),
MSG_TABLE(FRENCH, MSG_TRACK_GPS),
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_NO_DATA),
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_STEPS_255),
MSG_TABLE(INTERNAT, MSG_STEPS_1023),
MSG_TABLE(INTERNAT, MSG_SERVO1),
MSG_TABLE(INTERNAT, MSG_SERVO2),
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);
}
/C-OSD/trunk/tags/v1.00/messages.h
0,0 → 1,484
 
/****************************************************************/
/* */
/* 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_STEPS_255 "255"
#define INTERNAT_STEPS_1023 "1023"
#define INTERNAT_SERVO1 "Servo 1"
#define INTERNAT_SERVO2 "Servo 2"
#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_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_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_OFF "aus"
#define GERMAN_ON "ein"
#define GERMAN_TRACKING "Antenne nachf."
#define GERMAN_TRACK_GPS "GPS mit wi232"
#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_NO_DATA " Noch\n keine Daten\n empfangen!"
#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_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_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_OFF "off"
#define ENGLISH_ON "on "
#define ENGLISH_TRACKING "Tracking"
#define ENGLISH_TRACK_GPS "GPS with wi232"
#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_NO_DATA " Not yet\n Data\n received!"
#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_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_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_OFF "OFF"
#define FRENCH_ON "ON "
#define FRENCH_TRACKING "Tracking"
#define FRENCH_TRACK_GPS "GPS with wi232"
#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_NO_DATA " Aucune donn""\x82""e\n re""\x87""ue!"
#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 3
#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_TX 8
#define MSG_TX_OFF 9
#define MSG_TX_ON 10
#define MSG_CONTINUE 11
#define MSG_CONTRAST 12
#define MSG_BACKGR_LIGHT 13
#define MSG_LIGHT 14
#define MSG_LIGHT_OFF 15
#define MSG_LIGHT_ON 16
#define MSG_SEC 17
#define MSG_BATTERY 18
#define MSG_U_MIN 19
#define MSG_U_SETUP 20
#define MSG_U_OFFSET 21
#define MSG_CALIBRATION 22
#define MSG_RUNNING 23
#define MSG_ERROR 24
#define MSG_TX_NOT 25
#define MSG_ACCU_LOW 26
#define MSG_SERVO_CALIBR 27
#define MSG_SERVO_STEPS 28
#define MSG_SERVO1_REVERSE 29
#define MSG_CALIB1_LEFT 30
#define MSG_CALIB1_RIGHT 31
#define MSG_CALIB1_MIDDLE 32
#define MSG_SERVO2_REVERSE 33
#define MSG_CALIB2_LEFT 34
#define MSG_CALIB2_RIGHT 35
#define MSG_CALIB2_MIDDLE 36
#define MSG_OFF 37
#define MSG_ON 38
#define MSG_TRACKING 39
#define MSG_TRACK_GPS 40
#define MSG_TRACK_TX_OSD_DATA 41
#define MSG_HYSTERESE 42
#define MSG_TRACK_TX_ON 43
#define MSG_GPS_DISPLAY 44
#define MSG_GPS_CALCULATE 45
#define MSG_GPS_CURRENT 46
#define MSG_GPS_HOME 47
#define MSG_GPS_NO_DATA 48
#define MSG_COM 49
#define MSG_KOMMA 50
#define MSG_UHW33V 51
#define LAST_NAT_MESSAGE 51
 
/* 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_STEPS_255 6 + LAST_NAT_MESSAGE + 1
#define MSG_STEPS_1023 7 + LAST_NAT_MESSAGE + 1
#define MSG_SERVO1 8 + LAST_NAT_MESSAGE + 1
#define MSG_SERVO2 9 + LAST_NAT_MESSAGE + 1
#define MSG_TRACK_RSSI 10 + LAST_NAT_MESSAGE + 1
#define MSG_TRACK_MKCOCKPIT 11 + LAST_NAT_MESSAGE + 1
#define MSG_TRACK_SERVO_HYTERESE 12 + LAST_NAT_MESSAGE + 1
#define MSG_BAUDRATE 13 + LAST_NAT_MESSAGE + 1
#define MSG_UHW5V 14 + LAST_NAT_MESSAGE + 1
#define MSG_VERSION1 15 + LAST_NAT_MESSAGE + 1
#define MSG_VERSION2 16 + LAST_NAT_MESSAGE + 1
#define MESSAGE_LAST_MESSAGE 16
 
#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_STEPS_255, INTERNAT_STEPS_255)
MSG_STRING(INTERNAT, MSG_STEPS_1023, INTERNAT_STEPS_1023)
MSG_STRING(INTERNAT, MSG_SERVO1, INTERNAT_SERVO1)
MSG_STRING(INTERNAT, MSG_SERVO2, INTERNAT_SERVO2)
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_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_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_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_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_NO_DATA, GERMAN_GPS_NO_DATA)
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_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_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_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_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_NO_DATA, ENGLISH_GPS_NO_DATA)
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_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_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_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_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_NO_DATA, FRENCH_GPS_NO_DATA)
MSG_STRING(FRENCH, MSG_COM, FRENCH_COM)
MSG_STRING(FRENCH, MSG_KOMMA, FRENCH_KOMMA)
MSG_STRING(FRENCH, MSG_UHW33V, FRENCH_UHW33V)
 
typedef uint16_t MessageType;
char* Msg(MessageType Message);
 
#endif /* _MESSAGES_H_ */
/C-OSD/trunk/tags/v1.00/ngvideo.c
0,0 → 1,657
/****************************************************************/
/* */
/* 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 <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 "tracking.c"
 
 
/************************************************************************************/
/* 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_dword(&ep_u_min, U_MIN);
eeprom_write_byte(&ep_channel, CHANNEL);
eeprom_write_byte(&ep_av_source, AV_SOURCE);
eeprom_write_byte(&ep_language, NO_LANGUAGE);
eeprom_write_word(&ep_udbm_min, UDBM_MIN);
eeprom_write_word(&ep_udbm_max, UDBM_MAX);
eeprom_write_word(&ep_udbm_korr_1, UDBM_KORR_FA);
eeprom_write_word(&ep_udbm_korr_2, UDBM_KORR_FA);
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_tracking, TRACKING_MIN);
eeprom_write_byte(&ep_track_hyst, TRACKING_HYSTERESE);
eeprom_write_byte(&ep_track_tx, 0);
eeprom_write_byte(&ep_baudrate, BAUDRATE);
sIdxSteps = STEPS_255;
}
else
{
light_time = eeprom_read_byte(&ep_light_time);
u_offset = eeprom_read_byte(&ep_u_offset);
u_min = eeprom_read_dword(&ep_u_min);
channel = eeprom_read_byte(&ep_channel);
av_source = eeprom_read_byte(&ep_av_source);
language = eeprom_read_byte(&ep_language);
udbm_min = eeprom_read_word(&ep_udbm_min);
udbm_max = eeprom_read_word(&ep_udbm_max);
udbm_korr_1 = eeprom_read_word(&ep_udbm_korr_1);
udbm_korr_2 = eeprom_read_word(&ep_udbm_korr_2);
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));
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);
}
dogm_vers = eeprom_read_byte(&ep_dogm_vers);
contrast = eeprom_read_byte(&ep_contrast);
hyst_u_min = u_min;
RSSI_Calc_UdBm(pudbm); // Vergleichstabelle für dBm-Balken berechnen
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);
}
 
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)
USART_Init(baud[baudrate]);
else
USART_Init(baud[6]); //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;
}
 
/************************************************************************************/
/* 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 */
/* */
/************************************************************************************/
uint8_t Set_AV_Source(uint8_t src)
{
switch(src) {
case AV1: CLEAR_INT10; // Interrupt für Sync ausschalten
SET_MUX_0;
break;
case AV2: CLEAR_INT10; // Interrupt für Sync ausschalten
SET_MUX_1;
break;
case DIVERSITY: SET_INT10; // External Interrupt Mask Register ein
SET_MUX_0;
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_time > BACKGR_LIGHT_MIN) && (light_count < light_time)) {
cli();
light_count = 0;
sei();
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
}
 
/* ADC Mehrfachmessung mit Mittelwertbbildung */
uint16_t ADC_Read_Avg( uint8_t channel, uint16_t average )
{
uint32_t result = 0;
for (uint16_t i = 0; i < average; ++i ){
result += ADC_Read( channel );
_delay_ms(1);
}
return (uint16_t)( result / average );
}
 
 
/**************************************************************/
/* */
/* Beeper */
/* */
/**************************************************************/
 
void Beep(uint8_t time)
{
PINB |= (1<<BEEPER);
PINB &= ~(1<<BEEPER);
_delay_ms(time);
PINB |= (1<<BEEPER);
PINB &= ~(1<<BEEPER);
}
 
void Double_Beep(uint8_t time, uint8_t pause)
{
Beep(time);
_delay_ms(pause);
Beep(time);
}
 
/**************************************************************/
/* */
/* U-Batterie */
/* */
/**************************************************************/
 
void Displ_Format_U(uint32_t u, uint8_t nkst)
{ char s[3];
uint16_t d1;
int i;
 
/* vereinfacht Variablenübergabe funktion change_value(uint32_t x),
kein printf, double oder float
siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik */
//nkst für 1 bis 2 Nachkommastellen mitgeben
d1 = u / 100 ;
if (d1 < 10) lcdPutc(' ');
utoa(d1 ,s ,10 );
lcdPuts(s);
lcdPuts(Msg(MSG_KOMMA));
for ( i = 1; i >= 0; i--) // Zahl hat hier immer 2 Nachkommatellen
{
s[i] = (u % 10) + '0'; // modulo für Nachkommastelle gleich als char
u /= 10;
}
s[nkst] = '\0';
lcdPuts(s);
}
 
// uint32_t u, da bei Displ_Fnct[fu_index](val) der größte Wert UBat gleich 32 Bit
void Displ_1Nk(uint32_t u)
{
Displ_Format_U(u, 1);
}
 
void Displ_U_2Nk(uint32_t u)
{
Displ_Format_U(u, 2);
lcdPutc('V');
}
 
// uint8_t beep_timer :Akku-leer-Beeper nur mit Task_0_1()-Intervalle bei Menü-Rücksprung
uint32_t U_Messen_cmp(uint8_t beep_timer)
{ uint32_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 != 0) { // nicht laufend Display neu schreiben
hyst_u_min = u_min + 20; // 200mV Hysterese - beruhigt Anzeige
lcdClear();
lcdPuts(Msg(MSG_ACCU_LOW));
bat_low = 0;
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 = 1; // 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
{ uint32_t ubat;
ubat = U_Messen_cmp(ENABLE_BTIMER);
if (bat_low != 0) { // würde sonst Anzeige Akku leer überschreiben
lcdGotoXY(11, 0);
Displ_1Nk(ubat);
}
}
 
 
/**************************************************************/
/* */
/* RSSI */
/* */
/**************************************************************/
 
/* RSSI Werte Korrekturfaktor berechnen */
uint16_t RSSI_Calc_Korr(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)+0.5; // 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)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
udbm_korr_1 = UDBM_KORR_FA;
u_max = u0;
}
eeprom_write_word(&ep_udbm_korr_1, udbm_korr_1);
eeprom_write_word(&ep_udbm_korr_2, udbm_korr_2);
return(u_max);
}
 
void Displ_Calibr_Aktiv(void)
{
lcdClear();
Disp_Str_mid(Msg(MSG_CALIBRATION),0);
Disp_Str_mid(Msg(MSG_RUNNING),1);
}
 
void Displ_Error_TX(uint8_t message)
{
lcdClear();
Disp_Str_mid(Msg(MSG_ERROR),0);
Disp_Str_mid(Msg(MSG_TX_NOT),1);
Disp_Str_mid(Msg(message), 2);
for ( uint8_t i=0; i<=30;i++)
_delay_ms(100);
}
 
void RSSI_Min_Calibrate(uint16_t *pudbm)
{ uint16_t u0, u1;
 
Displ_Calibr_Aktiv();
u0 = ADC_Read_Avg(RSSI0, 1000); //1000 Wiederholungen mit
u1 = ADC_Read_Avg(RSSI1, 1000); //Mittelwertbildung
// Plausibilitätsprüfung ob Sender ausgeschaltet
if (u0 + u1 > 500) {
udbm_min = RSSI_Calc_Korr(u0, u1); // ist real die größere Spannung, aber der kleinere dbm Wert
eeprom_write_word(&ep_udbm_min, udbm_min);
Double_Beep(DBEEPWR, DBEEPWRP);
RSSI_Calc_UdBm(pudbm);
}
else Displ_Error_TX(MSG_TX_OFF);
}
 
void RSSI_Max_Calibrate(uint16_t *pudbm)
{ uint16_t u0, u1;
 
Displ_Calibr_Aktiv();
u0 = ADC_Read_Avg(RSSI0, 1000); //1000 Wiederholungen mit
u1 = ADC_Read_Avg(RSSI1, 1000); //Mittelwertbildung
// Plausibilitätsprüfung ob Sender in der Nähe eingeschaltet
if (u0 + u1 < 400) {
udbm_max = RSSI_Calc_Korr(u0, u1); // ist real die kleinere Spannung, aber der größere dbm Wert
eeprom_write_word(&ep_udbm_max, udbm_max);
Double_Beep(DBEEPWR, DBEEPWRP);
RSSI_Calc_UdBm(pudbm);
}
else Displ_Error_TX(MSG_TX_ON);
}
 
// Vergleichstabelle für RSSI-Bargraph berechnen, vermeidet laufend gleiche Berechnung
void RSSI_Calc_UdBm(uint16_t *pudbm)
{ uint8_t n;
n = (udbm_min - udbm_max -3)/11; // -3 um Ende dBm Skala sicher zu erreichen
for (uint8_t i = 0; i < 12; i++)
pudbm[i] = (udbm_min - i * n);
}
 
void Displ_RSSI_Bargraph(uint16_t *pudbm, uint16_t uadc)
{ uint8_t i;
 
// Balken zeichnen - udbm
for (i = 0; i < 12; i++)
if (uadc < pudbm[i]) lcdPutc(0); else lcdPutc(' ');
}
 
uint8_t RSSI_Diversity(uint8_t src, uint16_t *pudbm, uint8_t visible)
{ uint16_t u0, u1;
static uint8_t div_flag, ret_div_flag;
char marker;
 
u0 = (ADC_Read(RSSI0) * (uint32_t)udbm_korr_1)/UDBM_KORR_FA;
u1 = (ADC_Read(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)) SET_MUX_0;
}
else {
ret_div_flag = AV2;
if ((vscount0 == 255) && (vscount1 == 255)) SET_MUX_1;
}
}
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
if (vsync0 == 0) {
div_flag = AV1;
}
else {
div_flag = 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 > pudbm[0]) && (u1 > pudbm[0])) marker = ' ';
lcdGotoXY(2, 1);
Displ_RSSI_Bargraph(pudbm, u0);
lcdGotoXY(2, 2);
Displ_RSSI_Bargraph(pudbm, 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 */
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_OLD) ++rx_timeout; // veranlasst bei GPS-Tracking MK Datensatz senden
}
 
/* 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;
else {
vsync0 = 1;
if (vsync1 == 0)
SET_MUX_1;
}
if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
if (sw_avx == AV1) {
SET_MUX_0;
}
else
SET_MUX_1;
}
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;
else {
vsync1 = 1;
if (vsync0 == 0)
SET_MUX_0;
}
if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
if (sw_avx == AV1) {
SET_MUX_0;
}
else
SET_MUX_1;
}
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, pudbm, bat_low);
}
}
 
void Task_0_3(void)
{
if (task_timer0_3) {
cli();
task_timer0_3 = 0;
sei();
sw_avx = RSSI_Diversity(av_source, pudbm, 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();
}
}
 
void Task_0_5(void)
{
lcd_BackgrLight_On(); // muss bei beliebiger Taste sofort eingeschaltet werden
if (task_timer0_5) {
cli();
task_timer0_5 = 0;
sei();
lcd_BackgrLight();
}
}
 
void Tasks_unvisible(void)
{
Task_0_3();
Task_0_4();
Task_0_5();
if (tracking == TRACKING_RSSI) Tracking_RSSI();
}
/C-OSD/trunk/tags/v1.00/ngvideo.h
0,0 → 1,134
 
/****************************************************************/
/* */
/* 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 SETTING_H_
#define SETTING_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'
#define MARKER_SYNC 's'
 
#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 Enter kurz Scroll_Menu() und Select_Menu()
#define DBEEPWR 4 // Beep on geänderte Werte ROM schreiben
#define DBEEPWRP 30 // Beep Pause geänderte 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 ENABLE_BTIMER 1 // damit Intervall Beeper für Akku leer mit TIMER0_1 gesteuert wird
#define DISABLE_BTIMER 0
 
#define GPS_DISP_NONE 0
#define GPS_DISP_CALC 1
#define GPS_DISP_CURRENT 2
#define GPS_DISP_HOME 3
 
#define BAUDRATE 5
#define BAUDRATE_MIN 0
#define BAUDRATE_MAX 6
 
#define POLOLU_CMD 2
 
#define OFF 0
#define ON 1
 
#define EEPROM __attribute__ ((section(".eeprom")))
 
uint32_t baud[8] = {4800, 7200, 9600, 14400, 19200, 38400, 57600};
 
typedef struct {
uint8_t rev;
uint16_t min;
uint16_t max;
uint16_t mid;
} servo_t;
 
/**************************************************************/
/* */
/* EEPROM */
/* */
/**************************************************************/
static uint8_t ep_eep_init EEPROM;
static char ep_version[sizeof(VERSION)] EEPROM;
static uint8_t ep_dogm_vers EEPROM;
static uint8_t ep_contrast EEPROM;
static uint8_t ep_light_time EEPROM;
static uint8_t ep_u_offset EEPROM;
static uint32_t ep_u_min EEPROM;
static uint8_t ep_channel EEPROM;
static uint8_t ep_av_source EEPROM;
static uint8_t ep_language EEPROM;
static uint16_t ep_udbm_min EEPROM;
static uint16_t ep_udbm_max EEPROM;
static uint16_t ep_udbm_korr_1 EEPROM;
static uint16_t ep_udbm_korr_2 EEPROM;
static uint8_t ep_sIdxSteps EEPROM;
static servo_t ep_servo[SERVO_NUM_CHANNELS][sizeof(servo_t)] EEPROM;
static uint8_t ep_tracking EEPROM;
static uint8_t ep_track_hyst EEPROM;
static uint8_t ep_track_tx EEPROM;
static uint8_t ep_baudrate EEPROM;
 
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;
uint32_t u_min = U_MIN;
uint8_t channel = CHANNEL;
uint8_t av_source = AV_SOURCE;
uint8_t language = NO_LANGUAGE;
uint16_t udbm_min = UDBM_MIN;
uint16_t udbm_max = UDBM_MAX;
uint16_t udbm_korr_1 = UDBM_KORR_FA;
uint16_t udbm_korr_2 = UDBM_KORR_FA;
uint32_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 tracking = TRACKING_MIN;
uint8_t track_hyst = TRACKING_HYSTERESE;
uint8_t track_tx = 0;
uint8_t baudrate = BAUDRATE;
uint8_t gps_display = 0;
uint8_t gps_disp_clear;
 
void RSSI_Calc_UdBm(uint16_t *pudbm);
uint8_t Set_AV_Source(uint8_t src);
 
uint16_t udbm[12];
uint16_t* pudbm = udbm;
uint8_t bat_low = 1;
uint8_t sw_avx; // steuert über Set_AV_Source() oder rssi_diversity(av_source) Marker-Position und RX-Umschaltung
 
volatile uint8_t vsync0;
volatile uint8_t vsync1;
volatile uint8_t vscount0;
volatile uint8_t vscount1;
 
uint16_t ADC_Read( uint8_t channel );
void servoSetDefaultPos(void);
void USART_Init_Baudrate(void);
 
#endif /* SETTING_H_ */
/C-OSD/trunk/tags/v1.00/servo.c
0,0 → 1,180
 
/********************************************************************/
/* */
/* 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 */
/* */
/*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];
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}};
 
 
// functions
 
//! initializes software PWM system
// 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(void)
{ 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_PERIODE * 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 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;
ServoChannels[channel].mid_scaled = (float)(ServoChannels[channel].max - ServoChannels[channel].min)/2 + \
(mid - (float)ServoConst[sIdxSteps].steps/2) + 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
// 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 = ((uint32_t)position*2*(float)(ServoChannels[channel].mid_scaled-ServoChannels[channel].min)/\
ServoConst[sIdxSteps].steps)+ServoChannels[channel].min;
else
//bei Position >= Servomittelstellung
pos_scaled = ServoChannels[channel].mid_scaled + (uint32_t)((position - ((float)ServoConst[sIdxSteps].steps/2)) \
* 2 * (float)(ServoChannels[channel].max-ServoChannels[channel].mid_scaled)/ServoConst[sIdxSteps].steps);
// set position
servoSetPositionRaw(channel, pos_scaled);
}
 
//! 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;
}
 
//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;
}
 
/C-OSD/trunk/tags/v1.00/servo.h
0,0 → 1,99
/*********************************************************************/
/* */
/* 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
 
#// functions
 
// initializes servo system
// You must run this to begin servo control
void servoInit(void);
 
// 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);
// 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 ServoSteps(void); // gibt "Konstante" derzeitiger Servoschritte zürück
 
#endif /* SERVO_H */
/C-OSD/trunk/tags/v1.00/tracking.c
0,0 → 1,264
 
/****************************************************************/
/* */
/* 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 "usart.h"
#include "math.h"
#include <stdio.h>
 
#include "servo.h"
 
#define DLEFT 0
#define DRIGHT 1
#define DEG_TO_RAD 0.0174533// degrees to radians = PI / 180
#define RAD_TO_DEG 57.2957795// radians to degrees = 180 / PI
 
 
typedef struct {
double distance;
double bearing;
} geo_t;
 
/**************************************************************/
/* */
/* RSSI Tracking */
/* */
/**************************************************************/
 
void Tracking_RSSI(void)
{ uint16_t u0, u1;
static uint8_t direction;
static uint16_t servo1pos;
u0 = (ADC_Read(RSSI0) * (uint32_t)udbm_korr_1)/UDBM_KORR_FA;
u1 = (ADC_Read(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;
char Sats;
if ((bat_low != 0) && (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)
lcdPutc(1);
else {
Sats = navi_data.SatsInUse; // aktuell empfangene Satellitenanzahl
if (navi_data.SatsInUse > 9)
Sats = 'X'; // Anzeige einstellig, da kein Platz auf Display
else
Sats = navi_data.SatsInUse + '0'; // Umrechnung Char
lcdPutc(Sats);
}
}
else
lcdPutc(' ');
wi232RX = 0;
if (++timer == BLINK_PERIOD) timer = 0;
}
}
 
// Berechnung von Distanz und Winkels aus GPS-Daten home(MK eingeschaltet)
// zur aktuellen Position(nach Motorstart)
geo_t calc_geo(HomePos_t home, GPS_Pos_t pos)
{ double lat1, lon1, lat2, lon2, d1, dlat;
geo_t geo;
lon1 = home.Home_Lon;
lat1 = home.Home_Lat;
lon2 = (double)pos.Longitude / 10000000;
lat2 = (double)pos.Latitude / 10000000;
 
// 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 Meter weiter gerechnet
d1 = 111300 * (double)cos((double)(lat1 + lat2) / 2 * DEG_TO_RAD) * (lon1 - lon2);
dlat = 111300 * (double)(lat1 - lat2);
// returns a value in metres http://www.kompf.de/gps/distcalc.html
geo.bearing = fmod((RAD_TO_DEG * (double)atan2(d1, dlat)) + 180, 360); // +180 besserer Vergleich mit MkCockpit
if (geo.bearing > 360) geo.bearing -= 360; // bekam schon Werte über 400
geo.distance = sqrt(d1 * d1 + dlat * dlat);
return(geo);
}
 
// MK OSD-Daten lesen und verifizieren
uint8_t OSD_Data_valid(void)
{ 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
// GPS-Daten nicht zu alt und ok.
if ((rx_timeout < RX_TIME_OLD) && (navi_data.NCFlags & NC_FLAG_GPS_OK)) {
ret = 1;
}
}
// ca. 150ms keine OSD-Daten empfangen ==> sende neue Anforderung an MK
// if ((track_tx) && (rx_timeout > RX_TIMEOUT)) tx_Mk(NC_ADDRESS, 'o', interval, 1); // 10 * 10ms interval
if ((track_tx) && (rx_timeout > RX_TIMEOUT)) USART_send_Str(tx_osd); // 10 * 10ms interval
return(ret);
}
 
// Umrechnung Winkel in Servoschritte
void servo_track(uint8_t servo_nr, int16_t Angel)
{
servoSetPosition(servo_nr, (uint16_t)((float)Angel * ServoSteps() / 180));
}
 
// MK eingeschaltet und GPS-ok, danach Motoren gestartet ==> Berechnung horizontaler/vertikaler Servowinkel
// Hauptprogramm von GPS Antennen-Nachführung
void Tracking_GPS(void)
{ geo_t geo;
int AngelPan, AngelTilt;
char puffer[30];
if (OSD_Data_valid()) {
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 = (double)navi_data.HomePosition.Longitude / 10000000;
MK_pos.Home_Lat = (double)navi_data.HomePosition.Latitude / 10000000;
MK_pos.Home_Alt = navi_data.HomePosition.Altitude;
MK_pos.direction = navi_data.CompassHeading;
coldstart = 0;
}
}
else {
geo = calc_geo(MK_pos, navi_data.CurrentPosition);
AngelTilt = RAD_TO_DEG * (double)atan2((double)(navi_data.CurrentPosition.Altitude - MK_pos.Home_Alt) / 1000, geo.distance);
if (geo.distance < 4) { // Abstand MK- zu Antennenposition < 4m ==> Pan-Servo in Mittelstellung
geo.bearing = MK_pos.direction;
AngelTilt = 0;
}
// egal wo der Übergangspunkt 359, 360, 1grd ist => Winkelübergangspunkt auf 0 bzw. 180grd des Servos bringen
// 360 grd negative Winkelwerte als positive
AngelPan = fmod(geo.bearing - MK_pos.direction + 360 + 90, 360);
if (AngelPan > 360) AngelPan -= 360;
 
if (AngelTilt < 0) AngelTilt = 0;
if (AngelTilt > 180) AngelTilt = 180;
if (AngelPan >= 180) { // zwecks 360grd-Abdeckung flipt Pan-/Tilt-Servo
AngelPan = AngelPan - 180;
AngelTilt = 180 - AngelTilt;
}
 
servo_track(0, AngelPan);
servo_track(1, AngelTilt);
if ((gps_display > GPS_DISP_NONE) && (bat_low != 0)) {
if (gps_disp_clear) {
gps_disp_clear = 0;
lcdClear();
}
// der Einfachheit halber doch noch mit Kommazahlen sprintf(...)
switch(gps_display) {
case GPS_DISP_CALC:
sprintf( puffer, "Dir:%3d", MK_pos.direction);
lcdGotoXY(0, 0);
lcdPuts(puffer);
sprintf( puffer, "Dis:%4.1f", geo.distance);
lcdGotoXY(8, 0);
lcdPuts(puffer);
sprintf( puffer, "Bea:%5.1f", geo.bearing);
lcdGotoXY(0, 1);
lcdPuts(puffer);
sprintf( puffer, "Pan:%3d", AngelPan);
lcdGotoXY(0, 2);
lcdPuts(puffer);
sprintf( puffer, "Til:%3d", AngelTilt);
lcdGotoXY(8, 2);
lcdPuts(puffer);
break;
case GPS_DISP_CURRENT:
sprintf( puffer, "aLon:%10.6f", (double)navi_data.CurrentPosition.Longitude / 10000000);
lcdGotoXY(0, 0);
lcdPuts(puffer);
sprintf( puffer, "aLat:%10.6f", (double)navi_data.CurrentPosition.Latitude / 10000000);
lcdGotoXY(0, 1);
lcdPuts(puffer);
sprintf( puffer, "aAlt:%10.1f", (double)navi_data.CurrentPosition.Altitude / 1000);
lcdGotoXY(0, 2);
lcdPuts(puffer);
break;
case GPS_DISP_HOME:
sprintf( puffer, "hLon:%10.6f", MK_pos.Home_Lon);
lcdGotoXY(0, 0);
lcdPuts(puffer);
sprintf( puffer, "hLat:%10.6f", MK_pos.Home_Lat);
lcdGotoXY(0, 1);
lcdPuts(puffer);
sprintf( puffer, "hAlt:%10.1f", (double)MK_pos.Home_Alt / 1000);
lcdGotoXY(0, 2);
lcdPuts(puffer);
break;
}
}
}
}
Displ_wiRX();
}
 
/************************************************************************/
/* */
/* 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;
servoSetPosition(data_decode[1], (uint16_t)((float)ServoPos * ServoSteps() / 180));
}
}
}
/C-OSD/trunk/tags/v1.00/usart.c
0,0 → 1,239
 
/****************************************************************/
/* */
/* 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 "usart.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 | Sent 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;
char start;
 
/**************************************************************/
/* */
/* 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)
{ char received;
static uint8_t line_flag = 1;
static char* ptr_write = rx_buffer;
static uint8_t frame = 6;
// von '#' bis '\r' Puffer, einschließlich Satzzeichen schreiben
received = UDR0;
if (rx_ready == 0) {
if ((received == start) && line_flag) { // start '#' oder 0x80
line_flag = 0; // MK-Datensatzanfang wurde erkannt
ptr_write = rx_buffer; // Schreibzeiger auf Anfang Puffer setzen
rx_len = 0;
}
if (line_flag == 0) { // MK/Pololu-Datensatz ?
*ptr_write = received;
rx_len++;
 
/* GPS Datensatzende */
if (rx_GPS) {
if (received == '\r') { // Ende MK-Datensatz ?
line_flag = 1;
rx_ready = 1; // Puffer Schreiben sperren, MK-Datensatz kann nun verarbeitet werden
}
}
/* Pololu Micro Serial stark reduziert/vereinfacht; rx_len-Abfrage 1 höher ==> bereits incrementiert */
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; // Puffer Schreiben sperren, Pololu-Datensatz kann nun verarbeitet werden
}
}
 
ptr_write++;
if(rx_len == RXD_BUFFER_SIZE) line_flag = 1; // ungültiger MK/Pololu-Datensatz ? ==> neu beginnen
}
}
}
 
// 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 Orginal H&I MK-Software mkprotocol.h und mkprotocol.c
uint8_t rx_line_decode(char rx_ID)
{ uint8_t ret = 0;
uint8_t crc1,crc2;
int tmpCRC = 0;
// rx_ready gleichzeitig usart rx_buffer schreiben gesperrt
if ((rx_ready == 1) && (rx_len > 0) && (rx_buffer[2] == rx_ID)) {
// 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 = 1;
}
cli();
rx_timeout = 0; // kein gültiger Datensatz rx_ID ==> Counter wird nicht mehr rückgesetzt
sei();
}
// für Blinken des Antennenzeichens, MK antwortet immer mit cmd Großbuchstaben
if ((rx_timeout < RX_TIME_OLD) && (rx_buffer[2] >= 'A') && (rx_buffer[2] <= 'Z')) wi232RX = 1;
rx_ready = 0; // Puffer Schreiben entsperren, neuer MK-Datensatz kann wieder empfangen/gepuffert werden
return(ret);
}
 
void USART_RX_Mode(uint8_t tracking)
{
rx_GPS = (tracking == TRACKING_GPS);
if (rx_GPS) start ='#'; else start = 0x80;
}
 
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);
}
/C-OSD/trunk/tags/v1.00/usart.h
0,0 → 1,112
 
/****************************************************************/
/* */
/* 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 TRACKING_RSSI 1
#define TRACKING_GPS 2
#define TRACKING_MKCOCKPIT 3
 
#define RXD_BUFFER_SIZE 150 //Puffergröße in Byte
#define TXD_BUFFER_SIZE 20
#define ANY_ADDRESS 0
#define FC_ADDRESS 1
#define NC_ADDRESS 2
 
#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
 
#define RX_TIMEOUT 420 // 210ms
#define RX_TIME_OLD 3 * RX_TIMEOUT // Grenze, Datensatz viel zu alt
 
//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 );
uint8_t rx_line_decode(char rx_ID);
//void tx_Mk(unsigned char addr, char cmd, char *data, uint8_t len);
 
// 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;
 
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;
 
NaviData_t navi_data;
 
typedef struct
{
double Home_Lon; // in 1E-7 deg
double Home_Lat; // in 1E-7 deg
int32_t Home_Alt; // in mm
int16_t direction; // ermittelte Konstante aus Mittelposition Antenne geo.bearing - navi_data.CompassHeading
} __attribute__((packed)) HomePos_t;
 
HomePos_t MK_pos;// steht hier nur wegen Vermeidung Compiler-Warnung
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);
 
#endif /* USART_H_ */