mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 07:06:36 +01:00
added OTA for M3 tags
This commit is contained in:
2901
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_22_BWR-full-flash.hex
Normal file
2901
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_22_BWR-full-flash.hex
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_22_BWR-ota.bin
Normal file
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_22_BWR-ota.bin
Normal file
Binary file not shown.
2907
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_29_BWR-full-flash.hex
Normal file
2907
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_29_BWR-full-flash.hex
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_29_BWR-ota.bin
Normal file
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_29_BWR-ota.bin
Normal file
Binary file not shown.
2821
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_75_BWR-full-flash.hex
Normal file
2821
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_75_BWR-full-flash.hex
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_75_BWR-ota.bin
Normal file
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_75_BWR-ota.bin
Normal file
Binary file not shown.
719
ARM_Tag_FW/Newton_M3_nRF52811/OEPL_bootloader.hex
Normal file
719
ARM_Tag_FW/Newton_M3_nRF52811/OEPL_bootloader.hex
Normal file
@@ -0,0 +1,719 @@
|
||||
:1000000000600020B5090000DD090000DF090000E4
|
||||
:10001000E1090000E3090000E5090000000000001C
|
||||
:10002000000000000000000000000000E7090000E0
|
||||
:10003000E909000000000000EB090000ED090000E4
|
||||
:10004000EF090000EF090000C90E0000EF090000F1
|
||||
:10005000EF090000EF090000EF090000EF090000C0
|
||||
:10006000EF090000EF090000EF090000B5020000F1
|
||||
:10007000EF090000EF090000EF090000EF090000A0
|
||||
:10008000EF090000450F0000EF090000EF09000034
|
||||
:10009000EF090000EF090000EF090000EF09000080
|
||||
:1000A000EF090000EF090000EF090000EF09000070
|
||||
:1000B000EF090000EF090000000000000000000050
|
||||
:1000C000EF090000EF090000EF090000EF09000050
|
||||
:1000D000EF090000EF090000EF0900000000000038
|
||||
:1000E0000000000000000000000000000000000010
|
||||
:1000F0000000000000000000000000000000000000
|
||||
:1001000000000000000000000000000000000000EF
|
||||
:1001100000000000000000000000000000000000DF
|
||||
:1001200000000000000000000000000000000000CF
|
||||
:1001300000000000000000000000000000000000BF
|
||||
:1001400000000000000000000000000000000000AF
|
||||
:10015000000000000000000000000000000000009F
|
||||
:10016000000000000000000000000000000000008F
|
||||
:10017000000000000000000000000000000000007F
|
||||
:10018000000000000000000000000000000000006F
|
||||
:10019000000000000000000000000000000000005F
|
||||
:1001A000000000000000000000000000000000004F
|
||||
:1001B000000000000000000000000000000000003F
|
||||
:1001C000000000000000000000000000000000002F
|
||||
:1001D000000000000000000000000000000000001F
|
||||
:1001E000000000000000000000000000000000000F
|
||||
:1001F00000000000000000000000000000000000FF
|
||||
:1002000010B5054C237833B9044B13B10448AFF350
|
||||
:1002100000800123237010BD780000200000000042
|
||||
:100220003C2C000008B5034B1BB103490348AFF356
|
||||
:10023000008008BD000000007C0000203C2C000075
|
||||
:10024000154B002B08BF134B9D46A3F5803A0021A8
|
||||
:100250008B460F461348144A121A01F0B5FB0F4B98
|
||||
:10026000002B00D098470E4B002B00D09847002061
|
||||
:10027000002104000D000D48002802D00C48AFF307
|
||||
:10028000008001F075FB2000290000F071FE01F0F4
|
||||
:100290005BFB00BF000008000060002000000000C1
|
||||
:1002A0000000000078000020540200200000000040
|
||||
:1002B0000000000073B5134CD4F84061012E1FD12B
|
||||
:1002C0000023C4F84031104BD4F80455186801F0ED
|
||||
:1002D00093F90E4901F09CFA4FF08E4101F0E4F9D8
|
||||
:1002E00001F05CF80A4B002200F0FAFE01F0AEF8D3
|
||||
:1002F0002844C4F84005D4F840310193019B66605E
|
||||
:1003000002B070BD00B000400000002000007A4440
|
||||
:100310000000E03F70B506460825002433064CBFB8
|
||||
:10032000012100210F2000F07DFE0E20012176002A
|
||||
:1003300000F078FE64000D20F6B2E4B200F084FE16
|
||||
:1003400008B144F0010400210E20013D00F06AFED6
|
||||
:1003500015F0FF05E2D1204670BD10B5002104461E
|
||||
:100360000C2000F05FFE2046FFF7D4FF01210C2097
|
||||
:10037000BDE8104000F056BE70B506460C460C2095
|
||||
:100380000021154600F04EFE5A20FFF7C3FF002063
|
||||
:10039000FFF7C0FF300AFFF7BDFFF0B2FFF7BAFF6B
|
||||
:1003A0000020FFF7B7FF2544AC4205D00020FFF73F
|
||||
:1003B000B1FF04F8010BF7E701210C20BDE8704004
|
||||
:1003C00000F030BE0C2008B5002100F02BFE052007
|
||||
:1003D000FFF7A0FF0020FFF79DFFC307FAD401211C
|
||||
:1003E0000C2000F01FFE012008BD70B506460C462B
|
||||
:1003F0000C200021154600F015FE0320FFF78AFFB0
|
||||
:10040000C6F30740FFF786FFC6F30720FFF782FF1A
|
||||
:10041000F0B2FFF77FFF2544AC4205D00020FFF784
|
||||
:1004200079FF04F8010BF7E701210C20BDE87040CB
|
||||
:1004300000F0F8BD2DE9F341AB20FFF78EFF082255
|
||||
:1004400069460020FFF798FF9DF80030532B0FD12D
|
||||
:100450009DF80130462B0BD19DF80230442B07D17B
|
||||
:100460009DF80330502B03D19DF80730FF2B34D07B
|
||||
:100470006D4801F0CDFB00210C2000F0D3FD902051
|
||||
:10048000FFF748FF0020FFF745FF0020FFF742FF7E
|
||||
:100490000020FFF73FFF0020FFF73CFFC22809D1F3
|
||||
:1004A000624B202200201A70FFF734FF052803D08A
|
||||
:1004B00012280ED0002404E05D4B4FF480321A6005
|
||||
:1004C000012401210C2000F0ADFD204602B0BDE862
|
||||
:1004D000F081574B4FF40022F1E79DF805100129F8
|
||||
:1004E00006D09DF80420534801F01EFB0024ECE7E1
|
||||
:1004F0009DF80640FF2C08BFFE240025E8B201301D
|
||||
:1005000008226946C000FFF737FF9DF80030002B36
|
||||
:1005100040F083809DF80230012B7ED19DF803309E
|
||||
:10052000082B7AD9444CBDF8040024222146FFF759
|
||||
:1005300023FF237803F00302012A204604D03F481A
|
||||
:1005400001F066FB3E4845E05A0701D43D48F7E715
|
||||
:10055000A37813F0060F01D03B48F1E765786B1ED6
|
||||
:10056000DBB2FD2B01D93948EAE7304BE2791D7047
|
||||
:10057000130601D53648E3E77AB32D4B4FF400114B
|
||||
:1005800019602B4B196854104900E2B2002CFAD1C3
|
||||
:100590001960304A304992F800C091F800E01C27F9
|
||||
:1005A0002346A046C4196478661EF6B2FD2E24D8F0
|
||||
:1005B000C65D0F2E2ED0102E1CD00C2E1DD1A542A4
|
||||
:1005C0001BD0B8F1000F01D081F800E00BB182F828
|
||||
:1005D00000C0224801F01CFB88E7A2791AB1144B35
|
||||
:1005E0004FF40051CCE7627912B1114B2021C7E7DB
|
||||
:1005F0001B48A5E7A6464FF001080237242FD1D1AA
|
||||
:10060000B8F1000F01D081F800E00BB182F800C012
|
||||
:1006100001245AE7A4460123EFE70135EBB29C42DF
|
||||
:10062000BFF46CAF8EE700BF8C290000980000205B
|
||||
:1006300094000020A32900009B000020BF29000097
|
||||
:10064000602A0000CF290000E8290000FC290000F2
|
||||
:10065000182A0000990000209A000020452A000076
|
||||
:100660002D2A00002DE9F04105460F4616468EB3AF
|
||||
:100670005FFA85F8C8F58074A4B2B4424FF0060062
|
||||
:1006800028BF3446FFF769FE00210C2000F0CAFCA9
|
||||
:100690000220FFF73FFEC5F30740FFF73BFEC5F31F
|
||||
:1006A0000720FFF737FE4046FFF734FE07EB04084C
|
||||
:1006B000474504D017F8010BFFF72CFEF8E701219E
|
||||
:1006C0000C2000F0AFFCFFF77DFE20B12544341B69
|
||||
:1006D000A6B2CCE70120BDE8F08100001FB50C22D6
|
||||
:1006E00001A94FF44030FFF780FE074B029A9A426F
|
||||
:1006F00007D10398054BC31A5842584105B05DF81D
|
||||
:1007000004FB0020FAE700BFBAABBAABEFBEADDE28
|
||||
:100710001FB50C2201A94FF44030FFF766FE019887
|
||||
:1007200005B05DF804FB00001A4B022230B5C3F897
|
||||
:100730000425D3F80024002AFBD0C3F80805D3F819
|
||||
:100740000024002AFBD00022C3F80425114B1A46CE
|
||||
:10075000D3F80044002CFBD00124C3F80445D2F8A0
|
||||
:100760000034002BFBD00B4A0B1F01F6FC74401A1F
|
||||
:10077000114653F8045FC550D2F80054002DFBD049
|
||||
:10078000A342F6D10023C2F80435D1F80034002B7F
|
||||
:10079000FBD030BD00E001401FB504A9002341F8A3
|
||||
:1007A0000C3D0C224FF44030CDE90233FFF75AFFE5
|
||||
:1007B00005B05DF804FB08B50121102000F032FC03
|
||||
:1007C0000121112000F02EFC0121122000F02AFC52
|
||||
:1007D0000121102000F0FEFB0121112000F0FAFBA6
|
||||
:1007E0000121122000F0F6FB02211C2000F0F2FB98
|
||||
:1007F00002211D2000F0EEFB03210A2000F0EAFB9D
|
||||
:1008000003210B2000F0E6FB00210D2000F0E2FBAD
|
||||
:1008100001210E2000F0DEFB01210F2000F0DAFBA9
|
||||
:1008200001210C2000F0FEFB01210C20BDE8084056
|
||||
:1008300000F0D0BB80B400AF72B6074A4FF48043DB
|
||||
:1008400093601B6883F3088844F204031B6862B654
|
||||
:10085000BD4680BC184700BF00ED00E010B5002188
|
||||
:10086000044600F0DFFB032000F05EFB2046012180
|
||||
:10087000BDE8104000F0D6BBF8B5FFF749FF0F24E4
|
||||
:1008800005461220FFF7EAFF013C462000F04CFB32
|
||||
:1008900014F0FF04F5D1A5F50053B3F5283F0BD9AB
|
||||
:1008A00014241020FFF7DAFF013C642000F03CFB29
|
||||
:1008B00014F0FF04F5D1F8BD29461848184F01F08F
|
||||
:1008C00033F94FF4805001F077F806464FF4805228
|
||||
:1008D00020463146FFF789FD04F580403146FFF799
|
||||
:1008E00023FF2146384601F01FF904F580541220F9
|
||||
:1008F000FFF7B4FFA542E9D80A4801F089F90021C1
|
||||
:10090000112000F08FFB4FF4FA7000F00DFB012175
|
||||
:100910001120BDE8F84000F085BB00BF8F2A000021
|
||||
:10092000B32A0000C92A00007047000008B54FF440
|
||||
:10093000E1310E4800F084F94FF4967000F0F4FABB
|
||||
:100940000B4801F065F9FFF736FFFFF773FDFFF77E
|
||||
:10095000C5FE38B1FFF790FFFFF71EFFBDE8084066
|
||||
:10096000FFF768BF1120FFF779FFF7E7DC010020F0
|
||||
:10097000E22A000010B50348144600F005F82046AE
|
||||
:1009800010BD00BFDC0100202DE9F04106460D46F8
|
||||
:1009900001EB02080C464445A4EB050707D0336879
|
||||
:1009A00014F8011B1B68304698470028F3D13846DD
|
||||
:1009B000BDE8F0810649074A074B9B1A03DD043B5B
|
||||
:1009C000C858D050FBDC00F039F8FFF739FC0000C4
|
||||
:1009D000482C00000000002078000020FEE7FEE721
|
||||
:1009E000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE7DF
|
||||
:1009F000074B1B78062B09D1064B1B68C3F3031367
|
||||
:100A0000033B032B02D8044AD05C70470020704798
|
||||
:100A1000E00F00F0E80F00F0F02A0000054B186826
|
||||
:100A2000421C04BF044B187820F00800831F584272
|
||||
:100A30005841704730010010E00F00F008B56C4BD2
|
||||
:100A40001B685A1C04BF6B4B1B78062B05D16A4BE5
|
||||
:100A50006A4A1B68C3F304231360FFF7C9FF10B190
|
||||
:100A6000674B684A1A60FFF7D9FF28B1664B674A9F
|
||||
:100A70001B68C3F342331360FFF7BAFF20B1644A27
|
||||
:100A8000D36823F08073D360FFF7C8FF40B14FF005
|
||||
:100A900080430022C3F80C21C3F81021C3F8382585
|
||||
:100AA000FFF7A6FF10B15B4B03221A60FFF7A0FF10
|
||||
:100AB00040B1594B05221A6001229A6700229A60C0
|
||||
:100AC0003F225A604A4B1A68501C0BBF494B534B8C
|
||||
:100AD0001A781B6802BF08331B68C3F30313062A86
|
||||
:100AE0004ED1033B032B03D84D4AD35C002B49D096
|
||||
:100AF0004FF080524B4BD2F80414C3F82015D2F8B3
|
||||
:100B00000814C3F82415D2F80C14C3F82815D2F829
|
||||
:100B10001014C3F82C15D2F81414C3F83015D2F8F9
|
||||
:100B20001814C3F83415D2F81C14C3F84015D2F8C1
|
||||
:100B30002014C3F84415D2F82414C3F84815D2F889
|
||||
:100B40002814C3F84C15D2F82C14C3F85015D2F859
|
||||
:100B50003014C3F85415D2F83414C3F86015D2F821
|
||||
:100B60003814C3F86415D2F83C14C3F86815D2F8E9
|
||||
:100B70004014C3F86C15D2F84424C3F8702501E082
|
||||
:100B80000E2AB5D01A4B1B68591C04BF194B1B7891
|
||||
:100B9000062B05D1244B254A1B6803F04F03136035
|
||||
:100BA000FFF73CFF48B14FF08043D3F80024D20751
|
||||
:100BB00044BF6FF00102C3F800240D4B1B68062BE5
|
||||
:100BC00009D1164B1B68033B022B81BF184A1368DF
|
||||
:100BD00043F480631360064B1B680E2B01BF134A5E
|
||||
:100BE000136843F00F031360124B134A1A6008BDD9
|
||||
:100BF00030010010E00F00F02403001040350140E8
|
||||
:100C000074C007400DF0ADBA440200103C0500402E
|
||||
:100C1000F0ED00E0A0050040105600403401001047
|
||||
:100C2000EC2A000000C0004058020010E40E004012
|
||||
:100C30003C170040040000200090D00301207047C2
|
||||
:100C400003681322DB69184770470369C3F81C1552
|
||||
:100C50000369D3F81C21002AFBD00022C3F81C2111
|
||||
:100C60000120704710B490F95C30144C59090122EE
|
||||
:100C7000203103F01F0302FA03F344F82130036923
|
||||
:100C800010BC0421C3F8081303695A600369DA60D1
|
||||
:100C900003690022C3F8002502694FF0FF33C2F850
|
||||
:100CA0000C350269C2F814350269C2F808350269C8
|
||||
:100CB0001430C2F8103500F0EDB900BF00E100E0DB
|
||||
:100CC000143000F0F9B9143000F0FCB9143000F021
|
||||
:100CD000E5B90000036990F85E2010B5C3F80C2553
|
||||
:100CE000036990F85D20C3F8142590F8612003692A
|
||||
:100CF000012A01BF90F85F40C3F81045036990F8DE
|
||||
:100D0000604006BFC3F8084503690022B1F5966F3D
|
||||
:100D1000C3F86C2569D9B1F5166F69D9B1F5965F3D
|
||||
:100D200069D9B1F5165F68D9B1F5615F67D9B1F5D9
|
||||
:100D3000964F66D9B1F5E14F65D9B1F5164F64D933
|
||||
:100D4000B1F5614F64D9B1F5963F64D9B1F5E13F92
|
||||
:100D500063D9B1F5613F63D9364B994263D9B1F597
|
||||
:100D6000E12F63D9B1F5612F94BF4FF070634FF05D
|
||||
:100D700080530269C2F8243503690422C3F80025B0
|
||||
:100D800001690023C1F808310169C1F81C3101690A
|
||||
:100D900001230B6001698B600169C1F8042390F99C
|
||||
:100DA0005C20510902F01F0293406031224A42F850
|
||||
:100DB000213090F95C30002BBDBF03F00F0302F629
|
||||
:100DC000FC32D2189B18B5BF60236022137683F8DB
|
||||
:100DD000002390F95C300122590903F01F0302FA45
|
||||
:100DE00003F3154A42F8213010BD4FF49E23C0E7AB
|
||||
:100DF0004FF41D23BDE7114BBBE7114BB9E7114B76
|
||||
:100E0000B7E7114BB5E7114BB3E74FF41D03B0E75C
|
||||
:100E10004FF46B03ADE70E4BABE74FF0EB73A8E776
|
||||
:100E20004FF06C73A5E74FF08063A2E74FF0E863E3
|
||||
:100E30009FE700BF90D0030000E100E000B0130086
|
||||
:100E40000050270000F03A0000A04E0000C07500DE
|
||||
:100E500000903A012DE9F0411E4600254FF47A73C7
|
||||
:100E6000C0E901530D4B044640F8143B1746884631
|
||||
:100E700000F0FCF80A4AC4F8108084F85C7052F85C
|
||||
:100E8000263084F85D309DF8183052F8233084F80D
|
||||
:100E90005E3084F861502046BDE8F081FC2A0000F5
|
||||
:100EA000242B000010B50369D3F8082104464AB189
|
||||
:100EB000D3F818151430C9B200F0E1F82369002204
|
||||
:100EC000C3F8082110BD00000148FFF7EBBF00BFC9
|
||||
:100ED000DC01002007B51923009302221A230349DD
|
||||
:100EE0000348FFF7B7FF03B05DF804FB00200040A4
|
||||
:100EF000DC0100200A4B19680A4B30B5D3F8040511
|
||||
:100F00000C060D0A44EA00024FF47A712B46A2FB4C
|
||||
:100F1000014501FB0355E00B40EA454030BD00BFF1
|
||||
:100F2000400200200010014038B5044648B1FFF7E8
|
||||
:100F3000E1FF054600F01AF8FFF7DCFF401BA04276
|
||||
:100F4000F8D338BD074B0022C3F8042182B0D3F890
|
||||
:100F50000431054A0193019B13680133DBB213602E
|
||||
:100F600002B07047001001404002002070477047F7
|
||||
:100F700008B500F011F8FFF7FAFF0120FFF7D4FFE2
|
||||
:100F8000FFF7D4FC034CFFF7CFFC002CFBD0AFF3F2
|
||||
:100F90000080F8E7000000000D4BE02283F81123E9
|
||||
:100FA0004FF40032C3F880211A604FF080430021D3
|
||||
:100FB0000122C3F818159A6003F58833C3F80815A1
|
||||
:100FC0000221C3F80413C3F844131A60704700BF2A
|
||||
:100FD00000E100E01F280FD8114B53F820300329FF
|
||||
:100FE0000AD8DFE801F002160A1003F5E0734FF0AB
|
||||
:100FF000A042002142F82310704703F5E0734FF040
|
||||
:10100000A0420C21F6E703F5E0734FF0A042042163
|
||||
:10101000F0E703F5E0734FF0A0420321EAE700BFD9
|
||||
:10102000242B00001F280CD8064B53F82020012346
|
||||
:1010300093404FF0A04211B9C2F80C357047C2F886
|
||||
:1010400008357047242B00001F289FBF4FF0A04396
|
||||
:10105000054AD3F8103552F820009ABF23FA00F061
|
||||
:1010600000F0010000207047242B000008B540224A
|
||||
:10107000002100F0A9FC0022C0E9102208BD026C8A
|
||||
:1010800010B5531C446C03F03F039C421CBF8154B9
|
||||
:10109000036410BD0023C0E910337047D0E910236A
|
||||
:1010A00093421FBFC25C013303F03F03436414BF8C
|
||||
:1010B00010464FF0FF307047D0E91030181A48BF83
|
||||
:1010C00040307047D0E91023934214BFC05C4FF00A
|
||||
:1010D000FF30704781F0004102E000BF83F0004321
|
||||
:1010E00030B54FEA41044FEA430594EA050F08BFC3
|
||||
:1010F00090EA020F1FBF54EA000C55EA020C7FEA87
|
||||
:10110000645C7FEA655C00F0E2804FEA5454D4EB03
|
||||
:101110005555B8BF6D420CDD2C4480EA020281EACD
|
||||
:10112000030382EA000083EA010180EA020281EA05
|
||||
:101130000303362D88BF30BD11F0004F4FEA013157
|
||||
:101140004FF4801C4CEA113102D0404261EB410166
|
||||
:1011500013F0004F4FEA03334CEA133302D05242EC
|
||||
:1011600063EB430394EA050F00F0A780A4F10104A8
|
||||
:10117000D5F1200E0DDB02FA0EFC22FA05F28018E2
|
||||
:1011800041F1000103FA0EF2801843FA05F35941C8
|
||||
:101190000EE0A5F120050EF1200E012A03FA0EFC47
|
||||
:1011A00028BF4CF0020C43FA05F3C01851EBE37171
|
||||
:1011B00001F0004507D54FF0000EDCF1000C7EEB8E
|
||||
:1011C00000006EEB0101B1F5801F1BD3B1F5001FCC
|
||||
:1011D0000CD349085FEA30004FEA3C0C04F10104EB
|
||||
:1011E0004FEA445212F5800F80F09A80BCF1004F14
|
||||
:1011F00008BF5FEA500C50F1000041EB045141EA96
|
||||
:10120000050130BD5FEA4C0C404141EB010111F496
|
||||
:10121000801FA4F10104E9D191F0000F04BF014641
|
||||
:101220000020B1FA81F308BF2033A3F10B03B3F11F
|
||||
:1012300020020CDA0C3208DD02F1140CC2F10C02AF
|
||||
:1012400001FA0CF021FA02F10CE002F11402D8BF0D
|
||||
:10125000C2F1200C01FA02F120FA0CFCDCBF41EAD9
|
||||
:101260000C019040E41AA2BF01EB0451294330BDA8
|
||||
:101270006FEA04041F3C1CDA0C340EDC04F1140485
|
||||
:10128000C4F1200220FA04F001FA02F340EA03005C
|
||||
:1012900021FA04F345EA030130BDC4F10C04C4F1A2
|
||||
:1012A000200220FA02F001FA04F340EA0300294682
|
||||
:1012B00030BD21FA04F0294630BD94F0000F83F4CC
|
||||
:1012C000801306BF81F480110134013D4EE77FEAAF
|
||||
:1012D000645C18BF7FEA655C29D094EA050F08BFFB
|
||||
:1012E00090EA020F05D054EA000C04BF19461046DC
|
||||
:1012F00030BD91EA030F1EBF0021002030BD5FEA20
|
||||
:10130000545C05D14000494128BF41F0004130BD47
|
||||
:1013100014F580043CBF01F5801130BD01F000459B
|
||||
:1013200045F0FE4141F470014FF0000030BD7FEA0E
|
||||
:10133000645C1ABF194610467FEA655C1CBF0B4609
|
||||
:10134000024650EA013406BF52EA033591EA030F20
|
||||
:1013500041F4002130BD00BF90F0000F04BF002118
|
||||
:10136000704730B54FF4806404F132044FF000054B
|
||||
:101370004FF0000150E700BF90F0000F04BF0021C4
|
||||
:10138000704730B54FF4806404F1320410F000452A
|
||||
:1013900048BF40424FF000013EE700BF42004FEA25
|
||||
:1013A000E2014FEA31014FEA02701FBF12F07F43A2
|
||||
:1013B00093F07F4F81F06051704732F07F4208BF59
|
||||
:1013C000704793F07F4F04BF41F40021704730B560
|
||||
:1013D0004FF4607401F0004521F000411CE700BFAC
|
||||
:1013E00050EA010208BF704730B54FF000050AE02F
|
||||
:1013F00050EA010208BF704730B511F0004502D530
|
||||
:10140000404261EB41014FF4806404F132045FEA31
|
||||
:10141000915C3FF4D8AE4FF003025FEADC0C18BFDA
|
||||
:1014200003325FEADC0C18BF033202EBDC02C2F1CC
|
||||
:10143000200300FA03FC20FA02F001FA03FE40EA5E
|
||||
:101440000E0021FA02F11444BDE600BF4A0011D299
|
||||
:1014500012F5001211D20DD56FF47873B3EB62520E
|
||||
:101460000ED44FEAC12343F0004343EA505323FA1A
|
||||
:1014700002F070474FF00000704750EA013002D18F
|
||||
:101480004FF0FF3070474FF00000704780F0004091
|
||||
:1014900002E000BF81F0004142001FBF5FEA41034C
|
||||
:1014A00092EA030F7FEA226C7FEA236C6AD04FEA4C
|
||||
:1014B0001262D2EB1363C1BFD21841404840414091
|
||||
:1014C000B8BF5B42192B88BF704710F0004F40F443
|
||||
:1014D000000020F07F4018BF404211F0004F41F45F
|
||||
:1014E000000121F07F4118BF494292EA030F3FD02B
|
||||
:1014F000A2F1010241FA03FC10EB0C00C3F120033E
|
||||
:1015000001FA03F100F0004302D5494260EB4000CC
|
||||
:10151000B0F5000F13D3B0F1807F06D340084FEA37
|
||||
:10152000310102F10102FE2A51D2B1F1004F40EB2C
|
||||
:10153000C25008BF20F0010040EA03007047490094
|
||||
:1015400040EB000010F4000FA2F10102EDD1B0FA5F
|
||||
:1015500080FCACF1080CB2EB0C0200FA0CF0AABF54
|
||||
:1015600000EBC25052421843BCBFD04018437047F2
|
||||
:1015700092F0000F81F4000106BF80F400000132F8
|
||||
:10158000013BB5E74FEA41037FEA226C18BF7FEACF
|
||||
:10159000236C21D092EA030F04D092F0000F08BF11
|
||||
:1015A0000846704790EA010F1CBF0020704712F0F8
|
||||
:1015B0007F4F04D1400028BF40F00040704712F137
|
||||
:1015C00000723CBF00F50000704700F0004343F09C
|
||||
:1015D000FE4040F4000070477FEA226216BF0846D2
|
||||
:1015E0007FEA23630146420206BF5FEA412390EA95
|
||||
:1015F000010F40F4800070474FF0000304E000BF8B
|
||||
:1016000010F0004348BF40425FEA000C08BF70473B
|
||||
:1016100043F0964301464FF000001CE050EA0102FF
|
||||
:1016200008BF70474FF000030AE000BF50EA010214
|
||||
:1016300008BF704711F0004302D5404261EB410101
|
||||
:101640005FEA010C02BF84460146002043F0B64326
|
||||
:1016500008BFA3F18053A3F50003BCFA8CF2083A4B
|
||||
:10166000A3EBC25310DB01FA02FC634400FA02FC54
|
||||
:10167000C2F12002BCF1004F20FA02F243EB02005B
|
||||
:1016800008BF20F00100704702F1200201FA02FCBD
|
||||
:10169000C2F1200250EA4C0021FA02F243EB0200B0
|
||||
:1016A00008BF20EADC7070474FF0FF0C1CEAD052F4
|
||||
:1016B0001EBF1CEAD15392EA0C0F93EA0C0F6FD0B5
|
||||
:1016C0001A4480EA010C400218BF5FEA41211ED093
|
||||
:1016D0004FF0006343EA501043EA5111A0FB01317F
|
||||
:1016E0000CF00040B1F5000F3EBF490041EAD37154
|
||||
:1016F0005B0040EA010062F17F02FD2A1DD8B3F1D0
|
||||
:10170000004F40EBC25008BF20F00100704790F03E
|
||||
:10171000000F0CF0004C08BF49024CEA502040EA90
|
||||
:1017200051207F3AC2BFD2F1FF0340EAC250704756
|
||||
:1017300040F400004FF00003013A5DDC12F1190F94
|
||||
:10174000DCBF00F000407047C2F10002410021FA06
|
||||
:1017500002F1C2F1200200FA02FC5FEA310040F11E
|
||||
:10176000000053EA4C0308BF20EADC70704792F097
|
||||
:10177000000F00F0004C02BF400010F4000F013ACF
|
||||
:10178000F9D040EA0C0093F0000F01F0004C02BFCA
|
||||
:10179000490011F4000F013BF9D041EA0C018FE739
|
||||
:1017A0000CEAD15392EA0C0F18BF93EA0C0F0AD03F
|
||||
:1017B00030F0004C18BF31F0004CD8D180EA010065
|
||||
:1017C00000F00040704790F0000F17BF90F0004FFE
|
||||
:1017D000084691F0000F91F0004F14D092EA0C0FE0
|
||||
:1017E00001D142020FD193EA0C0F03D14B0218BF73
|
||||
:1017F000084608D180EA010000F0004040F0FE40B9
|
||||
:1018000040F40000704740F0FE4040F44000704754
|
||||
:101810004FF0FF0C1CEAD0521EBF1CEAD15392EAD3
|
||||
:101820000C0F93EA0C0F69D0A2EB030280EA010CC3
|
||||
:1018300049024FEA402037D04FF0805343EA11115C
|
||||
:1018400043EA10130CF000408B4238BF5B0042F1BA
|
||||
:101850007D024FF4000C8B4224BF5B1A40EA0C005F
|
||||
:10186000B3EB510F24BFA3EB510340EA5C00B3EB91
|
||||
:10187000910F24BFA3EB910340EA9C00B3EBD10F7F
|
||||
:1018800024BFA3EBD10340EADC001B0118BF5FEAD1
|
||||
:101890001C1CE0D1FD2A3FF650AF8B4240EBC250FA
|
||||
:1018A00008BF20F0010070470CF0004C4CEA5020BB
|
||||
:1018B0007F32C2BFD2F1FF0340EAC250704740F40A
|
||||
:1018C00000004FF00003013A37E792F0000F00F0FC
|
||||
:1018D000004C02BF400010F4000F013AF9D040EA7A
|
||||
:1018E0000C0093F0000F01F0004C02BF490011F40E
|
||||
:1018F000000F013BF9D041EA0C0195E70CEAD15306
|
||||
:1019000092EA0C0F08D142027FF47DAF93EA0C0FEC
|
||||
:101910007FF470AF084676E793EA0C0F04D14B02D0
|
||||
:101920003FF44CAF08466EE730F0004C18BF31F082
|
||||
:10193000004CCAD130F000427FF45CAF31F000437C
|
||||
:101940007FF43CAF5FE700BF08B5074B044613B117
|
||||
:101950000021AFF30080054B1868836A03B19847F4
|
||||
:10196000204601F005F800BF00000000A42B000095
|
||||
:1019700070B50D4E0D4CA41BA4100025A54209D135
|
||||
:101980000B4E0C4C00F0F6FFA41BA4100025A54242
|
||||
:1019900005D170BD56F8253098470135EEE756F869
|
||||
:1019A000253098470135F2E76C0000206C000020DC
|
||||
:1019B0006C00002074000020024B0146186800F003
|
||||
:1019C00059B800BF0800002002440346934200D1EA
|
||||
:1019D000704703F8011BF9E738B50546002945D0E3
|
||||
:1019E00051F8043C0C1F002BB8BFE41800F0C6FBF4
|
||||
:1019F0001F4A1368104633B9636014602846BDE877
|
||||
:101A0000384000F0BCBBA3420CD921686218934255
|
||||
:101A100004BF1A685B68636004BF521822600460E8
|
||||
:101A2000ECE713465A680AB1A242FAD91968581865
|
||||
:101A3000A0420BD120680144581882421960DDD1C0
|
||||
:101A4000106852685A6001441960D7E702D90C2324
|
||||
:101A50002B60D3E7206821188A4204BF11685268BE
|
||||
:101A6000626004BF091821605C60C7E738BD00BF31
|
||||
:101A70004402002070B5CD1C25F0030508350C2D5F
|
||||
:101A800038BF0C25002D064601DBA94203D90C23E3
|
||||
:101A90003360002070BD00F071FB214A14682146BC
|
||||
:101AA00091B9204C23681BB9304600F0B9F820608A
|
||||
:101AB0002946304600F0B4F8431C24D10C2333608F
|
||||
:101AC000304600F05CFBE4E70B685B1B18D40B2B83
|
||||
:101AD0000FD90B60CD50CC18304600F050FB04F10C
|
||||
:101AE0000B00231D20F00700C31AD3D05A42E25046
|
||||
:101AF000D0E78C424B6816BF636013600C46EBE77F
|
||||
:101B00000C464968CCE7C41C24F00304A04205D06D
|
||||
:101B1000211A304600F084F80130CFD02560DBE791
|
||||
:101B200044020020480200200FB40A4B13B51C6881
|
||||
:101B300024B1A36913B9204600F032FA05AB049A28
|
||||
:101B4000A1680193204600F043FB02B0BDE81040BD
|
||||
:101B500004B070470800002070B50E46054618B165
|
||||
:101B600083690BB900F01CFAAB69AC6813B928465D
|
||||
:101B700000F016FA234B9C4217D16C68A3891B070F
|
||||
:101B80001DD52369DBB1013EA36816F8011F013B97
|
||||
:101B9000A360E9B9002B2EDA22460A21284600F07C
|
||||
:101BA0004FF8013011D00A2011E0174B9C4201D1AF
|
||||
:101BB000AC68E3E7154B9C4208BFEC68DEE72146C2
|
||||
:101BC000284600F08FF80028DDD04FF0FF3070BDC0
|
||||
:101BD000002B04DAA2699A4206DC0A2904D02368A1
|
||||
:101BE0005A1C22601970CFE72246284600F028F8D8
|
||||
:101BF0000130C9D1E9E723680A205A1C2260187015
|
||||
:101C0000E5E700BFC82B0000E82B0000A82B000070
|
||||
:101C1000024B01461868FFF79FBF00BF0800002075
|
||||
:101C200038B5064C002305460846236000F092FEB6
|
||||
:101C3000431C02D1236803B12B6038BD5002002041
|
||||
:101C4000F8B50E461446054618B183690BB900F085
|
||||
:101C5000A7F9214B9C422AD16C68A369A360A38990
|
||||
:101C60001A072ED5236963B323692068C01A6369F4
|
||||
:101C7000F6B28342374604DC2146284600F026F9B6
|
||||
:101C800028BBA368013BA36023685A1C22601E7016
|
||||
:101C900063690130834204D0A389DB0719D50A2E7A
|
||||
:101CA00017D12146284600F011F990B10FE00B4BF7
|
||||
:101CB0009C4201D1AC68D0E7094B9C4208BFEC685C
|
||||
:101CC000CBE72146284600F00DF80028CCD04FF095
|
||||
:101CD000FF373846F8BD00BFC82B0000E82B0000D6
|
||||
:101CE000A82B0000324B70B51D6806460C4625B186
|
||||
:101CF000AB6913B9284600F053F92E4B9C420FD123
|
||||
:101D00006C68B4F90C309AB215072CD4D00611D4F3
|
||||
:101D10000922326043F04003A3814FF0FF303EE0E0
|
||||
:101D2000254B9C4201D1AC68EBE7244B9C4208BF99
|
||||
:101D3000EC68E6E7510712D5616B41B104F1440349
|
||||
:101D4000994202D03046FFF747FE00236363A38920
|
||||
:101D500023F02403A3810023636023692360A38904
|
||||
:101D600043F00803A38123694BB9A38903F42073CB
|
||||
:101D7000B3F5007F03D02146304600F0BFF9A289B9
|
||||
:101D800012F001030CD00023A36063695B42A361DE
|
||||
:101D9000236953B9B4F90C3013F08000BAD170BD87
|
||||
:101DA000920758BF6369A360F2E70020F7E700BF1E
|
||||
:101DB00008000020C82B0000E82B0000A82B000022
|
||||
:101DC0008A892DE9F041054610070C4658D44B6826
|
||||
:101DD000002B05DC0B6C002B02DC0020BDE8F08141
|
||||
:101DE000E66A002EF9D0002312F480522F68216A8F
|
||||
:101DF0002B6032D0606DA3895A0705D56368C01A7D
|
||||
:101E0000636B0BB1236CC01A00230246E66A216A99
|
||||
:101E10002846B047431CA38906D129681D2948D804
|
||||
:101E2000294ACA40D60744D500226260D9042269F3
|
||||
:101E3000226004D5421C01D12B6803B96065616B37
|
||||
:101E40002F600029C9D004F14403994202D02846EA
|
||||
:101E5000FFF7C2FD00206063C0E701232846B047BA
|
||||
:101E6000411CC8D12B68002BC5D01D2B01D0162BCF
|
||||
:101E700001D12F60B1E7A38943F04003A381ADE70F
|
||||
:101E80000F69002FA9D093070E6808BF4B690F6038
|
||||
:101E900018BF0023A6EB07088B60B8F1000F9CDD8C
|
||||
:101EA00043463A46216AA66A2846B047002806DC1F
|
||||
:101EB000A38943F04003A3814FF0FF308EE707442E
|
||||
:101EC000A8EB0008E9E700BF0100402038B50B6926
|
||||
:101ED00005460C46DBB118B183690BB900F060F818
|
||||
:101EE0000C4B9C4209D16C68B4F90C307BB1214693
|
||||
:101EF0002846BDE83840FFF763BF074B9C4201D13D
|
||||
:101F0000AC68F1E7054B9C4208BFEC68ECE70020A9
|
||||
:101F100038BD00BFC82B0000E82B0000A82B000034
|
||||
:101F2000002310B50446C0E9003383608181436615
|
||||
:101F3000C281C0E904338361194608225C30FFF78F
|
||||
:101F400043FD054B6362054BA362054BE362054B02
|
||||
:101F50002462236310BD00BF092700002B27000067
|
||||
:101F60006327000087270000014900F085B800BF03
|
||||
:101F7000CD1E000070B54A1E682555430E4605F17A
|
||||
:101F80007401FFF777FD044640B10021C0E9001657
|
||||
:101F90000C30A06005F16802FFF716FD204670BD09
|
||||
:101FA000836910B5044633BBC0E912330365124B95
|
||||
:101FB000124A1B688262984204BF0123836100F0C9
|
||||
:101FC0001FF86060204600F01BF8A060204600F07B
|
||||
:101FD00017F80022E06004216068FFF7A1FF0122EA
|
||||
:101FE0000921A068FFF79CFF02221221E068FFF799
|
||||
:101FF00097FF0123A36110BDA42B0000691F0000FF
|
||||
:10200000F8B51B4B1E68B369074613B93046FFF796
|
||||
:10201000C7FF4836D6E90134013B03D5336833B1F5
|
||||
:102020003668F7E7B4F90C506DB16834F4E7042171
|
||||
:102030003846FFF79FFF30600028F1D10C233B604A
|
||||
:1020400004462046F8BD0B4B6566C4E90055A56003
|
||||
:10205000C4E90335C4E905550822294604F15C00AA
|
||||
:10206000FFF7B2FCC4E90D55C4E91255E9E700BF1A
|
||||
:10207000A42B00000100FFFF2DE9F84380468946AC
|
||||
:1020800000F14804002614B93046BDE8F883D4E9CD
|
||||
:102090000175013F01D52468F5E7AB89012B07D90C
|
||||
:1020A000B5F90E30013303D029464046C8470643F0
|
||||
:1020B0006835EEE770B50E46B1F90E10002996B0FE
|
||||
:1020C00014461D4607DA00232B60B3891A0610D484
|
||||
:1020D0004FF480630EE06A4600F07CFB0028F2DBE0
|
||||
:1020E000019A02F47042A2F500535A425A412A6002
|
||||
:1020F000EEE740230020236016B070BD8B8973B5D6
|
||||
:102100009D0706460C4607D504F14703236023616B
|
||||
:102110000123636102B070BD01AB6A46FFF7CAFFDD
|
||||
:10212000009905463046FFF7A5FC48B9B4F90C30D4
|
||||
:102130009A05EFD423F0030343F00203A381E3E7FE
|
||||
:102140000D4BB362A389206043F08003A381009B01
|
||||
:102150006361019B20615BB1B4F90E10304600F061
|
||||
:102160004BFB28B1A38923F0030343F00103A381B0
|
||||
:10217000A3891D43A581CDE7691F00007047704703
|
||||
:102180009368013B002B10B4936007DA9469A34273
|
||||
:1021900001DB0A2902D110BCFFF752BD1368581C9D
|
||||
:1021A00010601970084610BC7047F8B506460F4617
|
||||
:1021B0001446D518AC4201D1002007E03A4614F885
|
||||
:1021C000011B3046FFF7DCFF431CF3D1F8BD0000D4
|
||||
:1021D0002DE9F04F9DB00C4617460393064618B103
|
||||
:1021E00083690BB9FFF7DCFE7B4B9C4257D17468C7
|
||||
:1021F000A38918075DD52369002B5AD000230993C2
|
||||
:1022000020238DF8293030238DF82A304FF0010B30
|
||||
:10221000B846454615F8013B0BB1252B54D1B8EB18
|
||||
:10222000070A0BD053463A4621463046FFF7BDFF1A
|
||||
:10223000013000F0C280099B5344099398F80030A4
|
||||
:10224000002B00F0BA8000234FF0FF32CDE90523C8
|
||||
:10225000049307938DF853301A93A846052218F873
|
||||
:10226000011B5E4800F0ECFA049B78BBD90644BF22
|
||||
:1022700020228DF853201A0744BF2B228DF85320BB
|
||||
:102280002A782A2A2AD0079AA84600200A254146F9
|
||||
:1022900011F8013B303B092B69D960B324E0504B66
|
||||
:1022A0009C4201D1B468A3E74E4B9C4208BFF4683E
|
||||
:1022B0009EE721463046FFF715FD00289ED04FF0DF
|
||||
:1022C000FF301DB0BDE8F08FA846A2E7434A801A50
|
||||
:1022D0000BFA00F0184304904546BEE7039A111D1F
|
||||
:1022E00012680391002A01DB079204E0524243F096
|
||||
:1022F00002030792049398F800302E2B0ED198F821
|
||||
:1023000001302A2B38D1039B1A1D1B680392002B26
|
||||
:10231000B8BF4FF0FF3308F102080593324D98F82B
|
||||
:1023200000100322284600F08BFA40B14023401BE6
|
||||
:1023300003FA00F0049B034308F10108049398F8A2
|
||||
:1023400000102A488DF82810062208F1010700F035
|
||||
:1023500077FA002837D0264B1BBB039B073323F0AB
|
||||
:10236000070308330393099B4B44099350E705FB8C
|
||||
:102370000232012088468AE7002308F1010805930C
|
||||
:1023800019460A25404610F8012B303A092A03D98C
|
||||
:10239000002BC3D00591C1E705FB01210123804635
|
||||
:1023A000F0E703AB00932246124B04A93046AFF38B
|
||||
:1023B0000080B0F1FF3F8146D5D1A3895B063FF590
|
||||
:1023C0007EAF09987DE703AB00932246094B04A931
|
||||
:1023D000304600F087F8ECE7C82B0000082C00001E
|
||||
:1023E000E82B0000A82B00000E2C0000122C00008F
|
||||
:1023F00000000000AB2100002DE9F04791461F4688
|
||||
:102400008A680B69DDF820809342B8BF1346C9F88B
|
||||
:10241000003091F8432006460C4612B10133C9F84A
|
||||
:1024200000302368990642BFD9F800300233C9F85A
|
||||
:102430000030256815F0060507D104F1190AE36894
|
||||
:10244000D9F800209B1AAB4228DC94F8433022686C
|
||||
:10245000003318BF012392062DD404F143023946FC
|
||||
:102460003046C047013020D02368E568D9F8002005
|
||||
:1024700003F00603042B08BFAD1AA36822690CBF42
|
||||
:1024800025EAE57500259342C4BF9B1AED184FF06D
|
||||
:1024900000091A344D451AD1002008E001235246A4
|
||||
:1024A00039463046C047013003D14FF0FF30BDE818
|
||||
:1024B000F0870135C3E7E1185A1C302081F843004A
|
||||
:1024C000224494F8451082F843100233C5E70123F3
|
||||
:1024D000224639463046C0470130E6D009F10109AD
|
||||
:1024E000D8E700002DE9F04301F1430C0C46097ECA
|
||||
:1024F00085B06E291746064698460C9A00F0B380C0
|
||||
:1025000022D8632936D00AD8002900F0B98058298A
|
||||
:1025100000F0838004F1420584F8421032E064291F
|
||||
:1025200001D06929F6D120681368050603F104017A
|
||||
:102530002AD51B681160002B03DA2D225B4284F838
|
||||
:1025400043206F480A2239E0732900F09D8008D8A3
|
||||
:102550006F2920D07029DDD1236843F02003236048
|
||||
:1025600003E0752917D07829D4D1782384F8453031
|
||||
:10257000644855E01368191D1B68116004F1420599
|
||||
:1025800084F8423001238CE01B68116010F0400F8A
|
||||
:1025900018BF1BB2CFE713682568181D1060280606
|
||||
:1025A00001D51B6802E06806FBD51B8854486F29DB
|
||||
:1025B00014BF0A220822002184F843106568A56030
|
||||
:1025C000002DC0F29580216821F004012160002BCC
|
||||
:1025D0003DD1002D40F08E806546082A0BD123683E
|
||||
:1025E000DB0708D5236962689A42DEBF302305F80D
|
||||
:1025F000013C05F1FF35ACEB05032361CDF800800C
|
||||
:102600003B4603AA21463046FFF7F6FE01304DD186
|
||||
:102610004FF0FF3005B0BDE8F083394884F845102D
|
||||
:10262000136821681D1D1B6815600A060BD5CA07B3
|
||||
:1026300044BF41F0200121601BB9226822F0200232
|
||||
:1026400022601022B7E74D0648BF9BB2EFE7654610
|
||||
:10265000B3FBF2F102FB1133C35C05F8013D0B46FD
|
||||
:102660000029F5D1B9E7136825686169181D106064
|
||||
:1026700028061B6801D5196002E06A06FBD519809F
|
||||
:10268000002323616546B9E71368191D11601D68B1
|
||||
:1026900062680021284600F0D3F808B1401B606052
|
||||
:1026A00063682361002384F84330A7E723692A463F
|
||||
:1026B00039463046C0470130AAD023689B0713D45F
|
||||
:1026C000E068039B9842B8BF1846A3E701234A4637
|
||||
:1026D00039463046C04701309AD00135E368039A45
|
||||
:1026E0009B1AAB42F2DCEBE7002504F11909F5E790
|
||||
:1026F000002BACD1037884F8423004F142056CE73A
|
||||
:10270000192C00002A2C000010B50C46B1F90E104F
|
||||
:1027100000F0E6F80028ABBF636DA3891B1823F413
|
||||
:102720008053ACBF6365A38110BD2DE9F0411F4606
|
||||
:102730008B89DB0505460C46164605D5022300228B
|
||||
:10274000B1F90E1000F068F8A389B4F90E1023F463
|
||||
:102750008053A38132463B462846BDE8F04100F055
|
||||
:1027600017B810B50C46B1F90E1000F055F8431C1F
|
||||
:10277000A38915BF606523F4805343F48053A3817C
|
||||
:1027800018BFA38110BDB1F90E1000F013B80000FE
|
||||
:1027900038B5074C054608461146002222601A4605
|
||||
:1027A000FEF7E8F8431C02D1236803B12B6038BD63
|
||||
:1027B0005002002038B5064C002305460846236029
|
||||
:1027C00000F0A0F8431C02D1236803B12B6038BD90
|
||||
:1027D0005002002038B5074C002305460846114634
|
||||
:1027E000236000F097F8431C02D1236803B12B60EB
|
||||
:1027F00038BD00BF5002002038B5064C0023054606
|
||||
:102800000846236000F08EF8431C02D1236803B110
|
||||
:102810002B6038BD5002002038B5074C05460846ED
|
||||
:102820001146002222601A4600F084F8431C02D1AF
|
||||
:10283000236803B12B6038BD500200200000000067
|
||||
:1028400001F0FF01102A2BDB10F0070F08D010F861
|
||||
:10285000013B013A8B422DD010F0070F42B3F6D165
|
||||
:10286000F0B441EA012141EA014122F007047FF07E
|
||||
:1028700000070023F0E80256083C85EA010586EAD5
|
||||
:10288000010685FA47F5A3FA87F586FA47F6A5FA11
|
||||
:1028900087F68EB9EED1F0BC01F0FF0102F007021D
|
||||
:1028A00032B110F8013B013A83EA010313B1F8D1C8
|
||||
:1028B0000020704701387047002D06BF35460338A9
|
||||
:1028C000073815F0010F07D1013015F4807F02BFE2
|
||||
:1028D000013015F4C03F0130F0BC0138704700BF33
|
||||
:1028E00038B5074C054608461146002222601A46B4
|
||||
:1028F00000F028F8431C02D1236803B12B6038BDD7
|
||||
:1029000050020020024B58221A604FF0FF307047EF
|
||||
:1029100050020020024B58221A604FF0FF307047DF
|
||||
:1029200050020020024B58221A600020704700BF5E
|
||||
:1029300050020020024B58221A604FF0FF307047BF
|
||||
:1029400050020020024B58221A604FF0FF307047AF
|
||||
:1029500050020020044A05491368002B08BF0B46AB
|
||||
:1029600018441060184670474C020020580200209E
|
||||
:10297000FEE700BFF8B500BFF8BC08BC9E46704734
|
||||
:10298000F8B500BFF8BC08BC9E467047534644509B
|
||||
:102990003A20686561646572206E6F7420666F7599
|
||||
:1029A0006E6400534644503A2076657273696F6EC8
|
||||
:1029B0002077726F6E673A2025752E25640A0053C2
|
||||
:1029C0004644503A206E6F20344B2045525A0053F3
|
||||
:1029D0004644503A206E6F206C61726765207772B2
|
||||
:1029E0006974652062756600534644503A206164FC
|
||||
:1029F00064722E6C656E20213D2033005346445096
|
||||
:102A00003A20344B2045525A206F70636F64652022
|
||||
:102A1000696E76616C696400534644503A2064657F
|
||||
:102A20007669636520746F6F20626967005346445E
|
||||
:102A3000503A2064657669636520736F20736D6119
|
||||
:102A40006C6C3F2100344B2045525A206F70636FED
|
||||
:102A500064652064697361677265656D656E740095
|
||||
:102A6000534644503A206E6F204A454445432074F3
|
||||
:102A700061626C65206F662065787065637465645B
|
||||
:102A80002076657273696F6E20666F756E6400469E
|
||||
:102A90006C617368696E6720256C75206279746556
|
||||
:102AA000732066726F6D2053504920454550524F38
|
||||
:102AB0004D0A000D466C617368696E67207061672E
|
||||
:102AC0006520256C752E2E2E000A416C6C20646FDB
|
||||
:102AD0006E652C20626F6F74696E67204F45504C95
|
||||
:102AE00021004F45504C2D424F4F54000000010132
|
||||
:102AF0000100000000000000000000004B0C00007E
|
||||
:102B000089090000C10C0000CD0C0000C70C0000BA
|
||||
:102B1000490C0000410C0000D50C0000650C0000C1
|
||||
:102B20003D0C000000000000010000000200000059
|
||||
:102B30000300000004000000050000000600000083
|
||||
:102B40000700000008000000090000000A00000063
|
||||
:102B50000B0000000C0000000D0000000E00000043
|
||||
:102B60000F00000010000000110000001200000023
|
||||
:102B70001300000014000000150000001600000003
|
||||
:102B80001700000018000000190000001A000000E3
|
||||
:102B90001B0000001C0000001D0000001E000000C3
|
||||
:102BA0001F0000000C0000200000000000000000DA
|
||||
:102BB0000000000000000000000000000000000015
|
||||
:102BC0000000000000000000000000000000000005
|
||||
:102BD00000000000000000000000000000000000F5
|
||||
:102BE00000000000000000000000000000000000E5
|
||||
:102BF00000000000000000000000000000000000D5
|
||||
:102C00000000000000000000232D302B2000686C25
|
||||
:102C10004C006566674546470030313233343536FF
|
||||
:102C20003738394142434445460030313233343538
|
||||
:102C30003637383961626364656600000000000061
|
||||
:082C400000D6FF7F0100000037
|
||||
:102C4800F40100000090D0030C00002000000000F8
|
||||
:102C5800C82B0000E82B0000A82B00000000000093
|
||||
:102C6800000000000000000000000000000000005C
|
||||
:102C7800000000000000000000000000000000004C
|
||||
:102C8800000000000000000000000000000000003C
|
||||
:102C9800000000000000000000000000000000002C
|
||||
:102CA80000000000000000000000000025020000F5
|
||||
:082CB800D50E0000010200002E
|
||||
:04000003000009B53B
|
||||
:00000001FF
|
||||
25
ARM_Tag_FW/Newton_M3_nRF52811/make_ota.py
Normal file
25
ARM_Tag_FW/Newton_M3_nRF52811/make_ota.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import sys
|
||||
from intelhex import IntelHex
|
||||
|
||||
def cut_hex_file(input_hex_file, output_bin_file):
|
||||
try:
|
||||
ih = IntelHex(input_hex_file)
|
||||
|
||||
# Cut the first 16K (16 * 1024 bytes)
|
||||
ih = ih[16 * 1024:]
|
||||
|
||||
# Write the remaining data to a binary file
|
||||
ih.tobinfile(output_bin_file)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: python script.py input.hex output.bin")
|
||||
sys.exit(1)
|
||||
|
||||
input_hex_file = sys.argv[1]
|
||||
output_bin_file = sys.argv[2]
|
||||
|
||||
cut_hex_file(input_hex_file, output_bin_file)
|
||||
178
ARM_Tag_FW/Newton_M3_nRF52811/mergehex.py
Normal file
178
ARM_Tag_FW/Newton_M3_nRF52811/mergehex.py
Normal file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2008,2010,2011,2013,2014,2015 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Merge content of several hex files into one file."""
|
||||
|
||||
VERSION = '2.0'
|
||||
|
||||
USAGE = '''hexmerge: merge content of hex files.
|
||||
Usage:
|
||||
python hexmerge.py [options] FILES...
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-o, --output=FILENAME output file name (emit output to stdout
|
||||
if option is not specified)
|
||||
-r, --range=START:END specify address range for output
|
||||
(ascii hex value). Both values are inclusive.
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--no-start-addr Don't write start addr to output file.
|
||||
--overlap=METHOD What to do when data in files overlapped.
|
||||
Supported variants:
|
||||
* error -- stop and show error message (default)
|
||||
* ignore -- keep data from first file that
|
||||
contains data at overlapped address
|
||||
* replace -- use data from last file that
|
||||
contains data at overlapped address
|
||||
|
||||
Arguments:
|
||||
FILES list of hex files for merging
|
||||
(use '-' to read content from stdin)
|
||||
|
||||
You can specify address range for each file in the form:
|
||||
|
||||
filename:START:END
|
||||
|
||||
See description of range option above.
|
||||
|
||||
You can omit START or END, so supported variants are:
|
||||
|
||||
filename:START: read filename and use data starting from START addr
|
||||
filename::END read filename and use data till END addr
|
||||
|
||||
Use entire file content:
|
||||
|
||||
filename
|
||||
or
|
||||
filename::
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(args=None):
|
||||
import getopt
|
||||
|
||||
output = None
|
||||
start = None
|
||||
end = None
|
||||
write_start_addr = True
|
||||
overlap = 'error'
|
||||
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(args, 'hvo:r:',
|
||||
['help', 'version',
|
||||
'output=', 'range=',
|
||||
'no-start-addr', 'overlap=',
|
||||
])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ('-o', '--output'):
|
||||
output = a
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except (ValueError, IndexError):
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == '--no-start-addr':
|
||||
write_start_addr = False
|
||||
elif o == '--overlap':
|
||||
if a in ('error', 'ignore', 'replace'):
|
||||
overlap = a
|
||||
else:
|
||||
raise getopt.GetoptError('Bad overlap value')
|
||||
|
||||
if len(args) == 0:
|
||||
raise getopt.GetoptError('You should specify file list')
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
import intelhex
|
||||
# TODO: move actual merge code into intelhex package as helper function
|
||||
# and write couple of tests for it.
|
||||
res = intelhex.IntelHex()
|
||||
|
||||
def end_addr_inclusive(addr):
|
||||
if addr is not None:
|
||||
return addr + 1
|
||||
return addr
|
||||
|
||||
for f in args:
|
||||
try:
|
||||
fname, fstart, fend = intelhex._get_file_and_addr_range(f)
|
||||
except intelhex._BadFileNotation:
|
||||
sys.stderr.write('Bad argument: "%s"\n' % f)
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
if fname == '-':
|
||||
fname = sys.stdin
|
||||
ih = intelhex.IntelHex(fname)
|
||||
if (fstart, fend) != (None, None):
|
||||
ih = ih[fstart:end_addr_inclusive(fend)]
|
||||
try:
|
||||
res.merge(ih, overlap)
|
||||
except intelhex.AddressOverlapError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Merging: '+fname+"\n")
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
return 1
|
||||
|
||||
if (start, end) != (None, None):
|
||||
res = res[start:end_addr_inclusive(end)]
|
||||
if output is None:
|
||||
output = sys.stdout
|
||||
res.write_hex_file(output, write_start_addr)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
14
ARM_Tag_FW/Newton_M3_nRF52811/nrf52811_bootloader.ld
Normal file
14
ARM_Tag_FW/Newton_M3_nRF52811/nrf52811_bootloader.ld
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 0x30000-0x4000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x6000
|
||||
CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x6000
|
||||
}
|
||||
|
||||
|
||||
INCLUDE "nrf_common.ld"
|
||||
@@ -10,24 +10,32 @@ upload_protocol = stlink
|
||||
lib_deps =
|
||||
stevemarple/SoftWire @ ^2.0.9
|
||||
stevemarple/AsyncDelay @ ^1.1.2
|
||||
extra_scripts = post:preparefiles.py
|
||||
|
||||
|
||||
[env:Newton_M3_22_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_22_BWR
|
||||
-Tnrf52811_bootloader.ld
|
||||
build_src_filter =
|
||||
+<*>-<uc8179.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
|
||||
[env:Newton_M3_29_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_29_BWR
|
||||
-Tnrf52811_bootloader.ld
|
||||
build_src_filter =
|
||||
+<*>-<uc8179.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
|
||||
[env:Newton_M3_75_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-Tnrf52811_bootloader.ld
|
||||
-D BUILD_NEWTON_M3_75_BWR
|
||||
build_src_filter =
|
||||
+<*>-<ssd1619.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
24
ARM_Tag_FW/Newton_M3_nRF52811/preparefiles.py
Normal file
24
ARM_Tag_FW/Newton_M3_nRF52811/preparefiles.py
Normal file
@@ -0,0 +1,24 @@
|
||||
Import("env")
|
||||
|
||||
# Custom HEX from ELF
|
||||
env.AddPostAction(
|
||||
"$BUILD_DIR/${PROGNAME}.elf",
|
||||
env.VerboseAction(" ".join([
|
||||
"$OBJCOPY", "-O", "ihex", "-R", ".eeprom",
|
||||
"$BUILD_DIR/${PROGNAME}.elf", "$BUILD_DIR/${PROGNAME}.hex"
|
||||
]), "Building $BUILD_DIR/${PROGNAME}.hex")
|
||||
)
|
||||
|
||||
env.AddPostAction(
|
||||
"$BUILD_DIR/${PROGNAME}.elf",
|
||||
env.VerboseAction(" ".join([
|
||||
"python", "make_ota.py", "$BUILD_DIR/${PROGNAME}.hex", "${PIOENV}-ota.bin"
|
||||
]), "Generating OTA binary ${PIOENV}-ota.bin")
|
||||
)
|
||||
|
||||
env.AddPostAction(
|
||||
"$BUILD_DIR/${PROGNAME}.elf",
|
||||
env.VerboseAction(" ".join([
|
||||
"python", "mergehex.py", "OEPL_bootloader.hex", "$BUILD_DIR/${PROGNAME}.hex", "-o ${PIOENV}-full-flash.hex", "--overlap=replace"
|
||||
]), "Generating full-flash including bootloader ${PIOENV}-full-flash.hex")
|
||||
)
|
||||
@@ -11,6 +11,16 @@
|
||||
#include "userinterface.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#define FW_LOC 0
|
||||
#define FW_METADATA_LOC 196608
|
||||
#define MAGIC1 0xABBAABBA
|
||||
#define MAGIC2 0xDEADBEEF
|
||||
struct fwmetadata {
|
||||
uint32_t fwsize;
|
||||
uint32_t magic1;
|
||||
uint32_t magic2;
|
||||
};
|
||||
|
||||
// download-stuff
|
||||
uint8_t blockXferBuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
|
||||
static struct blockRequest curBlock = {0}; // used by the block-requester, contains the next request that we'll send
|
||||
@@ -383,7 +393,7 @@ static void sendXferComplete() {
|
||||
}
|
||||
static bool validateBlockData() {
|
||||
struct blockData *bd = (struct blockData *)blockXferBuffer;
|
||||
printf("expected len = %04X, checksum=%04X\n", bd->size, bd->checksum);
|
||||
//printf("expected len = %04X, checksum=%04X\n", bd->size, bd->checksum);
|
||||
if (bd->size > BLOCK_XFER_BUFFER_SIZE - sizeof(blockData)) {
|
||||
printf("Impossible data size, we abort here\n");
|
||||
return false;
|
||||
@@ -429,15 +439,22 @@ static uint8_t findSlot(const uint8_t *ver) {
|
||||
return 0xFF;
|
||||
}
|
||||
static void eraseUpdateBlock() {
|
||||
eepromErase(EEPROM_UPDATE_AREA_START, EEPROM_UPDATE_AREA_LEN / EEPROM_ERZ_SECTOR_SZ);
|
||||
eepromErase(FW_LOC, (FW_METADATA_LOC+EEPROM_ERZ_SECTOR_SZ) / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
static void eraseImageBlock(const uint8_t c) {
|
||||
eepromErase(getAddressForSlot(c), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
static void saveUpdateBlockData(uint8_t blockId) {
|
||||
if (!eepromWrite(EEPROM_UPDATE_AREA_START + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
|
||||
if (!eepromWrite(FW_LOC + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
|
||||
printf("EEPROM write failed\n");
|
||||
}
|
||||
static void saveUpdateMetadata(uint32_t size){
|
||||
struct fwmetadata metadata;
|
||||
metadata.magic1 = MAGIC1;
|
||||
metadata.magic2 = MAGIC2;
|
||||
metadata.fwsize = size;
|
||||
eepromWrite(FW_METADATA_LOC, &metadata, sizeof(struct fwmetadata));
|
||||
}
|
||||
static void saveImgBlockData(const uint8_t imgSlot, const uint8_t blockId) {
|
||||
uint32_t length = EEPROM_IMG_EACH - (sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE));
|
||||
if (length > 4096)
|
||||
@@ -550,7 +567,7 @@ static bool getDataBlock(const uint16_t blockSize) {
|
||||
printf("- COMPLETE\n");
|
||||
#endif
|
||||
if (validateBlockData()) {
|
||||
printf("- Validated\n");
|
||||
//printf("- Validated\n");
|
||||
// block download complete, validated
|
||||
return true;
|
||||
} else {
|
||||
@@ -572,6 +589,8 @@ static bool getDataBlock(const uint16_t blockSize) {
|
||||
return false;
|
||||
}
|
||||
uint16_t dataRequestSize = 0;
|
||||
uint32_t curXferSize = 0;
|
||||
|
||||
static bool downloadFWUpdate(const struct AvailDataInfo *avail) {
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
if (!memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8) && curDataInfo.dataSize) {
|
||||
@@ -582,6 +601,7 @@ static bool downloadFWUpdate(const struct AvailDataInfo *avail) {
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), 8);
|
||||
curBlock.type = avail->dataType;
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
curXferSize = avail->dataSize;
|
||||
eraseUpdateBlock();
|
||||
}
|
||||
|
||||
@@ -610,7 +630,7 @@ static bool downloadFWUpdate(const struct AvailDataInfo *avail) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t imageSize = 0;
|
||||
|
||||
static bool downloadImageDataToEEPROM(const struct AvailDataInfo *avail) {
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
if (!memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8) && curDataInfo.dataSize) {
|
||||
@@ -646,7 +666,7 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *avail) {
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), 8);
|
||||
curBlock.type = avail->dataType;
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
imageSize = curDataInfo.dataSize;
|
||||
curXferSize = curDataInfo.dataSize;
|
||||
}
|
||||
|
||||
while (curDataInfo.dataSize) {
|
||||
@@ -680,7 +700,7 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *avail) {
|
||||
memcpy(&eih->version, &curDataInfo.dataVer, 8);
|
||||
eih->validMarker = EEPROM_IMG_VALID;
|
||||
eih->id = ++curHighSlotId;
|
||||
eih->size = imageSize;
|
||||
eih->size = curXferSize;
|
||||
eih->dataType = curDataInfo.dataType;
|
||||
|
||||
#ifdef DEBUGBLOCKS
|
||||
@@ -767,8 +787,8 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
|
||||
powerUp(INIT_EEPROM);
|
||||
wdt60s();
|
||||
eepromReadStart(EEPROM_UPDATE_AREA_START);
|
||||
// selfUpdate();
|
||||
saveUpdateMetadata(curXferSize);
|
||||
NVIC_SystemReset();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
4
ARM_Tag_FW/nRF_Bootloader/.clang-format
Normal file
4
ARM_Tag_FW/nRF_Bootloader/.clang-format
Normal file
@@ -0,0 +1,4 @@
|
||||
Language: Cpp
|
||||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 0
|
||||
3
ARM_Tag_FW/nRF_Bootloader/.gitignore
vendored
Normal file
3
ARM_Tag_FW/nRF_Bootloader/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.pio
|
||||
.vscode
|
||||
core
|
||||
@@ -0,0 +1,261 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
|
||||
int8_t startHFCLK(void) {
|
||||
if (!isHFCLKstable()) {
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_HFCLKSTART = 1U;
|
||||
|
||||
while (!isHFCLKstable())
|
||||
;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t isHFCLKstable(void) {
|
||||
uint32_t stable = (uint32_t)(CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos) | (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos);
|
||||
|
||||
if (NRF_CLOCK->HFCLKSTAT == stable) {
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void boardGetOwnMac(uint8_t *mac) {
|
||||
mac[0] = MAC_ID_1;
|
||||
mac[1] = MAC_ID_0;
|
||||
mac[2] = (NRF_UICR->CUSTOMER[0]) & 0xFF;
|
||||
mac[3] = (NRF_UICR->CUSTOMER[0] >> 8) & 0xFF;
|
||||
mac[4] = (NRF_UICR->CUSTOMER[0] >> 16) & 0xFF;
|
||||
mac[5] = (NRF_UICR->CUSTOMER[0] >> 24);
|
||||
mac[6] = 0;
|
||||
mac[7] = 0;
|
||||
uint8_t cksum = 0;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
cksum ^= mac[c];
|
||||
cksum ^= mac[c] >> 4;
|
||||
}
|
||||
mac[0] += cksum & 0x0F;
|
||||
}
|
||||
|
||||
void watchdog_enable(int timeout) {
|
||||
NRF_WDT->CONFIG = NRF_WDT->CONFIG = (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos) | (WDT_CONFIG_SLEEP_Pause << WDT_CONFIG_SLEEP_Pos);
|
||||
NRF_WDT->CRV = (32768 * timeout) / 1000;
|
||||
NRF_WDT->RREN |= WDT_RREN_RR0_Msk;
|
||||
NRF_WDT->TASKS_START = 1;
|
||||
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
|
||||
}
|
||||
|
||||
uint32_t sleepMsEntry = 0;
|
||||
uint32_t loops = 0;
|
||||
bool interruped = false;
|
||||
|
||||
//uint8_t ledcfg[12] = {0b00100010,0x78,0b00100100,5,0x03,0b01000011,1,0xC2,0b1100001,10,10,0};
|
||||
//uint8_t ledcfg[12] = {0b00010010,0x7D,0,0,0x03,0xE8,0,0,0,0,0,0};
|
||||
uint8_t ledcfg[12] = {255,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
void setled(uint64_t parta,u_int32_t partb){
|
||||
ledcfg[0] = parta & 0xFF;
|
||||
ledcfg[1] = (parta >> 8)& 0xFF;
|
||||
ledcfg[2] = (parta >> 16)& 0xFF;
|
||||
ledcfg[3] = (parta >> 24)& 0xFF;
|
||||
ledcfg[4] = (parta >> 32)& 0xFF;
|
||||
ledcfg[5] = (parta >> 40)& 0xFF;
|
||||
ledcfg[6] = (parta >> 48)& 0xFF;
|
||||
ledcfg[7] = (parta >> 56)& 0xFF;
|
||||
ledcfg[8] = partb & 0xFF;
|
||||
ledcfg[9] = (partb >> 8)& 0xFF;
|
||||
ledcfg[10] = (partb >> 16)& 0xFF;
|
||||
ledcfg[11] = (partb >> 24)& 0xFF;
|
||||
}
|
||||
|
||||
void resettimer(){
|
||||
//tell the sleep function to net sleep again
|
||||
sleepMsEntry = sleepMsEntry - 999999999;
|
||||
loops = 0;
|
||||
interruped = true;
|
||||
}
|
||||
|
||||
void flashled(uint8_t color,uint8_t brightnes){
|
||||
uint8_t colorred = (color >> 5) & 0b00000111;
|
||||
uint8_t colorgreen = (color >> 2) & 0b00000111;
|
||||
uint8_t colorblue = color & 0b00000011;
|
||||
for(uint16_t i = 0;i < brightnes;i++){
|
||||
digitalWrite(LED_RED, !(colorred >= 7));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 7));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 3));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 1));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 1));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 6));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 6));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 1));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 2));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 2));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 5));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 5));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 3));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 3));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 2));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 4));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 4));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
void sleepwithinterrupts(uint32_t sleepinterval){
|
||||
yield();
|
||||
sleepMsEntry = millis();
|
||||
//sometimes we wake up early
|
||||
while (millis() - sleepMsEntry < sleepinterval){
|
||||
initRTC0(sleepinterval);
|
||||
__WFE();
|
||||
__SEV();
|
||||
__WFE();
|
||||
}
|
||||
}
|
||||
|
||||
void ledflashlogic(uint32_t ms){
|
||||
watchdog_enable(ms + 1000);
|
||||
uint8_t brightnes = ledcfg[0] >> 4 & 0b00001111;
|
||||
uint8_t mode = ledcfg[0] & 0b00001111;
|
||||
//lets not blink for short delays
|
||||
if(ms < 2000)mode = 15;
|
||||
//if(mode == 0)sleepwithinterrupts(ms);
|
||||
if(mode == 1){
|
||||
uint8_t color = ledcfg[1];
|
||||
uint32_t ledinerv = (ledcfg[2] << 24 )+ (ledcfg[3] << 16)+ (ledcfg[4] << 8)+ ledcfg[5];
|
||||
uint32_t sleepinterval = ledinerv;
|
||||
loops = ms / ledinerv;
|
||||
if(loops == 0){
|
||||
loops = 1;
|
||||
sleepinterval = ms;
|
||||
}
|
||||
if(sleepinterval > ms)sleepinterval = ms;
|
||||
for(uint32_t i = 0;i < loops;i++){
|
||||
flashled(color,brightnes);
|
||||
sleepwithinterrupts(sleepinterval);
|
||||
}
|
||||
}
|
||||
else if(mode == 0){
|
||||
interruped = false;
|
||||
uint8_t interloopdelayfactor = 100;
|
||||
u_int8_t loopdelayfactor = 100;
|
||||
uint8_t c1 = ledcfg[1];
|
||||
uint8_t c2 = ledcfg[3];
|
||||
uint8_t c3 = ledcfg[5];
|
||||
uint8_t loop1delay = (ledcfg[2] >> 4) & 0b00001111;
|
||||
uint8_t loop2delay = (ledcfg[4] >> 4) & 0b00001111;
|
||||
uint8_t loop3delay = (ledcfg[6] >> 4) & 0b00001111;
|
||||
uint8_t loopcnt1 = ledcfg[2] & 0b00001111;
|
||||
uint8_t loopcnt2 = ledcfg[4] & 0b00001111;
|
||||
uint8_t loopcnt3 = ledcfg[6] & 0b00001111;
|
||||
uint8_t ildelay1 = 0;
|
||||
uint8_t ildelay2 = 0;
|
||||
uint8_t ildelay3 = 0;
|
||||
uint8_t grouprepeats = ledcfg[7];
|
||||
uint32_t fulllooptime1 = loopcnt1 * loop1delay * loopdelayfactor + ildelay1 * interloopdelayfactor;
|
||||
uint32_t fulllooptime2 = loopcnt2 * loop2delay * loopdelayfactor + ildelay2 * interloopdelayfactor;
|
||||
uint32_t fulllooptime3 = loopcnt3 * loop3delay * loopdelayfactor + ildelay3 * interloopdelayfactor;
|
||||
uint32_t looptimesum = fulllooptime1 + fulllooptime2 + fulllooptime3;
|
||||
int fittingrepeats = (int) ms / looptimesum;
|
||||
|
||||
grouprepeats = fittingrepeats;
|
||||
if(grouprepeats == 0)grouprepeats = 1;
|
||||
|
||||
for(int j = 0;j < grouprepeats;j++){
|
||||
|
||||
if(!interruped){
|
||||
for(int i = 0;i < loopcnt1;i++){
|
||||
flashled(c1,brightnes);
|
||||
sleepwithinterrupts(loop1delay * loopdelayfactor);
|
||||
if(interruped)break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay1 * interloopdelayfactor);
|
||||
}
|
||||
if(!interruped){
|
||||
for(int i = 0;i < loopcnt2;i++){
|
||||
flashled(c2,brightnes);
|
||||
sleepwithinterrupts(loop2delay * loopdelayfactor);
|
||||
if(interruped)break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay2 * interloopdelayfactor);
|
||||
}
|
||||
|
||||
if(!interruped){
|
||||
for(int i = 0;i < loopcnt3;i++){
|
||||
flashled(c3,brightnes);
|
||||
sleepwithinterrupts(loop3delay * loopdelayfactor);
|
||||
if(interruped)break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay3 * interloopdelayfactor);
|
||||
}
|
||||
if(interruped)break;
|
||||
}
|
||||
}
|
||||
else sleepwithinterrupts(ms);
|
||||
}
|
||||
|
||||
void sleepForMs(uint32_t ms) {
|
||||
// Turn everything off for minimal deep sleep current
|
||||
//radioRxEnable(0);
|
||||
NRF_CLOCK->TASKS_HFCLKSTOP = 1U;
|
||||
while ((NRF_CLOCK->HFCLKSTAT & 0x10001) == 0x10001);
|
||||
Serial.end();
|
||||
yield();
|
||||
//led and sleep stuff
|
||||
ledflashlogic(ms);
|
||||
//we have to restart the serial
|
||||
Serial.begin(115200);
|
||||
Serial.println("wu");
|
||||
}
|
||||
|
||||
#define LF_FREQUENCY 32768UL
|
||||
#define SECONDS(x) ((uint32_t)((LF_FREQUENCY * (float)((float)x / (float)1000)) + 0.5))
|
||||
uint32_t wakeUpSeconds = 500;
|
||||
|
||||
void initRTC0(uint32_t ms) {
|
||||
NVIC_DisableIRQ(RTC0_IRQn);
|
||||
NVIC_ClearPendingIRQ(RTC0_IRQn);
|
||||
NVIC_SetPriority(RTC0_IRQn, 15);
|
||||
NRF_RTC0->PRESCALER = 0;
|
||||
NRF_RTC0->INTENSET = RTC_EVTENSET_COMPARE0_Enabled << RTC_EVTENSET_COMPARE0_Pos;
|
||||
NRF_RTC0->EVTENSET = RTC_INTENSET_COMPARE0_Enabled << RTC_INTENSET_COMPARE0_Pos;
|
||||
wakeUpSeconds = ms;
|
||||
NRF_RTC0->CC[0] = NRF_RTC0->COUNTER + SECONDS(wakeUpSeconds);
|
||||
NVIC_EnableIRQ(RTC0_IRQn);
|
||||
NRF_RTC0->TASKS_START = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void RTC0_IRQHandler(void) {
|
||||
volatile uint32_t dummy;
|
||||
if (NRF_RTC0->EVENTS_COMPARE[0] == 1) {
|
||||
NRF_RTC0->EVENTS_COMPARE[0] = 0;
|
||||
NRF_RTC0->CC[0] = NRF_RTC0->COUNTER + SECONDS(wakeUpSeconds);
|
||||
dummy = NRF_RTC0->EVENTS_COMPARE[0];
|
||||
dummy;
|
||||
NRF_RTC0->TASKS_STOP = 1;
|
||||
}
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
#define RADIO_FIRST_CHANNEL (11) //2.4-GHz channels start at 11
|
||||
|
||||
#define eepromByte spiByte
|
||||
#define eepromPrvSelect() \
|
||||
do { \
|
||||
digitalWrite(FLASH_CS, LOW); \
|
||||
} while (0)
|
||||
#define eepromPrvDeselect() \
|
||||
do { \
|
||||
digitalWrite(FLASH_CS, HIGH); \
|
||||
} while (0)
|
||||
|
||||
#define LED_RED 16
|
||||
#define LED_GREEN 17
|
||||
#define LED_BLUE 18
|
||||
|
||||
#define BUTTON1 28
|
||||
#define BUTTON2 29
|
||||
|
||||
#define EPD_RST 4
|
||||
#define EPD_BS 2
|
||||
#define EPD_CS 6
|
||||
#define EPD_DC 5
|
||||
#define EPD_BUSY 3
|
||||
#define EPD_CLK 19
|
||||
#define EPD_MOSI 20
|
||||
|
||||
#define NFC_I2C_SDA 8
|
||||
#define NFC_I2C_SCL 9
|
||||
#define NFC_POWER 10
|
||||
#define NFC_IRQ 11
|
||||
|
||||
#define FLASH_CS 12
|
||||
#define FLASH_MISO 13
|
||||
#define FLASH_CLK 14
|
||||
#define FLASH_MOSI 15
|
||||
|
||||
#define EPD_POWER 7
|
||||
|
||||
// Can be used as wanted UART RXD and TXD are used for Debug output
|
||||
#define DBG_RST 21
|
||||
#define DBG_DL 22
|
||||
#define DBG_TXD 25
|
||||
#define DBG_RXD 26
|
||||
#define DBG_TEST 27
|
||||
|
||||
void initRTC0(uint32_t ms);
|
||||
int8_t startHFCLK(void);
|
||||
uint8_t isHFCLKstable(void);
|
||||
void boardGetOwnMac(uint8_t *mac);
|
||||
void sleepForMs(uint32_t ms);
|
||||
void setled(uint64_t parta,u_int32_t partb);
|
||||
void resettimer();
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
// eeprom map
|
||||
#define EEPROM_SETTINGS_AREA_START (0x01000UL)
|
||||
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
|
||||
#define EEPROM_UPDATE_AREA_START (0x04000UL)
|
||||
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
|
||||
#define EEPROM_IMG_START (0x14000UL)
|
||||
#define EEPROM_IMG_EACH (0x04000UL) // 168*384 / 8 * 2 = 0x3F00
|
||||
|
||||
// Mac fixed part
|
||||
// 7E22CC67B298 (B29)
|
||||
#define MAC_ID_0 0xB2
|
||||
#define MAC_ID_1 0x90
|
||||
|
||||
// AP mode definitions
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
// hw types
|
||||
#define HW_TYPE SOLUM_M3_BWR_29
|
||||
|
||||
#define SCREEN_WIDTH 168
|
||||
#define SCREEN_HEIGHT 384
|
||||
|
||||
|
||||
#endif
|
||||
46
ARM_Tag_FW/nRF_Bootloader/include/eeprom.h
Normal file
46
ARM_Tag_FW/nRF_Bootloader/include/eeprom.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _EEPROM_H_
|
||||
#define _EEPROM_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EEPROM_WRITE_PAGE_SZ 256 //max write size & alignment
|
||||
#define EEPROM_ERZ_SECTOR_SZ 4096 //erase size and alignment
|
||||
|
||||
//device has 256 sectors, so eepromErase() cannot erase thw whole device...i can live with that
|
||||
|
||||
bool eepromInit(void);
|
||||
void eepromOtpModeEnter(void);
|
||||
void eepromOtpModeExit(void);
|
||||
|
||||
void eepromRead(uint32_t addr, void *dst, uint16_t len) ;
|
||||
|
||||
bool eepromWrite(uint32_t addr, const void *src, uint16_t len) ;
|
||||
|
||||
bool eepromErase(uint32_t addr, uint16_t numSectors) ;
|
||||
|
||||
void eepromDeepPowerDown(void);
|
||||
|
||||
uint32_t eepromGetSize(void);
|
||||
|
||||
//this is for firmware update use
|
||||
void eepromReadStart(uint32_t addr) ;
|
||||
|
||||
//structures
|
||||
#define EEPROM_IMG_INPROGRESS (0x7fffffffUL)
|
||||
#define EEPROM_IMG_VALID (0x494d4721UL)
|
||||
|
||||
struct EepromImageHeader { //each image space is 0x17000 bytes, we have space for ten of them
|
||||
uint64_t version;
|
||||
uint32_t validMarker;
|
||||
uint32_t size;
|
||||
uint8_t dataType;
|
||||
uint32_t id;
|
||||
|
||||
//image data here
|
||||
//we pre-erase so progress can be calculated by finding the first non-0xff byte
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
10
ARM_Tag_FW/nRF_Bootloader/include/hal.h
Normal file
10
ARM_Tag_FW/nRF_Bootloader/include/hal.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifdef BUILD_NEWTON_M3_29_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_29_BWR.h"
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_NEWTON_M3_75_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_75_BWR.h"
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
#endif
|
||||
|
||||
56
ARM_Tag_FW/nRF_Bootloader/include/lut.h
Normal file
56
ARM_Tag_FW/nRF_Bootloader/include/lut.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
#define LUTGROUP_NEGATIVE 0
|
||||
#define LUTGROUP_FASTBLINK 1
|
||||
#define LUTGROUP_SLOWBLINK 2
|
||||
#define LUTGROUP_SET 3
|
||||
#define LUTGROUP_IMPROVE_SHARPNESS 4
|
||||
#define LUTGROUP_IMPROVE_REDS 5
|
||||
#define LUTGROUP_UNUSED 6
|
||||
|
||||
#define LUTGROUP_UNKNOWN 7
|
||||
#define LUTGROUP_UNUSED3 8
|
||||
#define LUTGROUP_UNUSED4 9
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
struct vgroup {
|
||||
uint8_t A : 2;
|
||||
uint8_t B : 2;
|
||||
uint8_t C : 2;
|
||||
uint8_t D : 2;
|
||||
};
|
||||
|
||||
struct lut {
|
||||
struct vgroup group[7];
|
||||
};
|
||||
|
||||
struct lut10 {
|
||||
struct vgroup group[10];
|
||||
} ;
|
||||
|
||||
struct group {
|
||||
uint8_t phaselength[4];
|
||||
uint8_t repeat;
|
||||
} ;
|
||||
|
||||
struct waveform {
|
||||
struct lut lut[5];
|
||||
struct group group[7];
|
||||
uint8_t gatelevel;
|
||||
uint8_t sourcelevel[3];
|
||||
uint8_t dummyline;
|
||||
uint8_t gatewidth;
|
||||
} ;
|
||||
|
||||
struct waveform10 {
|
||||
struct lut10 lut[5];
|
||||
struct group group[10];
|
||||
uint8_t gatelevel;
|
||||
uint8_t sourcelevel[3];
|
||||
uint8_t dummyline;
|
||||
uint8_t gatewidth;
|
||||
} ;
|
||||
#pragma pack(0)
|
||||
30
ARM_Tag_FW/nRF_Bootloader/include/wdt.h
Normal file
30
ARM_Tag_FW/nRF_Bootloader/include/wdt.h
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
void watchdog_enable(int timeout);
|
||||
|
||||
#define wdt10s() \
|
||||
do \
|
||||
{ \
|
||||
watchdog_enable(10000); \
|
||||
} while (0)
|
||||
|
||||
#define wdt30s() \
|
||||
do \
|
||||
{ \
|
||||
watchdog_enable(30000); \
|
||||
} while (0)
|
||||
|
||||
#define wdt60s() \
|
||||
do \
|
||||
{ \
|
||||
watchdog_enable(60000); \
|
||||
} while (0)
|
||||
|
||||
#define wdt120s() \
|
||||
do \
|
||||
{ \
|
||||
watchdog_enable(120000); \
|
||||
} while (0)
|
||||
46
ARM_Tag_FW/nRF_Bootloader/lib/README
Normal file
46
ARM_Tag_FW/nRF_Bootloader/lib/README
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
20
ARM_Tag_FW/nRF_Bootloader/platformio.ini
Normal file
20
ARM_Tag_FW/nRF_Bootloader/platformio.ini
Normal file
@@ -0,0 +1,20 @@
|
||||
[platformio]
|
||||
core_dir = $PROJECT_DIR/core
|
||||
|
||||
[env]
|
||||
platform = nordicnrf52@9.6.0
|
||||
board = nrf52811_dk
|
||||
framework = arduino
|
||||
debug_tool = stlink
|
||||
upload_protocol = stlink
|
||||
lib_deps =
|
||||
stevemarple/AsyncDelay @ ^1.1.2
|
||||
extra_scripts = post:preparefiles.py
|
||||
|
||||
|
||||
[env:nRFBootload]
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_29_BWR
|
||||
build_src_filter =
|
||||
+<*>-<uc8179.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
18
ARM_Tag_FW/nRF_Bootloader/preparefiles.py
Normal file
18
ARM_Tag_FW/nRF_Bootloader/preparefiles.py
Normal file
@@ -0,0 +1,18 @@
|
||||
Import("env")
|
||||
|
||||
# Custom HEX from ELF
|
||||
env.AddPostAction(
|
||||
"$BUILD_DIR/${PROGNAME}.elf",
|
||||
env.VerboseAction(" ".join([
|
||||
"$OBJCOPY", "-O", "ihex", "-R", ".eeprom",
|
||||
"$BUILD_DIR/${PROGNAME}.elf", "$BUILD_DIR/${PROGNAME}.hex"
|
||||
]), "Building $BUILD_DIR/${PROGNAME}.hex")
|
||||
)
|
||||
|
||||
env.AddPostAction(
|
||||
"$BUILD_DIR/${PROGNAME}.elf",
|
||||
env.VerboseAction(" ".join([
|
||||
"$OBJCOPY", "-O", "ihex", "-R", ".eeprom",
|
||||
"$BUILD_DIR/${PROGNAME}.elf", "../Newton_M3_nRF52811/OEPL_bootloader.hex"
|
||||
]), "Copying bootloader to Newton M3 directory: $BUILD_DIR/${PROGNAME}.hex")
|
||||
)
|
||||
315
ARM_Tag_FW/nRF_Bootloader/src/eeprom.cpp
Normal file
315
ARM_Tag_FW/nRF_Bootloader/src/eeprom.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
#include <Arduino.h>
|
||||
#include "eeprom.h"
|
||||
#include "hal.h"
|
||||
|
||||
uint8_t eepromByte(uint8_t data) {
|
||||
uint8_t temp = 0;
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (data & 0x80)
|
||||
digitalWrite(FLASH_MOSI, HIGH);
|
||||
else
|
||||
digitalWrite(FLASH_MOSI, LOW);
|
||||
data = (data << 1);
|
||||
digitalWrite(FLASH_CLK, HIGH);
|
||||
temp = (temp << 1);
|
||||
if (digitalRead(FLASH_MISO))
|
||||
temp |= 1;
|
||||
digitalWrite(FLASH_CLK, LOW);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
static uint32_t mEepromSize;
|
||||
static uint8_t mOpcodeErz4K = 0, mOpcodeErz32K = 0, mOpcodeErz64K = 0;
|
||||
|
||||
// extern uint8_t * tempBuffer;
|
||||
uint8_t tempBufferE[320] = {0};
|
||||
|
||||
uint32_t eepromGetSize(void) {
|
||||
return mEepromSize;
|
||||
}
|
||||
|
||||
void eepromReadStart(uint32_t addr) {
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x03);
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
}
|
||||
|
||||
void eepromRead(uint32_t addr, void *dstP, uint16_t len) {
|
||||
uint8_t *dst = (uint8_t *)dstP;
|
||||
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x03);
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
|
||||
while (len--)
|
||||
*dst++ = eepromByte(0);
|
||||
eepromPrvDeselect();
|
||||
}
|
||||
|
||||
static void eepromPrvSimpleCmd(uint8_t cmd) {
|
||||
eepromPrvSelect();
|
||||
eepromByte(cmd);
|
||||
eepromPrvDeselect();
|
||||
}
|
||||
|
||||
static bool eepromPrvBusyWait(void) {
|
||||
uint8_t val;
|
||||
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x05);
|
||||
while ((val = eepromByte(0x00)) & 1)
|
||||
;
|
||||
eepromPrvDeselect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool eepromWriteLL(uint32_t addr, const void *srcP, uint16_t len) {
|
||||
const uint8_t *src = (const uint8_t *)srcP;
|
||||
|
||||
eepromPrvSimpleCmd(0x06);
|
||||
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x02);
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
|
||||
while (len--)
|
||||
eepromByte(*src++);
|
||||
eepromPrvDeselect();
|
||||
|
||||
return eepromPrvBusyWait();
|
||||
}
|
||||
|
||||
void eepromDeepPowerDown(void) {
|
||||
eepromPrvSimpleCmd(0xb9);
|
||||
}
|
||||
|
||||
static void eepromPrvWakeFromPowerdown(void) {
|
||||
eepromPrvSimpleCmd(0xab);
|
||||
}
|
||||
|
||||
static void eepromPrvSfdpRead(uint16_t ofst, uint8_t *dst, uint8_t len) {
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x5a); // cmd
|
||||
eepromByte(0); // addr
|
||||
eepromByte(ofst >> 8);
|
||||
eepromByte(ofst);
|
||||
eepromByte(0x00); // dummy
|
||||
while (len--)
|
||||
*dst++ = eepromByte(0);
|
||||
eepromPrvDeselect();
|
||||
}
|
||||
|
||||
boolean eepromInit(void) {
|
||||
uint8_t buf[8];
|
||||
uint8_t i, nParamHdrs;
|
||||
|
||||
eepromPrvWakeFromPowerdown();
|
||||
|
||||
// process SFDP
|
||||
|
||||
eepromPrvSfdpRead(0, buf, 8);
|
||||
if (buf[0] != 0x53 || buf[1] != 0x46 || buf[2] != 0x44 || buf[3] != 0x50 || buf[7] != 0xff) {
|
||||
printf("SFDP: header not found\n");
|
||||
|
||||
boolean valid = false;
|
||||
|
||||
// try manual ID for chips we know of
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x90);
|
||||
eepromByte(0x00);
|
||||
eepromByte(0x00);
|
||||
eepromByte(0x00);
|
||||
if (eepromByte(0) == 0xc2) { // old macronix chips
|
||||
valid = true;
|
||||
mOpcodeErz4K = 0x20;
|
||||
switch (eepromByte(0)) {
|
||||
case 0x05: // MX25V512
|
||||
mEepromSize = 0x00010000ul;
|
||||
break;
|
||||
|
||||
case 0x12: // MX25V4005
|
||||
mEepromSize = 0x00080000ul;
|
||||
break;
|
||||
|
||||
default:
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eepromPrvDeselect();
|
||||
|
||||
return valid;
|
||||
}
|
||||
if (buf[5] != 0x01) {
|
||||
printf("SFDP: version wrong: %u.%d\n", buf[5], buf[4]);
|
||||
return false;
|
||||
}
|
||||
nParamHdrs = buf[6];
|
||||
if (nParamHdrs == 0xff) // that case is very unlikely and we just do not care
|
||||
nParamHdrs--;
|
||||
|
||||
// now we need to find the JEDEC parameter table header
|
||||
for (i = 0; i <= nParamHdrs; i++) {
|
||||
eepromPrvSfdpRead((i * 8) + 8, buf, 8);
|
||||
if (buf[0] == 0x00 && buf[2] == 0x01 && buf[3] >= 9) {
|
||||
uint8_t j;
|
||||
|
||||
eepromPrvSfdpRead(*(uint16_t *)(buf + 4), tempBufferE, 9 * 4);
|
||||
if ((tempBufferE[0] & 3) != 1) {
|
||||
printf("SFDP: no 4K ERZ\n");
|
||||
break;
|
||||
}
|
||||
if (!(tempBufferE[0] & 0x04)) {
|
||||
printf("SFDP: no large write buf\n");
|
||||
break;
|
||||
}
|
||||
if ((tempBufferE[2] & 0x06)) {
|
||||
printf("SFDP: addr.len != 3\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tempBufferE[1] || tempBufferE[1] == 0xff) {
|
||||
printf("SFDP: 4K ERZ opcode invalid\n");
|
||||
break;
|
||||
}
|
||||
mOpcodeErz4K = tempBufferE[1];
|
||||
|
||||
if (tempBufferE[7] & 0x80) {
|
||||
printf("SFDP: device too big\n");
|
||||
break;
|
||||
} else {
|
||||
uint8_t t;
|
||||
|
||||
if ((t = tempBufferE[7]))
|
||||
mEepromSize = 0x00200000UL;
|
||||
else if ((t = tempBufferE[6]))
|
||||
mEepromSize = 0x00002000UL;
|
||||
else if ((t = tempBufferE[5]))
|
||||
mEepromSize = 0x00000020UL;
|
||||
else {
|
||||
printf("SFDP: device so small?!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
while (t) {
|
||||
mEepromSize <<= 1;
|
||||
t >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// get erase opcodes
|
||||
for (j = 0x1c; j < 0x24; j += 2) {
|
||||
uint8_t instr = tempBufferE[j + 1];
|
||||
|
||||
if (!instr || instr == 0xff)
|
||||
continue;
|
||||
|
||||
switch (tempBufferE[j]) {
|
||||
case 0x0c:
|
||||
if (mOpcodeErz4K != instr) {
|
||||
printf("4K ERZ opcode disagreement\n");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0f: // 32K erase
|
||||
mOpcodeErz32K = instr;
|
||||
break;
|
||||
|
||||
case 0x10: // 64K erase
|
||||
mOpcodeErz64K = instr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
printf("EEPROM accepted\n");
|
||||
printf(" ERZ opcodes: \n");
|
||||
if (mOpcodeErz4K)
|
||||
printf(" 4K: %02xh\n", mOpcodeErz4K);
|
||||
if (mOpcodeErz32K)
|
||||
printf(" 32K: %02xh\n", mOpcodeErz32K);
|
||||
if (mOpcodeErz64K)
|
||||
printf(" 64K: %02xh\n", mOpcodeErz64K);
|
||||
printf(" Size: 0x%*08lx\n", (uint16_t)&mEepromSize);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
printf("SFDP: no JEDEC table of expected version found\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eepromWrite(uint32_t addr, const void *srcP, uint16_t len) {
|
||||
const uint8_t *src = (const uint8_t *)srcP;
|
||||
|
||||
while (len) {
|
||||
uint16_t lenNow = EEPROM_WRITE_PAGE_SZ - (addr & (EEPROM_WRITE_PAGE_SZ - 1));
|
||||
|
||||
if (lenNow > len)
|
||||
lenNow = len;
|
||||
|
||||
if (!eepromWriteLL(addr, src, lenNow))
|
||||
return false;
|
||||
|
||||
addr += lenNow;
|
||||
src += lenNow;
|
||||
len -= lenNow;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eepromErase(uint32_t addr, uint16_t nSec) {
|
||||
uint8_t now;
|
||||
|
||||
if (((uint16_t)addr) & 0x0fff)
|
||||
return false;
|
||||
|
||||
for (; nSec; nSec -= now) {
|
||||
eepromPrvSimpleCmd(0x06);
|
||||
eepromPrvSelect();
|
||||
|
||||
if (nSec >= 16 && !(uint16_t)addr && mOpcodeErz64K) { // erase 64K
|
||||
|
||||
eepromByte(mOpcodeErz64K);
|
||||
now = 16;
|
||||
} else if (nSec >= 8 && !(((uint16_t)addr) & 0x7fff) && mOpcodeErz32K) { // erase 32K
|
||||
|
||||
eepromByte(mOpcodeErz32K);
|
||||
now = 8;
|
||||
} else { // erase 4K
|
||||
|
||||
eepromByte(mOpcodeErz4K);
|
||||
now = 1;
|
||||
}
|
||||
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr);
|
||||
eepromPrvDeselect();
|
||||
|
||||
if (!eepromPrvBusyWait())
|
||||
return false;
|
||||
|
||||
addr += (EEPROM_ERZ_SECTOR_SZ * now);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void eepromOtpModeEnter(void) {
|
||||
eepromPrvSimpleCmd(0xb1);
|
||||
}
|
||||
|
||||
void eepromOtpModeExit(void) {
|
||||
eepromPrvSimpleCmd(0xc1);
|
||||
}
|
||||
172
ARM_Tag_FW/nRF_Bootloader/src/main.cpp
Normal file
172
ARM_Tag_FW/nRF_Bootloader/src/main.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#include <Arduino.h>
|
||||
#include <AsyncDelay.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eeprom.h"
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#define UICR_BASE 0x10001000
|
||||
#define UICR_VTOR_OFFSET 0x14
|
||||
|
||||
#define FW_LOC 0
|
||||
#define FW_METADATA_LOC 196608
|
||||
|
||||
#define MAGIC1 0xABBAABBA
|
||||
#define MAGIC2 0xDEADBEEF
|
||||
|
||||
#define BOOTLOADER_SIZE 16384
|
||||
#define FLASH_SIZE 196608
|
||||
#define FLASH_PAGE_SIZE 4096
|
||||
|
||||
#define APP_ENTRY BOOTLOADER_SIZE
|
||||
|
||||
struct fwmetadata {
|
||||
uint32_t fwsize;
|
||||
uint32_t magic1;
|
||||
uint32_t magic2;
|
||||
};
|
||||
|
||||
extern "C" int _write(int file, char *ptr, int len) {
|
||||
(void)file; /* Not used, avoid warning */
|
||||
Serial.write(ptr, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
bool fwFlashPending() {
|
||||
struct fwmetadata metadata;
|
||||
eepromRead(FW_METADATA_LOC, &metadata, sizeof(struct fwmetadata));
|
||||
if (metadata.magic1 == MAGIC1 && metadata.magic2 == MAGIC2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t fwFlashPendingSize() {
|
||||
struct fwmetadata metadata;
|
||||
eepromRead(FW_METADATA_LOC, &metadata, sizeof(struct fwmetadata));
|
||||
return metadata.fwsize;
|
||||
}
|
||||
|
||||
void writeFlashPage(uint32_t address, uint8_t *source) {
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
NRF_NVMC->ERASEPAGE = address;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
|
||||
// write bytes
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < FLASH_PAGE_SIZE; i += 4) {
|
||||
uint32_t data_word = *((uint32_t *)&(source[i]));
|
||||
*((uint32_t *)(address + i)) = data_word;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
}
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
}
|
||||
|
||||
void removeFwFlashPending() {
|
||||
struct fwmetadata metadata;
|
||||
metadata.magic1 = 0;
|
||||
metadata.magic2 = 0;
|
||||
metadata.fwsize = 0;
|
||||
eepromWrite(FW_METADATA_LOC, &metadata, sizeof(struct fwmetadata));
|
||||
}
|
||||
|
||||
void setupPortsInitial() {
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
pinMode(LED_BLUE, OUTPUT);
|
||||
pinMode(BUTTON1, INPUT_PULLUP);
|
||||
pinMode(BUTTON2, INPUT_PULLUP);
|
||||
pinMode(NFC_POWER, INPUT_PULLDOWN);
|
||||
pinMode(NFC_IRQ, INPUT_PULLDOWN);
|
||||
|
||||
pinMode(FLASH_MISO, INPUT);
|
||||
pinMode(FLASH_CLK, OUTPUT);
|
||||
pinMode(FLASH_MOSI, OUTPUT);
|
||||
digitalWrite(FLASH_CS, HIGH);
|
||||
pinMode(FLASH_CS, OUTPUT);
|
||||
}
|
||||
|
||||
typedef void (*app_reset_handler_t)(void);
|
||||
void jumpToApp(void) {
|
||||
// Disable interrupts while we configure the vector table
|
||||
__disable_irq();
|
||||
SCB->VTOR = APP_ENTRY;
|
||||
__set_MSP(*(uint32_t *)APP_ENTRY);
|
||||
app_reset_handler_t app_reset_handler = (app_reset_handler_t) * (uint32_t *)(APP_ENTRY + 4);
|
||||
__enable_irq();
|
||||
app_reset_handler();
|
||||
}
|
||||
|
||||
void ledBlink(uint8_t led) {
|
||||
digitalWrite(led, LOW);
|
||||
delay(3);
|
||||
digitalWrite(led, HIGH);
|
||||
}
|
||||
|
||||
void performFWFlash() {
|
||||
uint32_t filesize = fwFlashPendingSize();
|
||||
|
||||
for (uint8_t c = 0; c < 15; c++) {
|
||||
ledBlink(LED_BLUE);
|
||||
delay(70);
|
||||
}
|
||||
|
||||
if ((filesize < 8192) || (filesize > (FLASH_SIZE - BOOTLOADER_SIZE))) {
|
||||
for (uint8_t c = 0; c < 20; c++) {
|
||||
ledBlink(LED_RED);
|
||||
delay(100);
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf("Flashing %lu bytes from SPI EEPROM\n", filesize);
|
||||
uint8_t *eepromdata = (uint8_t *)malloc(FLASH_PAGE_SIZE);
|
||||
for (uint32_t offset = 0; offset < filesize; offset += FLASH_PAGE_SIZE) {
|
||||
eepromRead(FW_LOC + offset, eepromdata, FLASH_PAGE_SIZE);
|
||||
// dump(eepromdata, FLASH_PAGE_SIZE);
|
||||
writeFlashPage(APP_ENTRY + offset, eepromdata);
|
||||
printf("\rFlashing page %lu...", offset);
|
||||
ledBlink(LED_BLUE);
|
||||
}
|
||||
printf("\nAll done, booting OEPL!\n");
|
||||
digitalWrite(LED_GREEN, LOW);
|
||||
delay(500);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(300);
|
||||
printf("OEPL-BOOT\n");
|
||||
setupPortsInitial();
|
||||
eepromInit();
|
||||
if (fwFlashPending()) {
|
||||
performFWFlash();
|
||||
removeFwFlashPending();
|
||||
} else {
|
||||
ledBlink(LED_GREEN);
|
||||
}
|
||||
jumpToApp();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
11
ARM_Tag_FW/nRF_Bootloader/test/README
Normal file
11
ARM_Tag_FW/nRF_Bootloader/test/README
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Reference in New Issue
Block a user