13 Commits

Author SHA1 Message Date
c6c9128238 feat(rs232): enable SCI-A FIFO on PM35 and preserve RS485 2026-10-02 07:23:08 +03:00
419d6b17dc Устранить пересечение образа логгера с параметрами EEPROM и проверять размер BIN 2026-10-01 20:20:00 +03:00
e3d43ef279 Обновить проект CCS, результаты сборки и структуру данных Бальзам-167
Настроить CCS 12.3 и компилятор C2000 22.6.0, подключить общий UMP-протокол в Debug и Release и исправить относительный путь к исходникам. Обновить HEX, карты памяти, таблицу структуры данных и описание зависимости.
2026-10-01 19:04:21 +03:00
34a95bc553 Fix UMP logger boot initialization and configurable protocol build 2026-10-01 17:22:03 +03:00
1ce42a1877 Record PM67 ZPT voltages in UMP logger v3 2026-10-01 16:00:48 +03:00
316dd52f99 Use shared UMP protocol core and document DAC SPI review 2026-10-01 14:02:12 +03:00
2a9f42331c Append Git commit hash to firmware BIN filename 2026-09-22 12:56:45 +03:00
ee7dce4615 Remove file banners and legacy project names from comments 2026-09-22 12:40:43 +03:00
a3633d8ede Добавлен CAN-доступ к регистратору УМП через отдельный канал ответов 2026-09-21 00:49:53 +03:00
df719229b7 Добавлен регистратор запуска и отключения УМП для стендовой проверки
Реализованы кольцевая запись CAN-команд, дискретных сигналов, уставок и состояния ЦАП, а также отдельный архив отключения с секундой постинтервала.
Добавлено расширение Modbus для онлайн-графиков и чтения архива через SetGUI. Сохранены управляющая логика и существующая область технологических регистров.

Добавлены русские комментарии, описание протокола и тест регистратора. Проверка алгоритма и синтаксиса C пройдена; сборка TI/CCS и испытания на плате ещё требуются.
2026-09-21 00:15:27 +03:00
799e6ba46d чтобы импульс на СИФУ не трерялся 2026-09-18 22:15:38 +03:00
341f194b4d Начало и конец управляющего тока УМП регулируются 2026-09-16 12:09:49 +03:00
ed9680a36e игнор обрыва\перекоса как раньше 2026-09-07 13:52:49 +03:00
96 changed files with 5210 additions and 7193 deletions

10
.gitignore vendored
View File

@@ -1,5 +1,9 @@
/Debug/
/Release/
/UKSSTMS320F28335.CS_/
/Doc/build/
/Doc/.tools/
/Bin/UKSSTMS320F28335_*.bin
/Bin/LoggerFix/
/Bin/LoggerEepromFix/
/Bin/Rs232FifoTest/
/Bin/Rs232NoFifoTest/
/Bin/UartFifoTest/
/Bin/*.pending

View File

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

Binary file not shown.

View File

@@ -1,4 +1,4 @@
:20000000AA08000000000000000000000000000000000000FAB87F02000094BA00FF40DE90
:20000000AA08000000000000000000000000000000000000B5B98B02000000C000FFC0DADA
:2000200000000000C1C081C1400101C3C003800241C201C6C006800741C70005C1C581C4C4
:20004000400401CCC00C800D41CD000FC1CF81CE400E000AC1CA81CB400B01C9C0098008A5
:2000600041C801D8C018801941D9001BC1DB81DA401A001EC1DE81DF401F01DDC01D801CD4
@@ -15,990 +15,1005 @@
:2001C0004054019CC05C805D419D005FC19F819E405E005AC19A819B405B0199C0598058A4
:2001E00041980188C04880494189004BC18B818A404A004EC18E818F404F018DC04D804C33
:20020000418C0044C184818540450187C047804641860182C042804341830041C181818051
: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
:200220004040C0FFC0DE00000000000000000000C701B9019B09580900000000000000005A
:20024000CE01B7018A09600948130D136C13F9125E076A07D509E7090C138D130C13EF1293
:200260006A075107E709C609EC0ECE0EB10D340DC806AB0256030E00FB0EC90EC20D040D7F
:20028000D106B1025C0311000105F804000000006E02D708000000000A05050500000000FA
:2002A000FD07FD07A50AA50AFFFF42DC00001400FFFF43DC00000000FFFF44DC000000006D
:2002C000FFFF45DC00000000FFFF46DC00000000FFFF47DC00000000FFFF48DC000000009C
:2002E000FFFF51DC00000000FFFF54DC00000000FFFF55DC00000000EEFF68DC00001BD654
:20030000B738D79AFC3FA84C79BF0000000000000000000000000000000000000000000016
:200320000000FFFF72DF00000000FFFF73DF00000000FFFF74DF00000000FFFF75DF00007B
:200340000000FFFF76DF00000000FFFF77DF00000000FFFF78DF00000000FFFF79DF00004B
:200360000000FFFF00DF00000000FFFF01DF00000000FFFF02DF00000000FFFF03DF000003
:200380000000F4FF10DF00000000000000000000FCA300002EA40000F7A30000F2A30000DB
:2003A000FFFF58DF00000000FFFF59DF00000000FEFF66DF000000000000FEFF68DF00004C
:2003C00000000000FEFF6ADF000000000000FEFF6CDF000000000000EEFF2ADD00004A0C45
:2003E000023E4A0C023E0000803F0000803F6C09F93B6C09F93B6C09F93B6C09F93B000005
:20040000803FFFFF02DD00000000FFFF03DD00000000FFFF04DD00000000FFFF09DD00009F
:200420001400FFFF0CDD00000100F0FFB0DA00003F0006005B004F0066006D007D00070001
:200440007F006F00400000000000000079000000FFFF9BDF00000600FFFF9DDF00000000FD
:20046000FFFF9EDF00000000FEFFA2DF000000000000FFFF82DF00000000FFFF83DF0000C4
:200480000000FFFF84DF00000100FFFF85DF00000000FEFFBCDD000069BB0000FEFFBEDD46
:2004A000000069BB0000FEFFBCDF000000000000FEFFBEDF000000000000FFFF38DF0000D1
:2004C0000000FFFF39DF00000000FBFFCCDF000008000C00100000000400FFFF3CDD000022
:2004E0000A00FFFF3DDD00000100FFFFD5DF00000100FFFFD6DF00000100FEFFD9DF0000BD
:2005000000000000FEFFDBDF000000000000FFFF00D000000100FFFF40DE00000000FFFF3B
:1205200041DC00000000FFFF01DD0000000000000000D0
:20053200733B0000008002FEA4C5A988013B008FC0DBC7924196A9A8A681A71E1F76710305
:20055200C7CC00E041CA4296C7FF01900B9842CCFFFDA98803564201A91CFF03A9180002D8
:20057200A6CA429682FEC796060010E70B0001E8EAFA20E740000DE8BA9E6FE819F000E794
:20059200100000E7490000E70000007710E740004076BEBA02E8010250E80000407696B71E
:2005B2000600A71EA59243880860C4930461C40BA6920C6F009A0A6FC427AA2BA706AB0F7C
:2005D2000362019A036FC40AA69206001F767D03BDB23392BDAA03E2BD04586179D1808D25
:2005F200C0DB78D0013B9A92929EA985A9BD120F007700770077007789E604000077CFE63E
:20061200210002E80818407696B71F76710303E21E0002E8101CCFE621000FE83033407692
:2006320096B77AD11F76710378D0013B008FC0DB03E220009A92949EA985A9BD120F0077CA
:2006520000770077007789E6010002E80818407696B77BD11F76710379D0013B008FC0DBA2
:2006720003E222009A92949EA985A9BD120F007700770077007789E6010002E80818407642
:2006920096B71F76710303E224001F767D0332922F617AD1808DC0DB78D0013B9A92929EAD
:2006B200A985A9BD120F007700770077007789E6010002E84016407696B77BD11F7671038F
:2006D20079D0013B03E222009A92929EA985A9BD120F007700770077007789E6010002E835
:2006F2004016407696B71F76710303E2240000D1008FC0DB013BA9A8A181A98A74D0C8E2B2
:200712009400008F40DFA9A8A181A98AC4920252046002E8D123056F02E8E1300AE8010091
:20073200407696B7013B008F2ADD0356A1010156A40001D9A192045203E2C400DA64AFE201
:20075200BE04BE86BE8B0600BDB2BDAA04FE0052A92DA85A06601F7671030B920B2B0C964C
:20077200008FC0DB013BA9A8AC81A98AC44F076CAC921F7671030654E4FFB401008F86DE9E
:20079200A9A8AC81A9837FD0008FC0DB944CC4E2C500EDFF9E01A9A8AC81A98AC44D3F6CE1
:2007B200AC921F76710306543A6300B6A79200BEA985013BA98E008F40DFA9A8AC81A98343
:2007D200A9A8A681A98AC592C4541460008FC0DBA9A8A681A98A1F7671031392C4CE0A60FA
:2007F200008F86DEA9A8A681A98A01DFA93AC40DA98E01DEA6921852DF64A7920761A985EB
:20081200421EA93AC0006BBAA98EA93AA9BD120F007700770077007789E60000AC921F76DF
:200832007103079EA959A2922561008F40DF013BA9A8AC81A98AC4920A521A60AC92069E28
:20085200A988008FACDFA9A8A681A98AC8E2C401008FA4DFA9A8A681A98A01E860EE0EE837
:20087200686600E74000C492036106E84016A29256601F767D03329252617FD0008FC0DB84
:20089200949316D0D3FF9492C1FFA8CAA940246C1F767C033C0620601F767D033192055291
:2008B2000C6002E849280CE8010094E6080014AD0465A1920250A959A1920E64A9A8013B05
:2008D200A181A98A8CE6000078D013E2940040765380EFFF1401AC921F7671030654E3FF5F
:2008F2000E01A1400F6C79D0C8E29401007720E74000AFE2240300E71800007790E8007619
:200912000E6F78D0C8E29401007720E74000AFE2220300E71800007790E800761F767D03D4
:2009320033925261A192E3FFAF001F767D03319202521F61AC400F6C79D0008FC0DBC8E239
:2009520094011F76710320E74000AFE2240300E718003A6F78D0008FC0DBC8E294011F76FA
:20097200710320E74000AFE2220300E718002C6F08BEAC92A672008FC0DB013BA9A8A68160
:20099200A983807686DEA606AC81A71E18D0C7929596AC9206520D6378D0C8E294011F7693
:2009B200710320E74000AFE21E0300E718000C6F78D0C8E294011F76710320E74000AFE2D6
:2009D200200300E7180016D0008FC0DB26E8000D94937FD0D0FF949232E8401AC9FFA8CA9F
:2009F200A940036C02E8001150E80148A9A8013B8CE60000AC818CE60900A98318D01F76C1
:200A12007C03A6BF120F13E29501432B3C063460A9A8AC81A98AC493A84E2E6DA61BECFFAB
:200A32002565A692C852226330D09592FB9CA6540363A845146D008FC0DBA9A8AC81A98ADC
:200A520030D0A69294540B6248D0945415651F767103431A10000B1A08000E6F1F76710354
:200A7200431A20010B1A0400076F1F767103431A01000B1A1000AD5CAC9283DCA45C40764F
:200A920000803C6F1F767C033C0616601235008F00D90156A400407634BA013B008FC0DB99
:200AB200A9A8A181A98A8CE6000078D013E2940040765380236F1235C07640D70156A7008E
:200AD200008F00D90156A40011F68424176FA9A8AC81A98A8CE6000018D013E294000E6F5B
:200AF200008FC0DBA9A8AC81A983A9A8AC81A98AC52B18D0C51A0080942B84FEBE86BE8B5A
:200B12000600BDB2BDAABDA202FE0052A95A06601F7671030B920B2B0C96008FC0DB013BE9
:200B3200A9A8A281A61EC64FEDFFC700408F86DEA9A0A281A9837FD0944CC4E2C500EDFF52
:200B5200B300408F40DFA9A0A281A9830356C501408F2ADD0156A500AFE2C50100E74000DB
:200B7200A9A88CE60000A281A98AA1BF120F18D01F767C039479422B3C06E0FF8E00C64E90
:200B9200EDFF8B00A29207525C610356A201A95B1F767D034218FFFB008D08DEA32D3E0692
:200BB200412B22560190A95DA93AA381A98A20FFE80340763E80013B019B019089FFA395C7
:200BD2004298A82D4218FFF73E06412B22560190A95DA93AAC81A98A20FFE80340763E8084
:200BF20001908AFF4298A29206522B60029A4218FFEFA394A92D013B3E06412B22560190F2
:200C1200A95DA93AAC81A98A20FFE80340763E80013B039B0190A3958BFF4298A82D4218C5
:200C3200FFDF3E062256412B0190A95DA93AAC81A98A20FFE80340763E8001908CFF42984E
:200C52004292C0FF42CDBFFF42CA008FC0DB013BC0FF42CAC0FF42CAC3FF4090A8CA42963E
:200C7200A9A8A281A98348D0A19295540F63408F1CDFA9A0A281A983421A0800A9A8C581BF
:200C9200A98AC492089084FF4298429205611F7671030B1A0200AD5CA29282DCA45C407609
:200CB2000080156FA9A8A281A98A8CE6000018D013E294000C6FA9A8A281A983A9A8A28105
:200CD200A98AC52B18D0C51A0080942B82FEBE82BE86BE8B060000BE013B008FC0DBA9A811
:200CF200A681A98A01DE18D0A692C41800E01852942BF46400BE013B008FC0DB408FB4DFC6
:200D1200A9A8A681A98A0356A6010156A50070D0C8E294001F767D0303E2C50031920652C2
:200D32001760408F40DFA9A0A681A983C59203520F60A640056D18D094288601096F008FFB
:200D5200C0DBA9A8A681A98A18D09428300201DEA6920452D264319201521060008FC0DB12
:200D72001F767103A9A80881A98AC41A0040CC1A0040D41A0040DC1A00401F767D033192CB
:200D920006520760008FC0DBC41A0040CC1A00404076538006001F767D033092A9931F76DD
:200DB2007103BDB2FF9D052B062B072B01531C69A993FD9D015311690752086109521A60FB
:200DD200BF56060FBF56070D156FBF560508BF560608BF5607080E6FBF560507BF56060EFA
:200DF200BF56070E076FBF56050ABF560614BF5607141F767D033792AC2B013BC07668DC53
:200E12001F76710306940896008F40DFA9A8AC81A98AC42B008F1CDFA9A8AC81A98A408F27
:200E320040D71235C4210156A500008F00D90156A400AC92019C11F68524A92D185211F62C
:200E52008424E3641F767D03349225611F7671030692AC2B20651F767D0333920961008F60
:200E720040DF013BA9A8AC81A98ABF56C4091F767D0332920961008F40DF013BA9A8AC81C7
:200E9200A98ABF56C408AC921F767103019CA92D0654E2641F767D033792AC2B1565013B67
:200EB2001F7671030688AC92A672008F40DFA9A8A681A98A1F767D03AC92019CBF56C40A07
:200ED200A92D3754EE641F767D03359236611F767103AC2B013BBF5612C80892AC94A988C4
:200EF200008F40DFA9A8A681A98A408FB4DFBF56C403008F1CDFA9A8A681A98AAC9201F0E5
:200F12000894C4960356AC01008FC0DB0156A500A9A8AC81A98A70D01235C8E29400008F98
:200F3200C0DD0156A40003E2C500AC92019CA92D11F684240452D2641F767D033192065241
:200F52000B601F767103008F40DF12282C01BF56DC02BF56D4021F767D0330920952346052
:200F7200008F40DF408F1CDFC42BBF56C50108D0BF56CC010ED1CD2BBF56D404BF56D503B2
:200F9200BF56DC04BF56DD02BF56E404BF56E505BF56EC04BF56ED04BF56F406BF56FC052A
:200FB200BF56940609D0BF5694070AD0BF5694060BD0BF5694060CD0BF5694060DD0BF5657
:200FD2009408BF569C081F7671030002132B0D28F915BF560E120F28F22B10283E49AC2BFF
:200FF200013B90E5131A01E01F767D033E1E008FC0DFA9A8AC81A98AC42B008FC6DFA9A85C
:20101200AC81A98A0356AC01C42B008F8EDF0156A400AC92019CA92D03E2C4000652E86474
:20103200AC2B013B00BE0356AC01008F04D70156A400AC92019CC4C2A92D1C52F564AC2B8D
:20105200013B008F08DEA9A8AC81A98AAC92019CC42BA92D2052F664AC2B013B008FA4DF8B
:20107200A9A8AC81A98AC42B008FACDFA9A8AC81A98AAC92019CC42BA92D0852F064BE8B5C
:2010920006001F767D0335921F7671030880026104DF00D5013B00D40356A5038076F0D8E1
:2010B200A4810156A60001DCA492C62B0852F56401DDA5920252F0641F767D03319204525A
:2010D2007761A79200D52D65013BA592A2FF008FF0D8CBFFA594A3FFA927A9A8AB81A61E65
:2010F2000356AB04A92D019BA592ACEA189A67FFA594C699A988A2FFCBFFA594189CA3FFBC
:20111200A92701DDA9A8AB81A98A0356AB04A92DA692ACEA019A66FFC498A792A554D662ED
:2011320000D5013B008FF0D803BEA9A8A581A71EA592A672A9A8A681A98A08D001DDC7922F
:201152009496A5920352EF641F767D033192008FF8D802520460A9280003036FA928000F5F
:20117200FC981F767D0335920961408FF0D8A58A0FDCC41AFF00F51A003F1F767D033792C9
:2011920005611F766303361A08001F767D03319206521460408FF0D8A58A08DCFC1A3000F0
:2011B200EC1A0300FD1A00E0CD1A0030076F008FF8D8C41A0F00F41AFC01008FF0D8A483BB
:2011D20008DC01DDC51A0100F41A0700FC1A00E00600BDB2BDAABDA203E2BD0403E2BD05C8
:2011F20003E2BD060AFE1F767D034496319206520860449206601F7671030B920B2B0C9601
:201212001F7671030892008F1CDF013B4494A988A9A84481A98A808DC0DBC4924696449251
:2012320001F0019047964492A0FFA92D499603354896049AAC94A95BA9AAA681A98A457EAB
:20125200C44FEDFF4002008F3CD7A9A84481A98A64BE4492A672C4E2C404A9AAA681A98A25
:201272008CE62000408DB4DF13E2C40044920356A9010156A10002E891340BE801E0AFE2CC
:20129200C10020E72000407696B7442D008FC0DD1235AFE2C10110E740000156A40003E203
:2012B200C100407634BA1F767C038CE60000AC281F003EC4013B1F767C038DE60000A606CD
:2012D2002256A60740FF3C0F0965A9AA4481A98A8CE6000070D013E294004492408F2ADDAD
:2012F200008FC0DB0356A901A71E0156A500A9A84481A98A70D0C8E29400408D8EDF21E3E9
:20131200C501A70600E70C000156A10000E72101AFE2C10620E7880102E8512B0BE8010012
:20133200407696B7AFE2C10110E74000007703E2C1004076BEBA013B008FC6DF8CE60000E1
:20135200A9A84481A98A13E2C4004792E0FFA4001F767103CFE62000AFE22601407622802F
:20137200452D008F00D912350156A400407634BA4588008F40DF013BA9A8A681A98ACFE684
:201392000600C4920352066012E8060D14AD026396E5008F40DFA9A8A681A98AC492025273
:2013B200066012E8B61414AD026396E501E8A9FDCFE6300008E89927407696B71F767C0315
:2013D200CFE605003C061660008FC0DB4588013BA9A88CE6300018D0A681A98381DEA9A878
:2013F200A681A98A13E295008CE62B0018D013E294031F767103013BAFE62400408D8EDFAE
:20141200AFE226000356A30120E720000156A10000E70100AFE2C10020E7080002E8512B38
:201432000BE80100407696B7AFE2C10110E74000007703E2C1004076BEBA013B408FC6DF1E
:201452008CE60000A9A0A381A61EABBF120F68B6C63F4892A772008FC0DBA9A8A781A61ECF
:20147200A9A04681A71EAA286900C792C696A9A04481A71E4892AA72A9A8AA81A61EAA28BA
:201492006A00C792C6964892AA72A9A8AA81A98AC43F0C6F1F767D03319201520360AFE6D5
:2014B20024001F76710303E22604008FC6DFA9A84481A983A9A84681A98AC8E2C504C8E200
:2014D200C400008FC6DFA9A8A381A98A96E604001F767C03C8E2C4003C06432B96E6040028
:2014F200E0FFEA00008FC0DBA9A84581A98AC4CC0040CDFFA959008FC6DFA9A84481A98A82
:20151200C8E2C400CFE6210020E72000407696B701E8C9F400D50CE8D1CC94E6080014ADFC
:201532000B651F767103C8E21200007794E6040014AD026501D5008FC0DF013B1F767103FE
:20155200A9A84481412BA98A0F0E40763E8000520D61009BA1920260019B0356A8084393C8
:201572000451A818FFFEA8CA4396008FC6DF013BA9A8A381A98AC8E2C400CFE6210020E799
:201592002000407696B701E8C9F400D50CE8D1CC94E6080014AD0B651F767103C8E2120092
:2015B200007794E6040014AD026501D5008FC0DF013B1F767103A9A8412BA381A98A0F0E82
:2015D20040763E8000520D61009BA1920260019B0356A80843930451A818FFFEA8CA4396BD
:2015F2001F767D03319206526660479264604588008FC0DB013BA9A8A681A98A30D0C8E2BE
:201612009400007794E6050014AD0D65009BA1920260019B0356A80843932051A818FFFE22
:20163200A8CA4396008F40DFA9A8A681A98AC49203522860008FC0DBA9A8A681A98A48D0D4
:20165200412BC8E2940000D594E6050014AD026301D5008FDBDF1F767103A9A84981A98ADE
:201672000F0E40763E8000520D61009BA1920260019B0356A80843930851A818FFFEA8CAD4
:2016920043964588008F40DF013BA9A8A681A98AC49202521060008FC0DBA9A8A681A98A0E
:2016B20048D0C8E29400007794E6050014AD0365431A1000AD5C459283DCA45C40760080C1
:2016D2000E6F008FC0DBA9A8A681A983A9A8A681A98AC52B18D0C51A0080942B8AFEAFE2F3
:2016F200BE06AFE2BE05AFE2BE04BE82BE86BE8B06001B76F0FF00E2BD0030E600064229F4
:2017120016562576006F1B76F0FF00E2BD0030E6000602FE422916561F76330038924196C6
:2017320023760008267600003892382B2128FFFF1029103B419238962576006F1B76F0FF37
:2017520000E2BD0030E6000602FE422916561F7633003892419623760008267600003818EF
:2017720090002128FFFF1029103B419238962576006F1B76F0FF00E2BD0030E6000602FE16
:20179200422916561F763300389241962376000826760000381890002128FFFF1029103B0F
:2017B200419238962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003892C8
:2017D2004196237600082676000038189C002128FFFF1029103B419238962576006F1B76F0
:2017F200F0FF00E2BD0030E6000602FE422916561F763300389241962376000826760000B0
:2018120038189E002128FFFF1029103B419238962576006F1B76F0FF00E2BD0030E6000617
:2018320002FE422916561F7633002292419623760101221868002128FFFF1029103B419291
:2018520022962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300229241964F
:20187200237601012292222B2128FFFF1029103B419222962576006F1B76F0FF00E2BD003B
:2018920030E6000602FE422916561F763300229241962376010026760101221878002128BD
:2018B200FFFF1029103B419222962576006F1B76F0FF00E2BD0030E60006422916561029B4
:2018D2002576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E235
:2018F200BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000642291656D1
:2019120010292576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF9D
:2019320000E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000642291A
:20195200165610292576006F1B76F0FF00E2BD0030E600064229165610292576006F1B76E0
:20197200F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E6000656
:201992004229165610292576006F1B76F0FF00E2BD0030E600064229165610292576006FC6
:2019B2001B76F0FF00E2BD0030E600064229165610292576006F1B76F0FF00E2BD0030E68B
:2019D200000602FE422916561F7633002292419623760100267601012292222B2128FFFF45
:2019F2001029103B419222962576006F1B76F0FF00E2BD0030E6000602FE422916561F7615
:201A120033002C92419623762000267639012C922C2B2128FFFF1029103B41922C9625764D
:201A3200006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C92419623762000FD
:201A5200267639012C1832002128FFFF1029103B41922C962576006F1B76F0FF00E2BD009F
:201A720030E6000602FE422916561F7633002292419623760100267601012218F80021285B
:201A9200FFFF1029103B419222962576006F1B76F0FF00E2BD0030E6000602FE422916560B
:201AB2001F7633002292419623760100267601012218FA002128FFFF1029103B41922296FF
:201AD2002576006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241962376DE
:201AF200800026760000301803002128FFFF1029103B419230962576006F1B76F0FF00E29D
:201B1200BD0030E6000602FE422916561F76330032924196237600012676000132187500AA
:201B32002128FFFF1029103B419232962576006F1B76F0FF00E2BD0030E6000602FE42297D
:201B520016561F7633003292419623760001267600013218FD002128FFFF1029103B419288
:201B720032962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300309241960E
:201B920023768000267600002C1823002128FFFF1029103B419230962576006F1B76F0FF29
:201BB20000E2BD0030E6000602FE422916561F76330032924196237600012676000132189D
:201BD20071002128FFFF1029103B419232962576006F1B76F0FF00E2BD0030E6000602FED7
:201BF200422916561F7633003292419623760001267600013292322B2128FFFF1029103B76
:201C1200419232962576006F1B76F0FF00E2BD0030E6000642291656237639011029257654
:201C3200006F1B76F0FF00E2BD0030E60006422916562576006F1B76F0FF00E2BD0030E6D2
:201C520000064229165610292576006F1B76F0FF00E2BD0030E6000602FE422916561F76AB
:201C720033002C92419623762000267639012C1837002128FFFF1029103B41922C96257685
:201C9200006F1B76F0FF00E2BD0030E6000602FE422916561F7633002C924196237620009B
:201CB200267639012C922C2B2128FFFF1029103B41922C962576006F1B76F0FF00E2BD009E
:201CD20030E6000602FE422916561F7633002C92419623762000267639012C183300212853
:201CF200FFFF1029103B41922C962576006F1B76F0FF00E2BD0030E6000602FE422916569F
:201D12001F7633002C92419623762000267639012C1822002128FFFF1029103B41922C96FF
:201D32002576006F1B76F0FF00E2BD0030E6000602FE422916561F76330038924196237673
:201D520000082676000038189F002128FFFF1029103B419238962576006F1B76F0FF00E206
:201D7200BD0030E6000602FE422916561F7633003892419623760008267600003892382BCE
:201D92002128FFFF1029103B419238962576006F1B76F0FF00E2BD0030E6000642291656A9
:201DB2002576006F1B76F0FF00E2BD0030E60006422916562376390110292576006F1B764E
:201DD200F0FF00E2BD0030E60006422916562376391110292576006F1B76F0FF00E2BD002B
:201DF20030E600064229165610292576006F1B76F0FF00E2BD0030E6000602FE4229165689
:201E12001F763300309241962376800026760000301801002128FFFF1029103B41923096ED
:201E32002576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003092419623767A
:201E52008000267600002C922C2B2128FFFF1029103B419230962576006F1B76F0FF00E26F
:201E7200BD0030E6000602FE422916561F7633002A92419623761000267610012A922A2BDE
:201E92002128FFFF1029103B41922A962576006F1B76F0FF00E2BD0030E6000602FE422922
:201EB20016561F7633002A92419623761000267610012A1802002128FFFF1029103B419211
:201ED2002A962576006F1B76F0FF00E2BD0030E6000602FE422916561F76330024924196BF
:201EF200237602002676000024181F002128FFFF1029103B419224962576006F1B76F0FF5C
:201F120000E2BD0030E6000602FE422916561F763300269241962376040026763D01269297
:201F3200262B2128FFFF1029103B419226962576006F1B76F0FF00E2BD0030E6000602FE9F
:201F5200422916561F76330024924196237602002676000024180F002128FFFF1029103BF6
:201F7200419224962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300269226
:201F920041962376040026763D01261826002128FFFF1029103B419226962576006F1B7688
:201FB200F0FF00E2BD0030E6000602FE422916561F76330024924196237602002676000002
:201FD2002492242B2128FFFF1029103B419224962576006F1B76F0FF00E2BD0030E600064D
:201FF20002FE422916561F763300269241962376040026763D01261826002128FFFF102946
:20201200103B419226962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300F0
:20203200249241962376020026760000241808002128FFFF1029103B419224962576006F24
:202052001B76F0FF00E2BD0030E6000602FE422916561F76330026924196237604002676CC
:202072003D012692262B2128FFFF1029103B419226962576006F1B76F0FF00E2BD0030E66E
:20209200000602FE422916561F76330024924196237602002676000024180C002128FFFF36
:2020B2001029103B419224962576006F1B76F0FF00E2BD0030E6000602FE422916561F764C
:2020D2003300269241962376040026763D012692262B2128FFFF1029103B419226962576B7
:2020F200006F1B76F0FF00E2BD0030E6000602FE422916561F76330024924196237602005D
:202112002676000024180E002128FFFF1029103B419224962576006F1B76F0FF00E2BD0046
:2021320030E6000602FE422916561F763300269241962376040026763D0126183E00212807
:20215200FFFF1029103B419226962576006F1B76F0FF00E2BD0030E6000642291656102907
:202172002576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002892419623763F
:2021920008002676080128180F002128FFFF1029103B419228962576006F1B76F0FF00E269
:2021B200BD0030E6000602FE422916561F76330028924196237608002676080128180F006F
:2021D2002128FFFF1029103B419228962576006F1B76F0FF00E2BD0030E6000602FE4229E1
:2021F20016561F763300289241962376080026760801281803002128FFFF1029103B4192E1
:2022120028962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633002892419679
:202232002376080026760801281803002128FFFF1029103B419228962576006F1B76F0FF1D
:2022520000E2BD0030E6000602FE422916561F7633002A924196237608002676080128927F
:20227200282B2128FFFF1029103B419228962576006F1B76F0FF00E2BD0030E6000602FE58
:20229200422916561F763300289241962376080026760801281802002128FFFF1029103BA9
:2022B200419228962576006F1B76F0FF00E2BD0030E6000602FE422916561F7633003292D3
:2022D20041962376000126760001321875002128FFFF1029103B419232962576006F1B761E
:2022F200F0FF00E2BD0030E6000602FE422916561F763300329241962376000126760001B1
:202312003292322B2128FFFF1029103B419232962576006F1B76F0FF00E2BD0030E60006DF
:2023320002FE422916561F763300329241962376000126760001321831002128FFFF10291F
:20235200103B419232962576006F1B76F0FF00E2BD0030E6000602FE422916561F763300A1
:202372003292419623760001267600013292322B2128FFFF1029103B419232962576006FE8
:202392001B76F0FF00E2BD0030E6000602FE422916561F7633002E92419623764000267645
:2023B20000002E922E2B2128FFFF1029103B41922E962576006F1B76F0FF00E2BD0030E651
:2023D200000602FE422916561F7633002E92419623764000267600002E1828002128FFFF85
:2023F2001029103B41922E962576006F1B76F0FF00E2BD0030E6000602FE422916561F76FF
:2024120033002E92419623764000267600002E1820002128FFFF1029103B41922E96257608
:20243200006F1B76F0FF00E2BD0030E6000602FE422916561F7633002E92419623764000D1
:20245200267600002E1838002128FFFF1029103B41922E962576006F1B76F0FF00E2BD00C5
:2024720030E6000602FE422916561F7633002E92419623764000267600002E1838002128BC
:20249200FFFF1029103B41922E962576006F1B76F0FF00E2BD0030E6000602FE42291656F5
:2024B2001F7633002E92419623764000267600002E183E002128FFFF1029103B41922E9650
:2024D2002576006F1B76F0FF00E2BD0030E60006422916562376390110292576006F1B7627
:2024F200F0FF00E2BD0030E6000602FE422916561F763300229241962376010026760101BE
:20251200221848002128FFFF1029103B419222962576006F22761F767D0316D0008F806FB6
:202532003A9294CDFCFF03901F76BE0118D0A8CA16961F767D033B9294CDFCFF03901F760E
:20255200BE011AD0A8CA18961F767D033C92019094CDFEFF1F76BE01A8CA1BD01A961F76D8
:202572007D033D9201901F76BE0194CDFEFFA8CA1B961A7669FF060016D0008F806F1F769D
:202592007D039492039018D03A96949203901AD03B96949201901BD03C96949201903D96C6
:2025B20022761F76BE011618FCFF1818FCFF1A1A01001B1A01001A7669FF0600A9881F769A
:2025D2007D03319200D4003102521860A640036D008F0008A641056DA9A8A91A0002A98A46
:2025F200A642046DA9A88050A98AA643046DA9A80850A98A1F76BF0102A81F767D0331920F
:2026120003524960A69205601F76BF01041A0008015205601F76BF01041A000202520560AC
:202632001F76BF01041A8000035205601F76BF01041A0800045205601F76BF01041A020030
:20265200055205601F76BF01041A0001065205601F76BF01041A4000075205601F76BF01B5
:20267200041A0100085205601F76BF01051A0008095205601F76BF01051A00010A520560F8
:202692001F76BF010D1A20000B5205601F76BF010D1A04001F767D03319201521F60A640BA
:2026B200056DA9A8A81A0008A98AA641056DA9A8A81A0001A98AA642056DA9A8A81A000239
:2026D200A98AA643036DAA1A0200A644036DAA1A10001F76BF0104A80CA906001F767D0397
:2026F200319202520660008F880A1F76BF0104A8015209602FFF00161F76BF01128F000033
:20271200021E0AA81F767D03319203520B60A928CB0BA82800091F76BF01248F0000021E95
:202732000AA8060022761F76BE01408F806F061800000F8F00F0A5C4071800FF08183F0093
:20275200091800FF1BDD0BDE1606A918C0FF161EA9A818C0A89219C0C618EFFF0B18DFFF8D
:202772000B18BFFFC518F7FF1A76008FC06F1F767D03BF56300109D0CC92C4FF01F001906E
:2027920030721F76BF010192C3FF1F767D0301F0019080FF30721F76BF010192C5FF1F76E2
:2027B2007D0301F0019081FF30729492C2FF01F0019082FF309430960352036104520360FD
:2027D200BF5631010152036102520360BF5631030552036106520360BF563106075203606B
:2027F200BF56310208520360BF5631040952136131920152036106520360BF5635010252D5
:20281200036103520360BF5633010152066105520461056FBF563105BF56320131920152AE
:20283200036103520360BF56340202520360BF563401045217610152BF5636010360BF5639
:20285200370203520A610152086106520B601F76BF01021A80000A6F1F76BF010B1A0010FA
:20287200056F1F76BF010D1A001006520E6103520961015204610D1A0080096F0B1A008044
:20289200066F0B1A0040036F021A800006520B6104520961025204610B1A0004066F0B1A3E
:2028B2000040036F021A000206520661045204610B1A0020036F021A0800227604520A6287
:2028D20004522461015240610252346103522661446F0552116106524060088F8A021F7626
:2028F200BE01059AA82801FC0AA81A1E1F76BF01021A0800326F088F00001F76BE01049A0E
:20291200A82801BC0AA81A1E286F088F49031F76BE0105020AA81A1E206FA928CB0BA82869
:2029320008091F76BE010A1E059AA828257C1A1E146F088F8A0B1F76BE01059AA82801F845
:202952000AA81A1E0A6F2FFF10161F76BE010A1E059AA82813BC1A1E1A7669FF0600BDB24F
:20297200BDAABDA202FE1F767D03319200D200D3025232601F76BF0116D0008FC0DB09921C
:20299200C1FF94CDFEFF01F016D116D00190A8CAA9CDFDFF949616D0099203F01F766F032F
:2029B2000290A8CA9C9600CDFFF39492039089FFA8CA00961F76BF010040036C0102A98691
:2029D2000042026C02DA004A026C04DA0044026C08DA10D0947A1F767D0331920152316085
:2029F200408DC0DBA18A1F76BF01A183012916DCC418FDFF16DD0992C3FFA18A03F00290C5
:202A1200C59816DCC418FBFF0992412B008F78DFC1FF01F00190A95D20FFFFFF40763E80B9
:202A32000356A902A18A1F766F0316D0079016DCC49800CDFFE79192069089FFA8CA009687
:202A52001F767D03319204525B60408DC0DBA18A1F76BF0116DCC418FEFF01CC0004C9FF2F
:202A7200412BA95D008F78DF20FFE80340763E8016D91F76BF010190C198014B026C01DAAB
:202A92000148026C02DA0945026C04DA0942026C08DA014A026C10DA0147026C20DA0944BC
:202AB200026C40DA0044046CA9AA8009A9860149056CA9AA18FF0100A9860941056CA9AA5A
:202AD20019FF0100A986004B056CA9AA1AFF0100A9860045056CA9AA1BFF0100A9860940A8
:202AF200056CA9AA1CFF0100A986004A056CA9AA1DFF0100A98610D0008FC0DB947A1F76AE
:202B12007D033192065210601F76BF010046026D01DA0048026D02DA004B026D04DA10D0A8
:202B3200008FC0DB947A1F767D0331920552E0FF89001F76BF010945036D01DA026F10DB6A
:202B52000944036D02DA026F40DB0042036D04DA056FA9A21CFF0100A9820044036D08DA12
:202B7200056FA9A21DFF0100A9820046036D10DA056FA9A21EFF0100A9820040036D20DAEA
:202B9200056FA9A21FFF0100A9820048036D40DA056FA9A21FFF0200A982004A056DA9AA2F
:202BB2008009A986056FA9A21FFF0400A9820043066DA9AA18FF0100A986056FA9A21FFF12
:202BD2000800A9820045066DA9AA19FF0100A986056FA9A21FFF1000A9820047066DA9AA38
:202BF2001AFF0100A986056FA9A21FFF2000A9820041066DA9AA1BFF0100A986056FA9A242
:202C12001FFF4000A982004B066DA9AA1CFF0100A986056FA9A21FFF8000A9820049066D79
:202C3200A9AA1DFF0100A986056FA9A21FFF0001A9821F767D0310D0008FC0DB3EA2947ACD
:202C5200008FC06FCC92013B1F76BF01C4FF01F0019009D0A985A9860192C3FF01F0019063
:202C720080FFA9850156A2000192C5FF01F0019081FFA9850156A2009492C2FF01F00190B3
:202C920082FFA9850156A20017D0008FC0DB82FE947ABE82BE86BE8B060006000052A88880
:202CB200C48A096509520763FF9CC4CDF8FF0790A8CAC496A69245520D614E5208614F5214
:202CD2000D60C41A2000C418BFFF086FC418DFFF056FC41A2000C41A4000A592015203602F
:202CF200C4187FFF02520360C41A8000C418EFFFC418F7FF0600BDB200D5013B008F40DE84
:202D1200A9A8A581A98AC47D01DDA5924652F76433D1008F40DE34D0BF569C0CBF56940C87
:202D32001F76400335D03BD1BF56940836D0BF56940937D0BF56941038D0BF56940839D0AD
:202D5200BF56940C3AD0BF56940C3DD0BF569C053CD10092FE9C949641D00092FF9C94965F
:202D72003ED0BF56940810D0BF56DC08BF56E465BF56F408BF56940DBF56EC1BBF569C12A5
:202D9200BE8B0600A9BD120F00770077BDB21F7671038BE60100A48B50E8094088E23C001D
:202DB200407696B788E6000000770077A9BF120FC18AA993B7FFFF91D497C18AFF90DC9695
:202DD200BE8B06000852A927A4C50960089A01D54E9B4076BB93008D3B03972BAB9209520C
:202DF2000B60089AA78A01D54E9B4076BB93008D3B03BF5697010600A71EBDB2A492BDAA71
:202E12000152BDA22A60008F5070C08D40D01F76410300A822761F76BE01408F45B609CDAB
:202E3200FFF7A81A0004008F00B6099709CDFFFD1F763700A81A000100A01F76BE010997EA
:202E52001F76370002A81F763300321A0100321A0200237600011A7602523360008F507720
:202E7200C08DC0D31F764F0300A82276408F806F1F76BE01FDCDFFEF8076BBB5A58AA81A18
:202E92000020079716DD07CDFF3F1ADCA81A008007971F763700C518CFFF408F76B5C41A38
:202EB200040004C21F763300321A04001F76370006A01F763300321A0800237600011A7666
:202ED200D396A38A01D54E9B69FF089AC3864076BB93A2C4A2830BD0A28A0CDE0CDDC61AEF
:202EF20000400ADCC518FFDFCA18BFFFCA18DFFFCA18F7FFCA18FBFFCA1A0200CA1A010000
:202F1200C418FFBF92CCE0FF0BD0015092964076E893A38AA70640762F94D39202520560D2
:202F32001F76BF01081A0400C38A099ABF56E402A38A40764F94408D33030CD0932BA28A8A
:202F5200008D9E01932B9B2B0BDCC41A4000CA1A2000BE82BE86BE8B06001F764103BF56E5
:202F720002011F764F03BF5602021F764003009606000002008D4203941E0600BDB2BDAA66
:202F9200A486008D3A0392923660A9AA13FF6700A98A008D360301020156C4009206008D69
:202FB2003803920F0466C28ABF56E40208D092C5A7C408D0090201DE92C2C207A98A008D39
:202FD2003603C792C4969206008D3803920F4966C28AE446FE6CA28A099A40764F94D29297
:202FF200025205601F76BF01081A0400008D9E01922B376F008D3803928A408D3803A492DA
:20301200008D36030190A98801DC9AA89206008D3803920F0466C28ABF56E402A6920B60A2
:2030320008D092830902C207A98AC592A7FFFF90C4960D6F08D09283A5C408D0090201DE10
:2030520092C2C207A98AC592FF90C496008D36039206008D3803920F0466C28AE446FE6CBD
:203072001F763300211A0001BE86BE8B0600BDB200BEACA0BDAAA486BDA2A98201DEA61B73
:203092003075FD69D292025205601F76BF010818FBFF00BE01DEA61B1027FD69408D360386
:2030B200A9AB08D09AA20109921E008D3A03922BC28AE446FE6CA28A089A40764F9401BE4F
:2030D200008D38030102A30F92C21C68A7AB0902C207A98AC792C496C28AE446FE6C00BEDF
:2030F20001DEA61BE803FD69A28A099A40764F94D292025210601F76BF01009A081A040028
:203112000B6FC28A0902A7ABBF56E401C207A98AC792C496009ABE82BE86BE8B0600BDB2F5
:20313200BDAAA486EFFF3901C28AFCCCFF00A958EC47EDFF2C01408DA0019A92E0FF2D01BD
:20315200408D3B039A920152116000BE408D3D03BF569A01408D34039AC2408D3F039A2BB3
:20317200408D3E039A2B0DD19A2B408D3F039A92E0FF1301408D3D039A924F60F2C4208F4C
:203192000000A9A8A60F06662F8F0000A9A8A60F0867608F00000AD1208F0000F2A09AA82B
:2031B2000CD19A923A52E0FFF800408DA0019A922E60408D34039AC4A692A94001DE9AC2AB
:2031D200066DF28A0356A008C496076FF28AA9A80109F21EA092C498008D34039206E20F5B
:2031F200E8FFDB000FD10CD0BF569A33A28A099ABF56923340764F94408D3F03008DA001DE
:20321200BF569A01BF569201EFFFC700008D3F03BF569201EFFFC100408D3E039A923E6091
:20323200A0921F760E03305425611F7674033D5403603D921F60A088408D31039A0EA60FC6
:203252000560408D33039A921560A0921F7674033C5407603C920561408D33039A920A6150
:20327200408D3F03008D3D03BF569A01922BEFFF9400408D32039A78408D3E039A80019A9A
:20329200013BA7949A96A9AAA781A98A0ED1089A9C78A28A40764F947F6F9A80019A013B8E
:2032B200A7949A96A9AAA781A98A0ED19C78408D3E039A9207520E600DD19A9210520A6019
:2032D200408D33039A9206600A9A1F767903A0941096408D3E039A9203520B600DD19A59ED
:2032F200A19204520660059A008F40DEA0949C96408D3E039A9202521A60A0920DD10352AE
:203312009A78336842523166008F40DE949203522C68A09233520B600CD19A923A522560CB
:20333200A09233520460008D3D03922B0DD09258408D3E03008F40DE9A9294540467A91B11
:2033520090012A68A28A099A40764F94408D3D039A2B0DD0408D3F03BF569A01408DA001F4
:20337200BF569A01922B186FA28A099A40764F94408D3E039A2B0DD0408D3D03BF569A0172
:20339200408D3F039A2B922B076FC28ACC18DFFFC28ACC1A2000C28AEC46EDFFC7FE1F76F0
:2033B20033000BDC211A0001C41A4000BE86BE8B0600BDB2BDAAA486A61EBDA2A582D29246
:2033D200025205601F76BF010818FBFF408D360308D09AC292A2008D3A03BF569201C28A87
:2033F200E446FE6CA28A089A40764F94008D38030102921EC28300BE0902BF56E501C20773
:20341200A98AC392A7FFFF90C496A692BE82BE86BE8B06001F76BF0100920093C5FFD7FF64
:2034320001F001F10190019190FFA9CB0092CAFF01F0019081FFA8CA060009D0008FC06F05
:203452001F76BF0194CD0004D9FF09CC004090FFCDFFA9CBC492C2FF01F0019081FFA8CA59
:2034720006001F767403BDB20593A9800153BDAAE0FFFD001F767D0331930653E0FFF70059
:203492001F7671030493E1FFF2001F767403039302CBE0FFEA007FD0008FC0DB1193948837
:2034B2001660A646036C1546086CA647036D1547046D00530C600F6F061B7C0103680628BC
:2034D2007B01122B1128E803A71A0001061BF702E7FFC800A7920552056012930361A71AB4
:2034F2000002AC28F802AB282A00AA2B0B30608F0000ACA9080D6556A900A9A90156A500D2
:203512001E06C5961E06CD97D57FDD7E40767797E59640768A971F767E03ED9608921F7605
:203532007E03F5960680008FC0DBFD7FA4C508D009D11CDC7BDFC792A4C5008FC0DB9596BD
:2035520000D0C7929D96A9A80AD1A00DA71E5AFFA092A17218DFC7929D96A7A9A0920ED1DD
:20357200A17201D8C7929D96A0920452ED681F76740312D01392C076D1DF13D1959614D078
:20359200C7929D9615D1CF92959616D0D792A4C59D9614921F767D0350DF959617D018928A
:2035B2009596A9A851095AFFC792A7A918D119D09D96C7929596A9A87909A71EC792A4C53E
:2035D2001AD11BD078DF9D96C7929596A9A87A09A71EC792A4C51CD06FDF9596C792A4C573
:2035F2001DD01ED11F7674036EDF008F86DE95961FD0C7929D9620D11892959621D0199289
:203612009D9622D11A92959600D01B929D9623D11C929D9624D1A092A172949301D8A092AA
:203632009D970452F868C076DDDF28D129D01F767403C7929D96CF929596157EE5921696D0
:20365200A928F802ED93080A179708540260082B061BF8020267060A010201562000066FD9
:20367200BF561201036FBF560503BE86BE8B0600BDB2A888A98001D1BDAA0876303BBE5AEC
:20369200008F0010AA2BA727A9A8AB0F2A60A6935161A9A8AB0F2560A693015322601F7622
:2036B2007D03319206521D601F767103049219611F767403059201521461062BC076C0DB5A
:2036D200082B112B102B072B7FDF0A2BC7921596032B022B019ABF56050140769E972F6FCB
:2036F20020FF0110AB0F0B601F767403059201520661A6930461A61BE8031A6920FF021008
:20371200AB0F0460A61BF8020F68A78020FF0310A70F0860A692015205661F767403107E40
:203732000E6F00D10C6F1F767403077E086F097E066F1F767403BF560503112BBD7A007698
:20375200A192BE86BE8B06001F76740306930B8808920F0A0B1C0100112B062B0D970C7EE3
:203772000E96082B0600BDB20876303BBE591F767403059201521860010201561E000A0AF1
:2037920009920A5405660A2B019A40769E971F76740311920961FF9C11960660059A4076E2
:2037B2009E9740761199BD790076BE8B0600BDB20876303BBE59049A40769E97BD790076C3
:2037D200BE8B06000052A88005611F7674030D93046F1F7674030693005203610E88026F27
:2037F2000888005203610C27026F0B27A7550366009A1B6FA692A89EA794A908F802A91BEA
:20381200F8020668A90808FDA91BF802FC67AC28B07CAB32AC282A00A930AB07A40D208F91
:2038320000000156A400C4920600A927AB93A80800F00F5337660356AB01A988A60800E0AE
:20385200C076DAC3A706A60DA71EC7C52076A9284D55EFFF99002A9AEFFF9600A928F8022F
:20387200EFFF92001F7674030992EFFF8D001F7674031E06EFFF88001F7674031E06A80E08
:20389200EFFF82001F767D0331927D6F1F767D033092796FA928E803766F1F7674031192D3
:2038B200726FAB1B10105A68AB1B88101A671F76740310930460059301531361AB92A9082D
:2038D200F0EF2A9BA927C0005BBBA95C2ABEAB0E0FF6A61FA9931092079540764F99536F42
:2038F200AB1B00113B68AB1B7C1138671F767403069302530468AA280200026F062F200644
:20391200AB0800EFAA01A61EAB920360A6923B6F01520460A606A80E366F02520360AA9251
:20393200326F035205601F7674030F922C6FFC9C2ABEA927AB0E0FF6A61FA95DAA93A555C2
:203952000D69AB922A9BC0005BBBA95C0693AA9F009AA59540764F99166F009A146F1F7677
:203972007403109205611F7674030D920C6F06920A6F1F76740310920361039A046F1F76C8
:203992007403059206001F7674030592BDB2015227601F767D033192065222600876303B7A
:2039B200BE597FD0008FC0DB94881F767403150EA60F116040767797A9881F767403160ECF
:2039D200A60F096040768A97A9881F767403170EA60F0461039A40769E97BD790076BE8BE7
:2039F20006001F767403052B00B600BE062B009B00D0008FD1DF0F2B0E2B0D2B122B112B00
:203A1200102B142B132B0B2BBF560C01072B082BBF5609140A2B1EC320C2942B01D8A0922B
:203A32000352FC6800D0008FDDDF942B01D8A0920252FC681F7674031A2B192B182B1C2BFF
:203A52001B2B1597169717970600BDB2BDAA04FEA92F1F767D03A82D31920652426008762C
:203A7200303BBE59AACCFF1FAB28008000D04321A980427C417DAB92AACE1761A75A20FFA5
:203A92003101A20F0860AD8883DEA6881F767F0396921D96A79208520860AD8883DEA68854
:203AB2001F767F0396921E96AB9201D8C0FF01DFA927A0920352E0681F76740305920152B7
:203AD2000E6013578076D1DFC621029ACE7CD67D140A40769E97BD790076036FBD79007663
:203AF20084FEBE86BE8B0600608F00001F767403208F00FA22A024A82206261E282B220686
:203B1200046FA98A842BA9A81F767403240FFA680600BDB2A9A8BDAA10FFA101A98BA48610
:203B3200408FFFFFA98ABF56C1100602BF56C904D12BD92BE12BBF56E930407648B8A9CD3D
:203B5200FF00008D9E01A7FFFF90F197A28AA183F9960802BF5692014076A495BE86BE8B5E
:203B72000600BDB200BE00D0408FC0DBAA2B008F80DCA9A8A00DA98A9580C427A70EAB0F66
:203B92000361C47F01BE01D8A0928052F168A6921061408D80DC809AA18A407659B880D049
:203BB200A82802019196A18AA9287E3F40768FA5BE8B0600BDB2BDAABDA2AD5A88DAAD08B4
:203BD2008200A48B0ED90356D108D9CAA988A482A61B00100367009A3E6F0356E108E9CA98
:203BF2000876303BBE93AD5CAD5D08D09297A40880FFA5087FFFA6934196A45CA55DC992A2
:203C1200407663A0A98008D09292BD9600761F767403AD5CA9A23D8809D0A40880FF10FFB3
:203C3200A101417EC988A983A45CA98B427E9292439620FF9001447F4076DE9E00520A6141
:203C5200008D9E01A90EA38AA183BF5693014076A495019AAD087EFFBE82BE86BE8B0600E6
:203C7200A888A927BDB2A9A8A48B1F767403BDAA10FFA101408FFFFFA71EA986A98AAB92EE
:203C92003D278050C73FCF960302D77E407648B8A9CDFF00A7FFA283008D9E01FF90A18A3D
:203CB200DD97E5960502BF5691014076A495BE86BE8B0600BDB2A48B4076479B00523760B4
:203CD20000D5008DA101A9B2A50DA71EA9B2A50DA98A01DD0EDFC7929496A5920852F46881
:203CF200A18A0EDC0356D408DCCAA9580356E408A093ECCA80531667008FC0DB9496A092BD
:203D12007F52036040764499A9B2008D9E01A18A10FFA101BF569101A9830A024076A49599
:203D3200066F069A029BA18A40769D9BBE8B0600BDB2BDAABDA202FEA4864076479B00520E
:203D52007E60A28A0EDC0356D408DCCAA9270356E408ECCAA988FF9C7D526C67AB9280523A
:203D72006967809AAB9EA6546568A9AA10FFA101A71E00D41F7674033D92C7960356A60162
:203D9200BF56CF03D796A6921E61A458AB92408FC0DB03D1A0720356A401A980A9AA952F3F
:203DB20010FFA101A983A792A17204D0AA92C7FF9D96A792A07201DCAACCFF009596A692BF
:203DD200A454E4660356A6014196A993039A408FFFFFA894A959A9AA10FFA101A982A98A72
:203DF200A10E407648B8A9CDFF0004D0A7FF9B974193A073FF90AB280500089B9396AB92D4
:203E120041944195A958069A4194A980079A4194932BA758A859932BA958A28AA383A10E52
:203E3200932B008D9E019B2BBF5692014076A495066F039A029BA28A40769D9B82FEBE82A0
:203E5200BE86BE8B0600BDB2AC2BAB2808008076ACDF0C3505D106D0A483A172A072A980B9
:203E72000EDD03569D089594AC5807D19696AB92A794A958A793A173009B95929DCA0052D4
:203E92000261019BAC92AC58408FA4DF019C0852A92D9597DF68BE8B0600BDB210FEAD5C68
:203EB20089DCA45DAD5CC0768CC38FDCA45C08F6852400D0C0769CC305F68424008FC0DBB8
:203ED200942B01D8A0928052FC68A4C51F767D0330921F767D037EDFC7963192045208613F
:203EF20060D162D0BF569C0ABF569408116F1F76700300D0BF562002AD5C8FDCA45C9492B8
:203F1200008F22DC949601D8A0920652F66861D0008FC0DB1F767D03BF569465379204616B
:203F320063D0BF5694141F767D0336921B611F767D0330883092085281DE0365308882DE5E
:203F520000D00129008F34DC0356A603C076C0DEA00D0156A700C792949601D8A09208524D
:203F7200F4681F767D03319201521A601F767D033788012920FFF2FF00D0A60F1161008F9A
:203F9200C0DBA9A8A00DA98A30D101D8BF569C4648D1BF569C3C37920E9CA054F1661F7619
:203FB2007D0331920252216000D0008FC0DBA9A8A00DA98A01D830D1A092BF569CAA0652ED
:203FD20048D1BF569C96F26806D0008FC0DBA9A8A00DA98A01D830D1A092BF569C7308525A
:203FF20048D1BF569C69F2681F767D0331920352116000D0008FC0DBA9A8A00DA98A01D880
:2040120030D1A092BF569C46145248D1BF569C3CF2681F767D03309209521B6000D0013BE5
:20403200AD5C89DCA480008F40DFA7069481A71E008F08DCC792949601D8A0920F52F168EC
:204052003DD1008FC0DB3ED0BF569C46BF5694461F767D03319206522B60008FC0DB30D03D
:2040720032D19428A401A4C531D09428A40133D09C2884037ADF4BD19428840348D0942825
:204092002C0149D094282C014AD0942820039C282003C792A4C56ED051D194967BDF6FD01A
:2040B200C792949650D0BF569406BF569C101F767D0335920A6100D0008F30DC9428000865
:2040D20001D8A0920452FB684076D88390FEBE8B0600BDB2408D80DCA9287E3FA828020123
:2040F200A18A4076D2A5809AA18A407659B8A98080D0A988910EA70F0E60A688012920FF66
:20411200FFFFA60F08611F767D0330887ED0910EA60F15614076BA9C408DC0DB7FD0912B0D
:2041320040761E9B1F767D03349217617FD91F767103C11A10001128FFFF0F6F00D0008F4B
:2041520080DC9492008FC0DB949601D8A0928052F7681F7670033F2BBE8B06004076A59887
:2041720006000652A888436103520361019A486FA5921C60A492FF9C7D523F67A61B001026
:204192003C68A61B10100667A9281010A69EA4543667A61B10103168A61B88101F67A92827
:2041B2008810A69EA4541A682A6FA68020FF0010A70F0460A49210522261A68020FF10100F
:2041D200A70F0C60A49228521A6150521861785216612A52146154521261A68820FF0011BC
:2041F200A60F0B60A4927C520860096FA61B00100468A61B03100369029A026F009A06007F
:20421200407682990600BDB2BDAABDA206FEA927A85B44A052C44F92A4864196505D46C218
:204232004406036146060360009A366FAB92415CA39340761E9E468A0052C4962860A9AAF7
:204252002361AB9203520461E20604601D6FD2061B61AB9203520961E2C5C28AA3924193AD
:20427200673E00521161136F419200D11561A192D2C5C28AA394673E448A9C9601D9419288
:20429200A154F666096F468ABF56C403448AC47B4193029ACC9786FEBE82BE86BE8B060060
:2042B200A993FF90D7FFC497CC960600A9838076FFFFA9A00360A692146F8492FF90A6F2C4
:2042D20081DD009BA640046CC07601A0026F00B6A692019DC0FFA770A9880853EB67F36F93
:2042F2000600BDB2BDAAABA0BDA2A982A9A04C884B804A58495AA4833061A2922E61F7520A
:204312002C66A0927F522966A792FF52266600522160A9A02261A092035208600352086006
:20433200A692FF9C7C520468186F06521660A09206520460A69202521060A7920B60A09249
:20435200065206610356A601059CA90E046F0802026F0502A30F036900BE4A6FA4A9A79224
:20437200C47ACC782A60A09206521B610356A601D49600D0A6920F610356A001A980A9A9C2
:20439200A70DA98A959203DC4076BD9E01D8A692A054F3660356A601039CA90EAC1E126F0E
:2043B200C59202DC4076BD9EA4A9CD9204DC4076BD9E0602AC1E066FCC1A80000302D47F03
:2043D200AC1EA4A94076C39EA6A9A980A4ABA9AB0156A600A5A901DCA7CDFF00C697A9A839
:2043F20001DC0156A500A4C4A792C7FFC596BE82A606BE86BE8B0600BDB2BDAABDA2AD5A55
:204412008CDAAD0886000ED092A0D28010D0C227CA88927F0CD0DA5B921E0ED092060E61B5
:204432000CD092C5FD02A70F0966A392FF9CF752056710D092927F5203690002216FAD5DB1
:20445200A5087FFFA580AD5D413FA50880FF422BA69344C3A55D4076709EAD5C11D1417B2A
:2044720010D0A40880FF92930ED04297A45C9A934397449692830CD092064076DE9EAD08F2
:204492007AFFBE82BE86BE8B0600BDB2BDAA0AFEAD88C076A2C3AD58808D6D9E408D1B9E6D
:2044B20053278ADEA688522F512D8AD805F6862448AA46B2417DA483A05C42214357443F89
:2044D2004076699F8AFEBE86BE8B0600BDB20AFEAD88C07696C3AD588ADEA6884F27408DD8
:2044F2006D9E8AD805F6862480761B9E48B246C2413FBF56420144A0A483A05C4076709E44
:204512008AFEBE8B0600A4C4BDB2A827A95C4680452FA6061461A9A01261A49202520F68EF
:204532007C520D66A4400B6DC0FFAB540869AA92FF9CFF520467A792FF520369009A1A6FF1
:20455200A68A0356AB01A9599C92A58A4076BD9E01D0A192A072969202DC4076BD9EA58A48
:20457200A928001FAB9404DC4076BD9EF557089AFD7FBE8B0600BDB2BDA20AFEA827A92FD3
:20459200A9A0A5825487528851802C61A9AB2A61417FAD5DAA92AB93427E8ADDA55D407684
:2045B200F09F00521F61012903564A0849AF3FFFA71E03564808A988A38AA706A6AF47AFB9
:2045D200C41E0356460845AF3FFFA71E03564408A988A4ABA706A6AF43AFA71E089AC4C342
:2045F200026F009A8AFEBE82BE8B0600BDB20AFEAD88C076A8C3AD588ADEA6884F27408D5C
:204612006D9E8AD805F6862480761B9E48B246C2413F422B44A0A483A05C4076709E8AFE85
:20463200BE8B0600C493CC92A8380600BDB2BDAABDA204FEA61EABA0A9A0A48B52874D5A40
:2046520050821F61A9A21D610802A60F1A60FD02AC0F1766A292FF9CF7521367A4A9C48892
:20467200A20EA60F0E6000D09492FF520A6601D8A0920852FA6808024076C39E0052036100
:204692000002156FA4A902DC40767FA0A4A9A98804DC40767FA0A4A9417AA383CC934297E9
:2046B200A18A437E4496A9AB4076699F84FEBE82BE86BE8B0600BDB2BDAA04FEAC1EA5C4B0
:2046D200A9A0A48650C54EA34C8E3961A93A3761A9A93561A70633610802AC0F3060A9AB8E
:2046F20000D40D61A683A9A80156A500C592FF52266601DCA483A9ABA50FF566A68A04DC45
:2047120040767FA0A95D20FF001FA50F1860A683F5921561A4A9C496A68A40767FA0A927A0
:2047320002DC40767FA04196BF564201AB93A28A44C3FD92A0834076709E026F009A84FE11
:20475200BE86BE8B0600A988FF9C105203670253036900310B6F0129AB28FFFFAA28B9002A
:204772000356A804A60D0156AB00A9A906000600A983C57C0600BDB2BDAABDA206FE1F76CE
:204792007403A482BF5602010EDCEC92FF90A95AE492FF90A988A9AA37FFA6AFA986DC92A7
:2047B200FF90A988A9AA37FFA6AFA986D492FF90A98809D0A9AA37FFA6AFA9869492FF9059
:2047D20008D0A9599492FF90A988A9B237FFA6AFA98BFC92FF90A988008D3203A9B237FF4C
:2047F200A6AFA98BF492FF90A988408FFFFFA9B237FFA6AFA98BA9A210FFA101A71E441ECE
:20481200A98A9392C7960202BF56CC34407648B8A90E461EA28A465DA9B240761EB841965A
:2048320044830102A38A4076A49544830102A38ABF56C5344076A4954192A90E461EC38A51
:20485200E446FE6CA9B2A38AA28340764697C38AE446FE6CA9A210FFA101A983A38A469264
:20487200A993FF91A7FFFF90C597CD960602D52BDD2B4076A49586FEBE82BE86BE8B060010
:2048920006000600A98AC4920600A988BDB21F767103A9A8008D3203A48BBF560101BDAA02
:2048B20010FFA101408FFFFFA71EA986A98A9193C7970202CF7E407648B8A9CDFF00A2831E
:2048D200A7FFFF90A18AD597DD960602E52BED2B4076A495BE86BE8B0600BDB202FEA48B37
:2048F2000EDCEC92FF90A980E492FF90A988A70637FFA6AFA71EDC92FF90A9880129A7064E
:2049120037FFA6AFA71ED492FF90A988412BA70637FFA6AFA71EFC92FF90A9934196F492F0
:20493200A838419620FF0080A70F0666A706415C407625A1086FAD5CA792029B81DCA45C74
:2049520040768FA5399AA18A4076B2A182FEBE8B0600BDB2BDAA02FE1F767103A486BF5667
:2049720001010EDCEC92FF90A980E492FF90A988A70637FFA6AFA71EDC92FF90A988A706F5
:2049920037FFA6AFA71ED492FF90A988A70637FFA6AFA71E012920FF0080A70F0666A706FA
:2049B2004076AFA14196086FAD5CA792029B81DCA45C4076D2A5A9AA008D320310FFA10162
:2049D2001F767803A71EA98BA98A9292408FFFFFC796BF56CF384192FF90D7964192A7FFD7
:2049F200FF90DF963A92A9CDFF00A7FFFF90E197E9960602407648B8A9CDFF0009D0A7FF82
:204A1200A183A28AFF9008D1F597FD960A029D2B952B4076A49582FEBE86BE8B060002FE17
:204A3200A61EAC281F00013B2256A60740FF0156A400C492A640036CFF90036FA7FFFF9031
:204A520082FE0600BDB2A48BBDAAE1C50AD09183A706A58A021940767CA2A927A706A58AAE
:204A7200011940767CA2A1C5008D3203408FFFFF0EDF0356A908AB94A95AA78A9192C79657
:204A92000202BF56CF33407648B80AD0A95DE106918A021940761EB8A988A20EA60F1061A3
:204AB200008D3C03912BD192025205601F76BF01081A0400A18A099A40764F94096FA18ABB
:204AD200339A4076B2A1008D3C03BF569101BE86BE8B0600A4830EDDED92FF90A980E59228
:204AF200FF90A988A70637FFA6AFA71EDD92FF90A988A70637FFA6AFA71ED592FF90A98894
:204B120009D0A70637FFA6AFA71E9592FF9008D0A90EE41E9592FF90A988E40637FFA6AF0A
:204B3200E41EFD92FF90A988E40637FFA6AFE41EF592FF90A988E40637FFA6AFE41E0202D9
:204B52000156E4000AD01F7674033A9AF4C394C3BF5602014076B2A106000600BDB2BDAA3D
:204B7200BDA2A482008DA00193923D61408DA0010FD09B2B935A008F40DE013BA9A8A28150
:204B9200A98AC49203523268A91B90012F66A29233521A61008F40DEA9A8A281A98AC458FD
:204BB200A059408FFFFFA38A82D981D8A1880EDC035694089CCAA959A606407648B8A18841
:204BD200A90EA60F05600CD0A292937A1C6FD392025205601F76BF01081A0400A38A099AE1
:204BF20040764F94A928FFFF0E6FD392025205601F76BF01081A0400A38A099A40764F94BC
:204C1200A928FFFFBE82BE86BE8B0600BDB206FEA48B0EDCEC92FF90A90E421EE492FF902B
:204C3200A988420637FFA6AF421EDC92FF90A988420637FFA6AF421ED492FF90A98809D09E
:204C5200420637FFA6AF421E9492FF9008D0A90E441E9492FF90A988440637FFA6AF441E4C
:204C7200FC92FF90A988440637FFA6AF441EF492FF90A9880DD0440637FFA6AF441E94921D
:204C9200FF900CD0A90E461E9492FF90A9880BD0460637FFA6AF461E9492FF90A9880AD0C0
:204CB200460637FFA6AF461E9492FF90A9880ED0460637FFA6AF461E94CCFF0004520A6188
:204CD200055212604206448A46C4A6934076D2A5076F4206448A46C4A69340768FA53C9AE4
:204CF200A18A4076B2A186FEBE8B0600C4A0D41A01000600C4A0D41A02000600D493009AE7
:204D1200039100530260019A06001F76BF010118F7FF06001F76BF01011A08000600227617
:204D320008D0408F806F1F76BE0195CCFCFF015008960BDD08CCF7FF0450089608CCDFFFD6
:204D52001050089608183FFF1F76BF01C51A08000118F7FF1A761F76C10169FF0002BF5634
:204D72000007BF56011F022BBF56040D0A2800800B2B0C2BBF560F10D42BC41E001A8000C4
:204D920006001F767C030188BDB2A48BA6921352E6FF5801C076B2C30129A7060456A60162
:204DB200A71EC7C52076C18A020ED40F0561BF560111EFFF470108D091C5673E1F767C0312
:204DD200012B022BD118F7FFD118FDFFEFFF3A011F76C1010246ECFF3501C18A1F767C035C
:204DF200020EC407A71E1F76C10107921F767C03C796BF560113020AEFFF24011F76C10101
:204E12000246ECFF1F0107921F767C03BF5601110396EFFF17011F76C1010246ECFF12011D
:204E320007921F767C03BF56010F0396EFFF0A011F76C1010246ECFF050108D091C5673E99
:204E52001F76C10107400B6DD118FBFF1F767C03D118FEFF012B022BEFFFF4001F767C03FE
:204E7200BF560109EFFFEE001F76C1010246ECFFE90007921F767C03BF56010B0396EFFF5D
:204E9200E1001F76C1010246ECFFDC0007881F767C03037EC18A020ED40F0561BF560107D4
:204EB200EFFFD00008D091C5673E1F767C03BF560109EFFFC7001F76C1010246ECFFC2001B
:204ED20007921F767C03BF5601070396EFFFBA001F76C1010246ECFFB50007921F767C03C9
:204EF200BF5601050396EFFFAD001F76C1010246ECFFA800079208D01F767C03039691C5AB
:204F1200673E1F767C03BF560103EFFF9B00D140086CBF5601010AD0D11A040091C5673EC4
:204F3200D141ECFF8F001F767C030AD0BF56010DD11A080091C5673EEFFF84001F76C1010B
:204F5200BF56008F082B021A20001F767C03BF560112776F1F76C101BF56008FC18AE4924E
:204F72000896021A20001F767C03BF560110696F1F76C101BF56008708280003021A2000D1
:204F92001F767C03BF56010E5C6F1F76C101082B021A20001F767C03BF56010C526F0AD065
:204FB20091C5673E1F76C101BF56008708280005021A20001F767C03BF56010A426F028019
:204FD2001F76C101BF56008FC18AA706C407A71EC79208961F767C03020A1F76C101021AB2
:204FF20020001F767C03BF5601082B6F1F76C101BF56008FC18AE4920896021A20001F7688
:205012007C03BF5601061D6F0AD091C5673E1F76C101BF56008708280002021A20001F768C
:205032007C03BF5601040D6F1F76C101BF56008708280006021A20001F767C03BF560102B8
:20505200BE8B06001F763000A880A927A48E142820400002008F10DF1F7678033A1E4076C6
:20507200EBA30052FD61A792A793C0FF0191A995A880A7922661408F04DFAB9220BE1F907A
:20509200A674A792A6540267A7881F767C03A65C0356AB01043AA90E06A8081E008F10DFB7
:2050B2004076E3A34076EBA30052FD61A93AA60DA98EAB92A694A927A792A69EA980DE60B6
:2050D2001F7630001428104006001F763000A880A927A48E142820400002008F10DF1F76C7
:2050F20078033A1E4076EBA30052FD61A792A793C0FF0191A995A880A7922661408F0ADF35
:20511200AB9220BE1F90A674A792A6540267A7881F767C03A65C0356AB010A3AA90E0CA804
:205132000E1E008F10DF4076E7A34076EBA30052FD61A93AA60DA98EAB92A694A927A79232
:20515200A69EA980DE601F76300014281040060002FE1F767C0314C5008F10DF673E227693
:205172001F763400008FFBB91CA81A7669FF407608B91F7671030F8F40423A0642A8C000CB
:205192006BBAA9BD120F0077007702E84116008F38DE89E60000407647B92376002082FE1F
:2051B200060002FE22761F767D03319204520460008F25B4036F008F77AC1F7634001AA896
:2051D2001A760F8F40421F76710369FF3A0642A8C0006BBAA9BD120F0077007702E8D1233A
:2051F200008F30DE89E60000407647B91F7630000C2820402376001082FE0600BDB2BDAA7D
:20521200BDA24076EDB300D3103B69FF407695BA267600002F760000407648BB407677B95C
:205232004076FF901F767D03009A3093407620A90D9A40761A95418F00C201D4A9A04076B4
:2052520069941F767D0337920860418F00C202D4A9A040766994076F012902D420FF00E11F
:2052720040766994407615A640762990008FC06FA48300D20BDC0CDDC51A0100C41A010043
:20529200012920FF50C3407666B9008FC06FA48301DAA2920EDC0FDDC51A0100C41A010042
:2052B2000A52EF64008FC06FA4830BDC0ADDC51A0100C41A01004076F78F4076E19A407698
:2052D2005E9A1F767D03109B309240766ABB40763EA64076B4BA1F767D0331920452056115
:2052F20040763CAE407638844076AE854076D69D4076D8831F767D0331920652036040761E
:2053120011B01F767D03C076C0DB30927EDFC79622761F76C001BF56292F1A761F76710364
:20533200BF56040169FF40768BA81F76710303927B6163D0032B008FC0DB94920D611F76C2
:205352007F0363D0140A949214540666142B008FC0D34076F69A00D2008FD7DF013B408FA5
:20537200C0DBA9A8A281A98AA9A0A281A98360D0C40A9592C4545466005252611F767F032E
:2053920017924E61408FBEDEC42BA9A0A281A98AC49280520868008FBEDE013BA9A8A28137
:2053B200A98AC42B013B086F109AA794A9CCF0FFC4968052F167008FBEDEA9A8A281A98A67
:2053D200C4800356A203408FF0D8A61EA792C3FFA927A606AB0D0156A500A7CD0F00A82D9B
:2053F200C59262FFA988E161013B0A6F008FBEDEA9A8A281A98AA692A0FFA988C40AA6402D
:20541200F66C408DBEDE013BA9B2A281A98B008FC0DB009AC193407638AAC108030001DA6A
:20543200A29202529A647FD0008FC0DB9441066C7FDCC418FDFF4076BA9C7FD0008FC0DB5C
:205452009442066C7FDCC418FBFF40761E9B7FD0008FC0DB9443066C7FDCC418F7FF4076AD
:20547200D69D7FD0008FC0DB9445066C7FDCC418DFFF4076538040761C921F767D03319209
:205492000152136016D0408FC0DB9592A58AC1FF01F016D0A3CE0356A9027FDC0790C49834
:2054B20095CC0400C1FFA95B319206525A607FD0008FC0DB94921F767F03A99300B6D6FF5F
:2054D200C5FF01910190A9881592026001B6A892A7CE1B61008FC06FA4831F767D030BDDD5
:2054F200C51A0040319206520761045205610DDCC41A0020056F1F76BF01041A0800008FD7
:20551200E8031F767E0308A81F767F03169200B61597026001B6A693A7CF16611F767D0353
:2055320031931F76BF010B1A000406530661045304610B1A0020036F021A0800008FE80346
:205552001F767E0308A81F767F03167E1F767E03080607601F76BF010D1A00400D1A000456
:205572004076309A00D2A2920461408D40D0036F408DC0D3A18A40761BA3A91BFFFF596164
:205592001F76BF0100BE0F1A01001F767E03375222C213623752326133520A6233523A6197
:2055B2000352446104523E6106523861426F34522D61355227613D6F3A5208623A52126184
:2055D2003852186139521261346F3B5207613C523060A18A407673A32C6FA18A40761AA3D2
:2055F200286FA18A4076D7A2246FA18A4076DAA1206FA18A407616A21C6FA18A4076ADA1D7
:20561200186FA18A4076AEA1146FA18A407628A1106FA18A40768FA20C6FA18A4076C79B45
:20563200086FA18A4076909C046FA18A4076059C01DAA2920252E3FF77FE966FBDB2BDAA4A
:205652000AFE1F767D03219225611F76800108421A6D0A420A6D1F767803FABE32061F76A3
:205672007D032E03A60F7C6904021F768001061E0A42766C1F767D03212B1E2B1F7680019F
:205692000A1E0D6F1F767D030402212B1F768001081E1F767D031E921F5423661F767D03DB
:2056B2001A921C610876303BBE5A1B59AD5D1C93008F40DD1D88A1CCFF0089DD1A2BA55D17
:2056D200417E4076D39F1F767D03A1CD00FF1F2B49CB1E962097BD7A00761E921F5440690D
:2056F2001F7680010406A9403B6D1F767D032092AD5CAD5DC7FF1F93419686DC88DDA488CB
:2057120020C6D0FF4296A55D008F40DD1E9244C2407628A0005205601F767D031E2B206F64
:205732001F76780332C5040204BE1F768001468A48A3081E1F767D031F0802001F7680013D
:205752000AC21F76840116A81F767D03BF5621012EC31F76840114A91F768001041E8AFEBF
:20577200BE86BE8B0600BDAA34FEA892FF9C0564105204640F9A026F009A22761F76BE0143
:20579200AB28F0FFAA28457F09CDFFDF013B08B6A81A0010A4A908BE099700D209CDFF3F86
:2057B200A81A00400997A9851F7680015AFF2AC35D56A400A0A9AB2BAA28467F08D42CC2D4
:2057D200ACA91F7684015AFF5D56AC0002A8A5A9AB28E0FFAA28457F0AC3AB03AB28FAFF09
:2057F200AA28FFFF12C21F76800107BE00AA1F768401003A08A0101E1F76800102A900C2C1
:2058120000BE0002011960C2601A80F2081E000260C401190C1E000201191E1E000201198A
:20583200221E00020119181E14C21844FF6C16065E1E5E18FFFD5E1A00015D1800FF5D1AB9
:2058520005005E1A7F005E18FAFF5EC416C26018FFEF6006141E1844FF6D0002488F70645E
:205872001F768301541E088F7064541A010000A00031531A0200010200BE02A8541A060092
:205892001F768001408FBEB800D4301E54C5020232A82EA9008F93B81F76370008A01F76C8
:2058B2008001241E26C220C31F7637000AA81F763300321A1000321A2000237600011A7610
:2058D2001F767D0369FF000200B6182B261EB4FE22C224C3BE86060006FE00021F767E0317
:2058F2000ED0221E94A3AA8820FF001F0CD094C5A60F3D61A9A9A80EA958463FA0CC0080CF
:205912004396A0CC00404296A0CC00204196A706A018FF1F45974392447F00520861A092D1
:20593200805205674692008FC0DB9496429201D80861A092805205674592008FC0DB94963A
:20595200419201D80861A092805205674492008FC0DB9496A9A9455C445DA80E46934076AD
:20597200929A1F76BF010F1A0100146F0AD094920F9008520F60A9A9A91800FF009158FF85
:2059920009611F767D03A7061B3F1C971D7FBF561A0186FE06001F767D031992A88809610C
:2059B2001F7680010806A940046D0A06A9403E6C02D5A692013BAB28010001B6A572AA2BF2
:2059D2001F768001A9A8A581A98308A90AC301B6C58500915AFFA692A772A9A8A781A9839D
:2059F200C5853FFFABCAAACBA71EA9A8A681A98A1F768401C48500915AFFA6853FFFAACB88
:205A1200ABCAA81A00E0061E04C322761F76800100022E1E1A760102041E1F76BF010E1A44
:205A320001001F767D03BF56190169FF06001B76F0FF0500BDABBDAABDA8BDA0BDC2BDC38C
:205A520000E2BD0003E2BD0003E2BD0103E2BD0203E2BD0303E2BD0430E6000602FE69FFDD
:205A7200422916561F7633002292419623760100267601012218FA002128FFFF10291F7669
:205A92007C033C060461010241563C001F7671030492E1FF99011F76710311920D61FF9C2A
:205AB20011960A60008FC0DBA4837FDC7FDDC518EFFFC41A04001F767D033592196100D2E6
:205AD200008F0871013BA9A8A281A98AD492C3FFA988008F3CD7A9A8A281A98A69FFA2928B
:205AF200C47E4076568601DAA2920452EA641F767D03319206523A601F76C4010992C3FF8C
:205B1200A90EA9BD120F0077007763D0808DC0DB8BE60400008F40D78CE6200069FF13E262
:205B32009200CFE62000407634BA6ED16FD0013B008FC0DB9A92929EA985A9BD160F6FD010
:205B5200C8E29402CFE6040020E7A00089E60900407696B750E800C8007790E8008800772A
:205B72008CE600001DD013E292001F767D0331920552436000D21F76710306921F767C03D4
:205B9200390A39540262392B008F0871013BA9A83981A98AC492C3FFA90EA9BD120F392D1D
:205BB20069FF008F40D712358BE604000156A400CFE62000407634BA013B1F767C03008FB6
:205BD20086DE8EE60000A9A83981A98A13E2C400008F40DFA9A83981A98A01DAC49208526D
:205BF200056139924076EE82056F3992009B40761181A2920652C0641F767D033492E1FFAF
:205C1200E3001F767C033888350EA60F1A601F767D0332931F767C03399200530F611F7638
:205C32007103055402600D9A1F767C0339931F767103059F015302600C9A69FF40764B909A
:205C52001F767C033692385472671F767D03349200D26D651F767C03392D008F0871013BB4
:205C72001F767D033412A294A959A9A8A281A98AC492C3FFA980A7BD160FA188008F86DEF2
:205C9200A9A8A681A98A8BE60C00C4E2C400007720E7000100778CE6000000771F767C036D
:205CB200A9BF120FA98556FF009B37540267019B37543A970767008FD9DFA9A8A281A98AE3
:205CD200C40A008FA2DEA9A8A181A98A009AC49300530260019A3ACA2461A12D008F40D7F1
:205CF2001235CFE6200069FF0156A400407634BA1F767C033C0608618EE62000007700772E
:205D1200A6BF120F076F8EE6000000770077A6BF120F008F86DE013BA9A8A181A98AC47E76
:205D320001DA1F767D03A292345495641F767C033492380A38544766382B69FF4076DB906B
:205D520000D21F767D03349220651F767C03392D1F767D033412A294009BA959407611810F
:205D7200013BC076D9DF008FA2DEA706A281A71EA9A8A181A98A01DA1F767D03C792C496FA
:205D9200A292C72B3454E2641F76710305921F767C03029C390A395416621F767D03379285
:205DB20000D21F767C03392B0E651F7671030692019BA2944076118101DA1F767D03A29235
:205DD2003754F464008F0071A4831F76330019DC01DDC51A0040C41A1000BF562101103B7D
:205DF200419282FE2296AFE2BE04AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC54E
:205E1200BEC4BE83BE8ABE86BE870300303BF1FF177602761B76F0FF0500BDABBDA8BDA0CA
:205E3200BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FE69FFA0
:205E520042291656227601021F76780301563200237600102676391110291A767FD0008FEF
:205E7200C0DB944F046D69FF4076C8B21F767103020A029214520468022BBF56030116D1E1
:205E9200008FC0DB7FD09C9294CA0190A9880C9301F10191A6CB10601F767D0331930653F3
:205EB20006611F76BF010B1A0008146F1F76BF010B1A00200F6F1F767D03319306530661B3
:205ED2001F76BF010F1A0008056F1F76BF010F1A00200653E1FF4B011F767103150A1593C3
:205EF2000A53E0FFA1001F767D0331931F7671030553152B03601B9322601F767D033193CD
:205F1200015305601F7671031A9319601F767D03319306530F6104530D61025306611F76CF
:205F3200BF010B1A0004226F1F76BF010B1A00401D6F1F76BF01021A0002186F1F767D0380
:205F5200319306530F6104530D61025306611F76BF010D1A00040A6F1F76BF010D1A00406C
:205F7200056F1F76BF01041A00021F76710319930F601F767D033193035313610153116199
:205F9200065319601F76BF01021A8000186F1F767D03319303530F6101530D610653066184
:205FB2001F76BF010B1A00100A6F1F76BF01041A8000056F1F76BF010D1A00101F767103D0
:205FD2001A9315601F767D03319306530B610353046101531561196F1F76BF010B1A004028
:205FF200226F1F76BF01021A80001D6F1F767D0331930653146103530D61015306611F76C6
:20601200BF010B1A00800F6F1F76BF010D1A00800A6F1F76BF010D1A0040056F1F76BF0191
:20603200041A020000523E601F767103158062D0940EA70F37601F767D03319303530F61E0
:2060520001530D61065306611F76BF010D1A00100A6F1F76BF01021A8000056F1F76BF01ED
:206072000B1A001006530E6103530961015304610D1A0080096F0B1A0080066F0B1A0040FA
:20609200036F021A800006530B6104530961025304610B1A0004066F0B1A0040036F021A0F
:2060B20000021F767103009A1C9300530260019AA693A9CF04611428F401162B140AC4E2DE
:2060D20014001C7E12E8D01F14AD5564160A1693019100B6142B179716930791026101B644
:2060F200A692187F3C601F767D033092095224611F76710316D0BF56190194937FD0D0FF09
:206112009492C9FFA8CAA940026C197F0C42116D0C430C6D0C44036D1A2B2D6F1892009BA4
:2061320000520260019B1A97266F17921A96236FBF561A01206F1F7671030C41BF561B0186
:20615200036C1792026F009A0C401A96036D192B126F179317921B9719960D6F1793178860
:20617200179219971B961A7E066F69FF407680B04076209982FEAFE2BE03AFE2BE02AFE285
:20619200BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF1776027602FE89
:2061B2002276008F84AA1F7635000AA81A7669FF407616BB1F763300221A200023760100BF
:2061D20000D5013B008FA2DEA9A8A581A98AC42B008F86DEA9A8A581A98A01DDA592C42B53
:2061F2001C52F1641F767D03319206522360008F00711F76C401D4CCF0FF05500296DCCC99
:20621200F0FF0350039603CC1FFF1050039603CCFFF1A91A0005039603CCFF0FA91A0040AB
:206232000396E4CCF0FF0750049604CC0FFF205004961F767D03319203521460008F00719A
:206252001F76C401D4CCF0FF02500296DC18F0FF03CC1FFF1050039603CCFFF0A91A00020D
:2062720003961F767D03319201522860008F00711F76C401D4CCF0FF06500296DCCCF0FF52
:206292000550039603CC0FFF4050039603CCFFF7A91A0007039603CCFF0FA91A0020039677
:2062B200E4CCF0FF0350049604CC0FFF6050049604CCFFF1A91A000104961F767D03319222
:2062D20002520960408F0071A58A02DCC418F0FFDD18F0FF319205524C60408F0071A58ABE
:2062F2001F76C40102DCC41A0F00DDCCF0FF0250039603CC3FFF3050039603CCFFF0A91A3D
:206312000006039603CCFF0FA91A00C00396E5CCF8FF0A50049604CCBFFFB050049604CC3F
:20633200FFF7A91A0007049604CCFF0FA91A00400496EDCCF0FF0550059605CC1FFF10508F
:20635200059605CCFFFEA91A000E05960518FF0FF5CCF8FF08500696061AF00006CCFFFDA1
:20637200A91A000D069606CCFF0FA91A00900696408F0071C0760068A5C41F76C401A78AFE
:206392001AD019DD01DEC61A000119DC011A0008C51A1000001A10000018BFFF001A000F1B
:2063B200011A00401F763300BF5621011F76A001C41A000819CCFFFCA91A0004199697CC9C
:2063D200FFFDA91A00011A96BF56098000CC7FFCA91A0001009600CCFFE3A91A00080096ED
:2063F20000CC001CC9FFA92D019A66FFA98800CC800304600102AC1E076F00CC8003C6FFCA
:2064120080FFA985AC1EA6851F7671034456A900421E3A06C0006BBA008FA60E42A8C0000A
:206432006BBA1F767D03008F4C1D31931F76A00105960018FCFF1F767C0302533EA80C60B5
:20645200008F8A66BF56340FBF563504BF563609BF5637143EA81F767D03319203520E60D0
:206472001F767C03008FF22BBF56340ABF563501BF563604BF5637143EA81F767D0332923E
:206492000E611F767C03008FF22BBF5634FABF563519BF563696BF5637143EA81F767D03D9
:2064B200319206520660008F7C921F767C033EA805520660008FA60E1F767C033EA81F7623
:2064D2007C033E0682FE3C1E0600009A019C1952FE640600005206601F76BF010D1A0010B9
:2064F200056F1F76BF010B1A00100600BDB21F76BF01BDAA0D1A0008BDA2A95B0102407610
:206512006FBB00D1808DC06FA28AA392CEFF0BDCC41A00804076D7AFA39280FFA95B0102C8
:2065320040766FBB0DDA0102C21A008040766FBB01D9A1921052E7641F76BF010B1A000807
:20655200BE82BE86BE8B06001F767E03008F5902BF5600050128701706A80600BDB2BDAA02
:20657200BDA202FE79D0008FC0DBAC1E013BA98B94854C82A61E4456A90042A2C0006BBA46
:2065920078D0A98342A2215694004456A100C0006BBA7FD0A607A5039449046C7AD0013BEF
:2065B2009485A918FF0FA95AA91A00804076E3AF7BD0A9B2408FC0DB34FF957AA61EA9B2E2
:2065D20042A232FFA607C0006BBAA98A42A2C802AC1EA9B24456A900C0006BBA1CD0A49EA6
:2065F20082FE289C9596BE82BE86BE8B0600A92802904076E3AF1F767D03319206520F61FC
:2066120004520D61025206611F76BF010F1A00040A6F1F76BF010F1A0040056F1F76BF0167
:20663200061A0002060002FE1F767E03080604610102415608000092020A0254E6FFCF004D
:206652000606022BE0FFAB007FD0008FC0DB9447706C05924C6050D0013B9492FC9CA985AA
:20667200A9BD120F007700770077007789E6000051D003E20A009492FC9CA985A9BD160FAF
:20669200007720E8000003E20A0032E8000589E6090003E20A0003E20C0112E8010C14AD3A
:2066B200056502E8000C03E20A0094E6010014AD06628FE800E0007703E20C00AFE20A017A
:2066D200AFE20C0090E8092090E800201F76740350E8094850E800488EE609008EE60000CC
:2066F20013E21A011F76740313E21B001F767E030192C0FF03540267030A0192030A035430
:2067120002670396AFE20A00AFE20C01C4E20103C4E2030220E709004FE800604FE8096090
:2067320000E7180000E75100007710E74000086F0492032B90E5019CA918FF0304968EE644
:20675200000003887FD0A9BF120F01931F767403187E1F76740319971F7674031C969488F8
:206772001F767E03A693D6FF0191059704930A61A648086D0188013BA98542C240761BB0D8
:206792002D6F407664B01F767E03008FC0DBBF5604017FDCC418FFFE216F06060119A61E79
:2067B200061E20FF5802A60F136120FFF401060F0F6120FF9001060F0B6120FF2C01060FD6
:2067D2000761C802060F04616402060F0760407664B01F767E03BF56040182FE0600005247
:2067F20006601F76BF01041A0001056F1F76BF01021A00010600005206601F76BF01041A96
:206812004000056F1F76BF01021A4000060040765CB1019A407668B1009A40765CB101026E
:2068320040766FBB009A407668B11E0240766FBB0600009A407668B11E0240766FBB019AF3
:2068520040765CB11E0240766FBB009A40765CB11E0240766FBB0600BDB2BDAABDA20EFEBF
:2068720000D2A98BA288A492A52D0252A65BE3FFF000A9B2026301D256FFA983AC920564EC
:206892000452036301D3026FAC2BAC92A58B4B2B0B650A02421EA9B2C0006BBA4B0AA98B85
:2068B200AC924B54F762A9B20A650A02421EA9B2C0006BBA01DE58FFA98BF862A292A58BF2
:2068D200A694A988026001BEA692AC944B2B0452A9880F650A02421EA9B2C0006BBAAC8059
:2068F200A98B4B0AA69281DFFC9CA72D4B54F362AC920263AC2B019A66FFA95801520260D5
:2069120000D08076E803A9B242C2C0006BBA441EA9B242C2C0007ABAA61E6402421EA60685
:20693200C0006BBA461E6402421EA9B2C0007ABAA61E0A02421EA606C0006BBA481E0A02B4
:20695200421EA9B2C0007ABA4A1EA61E460648074407A607046000D0A02DAC5AA392156105
:20697200039A013B4B96AD888ADEA6880356A9010156A600C6060960AC924B5406610F02F6
:206992004B0BC61E4B92F062A2922061019A013B4B96AD5D8ADDA55D0356A9010156A5009D
:2069B2000F02C50F09614B9203520661019C04524B96F0640B6FAD5D8ADDA55D0ABE4B9223
:2069D2000356A9010156A500C5C2009A4B2B013BAD5D8ADDA55D0356A9010156A50080766B
:2069F200B0DAA606C507A61EC685C51E019A4B2D66FFA0CE046180020156C5004B0A4B9276
:206A12000452E76448A3AB92AA2BFF90A927A9A9AC28180037FF5AFF4A064E1E4E92FF906F
:206A32004E964D2B4E06ABCAAACB4E1E4606009BFF903FFF5AFF4E06ABCAAACB4E1E44063D
:206A52003B565AFF4E06ABCAAACB4E1E026F4EB2408FCCDF013BA9A0A481A98A4B2BC45B33
:206A7200A3921052246200D14E92013B0190A9884E0640FF4E1EA692407674B101D9A19219
:206A92000852F364A35A00D1A293A292B0FF0190A85A407674B101D9A1920652F66440766A
:206AB20086B101DB4B0A4B920452DB648EFEBE82BE86BE8B060011D0008F107094920F90D6
:206AD20004520E60CCCC8001C6FF0252096022761F76C001BF562555BF5625AA1A7669FFEC
:206AF200060022761F76C001BF5629681A7669FF0600BDB202FE1F76C001A888A98011437A
:206B1200026C257611CC80010561227611187FFE1A762276408F1070A58AA79211D00F90F9
:206B320001DCC41A400095CDF0FFA8CA21961A76A79204600102A98B026FA759A92880C3E5
:206B5200A828C90169FFAC1E0556A1004076DEB2A1A91140FF6C22761118BFFF1A76A693C7
:206B72000153036102530A602276A69211CD7FFE039086FFA8CA11961A76A6930A60A9B2A2
:206B9200013BAC281E0040FF2256A10741FFA98BA69301530A60A9B2013BAC281E0040FF23
:206BB2002256A10741FFA98BA69302530960A9B2AC281F00013B2256A10740FFA98BA792E2
:206BD2001460A69203521160227611CC7FFFA91A000169FF119620FFDA0540766FBB1F76F8
:206BF200C001111A80011A761F76710382FE69FF3AB2BE8B0600BDB202FE22761F76C001FD
:206C1200BF561A011B2B1A92036001BE046F03561A01A9881F76710342C269FF3A06C00091
:206C32006BBA3E1E1F76C0011B92036001BE046F03561B01A9881F76710342C23A06C00076
:206C52006BBA408D1070A18315D0008F200B3C1E0CDD1F762C0094CCF8FF015014DC359686
:206C7200C41A04003418F7FFC51A0800787680001F76C0011C1A1000A18A1C1A00041C1A52
:206C920000081C1A20000DDC10D91C1A00011C1A00101C1A00201C1A00401C1A00801C187F
:206CB200FBFFC41A01001D1A02001D1A04001D1A08001D1A10001D1A20001C1A04001D1A27
:206CD20000041D1A00081D1A00101D1A00201D1A00011D1A00021D1A00401D1A0080C11A47
:206CF2000001201A0002201A0004201A0008201A0010201A00201A7669FF82FEBE8B06005A
:206D12004076DEB2049A029B4076E6B2407668B3060002FE22761F762B002028FFFF2128D4
:206D3200FFFF2228FFFF2328FFFF2428FFFF2528FFFF2628FFFF2728FFFF1A761F76FFCF91
:206D520069FF38924196399241963A9241963B9241963C9241963D9241963E9241963F926C
:206D72001F762B0041962F9201F0019082FE06001B76F0FF0500BDABBDA8BDA0BDC2BDC3F3
:206D920000E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000669FF4229165600D188
:206DB200227601021F767803015632002376391110291A767FD0008FC0DB944F046D69FFAC
:206DD2004076C8B21F767103020A029214520668022B1F767103BF560301008FC06FA483C0
:206DF2001F767D0306DDC51A0100319206520E6104520C61025205610FDCC41A00040A6F5C
:206E12001F76BF010F1A0040056F1F76BF01061A00021F767D033192065208610452066161
:206E32001F76BF010F1A0020056F1F76BF01061A080001021F767E032207A61E008F204EAE
:206E5200221EA9A8A60F026722A81F0A1F920A5202641F2B1B92AC2B1261008FC0DBA9A84F
:206E7200AC0DA98A62D094921F540465019A66FFA172AC92019C1B54A92DF0681E0A1E927D
:206E9200025202651E2B7FD0008FC0DB9493A89216D094CAA940EDFF8300A84B586D20FF8F
:206EB200204E220F30691E920A60013B1F766F0300D401D569FF0085407699B11F767E037E
:206ED2001E9201520A60008FC0DB013B01D569FFCC8501D4407699B1A192408DC0DB02D4F8
:206EF20000D569FFD1CEA90E407699B11F767E031E9202527B60013B03D400D5D9854076FC
:206F120099B1746F1E92076000D4000200D569FF407699B11F767E031E920152076001D4B3
:206F3200000200D569FF407699B102D4000200D569FF407699B11F767E031E92025256601B
:206F520003D4000200D5407699B1506F1E92086020FFB82200D401D569FF407699B11F76FA
:206F72007E031E920152086020FFB82201D401D569FF407699B1A10E02D400D569FF40768F
:206F920099B11F767E031E9202523060012903D400D520FFFFFF407699B1286F69FF407643
:206FB200DEBA1E920760013B00D404D51A85407699B11F767E031E9201520760013B01D4F7
:206FD20004D51A85407699B11F767E0302D400D52006407699B11F767E031E9202520660C0
:206FF200200603D400D5407699B1AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC5C8
:20701200BEC4BE83BE8ABE870300303BF1FF177602761B76F0FF0500BDABBDA8BDA0BDC27D
:20703200BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FE69FF4229A2
:2070520016561F763300329241962376000126760001321875002128FFFF1029408FC0D377
:2070720069FFA58A4076269540762B95103B4192329682FEAFE2BE03AFE2BE02AFE2BE0127
:20709200AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF177602761B76F0FFB9
:2070B2000500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD0363
:2070D20030E6000602FE69FF422916561F76330032924196237600012676000132187100EE
:2070F2002128FFFF1029408FC0D369FFA58A407626954076FC95103B4192329682FEAFE256
:20711200BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE83BE8ABE870300303B4B
:20713200F1FF177602761B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E274
:20715200BD0103E2BD0203E2BD0330E6000602FE69FF422916561F763300329241962376BF
:207172000001267600013218FD002128FFFF1029408F40D069FFA58A4076269540762B953B
:20719200103B4192329682FEAFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC5BEC410
:2071B200BE83BE8ABE870300303BF1FF177602761B76F0FF0500BDABBDA8BDA0BDC2BDC3DE
:2071D20000E2BD0003E2BD0003E2BD0103E2BD0203E2BD0330E6000602FE69FF4229165615
:2071F2001F7633003292419623760001267600013292322B2128FFFF1029408F40D069FFFB
:20721200A58A407626954076FC95103B4192329682FEAFE2BE03AFE2BE02AFE2BE01AFE28B
:20723200BE0080E2BE00BEC5BEC4BE83BE8ABE870300303BF1FF177602762276008F806F12
:20725200A483A4C41F76BE0126DDC51A030027DE261A0C00A483261A3000261AC000261A2C
:20727200000317DD261A000C261A0030261A00C0C61A0300271A0C00271A3000271AC000A7
:20729200271A0003271A000C271A0030271A00C0C51A0300A48328DD171A0C0016DC171A6B
:2072B2003000171AC000171A0003171A000C171A0030171A00C0C51A0300281A0C00281A66
:2072D2003000281AC000281A0003281A000C281A0030281A00C0C41A00C0161AC000161AA5
:2072F2000030161A000C1A7669FF06002276008F806FA4C4A4831F76BE0118DEC61A030040
:2073120019DD181A0C00181A3000181AC000181A0003181A000C181A0030181A00C0C51A2D
:207332000300A48369FF191A0C0014DD15DC191A3000191AC000191A0003191A000C191A8A
:207352000030191A00C0C51A0300141A0C00141A3000141AC000141A0003141A000C141AF7
:207372000030141A00C0C41A0300151A0C00151A3000151AC000151A0003151A000C151AD7
:207392000030151A00C040768AB60600227615D0008F200B1F762C0094CCF8FFA483A4C5E1
:2073B200A4C40150359614DDC518FCFF0CDF3418F7FFA4830DDE341A0400C41A60000EDDB4
:2073D200C41A1C00C41A0300C41A0030C41A000EC41A8001CC1A4000C41A0040C41A0080C5
:2073F200211A0300C71A60002C1A1C002C1A03002C1A00302C1A000E2C1A8001C61A4000A0
:207412002C1A00402C1A00802D1A0300C51A6000A4830FDD2E1A1C0018DC2E1A03002E1A87
:2074320000302E1A000E2E1A8001C51A40002E1A00402E1A00802F1A0300C41A0700381AF9
:2074520038001A7669FF40768AB607F6007769FF0600BD3ABDB2BDAABDA202FE0129A9BF54
:20747200120F58FF5B61A85C7F91A8088000421EA493D6FFA85CA9BF160F6761A85D7F91A8
:20749200A8088000A859A958A593D6FFA85DA493A571A8180001A697A418FF00A518FF00D4
:2074B2007FDCA492A59EA7964D64A90801FF3E62A193A09236FFA859A958420635FF0EF68A
:2074D200A11FA95BA3010AF6A11F2D56A204A32DA03640FF0BF6A11F33FF009B30FF54FF54
:2074F200A20CA39540FFA70801001FF677FF200940FFA70801001FF677FF5AFFA79222655E
:20751200A90801FF1363A9A946FF7F91A85BA95AA625A79596FFA20CA395A9BD120F82FEFC
:20753200BE82BE86BE8BBE8E0600009B57FFA8087FFF5AFFA693F260A8280080AA71AB926F
:20755200ED6F20FF0000EA6F5AFFA493A818000196FFA85CA9A9A8087FFFA81C0080A4CB28
:20757200DD6F58FF5AFF00BE25610129A6920190A958A60640FFA407A71EC793A640046DB9
:20759200A892C7FFA92DA09201520460A8CCFF00A92DAC58A592A0F201DEA092FF90A95863
:2075B200A592408FC0DAC7FF9570A95DA9A9A60FDE66A5920600A71E8076C0DA0A6FA592BB
:2075D2008470FF90A95881DFA592C7FF9670A95DA706F660A59206000052A927FF76FFFFD7
:2075F20000BE3365A9A8013BA681A983A793C592FF90A92FAA71A880009AA740046DB0FF67
:20761200A880056FB0FFA81C01A0A880019C0852F564A9A8013BA681A983A793C592C7FFF9
:20763200A92FAA71A880009AA740046DB0FFA880056FB0FFA81C01A0A880019C0852F56454
:2076520001DEAB92A654CF62A79206001B76F0FF00E2BD0030E6000602FE422916561F76EB
:2076720033003292419623760001267600013292322B2128FFFF102901021F767D03180A18
:207692001F768001061E1F763300211A0001103B419282FE329680E2BE00303BF1FF17762C
:2076B20002761B76F0FF0500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2C9
:2076D200BD0203E2BD0330E6000602FE69FF422916561F7633003292419623760001267640
:2076F20000013292322B2128FFFF1029008F006169FF4076D9A91F76800102020C1E1F766D
:207712003300211A0001103B4192329682FEAFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2DE
:20773200BE00BEC5BEC4BE83BE8ABE870300303BF1FF1776027600021F763000008F000CE1
:207752000119021E1F767803408F100C000228A81F763000062B0119072BE41A1000041AA2
:2077720020001F763000008F080C0A1E1F76300000020119121E1F76300000020E2B0F2BFC
:207792001F76780330A838A02A1E1F763000162B172B1F763000E41A1000E51A10000C1A7F
:2077B20020001F763000141A20001F7678033A1E321E060000E0E45003E2F40188E610005A
:2077D200C48303E2D500C483F52BC483FD2BC483E51A1000C483E51A2000C483E518FFFBC6
:2077F200C483E518FFF7C4830002E51A0040D41E06000129BDB240FFBDAAA98B00D208610F
:20781200100240766FBB01DAA9B2A20FFA66BE86BE8B06001F76C001201A001040768AB6F4
:207832002276008F200BA4C4A4831F762C000ED015DE14DDC618F8FFC51A03003418F7FFD9
:207852003418FBFF94CCBFFF20502E960FDC2ECCE3FF08502E962ECCFCFF01502E962ECC97
:20787200FFDFA91A00102E962ECCFFF7A91A00062E962E187FFEC418BFFF2E18FFBF2E185D
:20789200FF7F2F1A03001A7607F6007769FF0600AD28000469FF1F5616561A5610E6000210
:2078B20040291F76000002291B762276A92800C0A828000001091B61C07600C004290F6FDC
:2078D200009BA92401DF046C0429A82401DFA61EA1F78624A706A1810109A71EA92403632E
:2078F2005CFF043BA95901DF0900ECFF1A76A928FFFFA828FFFF01090E61FF76FFFF066F78
:2079120001DFBDC3A71E673EBEC5A92401DFA82458FFF7604076FBBA407631BB1B76F0FF54
:207932000500BDABBDA8BDA0BDC2BDC300E2BD0003E2BD0003E2BD0103E2BD0203E2BD03DA
:2079520030E6000669FF42291656227601021F76780301563A00008F10DF69FF1F767C0384
:2079720016C5673E1A76AFE2BE03AFE2BE02AFE2BE01AFE2BE0080E2BE00BEC5BEC4BE833D
:20799200BE8ABE870300303BF1FF17760276BDB2CFE6010008D003E2BD040ED103E2BD05BC
:2079B20003E2BD0603E2BD07AFE2F400AFE2D40510E394040CD012E39C1F0ED118E394DA16
:2079D2000AE3C4A000E3E4C600E7BB0110E700010CD010E7C00003E29C0203E2940008D0B5
:2079F200F406941E03E2F401AFE2BE07AFE2BE06AFE2BE05AFE2BE04BE8B060002290429F6
:207A12005F565AFF42065F56421E00021FF617564200AB06325602292076022904295F561C
:207A32005AFF420656FF421E00021FF6175642003256022920765AFF00021FF617564200B0
:207A5200A9A920765AFF00021FF6175642002076103B1F7633002018FEFF222B242B69FF2B
:207A7200262B282B2A2B2C2B2E2B302B322B342B362B382B232B252B272B292B2B2B2D2B7E
:207A92002F2B312B332B352B372B392B06001F763300201A01002128FFFF102969FF0600A3
:207AB2000000A0E514AD0962A0E51F76740314AD90E5B4560101156F4FE803C092E6010039
:207AD2008CB5050000E7CA00007700E78A000077CFE812F0007700E75100007700E7400038
:207AF200060002FE1F767E031C0AC4E21C00007712E8D01F14AD11641D0A1D921C2B0A5261
:207B120002601D2B1D3457041A96200603610002036F00020119201E82FE0600A928FFFFA0
:207B3200AA28FFFFAB28FFFFA828FFFFAB0F04ED00D400BE0B6FA927A928FFFFA92FA4A949
:207B5200C488A928FFFF0209A98AA69240766BA6060022761F76C00169FF1C1A0800787633
:207B720080001A761F76C401028FE6491CCCFF3F69FFA91A00401C96BF5618E0A9A8407672
:207B92006FBB06000077006F1F767603BDB23EC5A959673E1F767E033EC5A70603ECA192AE
:207BB200673E1F767E033C0603ECA71E673E40762FBBBE8B0600408F8CC2008F000D22761D
:207BD200009A85C4019C805284C2FC641A7669FF0600A697009B0FF6A61F2076A697009B8D
:207BF2000FF6A61FA89220761F7676033CA806001F7676033EA8060006001F7674033C9702
:0C7C12003D9606000119C356FFFF060056
:207C1E00250100008CC27E8B00007E8B00007E8B00007E8B00007E8B00007E8B00007E8B93
:207C3E0000007E8B00007E8B00007E8B00007E8B00007E8B00007E8B00004C8C00003F8C4D
:207C5E000000CF8F0000718B0000E6880000888B0000598C00001C8A0000118A0000068A75
:207C7E000000FB890000F0890000E5890000DA890000CF890000C48900003D8A0000328AF0
:207C9E000000278A0000B48A0000998A0000E68800009089000077890000DC8F0000488AF0
:207CBE000000A9890000DE8D0000A88D0000728D00003C8D0000068D0000D08C0000E688AF
:207CDE000000E6880000F98D0000C38D00008D8D0000578D0000218D0000EB8C0000E688B1
:207CFE000000E6880000A68E00008B8E0000708E0000558E00003A8E00001F8E0000E688E7
:207D1E000000E6880000B58C00009A8C0000E6880000E6880000E6880000E6880000E6884A
:207D3E000000E68800007E8A0000638A0000C98B0000938B0000E48B0000AE8B0000E6883A
:207D5E000000E6880000B48F0000998F00007E8F0000638F0000488F00002D8F0000E6882C
:207D7E000000E68800007F8C0000648C0000E6880000E6880000208B0000CF8A0000E6882E
:207D9E000000E6880000568B0000058B00003B8B0000EA8A0000128F0000DC8E0000F78E1C
:207DBE000000C18E0000E6880000E6880000E6880000E6880000E6880000E6880000E68854
:207DDE000000E6880000E6880000E6880000E6880000E6880000E6880000E6880000E68815
:207DFE000000E68800005C89000041890000268900000B890000F0880000E6880000FF8B95
:207E1E0000001A8C00002C012C01000000000F00160014000A003C000000000000000000C5
:207E3E000000000000000A00080006000800060008000000000000000000000000000000F6
:107E5E000000000000000000000033000B000A00CC
:207E6E0048000000B2C3F4A4000081A50000E2A4000071A50000D5A4000063A50000C8A4F0
:207E8E0000004CA50000AEA400003CA50000A1A4000032A5000085A4000025A5000078A485
:207EAE00000017A500006BA400000BA5000055A4000040A40000949900002A9A0000269AAB
:207ECE0000001C9A0000989900009B9900009F990000A4990000A9990000AF990000B3992E
:187EEE000000B7990000009A0000209A0000BA9900002C9A00000000BF
:00000001FF

View File

@@ -2,7 +2,7 @@
TMS320C2000 Hex Converter v5.2.7
********************************************************************************
INPUT FILE NAME: <D:\project12\Balsam_167\bin\UKSSTMS320F28335.out>
INPUT FILE NAME: <UKSSTMS320F28335.out>
OUTPUT FORMAT: Binary
PHYSICAL MEMORY PARAMETERS
@@ -12,21 +12,20 @@ PHYSICAL MEMORY PARAMETERS
BOOT LOADER PARAMETERS
Table Type: SERIAL PORT (SCI 8 bit Mode)
Entry Point: 0x0000b8fa
Entry Point: 0x0000b9b5
OUTPUT TRANSLATION MAP
--------------------------------------------------------------------------------
00000000..003fffff Page=0 Memory Width=8 ROM Width=8
--------------------------------------------------------------------------------
OUTPUT FILES: D:\project12\Balsam_167\bin\UKSSTMS320F28335.bin [b0..b7]
OUTPUT FILES: UKSSTMS320F28335_34a95bc5.bin [b0..b7]
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
CONTENTS: 00000000..00007f05 BOOT TABLE
.cinit : dest=0000c000 size=0000028b width=00000002
.text : dest=00008000 size=00003b73 width=00000002
.econst : dest=0000c28c size=00000125 width=00000002
.switch : dest=0000c3b2 size=00000048 width=00000002
--------------------------------------------------------------------------------
00000000..003fffff Page=1 Memory Width=8 ROM Width=8 "*DEFAULT PAGE 1*"

View File

@@ -1,167 +0,0 @@
# Карта 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.

288
Doc/DAC_SPI_REVIEW.md Normal file
View File

@@ -0,0 +1,288 @@
# SPI и управление ЦАП в Бальзам 167
Дата анализа: 23.09.2026. Рассмотрена текущая рабочая копия проекта `167`.
Документ описывает существующий код и предложения; прошивка в рамках этого анализа не изменялась.
## 1. Как устроено сейчас
ЦАП обслуживает **программный SPI через GPIO**, реализованный в `DAC.c`.
Аппаратный SPI-A используется отдельно для EEPROM в `spise2p.c`.
Изменение `SpiaRegs.SPIBRR` не меняет скорость передачи в ЦАП.
| Сигнал ЦАП | Вывод DSP | Имя в таблице платы | Действие |
|---|---|---|---|
| CS | GPIO59 | csdac, 1:13B | 0 на время кадра, затем 1 |
| DIN / MOSI | GPIO60 | didac, 1:13A | данные от DSP к ЦАП |
| SCLK | GPIO63 | clkdac, 1:14A | 16 тактов на слово |
Обозначения контактов взяты из комментариев `GPIO_table.h`, а не из проверенной схемы.
MISO в драйвере отсутствует: код отправляет команды, но не читает подтверждение или статус ЦАП.
Для платы нагрузки `get_Mode()` выбирает обычные GPIO и выходные направления этих линий.
Цепочка работы:
```text
CPU Timer1: 1000 Гц, период 1 мс
→ cpu_timer1_isr_SENS(), только Desk == dsk_LOAD
→ Load_runner()
→ каждые 5 вызовов: расчёт задания / инициализация
→ Anal_output(kod, time_dac)
→ dSEND(16-битное слово)
→ GPIO59, GPIO60, GPIO63
→ ump_log_tick()
```
`READY_FREQ=1000`, `DAC_FREQ=200`, поэтому `period_dac=5`.
200 Гц — частота обновления задания, **не частота SCLK**.
`LOAD_TIME=30`, `time_dac=6000` — количество шагов, используемое в расчёте разгона.
Вызов `dSEND` синхронный: обработчик таймера занят, пока не выставлены все биты.
## 2. Что происходит внутри одного SPI-кадра
Функция `dSEND(word)` выполняет:
1. Опускает CS и вызывает `DSP28x_usDelay(1L)`.
2. Повторяет 16 раз: SCLK=1 → DIN=старший бит → сдвиг слова влево → задержка → SCLK=0 → задержка.
3. Поднимает CS.
Передача начинается со старшего бита: D15 … D0. После кадра SCLK остаётся в 0,
DIN — в состоянии последнего бита. Между кадрами CS остаётся в 1.
Перед первым кадром `dSEND` отдельно не устанавливает исходное состояние SCLK.
Последовательность одного бита:
```text
SCLK ↑ → выставить DIN → выдержать время → SCLK ↓ → выдержать время
```
Новый бит устанавливается **после восходящего фронта**, но до нисходящего.
Следовательно, код рассчитан на чтение данных по нисходящему фронту; это
вывод из последовательности операций, а не подтверждение режима конкретной микросхемы.
При SCLK idle=0 такое поведение соответствует замыслу SPI mode 1.
Если приёмник читает по восходящему фронту, нужного setup-time здесь нет.
Нельзя менять фронты по привычному примеру SPI mode 0 без проверки схемы и паспорта ЦАП.
Из исходников установлены такие слова:
| Вызов | Передаваемое слово |
|---|---|
| `Init_DAC()` | `0x9002` |
| Обычное обновление | `0x8000 | (out & 0x0FFF)` |
| Ручная калибровка | `0x8000 | (DAC_cal() & 0x0FFF)` |
Локальная переменная `x` в `Anal_output()` каждый раз получает 0. Ветка отправки
без `0x8000` сейчас не выполняется. Точный смысл командных битов, номера канала,
режима питания и `0x9002` нельзя достоверно назвать: маркировка ЦАП в исследованных
исходниках не указана. Нужны схема или название установленной микросхемы.
После отправки `0x9002` функция `Init_DAC()` также переключает `RES_OUT_1` —
для платы нагрузки это GPIO9. Это отдельная линия с неизвестным здесь
электрическим назначением; считать её аппаратным RESET или LDAC без схемы нельзя.
## 3. Задержки и влияние прерываний
`DSP28x_usDelay(1L)` **не задаёт 1 мкс**. Ассемблерная функция принимает счётчик
циклов своего внутреннего цикла. Для микросекунд библиотека предоставляет макрос
`DELAY_US`, который предварительно пересчитывает время.
В комментарии самой ассемблерной функции приведена модель `9 + 5 × LoopCount`
тактов процессора. Она применима с оговорками о памяти без wait-state; вызовы,
GPIO-записи, цикл C и прерывания дополнительно влияют на реальную длительность.
Поэтому по числу `1L` нельзя вычислять частоту SCLK как 500 кГц или 1 МГц.
В проекте `XCLKIN=30 МГц`, `CLKMULT=2`, PLL множитель 4, делитель 2:
расчётная частота SYSCLKOUT — **60 МГц**, если входной генератор соответствует
константе. При этом `CPU_RATE` для макроса `DELAY_US` остался `6.667 нс`
(150 МГц). Это несоответствие не участвует в прямом вызове `DSP28x_usDelay(1L)`,
но помешает простой замене на `DELAY_US(1)`: сначала надо согласовать CPU_RATE
с фактической частотой. При 60 МГц период такта примерно 16.667 нс.
В таймерном ISR выполняется `EINT` после настройки `IER/MINT13`.
В текущей таблице приоритетов Group9 имеет уровень 1, Timer1 — 4;
разрешённые прерывания CAN/UART могут удлинять части SPI-кадра.
Сам `dSEND` не запрещает прерывания и не имеет защиты от повторного входа.
В найденных вызовах передача ЦАП идёт из `Load_runner`; добавлять второго
вызывающего без организации единого владельца передачи нельзя.
Это не доказывает потерю данных: некоторые ЦАП допускают произвольное растяжение
SCLK. Следует проверить паспортные ограничения и измерить минимальные и
максимальные времена под нагрузкой CAN/RS. Полный запрет прерываний на кадр
может уменьшить разброс, но увеличит задержку обработки связи.
## 4. Инициализация и расчёт аналогового выхода
`Setup_DAC_time()` задаёт `WAKEpowse=601`. Счётчик уменьшается с частотой 200 Гц.
Во время примерно трёхсекундной стартовой фазы `Init_DAC()` вызывается шесть раз,
при остатках 600, 500, 400, 300, 200, 100. После этого начинается обычный вывод.
Команда `cInitDac` вызывает повторную инициализацию; на этом шаге слово задания
не отправляется. При остановленном УМП счётчик `x` в `Load_runner` также вызывает
периодическую инициализацию примерно раз в 5.12 с. Это другая переменная `x`,
не связанная с постоянным нулём в `Anal_output`.
Расчёт кода:
```text
out = DAC_min + vrot × DAC_max / maxx − vrot × DAC_min / maxx
при cCalibrDac: out = DAC_cal
затем out &= 0x0FFF
```
Два деления здесь целочисленные. Их нельзя без проверки заменить одним:
`DAC_min + vrot × (DAC_max − DAC_min) / maxx` может дать другое округление.
Сначала нужно определить требуемое округление и допустимость изменения результата.
В `modbus[0x7B]` сохраняется отправленный 12-битный код, а в `modbus[0x1C]` —
расчётное задание в десятых долях мА. Это **не измерение выходного тока**.
В режиме `cCalibrDac` эти значения могут описывать разные вещи: в ЦАП уходит
ручной код, а `0x1C` остаётся результатом формулы разгона.
## 5. Что стоит исправить в первую очередь
### 5.1. Порядок запуска таймера — высокий приоритет
В `main()` выполняются `timer_Init(); EnableInterrupts();`, а затем загрузка
параметров и только после неё `Setup_DAC_time()`.
В `cpu_timer1_isr_SENS` перед `Load_runner()` нет проверки `READY`.
До настройки глобальные `period_dac`, `time_dac`, `WAKEpowse` нулевые.
Если в этом промежутке сработает Timer1 на плате нагрузки, условие счётчика
проходит при нулевом `period_dac`, стартовая задержка отсутствует, и путь может
дойти до `Anal_output(..., 0)` — деления на ноль. Это найденный путь выполнения,
не результат воспроизведения на железе.
Предложение: до допуска обслуживания ЦАП настроить GPIO в известное состояние,
загрузить/проверить параметры и выполнить `Setup_DAC_time`. Для этого можно
отдельно разрешать ветку ЦАП флагом готовности или запускать Timer1 позднее.
Нельзя просто отключить все прерывания на время загрузки: EEPROM использует Timer2.
Дополнительно проверять `maxx > 0` и допустимость `period_dac` перед расчётом.
### 5.2. Ошибка ограничения уставки
В `Load_runner` есть строка:
```c
if (dac_stop > 16) dac_go = 16;
```
При превышении конечной уставки меняется начальная. Вероятное намерение —
ограничивать `dac_stop`, но это надо подтвердить требованиями к разгонной
характеристике. Ранее `dac_go` ограничивается диапазоном 0..5, а эта строка
может сразу заменить его на 16. Следующая проверка способна поднять `dac_stop`
до 17. Это влияет на ток независимо от исправности SPI.
Предложение: описать допустимые пары начальной/конечной уставок в мА,
проверять их совместно и протестировать границы. Внутри алгоритма из обеих
уставок вычитается 4 мА; ограничения должны учитывать это смещение.
### 5.3. Маскирование вместо насыщения
`out & 0xFFF` обрезает старшие биты, но не ограничивает числовое значение:
4096 превращается в 0, −1 — в 4095. При ошибочной калибровке или выходе
за диапазон это создаёт скачок кода.
Предложение: сначала проверить входные данные и ограничить результат
диапазоном 0..4095, затем сформировать командное слово. Для ошибочных параметров
явно определить поведение: отказ, удержание предыдущего кода или заданное
проектом аварийное значение. Не выбирать «0» автоматически: код и ток связаны
калибровкой и внешней схемой.
### 5.4. Реальная длительность разгона
После половины диапазона `count_load` увеличивается дважды за шаг:
один раз в `if(count_load > time_dac/2)`, второй — в `++count_load`.
Поэтому достижение конца при `LOAD_TIME=30` занимает примерно **22.5 с**,
а не 30 с, без учёта начальной фазы и задержек исполнения.
Это может быть намеренной двухступенчатой характеристикой.
Предложение: явно описать её либо перейти к расчёту по прошедшему времени,
если требование действительно состоит в линейном разгоне за 30 с.
## 6. Улучшения непосредственно SPI
| Изменение | Польза | Что проверить |
|---|---|---|
| Явный `dac_bus_init`: CS=1, SCLK в idle, DIN определён; затем включение выходов | Предсказуемый первый кадр | Схема, подтяжки, активные уровни |
| Именованные задержки setup/hold/high/low/CS-high | Понятные временные ограничения | Паспорт ЦАП и фактическая частота DSP |
| Имена констант вместо `0x9002`, `0x8000`, `0xFFF` | Ясный смысл команд | Сначала установить модель ЦАП |
| Один владелец передачи и флаг занятости | Исключает наложение двух кадров | Все вызывающие и разрешённые ISR |
| Отдельные функции расчёта кода и отправки слова | Проверка алгоритма без железа | Сохранение округления и масштаба |
| Диагностика отправок/максимальной длительности | Показывает нагрузку и задержки | Счётчик отправок не считать ACK от ЦАП |
| Удаление неиспользуемого `wast()` и недостижимой ветки `x` | Упрощает чтение | Не затронуть другой `x` в Load_runner |
Не следует повышать DAC_FREQ ради ускорения SPI: меняется алгоритм обновления,
число шагов и стартовые интервалы. Для других частот проверить целочисленность
отношения READY_FREQ/DAC_FREQ и диапазон 16-битного `time_dac` на C28x.
Текущие 6000 шагов помещаются; будущие LOAD_TIME/DAC_FREQ могут вызвать переполнение.
Вариант без переделки платы: сохранить GPIO-передачу, нормировать её тайминги,
измерить длительность кадра и только затем решать, нужна ли короткая критическая секция.
Не переносить отправку в основной цикл без анализа задержек: в проекте есть
блокирующие операции EEPROM. Если переносить — использовать явную очередь/последнее
задание с оговорённым временем обслуживания и отдельными командами инициализации.
## 7. Можно ли перейти на аппаратный SPI
У F28335 один SPI-A. Его выводы могут быть GPIO16/17/18/19 или GPIO54/55/56/57.
GPIO60 и GPIO63 не имеют функции SPISIMOA/SPICLKA, поэтому текущие DIN/SCLK
не переводятся на SPI-A одной настройкой mux. Нужны изменения соединений.
Это подтверждается [таблицами выводов TI, SPRS439Q](https://www.ti.com/lit/ds/symlink/tms320f28335.pdf).
В данном проекте SPI-A уже обслуживает EEPROM на GPIO16/17/18 и CS=GPIO19.
Вариант общей шины требует подключения ЦАП к тем же MOSI/SCLK и отдельного CS,
проверки электрической совместимости и последовательного доступа к SPI-A.
Если меняются длина слова/фаза/частота, переключать настройки можно только
после завершения предыдущей операции. Текущий автомат EEPROM работает через
Timer2 и сам меняет формат слова: потребуется общий владелец шины.
Сначала достаточно рассмотреть один 16-битный аппаратный кадр с ограниченным
ожиданием либо прерыванием завершения. FIFO/DMA усложнят короткую передачу;
их необходимость следует обосновывать измерениями. CS надо отпускать после
фактического окончания сдвига последнего бита, а не сразу после записи TXBUF.
Возможность DMA именно для выбранного периферийного блока отдельно проверять
по TRM, не переносить механически решение STM32.
Для будущего порта STM32 можно сохранить общий расчёт и формат слова,
а отправку реализовать аппаратным SPI на выводах конкретной платы. Нынешний
эмулятор лишь генерирует поля ЦАП в журнале; он не подтверждает физические
SPI-фронты и выходной ток устройства.
## 8. Практический порядок работ и проверка
1. Установить модель ЦАП, назначение GPIO9, схемные инверсии и требования timing.
2. Исправить порядок готовности ЦАП при запуске и защитить деление на ноль.
3. Согласовать диапазоны уставок, исправить ограничение и обрезание кода.
4. Снять текущие CS/SCLK/DIN при запуске, рабочем разгоне и нагрузке CAN/RS.
5. Нормировать программные задержки; аппаратный SPI выбирать по результатам измерений.
Логический анализатор подключить к CS, SCLK, DIN и общей земле; при необходимости
добавить GPIO9. Записать 16 бит каждого кадра, порядок битов, `0x9002`,
минимум/середину/максимум кода, setup/hold DIN, CS setup/hold, SCLK high/low,
длину кадра и интервал обновления. Отдельно проверить первый кадр после сброса.
Частоту дискретизации анализатора выбрать по измеренному SCLK с запасом.
Осциллографом проверить форму фронтов и выбросы, внешним измерителем — ток.
После правок проверить граничные и ошибочные уставки, `maxx=0`, калибровку,
разгон/останов, cInitDac, сохранение параметров EEPROM одновременно с CAN/RS.
Тесты расчёта должны фиксировать требуемое округление и поведение вне диапазона;
программная трасса GPIO — количество фронтов и порядок данных. Проверка GPIO
на компьютере не заменяет измерение времён на собранной плате.
## 9. Основания анализа
Факты о текущем поведении взяты из следующих файлов; номера строк относятся
к рабочей копии на дату анализа:
- [Формирование кадра, инициализация, расчёт выхода и разгон](C:/setcorp/git/tms_periph_28335/167/Source/Internal/DAC.c:45).
- [Запуск таймера и порядок инициализации](C:/setcorp/git/tms_periph_28335/167/Source/Internal/main.c:26).
- [Вызов Load_runner из ISR](C:/setcorp/git/tms_periph_28335/167/Source/Internal/measure.c:119).
- [Частоты и время разгона](C:/setcorp/git/tms_periph_28335/167/Source/Internal/Include/measure.h:73).
- [Назначение линий платы](C:/setcorp/git/tms_periph_28335/167/Source/Internal/Include/GPIO_table.h:294).
- [Mux и направления GPIO](C:/setcorp/git/tms_periph_28335/167/Source/Internal/peripher.c:44).
- [Аппаратный SPI EEPROM](C:/setcorp/git/tms_periph_28335/167/Source/Internal/spise2p.c:98).
- [Счётчик ассемблерной задержки](C:/setcorp/git/tms_periph_28335/167/Source/External/v120/DSP2833x_common/source/DSP2833x_usDelay.asm:62).
- [Настройки PLL и CPU_RATE](C:/setcorp/git/tms_periph_28335/167/Source/External/v120/DSP2833x_common/include/DSP2833x_Examples.h:66).
- [Приоритеты прерываний](C:/setcorp/git/tms_periph_28335/167/Source/External/v120/DSP2833x_common/include/DSP2833x_SWPrioritizedIsrLevels.h:61).
Модель ЦАП и электрическая схема не установлены. Режим выборки, назначение
командных битов и допустимые длительности нельзя считать подтверждёнными
до сверки с документацией конкретной микросхемы. Сборка/прошивка и стендовые
измерения в рамках подготовки этого документа не выполнялись.

View File

@@ -1,67 +0,0 @@
# 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

119
Doc/PERIPH28335_CAN.md Normal file
View File

@@ -0,0 +1,119 @@
# periph_28335: общая панель RS/CAN и регистратор УМП
## Где находятся панели
В верхнем ряду вкладок, рядом с **Altera Logic**, появилась **periph_28335**.
Внутри неё:
- **Dima / CAN terminal** — существующий CAN-терминал, его проекты, узлы и настройки адаптера;
- **rs232_periph_28335** — существующие операции RS232/485, Modbus и настройки COM;
- **Логгер УМП** — единая панель графиков и архива для обоих транспортов.
В общей группе CAN остались «Шина CAN / мост» и «DevBoard_V1».
В общей группе RS232/485 остался RS_TERMINAL_2812.
Терминалы сохраняют свои соединения: перенос вкладок не создаёт новые порты.
## Онлайн и чтение по CAN
1. Откройте **periph_28335 → Dima / CAN terminal → Настройки**.
2. Выберите Candle/gs_usb либо SLCAN/Lawicel и канал адаптера.
Для штатной прошивки Бальзам 167 используется CAN 250000 бит/с.
Нажмите «Подключить».
3. Перейдите в соседнюю вкладку **Логгер УМП**.
4. В строке **Связь логгера** выберите **CAN · адаптер Dima**.
5. Укажите **CAN-плата (Mode)**: физический номер платы в прошивке, 1..16.
Платы нагрузки Бальзам 167 имеют номера 5/6; выбирайте фактически подключённую.
Это не RS-адрес 16 и не индекс строки таблицы Dima. Выбор проекта в Dima
не меняет CAN-адрес регистратора: он явно определяется этим полем.
6. Нажмите **Начать запись** или **Онлайн**, если запись на плате уже идёт.
Остальные действия, флажки, легенда, единицы мА и CSV одинаковы для RS и CAN.
7. После команды отключения и секунды постинтервала нажмите
**Прочитать отключение**. Запись текущего банка на плате продолжается.
Кнопка **Настройки связи** открывает настройки выбранного транспорта.
Состояние адаптера/порта и адреса CAN постоянно отображаются над графиком.
**Прервать обмен** останавливает чтение GUI, не посылая команду остановки
регистратора или УМП. При переключении канала/платы незавершённые запросы
отменяются, поздние ответы не продолжают старую цепочку.
Для RS выберите **RS232/485** и настройте COM в соседней RS-панели:
обычно 115200, адрес 16. Сообщения «не подключён» и «занят запросом» разделены.
Отключение RS-порта не останавливает CAN-просмотр. CAN-разрыв не мешает RS.
Демо, если оно включено в сборке, по-прежнему работает без физической платы.
## Изменения прошивки
Для CAN требуется новая прошивка этой ветки. Предыдущая версия регистратора
умела отдавать данные только через Modbus. Старая плата игнорирует новые
служебные запросы; GUI сообщает о тайм-ауте без изменения команд УМП.
- MBOX0: прежняя передача технологических данных, ID 0xBA0010 + Mode - 1.
- MBOX1: прежний приём команд, ID 0xBA0000 + Mode - 1; дополнительно
распознаётся служебный заголовок 0x1F00 и длина ровно 8 байт.
- MBOX2: отдельные ответы регистратора, ID 0xBA0020 + Mode - 1.
Биты маски записи регистров у служебного запроса равны нулю. Обработчик
перехватывает его до изменения modbus[] и до журналирования CAN-команд:
опрос собственного журнала не заполняет журнал.
Запрос ставится в очередь из ISR. Основной цикл формирует целый снимок
под короткой блокировкой IRQ и отправляет максимум один кадр за вызов
UMP_CAN_service(). Ожидания передачи в цикле нет. Перед следующим
фрагментом приоритет отдаётся ожидающей штатной телеметрии MBOX0.
Если ACK служебного mailbox не приходит 250 тиков таймера, передача
отменяется. При этом штатные CAN-команды и MBOX0 не отменяются.
По CAN доступны те же расширенные адреса 0x1000 / 0x1010 / 0x1100,
состав записи и версия снимка 2. Новый протокол не даёт писать через
служебный запрос в технологические адреса 0..127.
## Формат кадров
CAN 2.0B, расширенный ID, 8 байт данных. Порядок соответствует существующей
прошивке: MDL (слова 1,2), затем MDH (заголовок, слово 0). Каждое слово
содержит сначала старший байт.
Запрос: `[адрес BE16, значение/длина BE16, 0x1F00 BE16, token:function BE16]`.
Функция 3 — чтение, 6 — запись; token — номер запроса 1..255.
Ответ: `[данные0 BE16, данные1 BE16, (0x1F00+индекс) BE16, token:error BE16]`.
Номер фрагмента 0..61, в нём два слова снимка. Ошибка 0 означает успех,
1 — неизвестная функция, 2 — неверный адрес/диапазон, 3 — запрещённое значение.
У записи успешный ответ содержит эхо адреса и значения.
Пример: Mode=5, token=7, чтение статуса 16 слов.
Запрос ID `0x00BA0004`, данные `10 00 00 10 1F 00 07 03`.
Ответы ID `0x00BA0024`, восемь фрагментов по два слова.
Онлайн-снимок из 124 слов передаётся 62 фрагментами.
GUI принимает только ответ выбранной платы с номером текущего запроса,
восстанавливает порядок фрагментов, игнорирует одинаковые дубликаты и
отклоняет противоречащие. Неполный снимок не попадает на график.
После потери подтверждения записи GUI прямо сообщает, что команда могла
выполниться; автоматического повторного старта регистратора нет.
Онлайн показывает последние три записи из полного снимка. При высокой
нагрузке шины/низкой скорости возможны пропуски онлайн-отображения;
они считаются существующим счётчиком. Архив читается целиком по блокам.
Предполагается один активный читатель архива: его курсор общий для RS/CAN.
Одновременное управление архивным курсором из двух независимых программ
не поддерживается.
## Проверки и ограничения
Пройдены тесты протокола, сборки всех 62 фрагментов, неверного адреса/токена,
пропущенных и повторных фрагментов, ACK и ошибок, отмены при смене канала,
иерархии вкладок и сохранения RS/демо. Набор тестов выполнен на Qt 6 и Qt 5.
В прошивке проверен настоящий код формирования ответов через host-тест;
изменённые C-файлы прошли проверку синтаксиса Clang с исходными заголовками.
Сборка TI/CCS, проверка MAP и испытание CAN на реальной плате ещё требуются.
Особенно проверить тайминги IRQ и приоритет штатной телеметрии на нагруженной
шине. Файлы прошивки Bin/*.out/hex не заменены. Архив остаётся в ОЗУ:
команда отключения фиксирует его, пропадание питания стирает.
## Общее ядро templates
Сервер CAN/RS логгера подключён через `Source/Internal/shared_ump.c`.
Для сборки требуется соседний `../../templates`. Контракт и порты:
`templates/c/set-protocol/docs/UMP_PROTOCOL.md`.

View File

@@ -1,337 +0,0 @@
@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

@@ -1,600 +0,0 @@
@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

@@ -1,344 +0,0 @@
@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

@@ -1,289 +0,0 @@
@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` |

View File

@@ -1,16 +0,0 @@
# Документация 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
```

View File

@@ -1,53 +0,0 @@
# Сборка проекта в 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`;
перенос репозитория в другой каталог не требует изменения настроек.

69
Doc/RS232_FIFO.md Normal file
View File

@@ -0,0 +1,69 @@
# RS232 FIFO для ПМ35 / TMS320F28335
Ветка `codex/pm35-uart-fifo`. FIFO включён **только SCI-A / COM_1 / RS232**.
SCI-B / COM_2 / RS485 сохраняет прежние настройки и обработчики без FIFO.
Скорости портов не менялись: RS232 115200; RS485 — прежние 57600/115200.
`Source/Internal/Include/RS485.h`: `RS232_USE_FIFO=1` по умолчанию.
Для сборки прежнего пути передачи определить `RS232_USE_FIFO=0`.
## Работа
- TX заполняет до 16 байт, пополняет при остатке не более 8.
- После постановки последнего байта порог переключается на 0. Следующее
прерывание завершает передачу только после пустого FIFO и `TXEMPTY`.
Ожидание внутри завершающего ISR ограничено остатком последнего символа;
передача всего FIFO внутри ISR не ожидается.
- Первый блок ставится в FIFO до разрешения TX-прерывания, под короткой
IRQ-блокировкой с восстановлением прежнего состояния.
- Убраны программные задержки перед передачей именно для SCI-A. Данные
`BM_CHAR32` и упакованный поток `BM_PACKED` сохраняют прежний порядок байтов.
Нулевая длина не обращается к указателю и не включает передатчик.
- RX читает накопленные байты из FIFO. Порог 1 сохраняет немедленный приём
коротких команд и остатка блока. `SCIRXBUF` читается один раз вместе с FE/PE.
- Ошибка/переполнение аннулирует пакет и `BS_LoadOK`, очищает FIFO. После
3–4 мс тишины обработчик таймера 1 мс возвращает SCI-A к ожиданию адреса.
Продолжающийся повреждённый поток продлевает ожидание. CMD_LOAD после
ошибки требует нового CMD_INITLOAD. Расчёт паузы предназначен для 115200.
- Счётчики отладчика: `rs_a.fifo_rx_errors`, `rs_a.fifo_overflows`.
Это UART-оптимизация. Она не меняет команды/формат логгера УМП и не подключает
экспериментальный GAS-логгер. Размеры блоков чтения УМП остаются прежними.
## Проверка
```powershell
python tests/rs232_fifo/run_test.py --cc C:/msys64/mingw64/bin/gcc.exe
```
Тест извлекает рабочие функции из `RS485.c`; заменяется только поведение
аппаратных регистров, ожидание продвижения UART и модель 16-битного char C28x.
Проверены TX-длины 0/1/2/7/8/15/16/17/31/120/253/400, упакованный блок 8194,
приём короткого/разделённого пакета и LOAD 8194, FIFO overflow, FE/PE,
восстановление после тишины, остаток сдвигового регистра и независимость SCI-B.
Полная сборка TI C2000 22.6.0.LTS:
```powershell
./build_logger.ps1 -OptimizeForSize -Rs232Fifo 1 `
-OutputDirectory "$PWD/Bin/Rs232FifoTest" -ImageName PM35_167_rs232_fifo
./build_logger.ps1 -OptimizeForSize -Rs232Fifo 0 `
-OutputDirectory "$PWD/Bin/Rs232NoFifoTest" -ImageName PM35_167_rs232_no_fifo
```
| Образ | Размер | Запас до параметров EEPROM |
|---|---:|---:|
| FIFO, `-O2 --opt_for_speed=0` | 32158 байт | 350 байт |
| Без FIFO, те же параметры оптимизации | 31234 байта | 1274 байта |
Оба BIN прошли проверку структуры SCI8 и лимита 32508 байт существующим
`check_firmware.ps1`. Старые `-O1 --opt_for_speed=3` с FIFO превышают лимит;
для этого варианта обязателен `-OptimizeForSize`. Проверка запрещает выпуск
слишком большого BIN и не даёт затронуть сохранённые параметры.
Оптимизация размера применяется ко всей сборке, поэтому временные
характеристики приложения нужно проверить на стенде.
На плату образы не загружены. Пока подтверждены сборка и тесты модели;
ускорение чтения логгера и устойчивость физического RS232 не измерены.
Для стенда сравнить одно и то же чтение архива на двух образах, проверить
CMD_LOAD/UPLOAD и параллельный RS485. FIFO не увеличивает baud rate.

241
Doc/UMP_LOGGER.md Normal file
View File

@@ -0,0 +1,241 @@
# Логгер запуска и отключения УМП: прошивка Бальзам 167 и SetGUI
## Назначение и работа оператора
В SetGUI открыть ПМ35 → Настройки, выбрать COM, скорость (обычно 115200)
и адрес контроллера (обычно 16). Затем открыть вкладку **Логгер УМП**.
Подключение используется существующее: прямой RS232/RS485 Modbus RTU.
CAN-команды от управляющего контроллера фиксируются самой платой нагрузки.
1. **Начать запись** включает только регистратор, не пуск УМП.
Период снимков по умолчанию 20 мс, диапазон 1–1000 мс.
2. Флажки выбирают отображаемые сигналы. Аналоги рисуются линиями,
дискретные сигналы — отдельными дорожками. Выбор не меняет состав
записи на плате: скрытую кривую можно включить после захвата.
3. **Онлайн** подключает график к уже идущей записи, в том числе после
восстановления соединения. Тайм-аут не посылает плате команду останова.
4. Фронт `cUMPreset` (бит 6 команды 0x7F) или спад `cUMPstart` (бит 7)
запускает фиксацию отключения. Ещё через 1000 тиков таймера / 1 секунду
банк становится архивом. Повторные команды внутри этой секунды
не продлевают интервал. Другие изменения команд не служат триггером.
5. **Прочитать отключение** загружает архив, не останавливая запись на плате.
На время чтения и просмотра архива онлайн-график приостанавливается;
вернуться к нему можно кнопкой **Онлайн**.
6. **Остановить и прочитать** останавливает только регистратор и читает
текущий банк. При этом существующий архив отключения остаётся доступным.
7. **Сохранить CSV** сохраняет все поля загруженного/онлайн-буфера,
включая невидимые кривые, время и код события. История GUI ограничена
800 последними точками; это не непрерывная запись на диск.
При разрыве связи журнал на плате продолжает работать. Архив хранится в ОЗУ
до следующей фиксации отключения либо перезагрузки/пропадания питания.
EEPROM не используется: под отключением в этой задаче понимается команда
управляющего контроллера, а не потеря питания.
## Память и точность
Использована существующая секция `.logg` по адресу 0x200000: 64000
16-битных слов. Два банка по 760 записей × 42 слова занимают 63840 слов (160 слов свободны).
Текущий банк кольцевой. При триггере сохраняются последние до 379 записей,
добавляется событие отключения, оставшаяся половина банка отведена
постинтервалу. При 20 мс это до примерно 7.6 секунды до отключения и 1 секунды
после. Дополнительные события CAN и дискретов сокращают временную глубину.
При интенсивном потоке событий или периоде 1 мс постинтервал может заполнить
свои места раньше секунды. Последнее место зарезервировано под конечный
снимок; он помечается `event & 0x200`, и GUI сообщает об усечении.
Событие отключения и предыстория при этом не вытесняются.
Время — 32-битный счётчик миллисекунд записи. Он идёт только при включённом
регистраторе и не является абсолютным временем. События в одном тике имеют
одинаковую отметку; порядок сохраняется порядком записей. На перезапуске
регистратора счётчик продолжает прежнюю шкалу, при перезагрузке платы — 0.
Онлайн-опрос возвращает две последние записи каждые 40 мс. Он не гарантирует
передачу каждого события при высоком CAN-трафике, медленном UART или паузах
GUI. Номера записей позволяют убрать дубликаты и явно показать пропуски.
Полный сохранившийся фрагмент следует читать кнопкой архива. Частота 20 мс
выбрана с учётом размера кадра; на низких скоростях нужна большая пауза
снимков и подходящий тайм-аут RS.
Все писатели и чтение одного Modbus-блока используют короткие критические
секции с восстановлением прежнего состояния IRQ. Внутри нет ожидания UART,
EEPROM, выделения памяти или копирования целого банка. Реальную задержку
прерываний и длительность критических секций нужно измерить на F28335.
## Состав записи v3: 42 слова
| Слова | Данные | Единицы/смысл |
|---|---|---|
| 0–1 | Время, младшее/старшее слово | мс записи |
| 2 | Событие | 1 период, 2 CAN RX, 3 изменение I/O, 4 RS-команда, 5 конец постинтервала |
| 2, бит 8 | Триггер отключения | флаг поверх причины события |
| 2, бит 9 | Усечён постинтервал | установлен в конечном снимке |
| 3 | Commands / modbus[0x7F] | все 16 бит, в том числе пуск, сброс, инициализация и калибровка ЦАП |
| 4 | Входы OMEGA, Start_1, Res_in | биты 0,1,2, активный уровень приведён к 1 |
| 5 | START_DPTB, STOP_DPTB, RES_OUT_2 | биты 0,1,2, активный уровень приведён к 1 |
| 6 | IMPowse | остаток импульса, мс |
| 7 | WAKEpowse | остаток инициализации, тики DAC_FREQ |
| 8 | modbus[0x7B] | 12-битный код, переданный функцией dSEND в ЦАП |
| 9 | modbus[0x1C] | расчётное задание в 0.1 мА; GUI/CSV переводит в мА |
| 10–13 | sens_data[0..3] | измеренные сигналы, знаковое 16-битное значение в исходном масштабе |
| 14–17 | modbus[0..3] | маски ошибок измерений |
| 18 | CAN заголовок | адрес регистра в младших 13 битах и маска трёх слов в старших |
| 19–21 | Три слова последнего принятого CAN-кадра | без преобразования |
| 22 | Счётчик записанных CAN RX | младшие 16 бит |
| 23 | CanTimeOutErrorTR | младшие 16 бит счётчика тайм-аутов CAN TX |
| 24–25 | DAC_go, DAC_stop | исходные начальная/конечная уставки, мА |
| 26–28 | DAC_min(), DAC_max(), DAC_cal() | коды калибровки и ручного задания ЦАП |
| 29–30 | DAC_04, DAC_20 | значения соответствующих регистров |
| 31–32 | count_load, time_dac | положение и длительность разгона в тиках |
| 33–34 | эффективные dac_go/dac_stop + 4 | 0.1 мА после ограничений алгоритма; GUI переводит в мА |
| 35 | kod | целочисленное положение, используемое Anal_output |
| 36–39 | ADC_table[0..3] | значения таблицы АЦП в исходном масштабе прошивки |
| 40 | ЗПТ1: U1 + U2, ПМ67 регистр 306 / индекс 305 | исходное 16-битное слово без пересчёта |
| 41 | ЗПТ2: U3 + U4, ПМ67 регистр 9 / индекс 8 | исходное 16-битное слово без пересчёта |
Напряжения принимаются из технологических CAN-кадров с нулевыми индексами
305 и 8. Учитываются все три позиции и биты маски 0x8000/0x4000/0x2000.
Они хранятся отдельно от массива modbus[0..127], обновляются и при выключенном
логгере. Запись содержит последние принятые значения; до первого приёма — 0.
При потере связи остаётся последнее значение: отдельного признака свежести нет.
Масштаб и знаковость физического напряжения не заданы исходной таблицей;
SetGUI показывает исходное беззнаковое слово, коэффициент задаётся в интерфейсе.
**Отправленный код ЦАП не является измеренным током выхода.** В этом проекте
не установлено, какой вход аппаратно измеряет ток ЦАП. При включённом
`cCalibrDac` отправляется `DAC_cal()`, а расчётное задание 0x1C остаётся
результатом алгоритма разгона. Для диагностики это различие сохранено.
ADC_table также уже обрабатывается существующим измерительным кодом;
это не обязательно необработанный регистр ADCRESULT.
Управляющая логика не исправлялась. Например, существующая строка
`if(dac_stop>16) dac_go=16;` в Load_runner сохранена; журнал показывает
фактически получившиеся эффективные уставки, чтобы выявить такое поведение.
## Протокол расширения Modbus
Технологические адреса 0..127 сохранены. Новая область использует полный
16-битный адрес; исходная реализация игнорировала старший байт.
Сначала GUI читает 16 слов 0x1000 и проверяет сигнатуру, версию, размер записи
и тип платы. До успешной проверки расширенные записи запрещены.
Обычный ответ расширения не содержит исторических хвостовых нулей.
Между ответом и следующим запросом GUI выдерживает паузу RTU.
FC03, 0x1000, 16 слов:
| Смещение | Значение |
|---|---|
| 0,1 | 0x554D, версия 3 |
| 2,3 | состояние и число записей выбранного источника |
| 4,5 | 42 слова в записи, 760 записей в банке |
| 6 | период периодических снимков, мс |
| 7,8 | счётчик времени, младшее/старшее слово |
| 9,10 | Desk (требуется 6 / dsk_LOAD), Mode |
| 11 | частота временной базы, 1000 Гц |
| 12 | поколение архива, mod 65536 |
| 13 | число записей архива |
| 14 | оставшиеся миллисекунды постинтервала |
| 15 | состояние текущего регистратора независимо от выбора источника |
Состояния: 0 — ещё не запущен, 1 — запись, 3 — остановлен/архив.
FC06:
- 0x1000: 1 — новый текущий журнал, 0 — остановить его;
- 0x1001: период 1..1000, менять только при остановленном журнале;
- 0x1002: хронологический индекс первой записи окна 0..759;
- 0x1003: источник окна, 0 — текущий остановленный банк, 1 — архив отключения.
FC03, 0x1010, до 120 слов: окно от установленного индекса; для целых записей v3 читать 42 или 84 слова.
CAN допускает 42/84 и прежние размеры 40/80/120; RTU допускает 1..120 слов.
Чтение текущего банка этим окном во время записи не выдаёт изменяющиеся
данные. GUI сначала останавливает его; архив можно читать при работающем
текущем банке. После всех блоков GUI повторно проверяет поколение архива;
при замене во время чтения результат не подменяет предыдущий график.
FC03, 0x1100, ровно 124 слова: онлайн-блок. Слова 0,1 — 32-битный номер
первой записи, 2 — число записей 0..2, 3 — поколение архива, далее до двух
записей по 42 слова. Неиспользованные слова равны нулю. Окно онлайн не
зависит от курсора/выбора архива. Разделение 0x1010 и 0x1100 предотвращает
пересечение двух окон.
Недопустимые диапазоны и значения возвращают исключения Modbus 2/3.
CRC и разбор стандартного ответа GUI используют существующее общее ядро.
SetGUI распознаёт v2 (40 слов, 800 записей) и v3 (42 слова, 760 записей).
Для v2 новые напряжения недоступны (NaN), для v3 доступны графики и CSV.
CAN-валидация общей библиотеки расширена размерами 42/84 слова.
Исходники протокола подключаются к прошивке из templates/c/set-protocol.
## Проверка и запуск
Полная сборка исправления: `./build_logger.ps1`. По умолчанию используется
`../newProject/SETGUI/third_party/templates`; другую копию можно указать
параметром `-TemplatesRoot`. В ней нужны `c/set-protocol/src/ump_protocol.c`
и `c/set-protocol/ports/tms320f28335/ump_tms28335.c` (порт УМП v3).
Само наличие папки templates не гарантирует наличие этого порта.
Результат — `Bin/LoggerFix/UKSSTMS320F28335_logger_fix.bin` (SCI8 boot),
рядом OUT и MAP. Старые образы в Bin не заменяются.
Скрипт использует TI C2000 22.6 COFF, оптимизацию размера и секции функций;
таблица `.cinit` размещена в RAML4 вместе с константами, код — в RAML0.
Для сборки из CCS добавьте `Source/Internal/shared_ump.c` в проект и каталоги
`<templates>/c/set-protocol`, `<templates>/c/set-protocol/ports/tms320f28335`
в include path; используйте параметры оптимизации из скрипта.
При загрузке `main()` вызывает `ump_log_init()` до включения прерываний.
Это обязательно для TI COFF: стартовый код не обнуляет неинициализированные
переменные `.ebss`. Без явной инициализации состояние, счётчики и номера
банков могут содержать остаточные значения RAM. Очистка `.logg` функцией
`clear_mem()` эти переменные не затрагивает. Повторный запуск записи через
FC06 не вызывает загрузочную инициализацию и сохраняет архив и шкалу времени.
Регрессия `python tests/ump_logger/run_init_test.py` (GCC в PATH) проверяет
запуск с ненулевой RAM и отрицательный контроль без инициализации;
внешняя библиотека `templates/c/set-protocol` для этого теста не нужна.
Изменены исходники прошивки и SetGUI. Готовый образ в Bin не обновлялся.
Для платы необходима сборка штатным TI C2000/CCS, проверка размещения .text,
.stack, .ebss и .logg по MAP, прошивка и испытание на стенде.
Автотест C в tests/ump_logger компилирует непосредственно log_to_mem.c
с подменой GPIO/IRQ. Проверяет кольцо, граничные адреса, обе команды
отключения, защиту триггера от переполнения, переключение банков,
сохранность архива во время дальнейшей записи и контрольные поля CAN/ЦАП.
Это проверка алгоритма на компьютере, не проверка таймингов и 16-битной ABI
TI. Отдельно выполнена синтаксическая проверка изменённых C-файлов Clang
с исходными заголовками и декларациями TI-интринсиков.
Тесты SetGUI: tests/test_ump_logger.py и tests/test_periph28335_tab.py.
Они проверяют единицы мА, битовые сигналы, временные метки, несовместимую
прошивку, порядок команд, архив при активной записи, замену поколения,
дубликаты/пропуски онлайн, потерю связи и флажки графиков.
Проверка на стенде: включить запись → подать CAN-пуск → изменить уставку →
подать откл. → через секунду прочитать архив → сверить код ЦАП, ток внешним
измерителем и физические входы/выходы; затем повторить с разрывом RS.
Период 1 мс проверить отдельно под максимальной CAN-нагрузкой.
Для сборки v3 нужен templates/main начиная с коммита c0ee7c4
(поддержка CAN-чтения 42/84 слов и порт TMS320F28335).
## Пересечение образа 34a95bc5 с параметрами EEPROM
Образ `UKSSTMS320F28335_34a95bc5.bin` имеет размер 32518 байт.
`Save_params` записывает 129 слов с адреса `0x3FFF-(128+1)`;
драйвер EEPROM умножает адрес на 2. Параметры начинаются с байта 32508.
Последние 10 байт BIN пересекаются с параметрами: два последних адреса
таблицы переходов `ump_log_read` (регистры 0x100E/0x100F) и завершающее
нулевое слово загрузочной таблицы. Сохранение параметров повреждает эту
часть образа для последующей загрузки. Это установленный дефект образа;
причину таймаута на конкретной плате нужно подтвердить повторной проверкой.
В исправлении временный снимок RS перенесён со стека в статический буфер:
обработчики RS вызываются последовательно из main, а перед возвратом
снимок полностью кодируется в собственный буфер UART. CAN имеет свой буфер.
Сборка `build_logger.ps1` использует параметры CCS Debug (-O1, speed=3)
и создаёт отдельный `Bin/LoggerEepromFix/UKSSTMS320F28335_logger_eeprom_fix.bin`.
Проверенный размер — 32494 байта, запас до параметров — 14 байт.
Оба сценария сборки вызывают `check_firmware.ps1` до публикации BIN.
Проверяются размер, формат SCI8, полнота блоков и конец загрузочной таблицы.
При превышении границы остаётся только файл `.pending`; готовый BIN
не публикуется. Проверка: `python tests/ump_logger/test_firmware_image.py`.
После перепрошивки требуется проверка на плате; проверка на ПК её не заменяет.

File diff suppressed because one or more lines are too long

View File

@@ -1,723 +0,0 @@
/**
@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 Описание адреса, буфера и длины.
*/
/**
@}
*/

View File

@@ -1,64 +0,0 @@
@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

View File

@@ -1,69 +0,0 @@
/**
@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, чтобы препроцессор не выбирал несовместимые варианты. */

File diff suppressed because one or more lines are too long

View File

@@ -1,70 +0,0 @@
# 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

@@ -128,7 +128,8 @@ SECTIONS
{
/* Allocate program areas: */
.cinit : > RAML0 PAGE = 0
/* Keep initialization tables out of the code RAM block. */
.cinit : > RAML4 PAGE = 0
.pinit : > RAML0 PAGE = 0
.text : > RAML0 PAGE = 0
codestart : > BEGIN PAGE = 0

View File

@@ -1,13 +1,3 @@
/**
* @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"
@@ -24,37 +14,20 @@
#include "peripher.h"
/** @brief Сырые отсчёты четырёх силовых каналов, передаваемые Current_count(). */
Uint16 adc_table_lem[4];
/** @brief Фильтрованные значения всех рабочих и калибровочных каналов. */
Uint16 ADC_table[28]; // Потому что +4 калибр
/** @brief Число допустимых отсчётов прошлого окна для контроля выбросов. */
Uint16 ADC_table[28]; // Ïîòîìó ÷òî +4 êàëèáð
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;
@@ -86,23 +59,21 @@ 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)
@@ -116,7 +87,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.
@@ -134,23 +105,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;
}
@@ -181,7 +152,6 @@ 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
@@ -225,18 +195,6 @@ 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;
@@ -256,7 +214,6 @@ interrupt void adc_isr(void)
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
/* До READY обслуживается только обязательное завершение аппаратного цикла. */
if(WAKE) WAKE--;
if(!READY) goto fin;
@@ -289,7 +246,7 @@ interrupt void adc_isr(void)
{
if (++cownt_cans>=tpl_cans) cownt_cans=0;
// Именно здесь нет дыр
// Èìåííî çäåñü íåò äûð
// if(sens_type[cownt_cans])
{
i++;
@@ -299,7 +256,6 @@ interrupt void adc_isr(void)
else Power_count(cownt_cans);
} } }
/* Программный мультиплексор: переключение, выдержка, накопление и расчёт. */
if(TermoSW)
{
if(cownt_one_canal==COUNT_DISCHARGE)
@@ -309,12 +265,11 @@ 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++)
{
@@ -322,7 +277,6 @@ interrupt void adc_isr(void)
Temper = *(&AdcRegs.ADCRESULT0 + i) >>4;
/* Ограничитель защищает рекурсивный фильтр от одиночного выброса. */
ok = abs(ADC_table[n]-Temper) < FILTER_CLIP;
if(ok) cwnt_ok[i]++;
@@ -371,7 +325,6 @@ 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,13 +1,3 @@
/**
* @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"
@@ -31,10 +21,6 @@ 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;
@@ -43,14 +29,12 @@ 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;
@@ -58,11 +42,6 @@ void wast()
for(i=0;i<25;i++);
}
/**
* @brief Последовательно передаёт одно управляющее слово во внешний ЦАП.
* @param word Слово протокола, выдаваемое по DATA синхронно с CLK.
* @note CS и CLK переключаются программно; порядок фронтов менять нельзя.
*/
void dSEND(unsigned int word)
{
int i;
@@ -78,20 +57,12 @@ 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;
@@ -99,7 +70,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();
@@ -128,14 +99,11 @@ 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;
@@ -162,12 +130,27 @@ 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_go=16;
if(dac_stop<=dac_go) dac_stop=dac_go+1;
/* Äëÿ ëîãà ñîõðàíÿåì ðåàëüíûå îãðàíè÷åííûå óñòàâêè:
* âíóòðåííèå dac_go/stop îòñ÷èòûâàþòñÿ îò 4 ìÀ. */
ump_dac_go10 = (unsigned int)((dac_go + 4.0) * 10.0);
ump_dac_stop10 = (unsigned int)((dac_stop + 4.0) * 10.0);
}
if(count_load > (time_dac/2))count_load++;
if(++count_load > time_dac) count_load = 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);
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);
}
else
{ count_load = 0;
@@ -175,6 +158,13 @@ void Load_runner()
x = (x+1)&0x3FF;
}
/* Ñíèìîê ñòàäèè ðàçãîíà äëÿ ñîïîñòàâëåíèÿ êîìàíäû CAN,
* îæèäàåìîãî òîêà è êîäà, äåéñòâèòåëüíî îòïðàâëåííîãî ÖÀÏ. */
ump_dac_ramp = count_load;
ump_dac_duration = time_dac;
ump_dac_position = (unsigned int)sinus;
preStart = cUMPstart;
if(!x || cInitDac)
{
Init_DAC(); x=1; cInitDac=0;

View File

@@ -1,18 +1,8 @@
/**
* @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,23 +1,8 @@
/**
* @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 long IMPowse, WAKEpowse;
extern unsigned int period_dac, time_dac;

View File

@@ -1,12 +1,3 @@
/**
* @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
@@ -20,7 +11,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
@@ -32,7 +23,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
@@ -63,7 +54,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
@@ -75,7 +66,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
@@ -106,7 +97,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
@@ -118,7 +109,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
@@ -149,7 +140,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
@@ -161,7 +152,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
@@ -192,7 +183,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
@@ -204,7 +195,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
@@ -235,7 +226,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
@@ -247,7 +238,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
@@ -278,7 +269,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
@@ -290,7 +281,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,21 +1,3 @@
/**
* @file RS485.h
* @brief Состояние портов SCI/RS-485, ограничения буферов и API обмена.
*
* RS_DATA объединяет регистры SCI, буферы, счётчики и состояние конечного
* автомата. Память буферов принадлежит вызывающему коду и должна оставаться
* доступной до завершения операции. MAX_RECEIVE_LENGTH/MAX_SEND_LENGTH задают
* жёсткую границу, которую необходимо проверить до помещения данных в буфер.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
RS485.h
****************************************************************
* Процедуры работы с UART *
****************************************************************/
#ifndef _RS485
#define _RS485
@@ -28,6 +10,10 @@
//#include "cntrl_adr.h"
//#include "params.h"
#ifndef RS232_USE_FIFO
#define RS232_USE_FIFO 1
#endif
#define COM_1 1
#define COM_2 2
@@ -47,107 +33,106 @@ 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;
unsigned long curr_baud;
unsigned long time_wait_rs_out;
#if RS232_USE_FIFO
volatile unsigned int fifo_tx_active, fifo_rx_guard;
volatile unsigned long fifo_rx_errors, fifo_overflows;
#endif
} RS_DATA;
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_DATA и задаёт размер команды 15. */
/* иницилизациа переменных rs_a,rs_b*/
void create_uart_vars(char size_cmd15);
/** Повторнаа инициализациа последовательного порта, используетса после подвиса */
/** Настройка режима приема/передачи */
/** Повторнаа инициализациа последовательного порта, используетса после подвиса */
/** Настройка режима приема/передачи */
void RS_SetBitMode(RS_DATA *rs_arr, int n);
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param rs_arr Состояние выбранного порта.
@param pBuf Адрес массива слов, каждое из которых содержит один байт.
@param len количество байт
@return Ненулевое значение, если передача принята драйвером.
/** Посылка блока байтов.
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество байт
@see RS_BSend, RS_TRANSMIT_INTR
*/
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len);
/** Посылка блока упакованных байтов.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param rs_arr Состояние выбранного порта.
@param pBuf Адрес массива с упакованными байтами.
@param len количество 8-битных байт
@return Ненулевое значение, если передача принята драйвером.
/** Посылка блока упакованных байтов.
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
@param buf адрес массива
@param len количество 8-битных байт
@see RS_Send, RS_TRANSMIT_INTR
*/
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len);
/** Инициализациа последовательного порта */
/** @param commnumber COM_1 или COM_2. @param speed_baud Скорость линии в бодах. */
void setup_uart(char commnumber,unsigned long speed_baud); /* 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
#if RS232_USE_FIFO
void RS_FifoWait(RS_DATA *rs_arr);
void RS_FifoTick1ms(void);
#define RS_Wait4OK(x) RS_FifoWait(x)
#else
#define RS_Wait4OK(x) while(!(x->SciRegs->SCICTL2.bit.TXEMPTY))
#endif
/** Переключение линии на прием */
/** Переключение линии на прием */
#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,20 +1,3 @@
/**
* @file bios_dsp.h
* @brief Команды сервисного BIOS и API удалённой работы с памятью.
*
* Объявляет номера команд загрузчика и обработчики, работающие с RS_DATA.
* Интерфейс предоставляет прямые операции с адресным пространством DSP и
* предназначен только для доверенных, уже проверенных протокольных запросов.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************/
/* Bios_dsp.h */
/****************************************************************/
/* Основные комманды BIOS */
/****************************************************************/
#ifndef _BIOS_DSP
#define _BIOS_DSP
@@ -50,85 +33,71 @@ 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,31 +1,22 @@
/**
* @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 //---------------------------------------------------------------------
@@ -33,45 +24,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 //---------------------------------------------------------------------
@@ -80,15 +71,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,20 +1,3 @@
/**
* @file cntrl_adr.h
* @brief Адреса узла в сервисном протоколе и функция их установки.
*
* Константные адреса задают специальные роли, CNTRL_ADDR и ADDR_FOR_ALL могут
* меняться во время настройки. Заголовок не выполняет валидацию диапазонов.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
cntrl_adr.h
****************************************************************
* Адрес контроллера *
****************************************************************/
#ifndef _CNTRL_ADR
#define _CNTRL_ADR
@@ -22,26 +5,22 @@
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,20 +1,8 @@
/**
* @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,22 +1,6 @@
/**
* @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[];
/* Íåáëîêèðóþùàÿ ïåðåäà÷à îòâåòîâ ëîããåðà îòäåëüíûì CAN mailbox. */
void UMP_CAN_service(void);

