Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Oct 04, 2013
Gene Jones very, very, very close to working
Stripped out Github logic for now.

Data now sent in chunks from the agent to the device; server performs
most of the heavy lifting of decoding the hex, line splits, etc.

Agent code is working.
Device code a little finicky, but very close to working.
67f1349
Gene Jones maybe soon?
Now the code results in no errors being thrown anywhere!

It still doesn't work, and I suspect there is an infinite loop or
something somewhere, but yeah. I should finish this up by the end of the
weekend.
295fe8c
Showing with 222 additions and 321 deletions.
  1. +99 −150 flashChip.c
  2. +123 −171 server.c
View
249 flashChip.c
@@ -1,4 +1,4 @@
-/*
+/*
* Secret Robot
* Reprogram an arduino anywhere!
* Uses an Electric Imp, some hardware, some code, and some magic.
@@ -11,6 +11,21 @@
*released under CC-A 3.0; no guarantee of any kind is made for this code
*/
+//define device constants
+
+//taken from 28.3 and 28.5 in the Atmel AVR doc
+//signature is what we expect the value to be
+//flash size is how many words are present
+//each word is 2 bytes long, so a Flash Size of 1600 is 32 Kb
+targets <- {
+"ATMEGA328P" : {"SIG":"\x1e\x95\x0f", "FLASH_SIZE":16384},
+"ATMEGA328" : {"SIG":"\x1e\x95\x14", "FLASH_SIZE":16384},
+"ATMEGA168A" : {"SIG":"\x1e\x94\x06", "FLASH_SIZE":8192},
+}
+
+imp.configure("8-bit-internet", [], []);
+server.show(format("Signal: %d dBm", imp.rssi()));
+
PROGRAM_SERIAL_SPEED <- 115200; //the baud for UNO programming
//Duemilanove 328P requires 57600, 168P based programm at 19200 baud
@@ -24,204 +39,138 @@ SYNC_CHECK_PROG <- 0x53;
STK_LOAD_ADDRESS <- 0x55;
STK_LEAVE_PROGMODE <- 0x51;
+agent.on("programModeBegin", function(t){
+ server.log("got told to do a program by the agent");
+ prog <- ArduinoProgrammer();
+ //make sure we make it a permanent class to avoid garbage collection until everything is better...
+ prog.programAVR();
+ //deltete prog here, such that it is garage collected...
+});
+
class ArduinoProgrammer {
- constructor(target, hex_info){
+
+ resetPin = hardware.pin7;
+ statusLEDPin = hardware.pin8;
+ progLEDPin = hardware.pin9;
+
attempt = 0; //the programming attempt we are currently on
+
+ constructor(){
//configure hardware for our usage
hardware.pin7.configure(DIGITAL_OUT_OD_PULLUP) //this will be our reset pin
- resetPin = hardware.pin7;
- serial = hardware.uart12.configure(PROGRAM_SERIAL_SPEED, 8, PARITY_NONE, 1, NO_CTSRTS);
- hex_info = hex_info;
- target = target;
+ hardware.pin8.configure(DIGITAL_OUT) //this will be our LED pin
+ hardware.pin9.configure(DIGITAL_OUT) //this will be our LED pin
+
+ hardware.uart12.configure(PROGRAM_SERIAL_SPEED, 8, PARITY_NONE, 1, NO_CTSRTS); //setup the serial lines...
+
+ //blank out the LEDs to start with...
+ progLEDPin.write(0);
+ statusLEDPin.write(0);
+
+ agent.on("next_chunk", program.bindenv(this));
}
function programAVR(){
server.log("Starting AVR programming process now");
try{
resetAVR();
enable_programming();
- verify_signature();
- program();
+ //verify_signature();
+ requestFirstChunk();
server.log("Successfully programmed AVR with new .hex file");
}
catch (error) {
server.log("ERROR. Programming failed due to "+error);
attempt++;
if (attempt<3){
- programAVR(); //attempt to program again, but only if this is our second or less attempt
+ requestFirstChunk(); //attempt to program again, but only if this is our second or less attempt
}
}
}
+ function requestFirstChunk(){
+ agent.send("next_chunk", "please");
+ }
+
function resetAVR(){
+ progLEDPin.write(1); //let the user know a program is in progress
resetPin.write(0); //pull pin7 low to reset the system
imp.sleep(0.25); //and wait .25s to ensure the AVR resets
resetPin.write(1); //
imp.sleep(0.05); //wait 50ms to allow the AVR to wake back up
}
- function send_command(){
- serial.write(command + STK_CRC_EOP);
- serial.flush();
- local b = serial.read();
- response = blob(1);
- while( b!= STK_OK){
- if(b >= 0){
- response.writen(b);
- }
- local b = serial.read();
- }
- return response;
- }
function enable_programming(){
- response = send_command(PROG-ENABLE);
+ response = send_command([STK_ENTER_PROGMODE]);
if (response[2] != STK_OK){
//we expect the third byte recieved to be the same as the second byte we sent; if not, we are not in sync
throw "Error in programming enable: not in sync";
}
+ server.log("arduino ready for programming!");
}
function exit_programming(){
- response = send_command(STK_LEAVE_PROGMODE);
+ response = send_command([STK_LEAVE_PROGMODE]);
if (response[2] != STK_OK){
//we expect the third byte recieved to be the same as the second byte we sent; if not, we are not in sync
throw "Error in programming enable: not in sync";
}
+ progLEDPin.write(0); //let the user know a program is finished
+ agent.send("avr reflash success", "great success!");
}
- function program(){
- extractAddressAndData(hex_info);
- }
-
- function verify_signature(){
- //we need to see if the device signature is correct
- //we DO NOT want to program an ATTiny8 as if it was an ATMega328
- observed_sig = send_command(SIGNATURE_CHECK);
- observed_sig = observed_sig.slice(0, 3);
- if (target.SIG != observed_sig){
- throw "Target device signature was incorrect. Expected "+target.SIG+" but recieved "+observed_sig;
- }
- return 1;
- //everything checked out!
- }
-
-}
-
-//hex, ArduinoProgrammer class are garbage collected after run
-
-//hex can use up signifigant portion of user-memory
-//Max Flash size on an ATMEGA-328P is 34Kb
-//There are 40KB of user-code-RAM; 34Kb/40Kb used by Hex File AND more RAM needed for other aspects of the code
-//I will look into splitting hex into chunks and downloading chunks as needed later
-agent.on("avr firmware change", function (target, hex_info){
- local prog = ArduinoProgrammer(target, hex_info);
- prog.programAVR();
- agent.send("avr reflash success");
- //because this is local, the prog constructor should be garbage collected after this function is ran...
-});
-
-//start hex stuff:
-//This file is for understanding .hex files
-//It has two main functions
-//The first function breaks up the .hex by line breaks
-//The second analyzes each line, and turns the .hex into a binary blob
-
-//http://www.sbprojects.com/knowledge/fileformats/intelhex.php
-
-function splitHex(hexString){
- //split each instruction in the hex File by newline instructions (0x0D0A)
- local lines = String.split(hexString, "\r\n");
- return lines;
-}
-
-function extractAddressAndData(hexString){
- local lines = splitHex(hexString);
- for (local i=0; i<lines.len(); i++){
- local result = understandHex(lines[i]);
- }
-}
-
-function convertHexToInteger(hex){
- //expects a string representing the hexidecimal of a single byte
- if (! len(hex) == 2){
- raise ("Error converting hexadecimal: length incorrect. Expected 2 chars to represent a single byte");
- }
-
- // see http://devwiki.electricimp.com/doku.php?id=webcolor&s[]=hex
- //I basically took the above, and add extra checks
-
- local result = 0;
- local shift = hex.len() * 4;
- for (local d=0; d<hex.len(); d++){
- local digit;
-
- // convert ascii such that it is case insensitive
- if(hex[d] >= 0x61 && hex[d] <= 0x66){ //if the hex digit is greater than or equal to 'a', but less than or greater than 'f'
- digit = hex[d] - 0x57;
- }
- else if(hex[d] >= 0x41 && hex[d] <= 0x41){//if the hex digit is less than or equal to 'A', but less than or greater than 'F'
- digit = hex[d] - 0x37; //shift value downwards by 55 (decimal), such that 'A' = 10 (decimal), and 'F' = 16
+ function program(chunk){
+ statusLEDPin.write(1);
+ local finished = 0;
+ for (local i=0; i<chunk.len(); i++){
+ local progResult = progLine(chunk[i]);
+ if(progResult == "exitProgMode"){
+ finished = 1;
+ break;
+ }
}
- else if (hex[d] >= 0x30 && hex[d] <= 0x39){ //if the digit is greater or equal to 0, but less than or equal to 9
- digit = hex[d] - 0x30; //move the value downwards by 48 (decimal), such that 0 (ascii) represents 0 (integer), and 9 (ascii) represents 9 (integer)
+ statusLEDPin.write(0);
+ if (!finished){
+ agent.send("next_chunk", "please");
}
else{
- raise (format("Error in hexadecimal conversion: value outside of expected ranges (0-9, A-F, a-f). Value was %x", hex[d]));
+ exit_programming();
}
-
- // Accumulate digit
- shift -= 4;
- result += digit << shift;
}
- return result;
-}
-
-function integerToBlob(integer){
- local blob_result = blob(1);
- blob_result.writen(integer, 'b'); //write the integer result as an unsigned 8-bit integer (basically, a single byte)
- return blob_result;
-}
-
-//needs hex to be split by line...
-function understandHex(hexLine){
- //Recall that we come close to the Max RAM on the Imp when programming, so saving the table space is worth it.
- if (!hexLine[0] == ':'){
- raise ("Error: hex format not correct, must contain : on start of each line");
- }
- local byteCount = convertHexToInteger(hexLine.splice(1,2) );
- local address = blob(2);
- address.writen(convertHexToInteger(hexLine.splice(3,4) ), 'b');
- address.writen(convertHexToInteger(hexLine.splice(5,6) ), 'b');
- local recordType = hexLine[8];
- local dataPayload = blob(byteCount);
- for (local i =0; i<byteCount; i++){
- local datum = convertHexToInteger(hexLine.splice(8 + i, 9 + i) );
- dataPayload.writen(datum, 'b');
- }
- //local checksum = convertHexToInteger(hexLine[byteCount + 10: byteCount + 11]);
- //I am not checking the checksum, HTTPS checksum already ensures integrity
- //if the checksum fails, we have bigger problems, so let's just assume it would have never failed
- if (recordType = '0'){
- //record is data, program chip...
- send_command(STK_LOAD_ADDRESS + address);
- //#55#00#00#20 STK_LOAD_ADDRESS, 0×0000(address location)
- //now write the data to the address...
- send_command(STK_PROGRAM_PAGE + byteCount + 'F' + dataPayload);
- //STK_PROGRAM_PAGE, 0×0080 (page size), ‘F’(flash memory), data bytes…,SYNC_CRC_EOP
- imp.sleep(0.045); //wait 4.5ms until the flash location has been written to
- }
- else if (recordType = '1'){
- //this is the last record. It's empty, should have no data, checksum should be 'FF'
- //assert byteCount is 00
- if (byteCount == 00){
- exitProgramMode();
+
+ function send_command(command_array){
+ foreach (command in command_array){
+ hardware.uart12.write(command);
}
- else{
- raise ("Error: final record contains more than 0 bytes. Abort.");
+ hardware.uart12.write(STK_CRC_EOP);
+ hardware.uart12.flush();
+ local b = hardware.uart12.read();
+ local response = blob(1);
+ while( b!= STK_OK){
+ if(b >= 0){
+ response.writen(b);
+ }
+ local b = hardware.uart12.read();
}
+ return response;
}
- else{
- raise ("Error: in hex format, Extended Address modes NOT accepted. Record type must be 0x00 or 0x01");
+
+
+ function progLine(hexLine){
+ //program each individual line of the code with this!
+ if (hexLine.recordType = '0'){
+ //record is data, program chip...
+ send_command([STK_LOAD_ADDRESS, hexLine.address]);
+ //#55#00#00#20 STK_LOAD_ADDRESS, 0װ000(address location)
+ //now write the data to the address...
+ send_command([STK_PROGRAM_PAGE, byteCount, 'F', hexLine.dataPayload]);
+ //STK_PROGRAM_PAGE, 0װ080 (page size), ҆Ҩflash memory), data bytes SYNC_CRC_EOP
+ imp.sleep(0.045); //wait 4.5ms until the flash location has been written to
+ return 1;
+ }
+ else if (hexLine.recordType = '1'){
+ //finalize programming...
+ return "exitProgMode";
+ }
}
- return results;
}
View
294 server.c
@@ -1,211 +1,163 @@
-/*
+/*
* Secret Robot
* Reprogram an arduino anywhere!
* Uses an Electric Imp, some hardware, some code, and some magic.
-* All you need is a WiFi connection at your Arduino deploy location.
-*
+* All you need is a WiFi connection at your Arduino deploy location.
*
-* Warning: semi-literate programming used. I ain't Knux w/ Tex, that's for sure...
*
* released under CC-A 3.0; no guarantee of any kind is made for this code
*/
/*
*
* This code is used server (agent) side.
-* I lknow there's...a lot here
-* It's all important though. Most of it only deals with the initial setup (getting the oAuth toekn from Github)
*/
-//define per-user constants
-const OWNER_NAME = "genejones"; //your Github user-name
-const REPO_NAME = "blink"; //your Github REPO_NAME
-const FILE_PATH = ".build/uno/firmware.hex"; //the path to the .hex file within the repo. By default, using the ino build-system, it should be './build/uno/firmware.hex'
const TARGET_NAME = "ATMEGA328P"; //the type of your AVR, choose among the targets table below. ATmega328P is typical for Arduino Uno and Diecemillia.
-//can also be within a folder, e.g. 'hardware/avr/flash.hex'
server.log("agent started on "+http.agenturl());
-GITHUB_TOKEN <- "837acf5d5b4b2d6bab0daab04c48635c3a70f9e8";
+function update_avr(fileURL){
+ //expects a table, with "content" containing the actual, raw, .hex file...
+ //and "length" as well, which we use to determine the length, funnily enough
+ try{
+ server.log("grabbing file..");
+ file <- http.get(fileURL).sendsync();
+ server.log("status was " + file.statuscode);
+ if (file.statuscode == 200){
+ hexItUp(file.body);
+ }
+ device.on("avr reflash success", function (t){
+ //we are all done now!
+ server.log("flash success!");
+ //maybe tell Twitter about our success?
+ });
+ device.on("next_chunk", chunkLines);
+ }
+ catch (e){
+ //something went horribly wrong during the deploy process
+ //sigh
+ //log it
+ server.log("Error during update process: "+e);
+ }
+}
-//general constants. Don't modify unless you know what you are doing.
-GITHUB_URL_BASE <- "https://api.github.com/repos/" + OWNER_NAME + "/" + REPO_NAME;
-server.log("running against " + GITHUB_URL_BASE);
+//start hex stuff:
+//This file is for understanding .hex files
+//It has two main functions
+//The first function breaks up the .hex by line breaks
+//The second analyzes each line, and turns the .hex into a binary blob
-//define device constants
+//http://www.sbprojects.com/knowledge/fileformats/intelhex.php
-//taken from 28.3 and 28.5 in the Atmel AVR doc
-//signature is what we expect the value to be
-//flash size is how many words are present
-//each word is 2 bytes long, so a Flash Size of 1600 is 32 Kb
-targets <- {
-"ATMEGA328P" : {"SIG":"\x1e\x95\x0f", "FLASH_SIZE":16384},
-"ATMEGA328" : {"SIG":"\x1e\x95\x14", "FLASH_SIZE":16384},
-"ATMEGA168A" : {"SIG":"\x1e\x94\x06", "FLASH_SIZE":8192},
+function splitHex(hexString){
+ //split each instruction in the hex File by newline instructions (0x0D0A)
+ local lines = split(hexString, "\r\n");
+ return lines;
}
-function router(request, res){
- try{
- switch(request.path){
- case "/updateAVR":
- server.log("github request made...");
- github_request(request, res)
- default:
- if (request.method == "OPTIONS" && request.path == ""){
- res.header("ALLOW", "GET,PUT,DELETE,OPTIONS");
- res.send(200, "OK");
- }
- else if (request.method == "GET" && request.path == ""){
- res.send(200, "This Rascal needs setup, captain!");
- }
- res.send(404, "Resource Does Not Exist");
- }
+//then split lines into chunks of about 64 lines at a time (which is 64*16 bytes, or 1024)
+
+programPosition <- 0;
+function chunkLines(t){
+ server.log("chunk requested by device");
+ local chunk_size = 64; //64 lines at a time works out to be 1024 data bytes at a time, plus addresses and overhead...still plenty of space in RAM
+ if ( programData.len() > programPosition + chunk_size){
+ local chunkTable = [];
+ for (local i=0; i < programPosition + chunk_size; i++){
+ chunkTable.append(programData[i + programPosition]);
+ }
+ device.send("next_chunk", chunkTable);
+ programPosition = programPosition + chunk_size;
+ server.log(format("sent chunk, at position %3d of %3d" programPosition, programData.len()));
}
- catch(e){
- res.send(500, "Server Error: " + e);
- raise(e);
+ else {
+ //we don't have a full 64 lines, so give the remaining lines as our chunk
+ local chunkTable = [];
+ for (local i=0; i < programPosition + chunk_size; i++){
+ chunkTable[i] = programData[i + programPosition]
+ }
+ device.send("next_chunk", chunkTable);
}
}
-http.onrequest(router);
-
-function github_request(request, res){
- switch (request.method){
- case "POST":
- try{
- local github = http.jsondecode(request.body);
- //Someone made a request asking me to flash some code to an AVR!
- //I'll get right to that...wait a second...
- //what if someone kept spamming me with re-write requests
- //The AVR would never get around to doing anyting useful!
- //or they could be trying to have us revert to an older commit!
- //or some other nefarious thing!
- //We will be diligent, wary, and awesome.
- //Let no unhallowed code pass through.
-
- if (github.repository.owner.name == OWNER_NAME){
- //Alright Mr. Request...who sent you?
- //Oh, I see from this note you carry that you were sent on my behalf by Github.
- //And, you also carry the secret pass phrase me and Github setup a while ago...
- //Hmm. Well, that's not enough proof. Let's see if Github backs up your story.
- //all request IPs should be within the ranges of: 204.232.175.64/27, 192.30.252.0/22
- local canidateCommit = github.commits[0].id;
- server.log("canidate Commit " + canidateCommit);
- //updateGithubStatus(canidateCommit, "pending", "Secret Robot is uploading everything now");
- //Github, was the .hex file updated on my repository recently?
- server.log(GITHUB_URL_BASE + "/contents/" + FILE_PATH);
- hexFileInfoResponse <- http.get(GITHUB_URL_BASE + "/contents/" + FILE_PATH, {"Accept":"application/vnd.github.raw", "User-Agent" : "Secret Robot/Imp Agent", "Authorization":getAuthority()} ).sendsync();
- if (hexFileInfoResponse.statuscode == 200){
- server.log("good response from github");
- //I was able to reach out to my friend at Github. What did he say?
- hexInfo <- http.jsondecode(hexFileInfoResponse.body);
- server.log(hexInfo.sha);
- if (hexInfo.sha == canidateCommit){
- //ensure the most recent update to the .hex occured on this most recent commit
- //no need to reset if, for instance, the README was the only thing affected...
- update_avr(hexInfo.bindenv(this));
- //All right, let's get to the .hex writing!
- //update_avr(hexInfo.html_url);
- }
- }
- else{server.log(hexFileInfoResponse.body + hexFileInfoResponse.statuscode);}
- }
- res.send(200, "Hex Updated");
- }
- catch (e){
- res.send(200, "Are you a hacker? Your JSON is all wrong: "+e);
- }
- case "OPTIONS":
- res.header("ALLOW", "POST,OPTIONS");
- res.send(200, "Allowed methods are POST. POST should be JSON formated according to <a href='https://help.github.com/articles/post-receive-hooks'>Github</a>. We check with Github to ensure a valid commit, so don't try anything funny.");
- break;
- default:
- res.send(405, "Method not implemented. See HTTP OPTIONS for valid options. Are you lost?");
- break;
+function extractAddressAndData(hexString){
+ local lines = splitHex(hexString);
+ for (local i=0; i<lines.len(); i++){
+ local result = understandHex(lines[i]);
}
}
-function update_avr(info){
- //expects a table, with "content" containing the actual, raw, .hex file...
- //and "length" as well, which we use to determine the length, funnily enough
- try{
- //alright, let's get started by telling Github that we are starting the deploy process
- server.log("updating the avr...");
- updateGithubStatus(info.sha, "pending", "Rascal is on the job!");
- //this provides a nice, easy wasy to see the status of our deploy
-
- local target_properties = targets[TARGET_NAME];
- //find out what our device is, and it's capabilities
- if (info.size > target_properties.size){
- //our target has too small of a flash memory
- //this should have gotten caught by the Garbage collection process
- raise ("Flash memory smaller than flash program");
+function convertHexToInteger(hex){
+ //expects a string representing the hexidecimal of a single byte
+
+ // see http://devwiki.electricimp.com/doku.php?id=webcolor&s[]=hex
+ //I basically took the above, and add extra checks
+ local result = 0;
+ local shift = hex.len() * 4;
+ for (local d=0; d<hex.len(); d++){
+ local digit;
+ // convert ascii such that it is case insensitive
+ if(hex[d] >= 0x61 && hex[d] <= 0x66){ //if the hex digit is greater than or equal to 'a', but less than or greater than 'f'
+ digit = hex[d] - 0x57;
}
-
- server.log("sending over to the Imp");
- device.send("avr firmware change", target_properties, info.content); //just send the code right over to the Imp
- //it's in his hands now.
-
- device.on("avr reflash success", function (){
- //we are all done now!
- updateGithubStatus(info.sha, "success");
- //alter the github status to reflect our awesomeness
- });
- }
- catch (e){
- //something went horribly wrong during the deploy process
- //sigh
- //log it
- server.log("Error during update process: "+e);
- //and tell the whole world about our mistake on Github
- updateGithubStatus(info.sha, "failure");
- //wait, what? Too late now. Nobody goes to our Github page anyway, I'm sure it's fine...
+ else if(hex[d] >= 0x41 && hex[d] <= 0x46){//if the hex digit is less than or equal to 'A', but less than or greater than 'F'
+ digit = hex[d] - 0x37; //shift value downwards by 55 (decimal), such that 'A' = 10 (decimal), and 'F' = 16
+ }
+ else if (hex[d] >= 0x30 && hex[d] <= 0x39){ //if the digit is greater or equal to 0, but less than or equal to 9
+ digit = hex[d] - 0x30; //move the value downwards by 48 (decimal), such that 0 (ascii) represents 0 (integer), and 9 (ascii) represents 9 (integer)
+ }
+ else{
+ throw (format("Error in hexadecimal conversion: value outside of expected ranges (0-9, A-F, a-f). Value was %x", hex[d]));
+ }
+
+ // Accumulate digit
+ shift -= 4;
+ result += digit << shift;
}
+ return result;
}
-function updateGithubStatus(commitID, status, description){
- local headers = {"User-Agent" : "Secret Robot/Imp Agent", "Authorization":getAuthority()};
- local payload = http.jsonencode({"state":status, "description":description});
- statusUpdatedRequest <- http.post(GITHUB_URL_BASE + "/statuses/" + commitID, headers, payload).sendsync();
- if (statusUpdatedRequest.statuscode == 201){
- server.log("Updated successfully");
- }
- else{
- server.log(statusUpdatedRequest.body);
- }
+function integerToBlob(integer){
+ local blob_result = blob(1);
+ blob_result.writen(integer, 'b'); //write the integer result as an unsigned 8-bit integer (basically, a single byte)
+ return blob_result;
}
-function setUpHook(){
- //sets up a post-commit hook on this agent url,
- //so that we get notified when hooks occur
- //and can update teh AVR accordingly
- local body = http.jsonencode({
- "name":"web",
- "active": true,
- "events": [
- "push"
- ],
- "config": {
- "url" : http.agenturl()+"/updateAVR",
- "content_type": "json",
- }
- });
- response <- http.post(GITHUB_URL_BASE + "/hooks" {"User-Agent" : "Secret Robot/Imp Agent", "Authorization":getAuthority()}, body).sendsync();
- switch(response.statuscode){
- case 201:
- server.log("Hook was setup correctly!");
- break;
- case 422:
- server.log("Hook already exists on this repository");
- break;
- default:
- server.log("Error occured within " + response.statuscode);
- break;
+programData <- [];
+
+function hexItUp(raw_hex_file){
+ local raw_lines = splitHex(raw_hex_file);
+ server.log("hexItUp");
+ foreach (i,raw_line in raw_lines){
+ local result = understandHex(raw_line);
+ //server.log(format("parsed line %04d", i));
+ programData.append(result);
}
+ //instruct the device to begin downloading our data...
+ device.send("programModeBegin", 1);
}
-function getAuthority(){
- return "Basic " + http.base64encode(OWNER_NAME + ":" + GITHUB_TOKEN);
+//needs hex to be split by line...
+function understandHex(hexLine){
+ if (!hexLine[0] == ':'){
+ throw ("Error: hex format not correct, must contain : on start of each line");
+ }
+ local byteCount = convertHexToInteger(hexLine.slice(1,2) );
+ local address = blob(2);
+ address.writen(convertHexToInteger(hexLine.slice(3,4) ), 'b');
+ address.writen(convertHexToInteger(hexLine.slice(5,6) ), 'b');
+ local recordType = hexLine[8];
+ local dataPayload = blob(byteCount);
+ for (local i =0; i<byteCount; i++){
+ local datum = convertHexToInteger(hexLine.slice(8 + i, 9 + i) );
+ dataPayload.writen(datum, 'b');
+ }
+ //I am not checking the checksum, HTTPS checksum already ensures integrity
+ //if the checksum fails, we have bigger problems, so let's just assume
+ results <- {"recordType":recordType, "address":address, "dataPayload":dataPayload, "byteCount":byteCount};
+ return results;
}
-//setUpHook();
+update_avr("https://raw.github.com/genejones/blink/master/.build/uno/firmware.hex");
+//testing...

No commit comments for this range

Something went wrong with that request. Please try again.