Skip to content

Commit

Permalink
MYSBootlaoder 1.3-beta3
Browse files Browse the repository at this point in the history
  • Loading branch information
tekka007 committed Dec 31, 2016
1 parent 0953739 commit 02cceb0
Show file tree
Hide file tree
Showing 16 changed files with 1,611 additions and 867 deletions.
57 changes: 57 additions & 0 deletions Core.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
MYSBootloader 1.3pre3
OTA RF24 bootloader for MySensors: http://www.mysensors.org
Based on MySensors library 2.1
Developed and maintained by tekka 2016
*/

#ifndef Core_H
#define Core_H

// version *************************************************************************************************************
#define MYSBOOTLOADER_MAJVER 1
#define MYSBOOTLOADER_MINVER 2
#define MYSBOOTLOADER_VERSION ((MYSBOOTLOADER_MINVER << 8) + MYSBOOTLOADER_MAJVER)

// size setting ********************************************************************************************************
#define BOOTLOADER_SIZE (2048)
#define BOOTLOADER_START_ADDRESS (0x8000 - BOOTLOADER_SIZE)

// DEBUG led patterns *************************************************************************************************

#define DEBUG_INIT _BV(3)
#define DEBUG_READ_CONFIG _BV(4)
#define DEBUG_FIND_PARENTS _BV(5)
#define DEBUG_CHECK_ID _BV(6)
#define DEBUG_CONFIGURATION _BV(7)
#define DEBUG_CONFIG_RECEIVED _BV(8)
#define DEBUG_INIT_UPDATE _BV(6) | _BV(7)
#define DEBUG_DO_UPDATE _BV(4) | _BV(5) | _BV(7)
#define DEBUG_PREPARE_RUN _BV(4) | _BV(5) | _BV(7)
#define DEBUG_RUN _BV(4) | _BV(5) | _BV(6) | _BV(7)

#include <string.h>
#include <stdlib.h>
#include <avr/eeprom.h>
#include <util/delay.h>

#include "Definitions.h"
#include "boot.h"
#include "HW.h"
#include "MyEepromAddresses.h"
#include "MyMessage.h"
#include "RF24.h"
#include "STK500Bootloader.h"
#include "MySensorsBootloader.h"


// global variables
MyMessage _outMsg;
MyMessage _inMsg;
nodeConfig_t _eepromNodeConfig;
uint8_t _configuredParentFound;
uint8_t _configuredParentID;
uint8_t _save_MCUSR;


#endif // Core_H
73 changes: 73 additions & 0 deletions Definitions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
MYSBootloader 1.3pre3
OTA RF24 bootloader for MySensors: http://www.mysensors.org
Based on MySensors library 2.1
Developed and maintained by tekka 2016
*/

#ifndef Definitions_H
#define Definitions_H

#define FIRMWARE_BLOCK_SIZE (16)

#define false (0)
#define true (1)

typedef uint8_t bool;

typedef enum {
BL_INIT,
BL_READ_CONFIG,
BL_FIND_PARENTS,
BL_CHECK_ID,
BL_CONFIGRUATION,
BL_INIT_UPDATE,
BL_DO_UPDATE,
BL_VALIDATE_OTA,
BL_RUN,
BL_EXIT
} SM_BL_STATE;


typedef struct {
union {
uint16_t type;
uint16_t bl_command;
} type_command;
union {
uint16_t version;
uint16_t bl_data;
} version_data;
uint16_t blocks;
uint16_t crc;
} __attribute__((packed)) nodeFirmwareConfig_t;

typedef struct {
uint16_t type;
uint16_t version;
uint16_t blocks;
uint16_t crc;
uint16_t BLVersion;
} __attribute__((packed)) requestFirmwareConfig_t;

typedef struct {
uint16_t type;
uint16_t version;
uint16_t block;
} __attribute__((packed)) requestFirmwareBlock_t;

typedef struct {
uint16_t type;
uint16_t version;
uint16_t block;
uint8_t data[FIRMWARE_BLOCK_SIZE];
} __attribute__((packed)) responseFirmwareBlock_t;

typedef struct {
uint8_t nodeId; // Current node id
uint8_t parentNodeId; // Where this node sends its messages
uint8_t distance; // This nodes distance to sensor net gateway (number of hops)
} __attribute__((packed)) nodeConfig_t;


#endif // Definitions_H
255 changes: 255 additions & 0 deletions HW.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
/*
MYSBootloader 1.3pre3
OTA RF24 bootloader for MySensors: http://www.mysensors.org
Based on MySensors library 2.1
Developed and maintained by tekka 2016
*/

#ifndef HW_H
#define HW_H

// hardware
# define UART_SRA UCSR0A
# define UART_SRB UCSR0B
# define UART_SRC UCSR0C
# define UART_SRL UBRR0L
# define UART_UDR UDR0


#ifndef BAUD_RATE
#if F_CPU >= 16000000L
#define BAUD_RATE 115200
#elif F_CPU >= 8000000L
#define BAUD_RATE 38400L
#elif F_CPU >= 1000000L
#define BAUD_RATE 9600L
#elif F_CPU >= 128000L
#define BAUD_RATE 4800L
#else
#define BAUD_RATE 1200L
#endif
#endif

#ifndef UART
#define UART 0
#endif

#define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
#define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
#if BAUD_ACTUAL <= BAUD_RATE
#define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
#if BAUD_ERROR >= 5
#error BAUD_RATE error greater than -5%
#elif BAUD_ERROR >= 2
#warning BAUD_RATE error greater than -2%
#endif
#else
#define BAUD_ERROR (( 100*(BAUD_ACTUAL - BAUD_RATE) ) / BAUD_RATE)
#if BAUD_ERROR >= 5
#error BAUD_RATE error greater than 5%
#elif BAUD_ERROR >= 2
#warning BAUD_RATE error greater than 2%
#endif
#endif

#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
#error Unachievable baud rate (too slow) BAUD_RATE
#endif // baud rate slow check
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
#if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero
#error Unachievable baud rate (too fast) BAUD_RATE
#endif
#endif

#ifndef UART
#define UART 0
#endif


// Watchdog definitions and functions
#define WATCHDOG_OFF (0)
#define WATCHDOG_16MS (_BV(WDE))
#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))


static inline void watchdogReset() {
__asm__ __volatile__ ("wdr\n");
}

void watchdogConfig(const uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}


// SPI communication
#define SPI_PORT PORTB //
#define SPI_DDR DDRB //
#define SPI_SCLK PB5 // Arduino Pin 13 <-> Bit 5 of port B
#define SPI_MISO PB4 // Arduino Pin 12 <-> Bit 4 of port B
#define SPI_MOSI PB3 // Arduino Pin 11 <-> Bit 3 of port B

#if defined(SPI_PINS_CE9_CSN10)
#define CSN_PORT PORTB // port for CSN
#define CSN_DDR DDRB // DDR for CSN
#define CSN_PIN PB2 // Arduino Pin 10 <-> Bit 2 of port B

#define CE_PORT PORTB // port for CE
#define CE_DDR DDRB // DDR for CE
#define CE_PIN PB1 // Arduino Pin 9 <-> Bit 1 of port B
#elif defined(SPI_PINS_CSN7_CE8)
#define CSN_PORT PORTD // port for CSN
#define CSN_DDR DDRD // DDR for CSN
#define CSN_PIN PD7 // Arduino Pin 7 <-> Bit 7 of port D

#define CE_PORT PORTB // port for CE
#define CE_DDR DDRB // DDR for CE
#define CE_PIN PB0 // Arduino Pin 8 <-> Bit 0 of port B
#endif

#define CSN_LOW() CSN_PORT &= ~_BV(CSN_PIN)
#define CSN_HIGH() CSN_PORT |= _BV(CSN_PIN)
#define CE_LOW() CE_PORT &= ~_BV(CE_PIN)
#define CE_HIGH() CE_PORT |= _BV(CE_PIN)