View File

@@ -1,11 +1,3 @@
/**
* @file filter_bat2.h
* @brief Коэффициенты и состояние рекурсивного НЧ-фильтра второго порядка.
*
* Наборы K*_FILTER_BATTER2_* рассчитаны для заданных частот среза при штатной
* частоте дискретизации. DEF_FILTERBAT создаёт нулевое состояние для 3 Гц;
* один экземпляр FILTERBAT нельзя одновременно использовать для разных каналов.
*/
#ifndef _FILTER_BAT2
#define _FILTER_BAT2
@@ -46,12 +38,6 @@ 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,13 +1 @@
/**
* @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,21 +1,3 @@
/**
* @file log_to_mem.h
* @brief Разметка внешней памяти и состояние кольцевого журнала.
*
* LOG_PAGE_START и LOG_PAGE_LEN обязаны совпадать с картой линковщика. Флаги
* no_write/never_write запрещают запись на разных уровнях, а clear_mem()
* полностью обнуляет область и потому является длительной операцией.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2001г. */
/****************************************************************/
/* log_to_mem.h
****************************************************************
* Запись логов в памyть *
****************************************************************/
#ifndef _LOG_TO_MEM
#define _LOG_TO_MEM
@@ -23,11 +5,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
{
@@ -40,17 +22,34 @@ 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();
/* Ëîããåð ÓÌÏ: îòäåëüíîå àäðåñíîå ïðîñòðàíñòâî Modbus, áåç èçìåíåíèÿ
* 128 òåõíîëîãè÷åñêèõ ðåãèñòðîâ. Äâà áàíêà ïî 760 çàïèñåé:
* òåêóùèé êîëüöåâîé æóðíàë è çàôèêñèðîâàííûé ôðàãìåíò îòêëþ÷åíèÿ. */
#define UMP_LOG_BASE 0x1000U
#define UMP_LOG_DATA 0x1010U
#define UMP_LOG_WORDS 42U
#define UMP_LOG_CAPACITY 760U
#define UMP_LOG_LIVE_RECORDS (120U / UMP_LOG_WORDS)
#define UMP_LOG_LIVE 0x1100U
extern unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
void ump_log_init(void);
void ump_log_tick(void);
void ump_log_io(void);
void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned int c);
void ump_log_rs(void);
unsigned int ump_log_read(unsigned int address);
int ump_log_write(unsigned int address, unsigned int value);
#ifdef __cplusplus
}
#endif

View File

@@ -1,41 +1,18 @@
// вгв
#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
@@ -86,14 +63,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
@@ -108,23 +85,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,11 +1,3 @@
/**
* @file message.h
* @brief Форматы команд, размеры ответов и API обработки Modbus-сообщений.
*
* CMD_TO_TMS описывает точную раскладку принятого кадра, включая CRC. Поля и
* ANSWER_LEN/REPLY_LEN согласованы с удалённым мастером; структура использует
* целевые типы DSP, поэтому не должна сериализоваться простым memcpy на PC.
*/
#ifndef MESSAGE_H
#define MESSAGE_H
@@ -19,8 +11,8 @@ typedef unsigned char CHAR;
typedef struct
{
unsigned char Address; // Адрес контроллера
unsigned char Number; // Номер команды
unsigned char Address; // Àäðåñ êîíòðîëëåðà
unsigned char Number; // Íîìåð êîìàíäû
BAITE byte0;
BAITE byte1;
@@ -38,20 +30,13 @@ 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,12 +1,3 @@
/**
* @file package.h
* @brief Центральная конфигурация изделия Balsam и адресов его подсистем.
*
* Значение BALSAM выбирает аппаратный вариант, направление вращения и набор
* возможностей. adr_* и последующие константы связывают физические модули с
* протоколом и массивами измерений. Изменение этого файла влияет на всю прошивку
* и должно сопровождаться проверкой схемы, карты CAN/Modbus и калибровки.
*/
#ifndef PACKAGE
#define PACKAGE
@@ -100,16 +91,15 @@
#define bSecretBt Buttons.bit.bit1
#define bTermoCal Buttons.bit.bit2
#define Cancount (modbus+0x60) // пауза между I посылками CAN
#define Bright (modbus+0x62) // аркость сигнальных лампочек
#define Brightness modbus[0x62] // аркость сигнальных лампочек
// Ïðèøëî âðåìà!
#define DAC_go modbus[0x50] // íà÷àëî çàðàäà
#define DAC_stop modbus[0x51] // êîíåö çàðàäà
#define Owncount modbus[0x63] // пауза между опросами OWEN
#define Cancount (modbus+0x60) // ïàóçà ìåæäó I ïîñûëêàìè CAN
#define Bright (modbus+0x62) // àðêîñòü ñèãíàëüíûõ ëàìïî÷åê
#define Brightness modbus[0x62] // àðêîñòü ñèãíàëüíûõ ëàìïî÷åê
/* Не врема!
#define DAC_go modbus[0x64] // начало зарада
#define DAC_stop modbus[0x65] // конец зарада
*/
#define Owncount modbus[0x63] // ïàóçà ìåæäó îïðîñàìè OWEN
#define m_FAST 0
#define m_SLOW 1

View File

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

View File

@@ -1,32 +1,8 @@
/**
* @file spise2p.h
* @brief Конфигурация SPI EEPROM и структуры её конечного автомата.
*
* Определяет команды микросхемы, ширину адреса/данных, скорость SPI и состояния
* транзакции. SPISE2P_DRV_DEFAULTS создаёт единственный драйвер с callback-функциями;
* перед чтением или записью требуется InitSeeprom(), а диапазон операции должен
* оставаться внутри SEEPROM_LEN.
*/
/*=====================================================================
File name : SPISE2P.H
Originator : Settu Duraisamy
C2000 Applications Team
Texas Instruments
Description :
Header file containing object definitions, proto type
declaration and default object initializers for
SPI Serial EEPROM driver using VSPI
Date : 30/6/2003 (DD/MM/YYYY)
=======================================================================*/
#ifndef __SPISE2P_H__
#define __SPISE2P_H__
// Ёмкость памати в байтах
// Ёмкость памати в байтах
#define SEEPROM_LEN 0x10000
#define NULL 0
@@ -99,28 +75,13 @@ 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)
@@ -133,27 +94,25 @@ 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 - длина блока в байтах. По-любому в байтах! */
/** @param size Размер блока в байтах, независимо от SPISE2P_DATA_WIDTH. */
/* Запись блока в SEEPROM. Параметры таковы: **
** adres - адрес в епромке, куда писать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, откуда писать. **
** size - длина блока в байтах. По-любому в байтах! */
void Seeprom_write(unsigned int adres, unsigned int buf[], unsigned int size);
/* Чтение блока из SEEPROM. Параметры таковы: **
** adres - адрес в епромке, откуда читать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, куда читать. **
** size - длина блока в байтах. По-любому в байтах! */
/** @param size Размер блока в байтах, независимо от SPISE2P_DATA_WIDTH. */
/* Чтение блока из SEEPROM. Параметры таковы: **
** adres - адрес в епромке, откуда читать. **
** adres = 0..0x8000, если длина слова 8 бит **
** adres = 0..0x4000, если длина слова 16 бит **
** buf - указатель на памать, куда читать. **
** size - длина блока в байтах. По-любому в байтах! */
void Seeprom_read(unsigned int adres, unsigned int buf[], unsigned int size);
#endif

View File

@@ -1,18 +1,7 @@
/**
* @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

@@ -0,0 +1,9 @@
/* Shared logger protocol; application owns IRQ protection and CAN scheduling. */
#ifndef UMP_CAN_PROTOCOL_H
#define UMP_CAN_PROTOCOL_H
#include "log_to_mem.h"
#include "ump_tms28335.h"
#define UMP_CAN_MARKER UMP_MARKER
#define UMP_CAN_MAX_WORDS UMP_MAX_WORDS
#define ump_can_prepare ump_tms28335_prepare
#endif

View File

@@ -1,23 +1,3 @@
/**
* @file RS485.c
* @brief Драйвер двух каналов SCI/RS-485 и автоматы приёма/передачи кадров.
*
* Настраивает SCI-A/SCI-B, обслуживает RX/TX-прерывания, контролирует длины
* команд и тайм-аут активности, а также переключает формат и скорость линии.
* RS_DATA содержит разделяемое состояние конечного автомата; буферы должны
* жить до завершения передачи и не превышать MAX_*_LENGTH. Обработчики обязаны
* подтверждать PIE и корректно возвращать приоритеты прерываний.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
RS485.с
****************************************************************
* Процедуры работы с UART *
****************************************************************/
//#include "big_dsp_module.h"
@@ -41,13 +21,13 @@ static char size_cmd15=1;
void RS_RX_Handler(RS_DATA *rs_arr);
void RS_TX_Handler(RS_DATA *rs_arr);
#if RS232_USE_FIFO
static int RS_FifoStart(RS_DATA *, unsigned int *, unsigned long, int);
static void RS_FifoTx(RS_DATA *);
static void RS_FifoAbort(RS_DATA *);
#endif
/** Обработчик прерываний UART - принато */
/**
* @brief ISR приёма SCI-A.
* @details Временно ограничивает приоритеты группы PIE9, вызывает общий
* RS_RX_Handler() для rs_a, затем восстанавливает маску и подтверждает группу.
*/
/** Îáðàáîò÷èê ïðåðûâàíèé UART - ïðèíàòî */
interrupt void RSA_RX_Handler(void)
{
// Set interrupt priority:
@@ -66,7 +46,6 @@ 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:
@@ -85,7 +64,6 @@ 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:
@@ -104,7 +82,6 @@ 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:
@@ -123,15 +100,7 @@ interrupt void RSB_TX_Handler(void)
PieCtrlRegs.PIEIER9.all = TempPIEIER;
}
/** Обработчик прерываний UART - принато */
/**
* @brief Принимает очередной символ и продвигает автомат сборки кадра.
* @param rs_arr Состояние порта, вызвавшего прерывание.
* @details Проверяет аппаратные ошибки, адресный девятый бит, ожидаемую длину
* команды и границы буфера. После полного кадра выставляет признак готовности
* для foreground-кода; при нарушении синхронизации возвращается к ожиданию адреса.
* @warning Выполняется из ISR и не должен вызывать блокирующие операции.
*/
/** Îáðàáîò÷èê ïðåðûâàíèé UART - ïðèíàòî */
void RS_RX_Handler(RS_DATA *rs_arr)
{
char Rc;
@@ -139,16 +108,34 @@ void RS_RX_Handler(RS_DATA *rs_arr)
// led1_on();
for(;;) // 'goto' это не оператор азыка С
for(;;) // 'goto' ýòî íå îïåðàòîð àçûêà Ñ
{
#if RS232_USE_FIFO
if (rs_arr->commnumber == COM_1) {
unsigned int received;
if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF || rs_arr->SciRegs->SCIRXST.bit.RXERROR) {
RS_FifoAbort(rs_arr); return;
}
if (!rs_arr->SciRegs->SCIFFRX.bit.RXFFST) {
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1;
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
return;
}
received=rs_arr->SciRegs->SCIRXBUF.all; /* one pop, data + FE/PE */
if (received & 0xC000U) { RS_FifoAbort(rs_arr); return; }
if (rs_arr->fifo_rx_guard) { rs_arr->fifo_rx_guard=4; continue; }
Rc=received & 255U;
} else
#endif
{
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
{
@@ -158,42 +145,44 @@ void RS_RX_Handler(RS_DATA *rs_arr)
continue;
}
if(rs_arr->RS_DataReady) continue; // Не забрали данные
}
if (rs_arr->RS_Flag9bit==1) // дла RS485????????
if(rs_arr->RS_DataReady) continue; // Íå çàáðàëè äàííûå
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)
{
@@ -206,77 +195,73 @@ 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 - послано */
/**
* @brief Передаёт следующий элемент активного RS-485 буфера.
* @param rs_arr Состояние обслуживаемого SCI.
* @details Пока счётчик не достиг RS_Length, пишет следующий байт в SCITXBUF.
* После последнего байта дожидается освобождения линии, возвращает трансивер
* в режим приёма и сбрасывает состояние передачи.
*/
/** Îáðàáîò÷èê ïðåðûâàíèé UART - ïîñëàíî */
void RS_TX_Handler(RS_DATA *rs_arr)
{
#if RS232_USE_FIFO
if (rs_arr->commnumber == COM_1) { RS_FifoTx(rs_arr); return; }
#endif
char RS_BytePtr;
// unsigned int i;
@@ -284,18 +269,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 */
@@ -304,7 +289,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 ));
@@ -312,22 +297,19 @@ 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 */
}
}
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
// rs_arr->SciRegs->SCIFFTX.bit.TXINTCLR=1; // Clear INT flag
}
/** Инициализациа массива длин команд */
/**
* @brief Заполняет таблицу ожидаемых длин сервисных и Modbus-команд.
* @post RS_Len[код] содержит полную длину кадра для поддерживаемых команд.
*/
/** Èíèöèàëèçàöèà ìàññèâà äëèí êîìàíä */
void setup_arr_cmd_length()
{
int i;
@@ -354,105 +336,94 @@ 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)
{
#if RS232_USE_FIFO
if (rs_arr->commnumber == COM_1) return RS_FifoStart(rs_arr,pBuf,len,BM_CHAR32);
#endif
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)
{
#if RS232_USE_FIFO
if (rs_arr->commnumber == COM_1) return RS_FifoStart(rs_arr,pBuf,len,BM_PACKED);
#endif
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 в бод */
/**
* @brief Пересчитывает делитель baud-rate выбранного SCI.
* @param speed Требуемая скорость в бодах.
* @pre speed больше нуля и достижима от LSPCLK.
*/
/** Óñòàíàâëèâàåò ñêîðîñòü îáìåíà.
@param speed ñêîðîñòü RS â áîä */
/** Óñòàíàâëèâàåò ñêîðîñòü îáìåíà.
@param speed ñêîðîñòü RS â áîä */
void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
{
long SciBaud;
@@ -466,11 +437,7 @@ 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;
@@ -480,13 +447,8 @@ 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;
@@ -549,15 +511,28 @@ void setup_uart(char commnumber, unsigned long speed_baud)
SciRegs->SCICTL1.bit.TXENA=1;
SciRegs->SCICTL1.bit.RXENA=1;
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
SciRegs->SCIFFRX.bit.RXFFIL=1; // Длина наименьшей команды
#if RS232_USE_FIFO
if (commnumber == COM_1) {
SciRegs->SCIFFTX.all=0xC008U; /* enhancement, reset held, TX level 8, IRQ off */
SciRegs->SCIFFRX.all=0x0061U; /* reset held, RX level 1, IRQ on */
SciRegs->SCIFFCT.all=0;
SciRegs->SCIFFRX.bit.RXFFOVRCLR=1;
SciRegs->SCIFFTX.bit.TXFFINTCLR=1;
SciRegs->SCIFFTX.bit.TXFIFOXRESET=1;
SciRegs->SCIFFRX.bit.RXFIFORESET=1;
rs_arr->fifo_tx_active=rs_arr->fifo_rx_guard=0;
rs_arr->fifo_rx_errors=rs_arr->fifo_overflows=0;
} else
#endif
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
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;
@@ -565,11 +540,10 @@ 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 количество стоповых бит */
/** @brief Программирует длину слова, чётность и число стоп-битов SCI. */
/** Íàñòðîéêà ðåæèìà ëèíèè.
@param bit êîëè÷åñòâî áèò äàííûõ
@param parity ðåæèì ÷åòíîñòè (N,O,E,M,S)
@param stop êîëè÷åñòâî ñòîïîâûõ áèò */
void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop)
{
volatile struct SCI_REGS *SciRegs;
@@ -607,14 +581,12 @@ 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 */
/** @brief Увеличивает watchdog связи и фиксирует тайм-аут удалённого узла. */
/* ïðîâåðêà íà æèâó÷åñòü RS */
void test_rs_live(RS_DATA *rs_arr)
{
/* if (rs_arr->time_wait_rs_out < RS_TIME_OUT)
@@ -622,6 +594,120 @@ 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);
}*/ }
#if RS232_USE_FIFO
/* FIFO is exclusively SCI-A / RS232. SCI-B keeps the legacy path. */
void RS_FifoWait(RS_DATA *rs_arr)
{
if (rs_arr->commnumber != COM_1) {
while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }
return;
}
while (rs_arr->fifo_tx_active || rs_arr->SciRegs->SCIFFTX.bit.TXFFST ||
!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }
}
static void RS_FifoTx(RS_DATA *rs_arr)
{
unsigned int data;
if (!rs_arr->fifo_tx_active) {
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
} else if (rs_arr->RS_SendLen == rs_arr->RS_SLength) {
/* Level 0 interrupt: FIFO drained, last symbol may still be shifting.
* Do not finish on TXFFST alone. At most one symbol remains. */
if (rs_arr->SciRegs->SCIFFTX.bit.TXFFST) {
rs_arr->SciRegs->SCIFFTX.bit.TXFFINTCLR=1;
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
return;
}
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }
if (rs_arr->RS_SendBlockMode == BM_CHAR32) {
RS_SetBitMode(rs_arr,9);
rs_arr->flag_TIMEOUT_to_Send=false;
}
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=0;
rs_arr->SciRegs->SCIFFRX.bit.RXFFOVRCLR=1;
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1;
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=1;
enableUARTInt(rs_arr);
rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA=1;
rs_arr->fifo_tx_active=0;
} else {
while (rs_arr->RS_SendLen < rs_arr->RS_SLength &&
rs_arr->SciRegs->SCIFFTX.bit.TXFFST < 16) {
if (rs_arr->RS_SendBlockMode == BM_CHAR32)
data=*rs_arr->pRS_SendPtr++;
else if (rs_arr->RS_SendLen & 1U)
data=LOBYTE(*rs_arr->pRS_SendPtr++);
else data=HIBYTE(*rs_arr->pRS_SendPtr);
SCI_send(rs_arr,data);
rs_arr->RS_SendLen++;
}
rs_arr->SciRegs->SCIFFTX.bit.TXFFIL=
rs_arr->RS_SendLen == rs_arr->RS_SLength ? 0 : 8;
}
rs_arr->SciRegs->SCIFFTX.bit.TXFFINTCLR=1;
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
}
static int RS_FifoStart(RS_DATA *rs_arr,unsigned int *buffer,unsigned long count,int mode)
{
unsigned int saved;
if (!count) return 0;
if (!buffer) return -1;
RS_FifoWait(rs_arr); /* before replacing the previous transfer's counters */
saved=__disable_interrupts();
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=0;
rs_arr->SciRegs->SCIFFRX.bit.RXFFIENA=0;
enableUARTIntW(rs_arr);
RS_SetBitMode(rs_arr,8);
rs_arr->pRS_SendPtr=buffer;
rs_arr->RS_SLength=count;
rs_arr->RS_SendLen=0;
rs_arr->RS_SendBlockMode=mode;
rs_arr->fifo_tx_active=1;
RS_FifoTx(rs_arr); /* prime before enabling a possibly immediate TX IRQ */
rs_arr->SciRegs->SCIFFTX.bit.TXFFIENA=1;
__restore_interrupts(saved);
if (count == 1 && mode == BM_CHAR32) RS_FifoWait(rs_arr);
return 0;
}
static void RS_FifoAbort(RS_DATA *rs_arr)
{
rs_arr->fifo_rx_errors++;
if (rs_arr->SciRegs->SCIFFRX.bit.RXFFOVF) rs_arr->fifo_overflows++;
rs_arr->RS_DataReady=0; rs_arr->BS_LoadOK=0;
rs_arr->RS_PrevCmd=0; rs_arr->RS_Cmd=0;
rs_arr->RS_Flag9bit=0; rs_arr->RS_FlagSkiping=1;
rs_arr->fifo_rx_guard=4;
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=0;
rs_arr->SciRegs->SCIFFRX.bit.RXFFOVRCLR=1;
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1;
if (rs_arr->SciRegs->SCIRXST.bit.RXERROR) {
rs_arr->SciRegs->SCICTL1.bit.SWRESET=0;
rs_arr->SciRegs->SCICTL1.bit.SWRESET=1;
}
rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=1;
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
}
void RS_FifoTick1ms(void)
{
unsigned int saved=__disable_interrupts();
RS_DATA *p=&rs_a;
if (p->SciRegs && p->fifo_rx_guard) {
if (p->SciRegs->SCIFFRX.bit.RXFFST) p->fifo_rx_guard=4;
else if (--p->fifo_rx_guard == 0) {
p->RS_HeaderCnt=0;p->RS_RecvLen=0;
p->RS_FlagBegin=1;p->RS_FlagSkiping=0;
RS_SetBitMode(p,9); /* fresh address after 3..4 ms of idle */
}
}
__restore_interrupts(saved);
}
#endif

View File

@@ -1,23 +1,3 @@
/**
* @file bios.c
* @brief Сервисные команды удалённого доступа к памяти и загрузки программы.
*
* Реализует разбор BIOS-команд, формирование ответов, чтение/запись памяти,
* загрузку блоков и запуск кода через транспорт RS-485. Адреса и размеры
* приходят извне, поэтому корректность пакета и CRC должна быть подтверждена
* до вызова обработчиков. Прямой доступ к памяти преднамеренно использует
* volatile и требует адресов из допустимой карты памяти контроллера.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
Bios.c
**************************************************************
Основные комманды BIOS *
дла работы с RS232
****************************************************************/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "RS485.h"
#include "bios_dsp.h"
@@ -28,95 +8,82 @@
//#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 если транзакций не было */
/**
* @brief Проверяет и диспетчеризует полностью принятый сервисный кадр.
* @param rs_arr Порт и буфер принятой команды.
* @return Код распознанной команды либо признак ошибки кадра.
* @details Проверяет адрес, длину и CRC, затем вызывает обработчик CMD_*.
*/
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
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;
@@ -132,7 +99,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;
@@ -145,8 +112,7 @@ static char _getbyte(unsigned int *addr, int32 offs)
}
/* начальные установки (не работает)*/
/** @brief Сбрасывает параметры текущей загрузочной сессии и подтверждает команду. */
/* начальные установки (не работает)*/
void init(RS_DATA *rs_arr)
{
/*
@@ -169,18 +135,13 @@ void init(RS_DATA *rs_arr)
*/
}
/**@name Комманды
* Комманды, вызываемые через последовательный канал
/**@name Комманды
* Комманды, вызываемые через последовательный канал
*/
//@{
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/**
* @brief Принимает заголовок нового образа и подготавливает диапазон загрузки.
* @details Из кадра извлекаются начальный адрес, длина и контрольные параметры;
* запись данных разрешается только после успешной проверки заголовка.
*/
/** Инициировать загрузку блока.
Настраивает прием блока данных */
void initload(RS_DATA *rs_arr)
{
unsigned long Address;
@@ -204,12 +165,8 @@ void initload(RS_DATA *rs_arr)
Answer(rs_arr,CMD_INITLOAD);
}
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/**
* @brief Записывает очередную порцию образа по текущему адресу загрузки.
* @post Рабочий адрес и остаток длины продвинуты на принятый блок.
*/
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
void load(RS_DATA *rs_arr)
{
unsigned int rcrc, crc;
@@ -234,32 +191,27 @@ 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);
@@ -292,8 +244,7 @@ void peek(RS_DATA *rs_arr)
}
/** Записать в ачейку памати */
/** @brief Записывает данные команды в заданную область памяти и отвечает статусом. */
/** Записать в ачейку памати */
void poke(RS_DATA *rs_arr)
{
unsigned long Address;
@@ -315,13 +266,12 @@ 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;
@@ -341,10 +291,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);
@@ -358,24 +308,22 @@ 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;
@@ -383,7 +331,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;
}
@@ -408,7 +356,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;
}
@@ -420,15 +368,11 @@ 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;
@@ -453,10 +397,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,21 +1,3 @@
/**
* @file cntrl_adr.c
* @brief Хранение и изменение сетевых адресов контроллера.
*
* Содержит рабочий, широковещательный, ответный и терминальный адреса узла.
* set_cntrl_addr() меняет только изменяемые адреса; вызывающий код отвечает
* за проверку диапазона и за отсутствие обмена во время перенастройки.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
cntrl_adr.c
****************************************************************
* Адрес контроллера *
****************************************************************/
#include "cntrl_adr.h"
#define ADDR_FOR_ALL_DEF 10
@@ -24,34 +6,27 @@
#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;
}

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