2 Commits

67 changed files with 7091 additions and 3043 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,5 @@
/Debug/
/Release/
/UKSSTMS320F28335.CS_/
/Doc/build/
/Doc/.tools/

3
Bin/CCS12/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# CCS 12 output files
*
!.gitignore

Binary file not shown.

View File

@@ -1,4 +1,4 @@
:20000000AA0800000000000000000000000000000000000098B1830200005FB300FFC0DAB5
:20000000AA08000000000000000000000000000000000000FAB87F02000094BA00FF40DE90
:2000200000000000C1C081C1400101C3C003800241C201C6C006800741C70005C1C581C4C4
:20004000400401CCC00C800D41CD000FC1CF81CE400E000AC1CA81CB400B01C9C0098008A5
:2000600041C801D8C018801941D9001BC1DB81DA401A001EC1DE81DF401F01DDC01D801CD4
@@ -15,873 +15,990 @@
:2001C0004054019CC05C805D419D005FC19F819E405E005AC19A819B405B0199C0598058A4
:2001E00041980188C04880494189004BC18B818A404A004EC18E818F404F018DC04D804C33
:20020000418C0044C184818540450187C047804641860182C042804341830041C181818051
:200220004040C0FF40DE00000000000000000000C701B9019B0958090000000000000000DA
:20024000CE01B7018A09600948130D136C13F9125E076A07D509E7090C138D130C13EF1293
:200260006A075107E709C609EC0ECE0EB10D340DC806AB0256030E00FB0EC90EC20D040D7F
:20028000D106B1025C0311000105F804000000006E02D708000000000A05050500000000FA
:2002A000FD07FD07A50AA50AFFFF42DC00001400FFFF43DC00000000FFFF44DC000000006D
:2002C000FFFF45DC00000000FFFF46DC00000000FFFF47DC00000000FFFF48DC000000009C
:2002E000FFFF51DC00000000FFFF54DC00000000FFFF55DC00000000EEFF68DC00001BD654
:20030000B738D79AFC3FA84C79BF0000000000000000000000000000000000000000000016
:200320000000FFFFACDE00000000FFFFADDE00000000FFFFAEDE00000000FFFFAFDE000097
:200340000000FFFFB0DE00000000FFFFB1DE00000000FFFFB2DE00000000FFFFB3DE000067
:200360000000FFFFA4DD00000000FFFFA5DD00000000FFFFA6DD00000000FFFFA7DD00007B
:200380000000F4FFB4DD00000000000000000000C89C0000FA9C0000C39C0000BE9C000026
:2003A000FFFFCEDE00000000FFFFCFDE00000000FEFFD4DE000000000000FEFFD6DE000088
:2003C00000000000FEFFD8DE000000000000FEFFDADE000000000000EEFF98DE00004A0CFC
:2003E000023E4A0C023E0000803F0000803F6C09F93B6C09F93B6C09F93B6C09F93B000005
:20040000803FF0FFB0DA00003F0006005B004F0066006D007D0007007F006F004000000030
:200420000000000079000000FFFF37DE00000600FFFF39DE00000000FFFF3ADE00000000FF
:20044000FEFF3EDE000000000000FFFFC2DE00000000FFFFC3DE00000000FFFFC4DE0000A6
:200460000100FFFFC5DE00000000FFFFF4DE00000000FFFFF5DE00000000FFFFF6DE000067
:200480000000FEFF28DF000055B30000FEFF2ADF000055B30000FEFF2CDF0000000000003A
:2004A000FEFF2EDF000000000000FFFFE0DE00000000FFFFE1DE00000000FBFF1EDF0000C2
:2004C00008000C00100000000400FFFF23DF00000A00FFFF24DF00000100FFFF3EDD0000CF
:2004E0000100FFFF3FDD00000100FEFF34DF000000000000FEFF36DF000000000000FFFFC0
:2005000000D000000100FFFFC0DD00000000FFFF41DC00000000FFFF27DF00000000000050
:020520000000D9
:200522005F330000008002FEA4C5A988013B008FC0DBC7924196A9A8A681A71E1F76710331
:20054200C7CC00E041CA4296C7FF01900B9842CCFFFDA98803564201A91CFF03A9180002E8
:20056200A6CA429682FEC796060010E70B0001E8EAFA20E740000DE8BA9E6FE819F000E7A4
:20058200100000E7490000E70000007710E740004076A0B202E8010250E80000407679AF79
:2005A2000600A71EA59243880860C4930461C40BA6920C6F009A0A6FC427AA2BA706AB0F8C
:2005C2000362019A036FC40AA69206001F767A03BDB22D92BDAA03E2BD04586179D1808D3E
:2005E200C0DB78D0013B9A92929EA985A9BD120F007700770077007789E604000077CFE64E
:20060200210002E80818407679AF1F76710303E21E0002E8101CCFE621000FE830334076C7
:2006220079AF7AD11F76710378D0013B008FC0DB03E220009A92949EA985A9BD120F0077FF
:2006420000770077007789E6010002E80818407679AF7BD11F76710379D0013B008FC0DBD7
:2006620003E222009A92949EA985A9BD120F007700770077007789E6010002E80818407652
:2006820079AF1F76710303E224001F767A032C922F617AD1808DC0DB78D0013B9A92929EEB
:2006A200A985A9BD120F007700770077007789E6010002E84016407679AF7BD11F767103C4
:2006C20079D0013B03E222009A92929EA985A9BD120F007700770077007789E6010002E845
:2006E2004016407679AF1F76710303E2240000D1008FC0DB013BA9A8A181A98A74D0C8E2E7
:200702009400008F80DEA9A8A181A98AC4920252046002E8D123056F02E8E1300AE8010062
:20072200407679AF013B008F98DE0356A1010156A40001D9A192045203E2C400DA64AFE2C7
:20074200BE04BE86BE8B0600BDB2BDAA04FE0052A92DA85A06601F7671030B920B2B0C965C
:20076200008FC0DB013BA9A8AC81A98AC44F076CAC921F7671030654E4FFB401008F21DD14
:20078200A9A8AC81A9837FD0008FC0DB944CC4E2C500EDFF9E01A9A8AC81A98AC44D3F6CF1
:2007A200AC921F76710306543A6300B6A79200BEA985013BA98E008F80DEA9A8AC81A98314
:2007C200A9A8A681A98AC592C4541460008FC0DBA9A8A681A98A1F7671031392C4CE0A600A
:2007E200008F21DDA9A8A681A98A01DFA93AC40DA98E01DEA6921852DF64A7920761A98561
:20080200421EA93AC0004EB2A98EA93AA9BD120F007700770077007789E60000AC921F7614
:200822007103079EA959A2922561008F80DE013BA9A8AC81A98AC4920A521A60AC92069EF9
:20084200A988008F08DFA9A8A681A98AC8E2C401008F00DFA9A8A681A98A01E860EE0EE88F
:20086200686600E74000C492036106E84016A29256601F767A032C9252617FD0008FC0DB9D
:20088200949316D0D3FF9492C1FFA8CAA940246C1F767B03240620601F767A032B920552C3
:2008A2000C6002E849280CE8010094E6080014AD0465A1920250A959A1920E64A9A8013B15
:2008C200A181A98A8CE6000078D013E2940040765380EFFF1401AC921F7671030654E3FF6F
:2008E2000E01A1400F6C79D0C8E29401007720E74000AFE2240300E71800007790E8007629
:200902000E6F78D0C8E29401007720E74000AFE2220300E71800007790E800761F767A03E7
:200922002D925261A192E3FFAF001F767A032B9202521F61AC400F6C79D0008FC0DBC8E258
:2009420094011F76710320E74000AFE2240300E718003A6F78D0008FC0DBC8E294011F760A
:20096200710320E74000AFE2220300E718002C6F08BEAC92A672008FC0DB013BA9A8A68170
:20098200A983807621DDA606AC81A71E18D0C7929596AC9206520D6378D0C8E294011F7609
:2009A200710320E74000AFE21E0300E718000C6F78D0C8E294011F76710320E74000AFE2E6
:2009C200200300E7180016D0008FC0DB26E8000D94937FD0D0FF949232E8401AC9FFA8CAAF
:2009E200A940036C02E8001150E80148A9A8013B8CE60000AC818CE60900A98318D01F76D1
:200A02007B03A6BF120F13E29501432B24063460A9A8AC81A98AC493A84E2E6DA61BECFFD4
:200A22002565A692C852226330D09592FB9CA6540363A845146D008FC0DBA9A8AC81A98AEC
:200A420030D0A69294540B6248D0945415651F767103431A10000B1A08000E6F1F76710364
:200A6200431A20010B1A0400076F1F767103431A01000B1A1000AD5CAC9283DCA45C40765F
:200A820000803C6F1F767B03240616601235008F00D90156A400407617B2013B008FC0DBE7
:200AA200A9A8A181A98A8CE6000078D013E2940040765380236F1235C07640D70156A7009E
:200AC200008F00D90156A40011F68424176FA9A8AC81A98A8CE6000018D013E294000E6F6B
:200AE200008FC0DBA9A8AC81A983A9A8AC81A98AC52B18D0C51A0080942B84FEBE86BE8B6A
:200B02000600BDB2BDAABDA202FE0052A95A06601F7671030B920B2B0C96008FC0DB013BF9
:200B2200A9A8A281A61EC64FEDFFC700408F21DDA9A0A281A9837FD0944CC4E2C500EDFFC8
:200B4200B300408F80DEA9A0A281A9830356C501408F98DE0156A500AFE2C50100E740003D
:200B6200A9A88CE60000A281A98AA1BF120F18D01F767B039479422B2406E0FF8E00C64EB9
:200B8200EDFF8B00A29207525C610356A201A95B1F767A034218FFFB008D01DDA32D3806B3
:200BA200412B22560190A95DA93AA381A98A20FFE80340763E80013B019B019089FFA395D7
:200BC2004298A82D4218FFF73806412B22560190A95DA93AAC81A98A20FFE80340763E809A
:200BE20001908AFF4298A29206522B60029A4218FFEFA394A92D013B3806412B2256019008
:200C0200A95DA93AAC81A98A20FFE80340763E80013B039B0190A3958BFF4298A82D4218D5
:200C2200FFDF38062256412B0190A95DA93AAC81A98A20FFE80340763E8001908CFF429864
:200C42004292C0FF42CDBFFF42CA008FC0DB013BC0FF42CAC0FF42CAC3FF4090A8CA42964E
:200C6200A9A8A281A98348D0A19295540F63408F1EDEA9A0A281A983421A0800A9A8C581CE
:200C8200A98AC492089084FF4298429205611F7671030B1A0200AD5CA29282DCA45C407619
:200CA2000080156FA9A8A281A98A8CE6000018D013E294000C6FA9A8A281A983A9A8A28115
:200CC200A98AC52B18D0C51A0080942B82FEBE82BE86BE8B060000BE013B008FC0DBA9A821
:200CE200A681A98A01DE18D0A692C41800E01852942BF46400BE013B008FC0DB408F10DF7A
:200D0200A9A8A681A98A0356A6010156A50070D0C8E294001F767A0303E2C5002B920652DB
:200D22001760408F80DEA9A0A681A983C59203520F60A640056D18D094288601096F008FCC
:200D4200C0DBA9A8A681A98A18D09428300201DEA6920452D2642B9201521060008FC0DB28
:200D62001F767103A9A80881A98AC41A0040CC1A0040D41A0040DC1A00401F767A032B92E4
:200D820006520760008FC0DBC41A0040CC1A00404076538006001F767A032A92A9931F76F6
:200DA2007103BDB2FF9D052B062B072B01531C69A993FD9D015311690752086109521A600B
:200DC200BF56060FBF56070D156FBF560508BF560608BF5607080E6FBF560507BF56060E0A
:200DE200BF56070E076FBF56050ABF560614BF5607141F767A033192AC2B013BC07668DC6C
:200E02001F76710306940896008F80DEA9A8AC81A98AC42B008F1EDEA9A8AC81A98A408FF7
:200E220040D71235C4210156A500008F00D90156A400AC92019C11F68524A92D185211F63C
:200E42008424E3641F767A032E9225611F7671030692AC2B20651F767A032D920961008F82
:200E620080DE013BA9A8AC81A98ABF56C4091F767A032C920961008F80DE013BA9A8AC8162
:200E8200A98ABF56C408AC921F767103019CA92D0654E2641F767A033192AC2B1565013B80
:200EA2001F7671030688AC92A672008F80DEA9A8A681A98A1F767A03AC92019CBF56C40ADB
:200EC200A92D3154EE641F767A032F9236611F767103AC2B013BBF5612C80892AC94A988E3
:200EE200008F80DEA9A8A681A98A408F10DFBF56C403008F1EDEA9A8A681A98AAC9201F059
:200F02000894C4960356AC01008FC0DB0156A500A9A8AC81A98A70D01235C8E29400008FA8
:200F220040DD0156A40003E2C500AC92019CA92D11F684240452D2641F767A032B920652DA
:200F42000B601F767103008F80DE12282C01BF56DC02BF56D4021F767A032A92095234602C
:200F6200008F80DE408F1EDEC42BBF56C50108D0BF56CC010ED1CD2BBF56D404BF56D50382
:200F8200BF56DC04BF56DD02BF56E404BF56E505BF56EC04BF56ED04BF56F406BF56FC053A
:200FA200BF56940609D0BF5694070AD0BF5694060BD0BF5694060CD0BF5694060DD0BF5667
:200FC2009408BF569C081F7671030002132B0D28F915BF560E120F28F22B10283E49AC2B0F
:200FE200013B90E5131A01E01F767A03381E008FBADEA9A8AC81A98AC42B008F18DFA9A82A
:20100200AC81A98A0356AC01C42B008FE8DE0156A400AC92019CA92D03E2C4000652E8642B
:20102200AC2B013B00BE0356AC01008F04D70156A400AC92019CC4C2A92D1C52F564AC2B9D
:20104200013B008F01DDA9A8AC81A98AAC92019CC42BA92D2052F664AC2B013B008F00DF47
:20106200A9A8AC81A98AC42B008F08DFA9A8AC81A98AAC92019CC42BA92D0852F064BE8B10
:2010820006001F767A032F921F7671030880026104DF00D5013B00D40356A5038076F0D8FA
:2010A200A4810156A60001DCA492C62B0852F56401DDA5920252F0641F767A032B92045273
:2010C2007761A79200D52D65013BA592A2FF008FF0D8CBFFA594A3FFA927A9A8AB81A61E75
:2010E2000356AB04A92D019BA592ACEA189A67FFA594C699A988A2FFCBFFA594189CA3FFCC
:20110200A92701DDA9A8AB81A98A0356AB04A92DA692ACEA019A66FFC498A792A554D662FD
:2011220000D5013B008FF0D803BEA9A8A581A71EA592A672A9A8A681A98A08D001DDC7923F
:201142009496A5920352EF641F767A032B92008FF8D802520460A9280003036FA928000F78
:20116200FC981F767A032F920961408FF0D8A58A0FDCC41AFF00F51A003F1F767A033192EB
:2011820005611F766303361A08001F767A032B9206521460408FF0D8A58A08DCFC1A300009
:2011A200EC1A0300FD1A00E0CD1A0030076F008FF8D8C41A0F00F41AFC01008FF0D8A483CB
:2011C20008DC01DDC51A0100F41A0700FC1A00E00600BDB2BDAABDA203E2BD0403E2BD05D8
:2011E20003E2BD060AFE1F767A0344962B9206520860449206601F7671030B920B2B0C961A
:201202001F7671030892008F1EDE013B4494A988A9A84481A98A808DC0DBC4924696449260
:2012220001F0019047964492A0FFA92D499603354896049AAC94A95BA9AAA681A98A457EBB
:20124200C44FEDFF4002008F3CD7A9A84481A98A64BE4492A672C4E2C404A9AAA681A98A35
:201262008CE62000408D10DF13E2C40044920356A9010156A10002E891340BE801E0AFE280
:20128200C10020E72000407679AF442D008F40DD1235AFE2C10110E740000156A40003E2B8
:2012A200C100407617B21F767B038CE60000AC281F0026C4013B1F767B038DE60000A6061C
:2012C2002256A60740FF240F0965A9AA4481A98A8CE6000070D013E294004492408F98DE66
:2012E200008FC0DB0356A901A71E0156A500A9A84481A98A70D0C8E29400408DE8DE21E3A0
:20130200C501A70600E70C000156A10000E72101AFE2C10620E7880102E8512B0BE8010022
:20132200407679AFAFE2C10110E74000007703E2C1004076A0B2013B008F18DF8CE60000EA
:20134200A9A84481A98A13E2C4004792E0FFA4001F767103CFE62000AFE22601407622803F
:20136200452D008F00D912350156A400407617B24588008F80DE013BA9A8A681A98ACFE67A
:201382000600C4920352066012E8060D14AD026396E5008F80DEA9A8A681A98AC492025244
:2013A200066012E8B61414AD026396E501E8A9FDCFE6300008E89927407679AF1F767B034B
:2013C200CFE6050024061660008FC0DB4588013BA9A88CE6300018D0A681A98381DEA9A8A0
:2013E200A681A98A13E295008CE62B0018D013E294031F767103013BAFE62400408DE8DE65
:20140200AFE226000356A30120E720000156A10000E70100AFE2C10020E7080002E8512B48
:201422000BE80100407679AFAFE2C10110E74000007703E2C1004076A0B2013B408F18DF27
:201442008CE60000A9A0A381A61EABBF120F68B6C63F4892A772008FC0DBA9A8A781A61EDF
:20146200A9A04681A71EAA286900C792C696A9A04481A71E4892AA72A9A8AA81A61EAA28CA
:201482006A00C792C6964892AA72A9A8AA81A98AC43F0C6F1F767A032B9201520360AFE6EE
:2014A20024001F76710303E22604008F18DFA9A84481A983A9A84681A98AC8E2C504C8E2BE
:2014C200C400008F18DFA9A8A381A98A96E604001F767B03C8E2C4002406432B96E60400FF
:2014E200E0FFEA00008FC0DBA9A84581A98AC4CC0040CDFFA959008F18DFA9A84481A98A40
:20150200C8E2C400CFE6210020E72000407679AF01E8C9F400D50CE8D1CC94E6080014AD31
:201522000B651F767103C8E21200007794E6040014AD026501D5008FBADE013B1F76710315
:20154200A9A84481412BA98A0F0E40763E8000520D61009BA1920260019B0356A8084393D8
:201562000451A818FFFEA8CA4396008F18DF013BA9A8A381A98AC8E2C400CFE6210020E757
:201582002000407679AF01E8C9F400D50CE8D1CC94E6080014AD0B651F767103C8E21200C7
:2015A200007794E6040014AD026501D5008FBADE013B1F767103A9A8412BA381A98A0F0E99
:2015C20040763E8000520D61009BA1920260019B0356A80843930451A818FFFEA8CA4396CD
:2015E2001F767A032B9206526660479264604588008FC0DB013BA9A8A681A98A30D0C8E2D7
:201602009400007794E6050014AD0D65009BA1920260019B0356A80843932051A818FFFE32
:20162200A8CA4396008F80DEA9A8A681A98AC49203522860008FC0DBA9A8A681A98A48D0A5
:20164200412BC8E2940000D594E6050014AD026301D5008F36DF1F767103A9A84981A98A93
:201662000F0E40763E8000520D61009BA1920260019B0356A80843930851A818FFFEA8CAE4
:2016820043964588008F80DE013BA9A8A681A98AC49202521060008FC0DBA9A8A681A98ADF
:2016A20048D0C8E29400007794E6050014AD0365431A1000AD5C459283DCA45C40760080D1
:2016C2000E6F008FC0DBA9A8A681A983A9A8A681A98AC52B18D0C51A0080942B8AFEAFE203
:2016E200BE06AFE2BE05AFE2BE04BE82BE86BE8B06001B76F0FF00E2BD0030E60006422904
:2017020016562576006F1B76F0FF00E2BD0030E6000602FE422916561F76330038924196D6
:2017220023760008267600003892382B2128FFFF1029103B419238962576006F1B76F0FF47
:2017420000E2BD0030E6000602FE422916561F7633003892419623760008267600003818FF
:2017620090002128FFFF1029103B419238962576006F1B76F0FF00E2BD0030E6000602FE26
:20178200422916561F763300389241962376000826760000381890002128FFFF1029103B1F
:2017A200419238962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003892D8
:2017C2004196237600082676000038189C002128FFFF1029103B419238962576006F1B7600
:2017E200F0FF00E2BD0030E6000602FE422916561F763300389241962376000826760000C0
:2018020038189E002128FFFF1029103B419238962576006F1B76F0FF00E2BD0030E6000627
:2018220002FE422916561F7633002292419623760101221868002128FFFF1029103B4192A1
:2018420022962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300229241965F
:20186200237601012292222B2128FFFF1029103B419222962576006F1B76F0FF00E2BD004B
:2018820030E6000602FE422916561F763300229241962376010026760101221878002128CD
:2018A200FFFF1029103B419222962576006F1B76F0FF00E2BD0030E60006422916561029C4
:2018C2002576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E245
:2018E200BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000642291656E1
:2019020010292576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FFAD
:2019220000E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000642292A
:20194200165610292576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0
:20196200F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000666
:201982004229165610292576006F1B76F0FF00E2BD0030E600064229165610292576006FD6
:2019A2001B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E69B
:2019C200000602FE422916561F7633002292419623760100267601012292222B2128FFFF55
:2019E2001029103B419222962576006F1B76F0FF00E2BD0030E6000602FE422916561F7625
:201A020033002C92419623762000267639012C922C2B2128FFFF1029103B41922C9625765D
:201A2200006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C924196237620000D
:201A4200267639012C1832002128FFFF1029103B41922C962576006F1B76F0FF00E2BD00AF
:201A620030E6000602FE422916561F7633002292419623760100267601012218F80021286B
:201A8200FFFF1029103B419222962576006F1B76F0FF00E2BD0030E6000602FE422916561B
:201AA2001F7633002292419623760100267601012218FA002128FFFF1029103B419222960F
:201AC2002576006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241962376EE
:201AE200800026760000301803002128FFFF1029103B419230962576006F1B76F0FF00E2AD
:201B0200BD0030E6000602FE422916561F76330032924196237600012676000132187500BA
:201B22002128FFFF1029103B419232962576006F1B76F0FF00E2BD0030E6000602FE42298D
:201B420016561F7633003292419623760001267600013218FD002128FFFF1029103B419298
:201B620032962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241961E
:201B820023768000267600002C1823002128FFFF1029103B419230962576006F1B76F0FF39
:201BA20000E2BD0030E6000602FE422916561F7633003292419623760001267600013218AD
:201BC20071002128FFFF1029103B419232962576006F1B76F0FF00E2BD0030E6000602FEE7
:201BE200422916561F7633003292419623760001267600013292322B2128FFFF1029103B86
:201C0200419232962576006F1B76F0FF00E2BD0030E6000642291656237639011029257664
:201C2200006F1B76F0FF00E2BD0030E60006422916562576006F1B76F0FF00E2BD0030E6E2
:201C420000064229165610292576006F1B76F0FF00E2BD0030E6000602FE422916561F76BB
:201C620033002C92419623762000267639012C1837002128FFFF1029103B41922C96257695
:201C8200006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C92419623762000AB
:201CA200267639012C922C2B2128FFFF1029103B41922C962576006F1B76F0FF00E2BD00AE
:201CC20030E6000602FE422916561F7633002C92419623762000267639012C183300212863
:201CE200FFFF1029103B41922C962576006F1B76F0FF00E2BD0030E6000602FE42291656AF
:201D02001F7633002C92419623762000267639012C1822002128FFFF1029103B41922C960F
:201D22002576006F1B76F0FF00E2BD0030E6000602FE422916561F76330038924196237683
:201D420000082676000038189F002128FFFF1029103B419238962576006F1B76F0FF00E216
:201D6200BD0030E6000602FE422916561F7633003892419623760008267600003892382BDE
:201D82002128FFFF1029103B419238962576006F1B76F0FF00E2BD0030E6000642291656B9
:201DA2002576006F1B76F0FF00E2BD0030E60006422916562376390110292576006F1B765E
:201DC200F0FF00E2BD0030E60006422916562376391110292576006F1B76F0FF00E2BD003B
:201DE20030E600064229165610292576006F1B76F0FF00E2BD0030E6000602FE4229165699
:201E02001F763300309241962376800026760000301801002128FFFF1029103B41923096FD
:201E22002576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003092419623768A
:201E42008000267600002C922C2B2128FFFF1029103B419230962576006F1B76F0FF00E27F
:201E6200BD0030E6000602FE422916561F7633002A92419623761000267610012A922A2BEE
:201E82002128FFFF1029103B41922A962576006F1B76F0FF00E2BD0030E6000602FE422932
:201EA20016561F7633002A92419623761000267610012A1802002128FFFF1029103B419221
:201EC2002A962576006F1B76F0FF00E2BD0030E6000602FE422916561F76330024924196CF
:201EE200237602002676000024181F002128FFFF1029103B419224962576006F1B76F0FF6C
:201F020000E2BD0030E6000602FE422916561F763300269241962376040026763D012692A7
:201F2200262B2128FFFF1029103B419226962576006F1B76F0FF00E2BD0030E6000602FEAF
:201F4200422916561F76330024924196237602002676000024180F002128FFFF1029103B06
:201F6200419224962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300269236
:201F820041962376040026763D01261826002128FFFF1029103B419226962576006F1B7698
:201FA200F0FF00E2BD0030E6000602FE422916561F76330024924196237602002676000012
:201FC2002492242B2128FFFF1029103B419224962576006F1B76F0FF00E2BD0030E600065D
:201FE20002FE422916561F763300269241962376040026763D01261826002128FFFF102956
:20200200103B419226962576006F1B76F0FF00E2BD0030E6000602FE422916561F76330000
:20202200249241962376020026760000241808002128FFFF1029103B419224962576006F34
:202042001B76F0FF00E2BD0030E6000602FE422916561F76330026924196237604002676DC
:202062003D012692262B2128FFFF1029103B419226962576006F1B76F0FF00E2BD0030E67E
:20208200000602FE422916561F76330024924196237602002676000024180C002128FFFF46
:2020A2001029103B419224962576006F1B76F0FF00E2BD0030E6000602FE422916561F765C
:2020C2003300269241962376040026763D012692262B2128FFFF1029103B419226962576C7
:2020E200006F1B76F0FF00E2BD0030E6000602FE422916561F76330024924196237602006D
:202102002676000024180E002128FFFF1029103B419224962576006F1B76F0FF00E2BD0056
:2021220030E6000602FE422916561F763300269241962376040026763D0126183E00212817
:20214200FFFF1029103B419226962576006F1B76F0FF00E2BD0030E6000642291656102917
:202162002576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002892419623764F
:2021820008002676080128180F002128FFFF1029103B419228962576006F1B76F0FF00E279
:2021A200BD0030E6000602FE422916561F76330028924196237608002676080128180F007F
:2021C2002128FFFF1029103B419228962576006F1B76F0FF00E2BD0030E6000602FE4229F1
:2021E20016561F763300289241962376080026760801281803002128FFFF1029103B4192F1
:2022020028962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002892419689
:202222002376080026760801281803002128FFFF1029103B419228962576006F1B76F0FF2D
:2022420000E2BD0030E6000602FE422916561F7633002A924196237608002676080128928F
:20226200282B2128FFFF1029103B419228962576006F1B76F0FF00E2BD0030E6000602FE68
:20228200422916561F763300289241962376080026760801281802002128FFFF1029103BB9
:2022A200419228962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003292E3
:2022C20041962376000126760001321875002128FFFF1029103B419232962576006F1B762E
:2022E200F0FF00E2BD0030E6000602FE422916561F763300329241962376000126760001C1
:202302003292322B2128FFFF1029103B419232962576006F1B76F0FF00E2BD0030E60006EF
:2023220002FE422916561F763300329241962376000126760001321831002128FFFF10292F
:20234200103B419232962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300B1
:202362003292419623760001267600013292322B2128FFFF1029103B419232962576006FF8
:202382001B76F0FF00E2BD0030E6000602FE422916561F7633002E92419623764000267655
:2023A20000002E922E2B2128FFFF1029103B41922E962576006F1B76F0FF00E2BD0030E661
:2023C200000602FE422916561F7633002E92419623764000267600002E1828002128FFFF95
:2023E2001029103B41922E962576006F1B76F0FF00E2BD0030E6000602FE422916561F760F
:2024020033002E92419623764000267600002E1820002128FFFF1029103B41922E96257618
:20242200006F1B76F0FF00E2BD0030E6000602FE422916561F7633002E92419623764000E1
:20244200267600002E1838002128FFFF1029103B41922E962576006F1B76F0FF00E2BD00D5
:2024620030E6000602FE422916561F7633002E92419623764000267600002E1838002128CC
:20248200FFFF1029103B41922E962576006F1B76F0FF00E2BD0030E6000602FE4229165605
:2024A2001F7633002E92419623764000267600002E183E002128FFFF1029103B41922E9660
:2024C2002576006F1B76F0FF00E2BD0030E60006422916562376390110292576006F1B7637
:2024E200F0FF00E2BD0030E6000602FE422916561F763300229241962376010026760101CE
:20250200221848002128FFFF1029103B419222962576006F22761F767A0316D0008F806FC9
:20252200349294CDFCFF03901F76BE0118D0A8CA16961F767A03359294CDFCFF03901F762D
:20254200BE011AD0A8CA18961F767A033692019094CDFEFF1F76BE01A8CA1BD01A961F76F1
:202562007A03379201901F76BE0194CDFEFFA8CA1B961A7669FF060016D0008F806F1F76B6
:202582007A039492039018D03496949203901AD03596949201901BD03696949201903796F1
:2025A20022761F76BE011618FCFF1818FCFF1A1A01001B1A01001A7669FF0600A9881F76AA
:2025C2007A032B9200D4003102521860A640036D008F0008A641056DA9A8A91A0002A98A5F
:2025E200A642046DA9A88050A98AA643046DA9A80850A98A1F76BF0102A81F767A032B9228
:2026020003524960A69205601F76BF01041A0008015205601F76BF01041A000202520560BC
:202622001F76BF01041A8000035205601F76BF01041A0800045205601F76BF01041A020040
:20264200055205601F76BF01041A0001065205601F76BF01041A4000075205601F76BF01C5
:20266200041A0100085205601F76BF01051A0008095205601F76BF01051A00010A52056008
:202682001F76BF010D1A20000B5205601F76BF010D1A04001F767A032B9201521F60A640D3
:2026A200056DA9A8A81A0008A98AA641056DA9A8A81A0001A98AA642056DA9A8A81A000249
:2026C200A98AA643036DAA1A0200A644036DAA1A10001F76BF0104A80CA906001F767A03AA
:2026E2002B9202520660008F880A1F76BF0104A8015209602FFF00161F76BF01128F000049
:20270200021E0AA81F767A032B9203520B60A928CB0BA82800091F76BF01248F0000021EAE
:202722000AA8060022761F76BE01408F806F061800000F8F00F0A5C4071800FF08183F00A3
:20274200091800FF1BDD0BDE1606A918C0FF161EA9A818C0A89219C0C618EFFF0B18DFFF9D
:202762000B18BFFFC518F7FF1A76008FC06F1F767A03BF562A0109D0CC92C4FF01F0019087
:202782002A721F76BF010192C3FF1F767A0301F0019080FF2A721F76BF010192C5FF1F7601
:2027A2007A0301F0019081FF2A729492C2FF01F0019082FF2A942A96035203610452036022
:2027C200BF562B010152036102520360BF562B030552036106520360BF562B06075203608D
:2027E200BF562B0208520360BF562B04095213612B920152036106520360BF562F010252FD
:20280200036103520360BF562D010152066105520461056FBF562B05BF562C012B920152D6
:20282200036103520360BF562E0202520360BF562E01045217610152BF5630010360BF565B
:20284200310203520A610152086106520B601F76BF01021A80000A6F1F76BF010B1A001010
:20286200056F1F76BF010D1A001006520E6103520961015204610D1A0080096F0B1A008054
:20288200066F0B1A0040036F021A800006520B6104520961025204610B1A0004066F0B1A4E
:2028A2000040036F021A000206520661045204610B1A0020036F021A0800227604520A6297
:2028C20004522461015240610252346103522661446F0552116106524060088F8A021F7636
:2028E200BE01059AA82801FC0AA81A1E1F76BF01021A0800326F088F00001F76BE01049A1E
:20290200A82801BC0AA81A1E286F088F49031F76BE0105020AA81A1E206FA928CB0BA82879
:2029220008091F76BE010A1E059AA828257C1A1E146F088F8A0B1F76BE01059AA82801F855
:202942000AA81A1E0A6F2FFF10161F76BE010A1E059AA82813BC1A1E1A7669FF0600BDB25F
:20296200BDAABDA202FE1F767A032B9200D200D3025232601F76BF0116D0008FC0DB099235
:20298200C1FF94CDFEFF01F016D116D00190A8CAA9CDFDFF949616D0099203F01F766F033F
:2029A2000290A8CA9C9600CDFFF39492039089FFA8CA00961F76BF010040036C0102A986A1
:2029C2000042026C02DA004A026C04DA0044026C08DA10D0947A1F767A032B92015231609E
:2029E200408DC0DBA18A1F76BF01A183012916DCC418FDFF16DD0992C3FFA18A03F00290D5
:202A0200C59816DCC418FBFF0992412B008FB2DEC1FF01F00190A95D20FFFFFF40763E8090
:202A22000356A902A18A1F766F0316D0079016DCC49800CDFFE79192069089FFA8CA009697
:202A42001F767A032B9204525B60408DC0DBA18A1F76BF0116DCC418FEFF01CC0004C9FF48
:202A6200412BA95D008FB2DE20FFE80340763E8016D91F76BF010190C198014B026C01DA82
:202A82000148026C02DA0945026C04DA0942026C08DA014A026C10DA0147026C20DA0944CC
:202AA200026C40DA0044046CA9AA8009A9860149056CA9AA18FF0100A9860941056CA9AA6A
:202AC20019FF0100A986004B056CA9AA1AFF0100A9860045056CA9AA1BFF0100A9860940B8
:202AE200056CA9AA1CFF0100A986004A056CA9AA1DFF0100A98610D0008FC0DB947A1F76BE
:202B02007A032B92065210601F76BF010046026D01DA0048026D02DA004B026D04DA10D0C1
:202B2200008FC0DB947A1F767A032B920552E0FF89001F76BF010945036D01DA026F10DB83
:202B42000944036D02DA026F40DB0042036D04DA056FA9A21CFF0100A9820044036D08DA22
:202B6200056FA9A21DFF0100A9820046036D10DA056FA9A21EFF0100A9820040036D20DAFA
:202B8200056FA9A21FFF0100A9820048036D40DA056FA9A21FFF0200A982004A056DA9AA3F
:202BA2008009A986056FA9A21FFF0400A9820043066DA9AA18FF0100A986056FA9A21FFF22
:202BC2000800A9820045066DA9AA19FF0100A986056FA9A21FFF1000A9820047066DA9AA48
:202BE2001AFF0100A986056FA9A21FFF2000A9820041066DA9AA1BFF0100A986056FA9A252
:202C02001FFF4000A982004B066DA9AA1CFF0100A986056FA9A21FFF8000A9820049066D89
:202C2200A9AA1DFF0100A986056FA9A21FFF0001A9821F767A0310D0008FC0DB38A2947AE6
:202C4200008FC06FCC92013B1F76BF01C4FF01F0019009D0A985A9860192C3FF01F0019073
:202C620080FFA9850156A2000192C5FF01F0019081FFA9850156A2009492C2FF01F00190C3
:202C820082FFA9850156A20017D0008FC0DB82FE947ABE82BE86BE8B060006000052A88890
:202CA200C48A096509520763FF9CC4CDF8FF0790A8CAC496A69245520D614E5208614F5224
:202CC2000D60C41A2000C418BFFF086FC418DFFF056FC41A2000C41A4000A592015203603F
:202CE200C4187FFF02520360C41A8000C418EFFFC418F7FF0600BDB200D5013B008FC0DD15
:202D0200A9A8A581A98AC47D01DDA5924652F76433D1008FC0DD34D0BF569C0CBF56940C18
:202D22001F76400335D03BD1BF56940836D0BF56940937D0BF56941038D0BF56940839D0BD
:202D4200BF56940C3AD0BF56940C3DD0BF569C053CD10092FE9C949641D00092FF9C94966F
:202D62003ED0BF56940810D0BF56DC08BF56E465BF56F408BF56940DBF56EC1BBF569C12B5
:202D8200BE8B0600A9BD120F00770077BDB21F7671038BE60100A48B50E8094088E23C002D
:202DA200407679AF88E6000000770077A9BF120FC18AA993B7FFFF91D497C18AFF90DC96CA
:202DC200BE8B06000852A927A4C50960089A01D54E9B4076BB93008D3B03972BAB9209521C
:202DE2000B60089AA78A01D54E9B4076BB93008D3B03BF5697010600A71EBDB2A492BDAA81
:202E02000152BDA22A60008F5070C08D40D01F76410300A822761F76BE01408F28AE09CDE0
:202E2200FFF7A81A0004008FE3AD099709CDFFFD1F763700A81A000100A01F76BE01099720
:202E42001F76370002A81F763300321A0100321A0200237600011A7602523360008F507730
:202E6200C08DC0D31F764F0300A82276408F806F1F76BE01FDCDFFEF80769EADA58AA81A4D
:202E82000020079716DD07CDFF3F1ADCA81A008007971F763700C518CFFF408F59ADC41A6D
:202EA200040004C21F763300321A04001F76370006A01F763300321A0800237600011A7676
:202EC200D396A38A01D54E9B69FF089AC3864076BB93A2C4A2830BD0A28A0CDE0CDDC61AFF
:202EE20000400ADCC518FFDFCA18BFFFCA18DFFFCA18F7FFCA18FBFFCA1A0200CA1A010010
:202F0200C418FFBF92CCE0FF0BD0015092964076E893A38AA70640762F94D39202520560E2
:202F22001F76BF01081A0400C38A099ABF56E402A38A40764F94408D33030CD0932BA28A9A
:202F4200008D9E01932B9B2B0BDCC41A4000CA1A2000BE82BE86BE8B06001F764103BF56F5
:202F620002011F764F03BF5602021F764003009606000002008D4203941E0600BDB2BDAA76
:202F8200A486008D3A0392923660A9AA13FF6700A98A008D360301020156C4009206008D79
:202FA2003803920F0466C28ABF56E40208D092C5A7C408D0090201DE92C2C207A98A008D49
:202FC2003603C792C4969206008D3803920F4966C28AE446FE6CA28A099A40764F94D292A7
:202FE200025205601F76BF01081A0400008D9E01922B376F008D3803928A408D3803A492EA
:20300200008D36030190A98801DC9AA89206008D3803920F0466C28ABF56E402A6920B60B2
:2030220008D092830902C207A98AC592A7FFFF90C4960D6F08D09283A5C408D0090201DE20
:2030420092C2C207A98AC592FF90C496008D36039206008D3803920F0466C28AE446FE6CCD
:203062001F763300211A0001BE86BE8B0600BDB200BEACA0BDAAA486BDA2A98201DEA61B83
:203082003075FD69D292025205601F76BF010818FBFF00BE01DEA61B1027FD69408D360396
:2030A200A9AB08D09AA20109921E008D3A03922BC28AE446FE6CA28A089A40764F9401BE5F
:2030C200008D38030102A30F92C21C68A7AB0902C207A98AC792C496C28AE446FE6C00BEEF
:2030E20001DEA61BE803FD69A28A099A40764F94D292025210601F76BF01009A081A040038
:203102000B6FC28A0902A7ABBF56E401C207A98AC792C496009ABE82BE86BE8B0600BDB205
:20312200BDAAA486EFFF3901C28AFCCCFF00A958EC47EDFF2C01408DA0019A92E0FF2D01CD
:20314200408D3B039A920152116000BE408D3D03BF569A01408D34039AC2408D3F039A2BC3
:20316200408D3E039A2B0DD19A2B408D3F039A92E0FF1301408D3D039A924F60F2C4208F5C
:203182000000A9A8A60F06662F8F0000A9A8A60F0867608F00000AD1208F0000F2A09AA83B
:2031A2000CD19A923A52E0FFF800408DA0019A922E60408D34039AC4A692A94001DE9AC2BB
:2031C200066DF28A0356A008C496076FF28AA9A80109F21EA092C498008D34039206E20F6B
:2031E200E8FFDB000FD10CD0BF569A33A28A099ABF56923340764F94408D3F03008DA001EE
:20320200BF569A01BF569201EFFFC700008D3F03BF569201EFFFC100408D3E039A923E60A1
:20322200A0921F760403115425611F767C032454036024921F60A088408D31039A0EA60F29
:203242000560408D33039A921560A0921F767C032354076023920561408D33039A920A618A
:20326200408D3F03008D3D03BF569A01922BEFFF9400408D32039A78408D3E039A80019AAA
:20328200013BA7949A96A9AAA781A98A0ED1089A9C78A28A40764F947F6F9A80019A013B9E
:2032A200A7949A96A9AAA781A98A0ED19C78408D3E039A9207520E600DD19A9210520A6029
:2032C200408D33039A9206600A9A1F767703A0941096408D3E039A9203520B600DD19A59FF
:2032E200A19204520660059A008FC0DDA0949C96408D3E039A9202521A60A0920DD103523F
:203302009A78336842523166008FC0DD949203522C68A09233520B600CD19A923A5225605C
:20332200A09233520460008D3D03922B0DD09258408D3E03008FC0DD9A9294540467A91BA2
:2033420090012A68A28A099A40764F94408D3D039A2B0DD0408D3F03BF569A01408DA00104
:20336200BF569A01922B186FA28A099A40764F94408D3E039A2B0DD0408D3D03BF569A0182
:20338200408D3F039A2B922B076FC28ACC18DFFFC28ACC1A2000C28AEC46EDFFC7FE1F7600
:2033A20033000BDC211A0001C41A4000BE86BE8B0600BDB2BDAAA486A61EBDA2A582D29256
:2033C200025205601F76BF010818FBFF408D360308D09AC292A2008D3A03BF569201C28A97
:2033E200E446FE6CA28A089A40764F94008D38030102921EC28300BE0902BF56E501C20783
:20340200A98AC392A7FFFF90C496A692BE82BE86BE8B06000600A983C57C0600BDB2BDAA39
:20342200BDA206FE1F767B03A482BF5634010EDCEC92FF90A95AE492FF90A988A9AA37FFEB
:20344200A6AFA986DC92FF90A988A9AA37FFA6AFA986D492FF90A98809D0A9AA37FFA6AFCE
:20346200A9869492FF9008D0A9599492FF90A988A9B237FFA6AFA98BFC92FF90A988008DB1
:203482003203A9B237FFA6AFA98BF492FF90A988408FFFFFA9B237FFA6AFA98BA9A210FF54
:2034A200A101A71E441EA98A9392C7960202BF56CC3440762BB0A90E461EA28A465DA9B29D
:2034C200407601B0419644830102A38A4076A49544830102A38ABF56C5344076A4954192FF
:2034E200A90E461EC38AE446FE6CA9B2A38AA28340764697C38AE446FE6CA9A210FFA101B1
:20350200A983A38A4692A993FF91A7FFFF90C597CD960602D52BDD2B4076A49586FEBE82F5
:20352200BE86BE8B060006000600A98AC4920600A988BDB21F767103A9A8008D3203A48B70
:20354200BF560101BDAA10FFA101408FFFFFA71EA986A98A9193C7970202CF7E40762BB0E2
:20356200A9CDFF00A283A7FFFF90A18AD597DD960602E52BED2B4076A495BE86BE8B0600BE
:20358200BDB202FEA48B0EDCEC92FF90A980E492FF90A988A70637FFA6AFA71EDC92FF903B
:2035A200A9880129A70637FFA6AFA71ED492FF90A988412BA70637FFA6AFA71EFC92FF9005
:2035C200A9934196F492A838419620FF0080A70F0666A706415C40767897086FAD5CA79210
:2035E200029B81DCA45C40765B9E399AA18A4076059882FEBE8B0600BDB2BDAA02FE1F7695
:203602007103A486BF5601010EDCEC92FF90A980E492FF90A988A70637FFA6AFA71EDC9232
:20362200FF90A988A70637FFA6AFA71ED492FF90A988A70637FFA6AFA71E012920FF0080DF
:20364200A70F0666A706407602984196086FAD5CA792029B81DCA45C40769E9EA9AA008DED
:20366200320310FFA1011F767803A71EA98BA98A9292408FFFFFC796BF56CF384192FF905A
:20368200D7964192A7FFFF90DF961892A9CDFF00A7FFFF90E197E996060240762BB0A9CDE4
:2036A200FF0009D0A7FFA183A28AFF9008D1F597FD960A029D2B952B4076A49582FEBE866C
:2036C200BE8B060002FEA61EAC281F00013B2256A60740FF0156A400C492A640036CFF900D
:2036E200036FA7FFFF9082FE0600BDB2A48BBDAAE1C50AD09183A706A58A02194076CF98EE
:20370200A927A706A58A01194076CF98A1C5008D3203408FFFFF0EDF0356A908AB94A95A96
:20372200A78A9192C7960202BF56CF3340762BB00AD0A95DE106918A0219407601B0A98895
:20374200A20EA60F1061008D3C03912BD192025205601F76BF01081A0400A18A099A4076EE
:203762004F94096FA18A339A40760598008D3C03BF569101BE86BE8B0600A4830EDDED920A
:20378200FF90A980E592FF90A988A70637FFA6AFA71EDD92FF90A988A70637FFA6AFA71E0F
:2037A200D592FF90A98809D0A70637FFA6AFA71E9592FF9008D0A90EE41E9592FF90A988DC
:2037C200E40637FFA6AFE41EFD92FF90A988E40637FFA6AFE41EF592FF90A988E40637FF43
:2037E200A6AFE41E02020156E4000AD01F767B033A9AF4C394C3BF563401407605980600BF
:203802000600BDB2BDAABDA2A482008DA00193923D61408DA0010FD09B2B935A008FC0DD28
:20382200013BA9A8A281A98AC49203523268A91B90012F66A29233521A61008FC0DDA9A8C3
:20384200A281A98AC458A059408FFFFFA38A82D981D8A1880EDC035694089CCAA959A60631
:2038620040762BB0A188A90EA60F05600CD0A292937A1C6FD392025205601F76BF01081A7E
:203882000400A38A099A40764F94A928FFFF0E6FD392025205601F76BF01081A0400A38AA7
:2038A200099A40764F94A928FFFFBE82BE86BE8B0600BDB206FEA48B0EDCEC92FF90A90ED8
:2038C200421EE492FF90A988420637FFA6AF421EDC92FF90A988420637FFA6AF421ED49256
:2038E200FF90A98809D0420637FFA6AF421E9492FF9008D0A90E441E9492FF90A988440624
:2039020037FFA6AF441EFC92FF90A988440637FFA6AF441EF492FF90A9880DD0440637FF90
:20392200A6AF441E9492FF900CD0A90E461E9492FF90A9880BD0460637FFA6AF461E949200
:20394200FF90A9880AD0460637FFA6AF461E9492FF90A9880ED0460637FFA6AF461E94CC31
:20396200FF0004520A61055212604206448A46C4A69340769E9E076F4206448A46C4A693A2
:2039820040765B9E3C9AA18A4076059886FEBE8B0600BDB2A9A8BDAA10FFA101A98BA48619
:2039A200408FFFFFA98ABF56C1100602BF56C904D12BD92BE12BBF56E93040762BB0A9CDF4
:2039C200FF00008D9E01A7FFFF90F197A28AA183F9960802BF5692014076A495BE86BE8BF0
:2039E2000600BDB200BE00D0408FC0DBAA2B008F80DCA9A8A00DA98A9580C427A70EAB0FF8
:203A02000361C47F01BE01D8A0928052F168A6921061408D80DC809AA18A40763CB080D0FF
:203A2200A82802019196A18AA9287E3F40765B9EBE8B0600BDB200BE008DA101A9A8A60D73
:203A4200A71EA9A8A60DA98301DE0EDFC7929596A6920852F468A483408D9E010EDD03565A
:203A6200E508DD58EDCAA988A9A8408FC0DB10FFA101957EA983BF569C010A024076A495E2
:203A8200BE8B0600BDB2BDAABDA202FEA4860EDC0356E408DC2FECCAA927A9AA10FFA101B2
:203AA200A71E00D51F767C032492C7960356AB01BF56CF03D796AB922061A588AA92A672AB
:203AC200008FC0DB03D1A9A8A60DA98A0356A501A980A9AA10FFA101A61EA792A17204D09F
:203AE200C492C7FF9E96A792A07201DDC492FF909696AB92A554E2660356AB014196A993A4
:203B0200039A408FFFFFA894A959A9AA10FFA101A982A98AA10E40762BB0A9CDFF0004D010
:203B2200A7FF9B974193A073FF90AB280500089B9396AB9241944195A958069A4194A9800A
:203B4200079A4194932BA758A859932BA958A28AA383A10E932B008D9E019B2BBF56920117
:203B62004076A49582FEBE82BE86BE8B0600BDB2AC2BAB280800807608DF0C3505D106D016
:203B8200A483A172A072A9800EDD03569D089594AC5807D19696AB92A794A958A793A173CD
:203BA200009B95929DCA00520261019BAC92AC58408F00DF019C0852A92D9597DF68BE8B10
:203BC2000600BDB210FEAD5C89DCA45DAD5CC07600C18FDCA45C08F6852400D0C07609C10F
:203BE20005F68424008FC0DB942B01D8A0928052FC68A4C51F767A032A921F767A037EDF50
:203C0200C7962B920452086160D162D0BF569C0ABF569408116F1F76700300D0BF5620026B
:203C2200AD5C8FDCA45C9492008F22DC949601D8A0920652F66861D0008FC0DB1F767A0303
:203C4200BF5694653192046163D0BF5694141F767A0330921B611F767A032A882A92085212
:203C620081DE03652A8882DE00D00129008F34DC0356A603C07640DEA00D0156A700C79276
:203C8200949601D8A0920852F4681F767A032B9201521A601F767A033188012920FFF2FF96
:203CA20000D0A60F1161008FC0DBA9A8A00DA98A30D101D8BF569C4648D1BF569C3C319216
:203CC2000E9CA054F1661F767A032B920252216000D0008FC0DBA9A8A00DA98A01D830D144
:203CE200A092BF569CAA065248D1BF569C96F26806D0008FC0DBA9A8A00DA98A01D830D118
:203D0200A092BF569C73085248D1BF569C69F2681F767A032B920352116000D0008FC0DBD5
:203D2200A9A8A00DA98A01D830D1A092BF569C46145248D1BF569C3CF2681F767A032A92B9
:203D420009521B6000D0013BAD5C89DCA480008F80DEA7069481A71E008F08DCC792949683
:203D620001D8A0920F52F1683DD1008FC0DB3ED0BF569C46BF5694461F767A032B92065229
:203D82002B60008FC0DB30D032D19428A401A4C531D09428A40133D09C2884037ADF4BD17A
:203DA2009428840348D094282C0149D094282C014AD0942820039C282003C792A4C56ED0DB
:203DC20051D194967BDF6FD0C792949650D0BF569406BF569C101F767A032F920A6100D0DB
:203DE200008F30DC9428000801D8A0920452FB684076D88390FEBE8B0600BDB2408D80DC18
:203E0200A9287E3FA8280201A18A40769E9E809AA18A40763CB0A98080D0A988910EA70F3C
:203E22000E60A688012920FFFFFFA60F08611F767A032A887ED0910EA60F156140764E9B04
:203E4200408DC0DB7FD0912B40765E9A1F767A032E9217617FD91F767103C11A1000112870
:203E6200FFFF0F6F00D0008F80DC9492008FC0DB949601D8A0928052F7681F7670033F2BE1
:203E8200BE8B0600C4A0D41A01000600C4A0D41A02000600D493009A039100530260019A39
:203EA20006001F76BF010118F7FF06001F76BF01011A08000600227608D0408F806F1F764F
:203EC200BE0195CCFCFF015008960BDD08CCF7FF0450089608CCDFFF1050089608183FFF24
:203EE2001F76BF01C51A08000118F7FF1A761F76C10169FF0002BF560007BF56011F022BA6
:203F0200BF56040D0A2800800B2B0C2BBF560F10D42BC41E001A800006001F7676032588EA
:203F2200BDB2A48BA6921352E6FF5801C07612C10129A7060456A601A71EC7C52076C18AF3
:203F4200260ED40F0561BF562511EFFF470108D091C5673E1F767603252B262BD118F7FF00
:203F6200D118FDFFEFFF3A011F76C1010246ECFF3501C18A1F767603260EC407A71E1F76BF
:203F8200C10107921F767603C796BF562513260AEFFF24011F76C1010246ECFF1F01079286
:203FA2001F767603BF5625112796EFFF17011F76C1010246ECFF120107921F767603BF568A
:203FC200250F2796EFFF0A011F76C1010246ECFF050108D091C5673E1F76C10107400B6D7C
:203FE200D118FBFF1F767603D118FEFF252B262BEFFFF4001F767603BF562509EFFFEE0038
:204002001F76C1010246ECFFE90007921F767603BF56250B2796EFFFE1001F76C101024614
:20402200ECFFDC0007881F767603277EC18A260ED40F0561BF562507EFFFD00008D091C580
:20404200673E1F767603BF562509EFFFC7001F76C1010246ECFFC20007921F767603BF56AB
:2040620025072796EFFFBA001F76C1010246ECFFB50007921F767603BF5625052796EFFFDD
:20408200AD001F76C1010246ECFFA800079208D01F767603279691C5673E1F767603BF56E5
:2040A2002503EFFF9B00D140086CBF5625010AD0D11A040091C5673ED141ECFF8F001F76A8
:2040C20076030AD0BF56250DD11A080091C5673EEFFF84001F76C101BF56008F082B021A9A
:2040E20020001F767603BF562512776F1F76C101BF56008FC18AE4920896021A20001F7633
:204102007603BF562510696F1F76C101BF56008708280003021A20001F767603BF56250E4A
:204122005C6F1F76C101082B021A20001F767603BF56250C526F0AD091C5673E1F76C101AB
:20414200BF56008708280005021A20001F767603BF56250A426F26801F76C101BF56008FAC
:20416200C18AA706C407A71EC79208961F767603260A1F76C101021A20001F767603BF56CA
:2041820025082B6F1F76C101BF56008FC18AE4920896021A20001F767603BF5625061D6FE6
:2041A2000AD091C5673E1F76C101BF56008708280002021A20001F767603BF5625040D6FFF
:2041C2001F76C101BF56008708280006021A20001F767603BF562502BE8B06001F7630001A
:2041E200A880A927A48E142820400002008FB4DD1F767803181E4076B79C0052FD61A7929D
:20420200A793C0FF0191A995A880A7922661408FA8DDAB9220BE1F90A674A792A654026717
:20422200A7881F767603A65C0356AB01283AA90E2AA82C1E008FB4DD4076AF9C4076B79CD9
:204242000052FD61A93AA60DA98EAB92A694A927A792A69EA980DE601F7630001428104063
:2042620006001F763000A880A927A48E142820400002008FB4DD1F767803181E4076B79C3A
:204282000052FD61A792A793C0FF0191A995A880A7922661408FAEDDAB9220BE1F90A67444
:2042A200A792A6540267A7881F767603A65C0356AB012E3AA90E30A8321E008FB4DD4076FF
:2042C200B39C4076B79C0052FD61A93AA60DA98EAB92A694A927A792A69EA980DE601F7647
:2042E200300014281040060002FE1F76760338C5008FB4DD673E22761F763400008FDEB1AB
:204302001CA81A7669FF4076EBB01F7671030F8F40423A0642A8C0004EB2A9BD120F00777D
:20432200007702E84116008F16DE89E6000040762AB12376002082FE060002FE22761F76D4
:204342007A032B9204520460008FCFAA036F008F4AA31F7634001AA81A760F8F40421F76A1
:20436200710369FF3A0642A8C0004EB2A9BD120F0077007702E8D123008F0EDE89E6000038
:2043820040762AB11F7630000C2820402376001082FE0600BDB2BDAABDA2407697AA00D303
:2043A200103B69FF407678B2267600002F76000040763FB340765AB14076FF901F767A0367
:2043C200009A2A93407620AC0D9A40761A95418F00C201D4A9A0407669941F767A033192BE
:2043E2000860418F00C202D4A9A040766994076F012902D420FF00E1407669944076E19E91
:2044020040762990008FC06FA48300D20BDC0CDDC51A0100C41A0100012920FF50C34076D3
:2044220049B1008FC06FA48301DAA2920EDC0FDDC51A0100C41A01000A52EF64008FC06F8A
:20444200A4830BDC0ADDC51A0100C41A01004076F78F40762AB31F767A03109B2A924076A8
:2044620056B340760A9F407697B21F767A032B920452056140760DA5407638844076AE8585
:2044820040766A9C4076D8831F767A032B920652036040764EA81F767A03C076C0DB2A9278
:2044A2007EDFC79622761F76C001BF56292F1A761F767103BF5604011F76710303927D61B6
:2044C20063D0032B008FC0DB94920E611F76740363D03D0A94923D5407663D2B008FC0D386
:2044E20069FF4076369A00D2008F32DF013B408FC0DBA9A8A281A98AA9A0A281A98360D045
:20450200C40A9592C4545566005253611F767C0332924F61408F30DFC42BA9A0A281A98AD7
:20452200C49280520868008F30DF013BA9A8A281A98AC42B013B086F109AA794A9CCF0FF75
:20454200C4968052F167008F30DFA9A8A281A98AC4800356A203408FF0D8A61EA792C3FFF8
:20456200A927A606AB0D0156A500A7CD0F00A82DC59262FFA988E161013B0A6F008F30DF33
:20458200A9A8A281A98AA692A0FFA988C40AA640F66C408D30DF013BA9B2A281A98B008FFB
:2045A200C0DB69FF009AC19340760DADC108030001DAA292025299647FD0008FC0DB94411E
:2045C200076C7FDC69FFC418FDFF40764E9B7FD0008FC0DB9442076C7FDC69FFC418FBFFD1
:2045E20040765E9A7FD0008FC0DB9443076C7FDC69FFC418F7FF40766A9C7FD0008FC0DB7E
:204602009445076C7FDC69FFC418DFFF4076538069FF40761C921F767A032B9201521360E5
:2046220016D0408FC0DB9592A58AC1FF01F016D0A3CE0356A9027FDC0790C49895CC040013
:20464200C1FFA95B2B9206525A607FD0008FC0DB94921F767403A99300B6D6FFC5FF0191FD
:204662000190A9883E92026001B6A892A7CE1B61008FC06FA4831F767A030BDDC51A004064
:204682002B9206520761045205610DDCC41A0020056F1F76BF01041A0800008FE8031F76FA
:2046A2007B0308A81F7674033F9200B63E97026001B6A693A7CF16611F767A032B931F76BE
:2046C200BF010B1A000406530661045304610B1A0020036F021A0800008FE8031F767B030B
:2046E20008A81F7674033F7E1F767B03080607601F76BF010D1A00400D1A000400D2A292CA
:204702000461408D40D0036F408DC0D3A18A40766E99A91BFFFF59611F76BF0100BE0F1AE3
:2047220001001F76780337523EC213623752326133520A6233523A610352446104523E614C
:2047420006523861426F34522D61355227613D6F3A5208623A5212613852186139521261F0
:20476200346F3B5207613C523060A18A4076C6992C6FA18A40766D99286FA18A40762A9984
:20478200246FA18A40762D98206FA18A407669981C6FA18A40760098186FA18A4076019868
:2047A200146FA18A40767B97106FA18A4076E2980C6FA18A4076879A086FA18A4076249B13
:2047C200046FA18A4076AF9A01DAA2920252E3FF75FE966F1B76F0FF0500BDABBDAABDA8C4
:2047E200BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0303E2BD0430E672
:20480200000602FE69FF422916561F7633002292419623760100267601012218FA00212849
:20482200FFFF10291F767B03240604610102415624001F7671030492E1FF99011F767103BD
:2048420011920D61FF9C11960A60008FC0DBA4837FDC7FDDC518EFFFC41A04001F767A03D2
:204862002F92196100D2008F0871013BA9A8A281A98AD492C3FFA988008F3CD7A9A8A281CF
:20488200A98A69FFA292C47E4076568601DAA2920452EA641F767A032B9206523A601F766A
:2048A200C4010992C3FFA90EA9BD120F0077007763D0808DC0DB8BE60400008F40D78CE640
:2048C200200069FF13E29200CFE62000407617B26ED16FD0013B008FC0DB9A92929EA98505
:2048E200A9BD160F6FD0C8E29402CFE6040020E7A00089E60900407679AF50E800C800777F
:2049020090E8008800778CE600001DD013E292001F767A032B920552436000D21F76710394
:2049220006921F767B03210A21540262212B008F0871013BA9A82181A98AC492C3FFA90E41
:20494200A9BD120F212D69FF008F40D712358BE604000156A400CFE62000407617B2013B2B
:204962001F767B03008F21DD8EE60000A9A82181A98A13E2C400008F80DEA9A82181A98A2F
:2049820001DAC4920852056121924076EE82056F2192009B40761181A2920652C0641F76FC
:2049A2007A032E92E1FFE3001F767B0320881D0EA60F1A601F767A032C931F767B03219249
:2049C20000530F611F767103055402600D9A1F767B0321931F767103059F015302600C9AD7
:2049E20069FF40764B901F767B031E92205472671F767A032E9200D26D651F767B03212DD5
:204A0200008F0871013B1F767A032E12A294A959A9A8A281A98AC492C3FFA980A7BD160F55
:204A2200A188008F21DDA9A8A681A98A8BE60C00C4E2C400007720E7000100778CE60000C4
:204A420000771F767B03A9BF120FA98556FF009B1F540267019B1F5422970767008F34DF6F
:204A6200A9A8A281A98AC40A008F88DDA9A8A181A98A009AC49300530260019A22CA246173
:204A8200A12D008F40D71235CFE6200069FF0156A400407617B21F767B03240608618EE688
:204AA200200000770077A6BF120F076F8EE6000000770077A6BF120F008F21DD013BA9A8E8
:204AC200A181A98AC47E01DA1F767A03A2922E5495641F767B031C92200A20544766202B4A
:204AE20069FF4076DB9000D21F767A032E9220651F767B03212D1F767A032E12A294009B7E
:204B0200A95940761181013BC07634DF008F88DDA706A281A71EA9A8A181A98A01DA1F7625
:204B22007A03C792C496A292C72B2E54E2641F76710305921F767B03029C210A21541662EC
:204B42001F767A03319200D21F767B03212B0E651F7671030692019BA2944076118101DA44
:204B62001F767A03A2923154F464008F0071A4831F76330019DC01DDC51A0040C41A100041
:204B8200BF562101103B419282FE2296AFE2BE04AFE2BE03AFE2BE02AFE2BE01AFE2BE00F1
:204BA20080E2BE00BEC5BEC4BE83BE8ABE86BE870300303BF1FF177602761B76F0FF0500D4
:204BC200BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E667
:204BE200000602FE69FF42291656227601021F767803015610002376001026763911102994
:204C02001A767FD0008FC0DB944F046D69FF407672A91F767103020A029214520468022B54
:204C2200BF56030116D1008FC0DB7FD09C9294CA0190A9880C9301F10191A6CB10601F7612
:204C42007A032B93065306611F76BF010B1A0008146F1F76BF010B1A00200F6F1F767A0328
:204C62002B93065306611F76BF010F1A0008056F1F76BF010F1A00200653E1FF4B011F7602
:204C82007103150A15930A53E0FFA1001F767A032B931F7671030553152B03601B932260F6
:204CA2001F767A032B93015305601F7671031A9319601F767A032B9306530F6104530D61DC
:204CC200025306611F76BF010B1A0004226F1F76BF010B1A00401D6F1F76BF01021A00024E
:204CE200186F1F767A032B9306530F6104530D61025306611F76BF010D1A00040A6F1F7683
:204D0200BF010D1A0040056F1F76BF01041A00021F76710319930F601F767A032B93035337
:204D2200136101531161065319601F76BF01021A8000186F1F767A032B9303530F61015303
:204D42000D61065306611F76BF010B1A00100A6F1F76BF01041A8000056F1F76BF010D1A3D
:204D620000101F7671031A9315601F767A032B9306530B610353046101531561196F1F76BF
:204D8200BF010B1A0040226F1F76BF01021A80001D6F1F767A032B930653146103530D617C
:204DA200015306611F76BF010B1A00800F6F1F76BF010D1A00800A6F1F76BF010D1A00408D
:204DC200056F1F76BF01041A020000523E601F767103158062D0940EA70F37601F767A0327
:204DE2002B9303530F6101530D61065306611F76BF010D1A00100A6F1F76BF01021A8000B5
:204E0200056F1F76BF010B1A001006530E6103530961015304610D1A0080096F0B1A00808D
:204E2200066F0B1A0040036F021A800006530B6104530961025304610B1A0004066F0B1A85
:204E42000040036F021A00021F767103009A1C9300530260019AA693A9CF04611428F40197
:204E6200162B140AC4E214001C7E12E8D01F14AD5364160A1693019100B6142B1797169375
:204E82000791026101B6A692187F3C601F767A032A92095224611F76710316D0BF56190127
:204EA20094937FD0D0FF9492C9FFA8CAA940026C197F0C42116D0C430C6D0C44036D1A2BC3
:204EC2002B6F1892009B00520260019B1A97246F17921A96216FBF561A011E6F1F767103AE
:204EE2000C41BF561B01036C1792026F009A0C401A96036D192B106F179317921B9719962C
:204F02000B6F17931788179219971B961A7E046F69FF4076BDA882FEAFE2BE03AFE2BE0211
:204F2200AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF177602767A
:204F420002FE2276008F57A11F7635000AA81A7669FF4076F8B21F763300221A200023769F
:204F6200010000D5013B008F88DDA9A8A581A98AC42B008F21DDA9A8A581A98A01DDA59244
:204F8200C42B1C52F1641F767A032B9206522360008F00711F76C401D4CCF0FF05500296DD
:204FA200DCCCF0FF0350039603CC1FFF1050039603CCFFF1A91A0005039603CCFF0FA91AC6
:204FC20000400396E4CCF0FF0750049604CC0FFF205004961F767A032B9203521460008F57
:204FE20000711F76C401D4CCF0FF02500296DC18F0FF03CC1FFF1050039603CCFFF0A91A21
:20500200000203961F767A032B9201522860008F00711F76C401D4CCF0FF06500296DCCCCA
:20502200F0FF0550039603CC0FFF4050039603CCFFF7A91A0007039603CCFF0FA91A0020A3
:205042000396E4CCF0FF0350049604CC0FFF6050049604CCFFF1A91A000104961F767A03D1
:205062002B9202520960408F0071A58A02DCC418F0FFDD18F0FF2B9205524C60408F0071B8
:20508200A58A1F76C40102DCC41A0F00DDCCF0FF0250039603CC3FFF3050039603CCFFF053
:2050A200A91A0006039603CCFF0FA91A00C00396E5CCF8FF0A50049604CCBFFFB0500496CF
:2050C20004CCFFF7A91A0007049604CCFF0FA91A00400496EDCCF0FF0550059605CC1FFFA2
:2050E2001050059605CCFFFEA91A000E05960518FF0FF5CCF8FF08500696061AF00006CCC0
:20510200FFFDA91A000D069606CCFF0FA91A00900696408F0071C0760068A5C41F76C401B5
:20512200A78A1AD019DD01DEC61A000119DC011A0008C51A1000001A10000018BFFF001A7B
:20514200000F011A00401F763300BF5621011F76A001C41A000819CCFFFCA91A0004199672
:2051620097CCFFFDA91A00011A96BF56098000CC7FFCA91A0001009600CCFFE3A91A0008A2
:20518200009600CC001CC9FFA92D019A66FFA98800CC800304600102AC1E076F00CC80037B
:2051A200C6FF80FFA985AC1EA6851F7671034456A900421E3A06C0004EB2008FA60E42A8AD
:2051C200C0004EB21F767A03008F4C1D2B931F76A00105960018FCFF1F767B03025326A82B
:2051E2000C60008F8A66BF561C0FBF561D04BF561E09BF561F1426A81F767A032B920352D6
:205202000E601F767B03008FF22BBF561C0ABF561D01BF561E04BF561F1426A81F767A0392
:205222002C920E611F767B03008FF22BBF561CFABF561D19BF561E96BF561F1426A81F7696
:205242007A032B9206520660008F7C921F767B0326A805520660008FA60E1F767B0326A8F5
:205262001F767B03260682FE241E0600005206601F76BF01041A0001056F1F76BF01021A14
:2052820000010600005206601F76BF01041A4000056F1F76BF01021A400006004076A3A670
:2052A200019A4076AFA6009A4076A3A6010240765BB3009A4076AFA61E0240765BB3060057
:2052C200009A4076AFA61E0240765BB3019A4076A3A61E0240765BB3009A4076A3A61E020C
:2052E20040765BB30600BDB2BDAABDA20EFE00D2A98BA288A492A52D0252A65BE3FFF00042
:20530200A9B2026301D256FFA983AC9205640452036301D3026FAC2BAC92A58B4B2B0B65A4
:205322000A02421EA9B2C0004EB24B0AA98BAC924B54F762A9B20A650A02421EA9B2C000D4
:205342004EB201DE58FFA98BF862A292A58BA694A988026001BEA692AC944B2B0452A98822
:205362000F650A02421EA9B2C0004EB2AC80A98B4B0AA69281DFFC9CA72D4B54F362AC9245
:205382000263AC2B019A66FFA9580152026000D08076E803A9B242C2C0004EB2441EA9B28C
:2053A20042C2C0005DB2A61E6402421EA606C0004EB2461E6402421EA9B2C0005DB2A61E0A
:2053C2000A02421EA606C0004EB2481E0A02421EA9B2C0005DB24A1EA61E460648074407E5
:2053E200A607046000D0A02DAC5AA3921561039A013B4B96AD888ADEA6880356A90101566D
:20540200A600C6060960AC924B5406610F024B0BC61E4B92F062A2922061019A013B4B9684
:20542200AD5D8ADDA55D0356A9010156A5000F02C50F09614B9203520661019C04524B963C
:20544200F0640B6FAD5D8ADDA55D0ABE4B920356A9010156A500C5C2009A4B2B013BAD5D88
:205462008ADDA55D0356A9010156A5008076B0DAA606C507A61EC685C51E019A4B2D66FF60
:20548200A0CE046180020156C5004B0A4B920452E76448A3AB92AA2BFF90A927A9A9AC2844
:2054A200180037FF5AFF4A064E1E4E92FF904E964D2B4E06ABCAAACB4E1E4606009BFF909C
:2054C2003FFF5AFF4E06ABCAAACB4E1E44063B565AFF4E06ABCAAACB4E1E026F4EB2408F6B
:2054E2001EDF013BA9A0A481A98A4B2BC45BA3921052246200D14E92013B0190A9884E061B
:2055020040FF4E1EA6924076BBA601D9A1920852F364A35A00D1A293A292B0FF0190A85A58
:205522004076BBA601D9A1920652F6644076CDA601DB4B0A4B920452DB648EFEBE82BE86B7
:20554200BE8B0600009A019C1952FE640600005206601F76BF010D1A0010056F1F76BF01E3
:205562000B1A00100600BDB21F76BF01BDAA0D1A0008BDA2A95B010240765BB300D1808D8C
:20558200C06FA28AA392CEFF0BDCC41A0080407614A8A39280FFA95B010240765BB30DDA8F
:2055A2000102C21A008040765BB301D9A1921052E7641F76BF010B1A0008BE82BE86BE8BBD
:2055C20006001F767B03008F5902BF5600050128701706A80600BDB2BDAABDA202FE79D0CA
:2055E200008FC0DBAC1E013BA98B94854C82A61E4456A90042A2C0004EB278D0A98342A25B
:20560200215694004456A100C0004EB27FD0A607A5039449046C7AD0013B9485A918FF0F23
:20562200A95AA91A0080407620A87BD0A9B2408FC0DB34FF957AA61EA9B242A232FFA60771
:20564200C0004EB2A98A42A2C802AC1EA9B24456A900C0004EB21CD0A49E82FE289C9596E2
:20566200BE82BE86BE8B0600A9280290407620A81F767A032B9206520F6104520D610252C5
:2056820006611F76BF010F1A00040A6F1F76BF010F1A0040056F1F76BF01061A00020600F7
:2056A20002FE1F767B03080604610102415608000092020A0254E6FFA8000606022BE0FF27
:2056C20084007FD0008FC0DB9447566C0592346050D0013B9492FC9CA985A9BD120F0077BD
:2056E20000770077007789E6000051D003E20A009492FC9CA985A9BD160F007720E80000CE
:2057020003E20A0032E8000589E6090003E20A0003E20C01AFE20C00AFE20A0132E8000CC1
:2057220003E20C0094E6080014AD06628FE808E0007703E20C000192C0FF03540267030AE5
:205742000192030A035402670396AFE20A00AFE20C01C4E20103C4E2030220E709004FE879
:2057620000604FE8096000E7180000E75100007710E74000086F0492032B90E5019CA91834
:20578200FF0304967FD09493A892C6FF0190059604920E61A8480C6D8CE600000188013B25
:2057A200A9BF120F42C2A985407658A82D6F4076A1A81F767B03008FC0DBBF5604017FDC29
:2057C200C418FFFE216F06060119A61E061E20FF5802A60F136120FFF401060F0F6120FFF6
:2057E2009001060F0B6120FF2C01060F0761C802060F04616402060F07604076A1A81F7612
:205802007B03BF56040182FE060011D0008F107094920F9004520E60CCCC8001C6FF0252BD
:20582200096022761F76C001BF562555BF5625AA1A7669FF060022761F76C001BF5629680A
:205842001A7669FF0600BDB202FE1F76C001A888A9801143026C257611CC80010561227671
:2058620011187FFE1A762276408F1070A58AA79211D00F9001DCC41A400095CDF0FFA8CA63
:2058820021961A76A79204600102A98B026FA759A92880C3A828C90169FFAC1E0556A1009E
:2058A200407688A9A1A91140FF6C22761118BFFF1A76A6930153036102530A602276A6926A
:2058C20011CD7FFE039086FFA8CA11961A76A6930A60A9B2013BAC281E0040FF2256A1071F
:2058E20041FFA98BA69301530A60A9B2013BAC281E0040FF2256A10741FFA98BA693025351
:205902000960A9B2AC281F00013B2256A10740FFA98BA7921460A69203521160227611CCDF
:205922007FFFA91A000169FF119620FFDA0540765BB31F76C001111A80011A761F767103B7
:2059420082FE69FF3AB2BE8B0600BDB202FE22761F76C001BF561A011B2B1A92036001BE81
:20596200046F03561A01A9881F76710342C269FF3A06C0004EB23E1E1F76C0011B920360D6
:2059820001BE046F03561B01A9881F76710342C23A06C0004EB2408D1070A18315D0008F3B
:2059A200200B3C1E0CDD1F762C0094CCF8FF015014DC3596C41A04003418F7FFC51A080048
:2059C200787680001F76C0011C1A1000A18A1C1A00041C1A00081C1A20000DDC10D91C1ABA
:2059E20000011C1A00101C1A00201C1A00401C1A00801C18FBFFC41A01001D1A02001D1A5F
:205A020004001D1A08001D1A10001D1A20001C1A04001D1A00041D1A00081D1A00101D1A71
:205A220000201D1A00011D1A00021D1A00401D1A0080C11A0001201A0002201A0004201A15
:205A42000008201A0010201A00201A7669FF82FEBE8B0600407688A9049A029B407690A9C0
:205A6200407612AA060002FE22761F762B002028FFFF2128FFFF2228FFFF2328FFFF2428EA
:205A8200FFFF2528FFFF2628FFFF2728FFFF1A761F76FFCF69FF38924196399241963A92B8
:205AA20041963B9241963C9241963D9241963E9241963F921F762B0041962F9201F00190CC
:205AC20082FE06001B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD01AC
:205AE20003E2BD0203E2BD0330E6000669FF4229165600D1227601021F767803015610001D
:205B02002376391110291A767FD0008FC0DB944F046D69FF407672A91F767103020A029228
:205B220014520668022B1F767103BF560301008FC06FA4831F767A0306DDC51A01002B92C9
:205B420006520E6104520C61025205610FDCC41A00040A6F1F76BF010F1A0040056F1F76F2
:205B6200BF01061A00021F767A032B9206520861045206611F76BF010F1A0020056F1F764D
:205B8200BF01061A080001021F7678033E07A61E008F204E3E1EA9A8A60F02673EA83B0A0C
:205BA2003B920A5202643B2B3792AC2B1261008FC0DBA9A8AC0DA98A62D094923B54046524
:205BC200019A66FFA172AC92019C3754A92DF0683A0A3A92025202653A2B7FD0008FC0DB73
:205BE2009493A89216D094CAA940EDFF8300A84B586D20FF204E3E0F30693A920A60013B09
:205C02001F766F0300D401D569FF00854076E0A61F7678033A9201520A60008FC0DB013BA9
:205C220001D569FFCC8501D44076E0A6A192408DC0DB02D400D569FFD1CEA90E4076E0A682
:205C42001F7678033A9202527B60013B03D400D5D9854076E0A6746F3A92076000D40002C9
:205C620000D569FF4076E0A61F7678033A920152076001D4000200D569FF4076E0A602D4ED
:205C8200000200D569FF4076E0A61F7678033A920252566003D4000200D54076E0A6506FF8
:205CA2003A92086020FFB82200D401D569FF4076E0A61F7678033A920152086020FFB822D7
:205CC20001D401D569FF4076E0A6A10E02D400D569FF4076E0A61F7678033A9202523060B5
:205CE200012903D400D520FFFFFF4076E0A6286F69FF4076C0B23A920760013B00D404D530
:205D020036854076E0A61F7678033A9201520760013B01D404D536854076E0A61F76780303
:205D220002D400D53C064076E0A61F7678033A92025206603C0603D400D54076E0A6AFE2E7
:205D4200BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303B2F
:205D6200F1FF1776027634FEA892FF9C0564105204640F9A026F009A22761F76BE01AB287F
:205D8200F0FFAA28457F09CDFFDF013B08BEA81A001008D4A0A908B6099709CDFF3FA81A9B
:205DA20000400997A9851F7680015AFF2AC25D56A000A5A92CA8AB2BAA28467F1F7684017C
:205DC200AB0302C3AB28FEFFAA28FFFF00B60AC21F76800103BE00C31F76840100A0081EB2
:205DE2001F76800102A900C200BE0002011960C2601A80F2081E000260C401190C1E0002A4
:205E020001191E1E00020119221E00020119181E14C21844FF6C16065E1E5E18FFFD5E1A5D
:205E220000015D1800FF5D1A05005E1A7F005E18FAFF5EC416C26018FFEF6006141E1844B5
:205E4200FF6D0002488F70641F768301541E088F7064541A010000A00031531A020001027F
:205E620000BE02A8541A06001F768001408FA1B000D4301E54C5020232A82EA9008F76B069
:205E82001F76370008A01F768001241E26C220C31F7637000AA81F763300321A1000321A7B
:205EA2002000237600011A761F767B0369FF000200B60E2B141EB4FE10C212C30600BDB22A
:205EC20006FE00021F7678030ED03E1E94C4A606A80EA9580CD19CC5467EA0CC00804396EE
:205EE200A0CC00404296A0CC00204196A018FF1FA70645974392447F00520861A092805203
:205F020005674692008FC0DB9496429201D80861A092805205674592008FC0DB9496419263
:205F220001D80861A092805205674492008FC0DB94961F76BF010F1A010086FEBE8B060031
:205F42001F767B030F92A88809611F7680010806A940046D0A06A9403E6C02D5A692013B85
:205F6200AB28010001B6A572AA2B1F768001A9A8A581A98308A90AC301B6C58500915AFF86
:205F8200A692A772A9A8A781A983C5853FFFABCAAACBA71EA9A8A681A98A1F768401C485C4
:205FA20000915AFFA6853FFFAACBABCAA81A00E0061E04C322761F76800100022E1E1A7689
:205FC2000102041E1F76BF010E1A01001F767B03BF560F0169FF06001B76F0FF0500BDAB89
:205FE200BDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000695
:2060020002FE69FF422916561F763300329241962376000126760001321875002128FFFF9F
:206022001029408FC0D369FFA58A4076269540762B95103B4192329682FEAFE2BE03AFE2FC
:20604200BE02AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF177601
:2060620002761B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E22F
:20608200BD0203E2BD0330E6000602FE69FF422916561F76330032924196237600012676A6
:2060A2000001321871002128FFFF1029408FC0D369FFA58A407626954076FC95103B4192D3
:2060C200329682FEAFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8A86
:2060E200BE870300303BF1FF177602761B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD00A9
:2061020003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FE69FF422916561F763300CC
:206122003292419623760001267600013218FD002128FFFF1029408F40D069FFA58A407698
:20614200269540762B95103B4192329682FEAFE2BE03AFE2BE02AFE2BE01AFE2BE0080E202
:20616200BE00BEC5BEC4BE83BE8ABE870300303BF1FF177602761B76F0FF0500BDABBDA8D7
:20618200BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FE58
:2061A20069FF422916561F7633003292419623760001267600013292322B2128FFFF102963
:2061C200408F40D069FFA58A407626954076FC95103B4192329682FEAFE2BE03AFE2BE0286
:2061E200AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF17760276A8
:206202002276008F806FA483A4C41F76BE0126DDC51A030027DE261A0C00A483261A3000B6
:20622200261AC000261A000317DD261A000C261A0030261A00C0C61A0300271A0C00271AF8
:206242003000271AC000271A0003271A000C271A0030271A00C0C51A0300A48328DD171AC9
:206262000C0016DC171A3000171AC000171A0003171A000C171A0030171A00C0C51A030027
:20628200281A0C00281A3000281AC000281A0003281A000C281A0030281A00C0C41A00C095
:2062A200161AC000161A0030161A000C1A7669FF06002276008F806FA4C4A4831F76BE0159
:2062C20018DEC61A030019DD181A0C00181A3000181AC000181A0003181A000C181A003086
:2062E200181A00C0C51A0300A48369FF191A0C0014DD15DC191A3000191AC000191A00038C
:20630200191A000C191A0030191A00C0C51A0300141A0C00141A3000141AC000141A00034D
:20632200141A000C141A0030141A00C0C41A0300151A0C00151A3000151AC000151A000339
:20634200151A000C151A0030151A00C040766DAE0600227615D0008F200B1F762C0094CC83
:20636200F8FFA483A4C5A4C40150359614DDC518FCFF0CDF3418F7FFA4830DDE341A0400B6
:20638200C41A60000EDDC41A1C00C41A0300C41A0030C41A000EC41A8001CC1A4000C41A9A
:2063A2000040C41A0080211A0300C71A60002C1A1C002C1A03002C1A00302C1A000E2C1A03
:2063C2008001C61A40002C1A00402C1A00802D1A0300C51A6000A4830FDD2E1A1C0018DCDA
:2063E2002E1A03002E1A00302E1A000E2E1A8001C51A40002E1A00402E1A00802F1A0300FE
:20640200C41A0700381A38001A7669FF40766DAE07F6007769FF0600BD3ABDB2BDAABDA234
:2064220002FE0129A9BF120F58FF5B61A85C7F91A8088000421EA493D6FFA85CA9BF160F53
:206442006761A85D7F91A8088000A859A958A593D6FFA85DA493A571A8180001A697A41812
:20646200FF00A518FF007FDCA492A59EA7964D64A90801FF3E62A193A09236FFA859A958AF
:20648200420635FF0EF6A11FA95BA3010AF6A11F2D56A204A32DA03640FF0BF6A11F33FF51
:2064A200009B30FF54FFA20CA39540FFA70801001FF677FF200940FFA70801001FF677FFBA
:2064C2005AFFA7922265A90801FF1363A9A946FF7F91A85BA95AA625A79596FFA20CA3954B
:2064E200A9BD120F82FEBE82BE86BE8BBE8E0600009B57FFA8087FFF5AFFA693F260A828A1
:206502000080AA71AB92ED6F20FF0000EA6F5AFFA493A818000196FFA85CA9A9A8087FFF63
:20652200A81C0080A4CBDD6F58FF5AFF00BE25610129A6920190A958A60640FFA407A71E17
:20654200C793A640046DA892C7FFA92DA09201520460A8CCFF00A92DAC58A592A0F201DED4
:20656200A092FF90A958A592408FC0DAC7FF9570A95DA9A9A60FDE66A5920600A71E8076A3
:20658200C0DA0A6FA5928470FF90A95881DFA592C7FF9670A95DA706F660A5920600005230
:2065A200A927FF76FFFF00BE3365A9A8013BA681A983A793C592FF90A92FAA71A880009A8B
:2065C200A740046DB0FFA880056FB0FFA81C01A0A880019C0852F564A9A8013BA681A983AA
:2065E200A793C592C7FFA92FAA71A880009AA740046DB0FFA880056FB0FFA81C01A0A880AE
:20660200019C0852F56401DEAB92A654CF62A79206001B76F0FF00E2BD0030E6000602FE67
:20662200422916561F7633003292419623760001267600013292322B2128FFFF1029010243
:206642001F767B030E0A1F768001061E1F763300211A0001103B419282FE329680E2BE0049
:20666200303BF1FF177602761B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD00C9
:2066820003E2BD0103E2BD0203E2BD0330E6000602FE69FF422916561F763300329241964E
:2066A20023760001267600013292322B2128FFFF1029008F006169FF4076CCAC1F76800164
:2066C20002020C1E1F763300211A0001103B4192329682FEAFE2BE03AFE2BE02AFE2BE012D
:2066E200AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF1776027600021F765C
:206702003000008F000C0119021E1F767803408F100C000206A81F763000062B0119072B85
:20672200E41A1000041A20001F763000008F080C0A1E1F76300000020119121E1F763000A5
:2067420000020E2B0F2B1F7678030EA816A0081E1F763000162B172B1F763000E41A100005
:20676200E51A10000C1A20001F763000141A20001F767803181E101E060000E0E45003E23C
:20678200F40188E61000C48303E2D500C483F52BC483FD2BC483E51A1000C483E51A2000F1
:2067A200C483E518FFFBC483E518FFF7C4830002E51A0040D41E06000129BDB240FFBDAAA0
:2067C200A98B00D20861100240765BB301DAA9B2A20FFA66BE86BE8B06001F76C001201A08
:2067E200001040766DAE2276008F200BA4C4A4831F762C000ED015DE14DDC618F8FFC51A9E
:2068020003003418F7FF3418FBFF94CCBFFF20502E960FDC2ECCE3FF08502E962ECCFCFFC1
:2068220001502E962ECCFFDFA91A00102E962ECCFFF7A91A00062E962E187FFEC418BFFFF8
:206842002E18FFBF2E18FF7F2F1A03001A7607F6007769FF0600AD28000469FF1F5616568E
:206862001A5610E6000240291F76000002291B762276A9285FB3A828000001091B61C076ED
:206882005FB304290F6F009BA92401DF046C0429A82401DFA61EA1F78624A706A1810109C9
:2068A200A71EA92403635CFF043BA95901DF0900ECFF1A76A928FFFFA828FFFF01090E61C8
:2068C200FF76FFFF066F01DFBDC3A71E673EBEC5A92401DFA82458FFF7604076DDB240765F
:2068E20013B31B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E259
:20690200BD0203E2BD0330E6000669FF42291656227601021F76780301561800008FB4DD7C
:2069220069FF1F7676033AC5673E1A76AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE0049
:20694200BEC5BEC4BE83BE8ABE870300303BF1FF17760276BDB2CFE6010008D003E2BD045C
:206962000ED103E2BD0503E2BD0603E2BD07AFE2F400AFE2D40510E394040CD012E39C1F38
:206982000ED118E394DA0AE3C4A000E3E4C600E7BB0110E700010CD010E7C00003E29C021E
:2069A20003E2940008D0F406941E03E2F401AFE2BE07AFE2BE06AFE2BE05AFE2BE04BE8B63
:2069C2000600022904295F565AFF42065F56421E00021FF617564200AB063256022920762C
:2069E200022904295F565AFF420656FF421E00021FF6175642003256022920765AFF0002C8
:206A02001FF617564200A9A920765AFF00021FF6175642002076103B1F7633002018FEFFCB
:206A2200222B242B69FF262B282B2A2B2C2B2E2B302B322B342B362B382B232B252B272BDC
:206A4200292B2B2B2D2B2F2B312B332B352B372B392B06001F763300201A01002128FFFFA8
:206A6200102969FF0600A0E514AD0962A0E51F767C0314AD90E5B4562701156F4FE803C03D
:206A820092E601008CB5050000E7CA00007700E78A000077CFE812F0007700E75100007746
:206AA20000E74000060002FE1F767803380AC4E23800007712E8D01F14AD1164390A3992D3
:206AC200382B0A520260392B3934570436963C0603610002036F000201193C1E82FE060085
:206AE200A928FFFFAA28FFFFAB28FFFFA828FFFFAB0F04ED00D400BE0B6FA927A928FFFF00
:206B0200A92FA4A9C488A928FFFF0209A98AA6924076379F060022761F76C00169FF1C1A9F
:206B22000800787680001A761F76C401028FE6491CCCFF3F69FFA91A00401C96BF5618E0E3
:206B4200A9A840765BB306000077006F1F767C03BDB22AC5A959673E1F767C032EC5A70665
:206B620003ECA192673E1F767C032C0603ECA71E673E407611B3BE8B0600608F00001F7660
:206B82007B03208F00FA38A03AA838063C1E3E2B3806046FA98A842BA9A81F767B033A0FD1
:206BA200FA680600408F00C0008F000D2276009A85C4019C805284C2FC641A7669FF0600B2
:206BC2001F767C0328A806001F767C032AA8060006001F767C032397249606000119C35616
:046BE200FFFF0600AB
:206BE6001201000000C07E8B00007E8B00007E8B00007E8B00007E8B00007E8B00007E8B7D
:206C060000007E8B00007E8B00007E8B00007E8B00007E8B00007E8B00004C8C00003F8C95
:206C26000000CF8F0000718B0000E6880000888B0000598C00001C8A0000118A0000068ABD
:206C46000000FB890000F0890000E5890000DA890000CF890000C48900003D8A0000328A38
:206C66000000278A0000B48A0000998A0000E68800009089000077890000DC8F0000488A38
:206C86000000A9890000DE8D0000A88D0000728D00003C8D0000068D0000D08C0000E688F7
:206CA6000000E6880000F98D0000C38D00008D8D0000578D0000218D0000EB8C0000E688F9
:206CC6000000E6880000A68E00008B8E0000708E0000558E00003A8E00001F8E0000E6882F
:206CE6000000E6880000B58C00009A8C0000E6880000E6880000E6880000E6880000E68893
:206D06000000E68800007E8A0000638A0000C98B0000938B0000E48B0000AE8B0000E68882
:206D26000000E6880000B48F0000998F00007E8F0000638F0000488F00002D8F0000E68874
:206D46000000E68800007F8C0000648C0000E6880000E6880000208B0000CF8A0000E68876
:206D66000000E6880000568B0000058B00003B8B0000EA8A0000128F0000DC8E0000F78E64
:206D86000000C18E0000E6880000E6880000E6880000E6880000E6880000E6880000E6889C
:206DA6000000E6880000E6880000E6880000E6880000E6880000E6880000E6880000E6885D
:206DC6000000E68800005C89000041890000268900000B890000F0880000E6880000FF8BDD
:206DE60000001A8C00002C012C01000000000F00160014000A003C000A00080006000800EE
:0A6E06000600080033000B000A002C
:206E10002800000012C1C09D00004D9E0000AE9D00003D9E0000A19D00002F9E0000949DBD
:206E30000000189E00007A9D0000089E00006D9D0000FE9D0000519D0000F19D0000449DCD
:186E50000000E39D0000379D0000D79D0000219D00000C9D00000000FB
:200220004040FFFF80D700001400FFFF81D700000000FFFF92D700000000FFFF93D70000B0
:200240000000FFFF94D700000000FFFF95D700000000FFFF96D700000000FEFF9FD70000ED
:2002600000000000FFFFBAD700000000EEFF28D800004A0C023E4A0C023E0000803F000017
:20028000803F6C09F93B6C09F93B6C09F93B6C09F93B0000803FEEFF40D800001BD6B73857
:2002A000D79AFC3FA84C79BF00000000000000000000000000000000000000000000000066
:2002C000FFFFBDD700000000FFFF52D800000000C0FF80DC00000000000000000000C70181
:2002E000B9019B0958090000000000000000CE01B7018A09600948130D136C13F9125E0752
:200300006A07D509E7090C138D130C13EF126A075107E709C609EC0ECE0EB10D340DC80694
:20032000AB0256030E00FB0EC90EC20D040DD106B1025C0311000105F804000000006E027D
:20034000D708000000000A05050500000000FD07FD07A50AA50AFFFF18DE00000000FFFF4D
:2003600019DE00000000FFFF1ADE00000000FFFF1BDE00000000FFFF1CDE00000000FFFFA3
:200380001DDE00000000FFFF1EDE00000000FFFF1FDE00000000F4FF46D70000000000005D
:2003A0000000000009A30000A5A3000055A300005AA30000FFFF5ED700000000FFFF5FD7ED
:2003C00000000000FFFF60D700000000FFFF61D700000000FEFF2ADE000000000000FEFFB0
:2003E0002CDE000000000000FEFF2EDE000000000000FEFF30DE000000000000FFFF32DED1
:2004000000000000FFFF33DE00000000F0FF01DE00003F0006005B004F0066006D007D00C0
:2004200007007F006F00400000000000000079000000FBFF11DE000008000C001000000001
:200440000400FFFF8DDF00000600FEFF8EDF000000000000FFFF91DF00000000FFFF92DFE1
:2004600000000000FFFF84DF00000000FFFF85DF00000000FEFF87DF000000000000FFFF58
:200480009ADF00000000FFFF9BDF00000000FFFF9CDF00000100FFFF34DE00000000FFFFE3
:2004A00035DE00000000FFFF3EDE00000000FEFFA8DF000088BA0000FEFFAADF000088BA81
:2004C0000000FEFFACDF000000000000FEFFAEDF000000000000FFFF00D700000000FFFF37
:2004E00044D300000100FFFFA4DF00000A00FFFFA5DF00000100FFFFA2DF00000100FFFF58
:1A050000A3DF00000100FFFF3FDE00000000FFFF89DF0000000000000000DD
:20051A00943A0000008010E70B0001E8EAFA20E741000DE8BA9E6FE818F000E7510000E791
:20053A00000000E74900007710E708004076E2B902E8010250E800004076BCB60600BDB2E8
:20055A00BDA203E2BD041F767803199255EC79D1C08DC0DC78D0013B9B92939EA985A9BDD7
:20057A00120F007700770077007789E6040002E80818CFE621004076BCB61F765E0303E20E
:20059A003E0002E8101C0FE83033CFE621004076BCB61F76600303E23A001F7674037AD028
:2005BA00013B9392389EA985A9BD120F007700770077007789E6010002E808184076BCB6B7
:2005DA001F76600303E23C007BD01F767403013B9392399EA985A9BD120F0077007700773F
:2005FA00007789E6010002E808184076BCB61F76600303E23E001F76780318922FEC7AD18D
:20061A00C08DC0DC78D0013B9B92939EA985A9BD120F007700770077007789E6010002E80A
:20063A0040164076BCB61F76600303E23C007BD179D0013B9B92939EA985A9BD120F0077AE
:20065A0000770077007789E6010002E840164076BCB61F76600303E23E0000D1013BA192E8
:20067A00008FC0DCA98574090156A400C8E2C400A192A985008FC8D70156A400C4920252ED
:20069A0004ED02E8D123056F02E8E1300AE801004076BCB6013B008F28D80356A1010156CA
:2006BA00A40003E2C400A192019C0452A959D764AFE2BE04BE82BE8B06001B76F0FF050009
:2006DA00BDA8BDA0BDC2BDC3BDAB00E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E694
:2006FA00000669FF42291656227601021F765D0301562C00237600102676391110291A7630
:20071A001F7674033F4F04EE69FF4076DAAE1F765E03000A1F765E030092145208681F769A
:20073A005E03002B1F765E03BF56010116D1008FC0DC7FD09C9294CA01901F765E031A93E5
:20075A005FFF0191A9CB10ED1F7678031793065306EC1F76BF010B1A0008146F1F76BF01BF
:20077A000B1A00200F6F1F7678031793065306EC1F76BF010F1A0008056F1F76BF010F1A1F
:20079A0000200653C1569E011F766103120A1F76610312930A53C056A3001F766103122B11
:2007BA001F7678031793055305ED1F766103189322ED1F7678031793015305ED1F7661036F
:2007DA00179319ED1F767803179306530FEC04530DEC025306EC1F76BF010B1A0004226F9B
:2007FA001F76BF010B1A00401D6F1F76BF01021A0002186F1F767803179306530FEC04533A
:20081A000DEC025306EC1F76BF010D1A00040A6F1F76BF010D1A0040056F1F76BF01041AE2
:20083A0000021F76610316930FED1F7678031793035313EC015311EC065319ED1F76BF01EA
:20085A00021A8000186F1F767803179303530FEC01530DEC065306EC1F76BF010B1A00102E
:20087A000A6F1F76BF01041A8000056F1F76BF010D1A00101F766103179315ED1F7678033D
:20089A00179306530BEC035304EC015315EC196F1F76BF010B1A0040226F1F76BF01021A65
:2008BA0080001D6F1F7678031793065314EC03530DEC015306EC1F76BF010B1A00800F6FF2
:2008DA001F76BF010D1A00800A6F1F76BF010D1A0040056F1F76BF01041A020000524CED59
:2008FA001F76740322931F766103125545ED1F767803179303530FEC01530DEC065306ECE8
:20091A001F76BF010D1A00100A6F1F76BF01021A8000056F1F76BF010B1A0010065314EC70
:20093A0003530DEC015306EC1F76BF010D1A00800F6F1F76BF010B1A00800A6F1F76BF01C6
:20095A000B1A0040056F1F76BF01021A800006530FEC04530DEC025306EC1F76BF010B1A4E
:20097A0000040A6F1F76BF010B1A0040056F1F76BF01021A00021F76610300D41993B156BF
:20099A00A401A993A4CF08EC1F765E033D28F4011F766103132B1F76610319961F765E03D0
:2009BA003D0A1F765E03C4E23D00007712E8D01F14ADE4FF8A001F765E033D2B1F76610318
:2009DA00130A1F766103139301911F76610314971F76610300D4139307911F766103B05601
:2009FA00A401157C005260ED1F7678031692095239EC1F766103BF56160116D0408FC0DC5A
:200A1A007FD195939D92D0FFC9FFA8CA019004EC1F766103167C1F765E031A421EEE1F760D
:200A3A005E031A4313EE1F765E031A4405EE1F766103172B496F009B1F76610315921F76D3
:200A5A006103B156A80117973F6F1F76610314921F7661031796386F1F766103BF561701FA
:200A7A00336F1F766103BF5618011F765E031A4105EF1F7661031492026F009A1F766103AB
:200A9A0017961F765E031A4005EE1F766103162B1B6F1F76610314921F76610318961F76AD
:200ABA0061031696116F1F76610314921F76610317961F76610316961F7661031896046F88
:200ADA0069FF407618B6AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC464
:200AFA00BE83BE8A0300F1FF17760276BDB2BDAA009A1F765E0315961F765E0313961F7616
:200B1A005E0314961F7678031692A993FF9D01532B69A993FD9D01531A6907520BEC0952E0
:200B3A001F765E03B156140F1F765E03B156150D276F1F765E03BF5613081F765E03BF5695
:200B5A0014081F765E03BF5615081A6F1F765E03BF5613071F765E03BF56140E1F765E0366
:200B7A00BF56150E0D6F1F765E03BF56130A1F765E03BF5614141F765E03BF5615141F7683
:200B9A0078031D921F765E0314941F765E03169600D1013BA192008FC8D7A9850156A4003A
:200BBA00C42BA192008FE0D7A9850156A400C479A12D408F40D81235008F80D8A9860156E4
:200BDA00A40012024076C0B9008F40DA408F40D8A9AA0156A40012024076C0B9A192019C23
:200BFA001852A959D7641F7678031A9227EC00D11F765E03149222651F76780319920AECC0
:200C1A00A192013B008FC8D7A9850156A400BF56C4091F76780318920AEC013BA192008F64
:200C3A00C8D7A9850156A400BF56C408A1921F765E03019C1454A959E06400D11F7678039C
:200C5A001D9214651F765E03013B1492008FC8D7A194A9850156A400BF56C40AA1921F7643
:200C7A007803019C1D54A959EE641F7678031B923EEC1F765E03BF563BC800D11F765E03C1
:200C9A00013B1692008FC8D7A194A9850156A400BF56C4031F765E03A985008FE0D701562D
:200CBA00A400A19201F01694C496A192A985008FC0DC70090156A400408FC0D70356A101ED
:200CDA00C8E2C4000156A50003E2C500A12D1235008F00DC408F40D80156A40012024076BA
:200CFA00C0B9A192019C0452A959C9641F767803179206520BED1F765E033B282C01008FEE
:200D1A00C8D7BF56DC02BF56D4021F7678031692095234ED008FC8D7C42B408FE0D7BF5650
:200D3A00C501BF56CC01CD2BBF56D404BF56D503BF56DC04BF56DD02BF56E404BF56E5053A
:200D5A00BF56EC04BF56ED04BF56F406BF56FC0508D0BF56940609D0BF5694070AD0BF564A
:200D7A0094060BD0BF5694060CD0BF5694060DD0BF5694080ED0BF56940800021F7678037B
:200D9A00201E1F765E031B28F9151F765E03BF561C121F765E031D28F22B1F765E031E28E7
:200DBA003E491F765E033C2B1F765E033C1A01E0013B90E500D1A192008FA1D7A9850156C7
:200DDA00A400C42BA192A985008FA7D70156A400C42B0356A101008FAED70156A40003E21F
:200DFA00C400A192019C0652A959E664013B00D10356A101008F48DC0156A4000002C41E07
:200E1A00A192019C1C52A959F464013B00D1A192008F00D8A9850156A400C42BA192019C91
:200E3A002052A959F564013B00D1A192008F20D8A985408FF8D70156A400A192A985015685
:200E5A00A500009AC496C596A192019C0852A959ED64BE86BE8B0600013B00B6A792008FBA
:200E7A00C0DCA985A4830156A500C51800E0A792A98518090156A400C42BA792019C1852FC
:200E9A00A980ED64013B00B6A792008FC0DCA985A4C45AFF70090156A600408FC0D7035644
:200EBA00A701C8E2C6000156A50003E2C5001F767803179206521BEDA792408FC8D7A9856C
:200EDA000156A500C592035212EDA792019008EDA9A918090156A400C4288601086FA79201
:200EFA00A98518090156A400C4283002A792019C0452A980CA641F7678031792015210EDE4
:200F1A001F765E03008FC0DC16850156A400C41A0040CC1A0040D41A0040DC1A00401F76C3
:200F3A0078031792065207ED008FC0DCC41A0040CC1A004040761C800600BDAA1F765E0303
:200F5A00162F1F7678031B9204ECAA92049CA92F013BAB2B00BE0356AB03008F82D7A681EB
:200F7A000156A400C42BA692019C0852A988F464AB92019C0252A927EE641F7678031792AC
:200F9A0004527AECAB2BAA923065AB93A892008D82D7A2FF013BCBFFA086A894A3FFA9859D
:200FBA000156A200109BAB92C000AFB9A92D019B67FFA28AC499189AAB94013BA988A2FFAE
:200FDA00CBFFA694A3FFA9850156A000109BA692C000AFB9019BA92D67FFC099AB92019C16
:200FFA00A927AA92AB54D262013BAB2BAB92008F82D7A985A4830156A500039AAB94C588E7
:20101A00A98508090156A400C47EAB92019C0352A927ED641F7678031792025204EDA9281B
:20103A000003036FA928000F1F765E0311981F7678031B9209EC408F82D7A58A0FDCC41AD0
:20105A00FF00F51A003F1F7678031D9205EC1F765E03081A08001F7678031792065215ED46
:20107A00408F82D7A58A0FDCC41A3000FD1A00E0CD1A00300A6F008F82D7A48308DDC51AAC
:20109A000F000EDCC41AFC01008F82D7CC1A0100A4830EDDC51A07000FDCC41A00E0BE86AE
:2010BA0006004388A71EA59208EDC49304ECC40BA6920C6F009A0A6FA706AA2BC427AB0F51
:2010DA000362019A036FC40AA6920600C488013BA985008FC0DC0156A400C4CC00E0A6CABC
:2010FA001F765E03A993D7FF01911999A9CDFFFDA8880356A9015EFFA9180002A6CAC496FB
:20111A000600BDB2BDAABDA203E2BD0403E2BD0503E2BD0608FE44961F7678031792065294
:20113A000CED44920AED1F765E0319921F765E031A961F765E03192B1F765E0316924494D8
:20115A00A959013B008FE0D744850156A400C492459644925EFF019046964492A0FF47960A
:20117A00A988A92D03354896049AA694A95AA185008FC0DCA4BD220F0156A400C44FCD5649
:20119A0037024485008F40DF0156A400C4E2C405649AA4BF220F44948CE62800A985015692
:2011BA00A400A9BF120FC496C08DC0D744920356A9010156A30002E891340BE801E0AFE2C3
:2011DA00C30020E728004076BCB6AFE2C30110E74000007703E2C300008F00DC442D12350D
:2011FA000156A400407640B98CE6000000778DE600001F767E0302C4AC281F00013B1F762F
:20121A007E03A6062256A60740FF000F0C65A4BF220F44858CE6000070090156A400A9BFF8
:20123A00120FC49644920356A901008FC0DCA61E448570090156A400408F28D8A606C8E2EF
:20125A00C4000156A50020E72800AFE2C50100E70C00C08DAED7A6060156A30000E72101BA
:20127A00AFE2C30020E7080002E8512B0BE801004076BCB6AFE2C30110E74000007703E287
:20129A00C3004076E2B9013B8CE60000008FA7D744850156A400A9BF120FC4964692C056D0
:2012BA00AE00CFE620001F766103AFE21A0140760080A12D008F40DA12350156A400407647
:2012DA0040B9CFE60500013B008FC8D7A1850156A400C492035206ED12E8050D14AD0263E6
:2012FA0095E5A185008FC8D70156A400C492025206ED12E8B51414AD026395E501E8A9FD7C
:20131A0008E89927CFE628004076BCB6CFE606001F767E03000619ED013B008FC0DCA18594
:20133A008CE62800A48318090156A500A9BF120FC596A192FF9C8CE63000A98518090156BB
:20135A00A400A9BF120FC4961F766103013BAFE21A00C08DAED70356A201AFE6240020E77E
:20137A0020000156A30000E70100AFE2C30020E7080002E8512B0BE801004076BCB6AFE2DB
:20139A00C30110E74000007703E2C300C08DA7D74076E2B98CE600000077013BA7BF120F51
:2013BA00A38AA2850156A400C47F4888A38345855AFF689AA672008FC0DCA9A90156A500D5
:2013DA00A692A985A4C40156A600C592C696488844855AFF699AA672A483A9A90156A300F5
:2013FA00A692A9850156A500C392C5966A9A4894A9850156A400C47F0C6F1F767803179241
:20141A00015203EDAFE624001F76610303E21A04008FA7D74485A4830156A500C8E2C5054D
:20143A0045850156A400C8E2C400007794E6050014ADC4E60500A285008FA7D70156A400CA
:20145A00C8E2C400007794E6050014ADC4E60500452B1F767E030006C056C2004485008FE2
:20147A00C0DC0156A400C44ECD56BA004485008FA7D70156A40000D3C8E2C400CFE62900DC
:20149A0020E728004076BCB601E8C9F40CE8D1CC94E6080014AD0B651F765E03C8E23B0016
:2014BA00007794E6050014ADB256A301013B4485008FA1D71F765E03412BA35D0156A40046
:2014DA001D0E4076CE85005203EC451A0401013B008FA7D7A2850156A40000D3C8E2C4006D
:2014FA00CFE6290020E728004076BCB601E8C9F40CE8D1CC94E6080014AD0B651F765E03BD
:20151A00C8E23B00007794E6050014ADB256A301013B008FA1D71F765E03A285412BA35D9D
:20153A000156A4001D0E4076CE85005203EC451A04011F7678031792065251ED46924FED5A
:20155A00013B008FC0DCA18530090156A400C8E2C400007794E6060014AD0365451A2001A2
:20157A00A185008FC8D70156A400C49203521EEDA185008FC0DC48090156A400412B00D56E
:20159A00C8E2C4001F765E0394E60600008F9FD714ADB456A50147850156A4001D0E40762F
:2015BA00CE85005203EC451A0801013B008FC8D7A1850156A400C492025211EDA185008F2D
:2015DA00C0DC48090156A400C8E2C400007794E6060014AD04654592105045964592AD5C88
:2015FA00439683DCA1924076E3850F6F008FC0DCA185A4830156A500C52BC51A0080A185E1
:20161A0018090156A400C42B88FEAFE2BE06AFE2BE05AFE2BE04BE82BE86BE8B0600BDB2E1
:20163A00BDAABDA204FEA92DA85B00520AED1F765E0319921F765E031A961F765E03192B25
:20165A00013BAC92008FC0DCA9850156A400C44F07EFAC921F765E031454E4FFEE01AC92ED
:20167A00008F44DFA9850156A400C4E2C4007FD0008FC0DC944CCD56D501AC92A9850156F5
:20169A00A400C44D4AEFAC921F765E031454456300B6A792A985A9BD120F00BE013BAC9222
:2016BA00008FC8D7A985A4830156A500A692A9850156A400C527AB92C4541AEDA692008F21
:2016DA00C0DCA9850156A4001F765E033C92C4CE0FEDA692008F44DFA9850156A400A9BF5E
:2016FA00120FC40DA9BD120FA792019CA980A692019C1852A988D464A7920DECA985421EF0
:20171A00A9BF120FC00074B9A9BD120F007700770077007789E60000AC921F765E03159E80
:20173A00A95AA39227EC013BAC92008FC8D7A9850156A400C4920A521BEDAC921F765E0385
:20175A00008FF8D7149EA9850156A40001E860EEC8E2C4010EE8686600E74000A985008FE8
:20177A0020D80156A400C49203EC06E84016A3925BED1F767803189257EC008FC0DC16D147
:20179A0094939C92D3FFC1FFA8CA019025EC1F767E03000621ED1F767803179205520CED01
:2017BA0002E849280CE8010094E6080014AD0465A2920250A95AA2920F64013BA9858CE607
:2017DA00000078090156A400A9BF120FC49640761C80EFFF4101AC921F765E031454E3FF90
:2017FA003B01A292019011EC1F767403C8E239011F76600320E74000AFE23E0100E70800E3
:20181A00007790E80076106F1F767403C8E238011F76600320E74000AFE23C0100E70800DF
:20183A00007790E800761F767803199254ECA292E3FFD0001F767803179202521EECAC92F3
:20185A0001900EEC1F767403C8E239011F76600320E74000AFE23E0100E708003C6F1F76B5
:20187A007403C8E238011F76600320E74000AFE23C0100E708002F6F013BAC928076C0DC4E
:20189A00408F44DFA985A6C50156A500089AAC94A98518090156A700C527C73FAC920652F0
:2018BA000E631F767403C8E238011F765E0320E74000AFE23E0100E708000D6F78D0C8E244
:2018DA0096011F76600320E74000AFE23A0100E70800007716E8000D14AD086412E8401A5A
:2018FA0014AD066502E8401A036F06E8000D16D0008FC0DC7FD194939C92D0FFC9FFA8CA32
:20191A00019003EC02E8001150E80148013BAC928CE60900A483A985A6BF160F5AFF180963
:20193A000156A500C57E8CE6000000770077A7BF120F00BE1F767E03000644EDAC92A483F7
:20195A00A9850156A500C55DA5CC00403BEDA71BECFF3165A792C8522E63A9A9300901563F
:20197A00A400C492FB9CA7540463A5CC20001CEDAC92008FC0DCA985A4835AFF3009015619
:20199A00A500A792C5541062A9A948090156A400A792C4541765A6921050A9881F765E039A
:2019BA00191A08000F6FA61A20011F765E03191A0400086FA6920150A9881F765E03191AEC
:2019DA001000AD5C437EAC9283DC4076E385436F1F767E03000618ED1235008F40DA01563E
:2019FA00A400407640B9013BA292008FC0DC8CE60000A98578090156A400A9BF120FC496E0
:201A1A0040761C80286F1235008F40DA408F80D80156A4000156A50012024076C0B91B6FE8
:201A3A00AC92A9858CE6000018090156A400A9BF120FC496106F008FC0DCA985A483015659
:201A5A00A500C52BC51A0080AC92A98518090156A400C42B84FEBE82BE86BE8B0600BDB23D
:201A7A00BDAABDA204FEA95900520AED1F765E0319921F765E031A961F765E03192B013B7C
:201A9A00A192008FC0DCA985A4830156A500C54FCD56E100A192807644DFA9850156A600EE
:201ABA00C4E2C6007FD0944CCD56CA00A1928076C8D7A9850156A600C07628D80356C6013B
:201ADA000156A700AFE2C70100E7400000778CE6000000770077A3BF120FA192A985180992
:201AFA000156A400C47B00D21F767E030006C056A000C54ECD569D00A192075269EC0356E1
:201B1A00A10143961F767803008D00D8432DA218FFFB2006A08A22560190A95D4385412B04
:201B3A000156A40020FFE8034076CE85019089FFA298019A1F767803013B4394A218FFF7BC
:201B5A00A988A08AA62D412B200622560190A95DA6850156A40020FFE8034076CE850190D2
:201B7A008AFFA298A192065233ED029A43941F767803A988013BA218FFEFA08AA62D200622
:201B9A00412B22560190A95DA6850156A40020FFE8034076CE8501908BFFA298039A1F76F0
:201BBA007803013BA218FFDF4394A988A62D200622560190A95DA6850156A000412B20FFFF
:201BDA00E803A08A4076CE8501908CFFA298A292C0FFA293A2CAC0FFA8CDBFFFA2CAC0FFC6
:201BFA00A2CAC3FF4090A8CAA95A008FC0DC013BA192A483A98548090156A500A392C554CE
:201C1A001163A2920850A95A408FE0D7A192A9850156A500C5850156A400C492089084FF0E
:201C3A00A298A29205EC1F765E03191A0200AD5C427AA19282DC4076E3851A6FA192A985A2
:201C5A008CE6000018090156A400A9BF120FC4960F6FA192A483A9850156A500C52BC51A28
:201C7A000080A192A98518090156A400C42B84FEBE82BE86BE8B06001B76F0FF00E2BD00EA
:201C9A0030E60006422916562376391110292576006F1B76F0FF00E2BD0030E6000642296B
:201CBA0016562376390110292576006F1B76F0FF00E2BD0030E600064229165623763901A3
:201CDA0010292576006F1B76F0FF00E2BD0030E60006422916562376390110292576006F7F
:201CFA001B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E640
:201D1A0000064229165610292576006F1B76F0FF00E2BD0030E600064229165610292576A3
:201D3A00006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD00A6
:201D5A0030E600064229165610292576006F1B76F0FF00E2BD0030E60006422916561029E8
:201D7A002576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E288
:201D9A00BD0030E600064229165610292576006F1B76F0FF00E2BD0030E600064229165624
:201DBA0010292576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FFF1
:201DDA0000E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000642296E
:201DFA00165610292576006F1B76F0FF00E2BD0030E600064229165610292576006F1B7634
:201E1A00F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E60006A9
:201E3A004229165610292576006F1B76F0FF00E2BD0030E6000602FE422916561F76330094
:201E5A002292419623760100267601011F7633002218FA001F7633002128FFFF1029103B16
:201E7A001F763300419222962576006F1B76F0FF00E2BD0030E6000602FE422916561F7644
:201E9A0033002292419623760100267601011F7633002218F8001F7633002128FFFF1029F0
:201EBA00103B1F763300419222962576006F1B76F0FF00E2BD0030E6000602FE422916564E
:201EDA001F76330022924196237601011F76330022921F763300222B1F7633002128FFFF5A
:201EFA001029103B1F763300419222962576006F1B76F0FF00E2BD0030E6000602FE422941
:201F1A0016561F76330022924196237601011F763300221868001F7633002128FFFF10299B
:201F3A00103B1F763300419222962576006F1B76F0FF00E2BD0030E6000602FE42291656CD
:201F5A001F7633002292419623760100267601011F763300221848001F7633002128FFFF83
:201F7A001029103B1F763300419222962576006F1B76F0FF00E2BD0030E6000602FE4229C0
:201F9A0016561F7633002292419623760100267601011F76330022921F763300222B1F760A
:201FBA0033002128FFFF1029103B1F763300419222962576006F1B76F0FF00E2BD0030E677
:201FDA00000602FE422916561F7633002292419623760100267601011F7633002218780005
:201FFA001F7633002128FFFF1029103B1F763300419222962576006F1B76F0FF00E2BD00B8
:20201A0030E6000602FE422916561F7633002492419623760200267600001F763300241823
:20203A000E001F7633002128FFFF1029103B1F763300419224962576006F1B76F0FF00E224
:20205A00BD0030E6000602FE422916561F7633002492419623760200267600001F76330062
:20207A0024180C001F7633002128FFFF1029103B1F763300419224962576006F1B76F0FF8C
:20209A0000E2BD0030E6000602FE422916561F7633002492419623760200267600001F7673
:2020BA003300241808001F7633002128FFFF1029103B1F763300419224962576006F1B760C
:2020DA00F0FF00E2BD0030E6000602FE422916561F763300249241962376020026760000D9
:2020FA001F76330024921F763300242B1F7633002128FFFF1029103B1F7633004192249649
:20211A002576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002492419623769B
:20213A000200267600001F76330024180F001F7633002128FFFF1029103B1F7633004192A6
:20215A0024962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300249241963A
:20217A0023760200267600001F76330024181F001F7633002128FFFF1029103B1F76330090
:20219A00419224962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002692FC
:2021BA0041962376040026763D011F76330026183E001F7633002128FFFF1029103B1F764B
:2021DA003300419226962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003F
:2021FA00269241962376040026763D011F76330026921F763300262B1F7633002128FFFF17
:20221A001029103B1F763300419226962576006F1B76F0FF00E2BD0030E6000602FE422919
:20223A0016561F763300269241962376040026763D011F76330026921F763300262B1F761C
:20225A0033002128FFFF1029103B1F763300419226962576006F1B76F0FF00E2BD0030E6D0
:20227A00000602FE422916561F763300269241962376040026763D011F763300261826006D
:20229A001F7633002128FFFF1029103B1F763300419226962576006F1B76F0FF00E2BD0011
:2022BA0030E6000602FE422916561F763300269241962376040026763D011F76330026183D
:2022DA0026001F7633002128FFFF1029103B1F763300419226962576006F1B76F0FF00E268
:2022FA00BD0030E6000602FE422916561F763300269241962376040026763D011F7633007E
:20231A0026921F763300262B1F7633002128FFFF1029103B1F763300419226962576006FDE
:20233A001B76F0FF00E2BD0030E6000602FE422916561F76330028924196237608002676DB
:20235A0008011F763300281802001F7633002128FFFF1029103B1F763300419228962576C9
:20237A00006F1B76F0FF00E2BD0030E6000602FE422916561F7633002A92419623760800C6
:20239A00267608011F76330028921F763300282B1F7633002128FFFF1029103B1F76330086
:2023BA00419228962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002892D4
:2023DA00419623760800267608011F763300281803001F7633002128FFFF1029103B1F7693
:2023FA003300419228962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633001B
:20241A002892419623760800267608011F763300281803001F7633002128FFFF1029103B2D
:20243A001F763300419228962576006F1B76F0FF00E2BD0030E6000602FE422916561F7678
:20245A0033002892419623760800267608011F76330028180F001F7633002128FFFF1029F9
:20247A00103B1F763300419228962576006F1B76F0FF00E2BD0030E6000602FE4229165682
:20249A001F7633002892419623760800267608011F76330028180F001F7633002128FFFF5D
:2024BA001029103B1F763300419228962576006F1B76F0FF00E2BD0030E6000602FE422975
:2024DA0016561F7633002A92419623761000267610011F7633002A1802001F7633002128A8
:2024FA00FFFF1029103B1F76330041922A962576006F1B76F0FF00E2BD0030E6000602FEA0
:20251A00422916561F7633002A92419623761000267610011F7633002A921F7633002A2B78
:20253A001F7633002128FFFF1029103B1F76330041922A962576006F1B76F0FF00E2BD006A
:20255A0030E6000602FE422916561F7633002C92419623762000267639011F7633002C1876
:20257A0032001F7633002128FFFF1029103B1F76330041922C962576006F1B76F0FF00E2B3
:20259A00BD0030E6000602FE422916561F7633002C92419623762000267639011F763300BD
:2025BA002C921F7633002C2B1F7633002128FFFF1029103B1F76330041922C962576006F2A
:2025DA001B76F0FF00E2BD0030E6000602FE422916561F7633002C9241962376200026761D
:2025FA0039011F7633002C1833001F7633002128FFFF1029103B1F76330041922C962576BD
:20261A00006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C9241962376200009
:20263A00267639011F7633002C1837001F7633002128FFFF1029103B1F76330041922C9677
:20265A002576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C92419623764E
:20267A002000267639011F7633002C1822001F7633002128FFFF1029103B1F7633004192EE
:20269A002C962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C924196E5
:2026BA0023762000267639011F7633002C921F7633002C2B1F7633002128FFFF1029103B39
:2026DA001F76330041922C962576006F1B76F0FF00E2BD0030E6000602FE422916561F76D2
:2026FA0033002E92419623764000267600001F7633002E183E001F7633002128FFFF1029ED
:20271A00103B1F76330041922E962576006F1B76F0FF00E2BD0030E6000602FE42291656D9
:20273A001F7633002E92419623764000267600001F7633002E1838001F7633002128FFFF56
:20275A001029103B1F76330041922E962576006F1B76F0FF00E2BD0030E6000602FE4229CC
:20277A0016561F7633002E92419623764000267600001F7633002E1838001F7633002128A8
:20279A00FFFF1029103B1F76330041922E962576006F1B76F0FF00E2BD0030E6000602FEF9
:2027BA00422916561F7633002E92419623764000267600001F7633002E1820001F7633005E
:2027DA002128FFFF1029103B1F76330041922E962576006F1B76F0FF00E2BD0030E6000670
:2027FA0002FE422916561F7633002E92419623764000267600001F7633002E1828001F7649
:20281A0033002128FFFF1029103B1F76330041922E962576006F1B76F0FF00E2BD0030E602
:20283A00000602FE422916561F7633002E92419623764000267600001F7633002E921F76B0
:20285A0033002E2B1F7633002128FFFF1029103B1F76330041922E962576006F1B76F0FF56
:20287A0000E2BD0030E6000602FE422916561F7633003092419623768000267600001F7601
:20289A0033002C921F7633002C2B1F7633002128FFFF1029103B1F7633004192309625767F
:2028BA00006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241962376800003
:2028DA00267600001F763300301801001F7633002128FFFF1029103B1F763300419230963D
:2028FA002576006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241962376A8
:20291A008000267600001F7633002C1823001F7633002128FFFF1029103B1F763300419224
:20293A0030962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241963A
:20295A0023768000267600001F763300301803001F7633002128FFFF1029103B1F7633003A
:20297A00419230962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003292FC
:20299A00419623760001267600011F76330032921F763300322B1F7633002128FFFF102916
:2029BA00103B1F763300419232962576006F1B76F0FF00E2BD0030E6000602FE4229165633
:2029DA001F7633003292419623760001267600011F7633003218FD001F7633002128FFFF25
:2029FA001029103B1F763300419232962576006F1B76F0FF00E2BD0030E6000602FE422926
:202A1A0016561F7633003292419623760001267600011F763300321871001F763300212802
:202A3A00FFFF1029103B1F763300419232962576006F1B76F0FF00E2BD0030E6000602FE52
:202A5A00422916561F7633003292419623760001267600011F763300321875001F7633009C
:202A7A002128FFFF1029103B1F763300419232962576006F1B76F0FF00E2BD0030E60006C9
:202A9A0002FE422916561F7633003292419623760001267600011F76330032921F76330057
:202ABA00322B1F7633002128FFFF1029103B1F763300419232962576006F1B76F0FF00E23D
:202ADA00BD0030E6000602FE422916561F7633003292419623760001267600011F763300CA
:202AFA0032921F763300322B1F7633002128FFFF1029103B1F763300419232962576006FD3
:202B1A001B76F0FF00E2BD0030E6000602FE422916561F76330032924196237600012676F0
:202B3A0000011F763300321831001F7633002128FFFF1029103B1F763300419232962576A6
:202B5A00006F1B76F0FF00E2BD0030E6000602FE422916561F7633003292419623760001DD
:202B7A00267600011F763300321875001F7633002128FFFF1029103B1F7633004192329621
:202B9A002576006F1B76F0FF00E2BD0030E6000602FE422916561F763300389241962376FD
:202BBA000008267600001F76330038189E001F7633002128FFFF1029103B1F763300419273
:202BDA0038962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003892419688
:202BFA0023760008267600001F76330038189C001F7633002128FFFF1029103B1F7633006F
:202C1A00419238962576006F1B76F0FF00E2BD0030E6000602FE422916561F76330038924B
:202C3A00419623760008267600001F763300381890001F7633002128FFFF1029103B1F7696
:202C5A003300419238962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300A2
:202C7A003892419623760008267600001F763300381890001F7633002128FFFF1029103B21
:202C9A001F763300419238962576006F1B76F0FF00E2BD0030E6000602FE422916561F7600
:202CBA0033003892419623760008267600001F76330038921F763300382B1F76330021281B
:202CDA00FFFF1029103B1F763300419238962576006F1B76F0FF00E2BD0030E6000602FEAA
:202CFA00422916561F7633003892419623760008267600001F76330038189F001F763300BE
:202D1A002128FFFF1029103B1F763300419238962576006F1B76F0FF00E2BD0030E6000620
:202D3A0002FE422916561F7633003892419623760008267600001F76330038921F763300A2
:202D5A00382B1F7633002128FFFF1029103B1F763300419238962576006F1B76F0FF00E28E
:202D7A00BD0030E60006422916562576006F1B76F0FF00E2BD0030E60006422916562576D2
:202D9A00006F1B76F0FF00E2BD0030E60006422916562576006F1B76F0FF0500BDA2BDA845
:202DBA00BDA0BDC2BDC3BDAB00E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E60006EC
:202DDA0002FE69FF422916561F7633003292419623760001267600011F76330032921F76DF
:202DFA003300322B1F7633002128FFFF1029C08D00D069FFA38A40763499A38A40767E95B6
:202E1A00103B1F7633004192329682FEAFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE0008
:202E3A00BE87BEC5BEC4BE83BE8ABE820300F1FF177602761B76F0FF0500BDA2BDA8BDA0C7
:202E5A00BDC2BDC3BDAB00E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FEA8
:202E7A0069FF422916561F7633003292419623760001267600011F763300321871001F7647
:202E9A0033002128FFFF1029C08D80D369FFA38A40763499A38A40767E95103B1F763300A4
:202EBA004192329682FEAFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC431
:202EDA00BE83BE8ABE820300F1FF177602761B76F0FF0500BDA2BDA8BDA0BDC2BDC3BDAB0A
:202EFA0000E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FE69FF4229165630
:202F1A001F7633003292419623760001267600011F7633003218FD001F7633002128FFFFDF
:202F3A001029C08D00D069FFA38A40763499A38A4076C996103B1F7633004192329682FE99
:202F5A00AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC4BE83BE8ABE82E2
:202F7A000300F1FF177602761B76F0FF0500BDA2BDA8BDA0BDC2BDC3BDAB00E2BD0003E2AE
:202F9A00BD0003E2BD0103E2BD0203E2BD0330E6000602FE69FF422916561F763300329287
:202FBA00419623760001267600011F763300321875001F7633002128FFFF1029C08D80D37A
:202FDA0069FFA38A40763499A38A4076C996103B1F7633004192329682FEAFE2BE03AFE26C
:202FFA00BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC4BE83BE8ABE820300F1FF1776A5
:20301A000276BDB2BDAAA486EFFF3A01C28AFCCCFF00A958EC47CD562D01408DA0019A92C3
:20303A00C0562E01408D3B039A92015211ED408D3D03BF569A010002408D34039A1E408D61
:20305A003F039A2B408D3E039A2B0DD19A2B408D3F039A92C0561401408D3D039A924DED00
:20307A00F2C4208F0000A9A8A60F06662F8F0000A9A8A60F0667208F0000F2A80AD19AA8C8
:20309A000CD19A923A52C056FB00408DA0019A922EED408D34039A06A61E01DE9AC2019087
:2030BA0006EDF28A0356A008C496076FF28AA9A80109F21EA092C498008D34039206E20FF4
:2030DA00E8FFDE000FD10CD0BF569A33BF569233099AA28A40768497008D3F03BF56920182
:2030FA00008DA001BF569201EFFFCA00008D3F03BF569201EFFFC400408D3E039A9241ED97
:20311A00A0921F760403115428EC1F767E03255405ED1F767E03259220EDA092408D3103C0
:20313A009A5405ED408D33039A9217EDA0921F767E03245409ED1F767E03249205EC408D22
:20315A0033039A920AEC008D3F03BF569201008D3D03922BEFFF9400408D32039A78013B2A
:20317A00A28A408D3E039A850156A400019BA9959A970ED19C78089AA28A407684977F6F56
:20319A00013BA28A9A850156A400019BA9959A970ED19C78408D3E039A9207520EED0DD129
:2031BA009A9210520AED408D33039A9206ED0A9A1F765C03A0941096408D3E039A9203524D
:2031DA000BED0DD19A59A192045206ED059A008F00D7A0949C96408D3E039A9202521AED90
:2031FA000DD19A78A0920352336842523166008F00D7949203522C68A09233520BED0CD177
:20321A009A923A5225EDA092335204ED008D3D03922B0DD09258408D3E03008F00D79A9231
:20323A0094540467A91B90012A68099AA28A40768497008D3D03922B008D3F03BF56920199
:20325A00008DA001BF5692010DD0922B186F099AA28A40768497008D3E03922B008D3D0365
:20327A00BF569201008D3F03922B0DD0922B076FC28ACC18DFFFC28ACC1A2000C28AEC4612
:20329A00CD56C6FE1F763300211A00010BDCC41A4000BE86BE8B0600BDB2BDAAA486008D04
:2032BA003A03929236EDA9AA008F38030156A400008D360301020156C4009206008D380314
:2032DA00920F0466C28ABF56E40208D0928A08D1A9A801099A1EC28309D0C4929596008D76
:2032FA0036039206008D3803920F4566C28AE446FEEF099AA28A40768497D292025205ED22
:20331A001F76BF01081A0400008D9E01922B336F008D3803928AA4920190A98801DC92A89A
:20333A00008D36039206008D3803920F0466C28ABF56E402A6920AED08D09283C28A09D0BA
:20335A00C592A7FFFF9094960C6F08D0928A08D1A9A801099A1EC28309D0C492FF90959614
:20337A00008D36039206008D3803920F0466C28AE446FEEF1F763300211A0001BE86BE8B0E
:20339A000600009A013BA985008F00D70156A400C496019C4652F86433D0008F00D7BF563F
:2033BA00940C34D0BF56940C35D0BF56940836D0BF56940937D0BF56941038D0BF569408B3
:2033DA0039D0BF56940C3AD0BF56940C3BD0BF5694051F764D033DD00492FE9C94961F76BC
:2033FA004D0341D00492FF9C94963ED0BF569408BF56DC08BF56E465BF56F40810D0BF56DB
:20341A00940DBF56EC1B3CD0BF5694120600BDB2BDAAA959A48608520AED089A01D54E9B54
:20343A00A28A40760799008D3B03922BA19209520BED089A01D54E9BA28A40760799008D72
:20345A003B03BF569201BE86BE8B0600BDB2BDAABDA2A48BA586A98200D401DCA41B30750A
:20347A00FD69D192025205ED1F76BF010818FBFF00D401DCA41B1027FD69008D360391A2AE
:20349A00A9AA08D00109911E008D3A03912BC18AE446FEEF089AA18A40768497008D3803E0
:2034BA000102911EA30F1968C18AC29209D09496C18AE446FEEF00D401DCA41BE803FD6948
:2034DA00099AA18A40768497D19202520DED1F76BF01081A0400086FC18ABF56E401C18A00
:2034FA0009D0C2929496009ABE82BE86BE8B0600BDB2BDAAA61EA586A48BD192025205ED51
:20351A001F76BF010818FBFF008D360391C208D091AA008D3A03BF569101C18AE446FEEF23
:20353A00089AA18A40768497008D38030102911EC18ABF56E401C292C18A09D0A7FFFF9067
:20355A009496009ABE86BE8B0600BDB2A9BD160F00770077A48B1F765D038BE6090088E20A
:20357A003C0050E809404076BCB688E6000000770077A9BF120FC18AA993B7FFFF91D4972F
:20359A00C18AFF90DC96BE8B06001F764D0304961F764003BF5602011F764E03BF56020208
:2035BA000600BDB2BDAABDA2A986A492015230ED008F50701F76400300A8C08D00D022765D
:2035DA001F76BE0109CDFFF7A81A00041F76BE0109971F76BE0109CDFFFDA81A00011F7679
:2035FA00BE0109971F763700008F489400A81F763700008FE49402A81F763300321A0100E1
:20361A001F763300321A0200237600011A76025237ED008F50771F764E0300A8C08D80D354
:20363A0022761F76BE01008F806FFCCDFFEFA81A002007971F76BE0107CDFF3FA81A008027
:20365A001F76BE010797A48316DDC518CFFF1ADCC41A04001F763700008F979404A81F76FA
:20367A003700008F319506A81F763300321A04001F763300321A0800237600011A76D3962F
:20369A00C38B089A01D54E9BA38A40760799A18A0CDCC41A0040A18A0CDCC418FFDFC918FF
:2036BA00BFFFC918DFFFC918F7FFC918FBFFC91A0200C91A0100A18A0ADCC418FFBF0BD072
:2036DA0091CCE0FF0150919640763E97A38AA9AA40762298D392025205ED1F76BF01081A7F
:2036FA000400C38ABF56E402099AA38A407684970CD0932B008D9E01932B008D3303932BBE
:20371A00A18A0BDCC41A4000C91A2000BE82BE86BE8B0600A888C48A005209650952076386
:20373A00C4CDF8FFFF9C0790A8CAC496A69245520DEC4E5208EC4F520DEDC41A2000C41818
:20375A00BFFF086FC418DFFF056FC41A2000C41A4000A592015203EDC4187FFF025203EDB8
:20377A00C41A8000C418EFFFC418F7FF06000002008D4203941E0600060016D0008F806F39
:20379A001F76780394920390229618D01F7678039492039023961AD01F7678039492019073
:2037BA0024961BD01F76780394920190259622761F76BE011618FCFF1F76BE011818FCFF34
:2037DA001F76BE011A1A01001F76BE011B1A01001A7669FF060022761F76780316D0008FA1
:2037FA00806F2292039094CDFCFF1F76BE01A8CA16961F76780318D0239203901F76BE0117
:20381A0094CDFCFFA8CA18961F7678031AD0249201901F76BE0194CDFEFFA8CA1A961F7668
:20383A0078031BD025921F76BE0194CDFEFF0190A8CA1B961A7669FF060022761F76BE0101
:20385A00061800001F76BE01071800FF1F76BE0108183F001F76BE01091800FF1F76BE0143
:20387A001618C0FF0F8F00F0ABA81F76BE01AB93AA9218C11F76BE0119C0008F806FA483E7
:20389A000BDDC518EFFF1F76BE010B18DFFF1F76BE010B18BFFF1BDCC418F7FF1A761F76E3
:2038BA007803BF561601008FC06F1F767803CC92C4FF5EFF019016721F76BF010192C3FF38
:2038DA005EFF019003EC029A026F009A1F76780316721F76BF010192C5FF5EFF019003EC29
:2038FA00049A026F009A1F767803167209D094921F767803C2FF5EFF019082FF16941F76EF
:20391A0078030352169603EC045205ED1F767803BF561701015203EC025205ED1F76780305
:20393A00BF561703055203EC065205ED1F767803BF56170607521F767803B1561702085289
:20395A001F767803B1561704095219EC1F7678031792015203EC065205ED1F767803BF5651
:20397A001B01025203EC035205ED1F767803BF561901015208EC055206EC096F1F76780330
:20399A00BF5617051F767803BF5618011F7678031792015203EC035205ED1F767803BF5637
:2039BA001A0202521F767803B1561A0104521AEC1F767803BF561C0101521F767803B15643
:2039DA001D0203520AEC015208EC06520BED1F76BF01021A80000A6F1F76BF010B1A0010D8
:2039FA00056F1F76BF010D1A0010065214EC03520DEC015206EC1F76BF010D1A00800F6F48
:203A1A001F76BF010B1A00800A6F1F76BF010B1A0040056F1F76BF01021A800006520FECA7
:203A3A0004520DEC025206EC1F76BF010B1A00040A6F1F76BF010B1A0040056F1F76BF015D
:203A5A00021A0002065208EC045206EC1F76BF010B1A0020056F1F76BF01021A080022767B
:203A7A0004520A6204522AEC01524EEC02523FEC03522EEC566F055214EC065252ED088F39
:203A9A008A021F76BE010AA8AA2801FCAB2805001F76BE011AA91F76BF01021A0800416F93
:203ABA00088F00001F76BE010AA8AA2801BCAB2804001F76BE011AA9346F088F49031F76B7
:203ADA00BE010AA805021F76BE011A1E2A6FAA280809AB28CB0B1F76BE010AA9AA28257C29
:203AFA00AB2805001F76BE011AA91B6F088F8A0B1F76BE010AA8AA2801F8AB2805001F76C9
:203B1A00BE011AA90E6FAA28080BAB2B1F76BE010AA9AA2813BCAB2805001F76BE011AA93A
:203B3A001A7669FF06001F7678031792025206ED008F880A1F76BF0104A801520CEDAA282D
:203B5A00000BAB2B1F76BF0102A9128F00001F76BF010AA803520DEDAA280009AB28CB0BEF
:203B7A001F76BF0102A9248F00001F76BF010AA8060002FE00BE42C200311F7678031793BE
:203B9A0002531CEDA9CD010004ED008F000842A8A9CD020003ED421A0002A9CD040004ED93
:203BBA00429380514297A9CD080004ED42930851429742C41F76BF0102C21F76780317931D
:203BDA00035349ED005205ED1F76BF01041A0008015205ED1F76BF01041A0002025205ED80
:203BFA001F76BF01041A8000035205ED1F76BF01041A0800045205ED1F76BF01041A020039
:203C1A00055205ED1F76BF01041A0001065205ED1F76BF01041A4000075205ED1F76BF0130
:203C3A00041A0100085205ED1F76BF01051A0008095205ED1F76BF01051A00010A5205ED73
:203C5A001F76BF010D1A20000B5205ED1F76BF010D1A0400015320EDA9CD010003ED411ABC
:203C7A000008A9CD020003ED411A0001A9CD040003ED411A0002A9CD080003EDAA1A020063
:203C9A00109003EDAA1A100042061F76BF01041E1F76BF010CA982FE0600BDB2BDAABDA222
:203CBA0003E2BD0402FE00D20002A9BD220F1F7678031792025239ED1F76BF01099216D0D0
:203CDA00008FC0DCC1FF5EFF94CDFEFF0190A8CA94961F76BF01A9CCFDFF09935FFF0291A4
:203CFA00A9CB94971F767303949200CDFFF303901F76730389FFA8CA00961F76BF01004058
:203D1A0002EF01D21F76BF01004202EF02DA1F76BF01004A02EF04DA1F76BF01004402EF69
:203D3A0008DA1F767303107A1F7678031792015231ED1F76BF01099216D0C08DC0DCC3FF47
:203D5A0016D15EFF93CDFDFF0290A8CA9B961F76BF010129008F1EDE412B0992C1FF5EFF46
:203D7A000190A95D20FFFFFF4076CE8516D00356A902079093CDFBFFA8CA9B961F767303E3
:203D9A009392069089FF00CDFFE71F767303A8CA00961F7678031792045273ED1F76BF013C
:203DBA0001CC0004008F1EDEC08DC0DC412BC9FFA95D20FFE8034076CE8516D0019093CD80
:203DDA00FEFFA8CA93961F76BF01014B02EF01DA1F76BF01014802EF02DA1F76BF010945B6
:203DFA0002EF04DA1F76BF01094202EF08DA1F76BF01014A02EF10DA1F76BF01014702EF5E
:203E1A0020DA1F76BF01094402EF40DA1F76BF01004404EFA9AA8009A9861F76BF010149AB
:203E3A0005EFA9AA18FF0100A9861F76BF01094105EFA9AA19FF0100A9861F76BF01004B0C
:203E5A0005EFA9AA1AFF0100A9861F76BF01004505EFA9AA1BFF0100A9861F76BF010940EF
:203E7A0005EFA9AA1CFF0100A9861F76BF01004A05EFA9AA1DFF0100A9861F767303107ACF
:203E9A001F7678031792065213ED1F76BF01004602EE01DA1F76BF01004802EE02DA1F7693
:203EBA00BF01004B02EE04DA1F767303107A0552C056C6001F76BF01094503EE01DA066F63
:203EDA00A9BF220F1009A9BD220F1F76BF01094403EE02DA066FA9BF220F4009A9BD220F22
:203EFA001F76BF01004203EE04DA076FA9BF220F1CFF0100A9BD220F1F76BF01004403EEF6
:203F1A0008DA076FA9BF220F1DFF0100A9BD220F1F76BF01004603EE10DA076FA9BF220F5D
:203F3A001EFF0100A9BD220F1F76BF01004003EE20DA076FA9BF220F1FFF0100A9BD220F6D
:203F5A001F76BF01004803EE40DA076FA9BF220F1FFF0200A9BD220F1F76BF01004A05EE47
:203F7A00A9AA8009A986076FA9BF220F1FFF0400A9BD220F1F76BF01004306EEA9AA18FF5E
:203F9A000100A986076FA9BF220F1FFF0800A9BD220F1F76BF01004506EEA9AA19FF010011
:203FBA00A986076FA9BF220F1FFF1000A9BD220F1F76BF01004706EEA9AA1AFF0100A986B8
:203FDA00076FA9BF220F1FFF2000A9BD220F1F76BF01004106EEA9AA1BFF0100A986076F46
:203FFA00A9BF220F1FFF4000A9BD220F1F76BF01004B06EEA9AA1CFF0100A986076FA9BF09
:20401A00220F1FFF8000A9BD220F1F76BF01004906EEA9AA1DFF0100A9860A6FA9BF220FDD
:20403A001FFF0001A9BD220F0077007700771F76780303E220041F767303107A008FC06FDF
:20405A00013BCC92C4FF5EFF0190A985A9861F76BF010192C3FF5EFF019003EC02BE026FE6
:20407A0000BEA9AAA607A9861F76BF010192C5FF5EFF019003EC04BE026F00BEA9AAA607BF
:20409A00A98609D09492C2FF5EFF019082FFA9850156A2001F767303177A82FEAFE2BE0412
:2040BA00BE82BE86BE8B060002FE2276008F02A01F7635000AA81A7669FF407621BA1F76B0
:2040DA003300221A200023760100013B009AA985008F60DF408F44DF0156A400A985015659
:2040FA00A500009BC497C597019C1C52F1641F7678031792065237ED008F00711F76C401C0
:20411A00D4CCF0FF055002961F76C401DCCCF0FF035003961F76C40103CC1FFF10501F76F0
:20413A00C40103961F76C40103CCFFF1A91A00051F76C40103961F76C40103CCFF0FA91A39
:20415A0000401F76C40103961F76C401E4CCF0FF075004961F76C40104CC0FFF1F76C40196
:20417A00205004961F767803179203521CED008F00711F76C401D4CCF0FF02500296DC183D
:20419A00F0FF1F76C40103CC1FFF10501F76C40103961F76C40103CCFFF01F76C401A91A47
:2041BA00000203961F7678031792015240ED008F00711F76C401D4CCF0FF065002961F76A5
:2041DA00C401DCCCF0FF055003961F76C40103CC0FFF40501F76C40103961F76C40103CC98
:2041FA00FFF7A91A00071F76C40103961F76C40103CCFF0FA91A00201F76C40103961F7650
:20421A00C401E4CCF0FF035004961F76C40104CC0FFF60501F76C40104961F76C40104CC2D
:20423A00FFF11F76C401A91A000104961F7678031792025207ED008F0071D418F0FFDC18EC
:20425A00F0FF1F767803179205527CED008F0071D41A0F001F76C401DCCCF0FF0250039603
:20427A001F76C40103CC3FFF30501F76C40103961F76C40103CCFFF0A91A00061F76C4010F
:20429A0003961F76C40103CCFF0FA91A00C01F76C40103961F76C401E4CCF8FF0A500496C9
:2042BA001F76C40104CCBFFFB0501F76C40104961F76C40104CCFFF7A91A00071F76C401C4
:2042DA0004961F76C40104CCFF0FA91A00401F76C40104961F76C401ECCCF0FF055005960A
:2042FA001F76C40105CC1FFF10501F76C40105961F76C40105CCFFFEA91A000E1F76C401B3
:20431A0005961F76C4010518FF0F1F76C401F4CCF8FF085006961F76C401061AF0001F765F
:20433A00C40106CCFFFDA91A000D1F76C40106961F76C40106CCFF0F1F76C401A91A009023
:20435A000696008F0071CC1A00011F76C401011A000819DCC41A10001F76C401001A1000DC
:20437A001F76C4010018BFFF1F76C401001A000F1F76C401011A00401F763300BF562101BC
:20439A00408F0068A58A19DCC41A00081F76A00119CCFFFCA91A00041F76A00119961AD016
:2043BA001F76A00195CCFFFDA91A00011A961F76A001BF5609801F76A00100CC7FFCA91AC8
:2043DA0000011F76A00100961F76A00100CCFFE3A91A00081F76A00100961F76A001019AAA
:2043FA0000CD001CD9FFA82D66FFA9881F76A00100CC800304ED0102A71E096F1F76A0018B
:20441A0000CC8003C6FF80FFA985A71EA6851F765D03AC1EA7064456A900421E3A06C000C2
:20443A0074B9008FA60E42A8C00074B91F76A00105961F76A0010018FCFF1F767E03008F5C
:20445A004C1D02A81F7678031792025216ED1F767D03BF563C0F1F767D03BF563D041F76AA
:20447A007D03BF563E091F767D03BF563F14008F8A661F767E0302A8035216ED1F767D031D
:20449A00BF563C0A1F767D03BF563D011F767D03BF563E041F767D03BF563F14008FF22BAA
:2044BA001F767E0302A81F767803189216EC1F767D03BF563CFA1F767D03BF563D191F76F1
:2044DA007D03BF563E961F767D03BF563F14008FF22B1F767E0302A81F767803179206525F
:2044FA0006ED008F7C921F767E0302A8055206ED008FA60E1F767E0302A81F767E030206E7
:20451A001F767E03001E82FE06001B76F0FF0500BDAABDA2BDA8BDA0BDC2BDC3BDAB00E271
:20453A00BD0003E2BD0003E2BD0103E2BD0203E2BD0303E2BD0430E6000602FE69FF422981
:20455A0016561F7633002292419623760100267601011F7633002218FA001F76330021283D
:20457A00FFFF10291F767E03000606EC01021F767E03415600001F765E031292C156CF01AB
:20459A001F765E033A920DECFF9C1F765E033A9608ED7FD0008FC0DC94CCEFFF04509496AA
:2045BA001F7678031B921CEC00D1013BA192008F0A71A9850156A400408F40DFC492C3FFA3
:2045DA00A988A192A9850156A500C57E69FFA1924076FE85A192019C0452A959E7641F7614
:2045FA0078031792065242ED1F76C4010992C3FFA90EA9BD120F00770077007700778BE6B4
:20461A00040000778CE6200063D0C08DC0DCA9BF120F9396008F80D869FFCFE620004076CB
:20463A0040B9CFE604006ED11F7674036FD0013B9B92C8E22F00939EA985A9BD160F007781
:20465A000077007720E7200089E609004076BCB650E800C8007790E8008800778CE600002B
:20467A0000771DD0A9BF120F93961F7678031792055258ED00D11F767E03050A1F765E03C9
:20469A0014921F767E03055404621F767E03052BA192019CA959013B1F767E03008F087113
:2046BA0005850156A400C492C3FFA90EA9BD120F00770077007700778BE604001F767E039E
:2046DA0069FF052D008F80D81235CFE620000156A400407640B9013B1F767E03008F44DF75
:2046FA008EE6000005850156A400A9BF120FC4961F767E03008FC8D705850156A400C492A5
:20471A00085207EC1F767E0305924076AC8A076F1F767E030592009B40768C88A192065286
:20473A00AB641F7678031A92C156F9001F767D033D921F767E03045419ED1F767E0305927F
:20475A001F76780318930FEC1F765E031354B156A90D1F767E0305931F765E03139F0153C5
:20477A00B156A90C69FF4076369B1F767D033E921F767E0304547B6700D11F7678031A92B2
:20479A0076651F767E03052D1F7678031A12A194A95A013B008F0871A192A9850156A400C8
:2047BA00C492C3FFA90EA9BD120F00770077007700778BE60400A285008F44DF0156A40064
:2047DA00C4E2C400007720E7000100778CE600001F767D0300D4A9BF120FA98556FF3F5465
:2047FA001F767E03B856A401A492067C08ECA192008F87DFA9850156A400C40AA285008F55
:20481A0060DF0156A4001F767E03009BC492B156A8010692A8CA24ECA22D008F80D869FF55
:20483A001235CFE620000156A400407640B9013B1F767E03008F44DFA2850156A40000066C
:20485A0008EC8EE6200000770077A9BF120F076F8EE6000000770077A9BF120FC496A19251
:20487A001F767803019C1A54A9598C641F767E03040A1F767D033C921F767E0304544E66E8
:20489A001F767E03042B69FF4076109B00D11F7678031A9222651F767E03052D1F76780384
:2048BA001A12A194A95A009B40768C88013B008F87DFA192A9850156A400408F60DFA28553
:2048DA000156A500C492C596C42BA1921F767803019CA9591A54E0641F765E0313921F765E
:2048FA007E03050A1F767E03029C055417621F767E03052B00D11F7678031D920F651F76A9
:20491A005E031492A194019B40768C88A1921F767803019CA9591D54F364008F0071CC1A4B
:20493A00004019DCC41A10001F763300BF562101103B1F7633004192229682FEAFE2BE04CA
:20495A00AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC4BE83BE8ABE82C8
:20497A00BE860300F1FF17760276BDB2BDAABDA203E2BD04A95BA85AA4BD220F1F765D0379
:20499A000002341E1F76300014282040008F46D740765FA30052FBECA292A293C0FF0191F1
:2049BA00A995A85AA2922FECA39220D11F90A174A292A1540267A2591F765D0303E21204E7
:2049DA00A10E1F765D03141E1F765D030356A301A90E161E008F46D7408F52D7407665A3A8
:2049FA00008F46D740765FA30052FBECA9BF220FA10DA9BD220FA392A194A95BA292A19E41
:204A1A00A95AD3ED1F76300014281040AFE2BE04BE82BE86BE8B0600BDB2BDAABDA203E228
:204A3A00BD04A95BA85AA4BD220F1F765D030002341E1F76300014282040008F46D74076F7
:204A5A005FA30052FBECA292A293C0FF0191A995A85AA2922FECA39220D11F90A174A2929A
:204A7A00A1540267A2591F765D0303E21804A10E1F765D031A1E1F765D030356A301A90E48
:204A9A001C1E008F46D7408F58D7407669A3008F46D740765FA30052FBECA9BF220FA10D72
:204ABA00A9BD220FA392A194A95BA292A19EA95AD3ED1F76300014281040AFE2BE04BE82BD
:204ADA00BE86BE8B060002FE1F765D030AC5008F46D7673E22761F763400008F6DA31CA850
:204AFA001A7669FF4076C6B71F765D030F8F404242A83A06C00074B9A9BD120F00770077D0
:204B1A0002E84116008F72D789E60000407611B82376002082FE0600227608D0408F806F07
:204B3A001F76BE0195CCFCFF015008961F76BE0108CCF7FF04501F76BE0108961F76BE0104
:204B5A0008CCDFFF10501F76BE0108961F76BE0108183FFF0BDDC51A08001F76BF01011848
:204B7A00F7FF1A761F76C101BF5600071F76C101BF56011F1F76C101022B1F76C101BF56A6
:204B9A00040D1F76C1010A2800801F76C1010B2B1F76C1010C2B1F76C101BF560F10D42B3C
:204BBA000002C41E1F76C101001A800069FF06001F76BF01011A080006001F76BF010118AC
:204BDA00F7FF0600009AD4930391B156A9010600C4A0D41A01000600C4A0D41A02000600C0
:204BFA001B76F0FF0500BDA8BDA0BDC2BDC3BDAB00E2BD0003E2BD0003E2BD0103E2BD0265
:204C1A0003E2BD0330E6000669FF42291656227601021F765D03015634001F765D030CC599
:204C3A00008F46D769FF673E1A76AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE876A
:204C5A00BEC5BEC4BE83BE8A0300F1FF17760276BDB2A48B1F765D031F921352E6FFA30182
:204C7A000356A901C07612C1A988A706A60DA71EA92401DFA824A71E2076C18A1F765D03A4
:204C9A00200ED40F1F765D03B0561F11C0568B0108D091C5673E1F765D031F2B1F765D0315
:204CBA00202BD118F7FFD118FDFFEFFF7C011F76C1010246CC567701C18A1F765D0320586F
:204CDA00C48A1F76C101079294961F765D03200A1F765D03BF561F13EFFF65011F76C1014C
:204CFA000246CC5660011F76C10107921F765D0321961F765D03BF561F11EFFF54011F7621
:204D1A00C1010246CC564F011F76C10107921F765D0321961F765D03BF561F0FEFFF4301F7
:204D3A001F76C1010246CC563E0108D091C5673E1F76C10107400DEED118FBFFD118FEFF24
:204D5A001F765D031F2B1F765D03202BEFFF2B011F765D03BF561F09EFFF25011F76C10103
:204D7A000246CC5620011F76C10107921F765D0321961F765D03BF561F0BEFFF14011F7626
:204D9A00C1010246CC560F011F76C10107921F765D032196C18A1F765D03200ED40F1F763B
:204DBA005D03B0561F07C056FE0008D091C5673E1F765D03BF561F09EFFFF5001F76C101FA
:204DDA000246CC56F0001F76C10107921F765D0321961F765D03BF561F07EFFFE4001F762C
:204DFA00C1010246CC56DF001F76C10107921F765D0321961F765D03BF561F05EFFFD30003
:204E1A001F76C1010246CC56CE001F76C10107921F765D03219608D091C5673E1F765D0385
:204E3A00BF561F03EFFFBF00D1400AEF1F765D03BF561F01D11A04000AD091C5673ED1416A
:204E5A00CC56B1001F765D03BF561F0DD11A08000AD091C5673EEFFFA6001F76C101BF5667
:204E7A00008F1F76C101082B1F76C101021A20001F765D03BF561F12EFFF95001F76C10157
:204E9A00BF56008FC18A1F76C101E49208961F76C101021A20001F765D03BF561F10EFFFE4
:204EBA0082001F76C101BF5600871F76C101082800031F76C101021A20001F765D03BF563C
:204EDA001F0E706F1F76C101082B1F76C101021A20001F765D03BF561F0C646F0AD091C557
:204EFA00673E1F76C101BF5600871F76C101082800051F76C101021A20001F765D03BF56D7
:204F1A001F0A506F1F76C101BF56008FC18A1F765D032058C48A1F76C101949208961F76DE
:204F3A005D03200A1F76C101021A20001F765D03BF561F08376F1F76C101BF56008FC18A1D
:204F5A001F76C101E49208961F76C101021A20001F765D03BF561F06256F0AD091C5673EA1
:204F7A001F76C101BF5600871F76C101082800021F76C101021A20001F765D03BF561F04DB
:204F9A00116F1F76C101BF5600871F76C101082800061F76C101021A20001F765D03BF565A
:204FBA001F02BE8B0600A98AC4920600A983C57C0600BDB2BDAABDA202FEA486008DA001D8
:204FDA0092923CEC922B0FD092924196013B008F00D7A9850156A400C49203523268A91B00
:204FFA0090012F66419233521AECA985408F00D70156A500C558A28A0EDCA093A092FE9D10
:20501A00FF9CA859A958035694089CCAA95B408FFFFFA10E407644B7A35405ED41920CD0B5
:20503A0092961C6FD292025205ED1F76BF01081A0400099AA28A40768497A928FFFF0E6F92
:20505A00D292025205ED1F76BF01081A0400099AA28A40768497A928FFFF82FEBE82BE869E
:20507A00BE8B0600BDB2BDAAA988A4861F767803BF563F01008FA101A9AA0156A400008D25
:20509A003203A48B9292C196C97E408FFFFF0202A18A407644B7A9CDFF00D197A7FFFF9011
:2050BA00D996E12BE92B0602A183A28A4076A397BE86BE8B0600A71EAC281F00013BA7C40D
:2050DA00A7062256A60740FF0156A400C488A7060190009B58FF04ECA6CCFF00046FA69222
:2050FA00A7FFFF9006000600A4830EDD0129E592FF90A988ED92FF900356A908A6AF37FF3F
:20511A00A71EDD92FF90A988A706A6AF37FFA71ED592FF90A988A706A6AFA71E09D0959296
:20513A00FF90A90EE41E08D09592FF90A988E40637FFA6AFE41EFD92FF90A988E40637FF68
:20515A00A6AFE41EF592FF90A988E40637FFA6AFE41E02020156E400F4C30AD094C31F7664
:20517A007803BF5634013A9A4076AFA50600BDB2BDAAA4860AD0928EE2A3A9A90219A08A56
:20519A004076D8A5A95DA9A9A08A01194076D8A50356A908A594A959008D3203A28A0EDCD6
:2051BA009292C496BF56CC33408FFFFF0202407644B7E2C40AD0A95D928A82DEA60640765D
:2051DA0057B7A193A95510EC008D3C03922BD292025205ED1F76BF01081A0400099AA28AFC
:2051FA0040768497096F339AA28A4076AFA5008D3C03BF569201BE86BE8B06000600BDB2CD
:20521A00BDAA02FEA4861F767803BF563F01A28A01290EDCE492FF90A988EC92FF900356A2
:20523A00A908A6AF37FFA71EDC92FF90A988A706A6AF37FFA71ED492FF90A988A706A6AF00
:20525A00A61E20FF0080A60F0666A606407650A54196076FA692AD5C029B81DC407689A2F0
:20527A00A9AA008FA1010156A400008D32039292A48BC196BF56C9384192FF90D196419277
:20529A00A7FFFF90D9961F765D033492A9CDFF00E197A7FFFF90E996408FFFFF0602A18AF4
:2052BA00407644B7A9CDFF00F197A7FFFF90F99608D0912B09D0912BA28A0A02A183407627
:2052DA00A39782FEBE86BE8B0600BDAA02FEA486A28A01290EDCE492FF90A988EC92FF9053
:2052FA000356A908A6AF37FFA71EDC92FF90A988A706A6AF37FFA71ED492FF90A988A7063C
:20531A00A6AFA61E412BFC92FF904196F4924193A838419620FF0080A60F0666415CA606E0
:20533A00407653A5076FA692AD5C029B81DC407632A2399AA28A4076AFA582FEBE86060097
:20535A00BDB2BDAABDA203E2BD0403E2BD05A4861F767803BF563401A28A0EDCE492FF9012
:20537A00A988EC92FF90A90E37FFA6AF37FFA9BD260F00770077DC92FF90A988A9BF260F09
:20539A00A6AF37FFA9BD260F00770077D492FF90A988A9BF260FA6AFA9BD260F08D009D17A
:2053BA009492FF90A9889C92FF90A90E37FFA6AF37FFA9BD220F00770077FC92FF90A988E5
:2053DA00A9BF220FA6AF37FFA9BD220F00770077F492FF90A988A9BF220FA6AFA9BD220F3F
:2053FA00A9AA008FA1010156A400008D3203A48B9292C196BF56C934408FFFFF0202A18A9A
:20541A00407644B7A95BA35DA4BF260FA9BF220F407657B7A95B0102A183A28A4076A39781
:20543A00BF56C1340102A183A28A4076A397C28AE446FEEFA9BF220FA5BF260FA28A40768E
:20545A00F597C28AE446FEEFA9AA408FA1010156A500A392FF90C596A392A7FFFF90CD9697
:20547A00D52BDD2BA28A06024076A397AFE2BE05AFE2BE04BE82BE86BE8B06000600060060
:20549A00BDAA06FEA486A28A0EDCEC92FF90A90E421EE492FF90A988420637FFA6AF421EBA
:2054BA00DC92FF90A988420637FFA6AF421ED492FF90A988420637FFA6AF421E09D0949219
:2054DA00FF90A90E441E08D09492FF90A988440637FFA6AF441EFC92FF90A988440637FF47
:2054FA00A6AF441EF492FF90A988440637FFA6AF441E0DD09492FF90A90E461E0CD09492AF
:20551A00FF90A988460637FFA6AF461E0BD09492FF90A988460637FFA6AF461E0AD094927A
:20553A00FF90A988460637FFA6AF461E0ED094CCFF0004520AEC055212ED4206448A46C457
:20555A00A693407689A2076F4206448A46C4A693407632A23C9AA28A4076AFA586FEBE86EA
:20557A000600BDB210FE408F00C1AD5C090289DC4076C0B9AD5C408F09C18FDC060240768B
:20559A00C0B9008FC0DC00D0942B01D8A0928052FC681F7678037ED0169294961F7678033D
:2055BA0017920452B056A060B056940AB056A062B056940810ED1F767403BF562002408F6F
:2055DA0022DD00D0AD5C8FDC9492959601D8A0920652F96861D0008FC0DCBF5694651F765A
:2055FA0078031D92B056A063B05694141F7678031C9220EC1F7678031692FF9CA9881F76CD
:20561A0078031692085206651F7678031692FE9CA988408F34DD00D0A60E008F80DC32FF85
:20563A00A00D0156A400C492959601D8A0920852F4681F7678031792015215ED00D00D6F0C
:20565A00008FC0DC30D1A9A8A00DA98ABF569C4648D1BF569C3C01D81F7678031D920E9C94
:20567A00A054EF661F7678031792025221ED00D0008FC0DC30D1A9A8A00DA98ABF569CAA24
:20569A0048D1BF569C9601D8A0920652F26806D0008FC0DC30D1A9A8A00DA98ABF569C737C
:2056BA0048D1BF569C6901D8A0920852F2681F7678031792035211ED00D0008FC0DC30D1D6
:2056DA00A9A8A00DA98ABF569C4648D1BF569C3C01D8A0921452F2681F76780316920952A4
:2056FA001AED013B00D0AD5C408FC8D789DC95850156A400408F08DDC492959601D8A0924C
:20571A000F52F2683DD0008FC0DCBF5694463ED0BF5694461F7678031792065223ED30D06F
:20573A00008FC0DC9428A40131D09428A40132D09428840333D09428840348D094282C01D5
:20575A0049D094282C014AD0942820034BD0942820036ED17AD094929C967BD094926FD0A9
:20577A0094961F7678031B920AEC008F30DD00D09428000801D8A0920452FB684076A9845B
:20579A0090FEBE8B0600BDA2A9287E3FC08D80DDA8280201A38A407689A2809AA38A40769D
:2057BA0082B780D093540AEDA91BFFFF07EC7ED01F7678039392165415EC40762EA8C08DEC
:2057DA00C0DC7FD0932B40767EA91F7678031A9217EC7FDBC31A10001F765E033A28FFFFCD
:2057FA000F6F408FC0DC008F80DD00D09492959601D8A0928052FB681F7674033F2BBE82A3
:20581A000600BDA200B600D0008FC0DC9488008F80DDA9A8A00DA98AA692C45403ECC47E9E
:20583A0001B601D8A0928052F068A79210ECC08D80DD809AA38A407682B780D09396A92803
:20585A007E3FA38AA8280201407632A2BE820600BDB2BDAABDA202FEA482A38A0EDCDC2F24
:20587A000356E408ECCAA927A9A2008FA1010156A4001F767E032592C496BF56CC03035668
:20589A00AB01D49600BEAB9220ECAA92A680408FC0DCA772008FA10103D0A9A0A70DA983BE
:2058BA000356A601A980A9A20156A400A792A072C593D7FF949704D0A072C592FF909496C5
:2058DA0001DEAB92A654E2660356AB014196008FA101039A4194A959A9A20156A400408FBA
:2058FA00FFFFA10EA486407644B7A9CDFF009A9704D04193A073A7FFFF90929605D04192A0
:20591A00A072922B06D0A072922B07D0A072922B089AA894A958922B408D9E01BF569B019A
:20593A00A283A38AA00E4076A39782FEBE82BE86BE8B060000BEA9A80ED0A60DA983A9A8ED
:20595A009580A60D008DA101A983957F01DEA6920852F268A4830EDDDD580356E508EDCAE7
:20597A00408FC0DC9596008D9E01BF569401A9A8408FA1010156A5000A024076A3970600E1
:20599A00BDB2BDAAA486008FA101A9AA0156A400A48BBF56C110BF56C904D12BD92BE12B6B
:2059BA00BF56E930408FFFFF0602A18A407644B7A9CDFF00F197A7FFFF90F996008D9E0101
:2059DA00BF5692010802A183A28A4076A397BE86BE8B0600BDB2C076F8D700D5A52D05D038
:2059FA000C3506D1A4C4A072A927A1720EDE03569608A5589E94979608D0AB92A07207D1DA
:205A1A00A172009B9692A5589ECAB056A801807620D8969701DDA5920852E168BE8B060060
:205A3A0002FE22761F7678031792045204ED008FCAB0036F008FDA801F7634001AA81A7635
:205A5A0069FF1F765D030F8F40423A0642A8C00074B9A9BD120F0077007702E8D123008FB6
:205A7A006AD789E60000407611B81F7630000C2820402376001082FE0600BDB2BDAABDA220
:205A9A0000D24076D1AE103B69FF4076A0B8267600002F760000407672BA407633B84076AA
:205ABA009A991F767803009A16934076EAAC0D9A4076429801D4418F00C2A9A040764E9877
:205ADA001F7678031D9208ED418F00C202D4A9A040764E98076F012902D420FF00E140767F
:205AFA004E984076E0A240763A99008FC06FA4830CDDC51A01000BDCC41A010000D1012976
:205B1A0020FF50C340768DB8008FC06FA4830FDDC51A01000EDCC41A0100A192019C0A5298
:205B3A00A959EE64008FC06FA4830ADDC51A01000BDCC41A010040766899407602BA1F76C7
:205B5A0078031692109B407689BA40768DAA4076EFB81F7678031792045205EC4076D19DF6
:205B7A004076F38240761A85407640A94076A9841F7678031792065203ED407662B51F76A6
:205B9A00780316921F7674033E9622761F76C001BF56292F1A761F765E03BF5612011F764A
:205BBA005E030192C15684001F765E03012B1F767403239212EC1F767E03210A1F7674030E
:205BDA0023921F767E03215408661F767E03212B008F80D340763DAA00D1013BA192008F4D
:205BFA009DDFA9850156A400408FC0DCC492019CA988C496A192A98560090156A500C593DF
:205C1A00A655506600534EEC1F767E031D924AEC013BC42B066F109AA794A918F0FFC496A2
:205C3A00A192008F9FDFA9850156A400C49280520268C42BA192008F9FDFA9850156A400F7
:205C5A00C4800356A103408F82D7A61EA792C3FFA927A606AB0D0156A500C592A7CD0F00F8
:205C7A00A82D62FFA988D8EC013B0B6FA192008F9FDFA9850156A400C40AA692A0FFA988EA
:205C9A000190F5EC013BA192C08D9FDFA9850156A300008FC0DCC393009A4076BCADC30811
:205CBA000300A192019C0252A95998647FD0008FC0DC944106EF7FDCC418FDFF40762EA8A2
:205CDA007FD0008FC0DC944206EF7FDCC418FBFF40767EA97FD0008FC0DC944306EF7FDCB6
:205CFA00C418F7FF407640A97FD0008FC0DC944506EF7FDCC418DFFF40761C804076CA9B4F
:205D1A001F7678031792015212ED16D0408FC0DC9592A58AC1FF5EFF7FDCA2CE0356A902CB
:205D3A000790C49895CC0400C1FFA95A1F7678031792065266ED009B1F767E0322921F76D0
:205D5A007403B156A8013F92C6FFA8CE1BEC008FC06FA4830BDDC51A00401F76780317924A
:205D7A00065207EC045205EC0DDCC41A0020056F1F76BF01041A0800008FE8031F767E0311
:205D9A0016A81F7674033F92A993D6FF1F767E030191229700D41F767E032393B156A40190
:205DBA00C5FFA4CE1AEC1F76BF010B1A00041F7678031792065208EC045206EC1F76BF016D
:205DDA000B1A0020056F1F76BF01021A0800008FE8031F767E0316A81F7674033FCC4000D2
:205DFA001F767E03C5FF23961F767E03160609ED1F76BF010D1A00401F76BF010D1A000492
:205E1A0000D1A19204ECC08D00D0036FC08D80D3A38A407656A5A91BFFFF59EC00BE1F760D
:205E3A007E030EC21F76BF010F1A010037521362375232EC33520A6233523AEC035244ECB2
:205E5A0004523EEC065238EC426F34522DEC355227EC3D6F3A5208623A5212EC385218EC88
:205E7A00395212EC346F3B5207EC3C5230EDA38A4076BDA72C6FA38A4076F0A5286FA38A93
:205E9A004076F1A5246FA38A4076E2A6206FA38A40767CA61C6FA38A4076BCA7186FA38A85
:205EBA0040767BA6146FA38A40761DA7106FA38A407634A60C6FA38A407617AA086FA38AC8
:205EDA00407667AA046FA38A4076A5A9A192019C0252A959E3FF65FE956F34FEA892FF9CC7
:205EFA000564105204640F9A026F009A22761F76BE0109CDFFDFA81A00101F76BE0109973B
:205F1A001F76BE0109CDFF3FA81A00401F76BE01099708BE1F7680012AC21F7680012CC23D
:205F3A001F76840102C21F7684010AC200BE1F76800100C2013BAA28457FAB28F0FFA9852B
:205F5A001F768401A6A95AFF5D56A60000A9AA28467FAB2B1F768401AB03081EAA28FFFF38
:205F7A00AB28FEFF1F76800102A91F7680010302001EAB28FFFF1F76800108A91F7680018F
:205F9A000CA91F7680011EA91F76800122A91F76800118A90002601E601A80F21F7680011B
:205FBA006006141E1F7680011844FDEF1F76800116065E1E5E18FFFD5E1A00015D1800FFC4
:205FDA005D1A05005E1A7F005E18FAFF1F7680015E06161E6018FFEF1F7680016006141E03
:205FFA001F7680011844FDEE088F70641F76830100A81F76830102A801021F768001301ED4
:20601A001F7680010002321E1F7680012E1E541E1F7680010202241E1F7680010002261E72
:20603A00541A0100531A0200541A06001F7680015406201E1F763700008F4EAE08A81F76AA
:20605A003300321A10001F763700008F9FAE0AA81F763300321A2000237600011A761F764A
:20607A0078030002281E1F767803261E1F767803322B1F7678032A1EB4FE69FF0600A880E2
:20609A001F76780333920BEC1F7680010806019006ED1F7680010A06019045EC01021F76F2
:2060BA008001081E1F7680010A1E013BA483029AA794A4C4A9850156A500019AA794A9583E
:2060DA00C5855AFFA092A9850156A600AA180000C6853FFFABCAAACBA61EA7850156A40086
:2060FA00C4855AFF1F768401AA180000A7853FFFABCAAACBA81A00E0061E1F76840104C20E
:20611A0022761F76800100022E1E1A761F7680010102041E1F767803BF5633011F76BF01F0
:20613A000E1A0100060006FE00021F767E030E1E0ED094C40CD094C5A606A80EA958A0CC94
:20615A0000804396A0CC00404296A0CC00204196A018FF1F467EA7064597447F439208EC36
:20617A00A092805205674692008FC0DC949601D8429208ECA092805205674592008FC0DC55
:20619A00949601D8419208ECA092805205674492008FC0DC94961F76BF010F1A010086FE7D
:2061BA0006001B76F0FF0500BDA8BDA0BDC2BDC3BDAB00E2BD0003E2BD0003E2BD0103E248
:2061DA00BD0203E2BD0330E6000602FE69FF422916561F763300329241962376000126764D
:2061FA0000011F76330032921F763300322B1F7633002128FFFF1029008F006169FF40767D
:20621A0010AE1F76800102020C1E1F763300211A0001103B1F7633004192329682FEAFE29F
:20623A00BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC4BE83BE8A0300F1FFAD
:20625A00177602761B76F0FF00E2BD0030E6000602FE422916561F76330032924196237611
:20627A000001267600011F76330032921F763300322B1F7633002128FFFF102901021F76D5
:20629A008001061E1F767803320A1F763300211A0001103B1F7633004192329682FE80E25F
:2062BA00BE00F1FF177602764076F1AE049A029B4076F9AE407687AF060011D0008F107042
:2062DA0094920F90045210EDCCCC8001C6FF02520BED22761F76C001BF5625551F76C0018F
:2062FA00BF5625AA1A76060022761F76C001BF5629681A7669FF0600BDAAA980A8881F7623
:20631A00C001114302EF25761F76C00111CC800107EC22761F76C00111187FFE1A7622765F
:20633A00008F1070CC1A4000A79211D01F76C0010F9094CDF0FFA8CA21961A76A79203EDCD
:20635A0001D2026FA75AA92880C3A828C901AC1E0556A200A2A94076F1AE1F76C001114022
:20637A00FDEF22761F76C0011118BFFF1A76A693015303EC02530EED22761F76C001A692C0
:20639A0011CD7FFE03901F76C00186FFA8CA11961A76A6930AED013BA9AAAC281E0040FF81
:2063BA002256A20741FFA986A69301530AED013BA9AAAC281E0040FF2256A20741FFA9865F
:2063DA00A693025309EDA9AAAC281F00013B2256A20740FFA986A79218EDA692035215ED41
:2063FA0022761F76C00111CC7FFF1F76C001A91A0001119669FF20FFDA05407690BA1F767E
:20641A00C001111A80011A761F765D033AAABE8669FF0600BDA202FE22761F76C001BF5678
:20643A001A011F76C0011B2B1F76C0011A9203ED0102066F1F76C00103561A01A90E421E40
:20645A001F765D0369FF3A06C00074B91F765D033E1E1F76C0011B9203ED0102066F1F7647
:20647A00C00103561B01A90E421E1F765D033A06C00074B91F765D033C1E15D0008F200BA5
:20649A001F762C0094CCF8FF0150359614DCC41A04001F762C003418F7FFC08D1070A38ADF
:2064BA000CDCC41A0800787680001F76C0011C1A10001F76C0011C1A00041F76C0011C1ACE
:2064DA0000081F76C0011C1A20001F76C0011C1A00011F76C0011C1A00101F76C0011C1A39
:2064FA0000201F76C0011C1A00401F76C0011C1A00801F76C0011C18FBFFA38A0DDCC41A12
:20651A0001001F76C0011D1A02001F76C0011D1A04001F76C0011D1A08001F76C0011D1A1E
:20653A0010001F76C0011D1A20001F76C0011C1A04001F76C0011D1A00041F76C0011D1AD6
:20655A0000081F76C0011D1A00101F76C0011D1A00201F76C0011D1A00011F76C0011D1AB4
:20657A0000021F76C0011D1A00401F76C0011D1A008010DBC31A00011F76C001201A0002CA
:20659A001F76C001201A00041F76C001201A00081F76C001201A00101F76C001201A002065
:2065BA001A7682FEBE8269FF060002FE22761F762B002028FFFF1F762B002128FFFF1F76C9
:2065DA002B002228FFFF1F762B002328FFFF1F762B002428FFFF1F762B002528FFFF1F767B
:2065FA002B002628FFFF1F762B002728FFFF1A761F76FFCF389241961F76FFCF3992419664
:20661A001F76FFCF3A9241961F76FFCF3B9241961F76FFCF3C9241961F76FFCF3D92419642
:20663A001F76FFCF3E9241961F76FFCF3F9241961F762B002F925EFF019082FE69FF0600CE
:20665A001F767E03100A1F767E03C4E21000007712E8D01F14AD21641F767E03102B1F7698
:20667A007E03110A1F767E0311920A5204ED1F767E03112B1F767E03113457041F767E0340
:20669A000C961F767E030A0603EC0002036F000201191F767E030A1E06001B76F0FF0500D0
:2066BA00BDAABDA2BDA8BDA0BDC2BDC3BDAB00E2BD0003E2BD0003E2BD0103E2BD0203E264
:2066DA00BD0330E6000669FF4229165600D2227601021F765D0301562C0023763911102984
:2066FA001A761F7674033F4F04EE69FF4076DAAE1F765E03000A1F765E0300921452086860
:20671A001F765E03002B1F765E03BF560101008FC06FF41A01001F767803179206520EEC59
:20673A0004520CEC025205EC0FDCC41A00040A6F1F76BF010F1A0040056F1F76BF01061ABF
:20675A0000021F7678031792065208EC045206EC1F76BF010F1A0020056F1F76BF01061A49
:20677A0008001F767E030102008F204E0E071F767E03A61E0E1EA9A8A60F04671F767E033F
:20679A000EA81F767E03130A1F767E0313920A5204641F767E03132B00D01F767E030D929E
:2067BA0012EC008F22DD1F767E03949213540565019AA02D66FFA27201D81F767E03A09224
:2067DA000D54F0681F767E03120A1F767E031292025204651F767E03122B16D0008FC0DCD9
:2067FA007FD194939C92A9CB0191C0568E00A9CC000860ED20FF204E1F767E030E0F346909
:20681A001F767E0312920AED013B1F76730300D401D569FF0085407627B41F767E03129284
:20683A0001520AED013B1F76730301D401D569FF0185407627B4C08DC0DC00D502D469FF87
:20685A00D392A2CEA90E407627B41F767E0312920252C0568900013B00D503D4DB85407656
:20687A0027B4EFFF81001F767E03129207ED00D400D569FF0002407627B41F767E031292A8
:20689A00015207ED00D501D469FF0002407627B400D502D469FF0002407627B41F767E0336
:2068BA001292025260ED00D503D40002407627B45A6F1F767E03129208ED00D401D569FFB0
:2068DA0020FFB822407627B41F767E031292015208ED01D401D569FF20FFB822407627B475
:2068FA0000D502D469FFA20E407627B41F767E031292025238ED012900D503D420FFFFFF04
:20691A00407627B4306F69FF40769DB01F767E03129209ED013B1F767E0300D404D50C8582
:20693A00407627B41F767E031292015209ED013B1F767E0301D404D50C85407627B41F76F2
:20695A007E0300D502D40A06407627B41F767E031292025208ED1F767E0300D503D40A067B
:20697A00407627B4AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BE87BEC5BEC4BE837F
:20699A00BE8ABE82BE860300F1FF17760276227615D0008F200B1F762C0094CCF8FF015079
:2069BA003596A48314DDC518FCFF1F762C003418F7FF1F762C00341A0400C41A6000C41AD0
:2069DA001C00C41A0300C41A0030C41A000EC41A8001CC1A4000C41A0040C41A00801F7610
:2069FA002C00211A0300A4830CDDC51A60001F762C002C1A1C001F762C002C1A03001F7602
:206A1A002C002C1A00301F762C002C1A000E1F762C002C1A8001A4830DDDC51A40001F7658
:206A3A002C002C1A00401F762C002C1A00801F762C002D1A0300A4830EDDC51A60001F7612
:206A5A002C002E1A1C001F762C002E1A03001F762C002E1A00301F762C002E1A000E1F769B
:206A7A002C002E1A8001A4830FDDC51A40001F762C002E1A00401F762C002E1A00801F766E
:206A9A002C002F1A030018DCC41A07001F762C00381A38001A7669FF407655B307F6007716
:206ABA0069FF06002276008F806FA48318DDC51A03001F76BE01181A0C001F76BE01181A22
:206ADA0030001F76BE01181AC0001F76BE01181A00031F76BE01181A000C1F76BE01181A85
:206AFA0000301F76BE01181A00C0A48319DDC51A03001F76BE01191A0C001F76BE01191AED
:206B1A0030001F76BE01191AC0001F76BE01191A00031F76BE01191A000C1F76BE01191A40
:206B3A0000301F76BE01191A00C0A48314DDC51A03001F76BE01141A0C001F76BE01141ABA
:206B5A0030001F76BE01141AC0001F76BE01141A00031F76BE01141A000C1F76BE01141A14
:206B7A0000301F76BE01141A00C015DCC41A03001F76BE01151A0C001F76BE01151A300075
:206B9A001F76BE01151AC0001F76BE01151A00031F76BE01151A000C1F76BE01151A0030D0
:206BBA001F76BE01151A00C069FF407655B306002276008F806FA48326DDC51A03001F7695
:206BDA00BE01261A0C001F76BE01261A30001F76BE01261AC0001F76BE01261A00031F764C
:206BFA00BE01261A000C1F76BE01261A00301F76BE01261A00C0A48327DDC51A03001F76B6
:206C1A00BE01271A0C001F76BE01271A30001F76BE01271AC0001F76BE01271A00031F7607
:206C3A00BE01271A000C1F76BE01271A00301F76BE01271A00C0A48317DDC51A03001F7682
:206C5A00BE01171A0C001F76BE01171A30001F76BE01171AC0001F76BE01171A00031F7607
:206C7A00BE01171A000C1F76BE01171A00301F76BE01171A00C0A48328DDC51A03001F7661
:206C9A00BE01281A0C001F76BE01281A30001F76BE01281AC0001F76BE01281A00031F7683
:206CBA00BE01281A000C1F76BE01281A00301F76BE01281A00C016DCC41A00C01F76BE01AD
:206CDA00161AC0001F76BE01161A00301F76BE01161A000C1A7669FF0600005206ED1F768E
:206CFA00BF01041A4000056F1F76BF01021A40000600005206ED1F76BF01041A0001056F04
:206D1A001F76BF01021A00010600009A4076EAB31E02407690BA019A4076F6B31E02407604
:206D3A0090BA009A4076F6B31E02407690BA06004076F6B3019A4076EAB3009A4076F6B38A
:206D5A000102407690BA009A4076EAB31E02407690BA0600BDB2BDAABDA20EFEA98200D0C7
:206D7A00A088A65AA4920252E3FFF800A9A2B456A001A9A256FFAC1EA59205640452B4560D
:206D9A00A201026400D5A3AB00D1A5920D650A02421EA9A2C00074B9A982A192019CA95992
:206DBA00A592A154F562A9A20B65A692019CA9880A02421EA9A2C00074B9A982F762A3ABFF
:206DDA00A092A694A988B156A601A692A594A98800D1A692FC9CA154E2FFB200A592B45642
:206DFA00A500A52D019A66FFA9880152B156A600C076E80342C3A9A2C00074B9441EC076DB
:206E1A00E803A9A242C3C00083B964B642C3C00074B9461E6402421EA9A2C00083B90AB6E4
:206E3A0042C3C00074B9481E0A02421EA9A2C00083B94A1EA71E460648074407A70704ED7B
:206E5A0000BEA65DA558A29214EC013B03D1AD800356A1018ADF0156A700C7060AEDA5928C
:206E7A00A15407EC0F02C71EA192FF9CA959F062A0921CEC013B01D1AD5D0356A1018ADD44
:206E9A000156A5000F02C50F09ECA192035206EC019C0452A959F164096FAD5D0356A101C1
:206EBA008ADD0156A5000A02C51E013B00D1AD5D0356A1018ADDA5800156A700408F01DE1C
:206EDA00A9A0C707A983C585C71EA12D019A66FFA6CE04EC80020156C700A192019C04522E
:206EFA00A959E66403564808A9855AFF4A064E1EAA1800004E92FF904E964D2B4E92ABCA5E
:206F1A004E964D92AC281800AACA4D964606FF90009B3FFFA9274E92ABCAA8274E964D92E6
:206F3A00ABCA4D9644063B56A9274E92ABCAA8274E964D92ABCA4D964E820F6FA592FF9CD5
:206F5A00A95D0A02421EA9A2C00074B9A982A192019CA959EFFF3FFFA492013B008F11DE54
:206F7A00A9850156A400C4924B9600D14B921052286200D2A3920190A988013BA9A240FF6E
:206F9A00A982A692407615B4A292019C0852A95AF2644B924C9600D24C9201904C93B0FFE3
:206FBA004C97407615B4A292019C0652A95AF5644B0A407602B4A192019C0452A959D764AC
:206FDA008EFEBE82BE86BE8B0600008F59021F767E0314A81F767E03BF5618051F767E031E
:206FFA00192870170600005206ED1F76BF010D1A0010056F1F76BF010B1A00100600009A3A
:20701A00019C1952FE640600BDB2BDAABDA2A9591F76BF010D1A00080102407690BA00D256
:20703A00C08DC06FA38A0BDCC41A0080A192CEFF407670B5A19280FFA9590102407690BAB6
:20705A000DDBC31A00800102407690BAA292019C1052A95AE6641F76BF010B1A0008BE828C
:20707A00BE86BE8B0600A9280290407681B51F767803179206520FEC04520DEC025206EC73
:20709A001F76BF010F1A00040A6F1F76BF010F1A0040056F1F76BF01061A00020600BDB2BD
:2070BA00BDAA04FEA98B4C86013B79D0008FC0DC42AA9485AC1E4456A100C00074B9013B64
:2070DA0078D0A98342AA9485AC1E4456A100C00074B9013B1F7674033981A503441E7FD0D0
:2070FA00944904EF7AD09485441E4492A918FF0F4496A91A0080407681B57BD0408FC0DC7D
:20711A0044929596A9B234FF42AAA61EA9B232FFA607C00074B9A98A42AAC802AC1E4456A3
:20713A00A100C00074B91CD0A49E289C959684FEBE86BE8B060002FE1F767E03160606EC51
:20715A0001021F767E03415616001F767E031A0A1F767E0318921F767E031A54E6FF8F005D
:20717A001F767E031A2B1F767E0314065AED1F7674033F4729EF1F767E0319921F767E03A2
:20719A00C0FF1B5404671F767E031B0A1F767E031B0A1F767E0319921F767E031B541F76EB
:2071BA007E032A561B081F767E03C4E21B001F767E03C4E219014FE800C84FE809800077AE
:2071DA0010E708000E6F1F767E031B2B90E51F767E031C92019C1F767E03A918FF031C965C
:2071FA001F767E031C9212EC1F7674033F480EEE1F767E038CE600001988013BA9BF120F36
:20721A0042C2A9854076CCB5396F4076B0B51F767E03BF561C011F7674033F18FFFE2E6FE3
:20723A001F767E0314C420FF58021F767E0381DEA60F14C21DEC20FFF4011F767E03140F77
:20725A0017EC20FF90011F767E03140F11EC20FF2C011F767E03140F0BECC8021F767E03CF
:20727A00140F06EC64021F767E03140F07ED4076B0B51F767E03BF561C0182FE0600BD3A6C
:20729A00BDB2BDAABDA202FE0129A9BF120F58FF5B61A85C7F91A8088000421EA493D6FF29
:2072BA00A85CA9BF160F6761A85D7F91A8088000A859A958A593D6FFA85DA493A571A818F5
:2072DA000001A697A418FF00A518FF007FDCA492A59EA7964D64A90801FF3E62A193A09266
:2072FA0036FFA859A958420635FF0EF6A11FA95BA3010AF6A11F2D56A204A32DA03640FF87
:20731A000BF6A11F33FF009B30FF54FFA20CA39540FFA70801001FF677FF200940FFA708CC
:20733A0001001FF677FF5AFFA7922265A90801FF1363A9A946FF7F91A85BA95AA625A795B3
:20735A0096FFA20CA395A9BD120F82FEBE82BE86BE8BBE8E0600009B57FFA8087FFF5AFFFA
:20737A00A693F260A8280080AA71AB92ED6F20FF0000EA6F5AFFA493A818000196FFA85C02
:20739A00A9A9A8087FFFA81C0080A4CBDD6FA71E807640DE0C6F81DF8458A592A0F2A092C9
:2073BA00FF90A958A592C7FF9670A95DA706F4EDA59206005AFF00B6A9A926ECA792019012
:2073DA00A9580129A4C4A70640FF0156A600C693A792019004EDA892C7FFA92DA0920152A8
:2073FA0004EDA8CCFF00A92DA593AC58A0F3807640DEA092D7FFFF90A9589671A85D01DFD2
:20741A00A9A9A70FDC66A5920600A927BF76FFFF00B6AB933D65013BA792A483A985015611
:20743A00A500C593FF91A6F3009AA693019105EDA693B0FFA888066FA693B0FFA81C01A0DB
:20745A00A888A993019DA8920853F064013BA792A483A9850156A500C593D7FFA6F3009AF8
:20747A00A693019105EDA693B0FFA888066FA693B0FFA81C01A0A888A993019DA8920853BC
:20749A00F064A793019DA880AB93A755C562A6920600008F000C1F765D0322A8AA28FFFFB5
:2074BA00AB28FFFF1F76300002A91F763000062B1F763000072BE41A10001F763000041A93
:2074DA00200000021F765D03241E1F765D03008F080C2AA8408F100C1F765D0332A01F7688
:2074FA0030000AA91F76300012A91F7630000E2B1F7630000F2B1F763000162B1F76300047
:20751A00172BE41A1000E51A10001F7630000C1A20001F763000141A20001F765D032C1E95
:20753A001F765D03341E060003E2E40003E2F40100E70800007788E60000C48303E2D5006C
:20755A00C483F52BC483FD2BC483E51A1000C483E51A2000C483E518FFFBC483E518FFF707
:20757A00C483E51A00400002D41E06001F76C001201A0010407655B32276008F200BA4839A
:20759A0015DDC518F8FFA48314DDC51A03001F762C003418F7FF1F762C003418FBFF0ED029
:2075BA001F762C0094CCBFFF20502E961F762C002ECCE3FF1F762C0008502E961F762C0063
:2075DA002ECCFCFF1F762C0001502E961F762C002ECCFFDF1F762C00A91A00102E961F7640
:2075FA002C002ECCFFF71F762C00A91A00062E961F762C002E187FFE0FDCC418BFFF1F7669
:20761A002C002E18FFBF1F762C002E18FF7F1F762C002F1A03001A7607F6007769FF06001C
:20763A00BDB2BDAAA98600D10129A9AA40FFA98608EC1002407690BA01D9A9AAA10FFA662C
:20765A00BE86BE8B0600103B1F7633002018FEFF1F763300222B1F763300242B1F76330041
:20767A00262B1F763300282B1F7633002A2B1F7633002C2B1F7633002E2B1F763300302B04
:20769A001F763300322B1F763300342B1F763300362B1F763300382B1F763300232B1F7685
:2076BA003300252B1F763300272B1F763300292B1F7633002B2B1F7633002D2B1F763300F1
:2076DA002F2B1F763300312B1F763300332B1F763300352B1F763300372B1F763300392B6E
:2076FA0069FF06001F763300201A01001F7633002128FFFF102969FF0600AD28000469FF08
:20771A001F5616561A5610E6000240291F76000002291B762276A92894BAA82800000109BB
:20773A001B61C07694BA04290F6F009BA92401DF046C0429A82401DFA61EA1F78624A70640
:20775A00A1810109A71EA92403635CFF043BA95901DF0900ECFF1A76A928FFFFA828FFFF4E
:20777A0001090E61FF76FFFF066F01DFBDC3A71E673EBEC5A92401DFA82458FFF760407664
:20779A003EBA40765BBABDB203E2BD0403E2BD0503E2BD06CFE6010008D0AFE2F40210E79C
:2077BA0092000ED112E3949CAFE2C40017E3D41D0CD000E394C20AE3E4A6AFE29C0340E7F6
:2077DA009B41007710E718000ED003E294020CD003E2940008D0F406941E03E2F401AFE290
:2077FA00BE06AFE2BE05AFE2BE04BE8B0600022904295F565AFF42065F56421E00021FF6DB
:20781A0017564200AB06325602292076022904295F565AFF420656FF421E00021FF61756BE
:20783A0042003256022920765AFF00021FF617564200A9A920765AFF00021FF6175642007D
:20785A002076A85CA971A697013BA98556FFA95DA48556FFA95CA5920FF6A41FA64F026C73
:20787A005CFF2076A696A85C013BA98556FFA95DA48556FFA95CA5920FF6A41FA64F026C13
:20789A005DFFA89220765AFFAB92A4C5A48E07ECFF9CA988859287960E00FEFFAB92A98805
:2078BA00A9A9A60F10ECAA930EECA9A9FF9DA85CBF76FEFF859287960E00FEFF85928796DD
:2078DA000C00F8FFA08A06000000A0E514AD0962A0E51F767E0314AD90E5B4560901156F41
:2078FA004FE803C092E601008CB5050000E7CA00007700E78A000077CFE812F0007700E78E
:20791A005100007700E740000600208F00001F76780336A81F767803208F00FA38A81F768D
:20793A00780336061F7678033A1E1F7678033C2B1F7678033606046FA98AC42B01091F7617
:20795A007803380FFA68060022761F76C0011C1A080069FF787680001A761F76C4011CCC0F
:20797A00FF3F1F76C401A91A00401C961F76C401BF5618E0028FE64969FFA9A8407690BAC0
:20799A000600A928FFFFAA28FFFFAB28FFFFA828FFFFAB0F04ED00D400BE0B6FA927A92831
:2079BA00FFFFA92FA4A9C488A928FFFF0209A98AA6924076BAAA06000077006F1F767E03DD
:2079DA00BDB22AC5A959673E1F767E032EC5A70603ECA192673E1F767E032C0603ECA71E0F
:2079FA00673E407659BABE8B0600008F00C0408F000D2276009A84C485C2019C8052FC64F5
:207A1A001A7669FF06001F767E0328A806001F767E032AA8060006001F767E0325961F7608
:0E7A3A007E03249706000119C356FFFF0600C5
:207A4800230000005DC12276008F800AC41A01001F762A00F4CCFFF1A91A000506961F76E5
:207A68002A0006CCF0FF05501F762A0006961F762A00FCCCE0FF08500796E41AFF01EC1A04
:0C7A8800FF011A7607F6007769FF060080
:207A94001201000000C02A9400002A9400002A9400002A9400002A9400002A9400002A94CD
:207AB40000002A9400002A9400002A9400002A9400002A9400002A940000B98B0000C68BA9
:207AD4000000D38B0000E08B00003E940000F88B0000038C00000E8C0000198C0000248CF6
:207AF40000002F8C00003A8C0000458C0000508C00005B8C0000668C0000718C00007C8C66
:207B14000000878C0000928C0000B38C00003E940000D48C0000F58C0000148D0000358DCB
:207B34000000588D0000798D00009A8D0000BB8D0000DC8D0000FF8D0000208E00003E9462
:207B540000003E940000418E0000628E0000858E0000A88E0000C98E0000EA8E00003E9496
:207B740000003E9400000D8F00002E8F0000518F0000728F0000938F0000B48F00003E94AE
:207B940000003E940000D58F0000F68F00003E9400003E9400003E9400003E9400003E94FC
:207BB40000003E940000199000003A9000005D9000007E9000009F900000C09000003E9420
:207BD40000003E940000E390000004910000259100004691000067910000889100003E9447
:207BF40000003E940000AB910000CE9100003E9400003E940000EF910000109200003E946C
:207C140000003E94000031920000549200007592000096920000B7920000DA920000FD9262
:207C340000001E9300003E9400003E9400003E9400003E9400003E9400003E9400003E94C1
:207C540000003E9400003E9400003E9400003E9400003E9400003E9400003E9400003E9480
:207C740000003E9400003F9300006093000081930000A2930000C39300003E940000E6936F
:207C94000000079400002C012C01000000000F00160014000A003C000A000800060008003C
:0A7CB4000600080033000B000A0070
:207CBE002800000012C191A400003EA500007DA400002AA500006CA4000018A500005BA4D7
:207CDE000000FFA400003CA40000EBA400002BA40000DFA400000DA40000CEA40000FCA360
:187CFE000000BBA40000EBA30000AAA40000D4A30000BAA3000000005F
:00000001FF

View File

@@ -2,7 +2,7 @@
TMS320C2000 Hex Converter v5.2.7
********************************************************************************
INPUT FILE NAME: <C:\Dima\Project\Balsam_167\Bin\UKSSTMS320F28335.out>
INPUT FILE NAME: <D:\project12\Balsam_167\bin\UKSSTMS320F28335.out>
OUTPUT FORMAT: Binary
PHYSICAL MEMORY PARAMETERS
@@ -12,18 +12,19 @@ PHYSICAL MEMORY PARAMETERS
BOOT LOADER PARAMETERS
Table Type: SERIAL PORT (SCI 8 bit Mode)
Entry Point: 0x0000b198
Entry Point: 0x0000b8fa
OUTPUT TRANSLATION MAP
--------------------------------------------------------------------------------
00000000..003fffff Page=0 Memory Width=8 ROM Width=8
--------------------------------------------------------------------------------
OUTPUT FILES: C:\Dima\Project\Balsam_167\Bin\UKSSTMS320F28335.bin [b0..b7]
OUTPUT FILES: D:\project12\Balsam_167\bin\UKSSTMS320F28335.bin [b0..b7]
CONTENTS: 00000000..00006e67 BOOT TABLE
.cinit : dest=0000b35f size=00000283 width=00000002
.text : dest=00008000 size=0000335f width=00000002
CONTENTS: 00000000..00007d15 BOOT TABLE
.cinit : dest=0000ba94 size=0000027f width=00000002
.text : dest=00008000 size=00003a94 width=00000002
ramfuncs : dest=0000c15d size=00000023 width=00000002
.econst : dest=0000c000 size=00000112 width=00000002
.switch : dest=0000c112 size=00000028 width=00000002

167
CAN_ADDRESS_MAP.md Normal file
View File

@@ -0,0 +1,167 @@
# Карта CAN-адресов `Balsam_167_periph` и `BALZAM_167`
## Формирование адреса peripheral
В `Source/Internal/main.c` выполняется:
```c
get_Mode();
InitCan(0, Mode);
```
В `Source/Internal/ecan.c` настроены два extended CAN ID:
```c
long id = 0x80BA0000;
MBOX0.MSGID.all = id + 0x10 + DevNum; /* передача */
MBOX1.MSGID.all = id + DevNum; /* приём */
```
`0x80000000` задаёт extended-формат и не является частью отображаемого
29-битного идентификатора. Фактические адреса на шине:
```text
TX peripheral = 0x00BA0010 + Mode
RX peripheral = 0x00BA0000 + Mode
```
## Адреса всех режимов peripheral
| `Mode` | Назначение | TX peripheral -> BALZAM | RX BALZAM -> peripheral |
|---:|---|---:|---:|
| 1 | `adr_TRN1` | `0x00BA0011` | `0x00BA0001` |
| 2 | `adr_TRN2` | `0x00BA0012` | `0x00BA0002` |
| 3 | `adr_POW1` | `0x00BA0013` | `0x00BA0003` |
| 4 | `adr_POW2` | `0x00BA0014` | `0x00BA0004` |
| 5 | `adr_LOA1`, УМП1 | `0x00BA0015` | `0x00BA0005` |
| 6 | `adr_LOA2`, УМП2 | `0x00BA0016` | `0x00BA0006` |
| 7 | `adr_ENG1` | `0x00BA0017` | `0x00BA0007` |
| 8 | `adr_PULT` | `0x00BA0018` | `0x00BA0008` |
| 9 | `adr_SHKF` | `0x00BA0019` | `0x00BA0009` |
## Приёмные адреса основного контроллера
В `BALZAM_167/Src/balzam_7/CanSetupBalzam7.c` настроено:
| RX mailbox | CAN ID | Запись обработчиком |
|---:|---:|---|
| 0 | `0x00BA0010` | `Unites[1]` |
| 1 | `0x00BA0011` | `Unites[2]` |
| 2 | `0x00BA0012` | `Unites[3]` |
| 3 | `0x00BA0013` | `Unites[4]` |
| 4 | `0x00BA0014` | `Unites[5]` |
| 5 | `0x00BA0015` | `Unites[6]` |
| 6 | `0x00BA0016` | `Unites[7]` |
| 7 | `0x00BA0017` | `Unites[8]` |
| 8 | `0x00BA0018` | `Unites[9]` |
| 9 | `0x00745019` | специальная обработка MPU |
| 10 | `0x00BA001A` | `Unites[11]` |
| 11 | `0x00BA001B` | `Unites[12]` |
Причина такого соответствия — запись в обработчике:
```c
Unites[box + 1][register_address] = received_data;
```
## Имена индексов `Unites`
Текущие определения в `CanSetupBalzam7.h`:
| Индекс | Имя устройства |
|---:|---|
| 1 | `UKSS1_CAN_DEVICE` |
| 2 | `UKSS4_CAN_DEVICE` |
| 3 | `UKSS2_CAN_DEVICE` |
| 4 | `UKSS3_CAN_DEVICE` |
| 5 | `UMP1_CAN_DEVICE` |
| 6 | `UMP2_CAN_DEVICE` |
| 7 | `UKSS8_CAN_DEVICE` |
| 8 | `VPU1_CAN_DEVICE` |
| 9 | `UKSS5_CAN_DEVICE` |
| 10 | `MPU_CAN_DEVICE` |
| 11 | `UKSS6_CAN_DEVICE` |
| 12 | `UKSS7_CAN_DEVICE` |
## Фактическое попадание пакетов
При текущем коде пакет peripheral с `Mode=N` принимается mailbox `N`, после
чего записывается в `Unites[N+1]`.
| Peripheral | TX CAN ID | Фактический `Unites` | Имя по текущим константам |
|---|---:|---:|---|
| `adr_TRN1`, Mode 1 | `0x00BA0011` | `Unites[2]` | `UKSS4_CAN_DEVICE` |
| `adr_TRN2`, Mode 2 | `0x00BA0012` | `Unites[3]` | `UKSS2_CAN_DEVICE` |
| `adr_POW1`, Mode 3 | `0x00BA0013` | `Unites[4]` | `UKSS3_CAN_DEVICE` |
| `adr_POW2`, Mode 4 | `0x00BA0014` | `Unites[5]` | `UMP1_CAN_DEVICE` |
| `adr_LOA1`, Mode 5 | `0x00BA0015` | `Unites[6]` | `UMP2_CAN_DEVICE` |
| `adr_LOA2`, Mode 6 | `0x00BA0016` | `Unites[7]` | `UKSS8_CAN_DEVICE` |
| `adr_ENG1`, Mode 7 | `0x00BA0017` | `Unites[8]` | `VPU1_CAN_DEVICE` |
| `adr_PULT`, Mode 8 | `0x00BA0018` | `Unites[9]` | `UKSS5_CAN_DEVICE` |
| `adr_SHKF`, Mode 9 | `0x00BA0019` | нет приёма | — |
## Связь с ошибкой обрыва фаз
Peripheral передаёт регистры ошибок `modbus[0]`, `modbus[1]` и `modbus[2]`
в CAN-пакете с начальным адресом данных `0`. Признак обрыва/перекоса `Wry`
занимает бит 2:
```text
Wry = 0x0004
```
Основной контроллер выставляет:
```c
mpu_out[125].bit6 =
(Unites[UMP1_CAN_DEVICE][0] & 0x0004) ||
(Unites[UMP1_CAN_DEVICE][1] & 0x0004);
mpu_out[125].bit10 =
(Unites[UMP2_CAN_DEVICE][0] & 0x0004) ||
(Unites[UMP2_CAN_DEVICE][1] & 0x0004);
```
С учётом `UMP1_CAN_DEVICE=5` и `UMP2_CAN_DEVICE=6` получаем:
| Выход MPU | Читаемые данные | CAN ID, заполняющий эти данные |
|---|---|---:|
| `mpu_out[125].bit6` | `Unites[5][0/1]` | `0x00BA0014` |
| `mpu_out[125].bit10` | `Unites[6][0/1]` | `0x00BA0015` |
Но УМП отправляют:
| Плата | Фактический CAN ID | Куда пакет попадает сейчас |
|---|---:|---|
| УМП1, `Mode=5` | `0x00BA0015` | `Unites[6]`, область УМП2 |
| УМП2, `Mode=6` | `0x00BA0016` | `Unites[7]`, область `UKSS8` |
Таким образом, сейчас присутствует смещение адреса на единицу. УМП1 может
влиять на `mpu_out[125].bit10` вместо `bit6`, а УМП2 не попадает ни в один из
двух ожидаемых массивов УМП.
## Обратное направление
Основной контроллер отправляет устройству с индексом `N` через mailbox
`15 + N`, которому назначен CAN ID с номером `N - 1`.
| Получатель | TX CAN ID BALZAM | RX CAN ID peripheral |
|---|---:|---:|
| УМП1 | `0x00BA0004` | `0x00BA0005` |
| УМП2 | `0x00BA0005` | `0x00BA0006` |
В обратном направлении также имеется смещение на единицу.
## Вывод
Перед изменением кода необходимо сверить CAN-трассу и реальные положения
адресных перемычек. После подтверждения адресной схемы возможны два варианта:
1. использовать при настройке CAN peripheral значение `Mode - 1`;
2. перенастроить RX/TX mailbox основного контроллера под текущие значения
`Mode` peripheral.
Комментарии возле mailbox основного проекта частично не совпадают с текущими
константами устройств, поэтому менять адреса только по комментариям нельзя.

Binary file not shown.

67
Doc/Doxyfile Normal file
View File

@@ -0,0 +1,67 @@
# Doxygen configuration for the Balsam 167 peripheral controller firmware.
# Run from this directory with build.bat or: doxygen Doxyfile
PROJECT_NAME = "Balsam 167 Peripheral"
PROJECT_NUMBER = "1.0"
PROJECT_BRIEF = "TMS320F28335 peripheral controller firmware"
OUTPUT_DIRECTORY = build/api
OUTPUT_LANGUAGE = Russian
INPUT_ENCODING = UTF-8
INPUT_FILE_ENCODING = *.c=UTF-8 \
*.h=UTF-8
TAB_SIZE = 4
INPUT = mainpage.md \
api.dox \
files.dox \
README_CCS12.md \
PHASE_BREAK_ERROR_FLOW.md \
PHASE_COMPARISON_BALSAM_165_167.md \
PHASE_VOLTAGE_CALCULATION.md \
PHASE_VOLTAGE_WEAK_POINTS.md \
../Source/Internal
FILE_PATTERNS = *.c *.h *.md *.dox
RECURSIVE = YES
USE_MDFILE_AS_MAINPAGE = mainpage.md
OPTIMIZE_OUTPUT_FOR_C = YES
JAVADOC_AUTOBRIEF = YES
MARKDOWN_SUPPORT = YES
AUTOLINK_SUPPORT = YES
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
EXTRACT_PRIVATE = YES
EXTRACT_LOCAL_CLASSES = YES
TYPEDEF_HIDES_STRUCT = YES
SORT_MEMBER_DOCS = NO
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
SKIP_FUNCTION_MACROS = YES
PREDEFINED = interrupt= \
__interrupt= \
EALLOW= \
EDIS=
ALIASES = precondition="\pre"
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = NO
WARN_NO_PARAMDOC = NO
WARN_LOGFILE = build/doxygen-warnings.log
GENERATE_HTML = YES
HTML_OUTPUT = html
GENERATE_TREEVIEW = YES
FULL_SIDEBAR = NO
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
ALPHABETICAL_INDEX = YES
SEARCHENGINE = YES
GENERATE_LATEX = NO
HAVE_DOT = NO

View File

@@ -0,0 +1,337 @@
@page phase_break_error_flow Детектирование и передача ошибки обрыва фаз
# Детектирование и передача ошибки обрыва фаз
## 1. Назначение
Документ описывает полную связь от входов АЦП платы УМП до выставления
признаков обрыва фаз в `modbus_table_mpu_out[125]` основного контроллера
`BALZAM_167`.
В текущей реализации обрыв определяется как сильный перекос действующих
значений фаз. Отдельных независимых флагов для физических фаз A, B и C нет.
Передаётся общий флаг `Wry` с маской `0x0004`.
## 2. Общая цепочка сигнала
```text
Фазные напряжения
|
v
АЦП peripheral-платы
CONV02 -> channel 0 -> измеряемая фаза A
CONV03 -> channel 1 -> измеряемая фаза C
|
v
Current_count(0), Current_count(1)
|
+--> RMS A = lev_count[0]
+--> RMS C = lev_count[1]
+--> RMS B = lev_count[4], расчёт B = -(A + C)
|
v
Выбор Max = max(RMS A, RMS B, RMS C)
|
v
(Max - RMS проверяемой фазы) / Max > 0.30
AND Max > Curr_Edge
|
v
Счётчик выдержки er_anal()
|
v
error.bit.Wry = 1 (бит 2, маска 0x0004)
|
v
sens_error[0] / sens_error[1]
|
v
modbus[0] / modbus[1]
|
v
Быстрый CAN-цикл peripheral-платы
|
v
Unites[UMP1_CAN_DEVICE][0/1]
или Unites[UMP2_CAN_DEVICE][0/1]
|
v
BALZAM_167, update_abnormal.c
|
+--> mpu_out[125].bit6 — УМП1
+--> mpu_out[125].bit10 — УМП2
```
## 3. Связь входов АЦП с фазами
Для режима УМП (`Desk == dsk_LOAD`) преобразования настроены в
`Source/Internal/ADC.c`.
| АЦП | Физический вход | Внутренний канал | Назначение |
|---|---:|---:|---|
| `CONV02` | `ADCINA5` | `0` | измеряемое напряжение фазы A |
| `CONV03` | `ADCINA4` | `1` | измеряемое напряжение фазы C |
| `CONV04` | `ADCINA7` | `2` | ток первого канала |
| `CONV05` | `ADCINA2` | `3` | ток второго канала |
В обработчике АЦП результаты `ADCRESULT2...ADCRESULT5` записываются в
`adc_table_lem[0...3]`, после чего для каждого канала вызывается
`Current_count(i)`.
## 4. Расчёт действующих значений
Из отсчёта АЦП вычитается сохранённый нулевой уровень и применяется
калибровочный коэффициент:
```c
Current = (Numb - Zero_lev[chan]) * powK[chan];
```
Действующее значение измеряемой фазы рассчитывается через экспоненциальное
усреднение квадрата:
```c
lev_quadr[chan] +=
((Current * Current) - lev_quadr[chan]) / (1.0 * ADC_FREQ);
lev_count[chan] = sqrt(lev_quadr[chan]);
```
Третья фаза непосредственно не измеряется. Она восстанавливается из условия
нулевой суммы фаз:
```text
A + B + C = 0
B = -(A + C)
```
В коде:
```c
Numb = -Current - aCurrent;
lev_quadr[thrd] +=
(Numb * Numb - lev_quadr[thrd]) / (1.0 * ADC_FREQ);
lev_count[thrd] = sqrt(lev_quadr[thrd]);
```
Диагностические значения публикуются в следующих регистрах:
| Регистр peripheral | Значение |
|---:|---|
| `0x68` | RMS фазы A |
| `0x69` | RMS фазы C |
| `0x6A` | расчётный RMS фазы B |
| `0x6B` | RMS первого токового канала |
| `0x6C` | RMS второго токового канала |
| `0x6D` | расчётный RMS третьего тока |
## 5. Условие выставления `Wry`
Для каждой пары выбирается максимальный уровень:
```c
Max = max(lev_count[chan], lev_count[pair], lev_count[thrd]);
```
Ошибка набирается при выполнении обоих условий:
```text
(Max - PhaseRms) / Max > 0.30
Max > Curr_Edge
```
Для УМП устанавливается:
```c
Curr_Edge = 300;
```
Следовательно, флаг формируется, когда:
1. максимальная из трёх фаз больше `300`;
2. проверяемая фаза ниже максимальной более чем на 30%;
3. счётчик `er_anal()` достиг выдержки.
Пример:
```text
RMS A = 400
RMS B = 390
RMS C = 100
Max = 400
(400 - 100) / 400 = 0.75
0.75 > 0.30 -> условие обрыва/перекоса фазы C активно
```
Если все три уровня одновременно ниже `Curr_Edge`, `Wry` не выставляется.
Полное пропадание напряжения должно определяться диагностикой низкого уровня
`Out`, а не фазовым перекосом `Wry`.
## 6. Выдержка времени
Частота обработки:
```c
#define ADC_FREQ 3750
```
Порог счётчика:
```c
time_3sec = 3 * ADC_FREQ; /* 11250 */
```
Функция `er_anal()` увеличивает счётчик на каждом ошибочном отсчёте и уменьшает
его на каждом нормальном отсчёте:
```c
if (term) {
if (*count >= edge)
return 1;
(*count)++;
return 0;
}
if (*count == 0)
return 0;
(*count)--;
return 0;
```
Для измеряемых фаз A и C номинальная выдержка составляет около 3 секунд.
Расчётная фаза B проверяется при обработке обоих измеряемых каналов, поэтому
её общий счётчик увеличивается дважды за цикл АЦП. Фактическая выдержка для B
может составлять около 1,5 секунды.
После запуска УМП диагностика блокируется на время `WAKE`:
```c
WAKE_TIME = 10L * ADC_FREQ;
```
То есть первые 10 секунд после запуска `Wry` не формируется.
## 7. Формирование регистра ошибки peripheral-платы
Структура регистра ошибки определена в `Source/Internal/Include/measure.h`:
| Бит | Маска | Поле | Назначение |
|---:|---:|---|---|
| 0 | `0x0001` | `Tear` | крайнее значение АЦП/обрыв датчика |
| 2 | `0x0004` | `Wry` | перекос или предполагаемый обрыв фазы |
| 3 | `0x0008` | `Out` | низкий общий уровень |
| 4 | `0x0010` | `Over` | превышение тока |
| 5 | `0x0020` | `Hyper` | превышение напряжения |
| 8 | `0x0100` | `Stop` | требование аварийного останова |
| 9 | `0x0200` | `Ready` | готовность канала |
| 14 | `0x4000` | `Ignor` | запрет локального останова |
| 15 | `0x8000` | `Bypas` | полное исключение канала |
После достижения выдержки выполняется:
```c
error.bit.Wry = 1;
if (!ignor)
error.bit.Stop = 1;
```
Поведение управляющих признаков:
| Состояние | `Wry` | `Stop` | Передача по CAN |
|---|---:|---:|---:|
| обычный канал | 1 | 1 | да |
| `Ignor = 1` | 1 | 0 | да |
| `Bypas = 1` | 0 | 0 | передаётся регистр без ошибки |
| `WAKE != 0` | 0 | 0 | передаётся регистр без ошибки |
Для УМП признаки напряжений находятся в регистрах ошибок:
| Регистр | Содержит `Wry` при проблеме |
|---:|---|
| `modbus[0]` | измеряемая фаза A или расчётная фаза B |
| `modbus[1]` | измеряемая фаза C или расчётная фаза B |
В основном контроллере регистры `0` и `1` объединяются логическим ИЛИ, поэтому
для индикации достаточно наличия маски `0x0004` в любом из них.
## 8. Передача по CAN
`Init_packMask()` включает регистры ошибок УМП `0...3` в быстрый CAN-цикл.
Главный цикл peripheral-платы вызывает:
```c
CAN_send(0, modbus, address);
```
Один CAN-пакет содержит начальный адрес и три 16-битных регистра. Основной
контроллер принимает пакет и записывает данные в массив:
```text
Unites[номер устройства][адрес регистра]
```
Соответствие устройств:
| Устройство | CAN-индекс основного контроллера | Регистры флага |
|---|---:|---:|
| УМП1 | `UMP1_CAN_DEVICE = 5` | `Unites[5][0]`, `Unites[5][1]` |
| УМП2 | `UMP2_CAN_DEVICE = 6` | `Unites[6][0]`, `Unites[6][1]` |
## 9. Выставление `mpu_out[125]`
Основной контроллер выполняет проверку в
`BALZAM_167/Src/balzam_7/update_abnormal.c`.
### УМП1
```c
modbus_table_mpu_out[125].bit.bit6 =
(Unites[UMP1_CAN_DEVICE][0] & 0x4) ||
(Unites[UMP1_CAN_DEVICE][1] & 0x4)
? 1 : 0;
```
### УМП2
```c
modbus_table_mpu_out[125].bit.bit10 =
(Unites[UMP2_CAN_DEVICE][0] & 0x4) ||
(Unites[UMP2_CAN_DEVICE][1] & 0x4)
? 1 : 0;
```
Оба признака разрешены только при следующем условии:
```c
f.FittingScheme == 1
```
Если выбрана другая схема, основной контроллер принудительно записывает ноль
в `mpu_out[125].bit6` и `mpu_out[125].bit10` независимо от данных УМП.
## 10. Итоговая таблица связей
| Физическое событие | Peripheral-регистр | Передаваемая маска | Приёмник | Выход MPU |
|---|---:|---:|---|---|
| перекос/обрыв A на УМП1 | `modbus[0]` | `0x0004` | `Unites[5][0]` | `mpu_out[125].bit6` |
| расчётный перекос B на УМП1 | `modbus[0]` или `[1]` | `0x0004` | `Unites[5][0/1]` | `mpu_out[125].bit6` |
| перекос/обрыв C на УМП1 | `modbus[1]` | `0x0004` | `Unites[5][1]` | `mpu_out[125].bit6` |
| перекос/обрыв A на УМП2 | `modbus[0]` | `0x0004` | `Unites[6][0]` | `mpu_out[125].bit10` |
| расчётный перекос B на УМП2 | `modbus[0]` или `[1]` | `0x0004` | `Unites[6][0/1]` | `mpu_out[125].bit10` |
| перекос/обрыв C на УМП2 | `modbus[1]` | `0x0004` | `Unites[6][1]` | `mpu_out[125].bit10` |
## 11. Ограничения алгоритма
1. `Wry` означает как обрыв, так и сильный перекос более 30%; эти события не
различаются.
2. Фаза B не измеряется непосредственно. Если при физическом обрыве B фазы A
и C остаются нормальными, расчётная B также может выглядеть нормальной и
ошибка не будет обнаружена.
3. Одновременное исчезновение всех фаз не создаёт `Wry`, потому что не
выполняется условие `Max > 300`.
4. Из-за двойной проверки расчётной фазы B её выдержка короче выдержки A и C.
5. Выходные биты `mpu_out[125].bit6` и `bit10` не показывают конкретную фазу,
а только общий факт фазового перекоса соответствующего УМП.

View File

@@ -0,0 +1,600 @@
@page phase_comparison_balsam Сравнение фазовой части Balsam 165 и Balsam 167
# Сравнение фазовой части Balsam 165 и Balsam 167
## Область сравнения
Сравнивались:
- захват фазных сигналов АЦП;
- удаление нулевого смещения;
- масштабирование в физические единицы;
- расчёт общего действующего значения;
- расчёт уровней отдельных фаз A, B и C;
- диагностика перекоса и обрыва фаз;
- диагностические биты и регистры Modbus;
- пороги напряжения и выдержки времени.
Исходные проекты:
- `K:/git_project/Balsam_165_periph`;
- `K:/git_project/Balsam_167_periph`.
Основные файлы:
| Проект | Файл |
|---|---|
| Balsam 165 | `K:/git_project/Balsam_165_periph/Source/Internal/measure.c` |
| Balsam 165 | `K:/git_project/Balsam_165_periph/Source/Internal/ADC.c` |
| Balsam 165 | `K:/git_project/Balsam_165_periph/Source/Internal/Include/measure.h` |
| Balsam 165 | `K:/git_project/Balsam_165_periph/Doc/Balsam 165 data stru.xls` |
| Balsam 167 | `Source/Internal/measure.c` |
| Balsam 167 | `Source/Internal/ADC.c` |
| Balsam 167 | `Source/Internal/Include/measure.h` |
| Balsam 167 | `Doc/Balsam 167 data stru.xls` |
## Вывод
Balsam 167 использует более правильный способ расчёта действующих значений
отдельных фаз: усреднение квадрата с последующим извлечением корня. Balsam 165
сглаживает модуль сигнала, что не является настоящим RMS.
При этом в Balsam 167 появились две ошибки индексации:
1. Парный канал записывается по абсолютному индексу, но читается по
относительному.
2. Бит `Ignor` устанавливается у абсолютного номера датчика, но проверяется у
относительного `chan`.
Для УМП, где `pow_addr == 0`, первая ошибка не проявляется. Для силового блока
она может приводить к дублированию фазных уровней и ложному `Wry + Stop`.
Рекомендуемый вариант: сохранить RMS-алгоритм Balsam 167, исправить индексацию
и выполнять диагностику трёх фаз один раз после обработки всей пары каналов.
## Сводная таблица
| Параметр | Balsam 165 | Balsam 167 | Оценка |
|---|---|---|---|
| Частота АЦП | 5000 Гц | 3750 Гц | Изменена |
| Выбор фазных входов АЦП | `CONV02…CONV05` | `CONV02…CONV05` | Одинаковый |
| Формула `im_calc()` | Одинаковая | Одинаковая | Без изменений |
| Фаза B | `-A-C`, для `dsk_COMM` эквивалентная разность | `-A-C` после смены знака A | По модулю эквивалентно |
| Уровень отдельной фазы | EMA от `abs(x)` | `sqrt(EMA(x²))` | 167 корректнее |
| Частота фильтра результата | 5 Гц | 3 Гц | 167 медленнее |
| Тип `lev_count[]` | `float` | `int` | В 167 раньше теряется дробная часть |
| Порог перекоса | 20% | 30% | 167 менее чувствителен |
| Выдержка измеряемой фазы | около 1,5 с | около 3 с | 167 медленнее |
| Выдержка восстановленной фазы | около 0,75 с | около 1,5 с | В обеих версиях вдвое короче |
| `Curr_Edge`, УМП | 100 | 300 | Порог существенно повышен |
| `Curr_Edge`, силовой блок | 40 | 200 | Порог существенно повышен |
| Низкое `Utr` | без выдержки | счётчик около 3 с | Улучшено, но блокируется `Ignor` |
| Верхнее `Utr` | без выдержки | без выдержки | Без улучшения |
| Калибровка входов | жёсткий `curK[]` | Modbus/EEPROM `Caliber[]` | 167 гибче |
| Пары каналов силового блока | корректные относительные индексы | несогласованные индексы | Регрессия 167 |
| Обработка `Ignor` | правильный абсолютный датчик | проверяется `chan` | Регрессия 167 |
| Отдельные биты фаз A/B/C | нет | нет | Общий недостаток |
| Контроль пределов АЦП U/I | нет | нет | Общий недостаток |
## 1. Захват сигналов АЦП
Для УМП обе версии используют одинаковые входы:
```c
CONV02 = 0x5; // напряжение 1
CONV03 = 0x4; // напряжение 2
CONV04 = 0x7; // ток 1
CONV05 = 0x2; // ток 2
```
Данные читаются из результатов `ADCRESULT2…ADCRESULT5`, после чего вызывается
`Current_count(i)`.
Различается частота обработки:
```text
Balsam 165: ADC_FREQ = 5000 Гц
Balsam 167: ADC_FREQ = 3750 Гц
```
Назначение входов УМП:
| `chan` | Сигнал |
|---:|---|
| 0 | `Utr A` |
| 1 | `Utr C` |
| 2 | `Itr A` |
| 3 | `Itr C` |
Фаза B физически не измеряется.
## 2. Нулевое смещение
В обеих версиях используется медленное усреднение:
```text
zero[n] = zero[n-1] + (ADC-zero[n-1]) / (5 * ADC_FREQ)
```
### Balsam 165
Ноль записывается постоянно:
```c
Zero_lev[chan] = filterbat(&out_filter[chan], zer_count[chan]);
```
Для подстройки используются те же `out_filter[]`, которые участвуют в другой
обработке сигналов.
### Balsam 167
Добавлены отдельные фильтры `zer_filter[]`:
```c
Zer = filterbat(&zer_filter[chan], zer_count[chan]);
if (WAKE < (WAKE_TIME / 2)) Zero_lev[chan] = Zer;
```
Разделение фильтров является улучшением. Однако после того как `WAKE` достиг
нуля, условие остаётся истинным. Подстройка нуля фактически продолжается во
время всей работы.
Если подстройка нужна только при запуске, должно проверяться также `WAKE > 0`.
## 3. Масштабирование
### Balsam 165
Используются жёстко заданные коэффициенты `curK[]`:
| Устройство | Напряжение | Ток |
|---|---:|---:|
| УМП 1/2 | `0.386` | `4.82` |
| Силовой блок | `0.402` | — |
Коэффициенты одинаковы для однотипных каналов и не берутся из EEPROM.
### Balsam 167
Коэффициенты вычисляются из `Caliber[0…3]`:
```text
напряжение: powK = Caliber / 10000
ток: powK = Caliber / 1000
```
Преимущества:
- индивидуальная калибровка каждого входа;
- отдельные значения для экземпляров устройств;
- сохранение и загрузка через EEPROM.
Значения тока заметно отличаются от Balsam 165. Например, для УМП 1 в
Balsam 167 используются `3.505` и `3.380` вместо `4.82`. Это может быть связано
с изменением аппаратной части или новой калибровкой и требует стендовой сверки.
## 4. Общий уровень трёхфазного сигнала
Функция `im_calc()` в проектах совпадает:
```text
isA = -1.5 * (a + b)
isB = cos(π/6) * (a - b)
Amplitude = 2/3 * sqrt(isA² + isB²)
Level = Amplitude / sqrt(2)
```
Эквивалентная формула амплитуды:
```text
Amplitude = 2/sqrt(3) * sqrt(a² + a*b + b²)
```
### Фильтрация общего уровня
Balsam 165 сначала делит амплитуду на `sqrt(2)`, затем фильтрует `Level`
фильтром 5 Гц. Для тока и всех каналов `dsk_COMM` используется дополнительная
статическая переменная `ffLev`.
`ffLev` одна на все вызовы функции. На силовом блоке результаты разных пар
могут влиять друг на друга.
Balsam 167 фильтрует амплитуду отдельным фильтром текущего датчика:
```c
Amplitude = filterbat(&out_filter[sens], im_calc(Current, aCurrent));
Level = Amplitude / RADIX2;
```
Это устраняет общий `ffLev` и разделяет состояния фильтров разных пар.
### Зона нечувствительности
Balsam 165:
```text
Level < Curr_Edge -> Level = 0
```
Для УМП порог равен 100 единицам RMS.
Balsam 167:
```text
напряжение: Amplitude < 20 -> 0
ток: Amplitude < 75 -> 0
```
В пересчёте на RMS это примерно 14,1 для напряжения и 53,0 для тока. Поэтому
Balsam 167 публикует слабые сигналы, которые Balsam 165 обнулял.
## 5. Уровни отдельных фаз
### Balsam 165: среднее модуля
```c
lev_count[chan] +=
(fabs(Current) - lev_count[chan]) / (ADC_FREQ / 5);
```
Для синусоиды установившееся значение соответствует среднему модулю:
```text
MeanAbs = 2/π * Amplitude ≈ 0.6366 * Amplitude
```
### Balsam 167: настоящий RMS
```c
lev_quadr[chan] +=
(Current * Current - lev_quadr[chan]) / ADC_FREQ;
lev_count[chan] = sqrt(lev_quadr[chan]);
```
Для синусоиды:
```text
RMS = 1/sqrt(2) * Amplitude ≈ 0.7071 * Amplitude
```
При одинаковом входном масштабе Balsam 167 показывает примерно в 1,1107 раза,
или на 11,1%, больше Balsam 165.
Это изменение влияет на абсолютные фазные уровни, но почти не влияет на
отношение минимальной фазы к максимальной, используемое для `Wry`.
### Скорость сглаживания
Balsam 165 использует коэффициент `5/ADC_FREQ`, что соответствует постоянной
времени около 0,2 с.
Balsam 167 использует коэффициент `1/ADC_FREQ`, что соответствует постоянной
времени около 1 с. Фазные уровни Balsam 167 изменяются медленнее и стабильнее.
## 6. Восстановление фазы B
Для УМП в обеих версиях:
```text
B = -A - C
```
Для силового блока в Balsam 165 используется:
```text
third = current_channel - first_channel
```
В Balsam 167 сначала меняется знак сохранённого первого канала, затем
применяется общая формула `-Current-aCurrent`. Результат отличается знаком, но
для RMS знак не имеет значения.
Основной недостаток общий: фаза B не измеряется. Неисправность B определяется
только через математическую связь с A и C.
## 7. Карта фазных регистров
В Balsam 165 код записывает:
```text
0x68 + n*3 + 0 = текущий нечётный канал, для УМП фаза C
0x68 + n*3 + 1 = парный канал, для УМП фаза A
0x68 + n*3 + 2 = восстановленная фаза B
```
То есть фактический порядок для УМП:
```text
C, A, B
```
В Balsam 167 первые две записи переставлены:
```text
0x68 + n*3 + 0 = парный канал A
0x68 + n*3 + 1 = текущий канал C
0x68 + n*3 + 2 = восстановленная фаза B
```
Порядок соответствует карте Balsam 167:
| Регистр | УМП |
|---:|---|
| `0x68` | `Utr A` |
| `0x69` | `Utr C` |
| `0x6A` | `Utr B` |
| `0x6B` | `Itr A` |
| `0x6C` | `Itr C` |
| `0x6D` | `Itr B` |
В карте Balsam 165 эти регистры не описаны как фазные. Адрес `0x68` обозначен
как яркость ламп, хотя исходный код записывает туда фазный уровень. Это риск
несовместимости прошивки с внешним ПО и документацией.
## 8. Диагностика `Wry`
В обеих версиях используется отношение:
```text
Max = max(phase_A, phase_C, phase_B)
deviation = (Max - phase) / Max
```
### Balsam 165
```text
deviation > 20%
Max > Curr_Edge
выдержка измеряемой фазы ≈ 1,5 с
```
`Curr_Edge`:
| Режим | Значение |
|---|---:|
| УМП | 100 |
| Силовой блок | 40 |
### Balsam 167
```text
deviation > 30%
Max > Curr_Edge
выдержка измеряемой фазы ≈ 3 с
```
`Curr_Edge`:
| Режим | Значение |
|---|---:|
| УМП | 300 |
| Силовой блок | 200 |
Balsam 167 значительно менее чувствителен к перекосу и реагирует медленнее.
### Ошибка выдержки восстановленной фазы
Один счётчик `err_count[thrd]` вызывается при обработке обоих каналов пары.
Поэтому он увеличивается дважды за цикл АЦП.
Фактическая выдержка постоянного дефекта фазы B:
| Проект | Заданная | Фактическая для B |
|---|---:|---:|
| Balsam 165 | 1,5 с | около 0,75 с |
| Balsam 167 | 3 с | около 1,5 с |
Проблема присутствует в обеих версиях.
### Деление на ноль
Обе версии сначала вычисляют отношение с делением на `Max`, а затем проверяют
нижний порог:
```c
((Max - phase) / Max > limit) && (Max > Curr_Edge)
```
При `Max == 0` выполняется `0/0`. Безопасный порядок:
```c
(Max > Curr_Edge) && (((Max - phase) / Max) > limit)
```
## 9. Различия обработки `Ignor`
### Balsam 165
Используется правильный абсолютный номер датчика:
```c
sens = tpl_cans + chan;
ignor = sens_error[sens].bit.Ignor;
```
Ошибки `Wry`, `Out` и `Hyper` продолжают вычисляться и передаваться, но
`Stop` не устанавливается для игнорируемого канала.
### Balsam 167
Проверяется относительный индекс:
```c
sens = pow_addr + chan;
if (WAKE || sens_error[chan].bit.Ignor) goto fin;
```
Последствия различаются по типу устройства.
#### УМП
Для УМП `pow_addr == 0`, поэтому индекс формально совпадает. Каналам напряжения
`0x00` и `0x01` по умолчанию устанавливается `Ignor`. В результате Balsam 167
полностью пропускает для напряжения:
- `Wry`;
- `Out` при `Utr < 300 В`;
- `Hyper` при `Utr > 420 В`;
- `Stop`.
В Balsam 165 эти информационные биты вычислялись, но `Stop` блокировался.
#### Силовой блок
На силовом блоке `pow_addr != 0`. `Ignor` устанавливается в
`sens_error[pow_addr+chan]`, но проверяется `sens_error[chan]`.
Из-за этого игнорирование может не сработать, а `Wry + Stop` сформироваться для
канала, который должен быть исключён из диагностики.
## 10. Регрессия `sens_pair` в Balsam 167
В Balsam 165 пары хранятся относительно `chan`:
```c
sens_pair[0] = 1;
sens_pair[1] = 0;
sens_pair[2] = 3;
sens_pair[3] = 2;
pair = sens_pair[chan];
```
В Balsam 167 пары записываются по абсолютному индексу:
```c
sens_pair[pow_addr+i] = pow_addr+(i^1);
```
Но чтение осталось старым:
```c
pair = sens_pair[chan];
```
Для силового блока элементы `sens_pair[0…3]` после общей инициализации равны
`0, 1, 2, 3`. Следовательно, `pair` указывает на текущий канал, а не на
соседний.
Последствия:
- один фазный уровень может записываться дважды;
- максимальная фаза выбирается из неполного набора;
- `Wry` может быть пропущен или сформирован ошибочно;
- карта `0x68…0x6D` для силового блока не соответствует ожидаемой.
Вероятное исправление:
```c
pair = sens_pair[sens] - pow_addr;
```
Окончательный вариант следует подтвердить стендовым тестом и ожидаемым
порядком фаз в регистрах.
## 11. Пороговые уровни УМП
Заводские уставки в проектах совпадают:
| Сигнал | Нижний порог | Верхний порог |
|---|---:|---:|
| `Utr` | 300 В | 420 В |
| `Itr` | 800 А, предупреждение | 900 А, авария |
Различается обработка нижнего напряжения:
| Проект | Реакция `Utr < 300 В` |
|---|---|
| Balsam 165 | `Out` сразу; `Stop` блокируется при штатном `Ignor` |
| Balsam 167 | счётчик около 3 с, но при штатном `Ignor` проверка не выполняется |
Верхний порог `Utr > 420 В` в обеих версиях не имеет отдельной выдержки и
гистерезиса.
## 12. Диагностические биты
Расположение основных битов не изменилось:
| Бит | Маска | Имя | Назначение |
|---:|---:|---|---|
| 0 | `0x0001` | `Tear` | обрыв датчика/предельное значение АЦП |
| 2 | `0x0004` | `Wry` | перекос фаз |
| 3 | `0x0008` | `Out` | ниже нижнего порога |
| 4 | `0x0010` | `Over` | выше предупредительного порога |
| 5 | `0x0020` | `Hyper` | выше аварийного порога |
| 8 | `0x0100` | `Stop` | авария |
| 9 | `0x0200` | `Ready` | готовность |
| 14 | `0x4000` | `Ignor` | игнорировать аварию |
| 15 | `0x8000` | `Bypas` | отключить канал |
В обеих версиях `Current_count()` не формирует `Tear` для фазных входов U/I.
Поэтому неисправность измерительного тракта нельзя надёжно отличить от
пропадания напряжения или тока.
## 13. Что следует перенести из Balsam 165
В Balsam 167 полезно вернуть следующие свойства реализации 165:
1. Согласованную систему индексов `sens_pair`.
2. Проверку `Ignor` через абсолютный индекс `sens_error[sens]`.
3. Использование `float` для внутренних фазных уровней до момента публикации.
Не следует возвращать:
- усреднение `fabs()` вместо RMS;
- общий статический фильтр `ffLev`;
- немедленное срабатывание нижнего напряжения;
- жёсткие коэффициенты `curK[]`.
## 14. Рекомендуемая итоговая реализация
1. Считать все абсолютные номера датчиков один раз:
```c
sens = pow_addr + chan;
```
2. Хранить `sens_pair[]` либо полностью в относительных, либо полностью в
абсолютных индексах. Не смешивать системы адресации.
3. Сохранить RMS Balsam 167, но хранить `lev_count[]` как `float`.
4. После поступления обоих отсчётов пары вычислять A, C и B в одном месте.
5. Один раз за цикл обновлять три RMS и три диагностических счётчика.
6. Проверять `Max > Curr_Edge` до деления.
7. Проверять `Ignor` через `sens_error[sens]`.
8. Разделить понятия:
- информационная ошибка присутствует;
- ошибка участвует в формировании `Stop`.
9. Добавить отдельную маску фаз A/B/C.
10. Добавить `Tear` по сырому значению АЦП.
11. Добавить выдержку и гистерезис для 300/420 В.
12. Явно определить, должна ли подстройка нуля работать после запуска.
## 15. Минимальные сравнительные тесты
| Тест | Что проверить |
|---|---|
| Одинаковая синусоида на обеих версиях | Разницу MeanAbs и RMS около 11,1% |
| Номинальные A и C | Правильный порядок A/C/B в `0x68…0x6D` |
| Обрыв A | RMS A, `Wry`, выдержку |
| Обрыв C | RMS C, `Wry`, выдержку |
| Нарушение вычисленной B | Отсутствие двойной скорости счётчика |
| Перекос 20%, 25%, 30%, 35% | Различия порогов 165 и 167 |
| `Max == 0` | Отсутствие деления на ноль |
| `Utr = 299 В` | `Out` и выдержку |
| `Utr = 421 В` | `Hyper` и отсутствие дребезга |
| `Ignor = 1` | Ошибка видна, но не создаёт `Stop`, если это требуемая семантика |
| Силовой блок, две пары | Отсутствие дублирования фазных RMS |
| АЦП около 0 и 4095 | Формирование `Tear` |
## Заключение
Фазовый расчёт Balsam 167 является хорошей основой благодаря настоящему RMS,
раздельным фильтрам и калибровке из регистров. Главный риск версии 167 находится
не в математике RMS, а в адресации состояния каналов.
До исправления `sens_pair` и `Ignor` фазные регистры и `Wry` силового блока
нельзя считать надёжными. Для УМП необходимо отдельно решить, должны ли
напряжения с установленным `Ignor` продолжать формировать информационные
`Wry`, `Out` и `Hyper`, как это происходило в Balsam 165.

View File

@@ -0,0 +1,344 @@
@page phase_voltage_calculation Расчёт входных фаз, диагностика обрыва и уровни напряжения
# Расчёт входных фаз, диагностика обрыва и уровни напряжения
Документ составлен по исходникам прошивки Balsam 167 и карте регистров
`Doc/Balsam 167 data stru.xls`.
## Где находится код
Основная обработка входных напряжений и токов находится в
`Source/Internal/measure.c`:
- `im_calc()` — восстановление амплитуды трёхфазного сигнала, строки 82–89;
- `Current_count()` — смещение АЦП, масштабирование, RMS фаз, общий уровень и
диагностика перекоса/пропадания, строки 444–614;
- `Power_count()` — контроль отдельных источников питания шкафа ВЭП,
строки 769–841;
- `er_anal()` — выдержка времени для диагностических признаков,
строки 423–432.
Частота расчёта задаётся как `ADC_FREQ = 3750 Гц` в
`Source/Internal/Include/measure.h:73`. Выбор каналов АЦП выполняется в
`Source/Internal/ADC.c`, а пороги по умолчанию — в
`Source/Internal/message.c:24–135`.
## 1. Получение входных отсчётов
Для плат с измерением напряжения/тока обрабатываются четыре входа:
| `chan` | Назначение для УМП (`dsk_LOAD`) | Сырой регистр |
|---:|---|---:|
| 0 | напряжение фазы A (`Utr A`) | `0x64` |
| 1 | напряжение фазы C (`Utr C`) | `0x65` |
| 2 | ток фазы A (`Itr A`) | `0x66` |
| 3 | ток фазы C (`Itr C`) | `0x67` |
В `ADC.c:228–233` результат АЦП читается так:
```c
adc_table_lem[i] = *((&AdcRegs.ADCRESULT0)+i+2) >> 4;
Current_count(i);
```
То есть используются 12 старших значащих бит результата АЦП.
### Удаление нулевого смещения и перевод в физические единицы
В `Current_count()` выполняется:
```text
N = adc_table_lem[chan]
X = (N - Zero_lev[chan]) * powK[chan]
```
`Zero_lev[0..3]` хранится в регистрах `0x70…0x73`; значение по умолчанию —
`0x800 = 2048`. Ноль дополнительно подстраивается медленным фильтром:
```text
zero[n] = zero[n-1] + (N - zero[n-1]) / (5 * 3750)
```
Коэффициент `powK` формируется из калибровки `Caliber[0..3]`:
```text
для напряжения: powK = Caliber / 10000
для тока: powK = Caliber / 1000
```
Калибровочные значения находятся в Modbus-регистрах `0x74…0x77`, могут быть
загружены из EEPROM и поэтому не обязаны совпадать со значениями по умолчанию.
Для Balsam 167 значения по умолчанию такие:
| Устройство | Каналы | `Caliber` | `powK` |
|---|---|---|---|
| Силовой 1, адрес 3 | `UA1, UB1, UA2, UB2` | `4936, 4877, 4972, 4857` | `0.4936, 0.4877, 0.4972, 0.4857` |
| Силовой 2, адрес 4 | `UA1, UB1, UA2, UB2` | `4876, 5005, 4876, 4847` | `0.4876, 0.5005, 0.4876, 0.4847` |
| УМП 1, адрес 5 | `Utr A, Utr C, Itr A, Itr C` | `3820, 3790, 3505, 3380` | `0.3820, 0.3790, 3.505, 3.380` |
| УМП 2, адрес 6 | `Utr A, Utr C, Itr A, Itr C` | `3835, 3785, 3522, 3332` | `0.3835, 0.3785, 3.522, 3.332` |
Источник значений: `Source/Internal/Include/caliber.h`, секция
`#if BALSAM == 167`.
## 2. Расчёт амплитуды и действующего значения
Функция `im_calc(a, b)` использует два измеренных фазных сигнала:
```text
isA = -1.5 * (a + b)
isB = cos(π/6) * (a - b)
Amplitude = 2/3 * sqrt(isA² + isB²)
```
Эквивалентная свёрнутая формула:
```text
Amplitude = 2/sqrt(3) * sqrt(a² + a*b + b²)
```
После цифрового фильтра Баттерворта 3 Гц получается амплитуда сигнала.
Действующее значение вычисляется как:
```text
Level = Amplitude / sqrt(2)
```
Для каналов напряжения амплитуда принудительно обнуляется при
`Amplitude < 20`; для каналов тока — при `Amplitude < 75`.
Результат пары записывается в два регистра данных:
```text
sens_data[нечётный канал] = Amplitude
sens_data[чётный канал] = Level
```
Для УМП это даёт:
| Регистр | Значение |
|---:|---|
| `0x18` | действующее `Utr` |
| `0x19` | амплитудное `Utr` |
| `0x1A` | действующее `Itr` |
| `0x1B` | амплитудное `Itr` |
Для силового блока адреса данных сдвинуты из-за температурных каналов:
`0x28/0x29` — действующее/амплитудное `Uвх1`, `0x2A/0x2B` —
действующее/амплитудное `Uвх2`.
## 3. Действующие значения отдельных фаз
Для каждой пары измеряются две фазы, третья восстанавливается по условию
трёхпроводной системы:
```text
x3 = -x1 - x2
```
Для каждого из трёх сигналов считается скользящее среднеквадратичное значение:
```text
Qphase[n] = Qphase[n-1] + (xphase² - Qphase[n-1]) / 3750
RMSphase = sqrt(Qphase)
```
`lev_count[]` имеет тип `int`, поэтому сохранённый RMS усекается до целого.
Карта регистров фаз для УМП:
| Регистр | Пара входов | Значение |
|---:|---|---|
| `0x68` | напряжение | RMS фазы A (`Utr A`) |
| `0x69` | напряжение | RMS фазы C (`Utr C`) |
| `0x6A` | напряжение | RMS восстановленной фазы B (`Utr B`) |
| `0x6B` | ток | RMS фазы A (`Itr A`) |
| `0x6C` | ток | RMS фазы C (`Itr C`) |
| `0x6D` | ток | RMS восстановленной фазы B (`Itr B`) |
В коде назначение пары определяется как `feed = chan >> 1`, а начальный адрес
фазных уровней — как `0x68 + feed * 3`.
## 4. Диагностика обрыва или сильного перекоса фазы
Отдельных битов «обрыв фазы A», «обрыв фазы B» и «обрыв фазы C» в прошивке
нет. Есть общий признак сильного отличия одной из трёх фаз — `Wry`.
Конкретную пропавшую фазу надо определять по минимальному значению среди
регистров `0x68…0x6A` или `0x6B…0x6D`.
Алгоритм в `Current_count()`:
```text
Max = max(RMS_A, RMS_B, RMS_C)
перекос фазы = ((Max - RMS_phase) / Max > 0.30) AND (Max > Curr_Edge)
```
Условие проходит через реверсивный счётчик `er_anal()`: при наличии ошибки он
увеличивается, а при исчезновении уменьшается, но не сбрасывается сразу. Порог
для измеряемой фазы равен примерно 3 секундам
(`time_3sec = 3 * ADC_FREQ = 11250` отсчётов). Для восстановленной фазы один и
тот же счётчик вызывается из обоих каналов пары, поэтому при постоянной ошибке
порог фактически достигается примерно вдвое быстрее — около 1,5 секунды.
После достижения порога устанавливаются:
| Бит диагностического слова | Маска | Имя | Значение |
|---:|---:|---|---|
| 2 | `0x0004` | `Wry` | перекос/пропадание одной из фаз более чем на 30% от максимальной |
| 8 | `0x0100` | `Stop` | авария, устанавливается вместе с `Wry` |
Для УМП `Curr_Edge = 300`. Поэтому фазовая диагностика не работает при
`Max <= 300` и не реагирует на слабый сигнал/шум около нуля.
Диагностические слова УМП:
| Регистр | Канал |
|---:|---|
| `0x00` | `Utr A` |
| `0x01` | `Utr C` |
| `0x02` | `Itr A` |
| `0x03` | `Itr C` |
При одиночном пропадании фаз ожидается следующая комбинация:
| Пропавшая фаза | Напряжение | Ток |
|---|---|---|
| A | `0x00.Wry` | `0x02.Wry` |
| C | `0x01.Wry` | `0x03.Wry` |
| B, восстановленная | `0x00.Wry` и `0x01.Wry` | `0x02.Wry` и `0x03.Wry` |
Вместе с каждым `Wry` ставится `Stop`. Эта комбинация выведена из порядка
проверок в коде, но при сложном перекосе она неоднозначна. Надёжнее определять
проблемную фазу по тройке RMS-регистров.
В месте чтения Modbus признаки можно проверять масками:
```c
// Напряжение УМП
bool phase_a_fault = (modbus[0x00] & 0x0004) != 0;
bool phase_c_fault = (modbus[0x01] & 0x0004) != 0;
bool voltage_stop = ((modbus[0x00] | modbus[0x01]) & 0x0100) != 0;
// Ток УМП
bool current_a_fault = (modbus[0x02] & 0x0004) != 0;
bool current_c_fault = (modbus[0x03] & 0x0004) != 0;
bool current_stop = ((modbus[0x02] | modbus[0x03]) & 0x0100) != 0;
```
Названия `phase_a_fault` и `phase_c_fault` здесь условные: каждый `Wry` также
участвует в контроле восстановленной фазы B. Для точной индикации следует
сравнить сами уровни `0x68…0x6D`.
### Другие связанные биты диагностики
Структура диагностического слова задана в
`Source/Internal/Include/measure.h:19–46`:
| Бит | Маска | Имя | Назначение |
|---:|---:|---|---|
| 0 | `0x0001` | `Tear` | обрыв датчика/крайнее значение АЦП; в фазовом расчёте не формируется |
| 2 | `0x0004` | `Wry` | перекос парных датчиков/фаз |
| 3 | `0x0008` | `Out` | уровень ниже нижней уставки |
| 4 | `0x0010` | `Over` | уровень выше предупредительной уставки |
| 5 | `0x0020` | `Hyper` | уровень выше аварийной верхней уставки |
| 6 | `0x0040` | `Contr` | нет сигнала на одном из дискретных входов контроля |
| 8 | `0x0100` | `Stop` | аварийный останов |
| 9 | `0x0200` | `Ready` | готовность, равна `!Stop` |
| 10–13 | `0x0400…0x2000` | `Discr1…Discr4` | отдельные дискретные входы контроля |
| 14 | `0x4000` | `Ignor` | игнорировать диагностику |
| 15 | `0x8000` | `Bypas` | отключить канал |
`reset_errs()` сохраняет управляющие биты 13–15 маской `NOER = 0xE000`,
добавляет вычисленные ошибки и каждый цикл формирует `Ready = !Stop`.
## 5. Уровни напряжения УМП
Проверка уровня выполняется только после расчёта общей амплитуды/RMS пары и
только для нечётного канала пары (`Current_count():569–591`).
### Входное напряжение `Utr`
| Условие | Выдержка | Устанавливаемые биты |
|---|---:|---|
| `Level < 300 В` | около 3 с | `Out` (бит 3) + `Stop` (бит 8) |
| `Level > 420 В` | без отдельной выдержки | `Hyper` (бит 5) + `Stop` (бит 8) |
Уставки находятся в `sens_lo_edge[0/1]` (Modbus `0x48/0x49`) и
`sens_hi_edge[0/1]` (Modbus `0x30/0x31`). Значения выше — заводские; записью
по Modbus или загрузкой EEPROM они могут быть изменены.
### Ток `Itr`
Для полноты связанной логики:
| Условие | Биты |
|---|---|
| `Level > 800 А` | `Over` (бит 4), предупреждение |
| `Level > 900 А` | `Hyper` (бит 5) + `Stop` (бит 8) |
## 6. Контроль напряжений шкафа ВЭП (`Power_count`)
На плате шкафа каждый канал масштабируется напрямую:
```text
Power = ADC_table[chan] * powK[sens_type[chan]]
```
Коэффициенты заданы в `measure.c:52–65`: `0.127` для каналов 380 В и
`0.0076` для низковольтных каналов.
Нижние уровни по умолчанию:
| Каналы | Контролируемое напряжение | Нижний уровень |
|---:|---|---:|
| 0, 1 | 380 В, фидеры 1 и 2 | 300 В |
| 2, 3 | 31 В, фидеры 1 и 2 | 15 В |
| 4, 5 | 31 В UC, фидеры 1 и 2 | 15 В |
| 6 | 24 В ПУ | 20 В |
| 7 | 27 В ФА | 22 В |
| 8 | 24 В ПК | 20 В |
| 9 | 15 В ДР | 10 В |
| 10 | +24 В ДТ | 20 В |
| 11 | −24 В ДТ | 20 В по модулю измеряемого значения |
| 12 | 24 В ПМУ | 20 В |
Если `Power < sens_lo_edge[chan]`, ставится `Out` (бит 3). `Stop` (бит 8)
ставится, когда `Out` уже установлен и у парного канала. Пары заданы как
`0↔1`, `2↔3`, `4↔5`; одиночные каналы спарены сами с собой. Поэтому для
двухфидерных источников аварийный останов означает пропадание обоих фидеров,
а пропадание одного фидера даёт только `Out` в его диагностическом слове.
Проверка превышения верхней уставки в `Power_count():829–835` закомментирована
и фактически не выполняется.
## 7. Особенности текущей реализации
1. На силовых блоках (`dsk_COMM`) четырём каналам назначается `Ignor` по
абсолютным индексам `pow_addr…pow_addr+3` (`measure.c:359–365`), но проверка
в `Current_count()` обращается к `sens_error[chan].Ignor`. Из-за разных
индексов назначенный `Ignor` может не отключать фазовую диагностику.
2. В `Current_count()` используется `pair = sens_pair[chan]`, тогда как для
силового блока пары инициализируются по абсолютному индексу
`sens_pair[pow_addr + chan]`. Для УМП, где `pow_addr == 0`, это работает как
задумано. На силовом блоке индекс `pair` остаётся равен текущему `chan`, что
может дублировать один фазовый RMS вместо чтения парного канала.
3. Следствие двух ошибок индексации: на силовом блоке `Wry` может формироваться,
хотя для канала выставлен `Ignor`, и опираться на неверно сопоставленные
фазовые уровни. Эту часть логики нельзя считать надёжной без исправления или
стендовой проверки.
4. В выражении перекоса деление на `Max` записано раньше проверки
`Max > Curr_Edge`. При `Max == 0` сначала вычисляется деление `0/0`.
Безопаснее сначала проверять порог, затем выполнять деление.
5. Все публикуемые значения и пороги хранятся в 16-битных регистрах как целые числа;
дробная часть после вычислений отбрасывается.
## Краткий итог
- Фазы: два сигнала измеряются, третий восстанавливается как `-x1-x2`.
- RMS каждой фазы: корень из экспоненциально усреднённого квадрата.
- Общий RMS входа: амплитуда `im_calc()` после фильтра, делённая на `sqrt(2)`.
- Обрыв/перекос одной фазы: `Wry`, бит 2; авария: `Stop`, бит 8.
- Определение конкретной фазы: по минимальному из трёх RMS-регистров, отдельного
фазового бита нет.
- Низкое `Utr`: ниже 300 В около 3 секунд — `Out + Stop`.
- Высокое `Utr`: выше 420 В — `Hyper + Stop`.

View File

@@ -0,0 +1,289 @@
@page phase_voltage_weak_points Слабые места расчёта фаз и контроля напряжения
# Слабые места расчёта фаз и контроля напряжения
Документ относится к алгоритмам из `Source/Internal/measure.c`, структуре
диагностики из `Source/Internal/Include/measure.h` и карте регистров
`Doc/Balsam 167 data stru.xls`.
## Критические проблемы
### 1. Неверная индексация парного канала на силовом блоке
В `Current_count()` используется:
```c
pair = sens_pair[chan];
```
При этом пары каналов инициализируются по абсолютному адресу:
```c
sens_pair[pow_addr+i] = pow_addr+(i^1);
```
Для УМП `pow_addr == 0`, поэтому ошибка не проявляется. На силовом блоке
`pow_addr != 0`, и `sens_pair[chan]` остаётся равным самому `chan`.
Последствия:
- вместо парного фазового RMS может использоваться текущий канал;
- регистры `0x68…0x6D` могут содержать дублирующиеся значения;
- расчёт максимальной фазы и диагностика `Wry` могут быть неверными.
Рекомендуемое исправление требует определить, в какой системе индексов должен
работать `lev_count[]`. Вероятный вариант:
```c
pair = sens_pair[sens] - pow_addr;
```
Перед изменением необходимо проверить ожидаемую карту каналов на силовом блоке.
### 2. Бит `Ignor` проверяется по неверному индексу
В `Init_sensors_more()` бит устанавливается так:
```c
Modbus[pow_addr+i].bit.bitE = 1;
```
Но в `Current_count()` проверяется:
```c
if (WAKE || sens_error[chan].bit.Ignor) goto fin;
```
Следует проверять диагностическое слово текущего датчика:
```c
if (WAKE || sens_error[sens].bit.Ignor) goto fin;
```
Последствие текущего кода: `Wry` может формироваться для канала, который должен
быть исключён из диагностики.
### 3. Деление на ноль в расчёте перекоса
Текущее условие:
```c
((Numb - lev_count[chan]) / Numb > 0.3) && (Numb > Curr_Edge)
```
Левая часть вычисляется раньше проверки `Numb > Curr_Edge`. При `Numb == 0`
сначала выполняется деление `0/0`.
Безопасный порядок:
```c
(Numb > Curr_Edge) &&
(((Numb - lev_count[chan]) / Numb) > 0.3)
```
Такое же изменение требуется для проверки `lev_count[thrd]`.
## Высокий приоритет
### 4. Нет независимых признаков обрыва фаз A, B и C
Прошивка формирует общий бит:
| Бит | Маска | Имя |
|---:|---:|---|
| 2 | `0x0004` | `Wry` |
Отдельных битов `PhaseA`, `PhaseB`, `PhaseC` нет. Конкретная фаза определяется
косвенно по RMS-регистрам `0x68…0x6D`.
Фаза B физически не измеряется и восстанавливается:
```text
B = -A - C
```
Из-за этого повреждение фазы B не всегда можно однозначно отличить от
изменения измеряемых фаз A и C.
Рекомендуется формировать отдельную маску состояния фаз, например:
| Бит | Назначение |
|---:|---|
| 0 | низкий RMS фазы A |
| 1 | низкий RMS фазы B |
| 2 | низкий RMS фазы C |
| 3 | общий перекос фаз |
### 5. Выдержка восстановленной фазы примерно вдвое короче
Для восстановленной фазы используется `err_count[thrd]`. Одна и та же ячейка
счётчика проверяется при обработке обоих каналов пары. Поэтому она может
увеличиваться два раза за один цикл АЦП.
Ожидаемое время:
```text
11250 / 3750 = 3 секунды
```
Фактическое время для восстановленной фазы при двух вызовах за цикл:
```text
11250 / (2 * 3750) ≈ 1,5 секунды
```
Рекомендуется выполнять проверку всех трёх фаз один раз после обновления всей
пары каналов.
### 6. Для входов U/I не формируется `Tear`
Бит `Tear` объявлен как бит 0 диагностического слова, но `Current_count()` его
не устанавливает. Нет отдельной проверки АЦП на значения около 0 или 4095.
Последствия:
- обрыв или короткое замыкание измерительного тракта может выглядеть как
обычное отсутствие напряжения;
- невозможно отличить пропадание сети от неисправности самого датчика.
Рекомендуется добавить контроль сырого значения АЦП с выдержкой времени и
отдельными порогами около нижней и верхней границ диапазона.
### 7. Подстройка нуля продолжается после запуска
Ноль обновляется при условии:
```c
if (WAKE < (WAKE_TIME / 2)) Zero_lev[chan] = Zer;
```
`WAKE` уменьшается до нуля. После запуска выражение `0 < WAKE_TIME/2` остаётся
истинным, поэтому `Zero_lev` продолжает изменяться во время работы.
Риск: медленная постоянная составляющая или неисправность входа может частично
компенсироваться алгоритмом нуля.
Если подстройка нужна только при запуске, условие должно ограничивать окно:
```c
if ((WAKE > 0) && (WAKE < (WAKE_TIME / 2))) {
Zero_lev[chan] = Zer;
}
```
Если непрерывная подстройка задумана, её следует явно документировать и
ограничить допустимым диапазоном изменения.
## Средний приоритет
### 8. Жёсткая зона нечувствительности
Для напряжения применяется:
```c
if (Amplitude < 20) Amplitude = 0;
```
Для тока применяется порог 75. Реальный слабый сигнал ниже порога становится
неотличим от полного отсутствия сигнала.
Рекомендуется использовать отдельные пороги включения и выключения
(гистерезис), а также сохранить необрезанное диагностическое значение.
### 9. Несимметричная запись ошибок пары
Проверки общего уровня `Level` выполняются только при `!ist`, то есть в
нечётном канале пары. Поэтому `Out` и `Hyper` записываются только в одно из двух
диагностических слов.
Например, для напряжения УМП низкий общий уровень записывается в `0x01`, хотя
само измерение относится ко всей трёхфазной системе.
Рекомендуется выделить отдельное диагностическое слово системы или явно
дублировать общий признак в оба слова пары.
### 10. Контроль перенапряжения шкафа ВЭП отключён
В `Power_count()` проверка:
```c
if (Power > sens_hi_edge[chan])
```
закомментирована. В рабочем коде контролируется только падение напряжения.
Неисправность с повышением напряжения не создаёт `Hyper` и `Stop`.
Перед включением проверки необходимо задать и проверить верхние уставки для
всех типов источников питания.
### 11. Недостаточный гистерезис порогов
Верхний порог `Utr > 420 В` проверяется непосредственно, без отдельного
счётчика и без порога возврата. При шуме около 420 В диагностический бит может
часто переключаться.
Для нижнего порога используется реверсивный счётчик, но состояние также не
имеет явно заданных разных порогов срабатывания и возврата.
Рекомендуется добавить:
- выдержку времени для перенапряжения;
- разные пороги срабатывания и возврата;
- насыщение и явный сброс диагностических счётчиков.
### 12. Потеря дробной части RMS
`lev_count[]` и Modbus-регистры имеют целочисленный тип. Результат `sqrt()`
сохраняется с отбрасыванием дробной части.
Для текущих порогов в сотнях вольт это не критично, но ухудшает точность
индикации и поведение около границы. При необходимости можно передавать
значения в десятых долях единицы.
## Дополнительные риски
### Разная задержка аварии у парных источников
В `Power_count()` бит `Stop` устанавливается, если `Out` уже присутствует у
парного канала. Из-за последовательной обработки второй канал пары может
получить `Stop` раньше первого. Первый получит его только при следующем опросе.
### Одиночный источник спарен сам с собой
Для непарных источников `sens_pair[chan] == chan`. После первого обнаружения
`Out` бит `Stop` появится при следующем вызове, когда будет прочитано собственное
предыдущее состояние `Out`. Это неочевидная зависимость от предыдущего цикла.
### Уставки доступны для записи без локальной проверки диапазона
Команда Modbus записывает переданное значение непосредственно в массив
регистров. В расчёте не видно проверки допустимого диапазона порогов. Ошибочная
уставка может полностью отключить контроль или вызвать постоянную аварию.
## Рекомендуемый порядок исправлений
1. Исправить индексацию `sens_pair` и `sens_error[].Ignor`.
2. Переставить проверку `Numb > Curr_Edge` перед делением.
3. Перенести расчёт и диагностику трёх фаз в один вызов на пару каналов.
4. Добавить отдельные признаки состояния фаз A/B/C.
5. Добавить диагностику предельных значений АЦП (`Tear`).
6. Определить требуемый режим подстройки нуля и ограничить его.
7. Добавить выдержку и гистерезис верхнего/нижнего напряжения.
8. Проверить все изменения стендовыми тестами: нормальная сеть, обрыв каждой
фазы, перекос, пропадание обоих фидеров, пониженное и повышенное напряжение.
## Минимальный набор тестов
| Тест | Ожидаемый результат |
|---|---|
| Номинальное трёхфазное напряжение | `Wry=0`, `Out=0`, `Hyper=0`, `Stop=0` |
| Обрыв измеряемой фазы A | снижение RMS A, отдельный признак A, затем `Stop` |
| Обрыв измеряемой фазы C | снижение RMS C, отдельный признак C, затем `Stop` |
| Нарушение восстановленной фазы B | снижение вычисленного RMS B без двойной скорости счётчика |
| Перекос ровно 30% | проверка граничного условия `>` |
| `Max = 0` | отсутствие деления на ноль |
| `Utr < 300 В` | `Out`, после выдержки `Stop` |
| `Utr > 420 В` | `Hyper`, после заданной выдержки `Stop` |
| АЦП около 0 или 4095 | `Tear`, отличие от пропадания сети |
| Канал с `Ignor=1` | отсутствие новых автоматических ошибок этого канала |
| Отключённый канал `Bypas=1` | нулевые данные, сохранён только `Bypas` |

16
Doc/README.md Normal file
View File

@@ -0,0 +1,16 @@
# Документация Balsam 167
Запустите `build.bat` из этого каталога. Скрипт всегда собирает обзорную
страницу в `build/index.html`. Скрипт использует переносимый Doxygen из
`.tools/doxygen-1.18.0` либо `doxygen.exe` из `PATH` и создаёт API-справочник
в `build/api/html/index.html`. Без Doxygen по
этому адресу создаётся поясняющая страница, поэтому ссылка из обзора не
остаётся битой.
Исходные файлы старого проекта сохранены в CP1251. `Doxyfile` явно задаёт эту
кодировку для `*.c` и `*.h`, а новые файлы документации хранятся в UTF-8.
```bat
cd Doc
build.bat
```

53
Doc/README_CCS12.md Normal file
View File

@@ -0,0 +1,53 @@
# Сборка проекта в Code Composer Studio 12
Проект поддерживает обе IDE параллельно:
- CCS 3 использует корневой файл `UKSSTMS320F28335.pjt`;
- CCS 12 использует проект из каталога `UKSSTMS320F28335`.
Файлы CCS 3 не изменялись. Объектные файлы и итоговые образы двух систем
сборки разнесены по разным каталогам и не перезаписывают друг друга.
## Импорт
1. Откройте **File → Import → Code Composer Studio → CCS Projects**.
2. В **Select search-directory** укажите каталог репозитория.
3. Выберите проект **UKSSTMS320F28335** и нажмите **Finish**.
4. Выберите конфигурацию **Debug** или **Release** и выполните **Build Project**.
Проект настроен для `TMS320F28335`, COFF ABI и C2000 Compiler
`22.6.0.LTS`, входящего в CCS 12.3.
## Результаты сборки
- CCS 3 продолжает использовать прежние каталоги `Debug`, `Release` и `Bin`.
- CCS 12 Debug создаёт `.out`, `.hex`, `.bin` и `.map` в `Bin/CCS12`.
- CCS 12 Release создаёт `UKSSTMS320F28335_Release.out` и
`UKSSTMS320F28335_Release.map` в `Bin/CCS12`.
## Публикация прошивки
`publish_firmware.bat` создаёт Gitea Release, загружает образ, вычисляет
SHA-256 и обновляет `firmware.releases` общего `update.json`. Перед запуском
сохраните вход Gitea в SETGUI. Альтернативно задайте `GITEA_TOKEN` либо пару
`GITEA_USER`/`GITEA_PASSWORD` в окружении CCS.
Пример отдельного шага после сборки CCS:
```bat
"${SRC_ROOT}\publish_firmware.bat" "${SRC_ROOT}\Bin\CCS12\UKSSTMS320F28335.bin" "1.0.0" "Описание изменений" "tms"
```
Путь к образу зависит от конфигурации CCS; первым параметром должен быть
фактический полный путь созданного `.bin` или `.hex`. Версия задаётся в формате
`MAJOR.MINOR.PATCH`. Повторный запуск той же версии заменяет asset и запись
каталога, не создавая дубликат.
Для проверки файла и доступа к Gitea без публикации добавьте пятый параметр:
```bat
"${SRC_ROOT}\publish_firmware.bat" "${SRC_ROOT}\Bin\CCS12\UKSSTMS320F28335.bin" "1.0.0" "Проверка" "tms" "check"
```
Все пути к исходникам заданы относительно каталога проекта через `SRC_ROOT`;
перенос репозитория в другой каталог не требует изменения настроек.

10
Doc/api-unavailable.html Normal file

File diff suppressed because one or more lines are too long

723
Doc/api.dox Normal file
View File

@@ -0,0 +1,723 @@
/**
@file api.dox
@brief Русскоязычные Doxygen-описания интерфейсов Balsam 167.
@defgroup measurement Измерения и диагностика
@brief АЦП, фильтрация, пересчёт каналов и формирование аварий.
@{
*/
/**
@fn void setup_adc(void)
@brief Настраивает ADC и быстрый обработчик преобразований.
@details Конфигурирует последовательность каналов и параметры накопления,
используемые измерительным контуром. Вызывается один раз при старте для всех
ролей, кроме пульта EPLT.
*/
/**
@fn void adc_isr(void)
@brief Обрабатывает очередную последовательность преобразований ADC.
@details Обновляет сырые выборки и фильтры; выполняется в контексте прерывания.
*/
/**
@fn void Init_sensors(void)
@brief Выполняет первичную инициализацию измерительных каналов.
*/
/**
@fn void Init_sensors_more(void)
@brief Применяет параметры изделия после загрузки сохранённых настроек.
*/
/**
@fn void Init_packMask(void)
@brief Формирует маски публикуемых CAN-регистров для каждой шины.
*/
/**
@fn void Temper_count(int chan, int own)
@brief Пересчитывает температурный канал и обновляет его диагностику.
@param chan Индекс базового канала в общей модели измерений.
@param own Признак локального либо внешнего источника температуры.
*/
/**
@fn void Current_count(int chan)
@brief Вычисляет ток по паре измерительных каналов и формирует ошибки.
@param chan Индекс канала тока.
*/
/**
@fn void Power_count(int chan)
@brief Вычисляет напряжение/мощность для заданного канала.
@param chan Индекс обрабатываемого канала.
*/
/**
@fn void calc_sensor_koef(void)
@brief Пересчитывает коэффициенты датчиков по калибровочным точкам.
*/
/**
@fn void calc_volta_edge(void)
@brief Пересчитывает пороги контроля напряжения из текущих настроек.
*/
/**
@fn void Is_Voltage_Hi(void)
@brief Проверяет превышение напряжения и обновляет общий признак аварии.
*/
/**
@fn void cpu_timer1_isr_SENS(void)
@brief Периодический обработчик измерительной платы.
@details Планирует выбор каналов, пересчёт величин, диагностику, мигание и
циклическую передачу. Выполняется в контексте прерывания CPU Timer1.
*/
/**
@fn int er_anal(int term, unsigned int *count, long edge, int pre)
@brief Реализует выдержку времени для появления и снятия диагностического условия.
@param term Текущее логическое состояние диагностического условия.
@param count Счётчик длительности условия; изменяется функцией.
@param edge Порог счётчика, после которого условие подтверждается.
@param pre Состояние ошибки на предыдущем шаге.
@return Ненулевое значение, когда ошибка считается активной.
*/
/**
@struct FILTERBAT
@brief Состояние рекурсивного фильтра второго порядка.
@details Содержит три коэффициента, три входные и три выходные выборки.
*/
/**
@fn float filterbat(FILTERBAT *b, float InpVarCurr)
@brief Пропускает одну выборку через фильтр Баттерворта.
@param b Экземпляр фильтра с коэффициентами и историей.
@param InpVarCurr Новая входная выборка.
@return Отфильтрованное значение.
*/
/**
@struct ERROR
@brief Шестнадцатибитное слово состояния измерительного канала.
@details Объединяет признаки обрыва, неправильного сигнала, выхода за пределы,
перегрева, блокировки, готовности, дискретных входов, игнорирования и bypass.
*/
/**
@struct FLAG
@brief Общие признаки ошибки, аварии, нагрева и теста ламп.
*/
/**
@}
*/
/**
@defgroup communication Последовательный обмен и сообщения
@brief Два канала SCI, физический режим RS-485 и прикладные команды.
@{
*/
/**
@struct RS_DATA
@brief Контекст одного SCI/RS-485 канала.
@details Хранит регистры SCI, указатели RX/TX, буферы, длины сообщений,
тайм-ауты, адреса и параметры линии. Глобальные экземпляры: `rs_a` и `rs_b`.
*/
/**
@fn void create_uart_vars(char size_cmd15_set)
@brief Инициализирует контексты двух UART и таблицу длин команд.
@param size_cmd15_set Размер payload команды 15 для текущего приложения.
*/
/**
@fn void setup_uart(char commnumber, unsigned long speed_baud)
@brief Настраивает SCI-A или SCI-B и соответствующие обработчики PIE.
@param commnumber Номер порта: `COM_1` либо `COM_2`.
@param speed_baud Скорость линии, бит/с.
*/
/**
@fn void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop)
@brief Задаёт длину слова, чётность и число стоп-битов.
@param rs_arr Контекст канала.
@param bit Число информационных битов.
@param parity Режим контроля чётности.
@param stop Режим стоп-битов.
*/
/**
@fn void RS_SetLineSpeed(RS_DATA *rs_arr, unsigned long speed)
@brief Изменяет скорость выбранного последовательного канала.
@param rs_arr Контекст канала.
@param speed Новая скорость, бит/с.
*/
/**
@fn void RS_SetBitMode(RS_DATA *rs_arr, int n)
@brief Выбирает байтовый либо упакованный режим данных SCI.
@param rs_arr Контекст канала.
@param n Требуемый режим представления элементов.
*/
/**
@fn int RS_Send(RS_DATA *rs_arr, unsigned int *pBuf, unsigned long len)
@brief Запускает неблокирующую передачу массива слов.
@param rs_arr Контекст канала.
@param pBuf Буфер передаваемых слов.
@param len Число слов.
@return Признак успешного запуска передачи.
*/
/**
@fn int RS_BSend(RS_DATA *rs_arr, unsigned int *pBuf, unsigned long len)
@brief Запускает передачу байтов, хранящихся в 16-битных ячейках C28x.
@param rs_arr Контекст канала.
@param pBuf Буфер данных.
@param len Число восьмибитных элементов.
@return Признак успешного запуска передачи.
*/
/**
@fn int get_command(RS_DATA *rs_arr)
@brief Проверяет принятый кадр и извлекает код команды.
@param rs_arr Контекст канала с принятым пакетом.
@return Код команды либо `-1`, если полного корректного кадра нет.
*/
/**
@fn void RSA_RX_Handler(void)
@brief Обработчик приёма SCI-A, делегирующий работу общему RX-автомату.
*/
/**
@fn void RSA_TX_Handler(void)
@brief Обработчик передачи SCI-A.
*/
/**
@fn void RSB_RX_Handler(void)
@brief Обработчик приёма SCI-B, делегирующий работу общему RX-автомату.
*/
/**
@fn void RSB_TX_Handler(void)
@brief Обработчик передачи SCI-B.
*/
/**
@fn void clear_timer_rs_live(RS_DATA *rs_arr)
@brief Сбрасывает счётчик контроля активности последовательного канала.
@param rs_arr Контекст канала.
*/
/**
@fn void test_rs_live(RS_DATA *rs_arr)
@brief Проверяет тайм-аут активности последовательного канала.
@param rs_arr Контекст канала.
*/
/**
@fn void ReceiveCommandModbus3(RS_DATA *rs_arr)
@brief Обрабатывает Modbus function 3 — чтение регистров.
@param rs_arr Канал, на котором принята команда.
*/
/**
@fn void ReceiveCommandModbus6(RS_DATA *rs_arr)
@brief Обрабатывает Modbus function 6 — запись одного регистра.
@param rs_arr Канал, на котором принята команда.
*/
/**
@fn void SendCommandModbus4(RS_DATA *rs_arr)
@brief Формирует запрос function 4 к внешнему устройству OWEN.
@param rs_arr Канал связи с устройством.
*/
/**
@fn void ReceiveAnswerModbus4(RS_DATA *rs_arr)
@brief Разбирает ответ OWEN на запрос входных регистров.
@param rs_arr Канал, на котором принят ответ.
*/
/**
@struct CMD_TO_TMS
@brief Формат короткой команды контроллеру.
@details Содержит адрес, номер команды, восемь байтов данных, CRC и добавочный байт.
*/
/**
@}
*/
/**
@defgroup can_bus CAN
@brief Инициализация eCAN-A, приём команд и публикация регистров.
@{
*/
/**
@fn void InitCan(int Port, int DevNum)
@brief Настраивает CAN-контроллер и почтовые ящики.
@param Port Зарезервированный номер CAN-порта; текущая плата использует порт 0.
@param DevNum Адрес/режим устройства, участвующий в конфигурации идентификаторов.
*/
/**
@fn void CAN_send(int Port, int data[], int Addr)
@brief Передаёт группу из трёх регистров общей модели.
@param Port Номер CAN-порта.
@param data Начало массива регистров.
@param Addr Адрес первого публикуемого регистра.
*/
/**
@fn void CANa_handler(void)
@brief Обработчик приёма eCAN-A; переносит данные mailbox в прикладную модель.
*/
/**
@fn void CANa_reset_err(void)
@brief Обрабатывает состояние ошибки eCAN-A и восстанавливает обмен.
*/
/**
@}
*/
/**
@defgroup storage Параметры, EEPROM и журнал
@brief Долговременное хранение конфигурации и диагностических выборок.
@{
*/
/**
@struct SE2P_DATA
@brief Описание операции с последовательной EEPROM.
@details Содержит указатель данных, размер операции и адрес EEPROM.
*/
/**
@struct SPISE2P_DRV
@brief Состояние и виртуальные методы драйвера SPI EEPROM.
*/
/**
@fn void InitSeeprom(void)
@brief Настраивает SPI-A, GPIO chip-select и Timer2 для EEPROM.
*/
/**
@fn void Seeprom_write(unsigned int adres, unsigned int buf[], unsigned int size)
@brief Синхронно записывает блок 16-битных слов во внешнюю EEPROM.
@param adres Адрес слова в EEPROM.
@param buf Буфер исходных слов.
@param size Количество записываемых слов.
*/
/**
@fn void Seeprom_read(unsigned int adres, unsigned int buf[], unsigned int size)
@brief Синхронно читает блок 16-битных слов из внешней EEPROM.
@param adres Адрес слова в EEPROM.
@param buf Буфер результата.
@param size Количество читаемых слов.
*/
/**
@fn void Default_params(void)
@brief Загружает заводские уставки и калибровочные значения в RAM.
*/
/**
@fn void Load_params(void)
@brief Читает настройки из EEPROM и проверяет их целостность.
*/
/**
@fn void Save_params(void)
@brief Записывает текущие настройки и контрольную сумму в EEPROM.
*/
/**
@struct LOG
@brief Границы и текущий указатель циклического журнала во внешней памяти.
*/
/**
@fn void clear_mem(void)
@brief Инициализирует область журнала и очищает её рабочее состояние.
*/
/**
@}
*/
/**
@defgroup hardware Аппаратные интерфейсы
@brief GPIO, режим платы, ЦАП и последовательная индикация.
@{
*/
/**
@fn void get_Mode(void)
@brief Читает конфигурационные входы и определяет `Mode` и `Desk`.
*/
/**
@fn void get_Buttons(void)
@brief Опросивает дискретные входы и обновляет биты кнопок/команд.
*/
/**
@fn void setup_leds_line(void)
@brief Временно настраивает линии двух диагностических светодиодов.
*/
/**
@fn void unsetup_leds_line(void)
@brief Возвращает мультиплексируемые линии из режима стартовой индикации.
*/
/**
@fn void select_tpl_canal(int n_tpl)
@brief Выбирает один канал мультиплексора термопар.
@param n_tpl Номер канала термопары.
*/
/**
@fn void select_tpl_255(void)
@brief Переводит адресные линии мультиплексора в неактивное состояние.
*/
/**
@fn void Setup_DAC_time(void)
@brief Вычисляет временные параметры программного обслуживания ЦАП.
*/
/**
@fn void Init_DAC(void)
@brief Инициализирует GPIO последовательного интерфейса ЦАП.
*/
/**
@fn void Anal_output(long vrot, long maxx)
@brief Выдаёт нормированное значение на аналоговый выход.
@param vrot Требуемое значение.
@param maxx Верхняя граница шкалы входного значения.
*/
/**
@fn void Load_runner(void)
@brief Обновляет выход нагрузки и формирует старт/стоп импульсы.
*/
/**
@fn void kanal_Send(int adr, long dat, int dot)
@brief Передаёт число на внешний семисегментный индикатор.
@param adr Адрес индикаторного канала.
@param dat Отображаемое целое значение.
@param dot Позиция десятичной точки.
*/
/**
@fn void cpu_timer1_isr_PULT(void)
@brief Периодический обработчик пульта и внешней индикации.
*/
/**
@}
*/
/**
@defgroup boot_protocol BIOS-протокол
@brief Команды удалённого чтения, записи, запуска и прошивки контроллера.
@{
*/
/**
@fn void Answer(RS_DATA *rs_arr, int n)
@brief Формирует и отправляет ответ BIOS-протокола.
@param rs_arr Канал ответа.
@param n Число элементов данных ответа.
*/
/**
@fn void init(RS_DATA *rs_arr)
@brief Возвращает идентификацию работающего приложения.
@param rs_arr Канал запроса.
*/
/**
@fn void initload(RS_DATA *rs_arr)
@brief Инициализирует сеанс загрузки программы.
@param rs_arr Канал запроса.
*/
/**
@fn void load(RS_DATA *rs_arr)
@brief Принимает очередной блок загружаемой программы.
@param rs_arr Канал запроса.
*/
/**
@fn void run(RS_DATA *rs_arr)
@brief Завершает загрузку и передаёт управление программе.
@param rs_arr Канал запроса.
*/
/**
@fn void peek(RS_DATA *rs_arr)
@brief Читает участок адресного пространства контроллера.
@param rs_arr Канал запроса и ответа.
*/
/**
@fn void poke(RS_DATA *rs_arr)
@brief Записывает данные в адресное пространство контроллера.
@param rs_arr Канал запроса.
*/
/**
@fn void upload(RS_DATA *rs_arr)
@brief Передаёт блок памяти контроллера ведущему устройству.
@param rs_arr Канал запроса и ответа.
*/
/**
@fn void tflash(RS_DATA *rs_arr)
@brief Выполняет команду обслуживания Flash TMS320F28335.
@param rs_arr Канал запроса и ответа.
*/
/**
@fn void xflash(RS_DATA *rs_arr)
@brief Обрабатывает совместимую команду доступа к внешней Flash/памяти.
@param rs_arr Канал запроса и ответа.
*/
/**
@fn void extendbios(RS_DATA *rs_arr)
@brief Обрабатывает расширенную команду BIOS-протокола.
@param rs_arr Канал запроса и ответа.
*/
/**
@fn unsigned int read_memory(unsigned long addr)
@brief Читает 16-битное слово по физическому адресу.
@param addr Адрес в пространстве данных C28x.
@return Прочитанное слово.
*/
/**
@fn void write_memory(unsigned long addr, unsigned int data)
@brief Записывает 16-битное слово по физическому адресу.
@param addr Адрес в пространстве данных C28x.
@param data Записываемое слово.
*/
/**
@}
*/
/**
@defgroup utilities Служебные функции
@brief CRC, внешняя зона памяти и точные задержки.
@{
*/
/**
@fn unsigned int get_crc_ccitt(unsigned int crc, unsigned int *buf, unsigned long size)
@brief Вычисляет CRC-CCITT для массива восьмибитных значений в словах C28x.
@param crc Начальное значение CRC.
@param buf Буфер входных значений.
@param size Число элементов.
@return Итоговое значение CRC.
*/
/**
@fn unsigned int get_crc_16(unsigned int crc, unsigned int *buf, unsigned long size)
@brief Вычисляет основной вариант CRC-16 проекта.
@param crc Начальное значение CRC.
@param buf Буфер входных значений.
@param size Число элементов.
@return Итоговое значение CRC.
*/
/**
@fn unsigned int get_crc_16b(unsigned int crc, unsigned int *buf, unsigned long size)
@brief Вычисляет CRC-16 с альтернативным порядком байтов.
@param crc Начальное значение CRC.
@param buf Буфер входных значений.
@param size Число элементов.
@return Итоговое значение CRC.
*/
/**
@fn int get_crc16(unsigned int *buf, int size)
@brief Вычисляет контрольное слово пакета прикладного протокола.
@param buf Буфер пакета.
@param size Число обрабатываемых элементов.
@return Шестнадцатибитное контрольное значение.
*/
/**
@fn void init_zone7(void)
@brief Настраивает зону XINTF7 для внешней памяти и периферии.
*/
/**
@fn void pause_us(unsigned long t)
@brief Выполняет программную задержку.
@param t Длительность в микросекундах согласно частоте проекта.
*/
/**
@fn void set_cntrl_addr(int cntrl_addr, int cntrl_addr_for_all)
@brief Устанавливает индивидуальный и групповой адреса контроллера.
@param cntrl_addr Индивидуальный адрес устройства.
@param cntrl_addr_for_all Групповой широковещательный адрес.
*/
/**
@fn void SPISE2P_DRV_init(SPISE2P_DRV *eeprom)
@brief Инициализирует низкоуровневый автомат SPI EEPROM.
@param eeprom Экземпляр драйвера.
*/
/**
@fn void SPISE2P_DRV_tick(SPISE2P_DRV *eeprom)
@brief Выполняет один шаг неблокирующего автомата EEPROM.
@param eeprom Экземпляр драйвера.
*/
/**
@fn void SPISE2P_DRV_csset(void)
@brief Деактивирует линию chip-select EEPROM.
*/
/**
@fn void SPISE2P_DRV_csclr(void)
@brief Активирует линию chip-select EEPROM.
*/
/**
@fn unsigned int spiSe2pFree(SPISE2P_DRV *se2p)
@brief Проверяет готовность автомата EEPROM к новой операции.
@param se2p Экземпляр драйвера.
@return Ненулевое значение, когда драйвер свободен.
*/
/**
@fn void spiSe2pWrite(SPISE2P_DRV *se2p, SE2P_DATA *data)
@brief Передаёт автомату описание операции записи.
@param se2p Экземпляр драйвера.
@param data Описание адреса, буфера и длины.
*/
/**
@fn void spiSe2pRead(SPISE2P_DRV *se2p, SE2P_DATA *data)
@brief Передаёт автомату описание операции чтения.
@param se2p Экземпляр драйвера.
@param data Описание адреса, буфера и длины.
*/
/**
@}
*/

64
Doc/build.bat Normal file
View File

@@ -0,0 +1,64 @@
@echo off
rem Builds the local HTML overview and Doxygen API reference in Doc\build.
rem Prefers the pinned Doc\.tools Doxygen, then falls back to a system install.
rem If Doxygen is unavailable, installs the explanatory API placeholder instead.
setlocal EnableExtensions
set "DOC_DIR=%~dp0"
set "SOURCE=%DOC_DIR%index.html"
set "BUILD_DIR=%DOC_DIR%build"
set "OVERVIEW=%BUILD_DIR%\index.html"
set "DOXYGEN_EXE=%DOC_DIR%.tools\doxygen-1.18.0\doxygen.exe"
echo [BALSAM 167] Building HTML documentation...
if not exist "%SOURCE%" (
echo [ERROR] Source HTML not found:
echo %SOURCE%
exit /b 1
)
if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%"
if errorlevel 1 (
echo [ERROR] Cannot create build directory:
echo %BUILD_DIR%
exit /b 2
)
copy /Y "%SOURCE%" "%OVERVIEW%" >nul
if errorlevel 1 (
echo [ERROR] Cannot build overview HTML.
exit /b 3
)
if not exist "%DOXYGEN_EXE%" (
where doxygen >nul 2>nul
if not errorlevel 1 set "DOXYGEN_EXE=doxygen"
)
if not exist "%DOXYGEN_EXE%" if /I not "%DOXYGEN_EXE%"=="doxygen" (
if not exist "%BUILD_DIR%\api\html" mkdir "%BUILD_DIR%\api\html"
copy /Y "%DOC_DIR%api-unavailable.html" "%BUILD_DIR%\api\html\index.html" >nul
echo [WARN] Doxygen is not installed; API reference was not regenerated.
echo [OK] Overview: %OVERVIEW%
exit /b 0
)
pushd "%DOC_DIR%"
"%DOXYGEN_EXE%" Doxyfile
set "DOXYGEN_RESULT=%ERRORLEVEL%"
popd
if not "%DOXYGEN_RESULT%"=="0" (
echo [ERROR] Doxygen failed with code %DOXYGEN_RESULT%.
exit /b %DOXYGEN_RESULT%
)
if not exist "%BUILD_DIR%\api\html\index.html" (
echo [ERROR] Doxygen did not create the expected API index.
exit /b 4
)
echo [OK] Overview: %OVERVIEW%
echo [OK] API: %BUILD_DIR%\api\html\index.html
exit /b 0

69
Doc/files.dox Normal file
View File

@@ -0,0 +1,69 @@
/**
@file main.c
@brief Точка входа, запуск периферии и главный цикл приложения.
@details Связывает все внутренние модули, выбирает ISR Timer1 по роли платы и
обслуживает CAN, команды конфигурации, кнопки и оба последовательных канала.
*/
/** @file ADC.c
@brief Настройка ADC TMS320F28335 и обработка потока сырых измерений. */
/** @file measure.c
@brief Пересчёт измерений Balsam 167, калибровка и диагностика каналов.
@details Содержит периодический измерительный ISR и общие массивы фильтров,
счётчиков, внешних температур, масок CAN и слов ошибок. */
/** @file filter_bat2.c
@brief Реализация рекурсивного фильтра Баттерворта второго порядка. */
/** @file RS485.c
@brief Драйвер SCI-A/SCI-B и автоматы приёма/передачи RS-485. */
/** @file bios.c
@brief Сервисные и загрузочные команды BIOS-протокола TMS. */
/** @file message.c
@brief Modbus-команды, обмен с OWEN и сохранение параметров изделия. */
/** @file ecan.c
@brief Настройка eCAN-A, почтовые ящики, приём и отправка телеметрии. */
/** @file spise2p.c
@brief Доступ к последовательной EEPROM через SPI-A. */
/** @file peripher.c
@brief Определение аппаратной роли, таблицы GPIO и дискретные входы/выходы. */
/** @file DAC.c
@brief Программный последовательный интерфейс аналогового выхода нагрузки. */
/** @file pulto.c
@brief Периодическая логика панели EPLT. */
/** @file kanal.c
@brief Низкоуровневая передача данных внешним семисегментным каналам. */
/** @file crc16.c
@brief Варианты CRC-16, используемые транспортными и сервисными протоколами. */
/** @file cntrl_adr.c
@brief Хранение и проверка индивидуального и группового адресов контроллера. */
/** @file log_to_mem.c
@brief Инициализация циклического журнала во внешней памяти XINTF. */
/** @file tools.c
@brief Настройка XINTF zone 7 и программные задержки. */
/** @file package.h
@brief Конфигурация варианта Balsam и логическая карта массива Modbus.
@warning Изменение смещений влияет на CAN, RS-485, EEPROM и внешнее ПО. */
/** @file GPIO_table.h
@brief Направления, уровни и мультиплексирование GPIO для всех ролей платы. */
/** @file caliber.h
@brief Заводские калибровочные таблицы вариантов Balsam.
@note Заголовок содержит определения данных и намеренно исключён из разбора
Doxygen, чтобы препроцессор не выбирал несовместимые варианты. */

117
Doc/index.html Normal file

File diff suppressed because one or more lines are too long

70
Doc/mainpage.md Normal file
View File

@@ -0,0 +1,70 @@
# Balsam 167 Peripheral {#mainpage}
Прошивка периферийного контроллера **Balsam 167** для цифрового сигнального
контроллера Texas Instruments TMS320F28335. Контроллер измеряет токи,
напряжения и температуры, анализирует аварийные состояния, управляет
дискретными выходами и обменивается данными по CAN и двум каналам SCI/RS-485.
@tableofcontents
## Назначение
Один исполняемый образ поддерживает несколько аппаратных ролей. Роль платы
определяется входами режима при старте и хранится в `Desk`:
| Значение | Роль | Основная задача |
|---|---|---|
| `dsk_COMM` | COMM | связь и термокалибровка |
| `dsk_BKSD` | BKSD | дискретные сигналы |
| `dsk_BKST` | BKST | температурные каналы |
| `dsk_EPLT` | EPLT | пульт/индикация |
| `dsk_SHKF` | SHKF | шкафной контроллер |
| `dsk_LOAD` | LOAD | нагрузка и аналоговый выход |
Конфигурация изделия выбирается макросом `BALSAM` в `package.h`. Для этого
репозитория задано значение `167`.
## Выполнение программы
1. `main()` настраивает системную тактовую частоту, PIE, внешнюю память,
GPIO, CAN, SCI, EEPROM и измерительные каналы.
2. `timer_Init()` выбирает обработчик Timer1: `cpu_timer1_isr_SENS()` для
измерительных плат или `cpu_timer1_isr_PULT()` для пульта.
3. Быстрый контур АЦП выполняется в `adc_isr()`.
4. Главный цикл передаёт телеметрию, обслуживает команды настройки,
дискретные входы и протокол BIOS/Modbus.
## Карта модулей
- @ref measurement — сбор АЦП, фильтрация, пересчёт физических величин и ошибки.
- @ref communication — SCI/RS-485, разбор команд и Modbus-пакеты.
- @ref can_bus — CAN eCAN-A и циклическая телеметрия.
- @ref storage — SPI EEPROM, параметры и журнал во внешней памяти.
- @ref hardware — GPIO, дискретные выходы, ЦАП и семисегментный канал.
- @ref boot_protocol — команды чтения, записи и запуска ПО через BIOS-протокол.
- @ref utilities — CRC, фильтр Баттерворта, задержки и служебные функции.
## Общая память данных
Массив `modbus` — центральная модель состояния. Макросы из `package.h`
проецируют его участки на флаги ошибок, измерения, уставки, коэффициенты
калибровки и команды. Измерительный контур обновляет модель, а CAN/RS-485
публикуют или изменяют её. При изменении разметки следует одновременно
проверять адреса протокола, `ANSWER_LEN` и таблицу данных изделия в `Doc`.
## Сборка прошивки
Инструкции для Code Composer Studio 12 находятся в
[README_CCS12.md](README_CCS12.md). Старый проект CCS 3 использует
`UKSSTMS320F28335.pjt`; проект CCS 12 расположен в каталоге
`UKSSTMS320F28335`.
## Сборка документации
Запустите `Doc\\build.bat`. Обзор будет помещён в `Doc\\build\\index.html`,
а при наличии Doxygen API-справочник появится в
`Doc\\build\\api\\html\\index.html`.
@warning Обработчики прерываний и функции, меняющие GPIO или регистры
периферии, нельзя вызывать как обычные функции без понимания контекста PIE,
частоты тактирования и выбранной роли платы.

View File

@@ -1,3 +1,13 @@
/**
* @file ADC.c
* @brief Сбор аналоговых отсчётов и первичная обработка измерительных каналов.
*
* Модуль настраивает АЦП TMS320F28335 и обслуживает прерывание окончания
* преобразования. Отсчёты накапливаются в ADC_table и adc_table_lem, после
* чего передаются измерительному контуру. Обработчик работает в контексте
* прерывания, поэтому его время выполнения ограничено частотой дискретизации,
* а разделяемые таблицы должны читаться основным циклом согласованно.
*/
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP281x Examples Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
@@ -14,20 +24,37 @@
#include "peripher.h"
/** @brief Сырые отсчёты четырёх силовых каналов, передаваемые Current_count(). */
Uint16 adc_table_lem[4];
Uint16 ADC_table[28]; // Ïîòîìó ÷òî +4 êàëèáð
/** @brief Фильтрованные значения всех рабочих и калибровочных каналов. */
Uint16 ADC_table[28]; // Потому что +4 калибр
/** @brief Число допустимых отсчётов прошлого окна для контроля выбросов. */
Uint16 prev_ok[28];
/** @brief Параметры временного мультиплексирования термоканалов в тиках АЦП. */
unsigned int COUNT_ONE_CANAL;
unsigned int COUNT_DISCHARGE;
unsigned int COUNT_TRANSICIA;
unsigned int FILTER_CLIP;
/** @brief Счётчик прогрева измерений и его начальная длительность. */
long WAKE, WAKE_TIME;
// Prototype statements for functions found within this file.
/** @brief ISR конца последовательности ADC SEQ1. */
interrupt void adc_isr(void);
/**
* @brief Полностью настраивает АЦП, ePWM-триггер и расписание каналов платы.
*
* @details По Desk выбирается физическая последовательность входов ADCINA/B.
* ePWM1 затем запускает SEQ1 с частотой ADC_FREQ. Для мультиплексированных
* термоканалов рассчитываются интервалы разряда, переходного процесса и окна
* накопления; WAKE подавляет использование неустановившихся фильтров при старте.
*
* @pre Desk и признаки TermoAD/TermoSW определены функцией get_Mode().
* @post ADCINT подключён к adc_isr(), SEQ1 и ePWM1 запущены.
*/
void setup_adc()
{
long CLKdiv,HSPCLKdiv,Rate;
@@ -59,21 +86,23 @@ void setup_adc()
// EINT; // Enable Global interrupt INTM
// ERTM; // Enable Global realtime interrupt DBGM
/* Исключаем использование остаточных данных до первого полного цикла АЦП. */
for(i=0;i<28;i++)
ADC_table[i]=
prev_ok[i] = 0;
/* Каждая роль платы имеет собственную разводку входов и длину sequencer. */
// Configure ADC
if(Desk==dsk_LOAD)
{
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0005; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // òåìïåðàòóðà (êîòîðîé íåò)
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // îìåãà
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5; // íàïðóãà 1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4; // íàïðóãà 2
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // òîê 1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2; // òîê 2
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // температура (которой нет)
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // омега
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5; // напруга 1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4; // напруга 2
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // ток 1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2; // ток 2
}
if(Desk==dsk_BKST)
@@ -87,7 +116,7 @@ void setup_adc()
if(Desk==dsk_COMM)
{
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0006; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // ñíà÷àëà òîæå áóäóò òåìïåðàòóðû
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // сначала тоже будут температуры
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x4; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x7; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
@@ -105,23 +134,23 @@ void setup_adc()
if(Desk==dsk_SHKF)
{
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x000F; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // 380Â Ô1
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // 380Â Ô2
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6; // 31Â Ô1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC; // 31Â Ô2 ?
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA; // 31Â UC1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB; // 31Â UC2
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 24Â ÏÓ
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4; // 24Â ÏÓ
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // 380В Ф1
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // 380В Ф2
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6; // 31В Ф1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC; // 31В Ф2 ?
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA; // 31В UC1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB; // 31В UC2
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 24В ПУ
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4; // 24В ПУ
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5; // 24Â ÏÊ áûëî 5
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1; // 15Â Äð
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE; // +24Â Äò
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0; // +24Â Äò
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8; // -24Â Äò áûëî 8
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5; // 24В ПК было 5
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1; // 15В Др
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE; // +24В Дт
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0; // +24В Дт
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8; // -24В Дт было 8
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;//0xF; // ÄÒ° 1
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;//0xD; // ÄÒ° 2
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;//0xF; // ДТ° 1
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;//0xD; // ДТ° 2
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x9;//0x9;
}
@@ -152,6 +181,7 @@ void setup_adc()
if(EPwm1Regs.TBCTL.bit.HSPCLKDIV) HSPCLKdiv = 2*EPwm1Regs.TBCTL.bit.HSPCLKDIV;
else HSPCLKdiv = 1;
/* Период ePWM получается из реальной частоты TBCLK после обоих делителей. */
Rate = (SYSCLKOUT/(HSPCLKdiv*CLKdiv))/ADC_FREQ;
EPwm1Regs.TBPRD = Rate; // Set period for ePWM1
@@ -195,6 +225,18 @@ void setup_adc()
WAKE = WAKE_TIME;
}
/**
* @brief Забирает результаты SEQ1, фильтрует их и запускает расчёт величин.
*
* @details Сначала разрешает вложенные прерывания согласно программному
* приоритету PIE. В зависимости от аппаратной роли обрабатывает силовые каналы,
* нагрузочный аналоговый вход, шкафные каналы либо мультиплексированные
* термодатчики. Выброс принимается только при прохождении FILTER_CLIP; во время
* WAKE фильтр обучается, но наружу выдаётся непосредственный отсчёт.
*
* @note На общем выходе fin всегда сбрасывает SEQ1, подтверждает PIE и
* восстанавливает сохранённую маску PIEIER1, включая путь раннего выхода.
*/
interrupt void adc_isr(void)
{
static int cownt_one_canal=0;
@@ -214,6 +256,7 @@ interrupt void adc_isr(void)
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
/* До READY обслуживается только обязательное завершение аппаратного цикла. */
if(WAKE) WAKE--;
if(!READY) goto fin;
@@ -246,7 +289,7 @@ interrupt void adc_isr(void)
{
if (++cownt_cans>=tpl_cans) cownt_cans=0;
// Èìåííî çäåñü íåò äûð
// Именно здесь нет дыр
// if(sens_type[cownt_cans])
{
i++;
@@ -256,6 +299,7 @@ interrupt void adc_isr(void)
else Power_count(cownt_cans);
} } }
/* Программный мультиплексор: переключение, выдержка, накопление и расчёт. */
if(TermoSW)
{
if(cownt_one_canal==COUNT_DISCHARGE)
@@ -265,11 +309,12 @@ interrupt void adc_isr(void)
if(TermoAD)
{
if(cownt_cans == TPL_CANS ) code_tpl_canal = TERMOPAIR-1;
if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2; // ïîòîìó ÷òî 300 è 400 íàîáîðîò
if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2; // потому что 300 и 400 наоборот
}
select_tpl_canal(code_tpl_canal);
}
/* Отсчёты до окончания переходного процесса намеренно отбрасываются. */
if(cownt_one_canal > COUNT_TRANSICIA)
for(i=0;i<TermoSW;i++)
{
@@ -277,6 +322,7 @@ interrupt void adc_isr(void)
Temper = *(&AdcRegs.ADCRESULT0 + i) >>4;
/* Ограничитель защищает рекурсивный фильтр от одиночного выброса. */
ok = abs(ADC_table[n]-Temper) < FILTER_CLIP;
if(ok) cwnt_ok[i]++;
@@ -325,6 +371,7 @@ for(i=0;i<1;i++)
fin:
/* Единая эпилоговая секция обязательна и после goto при READY == 0. */
// Reinitialize for next ADC sequence
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit

View File

@@ -1,3 +1,13 @@
/**
* @file DAC.c
* @brief Управление внешним ЦАП и формирование аналогового задания нагрузки.
*
* Формирует последовательный поток через GPIO, рассчитывает временные интервалы
* относительно READY_FREQ и выдаёт нормированное значение Anal_output().
* Линии CLK/CS/DATA управляются непосредственно, поэтому порядок переключений
* и программные задержки являются частью аппаратного протокола и не должны
* переставляться без проверки осциллографом.
*/
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
#include "filter_bat2.h"
@@ -21,6 +31,10 @@ unsigned long WAKEpowse;
unsigned long IMPowse;
unsigned int period_dac, time_dac;
/**
* @brief Переводит физические интервалы профиля нагрузки в тики READY_FREQ.
* @post Обновлены WAKEpowse, period_dac и time_dac.
*/
void Setup_DAC_time(void)
{
WAKEpowse = 3L * DAC_FREQ +1;
@@ -29,12 +43,14 @@ void Setup_DAC_time(void)
time_dac = LOAD_TIME * DAC_FREQ;
}
/** @brief Устанавливает логический уровень последовательной линии DATA ЦАП. */
void dOUT(int x)
{
if(x) GpioDataRegs.GPBSET.bit.GPIO60=1;
else GpioDataRegs.GPBCLEAR.bit.GPIO60=1;
}
/** @brief Формирует короткую аппаратно-зависимую задержку между фронтами GPIO. */
void wast()
{
int i;
@@ -42,6 +58,11 @@ void wast()
for(i=0;i<25;i++);
}
/**
* @brief Последовательно передаёт одно управляющее слово во внешний ЦАП.
* @param word Слово протокола, выдаваемое по DATA синхронно с CLK.
* @note CS и CLK переключаются программно; порядок фронтов менять нельзя.
*/
void dSEND(unsigned int word)
{
int i;
@@ -57,12 +78,20 @@ void dSEND(unsigned int word)
dCS_1();
}
/** @brief Устанавливает CS, CLK и DATA в безопасные уровни ожидания. */
void Init_DAC(void)
{
dSEND(0x9002|0x0000);
toggle_RES_OUT_1();
}
/**
* @brief Масштабирует прикладное задание и отправляет код во внешний ЦАП.
* @param vrot Требуемое значение в прикладных единицах.
* @param maxx Значение полной шкалы; должно быть больше нуля.
* @details Результат ограничивается аппаратным диапазоном перед формированием
* управляющего слова, поэтому выход не переполняется при завышенном задании.
*/
void Anal_output(long vrot, long maxx)
{
long out;
@@ -70,7 +99,7 @@ void Anal_output(long vrot, long maxx)
out = DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ;
x=0;// !x; òùåòíî áûòèå
x=0;// !x; тщетно бытие
if(cCalibrDac) out=DAC_cal();
@@ -99,11 +128,14 @@ Log_to_mem(modbus[0x1D]);
}
/**
* @brief Выполняет очередной шаг временного профиля аналоговой нагрузки.
* @details Использует IMPowse как фазу профиля и на границах интервалов
* выбирает новое задание, передаваемое через Anal_output().
*/
void Load_runner()
{
static unsigned int count_dac=0, count_load=0, x=1;
static unsigned int preStart=0;
static float dac_go,dac_stop;
float sinus=0;
int kod;
@@ -130,23 +162,12 @@ void Load_runner()
{
if(cUMPstart)
{
if(!preStart)
{
dac_go=DAC_go-4;
dac_stop=DAC_stop-4;
if(dac_go<0) dac_go=0;
if(dac_go>5) dac_go=5;
if(dac_stop>16) dac_stop=16;
if(dac_stop<=dac_go) dac_stop=dac_go+1;
}
if(count_load > (time_dac/2))count_load++;
if(++count_load > time_dac) count_load = time_dac;
sinus = ((dac_stop - dac_go) / 16.0 * count_load) + (dac_go / 16.0 * time_dac);
// sinus = (10.0 / 16.0 * count_load) + (2.0 / 16.0 * time_dac);
// sinus = ((float)(DAC_stop - DAC_go) / 16.0 * count_load) + ((float)(DAC_go - 4.0) / 16.0 * time_dac);
sinus = (10.0 / 16.0 * count_load) + (2.0 / 16.0 * time_dac);
}
else
{ count_load = 0;
@@ -154,8 +175,6 @@ void Load_runner()
x = (x+1)&0x3FF;
}
preStart = cUMPstart;
if(!x || cInitDac)
{
Init_DAC(); x=1; cInitDac=0;

View File

@@ -1,8 +1,18 @@
/**
* @file ADC.h
* @brief Публичный интерфейс подсистемы АЦП.
*
* Экспортирует таблицы последних/накопленных отсчётов и временные признаки,
* обновляемые ADC.c. Размеры массивов определены реализацией и аппаратной
* разводкой; потребители должны использовать только известные индексы каналов.
*/
extern Uint16 adc_table_lem[];
extern Uint16 ADC_table[];
/** Инициализирует тактирование, последовательность каналов и прерывание АЦП. */
void setup_adc(void);
/** Счётчик активности и его порог, используемые для контроля измерительного цикла. */
extern long WAKE,WAKE_TIME;

View File

@@ -1,7 +1,23 @@
/**
* @file DAC.h
* @brief Интерфейс внешнего ЦАП и генератора задания нагрузки.
*
* Перед первым выводом требуется Init_DAC() и Setup_DAC_time(). Значение
* Anal_output() масштабируется относительно maxx; maxx должен быть положительным.
*/
/** Выполняет очередной шаг временного профиля аналогового выхода нагрузки. */
void Load_runner(void);
/**
* Выдаёт нормированное значение на ЦАП.
* @param vrot Требуемая величина выхода.
* @param maxx Полная шкала; должна быть больше нуля.
*/
void Anal_output(long vrot, long maxx);
/** Переводит линии внешнего ЦАП в исходное состояние. */
void Init_DAC(void);
/** Пересчитывает интервалы ЦАП из READY_FREQ, DAC_FREQ и LOAD_TIME. */
void Setup_DAC_time(void);
/** Внутренние счётчики профиля, обновляемые DAC.c. */
extern unsigned long IMPowse;
extern unsigned int period_dac, time_dac;

View File

@@ -1,3 +1,12 @@
/**
* @file GPIO_table.h
* @brief Таблицы направления и мультиплексирования GPIO для вариантов плат.
*
* Макросы сгруппированы по аппаратным исполнениям и напрямую соответствуют
* выводам разъёмов. Значения 0/1 кодируют вход/выход либо выбранную функцию MUX.
* Любое изменение требует сверки со схемой конкретной платы и package.h;
* этот заголовок содержит конфигурацию, а не переносимую логику GPIO.
*/
#define COMM_gpio00_dir 0UL
#define COMM_gpio01_dir 0UL
#define COMM_gpio02_dir 0UL
@@ -11,7 +20,7 @@
#define COMM_gpio10_dir 0UL
#define COMM_gpio11_dir 0UL
#define COMM_gpio19_dir 1UL // 63 — SPI
#define COMM_gpio19_dir 1UL // 63 — SPI
#define COMM_gpio20_dir 0UL // 64 2:9B mode 2
#define COMM_gpio21_dir 0UL // 65 2:9A mode 4
#define COMM_gpio22_dir 0UL // 66 2:12C mode 1
@@ -23,7 +32,7 @@
#define COMM_gpio32_dir 1UL // 74 2:10B DIOD green
#define COMM_gpio33_dir 0UL
#define COMM_gpio34_dir 1UL // 142 — SCI
#define COMM_gpio34_dir 1UL // 142 — SCI
#define COMM_gpio48_dir 1UL // 88 2:14C DIOD red
#define COMM_gpio49_dir 1UL // 89 2:14B select
@@ -54,7 +63,7 @@
#define BKSD_gpio10_dir 0UL // 19 2:6C oil
#define BKSD_gpio11_dir 1UL // 20 2:3C select
#define BKSD_gpio19_dir 1UL // 63 — SPI
#define BKSD_gpio19_dir 1UL // 63 — SPI
#define BKSD_gpio20_dir 0UL // 64 2:9B mode 2
#define BKSD_gpio21_dir 0UL // 65 2:9A mode 4
#define BKSD_gpio22_dir 0UL // 66 2:12C mode 1
@@ -66,7 +75,7 @@
#define BKSD_gpio32_dir 1UL // 74 2:10B DIOD green
#define BKSD_gpio33_dir 0UL
#define BKSD_gpio34_dir 1UL // 142 — SCI
#define BKSD_gpio34_dir 1UL // 142 — SCI
#define BKSD_gpio48_dir 1UL // 88 2:14C DIOD red
#define BKSD_gpio49_dir 0UL // 89 2:14B input 2
@@ -97,7 +106,7 @@
#define BKST_gpio10_dir 0UL
#define BKST_gpio11_dir 1UL // 20 2:3C select
#define BKST_gpio19_dir 1UL // 63 — SPI
#define BKST_gpio19_dir 1UL // 63 — SPI
#define BKST_gpio20_dir 0UL // 64 2:9B mode 2
#define BKST_gpio21_dir 0UL // 65 2:9A mode 4
#define BKST_gpio22_dir 0UL // 66 2:12C mode 1
@@ -109,7 +118,7 @@
#define BKST_gpio32_dir 1UL // 74 2:10B DIOD green
#define BKST_gpio33_dir 0UL
#define BKST_gpio34_dir 1UL // 142 — SCI
#define BKST_gpio34_dir 1UL // 142 — SCI
#define BKST_gpio48_dir 1UL // 88 2:14C DIOD red
#define BKST_gpio49_dir 0UL
@@ -140,7 +149,7 @@
#define PULT_gpio10_dir 0UL
#define PULT_gpio11_dir 0UL
#define PULT_gpio19_dir 1UL // 63 — SPI
#define PULT_gpio19_dir 1UL // 63 — SPI
#define PULT_gpio20_dir 0UL // 64 2:9B mode 2
#define PULT_gpio21_dir 0UL // 65 2:9A mode 4
#define PULT_gpio22_dir 0UL // 66 2:12C mode 1
@@ -152,7 +161,7 @@
#define PULT_gpio32_dir 1UL // 74 2:10B DIOD green
#define PULT_gpio33_dir 0UL
#define PULT_gpio34_dir 1UL // 142 — SCI
#define PULT_gpio34_dir 1UL // 142 — SCI
#define PULT_gpio48_dir 1UL // 88 2:14C DIOD red
#define PULT_gpio49_dir 0UL // 89 2:14B button
@@ -183,7 +192,7 @@
#define PLT2_gpio10_dir 0UL
#define PLT2_gpio11_dir 0UL
#define PLT2_gpio19_dir 1UL // 63 × SPI
#define PLT2_gpio19_dir 1UL // 63 Ч SPI
#define PLT2_gpio20_dir 0UL // 64 2:9B mode 2
#define PLT2_gpio21_dir 0UL // 65 2:9A mode 4
#define PLT2_gpio22_dir 0UL // 66 2:12C mode 1
@@ -195,7 +204,7 @@
#define PLT2_gpio32_dir 1UL // 74 2:10B DIOD green
#define PLT2_gpio33_dir 0UL // 75 2:10C button
#define PLT2_gpio34_dir 1UL // 142 × SCI
#define PLT2_gpio34_dir 1UL // 142 Ч SCI
#define PLT2_gpio48_dir 0UL // 88 2:14C button
#define PLT2_gpio49_dir 0UL // 89 2:14B button
@@ -226,7 +235,7 @@
#define SHKF_gpio10_dir 0UL // 19 2:6C input
#define SHKF_gpio11_dir 0UL // 20 2:3C input
#define SHKF_gpio19_dir 1UL // 63 — SPI
#define SHKF_gpio19_dir 1UL // 63 — SPI
#define SHKF_gpio20_dir 0UL // 64 2:9B mode 2
#define SHKF_gpio21_dir 0UL // 65 2:9A mode 4
#define SHKF_gpio22_dir 0UL // 66 2:12C mode 1
@@ -238,7 +247,7 @@
#define SHKF_gpio32_dir 0UL // 74 2:10B input
#define SHKF_gpio33_dir 0UL // 75 2:10C input
#define SHKF_gpio34_dir 1UL // 142 — SCI
#define SHKF_gpio34_dir 1UL // 142 — SCI
#define SHKF_gpio48_dir 1UL // 88 2:14C DIOD red
#define SHKF_gpio49_dir 0UL // 89 2:14B input
@@ -269,7 +278,7 @@
#define LOAD_gpio10_dir 0UL
#define LOAD_gpio11_dir 0UL // 20 2:3C res_in 0
#define LOAD_gpio19_dir 1UL // 63 — SPI
#define LOAD_gpio19_dir 1UL // 63 — SPI
#define LOAD_gpio20_dir 0UL // 64 2:9B mode 2
#define LOAD_gpio21_dir 0UL // 65 2:9A mode 4
#define LOAD_gpio22_dir 0UL // 66 2:12C mode 1
@@ -281,7 +290,7 @@
#define LOAD_gpio32_dir 1UL // 74 2:10B DIOD green
#define LOAD_gpio33_dir 0UL
#define LOAD_gpio34_dir 1UL // 142 — SCI
#define LOAD_gpio34_dir 1UL // 142 — SCI
#define LOAD_gpio48_dir 1UL // 88 2:14C DIOD red
#define LOAD_gpio49_dir 0UL

View File

@@ -1,11 +1,20 @@
/**
* @file RS485.h
* @brief Состояние портов SCI/RS-485, ограничения буферов и API обмена.
*
* RS_DATA объединяет регистры SCI, буферы, счётчики и состояние конечного
* автомата. Память буферов принадлежит вызывающему коду и должна оставаться
* доступной до завершения операции. MAX_RECEIVE_LENGTH/MAX_SEND_LENGTH задают
* жёсткую границу, которую необходимо проверить до помещения данных в буфер.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
RS485.h
****************************************************************
* Процедуры работы с UART *
* Процедуры работы с UART *
****************************************************************/
#ifndef _RS485
#define _RS485
@@ -38,30 +47,30 @@ typedef struct
{
volatile struct SCI_REGS *SciRegs;
unsigned int commnumber; // Номер порта
unsigned long RS_Length; // Длина пакета
unsigned int commnumber; // Номер порта
unsigned long RS_Length; // Длина пакета
unsigned int *pRS_RecvPtr; // Буфер приема
unsigned int *pRS_SendPtr; // Буфер посылки
unsigned int *pRS_RecvPtr; // Буфер приема
unsigned int *pRS_SendPtr; // Буфер посылки
unsigned int *pRecvPtr;
unsigned int RS_PrevCmd; // Предыдущаа комманда
unsigned int RS_Cmd; // Текущаа комманда
unsigned int RS_Header[MAX_RECEIVE_LENGTH]; // Заголовок
unsigned int flag_TIMEOUT_to_Send; // Флаг ожиданиа таймаута на отсылку
unsigned int flag_TIMEOUT_to_Receive; // Флаг ожиданиа таймаута на прием
unsigned int RS_DataReady; // Флаг готовности RS данных
unsigned int buffer[MAX_SEND_LENGTH]; // Буфер дла отсылки по RS
unsigned int RS_PrevCmd; // Предыдущаа комманда
unsigned int RS_Cmd; // Текущаа комманда
unsigned int RS_Header[MAX_RECEIVE_LENGTH]; // Заголовок
unsigned int flag_TIMEOUT_to_Send; // Флаг ожиданиа таймаута на отсылку
unsigned int flag_TIMEOUT_to_Receive; // Флаг ожиданиа таймаута на прием
unsigned int RS_DataReady; // Флаг готовности RS данных
unsigned int buffer[MAX_SEND_LENGTH]; // Буфер дла отсылки по RS
unsigned int addr_answer; // адрес куда отвечать в режиме ведущего
unsigned int addr_recive; // адрес по которому нас запросили
unsigned int flag_LEADING; // Флаг режима контроллера (по умолчанию ведомый)
unsigned int addr_answer; // адрес куда отвечать в режиме ведущего
unsigned int addr_recive; // адрес по которому нас запросили
unsigned int flag_LEADING; // Флаг режима контроллера (по умолчанию ведомый)
unsigned long RS_RecvLen;
unsigned long RS_SLength; // Длина пакета дла посылки
unsigned long RS_SendLen; // Количество байт уже передали
char RS_SendBlockMode; // Режим передачи
char RS_Flag9bit; // дла RS485????????
int BS_LoadOK; // Флаг успешности приема блока
unsigned long RS_SLength; // Длина пакета дла посылки
unsigned long RS_SendLen; // Количество байт уже передали
char RS_SendBlockMode; // Режим передачи
char RS_Flag9bit; // дла RS485????????
int BS_LoadOK; // Флаг успешности приема блока
int RS_FlagBegin;
int RS_HeaderCnt;
int RS_FlagSkiping;
@@ -73,61 +82,72 @@ typedef struct
extern RS_DATA rs_a,rs_b;
extern unsigned int
RS_Len[70]; /* Действительнаа длина команды (отладочной) + 1 */
RS_Len[70]; /* Действительнаа длина команды (отладочной) + 1 */
/** ISR приёма и передачи SCI-A/SCI-B; вызывают общий автомат соответствующего порта. */
interrupt void RSA_RX_Handler(void);
interrupt void RSA_TX_Handler(void);
interrupt void RSB_RX_Handler(void);
interrupt void RSB_TX_Handler(void);
/* иницилизациа переменных rs_a,rs_b*/
/* иницилизациа переменных rs_a,rs_b*/
/** Создаёт исходное состояние обоих RS_DATA и задаёт размер команды 15. */
void create_uart_vars(char size_cmd15);
/** Повторнаа инициализациа последовательного порта, используетса после подвиса */
/** Настройка режима приема/передачи */
/** Повторнаа инициализациа последовательного порта, используетса после подвиса */
/** Настройка режима приема/передачи */
void RS_SetBitMode(RS_DATA *rs_arr, int n);
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество байт
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param rs_arr Состояние выбранного порта.
@param pBuf Адрес массива слов, каждое из которых содержит один байт.
@param len количество байт
@return Ненулевое значение, если передача принята драйвером.
@see RS_BSend, RS_TRANSMIT_INTR
*/
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len);
/** Посылка блока упакованных байтов.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество 8-битных байт
/** Посылка блока упакованных байтов.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param rs_arr Состояние выбранного порта.
@param pBuf Адрес массива с упакованными байтами.
@param len количество 8-битных байт
@return Ненулевое значение, если передача принята драйвером.
@see RS_Send, RS_TRANSMIT_INTR
*/
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len);
/** Инициализациа последовательного порта */
void setup_uart(char commnumber,unsigned long speed_baud); /* speed_baud - скорость линии в бодах */
/** Инициализациа последовательного порта */
/** @param commnumber COM_1 или COM_2. @param speed_baud Скорость линии в бодах. */
void setup_uart(char commnumber,unsigned long speed_baud); /* speed_baud - скорость линии в бодах */
/** Настраивает число бит данных, чётность и число стоп-битов выбранного SCI. */
void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop);
/** Меняет скорость уже созданного порта и обновляет curr_baud. */
void RS_SetLineSpeed(RS_DATA *rs_arr, unsigned long speed);
// Transmit a character from the SCI'
#define SCI_send(x,y) x->SciRegs->SCITXBUF=(unsigned char)(y)
// Ожидание завершениа передачи UART
// Ожидание завершениа передачи UART
// wait for TRDY =1 for empty state
#define RS_Wait4OK(x) while(!(x->SciRegs->SCICTL2.bit.TXEMPTY))
/** Переключение линии на прием */
/** Переключение линии на прием */
#define RS_Line_to_receive(x) if(x->commnumber==COM_2) GpioDataRegs.GPBDAT.bit.GPIO34 = 1;
/** Переключение линии на передачу */
/** Переключение линии на передачу */
#define RS_Line_to_send(x) if(x->commnumber==COM_2) GpioDataRegs.GPBDAT.bit.GPIO34 = 0;
/** Разрешение прерываний по получению символа и ошибкам от UART */
/** Разрешение прерываний по получению символа и ошибкам от UART */
#define enableUARTInt(x) x->SciRegs->SCICTL2.all=2
#define enableUARTIntW(x) x->SciRegs->SCICTL2.all=1
/** Сбрасывает таймер контроля активности после корректного обмена. */
void clear_timer_rs_live(RS_DATA *rs_arr);
/** Обновляет признак потери связи по тайм-ауту RS_TIME_OUT. */
void test_rs_live(RS_DATA *rs_arr);
#ifdef __cplusplus

View File

@@ -1,11 +1,19 @@
/**
* @file bios_dsp.h
* @brief Команды сервисного BIOS и API удалённой работы с памятью.
*
* Объявляет номера команд загрузчика и обработчики, работающие с RS_DATA.
* Интерфейс предоставляет прямые операции с адресным пространством DSP и
* предназначен только для доверенных, уже проверенных протокольных запросов.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************/
/* Bios_dsp.h */
/****************************************************************/
/* Основные комманды BIOS */
/* Основные комманды BIOS */
/****************************************************************/
#ifndef _BIOS_DSP
#define _BIOS_DSP
@@ -42,71 +50,85 @@ enum {
CMD_VECTOR=61,
CMD_IMPULSE,
/* стандартные команды */
/* стандартные команды */
CMD_STD=65, CMD_STD_ANS
};
enum {false=0, true};
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
/** Проверяет кадр и выполняет содержащуюся в нём сервисную команду. */
int get_command(RS_DATA *rs_arr);
/** Стандартный ответ, без параметров */
/** Стандартный ответ, без параметров */
/** Формирует и отправляет ответ длиной n слов через заданный порт. */
void Answer(RS_DATA *rs_arr,int n);
/* начальные установки (не работает)*/
/* начальные установки (не работает)*/
/** Сбрасывает состояние текущей сессии загрузчика. */
void init(RS_DATA *rs_arr);
/**@name Комманды
* Комманды, вызываемые через последовательный канал*/
/**@name Комманды
* Комманды, вызываемые через последовательный канал*/
//@{
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/** Подготавливает диапазон памяти к приёму нового образа. */
void initload(RS_DATA *rs_arr);
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/** Записывает очередной проверенный блок образа в память. */
void load(RS_DATA *rs_arr);
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
@see load */
/** Передаёт управление по адресу, заданному сервисной командой. */
void run (RS_DATA *rs_arr);
/** Прочитать ачейку памати */
/** Прочитать ачейку памати */
/** Читает запрошенный диапазон памяти и возвращает его ведущему узлу. */
void peek(RS_DATA *rs_arr);
/** Записать в ачейку памати */
/** Записать в ачейку памати */
/** Записывает одно или несколько слов по адресу из команды. */
void poke(RS_DATA *rs_arr);
/** Передать блок памати */
/** Передать блок памати */
/** Передаёт ведущему узлу очередной блок содержимого памяти. */
void upload(RS_DATA *rs_arr);
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
@see load */
/** Обрабатывает команду доступа к внешней Flash-памяти. */
void xflash(RS_DATA *rs_arr);
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
/** Обрабатывает команду доступа к целевой Flash-памяти. */
void tflash(RS_DATA *rs_arr);
/* расширенные команды дла биоса */
/* расширенные команды дла биоса */
/** Обрабатывает расширенную сервисную команду BIOS. */
void extendbios(RS_DATA *rs_arr);
/** Записывает слово по физическому адресу; адрес обязан быть допустимым. */
void write_memory(unsigned long addr, unsigned int data);
/** Читает слово по физическому адресу; адрес обязан быть допустимым. */
unsigned int read_memory(unsigned long addr);

View File

@@ -1,22 +1,31 @@
/**
* @file caliber.h
* @brief Заводские калибровочные таблицы для вариантов семейства Balsam.
*
* Ровно одна таблица def_cal включается по значению BALSAM. Строки и столбцы
* имеют фиксированный смысл для измерительных каналов и диапазонов; их порядок
* согласован с message.c и внешней методикой калибровки. Файл определяет данные,
* поэтому должен подключаться только одним модулем реализации.
*/
#if BALSAM == 167 //-------------------------------------------------------------
int def_cal[][8] = {
// ÁÊÑÑ òðàíñ 100 1 100 2 150 1 150 2
0, 0, 0, 0, 455, 441, 2459, 2392, // Áîðò 0
0, 0, 0, 0, 462, 439, 2442, 2400, // Áîðò 1
// БКСС транс 100 1 100 2 150 1 150 2
0, 0, 0, 0, 455, 441, 2459, 2392, // Борт 0
0, 0, 0, 0, 462, 439, 2442, 2400, // Борт 1
// Ñèëîâîé UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
4936, 4877, 4972, 4857, 1886, 1898, 2517, 2535, // Áîðò 0
4876, 5005, 4876, 4847, 1898, 1873, 2535, 2502, // Áîðò 1
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
4936, 4877, 4972, 4857, 1886, 1898, 2517, 2535, // Борт 0
4876, 5005, 4876, 4847, 1898, 1873, 2535, 2502, // Борт 1
// ÓÌÏ UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3820, 3790, 3505, 3380, 1736, 683, 854, 14, // Áîðò 0 1062 1980
3835, 3785, 3522, 3332, 1745, 689, 860, 17, // Áîðò 1 1720 2405
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3820, 3790, 3505, 3380, 1736, 683, 854, 14, // Борт 0 1062 1980
3835, 3785, 3522, 3332, 1745, 689, 860, 17, // Борт 1 1720 2405
// ÁÊÑÑÄ 100 Ohm 150 Ohm
// БКССД 100 Ohm 150 Ohm
1281, 1272, 0, 0, 622, 2263, 0, 0,
// ÂÝÏ 380Ô1 380Ô2 300 1 300 2 400 1 400 2
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
1290, 1285, 0, 0, 2045, 2045, 2725, 2725 };
#endif //---------------------------------------------------------------------
@@ -24,45 +33,45 @@
#if BALSAM == 166 //-------------------------------------------------------------
int def_cal[][8] = {
// Ñèëîâîé UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
4936, 4877, 4972, 4857, 1960, 1920, 2610, 2570, // Áîðò 0
4876, 5005, 4876, 4847, 1950, 1965, 2600, 2615, // Áîðò 1
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
4936, 4877, 4972, 4857, 1960, 1920, 2610, 2570, // Борт 0
4876, 5005, 4876, 4847, 1950, 1965, 2600, 2615, // Борт 1
// ÓÌÏ UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3820, 3790, 3505, 3380, 1718, 673, 854, 14, // Áîðò 0
3835, 3785, 3522, 3332, 1697, 653, 860, 17, // Áîðò 1
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3820, 3790, 3505, 3380, 1718, 673, 854, 14, // Борт 0
3835, 3785, 3522, 3332, 1697, 653, 860, 17, // Борт 1
// ÂÝÏ 380Ô1 380Ô2 300 1 300 2 400 1 400 2
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
1281, 1272, 0, 0, 2049, 2050, 2749, 2750 };
#endif //---------------------------------------------------------------------
#if BALSAM == 165 //-------------------------------------------------------------
int def_cal[][8] = {
// Ñèëîâîé UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
5130, 4960, 4925, 5070, 1881, 1881, 2506, 2516, // Áîðò 0
5020, 5040, 4950, 5030, 1871, 1879, 2507, 2514, // Áîðò 1
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
5130, 4960, 4925, 5070, 1881, 1881, 2506, 2516, // Борт 0
5020, 5040, 4950, 5030, 1871, 1879, 2507, 2514, // Борт 1
// ÓÌÏ UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3890, 3865, 5100, 4850, 1730, 675, 854, 14, // Áîðò 0
3845, 3800, 3250, 3100, 1044, 0, 860, 17, // Áîðò 1
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3890, 3865, 5100, 4850, 1730, 675, 854, 14, // Борт 0
3845, 3800, 3250, 3100, 1044, 0, 860, 17, // Борт 1
// ÂÝÏ 380Ô1 380Ô2 300 1 300 2 400 1 400 2
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
1289, 1280, 0, 0, 2073, 2071, 2773, 2771 };
#endif //---------------------------------------------------------------------
#if BALSAM == 164 //-------------------------------------------------------------
int def_cal[][8] = {
// Ñèëîâîé UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
7573, 7573, 7573, 7573, 1979, 1888, 2592, 2513, // Áîðò 0
7573, 7573, 7573, 7573, 1970, 1907, 2584, 2558, // Áîðò 1
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
7573, 7573, 7573, 7573, 1979, 1888, 2592, 2513, // Борт 0
7573, 7573, 7573, 7573, 1970, 1907, 2584, 2558, // Борт 1
// ÓÌÏ UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3920, 3905, 3300, 3220, 1015, 0, 854, 14, // Áîðò 0
3835, 3785, 5100, 4600, 1750, 680, 860, 17, // Áîðò 1
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
3920, 3905, 3300, 3220, 1015, 0, 854, 14, // Борт 0
3835, 3785, 5100, 4600, 1750, 680, 860, 17, // Борт 1
// ÂÝÏ 380Ô1 380Ô2 300 1 300 2 400 1 400 2
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
1266, 1267, 0, 0, 2063, 2040, 2678, 2655 };
#endif //---------------------------------------------------------------------
@@ -71,15 +80,15 @@
#if PXXXXX == 1 //-------------------------------------------------------------
int def_cal[][6] = {
// Ñèëîâîé UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Áîðò 0
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Áîðò 1
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Борт 0
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Борт 1
// ÓÌÏ UA UC IA IC 20mA 4mA
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Áîðò 0
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Áîðò 1
// УМП UA UC IA IC 20mA 4mA
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Борт 0
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Борт 1
// ÂÝÏ 380Ô1 380Ô2 300 1 300 2 400 1 400 2
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
1270, 1270, 0, 0, 1950, 1950, 2600, 2600 };
#endif //---------------------------------------------------------------------
*/

View File

@@ -1,11 +1,18 @@
/**
* @file cntrl_adr.h
* @brief Адреса узла в сервисном протоколе и функция их установки.
*
* Константные адреса задают специальные роли, CNTRL_ADDR и ADDR_FOR_ALL могут
* меняться во время настройки. Заголовок не выполняет валидацию диапазонов.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
cntrl_adr.h
****************************************************************
* Адрес контроллера *
* Адрес контроллера *
****************************************************************/
#ifndef _CNTRL_ADR
@@ -15,22 +22,26 @@
extern "C" {
#endif
/** адрес контроллера дла посылки всем АИНам */
/** адрес контроллера дла посылки всем АИНам */
extern int ADDR_FOR_ALL;
/** адрес контроллера дла посылки ответа */
/** адрес контроллера дла посылки ответа */
extern const int ADDR_ANSWER;
/** адреса терминала дла посылки ответа */
/** адреса терминала дла посылки ответа */
extern const int ADDR_TERMINAL;
/* Адрес контроллера */
/* Адрес контроллера */
extern int CNTRL_ADDR;
/* Универсальный адрес контроллера */
/* Универсальный адрес контроллера */
extern const int CNTRL_ADDR_UNIVERSAL;
/** Установка адреса контроллера дла прошивки */
/** Установка адреса контроллера дла прошивки */
/**
* @param cntrl_addr Новый индивидуальный адрес узла.
* @param cntrl_addr_for_all Новый адрес групповых команд.
*/
void set_cntrl_addr (int cntrl_addr,int cntrl_addr_for_all);

View File

@@ -1,8 +1,20 @@
/**
* @file crc16.h
* @brief Интерфейс алгоритмов CRC, используемых коммуникационными модулями.
*
* Буфер представлен словами целевого DSP; параметр size трактуется реализацией
* как число обрабатываемых элементов. Вызывающий код выбирает вариант CRC и
* передаёт требуемое протоколом начальное значение.
*/
typedef unsigned short WORD;
typedef unsigned char byte;
/** Вычисляет CRC-CCITT для size слов, продолжая переданное значение crc. */
unsigned int get_crc_ccitt(unsigned int crc, unsigned int *buf, unsigned long size );
/** Вычисляет табличный CRC-16 (полином 0xA001) для size слов. */
unsigned int get_crc_16(unsigned int crc,unsigned int *buf,unsigned long size );
/** Вычисляет побитовый вариант CRC-16 для проверки табличной реализации. */
unsigned int get_crc_16b(unsigned int crc,unsigned int *buf,unsigned long size );
/** Возвращает CRC-16 кадра с принятым в проекте начальным значением. */
int get_crc16(unsigned int *buf, int size );

View File

@@ -1,3 +1,22 @@
/**
* @file ecan.h
* @brief Минимальный публичный интерфейс обмена по CAN.
*
* Port выбирает аппаратный контроллер, DevNum/Addr определяют логический узел.
* Массив данных должен содержать формат кадра, ожидаемый реализацией ecan.c.
*/
/**
* Настраивает CAN-порт и почтовые ящики логического устройства.
* @param Port Номер аппаратного CAN-контроллера.
* @param DevNum Номер узла; реализация ограничивает его диапазоном 1..16.
*/
void InitCan(int Port, int DevNum);
/**
* Ставит прикладные данные в передающий mailbox.
* @param Port Номер аппаратного CAN-контроллера.
* @param data Массив слов кадра в формате проекта.
* @param Addr Адрес получателя.
*/
void CAN_send(int Port, int data[], int Addr);
/** Последние прикладные слова, принятые обработчиком CAN. */
extern int CAN_input_data[];

View File

@@ -1,3 +1,11 @@
/**
* @file filter_bat2.h
* @brief Коэффициенты и состояние рекурсивного НЧ-фильтра второго порядка.
*
* Наборы K*_FILTER_BATTER2_* рассчитаны для заданных частот среза при штатной
* частоте дискретизации. DEF_FILTERBAT создаёт нулевое состояние для 3 Гц;
* один экземпляр FILTERBAT нельзя одновременно использовать для разных каналов.
*/
#ifndef _FILTER_BAT2
#define _FILTER_BAT2
@@ -38,6 +46,12 @@ typedef struct { float k_0;
K3_FILTER_BATTER2_3HZ, \
0,0,0,0,0,0}
/**
* Выполняет один шаг фильтра и обновляет его историю на месте.
* @param b Уникальное состояние фильтра конкретного канала.
* @param InpVarCurr Текущий входной отсчёт.
* @return Новый фильтрованный отсчёт.
*/
float filterbat(FILTERBAT *b, float InpVarCurr);

View File

@@ -1 +1,13 @@
/**
* @file kanal.h
* @brief Интерфейс вывода значения на адресуемый канальный индикатор.
*
* adr выбирает индикатор, dat содержит отображаемое число, dot — позицию точки.
*/
/**
* Передаёт число адресуемому индикатору.
* @param adr Аппаратный адрес канала.
* @param dat Отображаемое целое значение.
* @param dot Позиция десятичной точки в протокольном формате индикатора.
*/
void kanal_Send(int adr, long dat, int dot);

View File

@@ -1,11 +1,19 @@
/**
* @file log_to_mem.h
* @brief Разметка внешней памяти и состояние кольцевого журнала.
*
* LOG_PAGE_START и LOG_PAGE_LEN обязаны совпадать с картой линковщика. Флаги
* no_write/never_write запрещают запись на разных уровнях, а clear_mem()
* полностью обнуляет область и потому является длительной операцией.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2001г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2001г. */
/****************************************************************/
/* log_to_mem.h
****************************************************************
* Запись логов в памyть *
* Запись логов в памyть *
****************************************************************/
#ifndef _LOG_TO_MEM
@@ -15,11 +23,11 @@
extern "C" {
#endif
/* Определениa длa работы логгера */
/* Определениa длa работы логгера */
#define LOG_PAGE_START 0x0200000
#define LOG_PAGE_LEN 0xFA00
extern int no_write, never_write; // Флаги, чтобы не писать (если что)
extern int no_write, never_write; // Флаги, чтобы не писать (если что)
typedef struct
{
@@ -32,14 +40,15 @@ typedef struct
extern LOG Log;
/* Запись словa в памать, где логи лежат */
/* Запись словa в памать, где логи лежат */
#define Log_to_mem(x) *(int *)(Log.Adres++) = x
/* Проверка границы памати дла логов */
/* Проверка границы памати дла логов */
//#define Test_mem_limit(x) if(Log.Adres > (Log.Finis - (x))) Log.Adres = Log.Start
#define Test_mem_limit(x) if(Log.Adres > (Log.Finis - (x))) Log.Adres -=(x)
/* Очистка памати (обнуление) */
/* Очистка памати (обнуление) */
/** Полностью обнуляет область журнала и возвращает указатель записи в начало. */
void clear_mem();
#ifdef __cplusplus

View File

@@ -1,19 +1,41 @@
// âãâ
// вгв
#ifndef _MEASURE
#define _MEASURE
/**
* @file measure.h
* @brief Общие типы, состояния и API измерительно-диагностической подсистемы.
*
* Объявляет этапы обработки каналов, битовые флаги ошибок и разделяемые данные,
* используемые ISR, протоколом и главным циклом. Номера каналов и позиции битов
* являются частью внешнего формата сообщений; менять их независимо нельзя.
*/
/** ISR Timer1 для периодического запуска измерительных и диагностических этапов. */
interrupt void cpu_timer1_isr_SENS(void);
/** Инициализирует основные структуры, фильтры и состояния датчиков. */
void Init_sensors(void);
/** Выполняет дополнительную инициализацию, зависящую от типа платы. */
void Init_sensors_more(void);
/** Строит маски упаковки каналов для внешних сообщений. */
void Init_packMask(void);
/** Рассчитывает температуру канала; ovn выбирает источник/режим измерения. */
void Temper_count(int chan, int ovn);
/** Рассчитывает ток и обновляет диагностику заданного канала. */
void Current_count(int chan);
/** Рассчитывает электрическую мощность заданного канала. */
void Power_count(int chan);
/** Пересчитывает масштабные коэффициенты из калибровочных параметров. */
void calc_sensor_koef(void);
/** Обновляет признаки превышения допустимого напряжения. */
void Is_Voltage_Hi(void);
/** Пересчитывает пороги напряжения для текущего режима изделия. */
void calc_volta_edge(void);
/**
* Выполняет временную проверку порога ошибки.
* @return Ненулевое значение после требуемого числа последовательных нарушений.
*/
int er_anal(int term, unsigned int * count, long edge, int pre);
typedef union
@@ -64,14 +86,14 @@ typedef union
#define NOER 0xE000//C
#define EROR 0x01FF
#define READY_FREQ (500.0 * 2)// Ãö
#define BLINK_FREQ 2 // Ãö
#define READY_FREQ (500.0 * 2)// Гц
#define BLINK_FREQ 2 // Гц
#define BLINK_TIME (READY_FREQ / BLINK_FREQ)
#define CANPOWSE 20
#define ADC_FREQ 3750 //3885.0//777//2000//20000 //777 //3885 // Ãö (777*5)
#define DAC_FREQ 200//5 // Ãö
#define ADC_FREQ 3750 //3885.0//777//2000//20000 //777 //3885 // Гц (777*5)
#define DAC_FREQ 200//5 // Гц
#define LOAD_TIME 30//15 // sec
@@ -86,23 +108,23 @@ extern unsigned int Caliber_time;
#define ZERO 27
#define Cooling 5 // (°Ñ) Ãèñòåðåçèñ ïî ñíàòèþ ïåðåãðåâà
#define Cooling 5 // (°С) Гистерезис по снатию перегрева
#define COSPi6 0.86602540378443864676372317075294
#define RADIX2 1.4142135623730950488016887242097
#define POWER_380 0 // ïèòàíèå 380Â
#define POWER_38O 1 // ïèòàíèå 380Â
#define CURRENT 2 // òîê
#define VOLTAGE 3 // íàïðàæåíèå
#define POWER_31 4 // ïèòàíèå 31Â
#define POWER_27 5 // ïèòàíèå 24Â
#define POWER_24 6 // ïèòàíèå 24Â
#define POWER_15 7 // ïèòàíèå 15Â
#define TERMO_AD 8 // òåðìîäàò÷èê ìåëêîñõåìà
#define TERMO_RS 9 // òåðìîðåçèñòîð
#define TRM_OBEH 10 // òåðìîäàò÷èê îâåí
#define POWER_380 0 // питание 380В
#define POWER_38O 1 // питание 380В
#define CURRENT 2 // ток
#define VOLTAGE 3 // напражение
#define POWER_31 4 // питание 31В
#define POWER_27 5 // питание 24В
#define POWER_24 6 // питание 24В
#define POWER_15 7 // питание 15В
#define TERMO_AD 8 // термодатчик мелкосхема
#define TERMO_RS 9 // терморезистор
#define TRM_OBEH 10 // термодатчик овен
extern int TPL_CANS,tpl_cans;

View File

@@ -1,3 +1,11 @@
/**
* @file message.h
* @brief Форматы команд, размеры ответов и API обработки Modbus-сообщений.
*
* CMD_TO_TMS описывает точную раскладку принятого кадра, включая CRC. Поля и
* ANSWER_LEN/REPLY_LEN согласованы с удалённым мастером; структура использует
* целевые типы DSP, поэтому не должна сериализоваться простым memcpy на PC.
*/
#ifndef MESSAGE_H
#define MESSAGE_H
@@ -11,8 +19,8 @@ typedef unsigned char CHAR;
typedef struct
{
unsigned char Address; // Àäðåñ êîíòðîëëåðà
unsigned char Number; // Íîìåð êîìàíäû
unsigned char Address; // Адрес контроллера
unsigned char Number; // Номер команды
BAITE byte0;
BAITE byte1;
@@ -30,13 +38,20 @@ typedef struct
extern int modbus[];
/** Принимает запрос чтения регистров и подготавливает соответствующий ответ. */
void ReceiveCommandModbus3(RS_DATA *rs_arr);
/** Принимает запрос записи одного регистра и применяет разрешённый параметр. */
void ReceiveCommandModbus6(RS_DATA *rs_arr);
/** Отправляет текущий блок телеметрии ответом прикладной функции 4. */
void SendCommandModbus4(RS_DATA *rs_arr);
/** Разбирает ответ функции 4, полученный от ведомого устройства. */
void ReceiveAnswerModbus4(RS_DATA *rs_arr);
/** Сохраняет текущий массив параметров в EEPROM. */
void Save_params(void);
/** Загружает параметры из EEPROM и заменяет некорректные значения безопасными. */
void Load_params(void);
/** Заполняет параметры значениями для выбранного в package.h варианта платы. */
void Default_params(void);
#endif //MESSAGE_H

View File

@@ -1,3 +1,12 @@
/**
* @file package.h
* @brief Центральная конфигурация изделия Balsam и адресов его подсистем.
*
* Значение BALSAM выбирает аппаратный вариант, направление вращения и набор
* возможностей. adr_* и последующие константы связывают физические модули с
* протоколом и массивами измерений. Изменение этого файла влияет на всю прошивку
* и должно сопровождаться проверкой схемы, карты CAN/Modbus и калибровки.
*/
#ifndef PACKAGE
#define PACKAGE
@@ -91,15 +100,16 @@
#define bSecretBt Buttons.bit.bit1
#define bTermoCal Buttons.bit.bit2
// Ïðèøëî âðåìà!
#define DAC_go modbus[0x50] // íà÷àëî çàðàäà
#define DAC_stop modbus[0x51] // êîíåö çàðàäà
#define Cancount (modbus+0x60) // пауза между I посылками CAN
#define Bright (modbus+0x62) // аркость сигнальных лампочек
#define Brightness modbus[0x62] // аркость сигнальных лампочек
#define Cancount (modbus+0x60) // ïàóçà ìåæäó I ïîñûëêàìè CAN
#define Bright (modbus+0x62) // àðêîñòü ñèãíàëüíûõ ëàìïî÷åê
#define Brightness modbus[0x62] // àðêîñòü ñèãíàëüíûõ ëàìïî÷åê
#define Owncount modbus[0x63] // пауза между опросами OWEN
#define Owncount modbus[0x63] // ïàóçà ìåæäó îïðîñàìè OWEN
/* Не врема!
#define DAC_go modbus[0x64] // начало зарада
#define DAC_stop modbus[0x65] // конец зарада
*/
#define m_FAST 0
#define m_SLOW 1

View File

@@ -1,3 +1,12 @@
/**
* @file peripher.h
* @brief GPIO-примитивы и интерфейс определения аппаратного режима.
*
* Inline-функции учитывают различия разводки плат через глобальный Desk.
* Большинство выходов активны низким уровнем, поэтому set/clear не всегда
* совпадают с физическими SET/CLEAR регистрами. Desk должен быть определён
* get_Mode() до первого управления линиями.
*/
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
extern int Mode,Desk,TermoAD,TermoRS,TermoSW,Kurrent,Kalibro,Owen;

View File

@@ -1,3 +1,10 @@
/**
* @file pulto.h
* @brief Обработчик периодического таймера для режима пульта.
*
* Функция устанавливается в вектор Timer1 только для соответствующего Desk.
*/
//void what_is(void);
/** ISR таймера CPU1: обновляет индикацию и контроль связи в режиме пульта. */
interrupt void cpu_timer1_isr_PULT(void);

View File

@@ -1,3 +1,12 @@
/**
* @file spise2p.h
* @brief Конфигурация SPI EEPROM и структуры её конечного автомата.
*
* Определяет команды микросхемы, ширину адреса/данных, скорость SPI и состояния
* транзакции. SPISE2P_DRV_DEFAULTS создаёт единственный драйвер с callback-функциями;
* перед чтением или записью требуется InitSeeprom(), а диапазон операции должен
* оставаться внутри SEEPROM_LEN.
*/
/*=====================================================================
File name : SPISE2P.H
@@ -17,7 +26,7 @@ Date : 30/6/2003 (DD/MM/YYYY)
#define __SPISE2P_H__
// Ёмкость памати в байтах
// Ёмкость памати в байтах
#define SEEPROM_LEN 0x10000
#define NULL 0
@@ -90,13 +99,28 @@ typedef struct {
typedef SPISE2P_DRV *SPISE2P_DRV_handle;
/** Сбрасывает поля конечного автомата и конфигурирует SPI. */
void SPISE2P_DRV_init(SPISE2P_DRV * );
/** Продвигает конечный автомат EEPROM на один таймерный такт. */
void SPISE2P_DRV_tick(SPISE2P_DRV *);
/** Деактивирует аппаратный chip-select EEPROM. */
void SPISE2P_DRV_csset(void);
/** Активирует аппаратный chip-select EEPROM. */
void SPISE2P_DRV_csclr(void);
/** @return Ненулевое значение, когда драйвер готов принять новую операцию. */
unsigned int spiSe2pFree(SPISE2P_DRV *se2p);
/**
* Запускает асинхронную запись.
* @param se2p Экземпляр конечного автомата.
* @param msgPtr Описание адреса, буфера и длины блока.
*/
void spiSe2pWrite(SPISE2P_DRV *se2p, SE2P_DATA *data);
/**
* Запускает асинхронное чтение.
* @param se2p Экземпляр конечного автомата.
* @param msgPtr Описание адреса, буфера и длины блока.
*/
void spiSe2pRead(SPISE2P_DRV *se2p, SE2P_DATA *data);
#if(SPISE2P_DATA_WIDTH==SIXTEEN_BIT)
@@ -109,25 +133,27 @@ void spiSe2pRead(SPISE2P_DRV *se2p, SE2P_DATA *data);
#define WORD_LEN 1
#endif
/* Установка драйвера сериальной EEPROM. **
** Инициализациа SPI и проч. Также настройка таймера. **
** Драйвер работает на прерываниах от таймера 2! */
/* Установка драйвера сериальной EEPROM. **
** Инициализациа SPI и проч. Также настройка таймера. **
** Драйвер работает на прерываниах от таймера 2! */
void InitSeeprom(void);
/* Запись блока в SEEPROM. Параметры таковы: **
** adres - адрес в епромке, куда писать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, откуда писать. **
** size - длина блока в байтах. По-любому в байтах! */
/* Запись блока в SEEPROM. Параметры таковы: **
** adres - адрес в епромке, куда писать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, откуда писать. **
** size - длина блока в байтах. По-любому в байтах! */
/** @param size Размер блока в байтах, независимо от SPISE2P_DATA_WIDTH. */
void Seeprom_write(unsigned int adres, unsigned int buf[], unsigned int size);
/* Чтение блока из SEEPROM. Параметры таковы: **
** adres - адрес в епромке, откуда читать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, куда читать. **
** size - длина блока в байтах. По-любому в байтах! */
/* Чтение блока из SEEPROM. Параметры таковы: **
** adres - адрес в епромке, откуда читать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, куда читать. **
** size - длина блока в байтах. По-любому в байтах! */
/** @param size Размер блока в байтах, независимо от SPISE2P_DATA_WIDTH. */
void Seeprom_read(unsigned int adres, unsigned int buf[], unsigned int size);
#endif

View File

@@ -1,7 +1,18 @@
/**
* @file tools.h
* @brief Низкоуровневые вспомогательные функции платформы TMS320F28335.
*
* init_zone7() настраивает внешнюю шину, pause_us() выполняет активную задержку.
*/
#ifndef TOOLS_H
#define TOOLS_H
/** Настраивает 16-битную внешнюю шину XINTF Zone 7. */
void init_zone7(void);
/**
* Выполняет активную задержку.
* @param t Длительность в микросекундах при штатной частоте CPU.
*/
void pause_us(unsigned long t);
#endif //TOOLS_H

View File

@@ -1,11 +1,21 @@
/**
* @file RS485.c
* @brief Драйвер двух каналов SCI/RS-485 и автоматы приёма/передачи кадров.
*
* Настраивает SCI-A/SCI-B, обслуживает RX/TX-прерывания, контролирует длины
* команд и тайм-аут активности, а также переключает формат и скорость линии.
* RS_DATA содержит разделяемое состояние конечного автомата; буферы должны
* жить до завершения передачи и не превышать MAX_*_LENGTH. Обработчики обязаны
* подтверждать PIE и корректно возвращать приоритеты прерываний.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
RS485.с
RS485.с
****************************************************************
* Процедуры работы с UART *
* Процедуры работы с UART *
****************************************************************/
//#include "big_dsp_module.h"
@@ -32,7 +42,12 @@ static char size_cmd15=1;
void RS_RX_Handler(RS_DATA *rs_arr);
void RS_TX_Handler(RS_DATA *rs_arr);
/** Обработчик прерываний UART - принато */
/** Обработчик прерываний UART - принато */
/**
* @brief ISR приёма SCI-A.
* @details Временно ограничивает приоритеты группы PIE9, вызывает общий
* RS_RX_Handler() для rs_a, затем восстанавливает маску и подтверждает группу.
*/
interrupt void RSA_RX_Handler(void)
{
// Set interrupt priority:
@@ -51,6 +66,7 @@ interrupt void RSA_RX_Handler(void)
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** @brief ISR приёма SCI-B; адаптер общего автомата к состоянию rs_b. */
interrupt void RSB_RX_Handler(void)
{
// Set interrupt priority:
@@ -69,6 +85,7 @@ interrupt void RSB_RX_Handler(void)
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** @brief ISR освобождения TX SCI-A; продолжает передачу буфера rs_a. */
interrupt void RSA_TX_Handler(void)
{
// Set interrupt priority:
@@ -87,6 +104,7 @@ interrupt void RSA_TX_Handler(void)
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** @brief ISR освобождения TX SCI-B; продолжает передачу буфера rs_b. */
interrupt void RSB_TX_Handler(void)
{
// Set interrupt priority:
@@ -105,7 +123,15 @@ interrupt void RSB_TX_Handler(void)
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** Обработчик прерываний UART - принато */
/** Обработчик прерываний UART - принато */
/**
* @brief Принимает очередной символ и продвигает автомат сборки кадра.
* @param rs_arr Состояние порта, вызвавшего прерывание.
* @details Проверяет аппаратные ошибки, адресный девятый бит, ожидаемую длину
* команды и границы буфера. После полного кадра выставляет признак готовности
* для foreground-кода; при нарушении синхронизации возвращается к ожиданию адреса.
* @warning Выполняется из ISR и не должен вызывать блокирующие операции.
*/
void RS_RX_Handler(RS_DATA *rs_arr)
{
char Rc;
@@ -113,16 +139,16 @@ void RS_RX_Handler(RS_DATA *rs_arr)
// led1_on();
for(;;) // 'goto' это не оператор азыка С
for(;;) // 'goto' это не оператор азыка С
{
if(!rs_arr->SciRegs->SCIRXST.bit.RXRDY) // Receiver ready flag
{
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1; // Clear INT flag
return; // кстати это единственный выход из прерываниа
return; // кстати это единственный выход из прерываниа
}
Rc = rs_arr->SciRegs->SCIRXBUF.bit.RXDT; // Читаем символ в любом случае
Rc = rs_arr->SciRegs->SCIRXBUF.bit.RXDT; // Читаем символ в любом случае
if(rs_arr->SciRegs->SCIRXST.bit.RXERROR) // Receiver error flag
{
@@ -132,42 +158,42 @@ void RS_RX_Handler(RS_DATA *rs_arr)
continue;
}
if(rs_arr->RS_DataReady) continue; // Не забрали данные
if(rs_arr->RS_DataReady) continue; // Не забрали данные
if (rs_arr->RS_Flag9bit==1) // дла RS485????????
if (rs_arr->RS_Flag9bit==1) // дла RS485????????
{
// Инициализируем переменные и флаги
rs_arr->RS_FlagBegin = true; // Ждем заголовок
// Инициализируем переменные и флаги
rs_arr->RS_FlagBegin = true; // Ждем заголовок
rs_arr->RS_RecvLen = 0;
rs_arr->RS_FlagSkiping = false;
rs_arr->RS_HeaderCnt = 0;
rs_arr->RS_Cmd = 0;
}
if(rs_arr->RS_FlagSkiping) continue; // Не нам
if(rs_arr->RS_FlagSkiping) continue; // Не нам
if (rs_arr->RS_FlagBegin) // Заголовок
if (rs_arr->RS_FlagBegin) // Заголовок
{
if (rs_arr->RS_HeaderCnt==0) // Адрес контроллера или стандартнаа команда
if (rs_arr->RS_HeaderCnt==0) // Адрес контроллера или стандартнаа команда
{
if( (Rc == CNTRL_ADDR_UNIVERSAL) || (Rc == CNTRL_ADDR && CNTRL_ADDR!=0) || ((Rc == rs_arr->addr_answer) && rs_arr->flag_LEADING)
|| ((Rc == ADDR_FOR_ALL && ADDR_FOR_ALL!=0) && !rs_arr->flag_LEADING))
{
rs_arr->addr_recive=Rc; // запомнили адрес по которому нас запросили
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Первый байт
RS_SetBitMode(rs_arr,8); // перестроились в 8-бит режим
rs_arr->addr_recive=Rc; // запомнили адрес по которому нас запросили
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Первый байт
RS_SetBitMode(rs_arr,8); // перестроились в 8-бит режим
}
else
{
rs_arr->RS_FlagSkiping = true; // Не нашему контроллеру
rs_arr->RS_FlagBegin = false; // остались в 9-бит режиме
rs_arr->RS_FlagSkiping = true; // Не нашему контроллеру
rs_arr->RS_FlagBegin = false; // остались в 9-бит режиме
// led1_off();
}
}
else
{
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Второй байт и т.д.
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Второй байт и т.д.
if (rs_arr->RS_HeaderCnt == 7 && rs_arr->RS_Cmd==CMD_MODBUS_16 && !rs_arr->flag_LEADING)
{
@@ -180,68 +206,75 @@ void RS_RX_Handler(RS_DATA *rs_arr)
RS_Len[rs_arr->RS_Cmd] = Rc + 5;
}
// если второй байт - это команда
// если второй байт - это команда
if (rs_arr->RS_HeaderCnt == 2)
{
rs_arr->RS_Cmd = Rc;
// Проверка длины посылки
// CMD_LOAD - младшаа на данный момент
// CMD_STD_ANS - старшаа на данный момент
// Проверка длины посылки
// CMD_LOAD - младшаа на данный момент
// CMD_STD_ANS - старшаа на данный момент
if ((rs_arr->RS_Cmd < CMD_MODBUS_3) || (rs_arr->RS_Cmd > CMD_STD_ANS) || (RS_Len[rs_arr->RS_Cmd]<3)
|| ((rs_arr->RS_Cmd == CMD_LOAD)&&(rs_arr->RS_PrevCmd != CMD_INITLOAD))
)
{
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
rs_arr->RS_HeaderCnt = 0; // Потому что команда не та
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
rs_arr->RS_HeaderCnt = 0; // Потому что команда не та
rs_arr->RS_FlagBegin = true;
rs_arr->RS_FlagSkiping = false;
rs_arr->RS_Cmd=0;
// led1_off();
continue;
}
if (rs_arr->RS_Cmd == CMD_LOAD) // Дла этой команды заголовок очень короткий
rs_arr->RS_FlagBegin = false;// дальше идут данные
if (rs_arr->RS_Cmd == CMD_LOAD) // Дла этой команды заголовок очень короткий
rs_arr->RS_FlagBegin = false;// дальше идут данные
}
if( (rs_arr->RS_HeaderCnt >= RS_Len[rs_arr->RS_Cmd]) ||
(rs_arr->RS_HeaderCnt >= sizeof(rs_arr->RS_Header)))
{ // Получили заголовок
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
{ // Получили заголовок
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
rs_arr->RS_FlagBegin = false;
rs_arr->RS_FlagSkiping = true;
rs_arr->RS_DataReady = true;
rs_arr->RS_Cmd=0;
// led1_off();
} } }
else // Поток данных
else // Поток данных
{
if(rs_arr->pRS_RecvPtr<(unsigned int *)Rec_Bloc_Begin || rs_arr->pRS_RecvPtr>(unsigned int *)Rec_Bloc_End)
{
rs_arr->pRS_RecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
rs_arr->pRecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
rs_arr->pRS_RecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
rs_arr->pRecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
}
if(rs_arr->RS_PrevCmd != CMD_INITLOAD) continue; // Мы здесь оказались по какой-то чудовищной ошибке
if(rs_arr->RS_PrevCmd != CMD_INITLOAD) continue; // Мы здесь оказались по какой-то чудовищной ошибке
if(rs_arr->RS_DataReady) // Если данные в основном цикле не забраны,
{ // то пропускаем следующую посылку
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
if(rs_arr->RS_DataReady) // Если данные в основном цикле не забраны,
{ // то пропускаем следующую посылку
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
// led1_off();
continue;
}
RS_BytePtr = rs_arr->RS_RecvLen++ % 2;
if(RS_BytePtr) *rs_arr->pRS_RecvPtr++ |= Rc; // Получили слово
if(RS_BytePtr) *rs_arr->pRS_RecvPtr++ |= Rc; // Получили слово
else *rs_arr->pRS_RecvPtr = Rc<<8;
if(rs_arr->RS_Length <= rs_arr->RS_RecvLen) // Конец посылки
if(rs_arr->RS_Length <= rs_arr->RS_RecvLen) // Конец посылки
{
rs_arr->RS_PrevCmd = rs_arr->RS_Header[1] = CMD_LOAD;
RS_SetBitMode(rs_arr,9); // Получили все данные перестроились в 9-бит дла RS485?
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
rs_arr->RS_DataReady = true; // Флаг в основной цикл - данные получены
RS_SetBitMode(rs_arr,9); // Получили все данные перестроились в 9-бит дла RS485?
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
rs_arr->RS_DataReady = true; // Флаг в основной цикл - данные получены
// led1_off();
} } } }
/** Обработчик прерываний UART - послано */
/** Обработчик прерываний UART - послано */
/**
* @brief Передаёт следующий элемент активного RS-485 буфера.
* @param rs_arr Состояние обслуживаемого SCI.
* @details Пока счётчик не достиг RS_Length, пишет следующий байт в SCITXBUF.
* После последнего байта дожидается освобождения линии, возвращает трансивер
* в режим приёма и сбрасывает состояние передачи.
*/
void RS_TX_Handler(RS_DATA *rs_arr)
{
char RS_BytePtr;
@@ -251,18 +284,18 @@ void RS_TX_Handler(RS_DATA *rs_arr)
{
if(++rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
}
SCI_send(rs_arr,*(rs_arr->pRS_SendPtr++));
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
RS_Wait4OK(rs_arr);
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
rs_arr->flag_TIMEOUT_to_Send=false; /* сбросили флаг ожиданиа таймаута */
rs_arr->flag_TIMEOUT_to_Send=false; /* сбросили флаг ожиданиа таймаута */
}
}
else /* BM_PACKED */
@@ -271,7 +304,7 @@ void RS_TX_Handler(RS_DATA *rs_arr)
RS_BytePtr = (rs_arr->RS_SendLen++) % 2;
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
}
if(RS_BytePtr) SCI_send(rs_arr, LOBYTE( *(rs_arr->pRS_SendPtr++) ));
else SCI_send(rs_arr, HIBYTE( *rs_arr->pRS_SendPtr ));
@@ -279,9 +312,9 @@ void RS_TX_Handler(RS_DATA *rs_arr)
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
{
RS_Wait4OK(rs_arr);
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
// RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
// RS_Line_to_receive(); /* режим приема RS485 */
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
// RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
// RS_Line_to_receive(); /* режим приема RS485 */
}
}
@@ -290,7 +323,11 @@ void RS_TX_Handler(RS_DATA *rs_arr)
// rs_arr->SciRegs->SCIFFTX.bit.TXINTCLR=1; // Clear INT flag
}
/** Инициализациа массива длин команд */
/** Инициализациа массива длин команд */
/**
* @brief Заполняет таблицу ожидаемых длин сервисных и Modbus-команд.
* @post RS_Len[код] содержит полную длину кадра для поддерживаемых команд.
*/
void setup_arr_cmd_length()
{
int i;
@@ -317,86 +354,105 @@ void setup_arr_cmd_length()
RS_Len[CMD_EXTEND] = 18;
}
/** Настройка режима приема/передачи */
/** Настройка режима приема/передачи */
/**
* @brief Переключает SCI между 8- и 9-битным форматом символа.
* @param rs_arr Настраиваемый порт.
* @param n Требуемое число бит данных.
*/
void RS_SetBitMode(RS_DATA *rs_arr,int n)
{
if(n == 8)
{
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
rs_arr->RS_Flag9bit=0;
}
if(n == 9)
{
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
rs_arr->RS_Flag9bit=1;
} }
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество байт
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество байт
@see RS_BSend, RS_TRANSMIT_INTR */
/**
* @brief Запускает передачу массива, где один элемент хранит один байт.
* @return 1 после успешного запуска, 0 если порт занят или длина недопустима.
* @note Первый адресный символ отправляется в 9-битном режиме, оставшиеся — в 8-битном.
*/
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf,unsigned long len)
{
unsigned int i;
for (i=0; i <= 30000; i++){} /* Пауза дла PC */
for (i=0; i <= 30000; i++){} /* Пауза дла PC */
RS_Line_to_send(rs_arr); /* режим передачи RS485 */
RS_Line_to_send(rs_arr); /* режим передачи RS485 */
for (i=0; i <= 10000; i++){} /* Пауза дла PC */
for (i=0; i <= 10000; i++){} /* Пауза дла PC */
rs_arr->RS_SLength = len; /* Настраиваем переменные */
rs_arr->RS_SLength = len; /* Настраиваем переменные */
rs_arr->pRS_SendPtr = pBuf + 1;
rs_arr->RS_SendBlockMode = BM_CHAR32;
RS_Wait4OK(rs_arr); /* Дожидаемса ухода */
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
RS_Wait4OK(rs_arr); /* Дожидаемса ухода */
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
rs_arr->RS_SendLen = 1; /* Два байта уже передали */
rs_arr->RS_SendLen = 1; /* Два байта уже передали */
if(len > 1)
{
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
}
else
{
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
RS_Wait4OK(rs_arr); /* Дожидаемса ухода без прерываниа */
for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
RS_SetBitMode(rs_arr,9); /* Обратно в 9-бит режим */
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
RS_Wait4OK(rs_arr); /* Дожидаемса ухода без прерываниа */
for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
RS_SetBitMode(rs_arr,9); /* Обратно в 9-бит режим */
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
}
return 0;
}
// Посылка блока упакованных байтов
// Посылка блока упакованных байтов
/**
* @brief Запускает передачу массива с байтами, упакованными в слова DSP.
* @return 1 после успешного запуска, 0 при занятом порте или ошибке длины.
*/
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len)
{
RS_Line_to_send(rs_arr); // режим передачи RS485
RS_Line_to_send(rs_arr); // режим передачи RS485
rs_arr->RS_SLength = len; // Настраиваем переменные
rs_arr->RS_SLength = len; // Настраиваем переменные
rs_arr->pRS_SendPtr = pBuf;
rs_arr->RS_SendBlockMode = BM_PACKED;
RS_Wait4OK(rs_arr); // Ожидаем очистки и ухода последнего байта
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
RS_Wait4OK(rs_arr); // Ожидаем очистки и ухода последнего байта
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
rs_arr->RS_SendLen = 1; // Один байт уже передали
rs_arr->RS_SendLen = 1; // Один байт уже передали
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
SCI_send(rs_arr,HIBYTE(*pBuf));// Передаем первый байт
SCI_send(rs_arr,HIBYTE(*pBuf));// Передаем первый байт
return 0;
}
/** Устанавливает скорость обмена.
@param speed скорость RS в бод */
/** Устанавливает скорость обмена.
@param speed скорость RS в бод */
/** Устанавливает скорость обмена.
@param speed скорость RS в бод */
/** Устанавливает скорость обмена.
@param speed скорость RS в бод */
/**
* @brief Пересчитывает делитель baud-rate выбранного SCI.
* @param speed Требуемая скорость в бодах.
* @pre speed больше нуля и достижима от LSPCLK.
*/
void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
{
long SciBaud;
@@ -410,7 +466,11 @@ void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
}
/** Инициализациа последовательного порта */
/** Инициализациа последовательного порта */
/**
* @brief Обнуляет состояния обоих портов и создаёт таблицу длин команд.
* @param size_cmd15_set Прикладная длина команды функции 15.
*/
void create_uart_vars(char size_cmd15_set)
{
size_cmd15=size_cmd15_set;
@@ -420,8 +480,13 @@ void create_uart_vars(char size_cmd15_set)
/** Инициализациа последовательного порта */
/** Инициализациа последовательного порта */
/**
* @brief Назначает GPIO/векторы и запускает один из двух SCI-портов.
* @param commnumber COM_1 для SCI-A либо COM_2 для SCI-B.
* @param speed_baud Начальная скорость линии.
*/
void setup_uart(char commnumber, unsigned long speed_baud)
{
volatile struct SCI_REGS *SciRegs;
@@ -485,14 +550,14 @@ void setup_uart(char commnumber, unsigned long speed_baud)
SciRegs->SCICTL1.bit.RXENA=1;
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
SciRegs->SCIFFRX.bit.RXFFIL=1; // Длина наименьшей команды
SciRegs->SCIFFRX.bit.RXFFIL=1; // Длина наименьшей команды
setup_arr_cmd_length();
RS_SetLineSpeed(rs_arr,speed_baud); // скорость линии
RS_Line_to_receive(rs_arr); // режим приема RS485
enableUARTInt(rs_arr); // разрешение прерываний UART
RS_SetLineSpeed(rs_arr,speed_baud); // скорость линии
RS_Line_to_receive(rs_arr); // режим приема RS485
enableUARTInt(rs_arr); // разрешение прерываний UART
RS_SetBitMode(rs_arr,9);
rs_arr->RS_PrevCmd = 0; // не было никаких команд
rs_arr->RS_PrevCmd = 0; // не было никаких команд
rs_arr->flag_TIMEOUT_to_Send = 0;
rs_arr->flag_LEADING = 0;
@@ -500,10 +565,11 @@ void setup_uart(char commnumber, unsigned long speed_baud)
SciRegs->SCICTL1.bit.SWRESET=1; // Relinquish SCI from Reset
}
/** Настройка режима линии.
@param bit количество бит данных
@param parity режим четности (N,O,E,M,S)
@param stop количество стоповых бит */
/** Настройка режима линии.
@param bit количество бит данных
@param parity режим четности (N,O,E,M,S)
@param stop количество стоповых бит */
/** @brief Программирует длину слова, чётность и число стоп-битов SCI. */
void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop)
{
volatile struct SCI_REGS *SciRegs;
@@ -541,12 +607,14 @@ Bit Bit Name Designation Functions
SciRegs->SCICCR.bit.ADDRIDLE_MODE = 0;
}
/** @brief Отмечает успешную активность порта и сбрасывает его watchdog связи. */
void clear_timer_rs_live(RS_DATA *rs_arr)
{
rs_arr->time_wait_rs_out=0;
}
/* проверка на живучесть RS */
/* проверка на живучесть RS */
/** @brief Увеличивает watchdog связи и фиксирует тайм-аут удалённого узла. */
void test_rs_live(RS_DATA *rs_arr)
{
/* if (rs_arr->time_wait_rs_out < RS_TIME_OUT)
@@ -554,6 +622,6 @@ void test_rs_live(RS_DATA *rs_arr)
else
{
rs_arr->time_wait_rs_out=0;
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
}*/ }

View File

@@ -1,12 +1,22 @@
/**
* @file bios.c
* @brief Сервисные команды удалённого доступа к памяти и загрузки программы.
*
* Реализует разбор BIOS-команд, формирование ответов, чтение/запись памяти,
* загрузку блоков и запуск кода через транспорт RS-485. Адреса и размеры
* приходят извне, поэтому корректность пакета и CRC должна быть подтверждена
* до вызова обработчиков. Прямой доступ к памяти преднамеренно использует
* volatile и требует адресов из допустимой карты памяти контроллера.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
Bios.c
**************************************************************
Основные комманды BIOS *
дла работы с RS232
Основные комманды BIOS *
дла работы с RS232
****************************************************************/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "RS485.h"
@@ -18,82 +28,95 @@
//#include "spartan_tools.h"
//#include "big_dsp_module.h"
int flag_DEBUG = false; /* Флаг отладочного режима */
int flag_DEBUG = false; /* Флаг отладочного режима */
//static unsigned int *RecvPtr;
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
/**********************************************************/
/* Прототипы функций, используемых и определенных в файле */
/* Прототипы функций, используемых и определенных в файле */
/**********************************************************/
//static int _getbyte(int *addr, int offs);
/** @brief Читает одно volatile-слово из физического адресного пространства DSP. */
unsigned int read_memory(unsigned long addr)
{
return (*(volatile int *)(addr));
}
/** @brief Записывает одно слово data по физическому адресу addr. */
void write_memory(unsigned long addr, unsigned int data)
{
(*(volatile int *)( addr )) = data;
}
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
/**
* @brief Проверяет и диспетчеризует полностью принятый сервисный кадр.
* @param rs_arr Порт и буфер принятой команды.
* @return Код распознанной команды либо признак ошибки кадра.
* @details Проверяет адрес, длину и CRC, затем вызывает обработчик CMD_*.
*/
int get_command(RS_DATA *rs_arr)
{
int cmd;
unsigned int crc, rcrc;
if(rs_arr->RS_DataReady) // Данные по RS пришли
if(rs_arr->RS_DataReady) // Данные по RS пришли
{
rs_arr->RS_DataReady = false;
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
// Провераем длину команды дла считываниа CRC
// Провераем длину команды дла считываниа CRC
if((RS_Len[cmd]<3) || (RS_Len[cmd]>MAX_RECEIVE_LENGTH))
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return -1;
}
if(cmd == CMD_LOAD) // Если команда загрузки
if(cmd == CMD_LOAD) // Если команда загрузки
{
rs_arr->RS_PrevCmd = cmd;
return cmd; // Нет проверки crc
return cmd; // Нет проверки crc
}
else // Все остальные команды
else // Все остальные команды
{
// Считываем crc из посылки
// Считываем crc из посылки
crc = (rs_arr->RS_Header[RS_Len[cmd]-1] << 8) |
(rs_arr->RS_Header[RS_Len[cmd]-2]) ;
}
// Рассчитываем crc из посылки
// Рассчитываем crc из посылки
rcrc = 0xffff;
rcrc = get_crc_16( rcrc, rs_arr->RS_Header, (RS_Len[cmd]-2) );
if(crc == rcrc) // Провераем crc
if(crc == rcrc) // Провераем crc
{
rs_arr->RS_PrevCmd = cmd;
return cmd;
}
else
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
} }
return -1;
}
/** Стандартный ответ, без параметров */
/** Стандартный ответ, без параметров */
/**
* @brief Добавляет CRC и отправляет n слов ответа через исходный порт.
* @param rs_arr Порт, через который пришёл запрос.
* @param n Число информационных слов до CRC.
*/
void Answer(RS_DATA *rs_arr,int n)
{
int crc;
flag_DEBUG = true; // Флаг отладочного режима
flag_DEBUG = true; // Флаг отладочного режима
rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR;
rs_arr->buffer[1] = n;
@@ -109,7 +132,7 @@ void Answer(RS_DATA *rs_arr,int n)
RS_Send(rs_arr,rs_arr->buffer, 6);
}
/* Внутреннаа ф-циа */
/* Внутреннаа ф-циа */
static char _getbyte(unsigned int *addr, int32 offs)
{
unsigned int *address;
@@ -122,7 +145,8 @@ static char _getbyte(unsigned int *addr, int32 offs)
}
/* начальные установки (не работает)*/
/* начальные установки (не работает)*/
/** @brief Сбрасывает параметры текущей загрузочной сессии и подтверждает команду. */
void init(RS_DATA *rs_arr)
{
/*
@@ -145,13 +169,18 @@ void init(RS_DATA *rs_arr)
*/
}
/**@name Комманды
* Комманды, вызываемые через последовательный канал
/**@name Комманды
* Комманды, вызываемые через последовательный канал
*/
//@{
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/**
* @brief Принимает заголовок нового образа и подготавливает диапазон загрузки.
* @details Из кадра извлекаются начальный адрес, длина и контрольные параметры;
* запись данных разрешается только после успешной проверки заголовка.
*/
void initload(RS_DATA *rs_arr)
{
unsigned long Address;
@@ -175,8 +204,12 @@ void initload(RS_DATA *rs_arr)
Answer(rs_arr,CMD_INITLOAD);
}
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/**
* @brief Записывает очередную порцию образа по текущему адресу загрузки.
* @post Рабочий адрес и остаток длины продвинуты на принятый блок.
*/
void load(RS_DATA *rs_arr)
{
unsigned int rcrc, crc;
@@ -201,27 +234,32 @@ void load(RS_DATA *rs_arr)
else
{
rs_arr->BS_LoadOK = false;
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
} }
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
@see load */
/** @brief Подтверждает команду и передаёт управление загруженной программе. */
void run (RS_DATA *rs_arr)
{
return;
}
/** Прочитать ачейку памати */
/** Прочитать ачейку памати */
/**
* @brief Возвращает содержимое заданного диапазона памяти.
* @warning Диапазон должен быть предварительно разрешён протокольным уровнем.
*/
void peek(RS_DATA *rs_arr)
{
unsigned long Address;
unsigned int Data, crc;
flag_DEBUG = true; // Флаг отладочного режима
flag_DEBUG = true; // Флаг отладочного режима
Address = rs_arr->RS_Header[5] & 0xFF;
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
@@ -254,7 +292,8 @@ void peek(RS_DATA *rs_arr)
}
/** Записать в ачейку памати */
/** Записать в ачейку памати */
/** @brief Записывает данные команды в заданную область памяти и отвечает статусом. */
void poke(RS_DATA *rs_arr)
{
unsigned long Address;
@@ -276,12 +315,13 @@ void poke(RS_DATA *rs_arr)
Answer(rs_arr,CMD_POKE);
}
/** Передать блок памати */
/** Передать блок памати */
/** @brief Передаёт ведущему очередной блок ранее выбранной области памяти. */
void upload(RS_DATA *rs_arr)
{
int32 Address, Length, crc;
no_write = 1; // Флаг отладочного режима
no_write = 1; // Флаг отладочного режима
// stopp=1;
Address = rs_arr->RS_Header[5] & 0xFF;
@@ -301,10 +341,10 @@ void upload(RS_DATA *rs_arr)
crc = get_crc_16( crc, rs_arr->buffer, 2);
crc = get_crc_16b( crc, (unsigned int *)Address, Length);
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
rs_arr->buffer[0] = CMD_UPLOAD;
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
RS_Wait4OK(rs_arr);
RS_BSend(rs_arr,(unsigned int*)Address, Length);
@@ -318,22 +358,24 @@ void upload(RS_DATA *rs_arr)
}
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
@see load */
/** @brief Обрабатывает совместимую команду программирования внешней логики. */
void xflash(RS_DATA *rs_arr)
{
return;
}
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
/** @brief Обрабатывает команду программирования памяти целевого контроллера. */
void tflash(RS_DATA *rs_arr)
{
// volatile unsigned long Address1,Address2;
@@ -341,7 +383,7 @@ void tflash(RS_DATA *rs_arr)
/*
if(!rs_arr->BS_LoadOK)
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return;
}
@@ -366,7 +408,7 @@ void tflash(RS_DATA *rs_arr)
if( (Address2 < 0x100000) || (Address2 > 0x180000) || ((Address2+LengthW) > 0x180000) )
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return;
}
@@ -378,11 +420,15 @@ void tflash(RS_DATA *rs_arr)
return;
}
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
/**
* @brief Выполняет расширенную BIOS-команду, не входящую в базовый набор.
* @details Подкоманда и её аргументы извлекаются из принятого сервисного кадра.
*/
void extendbios(RS_DATA *rs_arr)
{
volatile unsigned long Address1,Address2,Length;
@@ -407,10 +453,10 @@ void extendbios(RS_DATA *rs_arr)
switch ( code )
{
// Прошиваем EPROM Из RAM
// Прошиваем EPROM Из RAM
case 4: Seeprom_write(Address1,(unsigned int*)Address2,Length);
break;
// Читаем из EPROM в RAM
// Читаем из EPROM в RAM
case 5: Seeprom_read(Address1,(unsigned int*)Address2,Length);
break;

View File

@@ -1,11 +1,19 @@
/**
* @file cntrl_adr.c
* @brief Хранение и изменение сетевых адресов контроллера.
*
* Содержит рабочий, широковещательный, ответный и терминальный адреса узла.
* set_cntrl_addr() меняет только изменяемые адреса; вызывающий код отвечает
* за проверку диапазона и за отсутствие обмена во время перенастройки.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
cntrl_adr.c
****************************************************************
* Адрес контроллера *
* Адрес контроллера *
****************************************************************/
#include "cntrl_adr.h"
@@ -16,27 +24,34 @@
#define ADDR_UNIVERSAL_DEF 10
/** Установка адреса контроллера дла посылки всем АИНам */
/** Установка адреса контроллера дла посылки всем АИНам */
int ADDR_FOR_ALL = ADDR_FOR_ALL_DEF;
/** Установка адреса контроллера дла посылки ответа */
/** Установка адреса контроллера дла посылки ответа */
const int ADDR_ANSWER = ADDR_ANSWER_DEF;
/** Установка адреса терминала дла посылки ответа */
/** Установка адреса терминала дла посылки ответа */
const int ADDR_TERMINAL = ADDR_TERMINAL_DEF;
/* Универсальный адрес контроллера */
/* Универсальный адрес контроллера */
const int CNTRL_ADDR_UNIVERSAL=ADDR_UNIVERSAL_DEF;
/* Адрес контроллера */
/* Адрес контроллера */
int CNTRL_ADDR=1;
int cntr_addr_c;
int cntr_addr_c_all;
/** Установка адреса контроллера дла прошивки */
/** Установка адреса контроллера дла прошивки */
/**
* @brief Одновременно обновляет индивидуальный и групповой адреса узла.
* @param cntrl_addr Новый адрес данного контроллера.
* @param cntrl_addr_for_all Адрес, по которому принимаются групповые команды.
* @note Проверка допустимого диапазона выполняется уровнем конфигурации.
*/
void set_cntrl_addr (int cntrl_addr,int cntrl_addr_for_all)
{
/* Пара адресов меняется в одном месте, исключая смешанную конфигурацию. */
CNTRL_ADDR = cntrl_addr;
ADDR_FOR_ALL = cntrl_addr_for_all;
}

View File

@@ -1,3 +1,12 @@
/**
* @file crc16.c
* @brief Расчёт контрольных сумм CRC-CCITT и CRC-16 для протокольных кадров.
*
* Поддерживает табличные и побитовые варианты алгоритмов. Текущая конфигурация
* FAST_CRC/ONLY_CRC16 оставляет в прошивке только требуемый быстрый CRC-16.
* Размер задаётся в элементах буфера целевой платформы, а не в байтах host-PC;
* начальное значение CRC определяет вызывающий протокол.
*/
#include "crc16.h"
#define MAKE_TABS 0 /* Builds tables below */
#define FAST_CRC 1 /* If fast CRC should be used */
@@ -87,6 +96,13 @@ WORD crc_16_tab[] = {
/* CRC-CCITT is based on the polynomial x^16 + x^12 + x^5 + 1. Bits */
/* are sent MSB to LSB. */
/**
* @brief Продолжает расчёт CRC-CCITT по массиву слов.
* @param crc Начальное значение либо CRC предыдущего блока.
* @param buf Буфер данных; значим младший байт каждого слова.
* @param size Число обрабатываемых элементов.
* @return Итоговое 16-битное значение CRC-CCITT.
*/
unsigned int get_crc_ccitt(unsigned int crc,unsigned int *buf,unsigned long size )
{
#if !(FAST_CRC & !MAKE_TABS)
@@ -112,6 +128,13 @@ unsigned int get_crc_ccitt(unsigned int crc,unsigned int *buf,unsigned long size
/* CRC-16 is based on the polynomial x^16 + x^15 + x^2 + 1. Bits are */
/* sent LSB to MSB. */
/**
* @brief Вычисляет быстрый табличный CRC-16 с отражённым полиномом 0xA001.
* @param crc Начальное значение или результат предыдущей порции.
* @param buf Входные слова протокольного кадра.
* @param size Количество слов.
* @return CRC после обработки всего блока.
*/
unsigned int get_crc_16(unsigned int crc,unsigned int *buf,unsigned long size )
{
#if !(FAST_CRC & !MAKE_TABS)
@@ -139,6 +162,11 @@ unsigned int get_crc_16(unsigned int crc,unsigned int *buf,unsigned long size )
/**
* @brief Побитовый эталон расчёта CRC-16 без таблицы.
* @details Используется как компактная реализация и для сверки табличного
* варианта; восемь итераций обрабатывают каждый входной байт.
*/
unsigned int get_crc_16b(unsigned int crc,unsigned int *buf,unsigned long size )
{
@@ -175,6 +203,12 @@ unsigned long i;
return (crc & 0xffff);
}
/**
* @brief Проектная обёртка CRC-16 с установленным протоколом начальным значением.
* @param buf Кадр без добавляемого поля CRC.
* @param size Число элементов кадра.
* @return Контрольная сумма, готовая для сравнения или передачи.
*/
int get_crc16(unsigned int *buf, int size )
{
int crc16,i,j;

View File

@@ -1,3 +1,12 @@
/**
* @file ecan.c
* @brief Инициализация eCAN, передача кадров и обработка CAN-прерываний.
*
* Настраивает выбранный CAN-контроллер и mailbox, нормализует номер устройства,
* отправляет данные и ведёт счётчики приёма, передачи и ошибок. Регистры eCAN
* изменяются через shadow-копии согласно требованиям C2000; обработчики должны
* подтверждать источник прерывания и не задерживать остальные группы PIE.
*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
@@ -30,6 +39,14 @@ int CanTimeOutErrorTR = 0;
int wait=0;
/**
* @brief Настраивает eCAN-A и его почтовые ящики для выбранного номера узла.
* @param Port Номер интерфейса; текущая аппаратная реализация использует CAN-A.
* @param DevNum Номер устройства 1..16, насыщаемый реализацией на границах.
* @details Регистры управления изменяются через ECanShadow, чтобы исключить
* опасные read-modify-write операции над регистрами с особыми битами.
* @post Разрешены приёмные mailbox и прерывания CAN, счётчики ошибок сброшены.
*/
void InitCan(int Port, int DevNum)
{
struct ECAN_REGS ECanShadow;
@@ -40,6 +57,7 @@ void InitCan(int Port, int DevNum)
long id = 0x80BA0000;
/* Протокольная нумерация начинается с 1, аппаратное поле — с 0. */
DevNum--;
if(DevNum<0)DevNum=0;
if(DevNum>15)DevNum=15;
@@ -66,16 +84,16 @@ void InitCan(int Port, int DevNum)
// Required before writing the MSGIDs
ECanRegs->CANME.all = 0;
// задаем адрес 0 ащикa на передачу
// задаем адрес 0 ащикa на передачу
ECanMboxes->MBOX0.MSGID.all = id + 0x10 + DevNum;
// задаем адрес 1 ащикa на прием
ECanMboxes->MBOX1.MSGID.all = id + DevNum; //поменать!!!! 1 и 0!!!
// задаем адрес 1 ащикa на прием
ECanMboxes->MBOX1.MSGID.all = id + DevNum; //поменать!!!! 1 и 0!!!
// задаем режимы работы ащикa 0 на передачу, остальные на прием
// задаем режимы работы ащикa 0 на передачу, остальные на прием
ECanRegs->CANMD.all = 0xFFFFFFFE;
// выбираем только 2 ащикa дла работы, остальные запрещаем
// выбираем только 2 ащикa дла работы, остальные запрещаем
ECanRegs->CANME.all = 0x00000003;
// Clear all TAn bits
@@ -100,7 +118,7 @@ void InitCan(int Port, int DevNum)
ECanRegs->CANMC.all = ECanShadow.CANMC.all;
while(!ECanRegs->CANES.bit.CCE); // Wait for CCE bit to be set..
// настриваем скорость CAN
// настриваем скорость CAN
ECanShadow.CANBTC.all = ECanRegs->CANBTC.all;
ECanShadow.CANBTC.bit.SJWREG=1;
@@ -113,7 +131,7 @@ void InitCan(int Port, int DevNum)
ECanRegs->CANMC.all = ECanShadow.CANMC.all;
while(ECanRegs->CANES.bit.CCE); // Wait for CCE bit to be cleared..
// задаем таймауты дла ожиданиа отправки получениа посылки
// задаем таймауты дла ожиданиа отправки получениа посылки
ECanMOTORegs->MOTO0 = 550000;
ECanMOTORegs->MOTO1 = 550000;
@@ -140,7 +158,7 @@ void InitCan(int Port, int DevNum)
IER |= M_INT9; // Enable CPU INT
EDIS;
// завершили настройку CAN ащиков
// завершили настройку CAN ащиков
MessageReceivedCount = 0;
ErrorCount = 0;
@@ -148,6 +166,14 @@ void InitCan(int Port, int DevNum)
MessageTransivedCount=0;
}
/**
* @brief Формирует и запускает передачу одного прикладного CAN-кадра.
* @param Port Номер CAN-интерфейса.
* @param data Слова полезной нагрузки в формате проекта.
* @param Addr Идентификатор/адрес получателя.
* @note Перед записью mailbox проверяется завершение предыдущей передачи;
* тайм-аут отражается в CanTimeOutErrorTR.
*/
void CAN_send(int Port, int data[], int Addr)
{
unsigned long hiword,loword;
@@ -177,13 +203,19 @@ void CAN_send(int Port, int data[], int Addr)
ECanRegs->CANTSC = 0; // clear time-out counter
EDIS;
ECanRegs->CANTRS.all = 1; // запустить передачу
ECanRegs->CANTRS.all = 1; // запустить передачу
wait=1;
led1_toggle();
}
/**
* @brief Разбирает данные сработавшего приёмного mailbox.
* @param ECanMboxes Набор mailbox активного CAN-контроллера.
* @details Копирует полезную нагрузку в CAN_input_data и обновляет счётчик
* принятых сообщений; подтверждение аппаратного флага выполняет вызывающий ISR.
*/
void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
{
unsigned int adr;
@@ -215,6 +247,11 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
led2_toggle();
}
/**
* @brief Основной ISR eCAN-A для приёма кадров и завершения передачи.
* @details Определяет источник по CANRMP/CANTA, вызывает Handlai() для входного
* mailbox, очищает обслуженные флаги и подтверждает группу PIE9.
*/
interrupt void CANa_handler(void)
{
// Set interrupt priority:
@@ -234,6 +271,11 @@ interrupt void CANa_handler(void)
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/**
* @brief ISR линии ошибок eCAN-A.
* @details Сохраняет диагностические счётчики, очищает причину ошибки и
* возвращает контроллер к приёму, не меняя прикладную адресацию mailbox.
*/
interrupt void CANa_reset_err(void)
{
// Set interrupt priority:

View File

@@ -1,12 +1,32 @@
/**
* @file filter_bat2.c
* @brief Один шаг рекурсивного фильтра второго порядка.
*
* filterbat() вычисляет новый выход по текущему входу и сохранённой истории,
* затем сдвигает состояние FILTERBAT. Каждый независимый сигнал обязан иметь
* собственный экземпляр структуры; коэффициенты задаются в filter_bat2.h и
* предполагают фиксированную частоту вызова, использованную при их расчёте.
*/
#include "filter_bat2.h"
/**
* @brief Вычисляет очередной отсчёт IIR-фильтра второго порядка.
* @param b Коэффициенты и история конкретного фильтруемого канала.
* @param InpVarCurr Текущий нефильтрованный отсчёт.
* @return Отфильтрованное значение.
* @pre b указывает на инициализированный объект FILTERBAT.
* @post История двух предыдущих входов и выходов сдвинута на один отсчёт.
*/
float filterbat(FILTERBAT *b, float InpVarCurr)
{
float y;
/* Прямая ветвь использует текущий и два предыдущих входных отсчёта. */
y = (b->k_0 * (InpVarCurr + (b->i_0*2) + b->i_1)) +
/* Рекурсивная ветвь возвращает два предыдущих выхода фильтра. */
(b->k_1 * b->u_0) + (b->k_2 * b->u_1);
/* Сначала сдвигается старая история, затем сохраняются новые значения. */
b->u_1=b->u_0;
b->u_0=y;
b->i_1=b->i_0;

View File

@@ -1,3 +1,12 @@
/**
* @file kanal.c
* @brief Последовательный вывод числовых данных на канальный индикатор.
*
* Управляет линиями DCLK/DOUT, формирует импульс сброса и передаёт разряды
* индикатора с учётом адреса, десятичной точки и множителя тактовой частоты.
* Задержки и таблица сегментов привязаны к внешней схеме; изменение GPIO или
* CLKMULT требует повторной проверки временной диаграммы.
*/
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
#include "filter_bat2.h"
@@ -15,12 +24,14 @@
int digits[16] = {63,6,91,79,102,109,125,7,127,111,64,0,0,0,121,0};
int readr[5] = {0x08,0x0C,0x10,0x00,0x04};
/** @brief Устанавливает тактовую линию канального последовательного интерфейса. */
void DCLK(int x)
{
if(x) GpioDataRegs.GPASET.bit.GPIO6=1;
else GpioDataRegs.GPACLEAR.bit.GPIO6=1;
}
/** @brief Устанавливает линию данных канального последовательного интерфейса. */
void DOUT(int x)
{
if(x) GpioDataRegs.GPASET.bit.GPIO8=1;
@@ -48,6 +59,10 @@ void DOUT(int x)
#define POWS1 80L
#endif
/**
* @brief Формирует последовательность сброса внешних регистров индикатора.
* @note Число холостых тактов является частью аппаратного протокола.
*/
void RESET()
{
DCLK(0);
@@ -64,6 +79,7 @@ void RESET()
#endif
}
/** @brief Выдаёт один бит данных и сопровождающий его импульс DCLK. */
void SENDBIT(int x)
{
DOUT(x); DCLK(1);
@@ -78,12 +94,20 @@ void SENDBIT(int x)
#endif
}
/**
* @brief Кодирует адрес и число и передаёт их семисегментному индикатору.
* @param adr Адрес физического канала.
* @param dat Значение для отображения.
* @param dot Позиция десятичной точки.
* @details Таблица digits преобразует цифры в сегменты; знак и ведущие позиции
* обрабатываются до побитовой отправки каждого разряда.
*/
void kanal_Send(int adr, long dat, int dot)
{
long Word,data,aliq_part,dg[4];
int i,j,bit,byt,addr,sgn=0,punkt=0,aliq_len=0,full_len, isdot=0;
if(adr>1) // Лампочки
if(adr>1) // Лампочки
{
Word =dat;
}
@@ -134,7 +158,7 @@ void kanal_Send(int adr, long dat, int dot)
for(i=3;i>0;i--)
{
if((dg[i]==0)&&(i!=dot))
dg[i]=0xF; // Это значит пусто
dg[i]=0xF; // Это значит пусто
else break;
}
@@ -143,7 +167,7 @@ void kanal_Send(int adr, long dat, int dot)
{
if( (dg[i]==0xF)||(i==3))
{
dg[i]=0xA; // Это значит минус
dg[i]=0xA; // Это значит минус
break;
} }

View File

@@ -1,17 +1,26 @@
/**
* @file log_to_mem.c
* @brief Кольцевой журнал событий во внешней области памяти.
*
* Резервирует секцию .logg, хранит границы и текущий адрес журнала и очищает
* всю отведённую область по запросу. LOG_PAGE_START/LOG_PAGE_LEN должны
* соответствовать linker command file; clear_mem() выполняет длительную
* блокирующую запись и не предназначена для вызова из обработчика прерывания.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2001г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2001г. */
/****************************************************************/
/* log_to_mem.c
****************************************************************
* Запись логов в памyть *
* Запись логов в памyть *
****************************************************************/
#include "log_to_mem.h"
int no_write = 0,
never_write = 0; // Флаги, чтобы не писать (если что)
never_write = 0; // Флаги, чтобы не писать (если что)
#pragma DATA_SECTION(logs_block,".logg");
unsigned int logs_block[0xFA00];
@@ -19,7 +28,13 @@ unsigned int logs_block[0xFA00];
LOG Log;
unsigned int flog=0;
// Очищение памати, где логи лежат
// Очищение памати, где логи лежат
/**
* @brief Сбрасывает метаданные и физически очищает всю область журнала.
* @post Log.Adres установлен в LOG_PAGE_START, Log.Circl сброшен, а каждое
* слово выделенной области равно нулю.
* @warning Функция блокируется на LOG_PAGE_LEN операций внешней памяти.
*/
void clear_mem()
{
unsigned long i;
@@ -29,6 +44,7 @@ void clear_mem()
Log.Adres = Log.Start;
Log.Circl = 0;
/* Полуинтервал [Start, Finis) исключает запись за последним словом секции. */
for (i=Log.Start; i<Log.Finis; i++)
*(volatile int *)i = 0;
}

View File

@@ -1,3 +1,12 @@
/**
* @file main.c
* @brief Точка входа и основной диспетчер периферийной прошивки Balsam 167.
*
* Выполняет инициализацию тактирования, GPIO, интерфейсов и измерительных
* модулей, выбирает обработчик Timer1 по типу платы и затем координирует CAN,
* RS-485, команды и контроль состояния. Порядок инициализации важен: глобальные
* прерывания разрешаются только после настройки таблицы PIE и зависимых блоков.
*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "cntrl_adr.h"
@@ -23,6 +32,13 @@
#include "measure.h"
extern void DSP28x_usDelay(Uint32 Count);
/**
* @brief Настраивает CPU Timer1 и выбирает его ISR по роли платы.
* @details Для пульта используется cpu_timer1_isr_PULT(), для остальных ролей
* — измерительный cpu_timer1_isr_SENS(). Период равен одному тику READY_FREQ.
* @pre Desk уже считан из конфигурационных GPIO.
* @post Вектор XINT13 установлен, Timer1 запущен, CPU INT13 разрешён.
*/
void timer_Init()
{
EALLOW; // This is needed to write to EALLOW protected registers
@@ -35,20 +51,32 @@ void timer_Init()
IER |= M_INT13;
}
/**
* @brief Инициализирует устройство и выполняет бесконечный диспетчерский цикл.
*
* @details Последовательно поднимает системное тактирование, внешнюю память,
* PIE, GPIO, UART, EEPROM, CAN, АЦП и таймеры. Затем обслуживает завершённые
* RS-485 кадры, сервисные команды, CAN-периодику, кнопки и контроль связи.
* Точные ветви исполнения определяются Desk и опциями package.h.
*
* @warning Порядок запуска существенен: ISR не должны сработать до создания
* буферов, установки векторов и инициализации разделяемого состояния.
*/
void main()
{
int i,j,mask;
static unsigned int cancount[2], cancell[2], rscount;
static int preCstart=1,preCstop=1;
int umpstart,umpstop;
RS_DATA * rs;
int presbyt=0;
InitSysCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
/* Конфигурация PIE и периферии выполняется при запрещённых прерываниях CPU. */
DINT;
/* После сброса PIE источники разрешаются отдельно каждым драйвером. */
InitPieCtrl();
IER = 0x0000;
@@ -57,6 +85,7 @@ void main()
InitPieVectTable();
init_zone7();
/* Роль платы определяет дальнейшую разводку ADC, GPIO и Timer1 ISR. */
get_Mode();
InitCan(0,Mode);
@@ -84,6 +113,7 @@ void main()
clear_mem();
set_cntrl_addr(Mode,16);
timer_Init();
/* Все базовые векторы и транспортные состояния готовы к обслуживанию ISR. */
EnableInterrupts();
if(Desk!=dsk_EPLT)
@@ -105,8 +135,10 @@ void main()
SysCtrlRegs.WDCR= 0x2F;
EDIS;
/* READY разрешает измерительному ADC ISR использовать накопленные данные. */
READY=1;
/* Foreground-цикл обрабатывает события, подготовленные ISR и таймерами. */
while(1)
{
if(CanGO)
@@ -177,22 +209,19 @@ void main()
if(Desk==dsk_LOAD)
{
umpstart = cUMPstart;
umpstop = cUMPreset;
if(umpstart & !preCstart)
if(cUMPstart & !preCstart)
{
set_START_DPTB(); set_RES_OUT_2();
IMPowse = READY_FREQ;
}
preCstart = umpstart;
preCstart = cUMPstart;
if(umpstop & !preCstop)
if(cUMPreset & !preCstop)
{
set_STOP_DPTB(); clear_RES_OUT_2();
IMPowse = READY_FREQ;
}
preCstop = umpstop;
preCstop = cUMPreset;
if(!IMPowse) { clear_START_DPTB(); clear_STOP_DPTB(); }
}
@@ -210,16 +239,16 @@ void main()
led2_toggle();
switch(j)
{
case CMD_INIT: init(rs); break; // íŕ÷ŕëüíűĺ óńňŕíîâęč
case CMD_INITLOAD: initload(rs); break; // íŕńňđîéęŕ çŕăđóçęč
case CMD_RUN: run(rs); break; // çŕăđóçčňü áëîę
case CMD_LOAD: load(rs); break; // çŕăđóçčňü áëîę
case CMD_PEEK: peek(rs); break; // ďđî÷čňŕňü ŕ÷ĺéęó ďŕěŕňč
case CMD_POKE: poke(rs); break; // çŕďčńŕňü â ŕ÷ĺéęó ďŕěŕňč
case CMD_UPLOAD: upload(rs); break; // ďĺđĺäŕňü áëîę ďŕěŕňč
case CMD_EXTEND: extendbios(rs); break; // đŕńřčđĺííűĺ ęîěŕíäű äëŕ áčîńŕ
case CMD_INIT: init(rs); break; // начальные установки
case CMD_INITLOAD: initload(rs); break; // настройка загрузки
case CMD_RUN: run(rs); break; // загрузить блок
case CMD_LOAD: load(rs); break; // загрузить блок
case CMD_PEEK: peek(rs); break; // прочитать ачейку памати
case CMD_POKE: poke(rs); break; // записать в ачейку памати
case CMD_UPLOAD: upload(rs); break; // передать блок памати
case CMD_EXTEND: extendbios(rs); break; // расширенные команды дла биоса
case CMD_TFLASH: tflash(rs); break; // ďđîřčňü TMS
case CMD_TFLASH: tflash(rs); break; // прошить TMS
case CMD_MODBUS_3: ReceiveCommandModbus3(rs); break;
case CMD_MODBUS_6: ReceiveCommandModbus6(rs); break;

Some files were not shown because too many files have changed in this diff Show More