static void initSPI(void) {
// Initialize the SPI pins: SCK, MOSI, CE, CSN as outputs, MISO as input
#if defined(SPI_PINS_CE9_CSN10)
// CSN_PIN (=PB2) is SS pin and set as output
SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(CSN_PIN);
#elif defined(SPI_PINS_CSN7_CE8)
// PB2 is SS pin has to be defined as OUTPUT, else SPI goes to slave mode
SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(PB2);
CSN_DDR = _BV(CSN_PIN);
#endif

// SPE = SPI enable
// SPIE = SPI interrupt enable
// DORD = data order (0:MSB first, 1:LSB first)
// MSTR = Master/Slave select
// SPR1 = SPI clock rate bit 1
// SPR0 = SPI clock rate bit 0; 0,0=osc/4, 0,1=osc/16, 1,0=osc/64, 1,1=osc/128
// CPOL = clock polarity idle (0:low, 1:high)
// CPHA = clock phase edge sampling (0:leading, 1:trailing)

// SPI speed setting, nRF24L01P max. 10Mhz
#if (F_CPU >= 16000000)
// DIV 16 = 1 Mhz
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
#elif (F_CPU >= 8000000)
// DIV 8 = 1 Mhz
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
SPSR = _BV(SPI2X);
#elif (F_CPU >= 4000000)
// DIV 4 = 1Mhz
SPCR = _BV(SPE) | _BV(MSTR);
#elif (F_CPU >= 2000000)
// DIV 2 = 1 Mhz
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
SPSR = _BV(SPI2X);
#else
// DIV 2 <= 0.5 Mhz
SPCR = _BV(SPE) | _BV(MSTR);
SPSR = _BV(SPI2X);
#endif

}
static uint8_t SPItransfer(const uint8_t value) {
SPDR = value;
while(!(SPSR & _BV(SPIF))); // wait until transmitted
return SPDR;
}
inline void SPIclose(void) {
// disable hardware SPI
SPCR = 0;
}


// UART
static void initUART(void) {
UART_SRA = _BV(U2X0); //Double speed mode USART0
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
}

void putch(const uint8_t ch) {
while (!(UART_SRA & _BV(UDRE0)));
UART_UDR = ch;
}

uint8_t getch(void) {
// wait until char received
while(!(UART_SRA & _BV(RXC0)));
// 10 bytes
// framing error?
if (!(UART_SRA & _BV(FE0))) {
watchdogReset();
}
return UART_UDR;
}

static void writeTemporaryBuffer(const uint16_t address, const uint16_t data) {
// fill temporary page buffer
__boot_page_fill_short(address, data);
}

static void programPage(const uint16_t page){
__boot_page_erase_short(page); // erase page
boot_spm_busy_wait();
__boot_page_write_short(page); // program page
boot_spm_busy_wait();
__boot_rww_enable_short(); // re-enable RWW
}

static uint16_t crc16_update(uint16_t crc, const uint8_t data) {
crc ^= data;
for (uint8_t i = 0; i < 8; ++i) {
crc = (crc >> 1) ^ (-(int16_t)(crc & 1) & 0xA001);
}
return crc;
}

static uint16_t calcCRCrom (const uint16_t len) {

uint16_t _internal_crc = 0xFFFF; // init
uint16_t address = 0x0000;
uint16_t count = len;

// prevent overflow
if(count>BOOTLOADER_START_ADDRESS) {
count = BOOTLOADER_START_ADDRESS;
}

// calc
while (count) {
uint8_t _rom_byte;
// read a flash byte and increment the address
__asm__ ("lpm %0,Z+\n" : "=r" (_rom_byte), "=z" (address): "1" (address));
_internal_crc = crc16_update(_internal_crc,_rom_byte);
count--;
}
return _internal_crc;
}

static void blinkLed(void) {
LED_DDR |= _BV(LED_PIN);
//300ms total
uint8_t count = 6;
do {
LED_PORT ^= _BV(LED_PIN);
_delay_ms(50);
} while (--count);
}


#endif // HW_H
Loading

0 comments on commit 02cceb0

Please sign in to comment.