Skip to content

Instantly share code, notes, and snippets.

@blindman2k
Created May 16, 2014 00:18
Show Gist options
  • Save blindman2k/2c88a06af55a1e537736 to your computer and use it in GitHub Desktop.
Save blindman2k/2c88a06af55a1e537736 to your computer and use it in GitHub Desktop.
DA14580 boot code
server.log("Agent started, URL is " + http.agenturl());
//------------------------------------------------------------------------------------------------------------------------------
program <- null;
html <- @"<HTML>
<BODY>
<form method='POST' enctype='multipart/form-data'>
Program the Dialog DA14580 BTLE module via the Imp.<br/><br/>
Step 1: Select an Intel HEX file to upload: <input type=file name=hexfile><br/>
Step 2: <input type=submit value=Press> to upload the file.<br/>
Step 3: Check out your module<br/>
</form>
</BODY>
</HTML>
";
//------------------------------------------------------------------------------------------------------------------------------
// Parses a hex string and turns it into an integer
function hextoint(str) {
local hex = 0x0000;
foreach (ch in str) {
local nibble;
if (ch >= '0' && ch <= '9') {
nibble = (ch - '0');
} else {
nibble = (ch - 'A' + 10);
}
hex = (hex << 4) + nibble;
}
return hex;
}
//------------------------------------------------------------------------------------------------------------------------------
// Parses a HTTP POST in multipart/form-data format
function parse_hexpost(req, res) {
local boundary = req.headers["content-type"].slice(30);
local bindex = req.body.find(boundary);
local hstart = bindex + boundary.len();
local bstart = req.body.find("\r\n\r\n", hstart) + 4;
local fstart = req.body.find("\r\n\r\n--" + boundary + "--", bstart);
return req.body.slice(bstart, fstart);
}
//------------------------------------------------------------------------------------------------------------------------------
// Parse the hex into an array of blobs
function parse_hexfile(hex) {
try {
// Look at this doc to work out what we need and don't. Max is about 122kb.
server.log("Parsing hex file");
// Create and blank the program blob
program = blob(0x20000); // 128k maximum
for (local i = 0; i < program.len(); i++) program.writen(0xFF, 'b');
program.seek(0);
local maxaddress = 0, from = 0, to = 0, line = "", offset = 0x00000000;
do {
if (to < 0 || to == null || to >= hex.len()) break;
from = hex.find(":", to);
if (from < 0 || from == null || from+1 >= hex.len()) break;
to = hex.find(":", from+1);
if (to < 0 || to == null || from >= to || to >= hex.len()) break;
line = hex.slice(from+1, to);
// server.log(format("[%d,%d] => %s", from, to, line));
if (line.len() > 10) {
local len = hextoint(line.slice(0, 2));
local addr = hextoint(line.slice(2, 6));
local type = hextoint(line.slice(6, 8));
// Ignore all record types except 00, which is a data record.
// Look out for 02 records which set the high order byte of the address space
if (type == 0) {
// Normal data record
} else if (type == 4 && len == 2 && addr == 0 && line.len() > 12) {
// Set the offset
// offset = hextoint(line.slice(8, 12)); // << 16;
if (offset != 0) {
server.log(format("Set offset to 0x%08X", offset));
}
continue;
} else {
server.log("Skipped: " + line)
continue;
}
// Read the data from 8 to the end (less the last checksum byte)
program.seek(offset + addr)
// server.log(format("Seek offset %02X -> %02X", offset + addr, program.tell()))
for (local i = 8; i < 8+(len*2); i+=2) {
local datum = hextoint(line.slice(i, i+2));
program.writen(datum, 'b')
}
// Checking the checksum would be a good idea but skipped for now
local checksum = hextoint(line.slice(-2));
/// Shift the end point forward
if (program.tell() > maxaddress) maxaddress = program.tell();
}
} while (from != null && to != null && from < to);
// Crop, save and send the program
server.log(format("Max address: 0x%08x", maxaddress));
program.resize(maxaddress);
server.log("Free RAM: " + (imp.getmemoryfree()/1024) + " kb")
// return false;
return true;
} catch (e) {
server.log(e)
return false;
}
}
//------------------------------------------------------------------------------------------------------------------------------
// Handle the agent requests
http.onrequest(function (req, res) {
if (req.method == "GET") {
res.send(200, program);
// res.send(200, html);
} else if (req.method == "POST") {
if ("content-type" in req.headers) {
if (req.headers["content-type"].len() >= 19
&& req.headers["content-type"].slice(0, 19) == "multipart/form-data") {
local hex = parse_hexpost(req, res);
if (hex == "") {
res.header("Location", http.agenturl());
res.send(302, "HEX file uploaded");
} else {
if (parse_hexfile(hex)) {
device.on("done", function(ready) {
res.header("Location", http.agenturl());
res.send(302, "HEX file uploaded");
server.log("Programming completed")
})
send();
} else {
res.header("Location", http.agenturl());
res.send(302, "HEX parsing failed");
}
}
} else if (req.headers["content-type"] == "application/json") {
local json = null;
try {
json = http.jsondecode(req.body);
} catch (e) {
server.log("JSON decoding failed for: " + req.body);
return res.send(400, "Invalid JSON data");
}
local log = "";
foreach (k,v in json) {
if (typeof v == "array" || typeof v == "table") {
foreach (k1,v1 in v) {
log += format("%s[%s] => %s, ", k, k1, v1.tostring());
}
} else {
log += format("%s => %s, ", k, v.tostring());
}
}
server.log(log)
return res.send(200, "OK");
} else {
return res.send(400, "Bad request");
}
} else {
return res.send(400, "Bad request");
}
}
})
//------------------------------------------------------------------------------------------------------------------------------
function send(success = true) {
if (program != null) {
server.log("Sending program to device: " + program.len() + " bytes");
device.send("burn", program)
} else {
server.log("Sorry, we don't have any firmware for you right now.")
}
}
//------------------------------------------------------------------------------------------------------------------------------
// Handle the device coming online
device.on("ready", send);
//------------------------------------------------------------------------------------------------------------------------------
device.on("done", function(ready) {
server.log("Programming completed")
})
//------------------------------------------------------------------------------------------------------------------------------
// Initialise a new agent with a hexfile. Should probably come from the web.
//
{
// This hexfile represents out test application which blinked the blue LED on P0_7 and advertises as a peripheral.
const HEXFILE = @"
:020000042000DA
:10000000009800209D0400203D0B0020A704002044
:1000100000000000000000000000000000000000E0
:10002000000000000000000000000000A904002003
:100030000000000000000000C1040020C3040020F4
:10004000951F0020053103000D3103001531030019
:100050006D2000208D310300A531030043300300E3
:10006000C5040020C5040020BF200020AD310300DE
:10007000578102004B1B02004B1B02004B1B02006E
:100080004B1B02004B1B02004B1B02004B1B0200D0
:100090004B1B02004B1B0200C50400204B1B02003F
:020000042000DA
:1001600032000000A505002007120020150A00201B
:10017000000000000000000063800200BD8002005B
:10018000CB800200FB800200198102003581020051
:100190005D81020051680200610500200D10002001
:1001A0003710002000000000000000003F000000A9
:1001B000F48B002000040000740B080048010000CC
:1001C0006807080000040000C80C080020050000B3
:1001D000000000002000000048000000580000005F
:1001E0006800000004010000160100002801000062
:1001F0002E010000202A00008E2E000001000000C9
:1002000088130000E7120020E9600200FD9302005D
:100210002315002019280300A57402002D190020C1
:1002200003000000D5200200150A00200400000091
:10023000D74902000F490200831D020063910200AA
:10024000B7910200BF910200078202007182020092
:1002500080480020AD8302009384020041850200A3
:1002600015860200378602005F860200758602004E
:10027000F9870200258902005D8A0200D38C020002
:10028000098D02000F900200438D0200278E0200AC
:10029000F98E0200478F0200998F0200D58F02006D
:1002A00049510200775102002F5202001000000055
:1002B00020030000803E000000000000000000005D
:020000042000DA
:1002C000504600030003983A6400F401B80B000C98
:1002D000B80B120030003000CD009A01120024004B
:1002E00030006400B0001800280012001200D0078F
:1002F0000000FFFF00000000000000000000000000
:100300001F00000252495649455241574156455334
:100310002D424C45000000000000000000000000DD
:0403200000000000D9
:020000042000DA
:10034000FFFF010000C201000000000000000000EB
:100350000000F401010001070A0F0201060303A0D7
:10036000FF0000000000000000000000000000008E
:100370000000000000000000000009FF006052576C
:100380002D424C450000000000000000000000006D
:100390000000000000000000000044413134353806
:1003A000302D30310000000000000000000000008F
:1003B000000000000000000000000000000000003D
:1003C000000000000000000000000000000000002D
:1003D0000000000000000000012345558911D007EE
:0403E0000690640A15
:020000042000DA
:100440000348854603F0AAF800480047C720020089
:1004500000980020104989683E2291432E310E4AAF
:10046000916000210522120711801146098A0F228E
:10047000120291438918052212071182002005E01B
:1004800000210122D20482181160001D03210903FA
:100490008842F5DB62B67047003300500A48804757
:1004A0000A480047FEE7FEE704207146084203D0F1
:1004B000EFF3098006490847EFF30880044908472D
:1004C000FEE7FEE7FEE7000055040020410400209F
:1004D000EF04002030B5024693688C68181B80B288
:1004E000FE4DA84201D9012030BD0020FCE7826901
:1004F000203A917F052904D28A00F94B9A588261EB
:1005000001E000BFFEE7704710B5F648F649086104
:10051000F6484861F6488861F648C861F6480862BE
:10052000F6484862F6488862F648C862F6480863AA
:10053000F64848630017C206D20E01219140F44AE2
:10054000116000BF002100F024FA0420C043C2065D
:10055000D20E01219140EE4A803A116000BF10BDD9
:1005600070B5EC480068AA2801D13E2400E0972429
:10057000E94800210160204603F0D0F985B2284601
:10058000C83085B2284603F0CFF900200121890741
:10059000096B49004908C207114301229207116300
:1005A00000BF70BD1CB50120DC4908700820DC4983
:1005B000088003F0BFF903F079FC00F05BFBD94839
:1005C0000078D8490870D8480078D74908700120C9
:1005D00003F0B6F9012149022720000103F0B6F922
:1005E00001F089FB00F058FD00F06CFBCF4800895A
:1005F00040094001CD490881084600890F21890240
:1006000088430521C9024018C8490881C848488262
:10061000262088820720C882C64808830120488394
:10062000084640881E2188431430C0494880042071
:1006300000F0A8F9072000F0A5F90A2000F0A2F9BF
:10064000062000F09FF90B2000F09CF9012000F03B
:1006500099F9022000F096F9002000F093F9B648CD
:10066000006803F079F9012080070068FF2101315B
:10067000884340188905086000F0CEF9A548006855
:10068000AA2805D1142000F0FDFB142000F011FC75
:1006900001F042FDFFF764FFA22005210907C8828F
:1006A000A2484088E0218843A030A0494880A34860
:1006B000046B2078002803D1012003F053F902E0F5
:1006C000002003F04FF903F053F9022803D003F0A0
:1006D0004FF9012812D108209149088000BF052058
:1006E0000007808A202108402028F8D00520000734
:1006F000408A8021884305210907488241E102F0B0
:100700004EF905200007008980210840C0112BD038
:10071000C805006B09020840C00B25D103F02EF973
:10072000C007C00F20D1042003F02EF9054603F0C6
:1007300031F9002D11D00020009076480068AA28D9
:1007400002D1142000F0B5FB0421684603F028F91B
:10075000002801D000F0E8FB00BF00BF002000BF70
:10076000002800D00DE100BF00BF002000BF00281E
:1007700000D006E172B600BF00BF01F020FB01907F
:1007800069460879042808D16D480078012802D10B
:100790000220019001E003200190684600790228C0
:1007A00003D06846007903287BD105200007008A22
:1007B00004218843001D0521090708825F4840384D
:1007C000C069012817D968460079032810D103F0C1
:1007D000EDF800280CD003F0EFF8002808D0032033
:1007E00003F0F0F8002803D002205649087010E00A
:1007F000022001900DE068460079032807D103F03C
:10080000E1F8002803D001204E49087001E00220E1
:10081000019000BF00BF68460079022803D06846F7
:100820000079032857D14848006904210843464904
:10083000086105200007408A202188430521090717
:1008400048820846008A02218843801C0521090746
:1008500008826846007902280FD10846408A0421A0
:100860008843001D0521090748820846408A102157
:1008700088430521090748822DE005200007408AAA
:1008800004218843001D0521090748827F2080013B
:1008900009888022914380310522120711800021AE
:1008A00002E067E04A1CD1B20A29FBDB05210907F7
:1008B000498A102291431031052212075182411EAC
:1008C000224A5161052109070988802291430522A6
:1008D0001207118000BF1548408839E030750000CC
:1008E0006C480020942703000084004000DF8968E2
:1008F00028A30200704701DF1CCA0200F8BD02DF16
:1009000040CB0200F5E703DF84D4020004DF89B0A6
:1009100080E100E0B07F00208C030800A87F002069
:100920000033005000000800202A0800200000507A
:100930004E02000077770000049000202002002083
:1009400054020800C406080000ED00E000800040EA
:10095000FF21013188432B49488000BF00BF30BFD1
:100960006946087900BF2848006904218843264960
:10097000086104E068460079012800D130BF62B602
:1009800000BFBCE6C206D20E012191401F4A116091
:10099000704710B500281BDA1B4A1C3203071B0FD7
:1009A000083B9B089B00D2588307DC0EFF23A34023
:1009B0009A438B071B0E8407E40EA3401A43124B85
:1009C0001C330407240F083CA408A4001A5118E0A3
:1009D0000F4A03231B02D21883089B00D2588307B7
:1009E000DC0EFF23A3409A438B071B0E8407E40E03
:1009F000A3401A43064B032424021B198408A400B5
:100A00001A5110BD2000005000ED00E080E200E02F
:100A100000E100E07047000042480078002804D15F
:100A2000414908704149C87002E08020404908707F
:100A300070473C480078002805D101203A490870E9
:100A40003A49C87002E0812039490870704735483A
:100A50000078002806D1022033490870012033496C
:100A6000C87002E0822032490870704700B53148F2
:100A70000078002804DD2F480078401E2D490870BA
:100A80002C480078002800DD00BD294800780028A7
:100A900009D0274800788007800F2249087000207D
:100AA0002349087008E01F480078002804D01D483A
:100AB0000078401E1B4908701A4802780020194926
:100AC0000870002A04D0012A03D0022A07D103E0CB
:100AD00006E0FFF7AEFF03E0FFF7B9FF00E000BF5D
:100AE00000BF00BFD0E710B512480078401C114984
:100AF00008700C480078002808D102F039FF04463D
:100B0000601CC4B2FFF788FF0648047010BD0120C6
:100B10000949087070470020074908707047064867
:100B200000787047A97F002054020800C60608001C
:100B3000AA7F0020AB7F0020AC7F002005200007AB
:100B4000008A04218843001D052109070882084600
:100B5000008A02218843801C052109070882084673
:100B60000089402188434030052109070881002081
:100B7000012181400A4A116000BF0820094908800C
:100B80005005408A802188438030510548820846BC
:100B9000808A20210840202800D100BE00BFFEE747
:100BA00080E200E00033005042480069002802D093
:100BB0000020C04300E001203E490861084600696A
:100BC000C117020F0901114300013B4B1A685B6812
:100BD00010431943384A1060516036484069002874
:100BE00002D00020C04300E001203249486108469D
:100BF0004069C117C20E4901114340012E4A1368D2
:100C00005268184311432C4A106051602948C0694A
:100C1000002802D00020C04300E001202549C8611F
:100C20000846C069C117420EC9011143C001224ADA
:100C300013685268184311431F4A1060516070478F
:100C400008B500200223032212020421009003F0C1
:100C500069F80020012302460521009003F062F8A4
:100C6000012000230322120207210090184603F0FE
:100C700059F808BD10B505200007008A02218843F5
:100C800005210907088200BF05200007808A082186
:100C90000842F9D0FFF738FCFFF7D2FF01F076FFEA
:100CA00005200007408A20218843203005210907BC
:100CB000488210BD007F0020A07F00200020E8496E
:100CC0000860704700B5052000070089302188437F
:100CD0000521090708810846008980218843803062
:100CE0000521090708810846008980088000401C0A
:100CF0000881084600890821884308300521090732
:100D00000881D8480088802188438030D5490880F0
:100D100005200007408A08218843052109074882E9
:100D20000846008940218843403005210907088191
:100D30000846008A0421884305210907088200BF6C
:100D400005200007808A02210842F9D0FFF7B6FF8C
:100D5000C348006800281DD1C248008840084000F0
:100D6000401CC049088008460088C9018843BD4925
:100D7000088008460088782188430830B9490880EF
:100D800005200007408A082188430830052109070B
:100D9000488235E0B2480068AA2831D1B14880883D
:100DA000F0218843B030AF4988800846808803210D
:100DB00009028843FF300130AA49888008468088AC
:100DC000000900018880084680884901884340184E
:100DD000A449888008468088890188434018A14931
:100DE000888008468088C901884340189D498880CA
:100DF00005200007408A0821884305210907488209
:100E0000984800888021884396490880052000077B
:100E100000894021884305210907088191484089BC
:100E2000012149020840401203D005208D4960315C
:100E30008880012080070068FF21013188438905EF
:100E40000860894800683F2149028843012149031D
:100E5000401885490860084600680903884340181F
:100E60008149086000BD03210902804A918108215F
:100E70005180002000E0401C9628FCD308217B4ACA
:100E80009180704700B50346794843800088800808
:100E90008000C01C764908800846008804218843E9
:100EA000001D73490880012072490870FFF7DBFFBD
:100EB00000BDF0B585B004466E480078002831D0FA
:100EC00000BF6B480088042108408010F9D16848B1
:100ED000C0880390664880880290039800040299B5
:100EE00040180190644961430846019902F070FD81
:100EF000009000205F4908706049009808600098E1
:100F000002F09BF8074639465D4802F058F806465D
:100F10008921C90502F016F8054602F095F85949ED
:100F2000086000BF05B0F0BDF8B50020009000BF1C
:100F300001205549C86300BF00BF00BF00BF524831
:100F4000C06B0028FAD100BF01208007C46900BF30
:100F50004E480068844202D200204C490860009844
:100F6000002812D0002000904848046002F036FDAE
:100F700047490880012002F037FD02F03BFD06469C
:100F8000002E01D101200090F8BD40480068201AD1
:100F90001921C90188421FD33C48046002F01EFD9C
:100FA00005463B4909888D4204DD39480088281AE6
:100FB00087B203E036480088401B87B2182F0BDB4E
:100FC00033480580012002F00FFD02F013FD0646B4
:100FD000002E01D10120009000BFD5E738B50446AE
:100FE00026490968614308462A4902F0F1FC00904D
:100FF000009838BD0CB5014600910098009021483A
:1010000000684843800A019001980CBD38B5044639
:1010100013480068002804D1204602F0F1FC00903B
:1010200007E00F480068AA2803D12046FFF7D6FF43
:101030000090009838BD38B504460948006800287B
:1010400004D1204602F06AFC009007E004480068E2
:10105000AA2803D12046FFF7CDFF0090009838BDA5
:10106000B07F0020200000500002004020300050DF
:1010700000160050B87F00200024F400B47F002048
:1010800000247449BC7F0020C00000407C0408009C
:101090007804080040420F00D349D448CA0512889A
:1010A00080239A438032CB051A8000BFD04A5289F0
:1010B00008231A40082A03D00A46491E002AF5D1FF
:1010C0000122CC4B1A600288CB4B1A80801C02880C
:1010D000CA4B1A8005221207128880239A430523DF
:1010E0001B071A8070470146002070477047704701
:1010F000704702460020704700BF01218907096B35
:10110000062211430122084610439107086300BFDD
:1011100070477047BA48BB4908604C20BA490880FC
:10112000BA48B94920390882B948BA494880BA480A
:10113000BA490880B8481930488022204881812067
:1011400080000882B6484882B6480883B448113007
:101150004883B548B1492031888041200001B34916
:101160008880B348C880B2481030C881B04808822F
:101170004882801C8882AE480B30C882FF204630EF
:101180000883AC4848835920AB490880AB48AA493A
:101190002031088043204880A948A7494882D520AB
:1011A000A54920318880FF20D3300881A548488197
:1011B000A5488881A548A6490880A6489249603973
:1011C00048800846C0881021884310308E49603915
:1011D000C8809A480A3808819F488B49403948801E
:1011E0008A488949203948820820874960394881DE
:1011F000824800889049403908827F480088974992
:10120000088070477047F0B58DB004460025002671
:10121000934860629348A062934860619348E0629B
:101220009348206093482062934860609348E0614F
:101230007F210906284688430721090645180F2102
:10124000090228468843052109024518FF2109049F
:1012500028468843152189044518280A00020546B6
:101260004C356848056067484038006B01218905A6
:1012700088436449403908630846406B1F210904CC
:1012800088430321090440185E49403948637C487B
:101290000068C91288437A49086008460068091343
:1012A00088437749086003E003A88655701CC6B2DE
:1012B000282EF9DB03A82027019028200290B803EC
:1012C0003818029A019902F0A1FB00BFFFF722FF34
:1012D00002F084FB6B490880002002F085FB02F0DD
:1012E00089FB0DB0F0BD70B500247F2109062046B2
:1012F00088430721090644180F2109022046884324
:10130000052109024418FF210904204688431521BC
:1013100089044418200A000204464C343948046009
:1013200038484038406B1F210904884303210904D1
:10133000401834494039486308060068C008C000B6
:101340000906086005200007008980088000401C0D
:1013500005210907088108460089082188430830CB
:101360000521090708810846008A0F2109028843E0
:1013700040180521090708821D48008940094001DD
:101380001B490881084600890F21890288430521ED
:10139000C902401816490881254820304882262075
:1013A00088820720C8822948DC38088301204883C6
:1013B000084640881E21884314300D494880FFF7B5
:1013C000A9FE3148056B2878002803D1012002F0DE
:1013D000C9FA07E02D4800880B496039C880002011
:1013E00002F0C0FA70BD0000A0860100087F040072
:1013F0002000005000800040560208004A03080008
:101400004C05540780000040602C00507F7F000096
:10141000AC290000002200500909000000240050FF
:101420002204000030D00000EE1100000025005022
:101430002E02000044200000402800500D950000BE
:1014400002420000E4DC000010920000537800002B
:10145000002A00508B1000009DD50000002600508F
:10146000E7100020ED100020F3100020F9100020FC
:10147000EF10002013110020F110002005120020B1
:1014800000020040780408002002002052040800F6
:1014900070B5EFF31085012080F31088264802F024
:1014A000BBFA0446002D1DD0012080F31088002CCB
:1014B00023D020462038C08B204988421DD1618925
:1014C000208902F0AFFA05000ED021461031A38921
:1014D00062892089A847002806D001280DD002285B
:1014E0000BD105E00020E0E7204602F0A1FA04E07D
:1014F000114821460C3002F0A1FAEFF310840120CC
:1015000080F310880C480068002802D1012002F006
:101510009BFA002C03D0012080F3108870BD0020BE
:10152000FAE710B5BC21064802F094FA05490120FB
:1015300002F096FA10BD0000A805080038830000EC
:10154000040608009114002070B516460D4610469A
:1015500002F08CFA002869D0340A304602F086FA8C
:10156000012812D0A87A1E2811D029460A310E2847
:1015700045D019DC801E030002F07EFA0B255829A5
:10158000582D58315839583D5800022070BD314609
:10159000274802F077FA0021204602F079FA02216A
:1015A000304602F07BFA41E018283CD006DC1028D7
:1015B00019D012282BD0162838D130E0522822D04A
:1015C000D22833D127E0204602F06EFA2EE02046E2
:1015D00002F070FA2AE0204602F072FA26E0204675
:1015E00002F074FA22E0204602F076FA1EE020466D
:1015F00002F078FA1AE0204602F07AFA16E0204665
:1016000002F07CFA12E0204602F07EFA0EE020465C
:1016100002F080FA0AE0204602F082FA06E0204654
:1016200002F084FA02E0204602F086FA002070BD43
:1016300001280000F3B581B001980C460102CA1DD3
:101640000E310223344802F07DFA047001990546F8
:10165000022732488E00002C06D0042C16D0062C0F
:1016600010D0072C3FD108E0815905224968897CB8
:10167000114069708059C77335E0084602F068FA76
:10168000687030E080590F21C1732CE00446805906
:101690004068417C012902D1007E01280FD00198C9
:1016A00002F05CFA01210028A0590BD04268D07DDD
:1016B00000281CD001281AD004280DD00FE00020EB
:1016C00068700DE04068C27D022A01D0042A06D16C
:1016D000007C02280BD102E0107C022807D06F703A
:1016E000A1590320C873284602F03EFAFEBD697076
:1016F000F6E701460A780120042A01D90020704744
:101700004A78002A01D0012AF8D10A79082AF5D8A6
:1017100049790829F2D87047021C00002805080002
:10172000FFB589B00D4600206946059008720B98F8
:10173000000A009002F012FA07460B9802F096F9A0
:1017400000287DD00B982978000A8400764E012964
:101750005ED0042904D0062943D0072963D120E0B4
:10176000687800281BD0305910224068A91C02F06C
:101770004DF9002F06D03159C87B032807D0042823
:1017800008D050E03059C07B032803D04BE00B2039
:10179000C87348E00521009802F0ECF943E001200D
:1017A000B6E03059C07B0E283DD1009802F0D0F948
:1017B000002103E02A18401C9170C0B21028F9D310
:1017C000688A69460883294606A80822143102302F
:1017D00002F01CF906ABAA1C3946009802F0D0F9B9
:1017E00021E03059C07B0F281DD1AA1C0A21009886
:1017F00002F0CCF9002F04D03946009802F0CCF961
:1018000011E000231A463946009802F0CBF90AE0AD
:10181000012F08D10B9802F029F901281CD00028CB
:1018200001D0022005906846007A002811D002AA53
:101830000521009802F0AAF96846027A602000E0CB
:1018400007E002436846027201233946009802F01D
:10185000A9F905980DB0F0BD3059C07B0228E2D13E
:101860006878002851D002210B9802F017F93059FE
:1018700007224068A91C173002F0C8F8E878002851
:1018800004D130594068407C01283AD0009802F0D9
:101890008FF9002837D0297A009802F08FF90028B4
:1018A00033D0009802F090F90121009802F092F9EB
:1018B00000282CD030594068417E00292BD00429C3
:1018C00029D0C17E027D1140C17630594068017F28
:1018D000427D114001776846007A0028A7D130592F
:1018E000022142680098173202F050F930594168DD
:1018F0004031897B002913D004210098FFF79AFE1C
:1019000091E7022004E0062002E0082000E0032026
:10191000694608728BE70021C17630594068D9E7E3
:101920000B21C1737FE7000028050800F8B50646C3
:101930000C4615460127312E77D012DC0C2E75D0BF
:1019400008DC012E20D0022E46D0072E60D00B2EB0
:1019500041D17DE0102E6AD0112E69D0122EF7D120
:10196000DCE0412E6FD008DC322E6DD0352E6CD0ED
:10197000362E6BD0402EEBD145E1422E67D0432E60
:1019800073D0442EE4D19CE10622EE49EE4802F0E9
:1019900027F9002808D00622EB49284602F036F83D
:1019A000062020700020F8BDE84800680078C007D5
:1019B000C00F10D02078062803DA002020700427FA
:1019C00009E00622E14801689831284602F01EF835
:1019D0000620207000278BE1DC48006800680221A7
:1019E000084214D020783E2803DA00202070042713
:1019F0000DE0D6480068427ED44801685A31284636
:101A000002F004F8D1480068407E207000276FE1A2
:101A1000CE48006800680421084213D020780228CC
:101A200007DA0020207004270CE08CE02DE048E06D
:101A30005FE0C6480068817C2970C07C6870022025
:101A40002070002754E1F7E096E0AEE0C3E00AE141
:101A5000BE48006800680821084215D02078202878
:101A600004DA0020207004270EE013E1B748006874
:101A7000C27DB64801681A31284601F0C7FFB34855
:101A80000068C07D2070002732E1B048006800681F
:101A90001021084214D02078202803DA002020707A
:101AA00004270DE0A9480068027EA8480168983123
:101AB000284601F0ABFFA5480068007E2070002793
:101AC00016E1A248006800682021084210D0207862
:101AD000042803DA00202070042709E004229B4830
:101AE0000168091D284601F091FF0420207000279D
:101AF000FEE0964800680068402108420DD020783A
:101B0000012803DA00202070042706E08F480068CF
:101B1000007D2870022020700027E9E08B480068D3
:101B20000068802108420DD02078012803DA0020C7
:101B30002070042706E085480068407D2870022058
:101B400020700027D4E0814800680068FF2101313F
:101B5000084210D02078042803DA002020700427DF
:101B600009E00422794801680C31284601F04EFF53
:101B7000042020700027BBE0744800680068012141
:101B80004902084210D02078042803DA002020708F
:101B9000042709E004226D4801680831284601F055
:101BA00035FF042020700027A2E068480068006824
:101BB0000121890208420DD02078012803DA002093
:101BC0002070042706E061480068807D28700120AD
:101BD000207000278CE05D48006800680121C90280
:101BE00008420FD02078022803DA00202070042752
:101BF00008E056480068017C2970407C687002202B
:101C00002070002774E05148006800680121090332
:101C1000084210D02078022803DA00202070042720
:101C200009E04A4800688230017F2970407F68706F
:101C30000220207000275BE0444800680068012112
:101C4000490308420ED02078012803DA00202070D2
:101C5000042707E03D480068A03000782870012084
:101C60002070002744E0394800680068012189039A
:101C700008420ED02078012803DA002020700427C3
:101C800007E032480068A1300078287001202070F9
:101C900000272DE02D48006800680121C903084293
:101CA0000ED02078012803DA00202070042707E0F6
:101CB00026480068A2300078287001202070002794
:101CC00016E02248006800680121090408420ED08D
:101CD0002078012803DA00202070042707E01B4841
:101CE0000068A3300078287001202070002700BF12
:101CF00000BF384657E670B5154D164CA006008853
:101D0000802188438030A106088000BF12484089A6
:101D100008210840082803D028466D1E0028F5D168
:101D200001200E49086006222146074801F06EFE98
:101D300005200007008880218843052109070880C5
:101D400070BD0000383E0300C07F0020C0060800C0
:101D5000A0860100D47F04002000005000800040D5
:101D600070B50546E802642101F032FE0446002CFD
:101D700000D0641E204670BDF1B586B07948006879
:101D800001F034FF0446784A784B01F035FF0191A9
:101D90000090069801F02AFF0646019B009A01F088
:101DA0002BFF0391029001F063F90490049800283E
:101DB00002D00498401E0490049807B0F0BDF8B516
:101DC00000256B4840690090FEF7A9FE002803D16A
:101DD00068480079022801D10020009000BF6648C1
:101DE0000078002819D000BF0121644AD16300BFE8
:101DF00000BF00BF00BF6149C96B0029FAD100BF15
:101E000001218907C86900BF1921C901884200D290
:101E1000A5E00021584A117000BF01F0F3FE002830
:101E200000D19CE001255348C078002800D196E0FD
:101E300005200007808AC007C00F01D004258EE06E
:101E400001F09CFD002800D089E04D4800683F2843
:101E500006D148480079002802D145480069009021
:101E600044488178684601F0D3FE002800D176E02E
:101E700040488178684601F093FD002800D16EE06B
:101E800001F0CCFE002800D169E004253D4800683F
:101E9000AA2801D13E2400E0972401208007C06BCE
:101EA000800A8002401C01218907C8630846C06B74
:101EB00035490840A102084301218907C863084643
:101EC000C06BC002C00A091240180902C8632D483D
:101ED000006800280FD10098FFF742FF064625480A
:101EE0000079002801D0012000E0002001463046A2
:101EF00001F09AFE12E023480068AA280ED100984B
:101F0000FFF73AFF06461B480079002801D0012060
:101F100000E000200146304601F086FE1B49C86AF9
:101F2000804700BF00BF01218907086BC91301402A
:101F3000C90B0029F6D001F07DFE01F081FE00BF43
:101F400013480068FF2101310842F9D0052000073D
:101F500000898021884305210907088100BF00BF4F
:101F60002846F8BDB47F00207B14AE47E17A443F99
:101F7000A0020020C6060800A87F0020C000004084
:101F800060010020B07F0020FF03E0FF1C07080075
:101F90000002004008B50020009008205749088042
:101FA00005200007008830218843303005210907CB
:101FB00008800846008880088000C01C088002E075
:101FC00000BF00BF00BF05200007808A80210840B5
:101FD000C011F5D005200007408980088000052148
:101FE00009074881464840884008400044494880E5
:101FF0000520000700883021884305210907088053
:1020000008460088800880000880FEF733FE05201F
:102010000007008980218843803005210907088155
:102020000846008A0421884305210907088200BF69
:1020300005200007808A02210842F9D003E00098B9
:10204000002800D00CE02F48006801210905084055
:10205000000DF4D188020069042108408008EED008
:1020600000BF01F0F3FD01F0F7FD08BD10B501F070
:10207000F9FD05200007408A8021884305210907D2
:1020800048821E480089400840001C4908811E48BB
:1020900000683F2801D101F0EBFD01208007806935
:1020A00004218843001D0907886101F0E7FD1748F6
:1020B0000068AA2802D11420FEF7E4FE10BD70B516
:1020C000134800888406A40E0E4846680E48C030A7
:1020D000056B2878002802D1204601F0D5FD0D4877
:1020E0000089FF2101310840001205D080200642FE
:1020F00002D0204601F0CEFD70BD0000003300503C
:10210000200000500002004060010020B07F00204D
:1021100000200050002C005010B50C213E4801F06A
:10212000BFFD01203C49C870087100F055FA3B49D9
:10213000322001F0BBFD0021322001F0AFFC00F0A5
:10214000BAF810BD10B5002400F00BFB0446204681
:1021500010BD10B530488078000201460E310223D0
:1021600032222F4801F0EEFC04460120207013209B
:102170006070204601F0F8FC10BD70B50546264899
:102180008078000201460E312C2332222448801E22
:1021900001F0D8FC044628200555002129200155CE
:1021A000204601F0E1FC70BD10B5502332220D2114
:1021B0001C4801F0C7FC0446204600F03DFA2046CA
:1021C00001F0D2FC0221322001F068FC10BD10B5F4
:1021D000012332220D2113480B3801F0B3FC0446D1
:1021E00002202070204601F0BFFC10BD10B500F0A9
:1021F000CBFA10BD70B505460E4614460A48844217
:1022000001DD044602E0002C00D1012422463146C3
:10221000284601F051FD70BDC67F0020A048002077
:10222000043800000E3400003075000010B501F0D5
:1022300049FD0446344901F04BFD3448081810BDEF
:1022400070B505463248857600240EE001F03AFD6F
:102250000646C017000E801900120002301AC1B2E3
:102260002B4810300155601CC4B2082CEEDB002056
:10227000044612E01021091BA94201DD002107E0FC
:1022800001F020FDC117090E091809120902411AAF
:102290001F4A1155601CC0B20446102CEADB01F045
:1022A00011FD0646C017000C801900140004301AF6
:1022B0001749088370BD10B52421154801F0F0FCC2
:1022C00000F08BF910BD10B512488078000201466D
:1022D0000E3102233222104801F034FC04460D2056
:1022E00020700B4820308078002800D102E0084898
:1022F000203080786070204601F036FC03213220C7
:1023000001F0CCFB10BD0000A0BB0D00A0860100B9
:10231000D27F0020C67F00201A380000F8B507469B
:102320000C4615461E462078030001F0A5FB080563
:1023300024242409181C2024204600F050FA1BE015
:102340006078012803D1204600F04AFA06E0607860
:10235000022803D12946304600F04CFA0CE0204612
:1023600000F03FFA08E0204600F03CFA04E0204686
:1023700000F039FA00E000BF00BF0020F8BDF8B55A
:1023800005460C4616461F462078801E030001F0C5
:1023900073FB06041A2321222023A1783748817079
:1023A0008078C007C00F0BD03548407933492039B9
:1023B000C87606223249891D3048001F01F026FBED
:1023C00000F012FA09E0FFF7C4FE00212B488170EB
:1023D00003E002E001E000E000BF00BF0020F8BD24
:1023E000F8B50D4617461E4612233A463146254893
:1023F00001F0A8FB0446284600F0F7F9002801D1B7
:10240000207027E01D488078C007C00F20D0082228
:10241000A91C1A48103801F0E3FB002818D117480E
:102420002038008B2988884212D10120207013485F
:102430002038807E6074102210492039601C01F021
:10244000E5FA0E498878FFF798FE00F0D2F901E02E
:1024500000202070204601F087FB2078002801D161
:10246000FFF777FE0020F8BDF8B504460D46164686
:102470001F4600F0BDF90020F8BD0000F27F0020EB
:10248000C67F002018380000F8B506460F461446EF
:10249000204601F0EBFA00280CD1012332220D2155
:1024A0004B4801F04FFB054601202870284601F0FB
:1024B0005BFB00BF0020F8BDF8B506460C4615468C
:1024C000207803281ED004DC012807D0022828D158
:1024D00026E00E281CD00F2823D11DE060780028AC
:1024E0000FD1222332220D213948801C01F02AFB12
:1024F00007463946284600F048F9384601F034FBD3
:1025000000BF0FE06078002801D100F054F909E025
:10251000607800F05EF905E0607800F05BF901E0BA
:1025200000BF00BF00BF0020F8BDF8B507460C464D
:1025300015461E46284601F099FA022806D13004B5
:10254000000E24498870204600F048F80020F8BDAD
:10255000F8B506460C4615461F4620780A2812D1C3
:10256000284601F083FA04280CD16078002803D0B3
:10257000607800F02CF905E00521284601F08EFA7C
:1025800000F026F900E000BF00BF0020F8BDF8B55C
:1025900006460D4614461F462946204600F0D1F84F
:1025A0000020F8BDF8B506460C4615461F462846DD
:1025B00001F05CFA012808D12078002805D1FFF746
:1025C000C1FD002801D000F006F90020F8BD000090
:1025D00002340000C67F0020704770473EB50446B5
:1025E000FA488078FF2824D00521322001F056FADD
:1025F0002088F6490880607A4871062221460A310F
:10260000F248801D01F002FAF1498878FFF7B5FD24
:10261000EE48C07AED49897AEC4A527A00920191EB
:102620000290EA48037AC2798179EAA000F0F5FACB
:1026300001E0FFF7B9FD3EBD70B590B00446F0482B
:10264000007820700020607019204001A081E08196
:1026500007202074EB48007860741C21E1741F216E
:1026600030200155E84801F039FB002809D0E7483F
:102670000178E1740278E6492046143001F0C6F989
:1026800007E00021E174E27CE2A12046143001F071
:10269000BDF9DD4801F022FB00280BD0DF480178AE
:1026A00030200155DD480278DD492046143001F024
:1026B000ADF908E0002130200155025DD9A1204686
:1026C000313001F0A3F9E07C1C21081A801E46B2CB
:1026D000002E34DDD44801F001FB002809D0D24897
:1026E00001F0FCFAC5B22A46CF49684601F0FCFA6F
:1026F00005E010252A46CDA1684601F0F5FA002D27
:102700001DDD28463146884201D2024600E00A46D5
:10271000D5B2681CC1B2E27C204614308154092233
:10272000E17C491C4254E27C921C014650182A4626
:10273000694601F06BF9E17CA81C0818E07410B040
:1027400070BD70B505460E46284601F08FF9044667
:10275000032C03D0052C01D0042C01D1FFF724FD5C
:1027600070BD00200121B64A11709849C97801292D
:1027700008DA00BF00BF00BF9449C978491C934ADA
:10278000D17000E001207047704703220A700A22CE
:102790004A7000224A820A754A751722CA820822A4
:1027A0000A8310224A8300228A836422CA83002378
:1027B00020225354704710B50121322001F06EF9E8
:1027C000FFF7C0FC002801D0FFF7EEFC10BD7047FA
:1027D00070477047704710B5FFF7E6FC10BD7047B3
:1027E0007047704770477047704701460120704737
:1027F000704770477047F0B58FB00646282105A88E
:1028000001F028F9002104910391029102A803A983
:1028100004AB05AA009101908AA1304600F024FA89
:102820000746042F7ED18EA17F4800F013FA05A938
:10283000754800F00FFA002078490870784876A1B2
:102840000978017068460821415600918389028AFF
:1028500005A9864800F0E1F900206C4908700D20B8
:10286000674908700320674908701A216748027891
:102870000078401C654B187065488154FF2118464C
:1028800002780078401C1870614881544C21184629
:1028900002780078401C18705D4881540021184669
:1028A00002780078401C187059488154022218465A
:1028B00001780078401C187055484254152118467C
:1028C00002780078401C187051488154002425E09B
:1028D00005A8005D2D2803D005A8005D202800D1A3
:1028E0001BE0002001902046641C05A9095C684695
:1028F000017105A8015D68464171002181711022B6
:1029000001A800F0E7FAC5B2404801780078401C01
:102910003E4A10703E48455400BF641C05A801F0B3
:10292000DDF900E036E0A042D2D86846008A001205
:1029300036490A780978491C344B1970344988544F
:102940006846008AC1B2184602780078401C1870A8
:102950002F48815468468089001219460A78097800
:10296000491C19702A49885468468089C1B21846A2
:1029700002780078401C1870254881546846017A16
:10298000184602780078401C1870214881540120B4
:102990000FB0F0BD36A000F040F90020F8E730B5E8
:1029A00099B03A4801680068401C384A1060022912
:1029B00002D137A000F031F900226421684600F00E
:1029C00005F90446002C69DD214668E0C67F002039
:1029D000F27F0020436F6E6E656374696F6E2066D0
:1029E000726F6D3A202530583A2530583A253058C4
:1029F0003A2530583A2530583A2530580D0A00000B
:102A00000C4A00200D4A00203090002079900020D0
:102A10005990002007010318000000005890002082
:102A20004490002002FF000020900020494D502DCE
:102A3000444131343538302D5445535400000000A2
:102A40008091002049424541434F4E2C255B5E2C2E
:102A50005D2C2568782C2568782C25686864000032
:102A6000494D50424541434F4E0000000849002067
:102A700050617273696E6720636F6D6D616E642063
:102A80006661696C65642E0D0A000000104A002022
:102A90000D0A426F6F7465642E0D0A003FE02AA094
:102AA00000F0BBF8002537E06846405D0D2803D0F4
:102AB0006846405D002814D12848006800282ADDB7
:102AC000274928A000F0A9F8244801682448FFF706
:102AD00092FE002801D0FFF767FB00201F49086025
:102AE00019E06846415D1D4802680068401C1B4BA8
:102AF00018601B48815418460068FF2806DD1DA099
:102B000000F08BF800201549086007E00020144908
:102B1000124A126888546D1CA542C5DB00BF1A48D2
:102B20000078002804D00721002001F02DF903E0EF
:102B30000721002001F058F913480078012148408E
:102B40001149087019B030BD526561643A2025649E
:102B50002063686172730D0A000000007C91002000
:102B60007A90002052656365697665643A20257322
:102B70000D0A000044697363617264696E672062C4
:102B800075666665720D0A00144A0020052000076C
:102B90008088802188438030052109078880802033
:102BA0002B498881002088800920088003208881A3
:102BB0000846008A4021884325490882012008816F
:102BC00008468088400840008880704770B50346FA
:102BD000002008E01E4C2488E6B20446401C1E5526
:102BE000884200D304E01A4CA48AE407E40FF1D130
:102BF00000BF70BD70B50346144600200AE01A5CA1
:102C000000BF134DAD8A20263542FAD0D5B2104E02
:102C10003580401C8842F2D370BD0FB410B5C2B0ED
:102C200045A8019002A8019A449901F0A5F9002055
:102C3000019002A801F052F804460022214602A8A1
:102C4000FFF7D8FF42B010BC08BC04B01847000022
:102C50000010005003460A780270491C401C002AEC
:102C6000F9D11846704700000FB400B58DB0099037
:102C70000B9010A900200091C0430A9000200C90F6
:102C800006480690064807906A4609A80F9900F082
:102C90005FFA0DB008BC04B0184700007131002085
:102CA00091310020FFB50027FF4383B000205C680E
:102CB00001909E681D46A9697F1C04988847009072
:102CC000296A88470028F6D10098401C0CD00320C0
:102CD00040028443002E19DD600614D500982B288D
:102CE00009D02D280FD103E00020C04307B0F0BD6C
:102CF000012080020443A9697F1C04988847761E3E
:102D00000090002E02DD0098302803D0059800289E
:102D100025D035E0012040020443761EA9697F1CBE
:102D2000049888470090002E03DD782805D05828A5
:102D300003D00598002810D022E00598002801D083
:102D400010281DD1012040028443761EA9697F1CF2
:102D5000049888470090102002E0082000E00A2034
:102D600005900DE0012149020C43059A0199761E58
:102D7000514308180190A9697F1C04988847009066
:102D8000002E05DD0599009800F0CDF90028E9DA5C
:102D9000E96904988847A00502D40120C043A5E74B
:102DA000E00722D1600611D56005019800D54042A8
:102DB00029680A1D2A600968220501D5087014E0F7
:102DC000220701D5088010E008600EE02868011D88
:102DD00029600068210502D50199017005E02107ED
:102DE000019901D5018000E0016038467EE7FFB51A
:102DF000002083B00090506801909169144600262D
:102E000097680498884705460C990698084305D0AA
:102E100009E0A169761C049888470546216A28467E
:102E200088470028F5D1681C03D00198C00704D05A
:102E300017E00020C04307B0F0BD2068011D2160ED
:102E4000006800900DE00198C00704D1009805705B
:102E50000098401C00907F1EA169761C049888474A
:102E60000546002F1CDD681C1AD0069800280FD0DC
:102E7000E817C00E401941118A00069940095118FF
:102E800040012A1A0968012090400142DBD107E085
:102E90000C980028D7D1216A284688470028D2D02C
:102EA000E1690498884701980C99C007C00F08434E
:102EB00002D1009800210170A068B84204DD0C988E
:102EC000002804D0002F02D00120C043B3E73046D1
:102ED000B1E70000F7B5009C0F4600262578641C7A
:102EE000002D05D000F012F90068405DC007F5D153
:102EF0002B2D02D02D2D18D0641E39462046029A63
:102F000000F058F9002F04D03968A14201D100998E
:102F100039607105022400290BDA4042002803DDE4
:102F200001F03CF80460A007FEBD012080020643CA
:102F3000E3E70028F8DA01F031F804600048FEBD4C
:102F4000FFFFFF7F024670B54A40D30FDB0740000A
:102F50002DD04A002AD0010E140E091900021202C7
:102F6000400A520A8418E50104465443000A120A32
:102F70002E045043A4194219200CC543AA18120C60
:102F800001257F39521CAD0352191204240400D0CC
:102F9000521C104301D44000491EC2B20C06C009A5
:102FA0002018401C4008802A02D003E0002070BD99
:102FB00040084000002900DA0020184370BD70B5B9
:102FC00002464A40D50F40004A00ED07400852082B
:102FD000002814D0002A12D0C40DD30D41020120C4
:102FE000C0055202490A520AE41A091812187D341F
:102FF000914201D3641C00E04900002C01DA00205A
:1030000070BD0023914201D3891A0343400849004F
:103010000028F7D100290AD0914202D10121C90725
:1030200005E0914201D2012101E00121C943E005FF
:10303000C018401900F011F970BD10B50022962398
:10304000114600F012F910BD410040020122400A71
:10305000D205090E80187F2901DA002070479629D1
:1030600003DC9622511AC840704796398840704751
:103070004A0009030123090B1B051943094B10B52D
:10308000520D9A4201DA002010BD064B34339A42A9
:1030900003DC9A1A00F02EFE10BD03495118884037
:1030A00010BD0000FF030000CDFBFFFFF0B51FB413
:1030B0000646002082B005464024019100901BE0A6
:1030C000019922460F46304600F014FE049A059BF3
:1030D000801A994110D310461946224600F010FE7E
:1030E000361A8F410197224601200021009F00F0EF
:1030F00007FE38184D4100902046641E0028DFDC92
:10310000019B00982946324607B0F0BD0048704741
:10311000D849002010B50446FFF7F8FF0068005DAD
:10312000C007C00F10BD3A2800D230382023024615
:103130009A43412A01D310463738884201D30020F0
:10314000C0437047026813785118016018467047F1
:1031500010B5D16004495161044911620021116127
:10316000114600F041FA10BD453100201531002014
:103170004268002A08D001680B78491C002B03D054
:10318000521E06C0184670470121C160881E704754
:103190004268002A0BD0C3680168002B07D18368FE
:1031A0008B4204D0491E521C06C0002070470020EC
:1031B000C0437047F7B582B0029C00272078641C9A
:1031C00015460197302802D0002D15D015E0207843
:1031D0000127641C782804D0582802D0002D09D07B
:1031E0000BE0002D01D0102D07D1002710252078ED
:1031F000641C02E0082500E00A250026009610E085
:103200000099012769430818020C294680B27143CE
:1032100000908E183804864201D301200190207856
:10322000641C2946FFF77FFF0028E9DA039800288D
:1032300005D0002F01D0641E00E0029C04600198BC
:10324000002806D000F0AAFE02210160C81E05B0C9
:10325000F0BD009930040843F9E7002904DA401C66
:10326000490001D140084000704770B40024050CAB
:1032700005D11024000402D1002922D01124050E0A
:1032800001D108340002050F01D1241D0001850F72
:1032900001D1A41C8000002801DB641C400000292F
:1032A00008D020252E1B0D46F540A14000D001215D
:1032B000294308431B1B0106DB1D000A002B02DA11
:1032C000002070BC7047DB05181880180029F8DA58
:1032D000401C4900F5D170BC400840007047000018
:1032E000F0B507460846584087B0C00F0490480024
:1032F0000E46590040084908BC1A884105D2384694
:1033000031461E4617460B460246580040081043F9
:1033100003D13846314607B0F0BD300D039040056B
:103320005900400D490D0590401A029040286DDA71
:1033300018030121000B090508430190049800922D
:10334000002805D001995242002088410092019046
:10335000029840210A1A0199009800F0D1FC054614
:103360000C46684607C800F02BF9C0197141039A52
:103370000E0D0023D71756401A467A40164340D008
:10338000049A002A29D0029A012A039A11DC120514
:10339000C01A914101263605001C7141D20F059ECD
:1033A000D2070093019202962A46234600F0AEFC13
:1033B000B1E71605224A0F46B218C01AB7410121DB
:1033C0000905001C4F4100187F411146181879412A
:1033D000E20F10436D19644113E0E2076D081543D5
:1033E0006408C2071443039A01261205C01A9141CA
:1033F0003605001C7141CE07400830434908C0180B
:1034000051412A46234600F087FC84E704980122B4
:103410004000C117121A00238B4104983146C4178B
:10342000381AA141EFE730B40124E407634030BC0F
:1034300056E730B40124E407614030BC50E7000097
:103440000000E0FFF0B50C465C4085B0E40FE407F7
:1034500003944C000026640859009446490802462B
:103460000296224321D062460A431ED06200570DC5
:103470004A000E032303550D012402462C4924055E
:10348000781B1B0B360B40182343264361460090E4
:103490001C46501AB44103D30098401C009002E02F
:1034A000921800985B41002803DA0020014605B01D
:1034B000F0BD0020012109050746864611E064465B
:1034C0001D46141BB54106D36546521BB3417446D5
:1034D00007430C43A646CD074008490828439218E5
:1034E0005B4105460D43EAD11046184313D06046B0
:1034F000194650407140084303D100220123DB07E5
:1035000009E06046101AB34102D20122002302E012
:103510000122D2435310009874460105381C6141C2
:10352000029C039D0019694100F0F6FBBFE7000013
:10353000FD0300004A0009030123090B1B05194381
:103540000A4B10B5520D9A4202DA0020014610BD16
:10355000064B34339A4203DC9A1A00F0CBFB10BDC1
:10356000034BD21800F0CCFB10BD0000FF0300009D
:10357000CDFBFFFF10B5002904DB0124E407404226
:103580008C412146002B04DB1C460123DB07524201
:10359000A341994200D1904210BD0000064C012584
:1035A000064E05E02046E36807C82B4398471034D1
:1035B000B442F7D3FCF748FFDC4900200C4A002056
:1035C00010B5202A06DBCB170846203A1041C11758
:1035D0000B4306E00B461341D0402024A21A914031
:1035E0000843194610BD0000F3B58DB000200A90C5
:1035F00001200B90002608460C300C4609906269A9
:1036000001210998904705002ED0252D2DD0216A43
:103610008847002818D06269012109989047216ADB
:1036200088470028F7D1411E62690998904700E059
:10363000761CA1690D988847216A88470028F7D130
:10364000E1690D988847DAE7A1690D988847074630
:10365000A84201D1761CD2E7E1690D9888477F1C0A
:1036600002D10A98002877D046E1002762693D46DA
:103670003946099890472A280CD162690121099896
:103680009047012506E00A214F433F18303FEBD415
:10369000102005436269012109989047014630399D
:1036A0000A2903D29A498F42DEDCECE7E90600D40E
:1036B000984F6C280AD04C2810D0682824D06A284B
:1036C0002ED074280CD07A280AD00DE0626901212E
:1036D000099890476C2823D004211CE02020054342
:1036E0006269012109989047A760656065284FD0FD
:1036F00026DC582839D01ADC452849D012DC252888
:1037000034D04128B0D143E0626901210998904743
:10371000682802D008210D43E6E70120C002DEE759
:103720000220DCE7462833D047282CD130E05B2844
:103730007BD061282CD0632877D0642823D15EE029
:103740006F284CD009DC662822D0672820D0692851
:1037500026D06E2817D12EE0CAE070284AD07328F0
:103760006CD075284BD078280DD150E0A1690D9808
:1037700088470546252800D16CE7E1690D98884700
:103780006D1C00D16DE7B7E00A2248E00A224FE045
:10379000012023466A46C0430D99C046C046A0E0BA
:1037A0002846402108436060A807234601D500222F
:1037B00035E000223CE02068011D216000682905F9
:1037C00001D506701BE7290701D5068017E7A90771
:1037D00003D5F1170660416011E706600FE7284640
:1037E000402108436060A807234601D5082216E05F
:1037F00008221DE0484928460840606016E0284637
:10380000402108436060A8072346BFD5BCE728468F
:10381000402108436060A80708D5234610220120F4
:10382000C0430D99C046C0465BE007E02346102226
:103830000120C0430D99FFF735FA52E000210C91A9
:103840000B460091632802D05B2807D043E0E806CE
:1038500001D40120A060012000903CE062690121B8
:10386000099890475E2805D101200C9001466269B5
:10387000099890472169002906D10B4601AA8F00BB
:10388000491CD3510829FADB002835D021690029C9
:103890000ED1C117C90E09184A11930001AA9A182E
:1038A00049094901411A0120136888400343136004
:1038B00062690121099890475D28E5D10C9800289C
:1038C00008D0002001AB81005A58401CD2435A5006
:1038D0000828F8DB01AB01202246C0430D99FFF711
:1038E00086FA00280ADA401C06D10B98002803D07B
:1038F0000020C0430FB0F0BD0A98FBE7E90702D1F2
:103900000A99491C0A91361800200B9077E60000AE
:10391000CCCCCC0CFFFFFF7FF1F7FFFF03B40148D5
:10392000019001BD3968020003B40148019001BD56
:103930002F2F030003B40148019001BD551B020065
:1039400003B40148019001BD0F3B030003B40148DB
:10395000019001BDCF2B030003B40148019001BDCC
:10396000CB2C030003B40148019001BD0990020073
:1039700003B40148019001BD1F21020003B40148B6
:10398000019001BDC12D030003B40148019001BDA8
:103990000921030003B40148019001BDC92D0300B2
:1039A00003B40148019001BD2B69020003B4014832
:1039B000019001BDEB31030003B40148019001BD4A
:1039C0003D32030003B40148019001BDD72103003B
:1039D00003B40148019001BDA73A030003B40148B4
:1039E000019001BD938F020003B40148019001BD15
:1039F000CD8C020003B40148019001BD418F02004B
:103A000003B40148019001BD2768020003B40148D6
:103A1000019001BD213B030003B40148019001BDA9
:103A2000BF22020003B40148019001BDEB26030050
:103A300003B40148019001BD3524030003B40148DB
:103A4000019001BD2F22020003B40148019001BD85
:103A5000DD20030003B40148019001BD533B030086
:103A600003B40148019001BD9D20030003B4014847
:103A7000019001BDB326030003B40148019001BDCC
:103A8000FD3D030003B40148019001BDA5280300DA
:103A900003B40148019001BDD5AF020003B4014851
:103AA000019001BD3126030003B40148019001BD1E
:103AB000A1A5020003B40148019001BDE3A50200E5
:103AC00003B40148019001BD87A8020003B4014876
:103AD000019001BDA7A9020003B40148019001BDF6
:103AE00093AA020003B40148019001BD95AB020006
:103AF00003B40148019001BDF9AB020003B40148D1
:103B0000019001BD69AC020003B40148019001BD00
:103B100017AD020003B40148019001BD77AD02006A
:103B200003B40148019001BDF1AD020003B40148A6
:103B3000019001BD85AE020003B40148019001BDB2
:103B400011AF020003B40148019001BDB12303008D
:103B500003B40148019001BD49E5020003B40148E6
:103B6000019001BDF9E3020003B40148019001BDD9
:103B7000E123030003B40148019001BD4BCD0200D5
:103B800003B40148019001BD99D1020003B401487A
:103B9000019001BDABD0020003B40148019001BD0A
:103BA00069D0020003B40148019001BD77CF020043
:103BB00003B40148019001BD01CC020003B40148E7
:103BC000019001BD29CC020003B40148019001BD60
:103BD00015D2020003B40148019001BD8DD202004C
:103BE00003B40148019001BD773B030003B40148D1
:103BF000019001BD893C030003B40148019001BD5F
:103C0000913B030003B40148019001BD79200300FA
:103C100003B40148019001BD2129030003B4014808
:103C2000019001BDD990020003B40148019001BD8B
:103C3000C768020003B40148019001BD0D2C0300C8
:103C400003B40148019001BDB9C7020003B40148A3
:103C5000019001BD231D020003B40148019001BD84
:103C6000C32C030003B40148019001BD652C03007F
:103C700003B40148019001BDF793020003B4014869
:103C8000019001BDDB2E030003B40148019001BD8A
:103C9000038D020003B40148019001BDCF8F0200E3
:103CA00003B40148019001BD533B030003B4014834
:103CB000019001BD8725030003B40148019001BDB7
:103CC0002528030003B40148019001BDFD3A03001B
:103CD00003B40148019001BDD33A030003B4014885
:103CE000019001BD693B030003B40148019001BD8F
:103CF000213B030003B40148019001BDAD3D030029
:103D000003B40148019001BD8D3D030003B4014897
:103D1000019001BDE73C030003B40148019001BDDF
:103D2000CD3C0300FFB583B006460F463A4601245A
:103D3000002520462946FFF7E3FF3201019102905A
:103D4000FFF7DEFF0F4B1A685B6810401940002335
:103D500058405940084300D100BE0C98002804D0B8
:103D60003946304600F010F803E03946304600F09E
:103D70003BF839463046069B059A00F065F807B0D7
:103D8000F0BD0000A07F0020F0B585B004460D46D0
:103D90002A460126002730463946FFF7B1FF2201A7
:103DA00002910390FFF7ACFF0D4B1A685B6810405F
:103DB0001940002358405940084300D100BE032C4D
:103DC00000D1042460010749401801900198801C2B
:103DD00000900120A84081B20098018005B0F0BD9C
:103DE000A07F002000300050F0B585B004460D469D
:103DF0002A460126002730463946FFF781FF220177
:103E000002910390FFF77CFF0D4B1A685B6810402E
:103E10001940002358405940084300D100BE032CEC
:103E200000D1042460010749401801900198001D49
:103E300000900120A84081B20098018005B0F0BD3B
:103E4000A07F002000300050FFB585B004460D462D
:103E50002A460126002730463946FFF751FF220146
:103E600003910490FFF74CFF0E4B1A685B681040FB
:103E70001940002358405940084300D100BE032C8C
:103E800000D104246001084940180290690002989A
:103E9000801D081801900899079801430198018036
:103EA00009B0F0BDA07F002000300050F0B585B013
:103EB00000240CE0002507E00021282060432B4A65
:103EC0008018AA0081506D1C0A2DF5DB641C042C9F
:103ED000F0DBFCF769FE0021254A116051600024E7
:103EE00040E000253AE00120A84080B20290600046
:103EF0002049085A0299084200D131E02820604345
:103F00001A494018A9004058401C03D1019400955B
:103F100000BE00BF2820604314494018A900405843
:103F2000002800D119E02820604310494018A9005A
:103F30004658F7172A4630463946FFF7E1FE220178
:103F400003910490FFF7DCFE094B1A685B6810438D
:103F50001943074A1060516000BF6D1C0A2DC2DB77
:103F600000BF641C042CBCDB05B0F0BD007F00204A
:103F7000A07F00209648002037B514460846064B1F
:103F80006A46214600F0CAF804466946002000F05F
:103F900067FC20463EBD0000614800200048704795
:103FA000184A002002E008C8121F08C1002AFAD1EE
:103FB00070477047002001E001C1121F002AFBD1A9
:103FC00070470000F0B51FB484B007980699020D41
:103FD00001430FD10F98012449A3012807D0049869
:103FE0000F9A84600360C260416009B0F0BD0E9812
:103FF000C143F4E7434844491018484305140F9857
:1040000001280E980BD0281A401C00243F4E40492E
:10401000009401910290002803DA474216E04042E2
:10402000F3E7074612E0F80707D022463346019926
:104030000098FFF7E1FD01910090224633461046BB
:104040001946FFF7D9FD04460E467F10002FEAD12E
:104050000298019B0028009A0799069802DAFFF758
:10406000CBFD01E0FFF7EEF904460E460022294B96
:10407000FFF780FA03D80020C043014607E0002282
:10408000254B20463146FFF72BF9FFF753FA102452
:1040900009E0002C0ADB0A220023FFF707F8059B42
:1040A00030321A55641E02460A43F2D1641C1122B2
:1040B000059B121B1C190F9B012B08D001230843E1
:1040C00002D10E9882420DDD00236D1C0EE00843E4
:1040D00003D10E98151A6D1E0AE011200E900020D3
:1040E0000F908CE7824201DA00236D1E002B86D0F0
:1040F00004980F99456004608260C16075E7000014
:104100003000000001FCFFFF104D000000002440C3
:104110000000F03F0000F0430000E03FFFB597B023
:10412000064600251FE2252879D10024F9492746B3
:10413000761C049432780120203A904002460A42CC
:1041400002D00443761CF5E730782A280ED00222EC
:10415000307801463039092916D804990A23594381
:10416000303940181443761C0490F1E7189802C8BF
:1041700004911890002904DA0120400304434842C6
:10418000049002200443761C30782E2814D1042099
:104190000443761C30782A2809D11898761C80C8E8
:1041A000189009E00A214F43303FC719761C307838
:1041B000014630390929F5D930786C2810D006DC51
:1041C0004C281AD068280ED06A2817D104E0742829
:1041D00013D07A2812D110E00120400504430CE0EE
:1041E0000121090501E0032109050C437178814291
:1041F00003D10120761C00052418761C307811901C
:1042000066280BD013DC58287ED009DC00287CD02F
:104210004528F6D04628F4D047281AD1AAE118E05C
:10422000632836D0642871D0652812D1A2E17028A5
:104230006DD008DC6728F1D069287CD06E280DD0BD
:104240006F2806D1BDE073282FD0752872D078284A
:104250005AD01A9A199990476D1C83E16002400F59
:10426000022809D003280DD00428189801680DD021
:10427000001D0D60189075E11898EA1702C80D60CE
:104280004A60F7E7189802C80D80F3E7001D0D702B
:10429000F0E718986A460178001D11721890002006
:1042A000507202A80090012005E0189802C81890EA
:1042B00000200091C04361070DD5002101E0019964
:1042C000491C0191B94212DA8142F8DB009A515C33
:1042D0000029F4D10BE0002101E00199491C019172
:1042E0008142FADB019A0099895C0029F5D1019994
:1042F00004981A9B471A21463846199A00F09AFAF0
:104300000199401945180BE051E030E113E050E00D
:10431000009800990078491C00911A9A19999047C1
:104320000198401E0190401CF2D1214638461A9B4C
:10433000199A14E139E00A200021009001916002ED
:10434000410F022907D0189A01CA1892C217944641
:1043500003290AD00CE01898C01DC108C9004A689A
:10436000086808319446189107E000B2C2179446D5
:10437000042902D140B2C1178C46002261469445FF
:1043800006DA0A460021404291418C462D2102E086
:10439000210504D52B216A461173012103E0E107B1
:1043A00001D02021F7E7029151E00A200AE0102015
:1043B00008E0102000900021042004430191082708
:1043C00003E008200021019100906002410F0229C2
:1043D00007D0189A01CA18920022944603290AD0DD
:1043E0000AE01898C01DC108C9004A680868083169
:1043F0009446189103E080B2042900D1C0B2002194
:104400000291210723D51199702928D0009A1021F3
:10441000019B4A401A4309D16146014306D030212D
:104420006A4611731199517302210291009A082171
:10443000019B4A401A430AD16146014301D16107F9
:1044400005D530216A46117301217F1E0291119911
:10445000582909D030A10E910DA90D9112E04021EB
:104460006A4611730121E0E730A1F4E76146019B40
:10447000009AFEF71BFE0E9B8C469B5C0D9A521E0B
:104480000D92137061460143F0D10D9805A9081AE9
:1044900020300190600703D501200004844300E030
:1044A00001270198874201DD381A00E000200199B8
:1044B00000904118029809180498401A0490E003EB
:1044C00006D421461A9B199A049800F0B3F94519AD
:1044D000002706E003A81A9AC05D199990476D1C41
:1044E0007F1C02988742F5DBE0030CD521461A9B1E
:1044F000199A049800F09EF9451904E01A9A3020A0
:10450000199990476D1C0099481E00900029F5DC10
:104510001FE00000092801003031323334353637CE
:1045200038396162636465660000000030313233FF
:10453000343536373839414243444546000000009F
:104540000D980D990078491C0D911A9A1999904768
:104550006D1C0199481E01900029F1DC4CE100F02E
:1045600059F94519761C3078002800D0DBE528463B
:104570001BB0F0BD600700D406271898C01DC10805
:10458000C90048680A680831C30FDB071891190091
:1045900001D09CA108E0210501D59BA104E0E10721
:1045A00001D09AA100E09AA1430011985B081091F4
:1045B00065280CD006DC452809D046281DD04728A0
:1045C00041D141E0662818D067283CD13CE0002169
:1045D000112F01DB112000E0781C0191009008A947
:1045E00011A8FFF7EFFC139905910021119A15927C
:1045F0007F1C12980197009150E00120C0070390A2
:104600000120019008A9009711A8FFF7DBFC139A7D
:10461000149905920022119B009212981593059A05
:104620000192002901D0104602E0791C4018019047
:10463000381A01D5019804E04042401E0090781CD1
:104640000190C01B029043E0012F00DA01270021F6
:10465000112F01DD112000E038460191009008A9DA
:1046600011A8FFF7AFFC13990591119A0021129838
:1046700015920091019721070CD40599B94201DBED
:10468000019900E00191012904DD159A491E515C50
:10469000302906D0B84201DA011D05DA0121029164
:1046A00015E00199491EEDE7002805DC0099411845
:1046B00000910199091A03E0019A411C914200DD21
:1046C00001910099401A401C02900120C0070390FC
:1046D000200706D402990198814202DB0020C043E2
:1046E000029000206946C87707AF0121039803377D
:1046F000C907884224D0022011902B2012900398E1
:1047000000280CDA404203902D20129007E00A2185
:104710000398FFF75DF930317F1E039039701199CE
:10472000481E11900029F2DC03980028EFD1791E71
:10473000129808703078202108404530BF1E38702C
:1047400006A8C01BC01D039010980078002800D058
:104750000120019941180298C017091803980918F7
:104760000498401A401E0490E00306D421461A9B88
:10477000199A049800F05EF84519109800780028FE
:1047800003D01A9A199990476D1CE00323D521464E
:104790001A9B199A049800F04DF845191BE00098EF
:1047A000002807DB00990598884203DD1598405CD6
:1047B000199901E0199930201A9A904700986D1CB8
:1047C000401C00900298401E029004D11A9A2E209C
:1047D000199990476D1C0199481E01900029DEDC53
:1047E00005E038781A9A7F1C199990476D1C039937
:1047F000481E03900029F4DC21461A9B199A04985C
:10480000ADE600002D0000002B000000200000009D
:1048100000000000F8B5044600251E46174688042F
:1048200004D405E039462020B0476D1C641EF9D53C
:104830002846F8BDFFB50446002581B01E46C803D2
:1048400001D5302700E02027880404D505E038464C
:104850000399B0476D1C641EF9D5284605B0F0BD1C
:104860000A68531C0B60107070470000D5040020CC
:104870004915002035160020F316002021170020CE
:104880000101000A04280A040203AA0055032A00B1
:10489000A001FFFF2C01FF003F00FF03FF0100000C
:1048A0000000000000490020F67F00200600010003
:1048B000013400008924002000340000B9240020C5
:1048C0000038000051250020013800002B25002071
:1048D000033800008F25002000C80000A525002017
:1048E000133800001D230020153800007F2300200E
:1048F00017380000E1230020193800006924002047
:10490000B04800200A00000053657420746F2069CD
:10491000426561636F6E207769746820555549441C
:1049200020272573272C206D616A6F722027253080
:104930003458272C20206D696E6F72202725303463
:1049400058272C207478706F7765722027253032B5
:10495000686858270D0A00004040404040404040F1
:104960004041414141414040404040404040404042
:104970004040404040404040050202020202020224
:104980000202020202020202202020202020202017
:104990002020020202020202029090909090901059
:1049A0001010101010101010101010101010101007
:1049B0001010100202020202028888888888880883
:1049C0000808080808080808080808080808080867
:1049D0000808080202020240584900201C4A002030
:1049E000007F0020F8000000B43F00201C4A002097
:1049F0002090002064010000B43F002068070800F8
:104A0000F41108000C1E0000B43F00200E0100004D
:0C4A100001000000010000000000000098
:040000052000044192
:00000001FF
";
}
parse_hexfile(HEXFILE);
//------------------------------------------------------------------------------
function calculateCRC(data, initial=0xFF) {
local crc = initial;
for (local i = 0; i < data.len(); i++) {
crc = crc ^ data[i];
}
return crc;
}
//------------------------------------------------------------------------------
function hexdump(data) {
local dump = "";
foreach (ch in data) {
dump += format("%02X ", ch);
}
if (dump.len() > 0) server.log(dump.slice(0, -1))
}
//------------------------------------------------------------------------------
function send(data) {
/*
local ch, crcin, crcout;
local length = data.len();
local soh = 0x01;
local lsb = (length & 0x00FF);
local msb = (length >> 8) & 0x00FF;
local preamble = format("%c%c%c", soh, lsb, msb);
// Reset the BTLE chip and let it settle
rst.write(1);
while (uart.read() != -1); // Drain the buffer
imp.sleep(0.01);
rst.write(0);
// imp.sleep(0.001);
// Wait for a 0x02 before starting
while (uart.read() != 0x02);
// Send the SOH, LSB and MSB
uart.write(preamble);
uart.flush();
// Wait for an ACK
while (uart.read() != 0x06);
// Send the data
data.seek(0);
uart.write(data);
// Read the CRC
while ((crcin = uart.read()) == -1);
// Send a final ACK
uart.write(0x06);
// Check the CRC
crcout = calculateCRC(data, 0x00);
server.log(format("CRC: %02X == %02X", crcin, crcout))
return true;
*/
const EMPTY = "\x00";
// Prepare the data to send
local preamble_s = "\x70\x50";
local length = data.len() / 4;
local length_s = format("%c%c", (length & 0x00FF), (length >> 8) & 0x00FF);
local crc = calculateCRC(data);
local crc_s = format("%c", crc);
local mode = 0x00; // 8 bit MOSI mode
local mode_s = format("%c", mode);
local send_s = preamble_s + EMPTY + length_s + crc_s + mode_s + EMPTY;
hardware.pin8.configure(DIGITAL_OUT);
hardware.pin8.write(1);
hardware.pin1.configure(DIGITAL_OUT);
hardware.pin1.write(0);
// Reset the BTLE chip and let it settle
rst.write(1);
imp.sleep(0.01);
rst.write(0);
imp.sleep(0.001);
cs_l.write(0);
spi.configure(CLOCK_IDLE_LOW, 2000);
hexdump(spi.writeread(send_s));
spi.write(data);
hexdump(spi.writeread(EMPTY + EMPTY));
cs_l.write(0);
return true;
}
//------------------------------------------------------------------------------
agent.on("burn", function(program) {
server.log("Received program of " + program.len() + " bytes. Memory free: " + imp.getmemoryfree() + " bytes.")
if (send(program)) {
server.log("Programming completed")
agent.send("done", true);
} else {
server.log("Programming failed")
agent.send("done", false);
}
})
//------------------------------------------------------------------------------
rst <- hardware.pinA;
rst.configure(DIGITAL_OUT);
rst.write(1); // Hold until we are ready
cs_l <- hardware.pinB;
cs_l.configure(DIGITAL_OUT);
cs_l.write(1);
spi <- hardware.spi189;
// spi.configure(CLOCK_IDLE_LOW, 2000);
uart <- hardware.uart6E;
hardware.uart6E.configure(57600, 8, PARITY_NONE, 1, NO_CTSRTS, function() {
// server.log(format("0x%02X", hardware.uart6E.read()))
});
server.log("Device booted. Requesting firmware.");
agent.send("ready", true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment