Support for MoteinoM0 and GUI v1.6
This commit is contained in:
parent
4c780da353
commit
11dd43144e
|
|
@ -30,12 +30,18 @@
|
||||||
// Please maintain this license information along with authorship
|
// Please maintain this license information along with authorship
|
||||||
// and copyright notices in any redistribution of this code
|
// and copyright notices in any redistribution of this code
|
||||||
// **********************************************************************************
|
// **********************************************************************************
|
||||||
#ifdef __AVR__
|
|
||||||
#include <RFM69_OTA.h>
|
#include <RFM69_OTA.h>
|
||||||
#include <RFM69registers.h>
|
#include <RFM69registers.h>
|
||||||
#include <avr/wdt.h>
|
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOTEINO_ZERO
|
||||||
|
#if defined(SERIAL_PORT_USBVIRTUAL)
|
||||||
|
#define Serial SERIAL_PORT_USBVIRTUAL // output on SerialUSB instead of Serial
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
//===================================================================================================================
|
//===================================================================================================================
|
||||||
// CheckForWirelessHEX() - Checks whether the last message received was a wireless programming request handshake
|
// CheckForWirelessHEX() - Checks whether the last message received was a wireless programming request handshake
|
||||||
// If so it will start the handshake protocol, receive the new HEX image and
|
// If so it will start the handshake protocol, receive the new HEX image and
|
||||||
|
|
@ -115,7 +121,7 @@ uint8_t HandleWirelessHEXData(RFM69& radio, uint8_t remoteID, SPIFlash& flash, u
|
||||||
uint16_t tmp,seq=0;
|
uint16_t tmp,seq=0;
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
uint16_t timeout = 3000; //3s for flash data
|
uint16_t timeout = 3000; //3s for flash data
|
||||||
uint16_t bytesFlashed=10;
|
|
||||||
#ifndef SHIFTCHANNEL
|
#ifndef SHIFTCHANNEL
|
||||||
HandleHandshakeACK(radio, flash);
|
HandleHandshakeACK(radio, flash);
|
||||||
if (DEBUG) Serial.println(F("FLX?OK (ACK sent)"));
|
if (DEBUG) Serial.println(F("FLX?OK (ACK sent)"));
|
||||||
|
|
@ -124,8 +130,15 @@ uint8_t HandleWirelessHEXData(RFM69& radio, uint8_t remoteID, SPIFlash& flash, u
|
||||||
//first clear the fist 32k block (dedicated to a new FLASH image)
|
//first clear the fist 32k block (dedicated to a new FLASH image)
|
||||||
flash.blockErase32K(0);
|
flash.blockErase32K(0);
|
||||||
flash.writeBytes(0,"FLXIMG:", 7);
|
flash.writeBytes(0,"FLXIMG:", 7);
|
||||||
|
#if defined (MOTEINO_ZERO)
|
||||||
|
flash.writeByte(10,':');
|
||||||
|
uint32_t bytesFlashed=11;
|
||||||
|
#else
|
||||||
flash.writeByte(9,':');
|
flash.writeByte(9,':');
|
||||||
|
uint32_t bytesFlashed=10;
|
||||||
|
#endif
|
||||||
now=millis();
|
now=millis();
|
||||||
|
pinMode(LEDpin,OUTPUT);
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
|
@ -133,6 +146,7 @@ uint8_t HandleWirelessHEXData(RFM69& radio, uint8_t remoteID, SPIFlash& flash, u
|
||||||
{
|
{
|
||||||
uint8_t dataLen = radio.DATALEN;
|
uint8_t dataLen = radio.DATALEN;
|
||||||
|
|
||||||
|
digitalWrite(LEDpin,HIGH);
|
||||||
if (dataLen >= 4 && radio.DATA[0]=='F' && radio.DATA[1]=='L' && radio.DATA[2]=='X')
|
if (dataLen >= 4 && radio.DATA[0]=='F' && radio.DATA[1]=='L' && radio.DATA[2]=='X')
|
||||||
{
|
{
|
||||||
if (radio.DATA[3]==':' && dataLen >= 7) //FLX:_:_
|
if (radio.DATA[3]==':' && dataLen >= 7) //FLX:_:_
|
||||||
|
|
@ -196,7 +210,14 @@ uint8_t HandleWirelessHEXData(RFM69& radio, uint8_t remoteID, SPIFlash& flash, u
|
||||||
}
|
}
|
||||||
if (dataLen==7 && radio.DATA[4]=='E' && radio.DATA[5]=='O' && radio.DATA[6]=='F') //Expected EOF
|
if (dataLen==7 && radio.DATA[4]=='E' && radio.DATA[5]=='O' && radio.DATA[6]=='F') //Expected EOF
|
||||||
{
|
{
|
||||||
#ifdef __AVR_ATmega1284P__
|
|
||||||
|
#if defined (MOTEINO_ZERO)
|
||||||
|
if ((bytesFlashed-10)>253952) { //max 65536 - 10 bytes (signature)
|
||||||
|
if (DEBUG) Serial.println(F("IMG > 64k, too big"));
|
||||||
|
radio.sendACK("FLX?NOK:HEX>64k",15);
|
||||||
|
return false; //just return, let MAIN timeout
|
||||||
|
}
|
||||||
|
#elif defined(__AVR_ATmega1284P__)
|
||||||
if ((bytesFlashed-10)>65526) { //max 65536 - 10 bytes (signature)
|
if ((bytesFlashed-10)>65526) { //max 65536 - 10 bytes (signature)
|
||||||
if (DEBUG) Serial.println(F("IMG > 64k, too big"));
|
if (DEBUG) Serial.println(F("IMG > 64k, too big"));
|
||||||
radio.sendACK("FLX?NOK:HEX>64k",15);
|
radio.sendACK("FLX?NOK:HEX>64k",15);
|
||||||
|
|
@ -212,16 +233,21 @@ uint8_t HandleWirelessHEXData(RFM69& radio, uint8_t remoteID, SPIFlash& flash, u
|
||||||
HandleHandshakeACK(radio, flash, false);
|
HandleHandshakeACK(radio, flash, false);
|
||||||
if (DEBUG) Serial.println(F("FLX?OK"));
|
if (DEBUG) Serial.println(F("FLX?OK"));
|
||||||
//save # of bytes written
|
//save # of bytes written
|
||||||
|
#ifdef MOTEINO_ZERO
|
||||||
|
flash.writeByte(7,(bytesFlashed-11)>>16);
|
||||||
|
flash.writeByte(8,(bytesFlashed-11)>>8);
|
||||||
|
flash.writeByte(9,(bytesFlashed-11));
|
||||||
|
//flash.writeByte(10,':'); //already done
|
||||||
|
#else
|
||||||
flash.writeByte(7,(bytesFlashed-10)>>8);
|
flash.writeByte(7,(bytesFlashed-10)>>8);
|
||||||
flash.writeByte(8,(bytesFlashed-10));
|
flash.writeByte(8,(bytesFlashed-10));
|
||||||
flash.writeByte(9,':');
|
//flash.writeByte(9,':'); //already done
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef LED //blink!
|
digitalWrite(LEDpin,LOW);
|
||||||
pinMode(LEDpin,OUTPUT); digitalWrite(LEDpin,HIGH); delay(1); digitalWrite(LEDpin,LOW);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//abort FLASH sequence if no valid packet received for a long time
|
//abort FLASH sequence if no valid packet received for a long time
|
||||||
|
|
@ -358,7 +384,7 @@ uint8_t HandleSerialHEXData(RFM69& radio, uint8_t targetID, uint16_t TIMEOUT, ui
|
||||||
index++;
|
index++;
|
||||||
uint8_t hexDataLen = validateHEXData(input+index, inputLen-index);
|
uint8_t hexDataLen = validateHEXData(input+index, inputLen-index);
|
||||||
|
|
||||||
if (hexDataLen>0)
|
if (hexDataLen>0 && hexDataLen<253)
|
||||||
{
|
{
|
||||||
if (tmp==seq) //only read data when packet number is the next expected SEQ number
|
if (tmp==seq) //only read data when packet number is the next expected SEQ number
|
||||||
{
|
{
|
||||||
|
|
@ -375,7 +401,8 @@ uint8_t HandleSerialHEXData(RFM69& radio, uint8_t targetID, uint16_t TIMEOUT, ui
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Serial.println(F("FLX:INV"));
|
//else Serial.print(F("FLX:INV"));
|
||||||
|
else { Serial.print(F("FLX:INV:"));Serial.println(hexDataLen); }
|
||||||
}
|
}
|
||||||
if (inputLen==7 && input[3]=='?' && input[4]=='E' && input[5]=='O' && input[6]=='F')
|
if (inputLen==7 && input[3]=='?' && input[4]=='E' && input[5]=='O' && input[6]=='F')
|
||||||
{
|
{
|
||||||
|
|
@ -414,24 +441,24 @@ uint8_t validateHEXData(void* data, uint8_t length)
|
||||||
for (uint8_t i=0; i<length;i++)
|
for (uint8_t i=0; i<length;i++)
|
||||||
{
|
{
|
||||||
if (!((input[i] >=48 && input[i]<=57) || (input[i] >=65 && input[i]<=70))) //0-9,A-F
|
if (!((input[i] >=48 && input[i]<=57) || (input[i] >=65 && input[i]<=70))) //0-9,A-F
|
||||||
return 0;
|
return 255;
|
||||||
if (i%2 && i<length-2) checksum+=BYTEfromHEX(input[i-1], input[i]);
|
if (i%2 && i<length-2) checksum+=BYTEfromHEX(input[i-1], input[i]);
|
||||||
}
|
}
|
||||||
checksum=(checksum^0xFF)+1;
|
checksum=(checksum^0xFF)+1;
|
||||||
|
|
||||||
//TODO : CHECK for address continuity (intel HEX addresses are big endian)
|
//TODO : CHECK for address continuity (intel HEX addresses are big endian)
|
||||||
|
|
||||||
//Serial.print(F("final CRC:"));Serial.println((uint8_t)checksum, HEX);
|
//Serial.print(F("final CRC:"));Serial.println((uint8_t)checksum, HEX);
|
||||||
//Serial.print(F("CRC byte:"));Serial.println(BYTEfromHEX(input[length-2], input[length-1]), HEX);
|
//Serial.print(F("CRC byte:"));Serial.println(BYTEfromHEX(input[length-2], input[length-1]), HEX);
|
||||||
|
|
||||||
//check CHECKSUM byte
|
//check CHECKSUM byte
|
||||||
if (((uint8_t)checksum) != BYTEfromHEX(input[length-2], input[length-1]))
|
if (((uint8_t)checksum) != BYTEfromHEX(input[length-2], input[length-1]))
|
||||||
return 0;
|
return 254;
|
||||||
|
|
||||||
uint8_t dataLength = BYTEfromHEX(input[0], input[1]); //length of actual HEX flash data (usually 16bytes)
|
uint8_t dataLength = BYTEfromHEX(input[0], input[1]); //length of actual HEX flash data (usually 16bytes)
|
||||||
//calculate record length
|
//calculate record length
|
||||||
if (length != dataLength*2 + 10) //add headers and checksum bytes (a total of 10 combined)
|
if (length != dataLength*2 + 10) //add headers and checksum bytes (a total of 10 combined)
|
||||||
return 0;
|
return 253;
|
||||||
|
|
||||||
return dataLength; //all validation OK!
|
return dataLength; //all validation OK!
|
||||||
}
|
}
|
||||||
|
|
@ -513,9 +540,18 @@ void PrintHex83(uint8_t* data, uint8_t length)
|
||||||
//===================================================================================================================
|
//===================================================================================================================
|
||||||
void resetUsingWatchdog(uint8_t DEBUG)
|
void resetUsingWatchdog(uint8_t DEBUG)
|
||||||
{
|
{
|
||||||
|
#ifdef __AVR__
|
||||||
//wdt_disable();
|
//wdt_disable();
|
||||||
if (DEBUG) Serial.print(F("REBOOTING"));
|
if (DEBUG) Serial.print(F("REBOOTING"));
|
||||||
wdt_enable(WDTO_15MS);
|
wdt_enable(WDTO_15MS);
|
||||||
while(1) if (DEBUG) Serial.print(F("."));
|
while(1) if (DEBUG) Serial.print(F("."));
|
||||||
}
|
#elif defined(MOTEINO_ZERO)
|
||||||
#endif
|
WDT->CTRL.reg = 0; // disable watchdog
|
||||||
|
while (WDT->STATUS.bit.SYNCBUSY == 1); // sync is required
|
||||||
|
WDT->CONFIG.reg = 0; // see Table 18.8.2 Timeout Period (valid values 0-11)
|
||||||
|
WDT->CTRL.reg = WDT_CTRL_ENABLE; //enable WDT
|
||||||
|
while (WDT->STATUS.bit.SYNCBUSY == 1);
|
||||||
|
WDT->CLEAR.reg= 0x00; // system reset via WDT
|
||||||
|
while (WDT->STATUS.bit.SYNCBUSY == 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
24
RFM69_OTA.h
24
RFM69_OTA.h
|
|
@ -2,11 +2,12 @@
|
||||||
// Library for OTA wireless programming of Moteinos using an RFM69 transceiver
|
// Library for OTA wireless programming of Moteinos using an RFM69 transceiver
|
||||||
// **********************************************************************************
|
// **********************************************************************************
|
||||||
// Hardware requirements:
|
// Hardware requirements:
|
||||||
// - DualOptiboot bootloader - ships with all Moteinos
|
// - DualOptiboot bootloader - ships with all AVR Moteino boards
|
||||||
// - SPI "Flash MEM" chip on Moteino (optional)
|
// - LowPowerLab Samba MultiBoot - ships with all ARM SAMD21 MoteinoM0 boards
|
||||||
|
// - SPI "Flash MEM" chip on Moteino
|
||||||
// Library requirements:
|
// Library requirements:
|
||||||
// - RFM69 - get library at: https://github.com/LowPowerLab/RFM69
|
// - RFM69 - get library at: https://github.com/LowPowerLab/RFM69
|
||||||
// - SPIFLash.h - get it here: http://github.com/LowPowerLab/SPIFlash
|
// - SPIFlash.h - get it here: http://github.com/LowPowerLab/SPIFlash
|
||||||
// **********************************************************************************
|
// **********************************************************************************
|
||||||
// Copyright LowPowerLab LLC 2018, https://www.LowPowerLab.com/contact
|
// Copyright LowPowerLab LLC 2018, https://www.LowPowerLab.com/contact
|
||||||
// **********************************************************************************
|
// **********************************************************************************
|
||||||
|
|
@ -30,15 +31,20 @@
|
||||||
// Please maintain this license information along with authorship
|
// Please maintain this license information along with authorship
|
||||||
// and copyright notices in any redistribution of this code
|
// and copyright notices in any redistribution of this code
|
||||||
// **********************************************************************************
|
// **********************************************************************************
|
||||||
#ifdef __AVR__
|
|
||||||
|
|
||||||
#ifndef RFM69_OTA_H
|
#ifndef RFM69_OTA_H
|
||||||
#define RFM69_OTA_H
|
#define RFM69_OTA_H
|
||||||
#ifdef __AVR_ATmega1284P__
|
|
||||||
|
#include <RFM69.h>
|
||||||
|
#include <SPIFlash.h>
|
||||||
|
|
||||||
|
#if defined(MOTEINO_ZERO)
|
||||||
|
#define LED 13 // Moteino M0
|
||||||
|
#elif defined(__AVR_ATmega1284P__)
|
||||||
#define LED 15 // Moteino MEGAs have LEDs on D15
|
#define LED 15 // Moteino MEGAs have LEDs on D15
|
||||||
#else
|
#elif defined (__AVR_ATmega328P__)
|
||||||
#define LED 9 // Moteinos have LEDs on D9
|
#define LED 9 // Moteinos have LEDs on D9
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SHIFTCHANNEL 1000000 //amount to shift frequency of HEX transmission to keep original channel free of the HEX transmission traffic
|
#define SHIFTCHANNEL 1000000 //amount to shift frequency of HEX transmission to keep original channel free of the HEX transmission traffic
|
||||||
|
|
||||||
#ifndef DEFAULT_TIMEOUT
|
#ifndef DEFAULT_TIMEOUT
|
||||||
|
|
@ -49,9 +55,6 @@
|
||||||
#define ACK_TIMEOUT 20
|
#define ACK_TIMEOUT 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <RFM69.h>
|
|
||||||
#include <SPIFlash.h>
|
|
||||||
|
|
||||||
//functions used in the REMOTE node
|
//functions used in the REMOTE node
|
||||||
void CheckForWirelessHEX(RFM69& radio, SPIFlash& flash, uint8_t DEBUG=false, uint8_t LEDpin=LED);
|
void CheckForWirelessHEX(RFM69& radio, SPIFlash& flash, uint8_t DEBUG=false, uint8_t LEDpin=LED);
|
||||||
void HandleHandshakeACK(RFM69& radio, SPIFlash& flash, uint8_t flashCheck=true);
|
void HandleHandshakeACK(RFM69& radio, SPIFlash& flash, uint8_t flashCheck=true);
|
||||||
|
|
@ -78,5 +81,4 @@ uint8_t BYTEfromHEX(char MSB, char LSB);
|
||||||
uint8_t readSerialLine(char* input, char endOfLineChar=10, uint8_t maxLength=115, uint16_t timeout=1000);
|
uint8_t readSerialLine(char* input, char endOfLineChar=10, uint8_t maxLength=115, uint16_t timeout=1000);
|
||||||
void PrintHex83(uint8_t* data, uint8_t length);
|
void PrintHex83(uint8_t* data, uint8_t length);
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue