Skip to content

Instantly share code, notes, and snippets.

@gemfarmer
Last active March 12, 2019 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gemfarmer/a6b08a4646ce0898bc913a01bd82ef80 to your computer and use it in GitHub Desktop.
Save gemfarmer/a6b08a4646ce0898bc913a01bd82ef80 to your computer and use it in GitHub Desktop.
Read Firmware from SD Card, Flash to P1
�
��
 H
I��B� J�B����HJ!���H�� d
h h � � p�� �KLF��%�B�V�%0�G5��p��$
T
�������@������x����@ pG#ppG����O�Q��������@I�L�
������@I�B�
����Khh����Kh[h����Khi����Kh[i����Kh�i����Kh�i����Khj����Kh�i����Kh[j����Kh�j����Kh�j����Khk����Kh[k����Khl����Khk����Kh�n����Kh[h����Kh[i����Kh�i����Khh����Kh�k����Khi����Kh[h����Kh���0����Kh���0����Khh����Kh[h���pG"FF��ƿHKJI`����l (
h �
pGAtpG|��p�|��M�|��Z�|��O�|��\��F���� F�p�E|FF%�|��V�(�1F |��p@��&�(Fp��FFF"b`O�zr�`J t"`"btF�� � F��4
8� M)h��(F����h�J!FK H����(F����JIH���H8�  � p h �
AtpGpG!|����!|����|����|����8�F|
F����(�`| �)F |���� 8�|�����F��Y� F��F#c`O�zs�`KF#`#!tctF��n� F�d
"|��n��F"!���K Fc`K�`@�#��##��� � 0�M�������)h��(F���`��!FH����(F���JIH��H�0��  h �
�F"!�s�K Fc`K�`@�#��##���� 0 �L�������#h�� F����`��!H���� F����JIH���H���, � h �
pG�F���� F���F�$�
"8F�J��BD�,��.!8F��D�� F�����@D�#C�BB�a#A`u�7�M`��P������0��
��hF�"F�G F��K3���U�hi�G(�K3�����hi�G(�
K ���� K{���{�hi�G(�������������������������K`�  HJI���@@@@`
�#�Fo�w����]���C�
+�P+ � Kh;��]��G�����#�Fo�w����]��� 8�LM#h�BK �""p�����%`�������
K��������!H������8@!H��н@@'�� =
�F��V� F�H#�`JI����� h �
KhK`pG� � JK`pG�
� ��F
F�$�B �3h��h0F�G(�D��,�F F��p�F FFI��K�+hF!F(F��p@�hGp�������h�hG*��
"0� F��!��$
�#�����3۲ +��0373۲!F�9+F-������ �0��"�hɲ�h�GҲ���ֿ����O��s7�
L%c�O��s(F��%p��1��@�]*F)F�����+�##p#e����0�� pG�F��B� F�p�FFK%`@� _����0F&q�����` Fp���
�L#FF� F���� FJI���@�)��� h

p� L N
M! F���� F L2F)F��! F����2F)F F��p@� �� h

  FFF�I�Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"` Kh�\�"`
Kh�\�"`pG�L H D @ < 8 4 0 $Kh�\�"`"Kh�\�"` Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`pG�| x t p l h d ` \ X T P $Kh�\�"`"Kh�\�"` Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`pG�� � � � � � � � � � � � Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"`Kh�\�"` Kh�\�"`
Kh�\�"`pG�� � � � � � � � �LF,�
FF ���� F��C
D�B��K�O���FD�B����pG8�KFh�kӹ ��k�C�3�c�J��3C�A�4#��N�mcÀM��c�#C� #��"#��#�k"aZa8�d F�+*��8pG
]
�
�
Firmware flashed!�
�
�
�

�
�
�
�
�
�
�
�
�

�
�
�
�
�
�




Z%+03d:%02u%Y-%m-%dT%H:%M:%S%zasctimeflnfncodedetail
%010u ] %d, (): [code = %idetails = baudSerialUSBSerial1typeparamcmdidhndstrmfiltlvladdHandlerremoveHandlerenumHandlersJSONStreamLogHandlerappnonetraceinfowarnerrorpanicall


C�
�
�
�
 
�
E
u
�
I

�
�
�
�

 
 ����f��U�Y�����ǘ{gY�F �^iK��&2(����
#include "Particle.h"
#include "system_update.h"
bool uploaded = false;
SerialDebugOutput debugOutput(9600, ALL_LEVEL);
// float dummyVoltage = 3.50; //This just shows to to write variables to OpenLog
// char mystr[13]; //Initialized variable to store recieved data
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
delay(1000);
Serial.println("I'm alive");
setupOpenLog(); //Resets logger and waits for the '<' I'm alive character
Serial.println("OpenLog online");
}
void loop() {
if (!uploaded) {
uploaded = true;
delay(5000);
poll();
}
}
void poll() {
//Now let's read back
gotoCommandMode(); //Puts OpenLog in command mode
readFirmware("confirm.bin");
//Now let's read back
readDisk(); //Check the size and stats of the SD card
//Infinite loop
Serial.println("Yay!");
}
void readFirmware(char *fileName) {
//Old way
Serial1.print("read ");
Serial1.print(fileName);
Serial1.write(13); //This is \r
//The OpenLog echos the commands we send it by default so we have 'read log823.txt\r' sitting
//in the RX buffer. Let's try to not print this.
while(1) {
if(Serial1.available())
if(Serial1.read() == '\r') break;
}
//This will listen for characters coming from OpenLog and print them to the terminal
//This relies heavily on the SoftSerial buffer not overrunning. This will probably not work
//above 38400bps.
//This loop will stop listening after 1 second of no characters received
int fileSize = getFileSize(fileName);
Serial.write(fileSize);
char file_bytes[fileSize];
for(int _timeOut = 0 ; _timeOut < 15000 ; _timeOut++) {
while(Serial1.available()) {
int spot = 0;
while(Serial1.available()) {
file_bytes[spot++] = Serial1.read();
if(spot > (fileSize - 2)) break;
}
file_bytes[spot] = '\0';
Serial.write(file_bytes);
_timeOut = 0;
}
delay(1);
}
uint8_t file_bytes_ = *file_bytes;
updateFirmwareFromFile(&file_bytes_);
}
void updateFirmwareFromFile(uint8_t* file_bytes) {
FileTransfer::Descriptor file;
Serial.printlnf("starting flash size=%d", sizeof(file_bytes));
file.file_length = sizeof(file_bytes);
file.file_address = 0; // Automatically set to HAL_OTA_FlashAddress if store is FIRMWARE
file.chunk_address = 0;
file.chunk_size = 0; // use default
file.store = FileTransfer::Store::FIRMWARE;
int result = Spark_Prepare_For_Firmware_Update(file, 0, NULL);
if (result != 0) {
Serial.printlnf("prepare failed %d", result);
return;
}
Serial.printlnf("chunk_size=%d file_address=0x%x", file.chunk_size, file.file_address);
if (file.chunk_size == 0) {
file.chunk_size = 512;
}
// Note that Spark_Prepare_For_Firmware_Update sets file.file_address so it's not really zero here
// even though it's what we initialize it to above!
file.chunk_address = file.file_address;
size_t offset = 0;
while(offset < file.file_length) {
if (file.chunk_size > (file.file_length - offset)) {
file.chunk_size = (file.file_length - offset);
}
Serial.printf("chunk_address=0x%x chunk_size=%d", file.chunk_address, file.chunk_size);
result = Spark_Save_Firmware_Chunk(file, &file_bytes[offset], NULL);
if (result != 0) {
Serial.printlnf("save chunk failed %d", result);
return;
}
file.chunk_address += file.chunk_size;
offset += file.chunk_size;
}
result = Spark_Finish_Firmware_Update(file, 0x1, NULL);
if (result != 0) {
Serial.printlnf("finish failed %d", result);
return;
}
Serial.printlnf("update complete");
}
void readDisk() {
//Old way
Serial1.print("disk");
Serial1.write(13); //This is \r
//New way
//OpenLog.print("read ");
//OpenLog.println(filename); //regular println works with OpenLog v2.51 and above
//The OpenLog echos the commands we send it by default so we have 'disk\r' sitting
//in the RX buffer. Let's try to not print this.
while(1) {
if(Serial1.available())
if(Serial1.read() == '\r') break;
}
//This will listen for characters coming from OpenLog and print them to the terminal
//This relies heavily on the SoftSerial buffer not overrunning. This will probably not work
//above 38400bps.
//This loop will stop listening after 1 second of no characters received
for(int timeOut = 0 ; timeOut < 1000 ; timeOut++) {
while(Serial1.available()) {
char tempString[100];
int spot = 0;
while(Serial1.available()) {
tempString[spot++] = Serial1.read();
if(spot > 98) break;
}
tempString[spot] = '\0';
Serial.write(tempString); //Take the string from OpenLog and push it to the Arduino terminal
timeOut = 0;
}
delay(1);
}
//This is not perfect. The above loop will print the '.'s from the log file. These are the two escape characters
//recorded before the third escape character is seen.
//It will also print the '>' character. This is the OpenLog telling us it is done reading the file.
//This function leaves OpenLog in command mode
}
void gotoCommandMode(void) {
//Send three control z to enter OpenLog command mode
//Works with Arduino v1.0
Serial1.write(26);
Serial1.write(26);
Serial1.write(26);
Serial1.write(13); //This is \r
Serial.println("go to command mode");
//Wait for OpenLog to respond with '>' to indicate we are in command mode
while(1) {
if(Serial1.available())
if(Serial1.read() == '>') break;
}
Serial.println("in command mode");
}
int getFileSize(char *fileName) {
//Old way
Serial1.print("size ");
Serial1.print(fileName);
Serial1.write(13); //This is \r
//The OpenLog echos the commands we send it by default so we have 'read log823.txt\r' sitting
//in the RX buffer. Let's try to not print this.
while(1) {
if(Serial1.available())
if(Serial1.read() == '\r') break;
}
Serial.write("after loop");
size_t sizeFile = 0;
for(int timeOut = 0 ; timeOut < 1000 ; timeOut++) {
while(Serial1.available()) {
sizeFile++;
Serial.write(Serial1.read());
}
delay(1);
}
return sizeFile;
}
//Setups up the software serial, resets OpenLog so we know what state it's in, and waits
//for OpenLog to come online and report '<' that it is ready to receive characters to record
void setupOpenLog(void) {
gotoCommandMode(); //Puts OpenLog in command mode
Serial1.print("reset");
Serial1.write(13); //This is \r
Serial.println("soft reset");
while(1) {
if(Serial1.available())
if(Serial1.read() == '<') break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment