Skip to content

Commit 02cceb0

Browse files
committed
MYSBootlaoder 1.3-beta3
1 parent 0953739 commit 02cceb0

16 files changed

+1611
-867
lines changed

Core.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
MYSBootloader 1.3pre3
3+
OTA RF24 bootloader for MySensors: http://www.mysensors.org
4+
Based on MySensors library 2.1
5+
Developed and maintained by tekka 2016
6+
*/
7+
8+
#ifndef Core_H
9+
#define Core_H
10+
11+
// version *************************************************************************************************************
12+
#define MYSBOOTLOADER_MAJVER 1
13+
#define MYSBOOTLOADER_MINVER 2
14+
#define MYSBOOTLOADER_VERSION ((MYSBOOTLOADER_MINVER << 8) + MYSBOOTLOADER_MAJVER)
15+
16+
// size setting ********************************************************************************************************
17+
#define BOOTLOADER_SIZE (2048)
18+
#define BOOTLOADER_START_ADDRESS (0x8000 - BOOTLOADER_SIZE)
19+
20+
// DEBUG led patterns *************************************************************************************************
21+
22+
#define DEBUG_INIT _BV(3)
23+
#define DEBUG_READ_CONFIG _BV(4)
24+
#define DEBUG_FIND_PARENTS _BV(5)
25+
#define DEBUG_CHECK_ID _BV(6)
26+
#define DEBUG_CONFIGURATION _BV(7)
27+
#define DEBUG_CONFIG_RECEIVED _BV(8)
28+
#define DEBUG_INIT_UPDATE _BV(6) | _BV(7)
29+
#define DEBUG_DO_UPDATE _BV(4) | _BV(5) | _BV(7)
30+
#define DEBUG_PREPARE_RUN _BV(4) | _BV(5) | _BV(7)
31+
#define DEBUG_RUN _BV(4) | _BV(5) | _BV(6) | _BV(7)
32+
33+
#include <string.h>
34+
#include <stdlib.h>
35+
#include <avr/eeprom.h>
36+
#include <util/delay.h>
37+
38+
#include "Definitions.h"
39+
#include "boot.h"
40+
#include "HW.h"
41+
#include "MyEepromAddresses.h"
42+
#include "MyMessage.h"
43+
#include "RF24.h"
44+
#include "STK500Bootloader.h"
45+
#include "MySensorsBootloader.h"
46+
47+
48+
// global variables
49+
MyMessage _outMsg;
50+
MyMessage _inMsg;
51+
nodeConfig_t _eepromNodeConfig;
52+
uint8_t _configuredParentFound;
53+
uint8_t _configuredParentID;
54+
uint8_t _save_MCUSR;
55+
56+
57+
#endif // Core_H

Definitions.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
MYSBootloader 1.3pre3
3+
OTA RF24 bootloader for MySensors: http://www.mysensors.org
4+
Based on MySensors library 2.1
5+
Developed and maintained by tekka 2016
6+
*/
7+
8+
#ifndef Definitions_H
9+
#define Definitions_H
10+
11+
#define FIRMWARE_BLOCK_SIZE (16)
12+
13+
#define false (0)
14+
#define true (1)
15+
16+
typedef uint8_t bool;
17+
18+
typedef enum {
19+
BL_INIT,
20+
BL_READ_CONFIG,
21+
BL_FIND_PARENTS,
22+
BL_CHECK_ID,
23+
BL_CONFIGRUATION,
24+
BL_INIT_UPDATE,
25+
BL_DO_UPDATE,
26+
BL_VALIDATE_OTA,
27+
BL_RUN,
28+
BL_EXIT
29+
} SM_BL_STATE;
30+
31+
32+
typedef struct {
33+
union {
34+
uint16_t type;
35+
uint16_t bl_command;
36+
} type_command;
37+
union {
38+
uint16_t version;
39+
uint16_t bl_data;
40+
} version_data;
41+
uint16_t blocks;
42+
uint16_t crc;
43+
} __attribute__((packed)) nodeFirmwareConfig_t;
44+
45+
typedef struct {
46+
uint16_t type;
47+
uint16_t version;
48+
uint16_t blocks;
49+
uint16_t crc;
50+
uint16_t BLVersion;
51+
} __attribute__((packed)) requestFirmwareConfig_t;
52+
53+
typedef struct {
54+
uint16_t type;
55+
uint16_t version;
56+
uint16_t block;
57+
} __attribute__((packed)) requestFirmwareBlock_t;
58+
59+
typedef struct {
60+
uint16_t type;
61+
uint16_t version;
62+
uint16_t block;
63+
uint8_t data[FIRMWARE_BLOCK_SIZE];
64+
} __attribute__((packed)) responseFirmwareBlock_t;
65+
66+
typedef struct {
67+
uint8_t nodeId; // Current node id
68+
uint8_t parentNodeId; // Where this node sends its messages
69+
uint8_t distance; // This nodes distance to sensor net gateway (number of hops)
70+
} __attribute__((packed)) nodeConfig_t;
71+
72+
73+
#endif // Definitions_H

HW.h

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
/*
2+
MYSBootloader 1.3pre3
3+
OTA RF24 bootloader for MySensors: http://www.mysensors.org
4+
Based on MySensors library 2.1
5+
Developed and maintained by tekka 2016
6+
*/
7+
8+
#ifndef HW_H
9+
#define HW_H
10+
11+
// hardware
12+
# define UART_SRA UCSR0A
13+
# define UART_SRB UCSR0B
14+
# define UART_SRC UCSR0C
15+
# define UART_SRL UBRR0L
16+
# define UART_UDR UDR0
17+
18+
19+
#ifndef BAUD_RATE
20+
#if F_CPU >= 16000000L
21+
#define BAUD_RATE 115200
22+
#elif F_CPU >= 8000000L
23+
#define BAUD_RATE 38400L
24+
#elif F_CPU >= 1000000L
25+
#define BAUD_RATE 9600L
26+
#elif F_CPU >= 128000L
27+
#define BAUD_RATE 4800L
28+
#else
29+
#define BAUD_RATE 1200L
30+
#endif
31+
#endif
32+
33+
#ifndef UART
34+
#define UART 0
35+
#endif
36+
37+
#define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
38+
#define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
39+
#if BAUD_ACTUAL <= BAUD_RATE
40+
#define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
41+
#if BAUD_ERROR >= 5
42+
#error BAUD_RATE error greater than -5%
43+
#elif BAUD_ERROR >= 2
44+
#warning BAUD_RATE error greater than -2%
45+
#endif
46+
#else
47+
#define BAUD_ERROR (( 100*(BAUD_ACTUAL - BAUD_RATE) ) / BAUD_RATE)
48+
#if BAUD_ERROR >= 5
49+
#error BAUD_RATE error greater than 5%
50+
#elif BAUD_ERROR >= 2
51+
#warning BAUD_RATE error greater than 2%
52+
#endif
53+
#endif
54+
55+
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
56+
#error Unachievable baud rate (too slow) BAUD_RATE
57+
#endif // baud rate slow check
58+
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
59+
#if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero
60+
#error Unachievable baud rate (too fast) BAUD_RATE
61+
#endif
62+
#endif
63+
64+
#ifndef UART
65+
#define UART 0
66+
#endif
67+
68+
69+
// Watchdog definitions and functions
70+
#define WATCHDOG_OFF (0)
71+
#define WATCHDOG_16MS (_BV(WDE))
72+
#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
73+
#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
74+
#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
75+
#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
76+
#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
77+
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
78+
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
79+
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
80+
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
81+
82+
83+
static inline void watchdogReset() {
84+
__asm__ __volatile__ ("wdr\n");
85+
}
86+
87+
void watchdogConfig(const uint8_t x) {
88+
WDTCSR = _BV(WDCE) | _BV(WDE);
89+
WDTCSR = x;
90+
}
91+
92+
93+
// SPI communication
94+
#define SPI_PORT PORTB //
95+
#define SPI_DDR DDRB //
96+
#define SPI_SCLK PB5 // Arduino Pin 13 <-> Bit 5 of port B
97+
#define SPI_MISO PB4 // Arduino Pin 12 <-> Bit 4 of port B
98+
#define SPI_MOSI PB3 // Arduino Pin 11 <-> Bit 3 of port B
99+
100+
#if defined(SPI_PINS_CE9_CSN10)
101+
#define CSN_PORT PORTB // port for CSN
102+
#define CSN_DDR DDRB // DDR for CSN
103+
#define CSN_PIN PB2 // Arduino Pin 10 <-> Bit 2 of port B
104+
105+
#define CE_PORT PORTB // port for CE
106+
#define CE_DDR DDRB // DDR for CE
107+
#define CE_PIN PB1 // Arduino Pin 9 <-> Bit 1 of port B
108+
#elif defined(SPI_PINS_CSN7_CE8)
109+
#define CSN_PORT PORTD // port for CSN
110+
#define CSN_DDR DDRD // DDR for CSN
111+
#define CSN_PIN PD7 // Arduino Pin 7 <-> Bit 7 of port D
112+
113+
#define CE_PORT PORTB // port for CE
114+
#define CE_DDR DDRB // DDR for CE
115+
#define CE_PIN PB0 // Arduino Pin 8 <-> Bit 0 of port B
116+
#endif
117+
118+
#define CSN_LOW() CSN_PORT &= ~_BV(CSN_PIN)
119+
#define CSN_HIGH() CSN_PORT |= _BV(CSN_PIN)
120+
#define CE_LOW() CE_PORT &= ~_BV(CE_PIN)
121+
#define CE_HIGH() CE_PORT |= _BV(CE_PIN)
122+
123+
124+
static void initSPI(void) {
125+
// Initialize the SPI pins: SCK, MOSI, CE, CSN as outputs, MISO as input
126+
#if defined(SPI_PINS_CE9_CSN10)
127+
// CSN_PIN (=PB2) is SS pin and set as output
128+
SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(CSN_PIN);
129+
#elif defined(SPI_PINS_CSN7_CE8)
130+
// PB2 is SS pin has to be defined as OUTPUT, else SPI goes to slave mode
131+
SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(PB2);
132+
CSN_DDR = _BV(CSN_PIN);
133+
#endif
134+
135+
// SPE = SPI enable
136+
// SPIE = SPI interrupt enable
137+
// DORD = data order (0:MSB first, 1:LSB first)
138+
// MSTR = Master/Slave select
139+
// SPR1 = SPI clock rate bit 1
140+
// SPR0 = SPI clock rate bit 0; 0,0=osc/4, 0,1=osc/16, 1,0=osc/64, 1,1=osc/128
141+
// CPOL = clock polarity idle (0:low, 1:high)
142+
// CPHA = clock phase edge sampling (0:leading, 1:trailing)
143+
144+
// SPI speed setting, nRF24L01P max. 10Mhz
145+
#if (F_CPU >= 16000000)
146+
// DIV 16 = 1 Mhz
147+
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
148+
#elif (F_CPU >= 8000000)
149+
// DIV 8 = 1 Mhz
150+
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
151+
SPSR = _BV(SPI2X);
152+
#elif (F_CPU >= 4000000)
153+
// DIV 4 = 1Mhz
154+
SPCR = _BV(SPE) | _BV(MSTR);
155+
#elif (F_CPU >= 2000000)
156+
// DIV 2 = 1 Mhz
157+
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
158+
SPSR = _BV(SPI2X);
159+
#else
160+
// DIV 2 <= 0.5 Mhz
161+
SPCR = _BV(SPE) | _BV(MSTR);
162+
SPSR = _BV(SPI2X);
163+
#endif
164+
165+
}
166+
static uint8_t SPItransfer(const uint8_t value) {
167+
SPDR = value;
168+
while(!(SPSR & _BV(SPIF))); // wait until transmitted
169+
return SPDR;
170+
}
171+
inline void SPIclose(void) {
172+
// disable hardware SPI
173+
SPCR = 0;
174+
}
175+
176+
177+
// UART
178+
static void initUART(void) {
179+
UART_SRA = _BV(U2X0); //Double speed mode USART0
180+
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
181+
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
182+
UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
183+
}
184+
185+
void putch(const uint8_t ch) {
186+
while (!(UART_SRA & _BV(UDRE0)));
187+
UART_UDR = ch;
188+
}
189+
190+
uint8_t getch(void) {
191+
// wait until char received
192+
while(!(UART_SRA & _BV(RXC0)));
193+
// 10 bytes
194+
// framing error?
195+
if (!(UART_SRA & _BV(FE0))) {
196+
watchdogReset();
197+
}
198+
return UART_UDR;
199+
}
200+
201+
static void writeTemporaryBuffer(const uint16_t address, const uint16_t data) {
202+
// fill temporary page buffer
203+
__boot_page_fill_short(address, data);
204+
}
205+
206+
static void programPage(const uint16_t page){
207+
__boot_page_erase_short(page); // erase page
208+
boot_spm_busy_wait();
209+
__boot_page_write_short(page); // program page
210+
boot_spm_busy_wait();
211+
__boot_rww_enable_short(); // re-enable RWW
212+
}
213+
214+
static uint16_t crc16_update(uint16_t crc, const uint8_t data) {
215+
crc ^= data;
216+
for (uint8_t i = 0; i < 8; ++i) {
217+
crc = (crc >> 1) ^ (-(int16_t)(crc & 1) & 0xA001);
218+
}
219+
return crc;
220+
}
221+
222+
static uint16_t calcCRCrom (const uint16_t len) {
223+
224+
uint16_t _internal_crc = 0xFFFF; // init
225+
uint16_t address = 0x0000;
226+
uint16_t count = len;
227+
228+
// prevent overflow
229+
if(count>BOOTLOADER_START_ADDRESS) {
230+
count = BOOTLOADER_START_ADDRESS;
231+
}
232+
233+
// calc
234+
while (count) {
235+
uint8_t _rom_byte;
236+
// read a flash byte and increment the address
237+
__asm__ ("lpm %0,Z+\n" : "=r" (_rom_byte), "=z" (address): "1" (address));
238+
_internal_crc = crc16_update(_internal_crc,_rom_byte);
239+
count--;
240+
}
241+
return _internal_crc;
242+
}
243+
244+
static void blinkLed(void) {
245+
LED_DDR |= _BV(LED_PIN);
246+
//300ms total
247+
uint8_t count = 6;
248+
do {
249+
LED_PORT ^= _BV(LED_PIN);
250+
_delay_ms(50);
251+
} while (--count);
252+
}
253+
254+
255+
#endif // HW_H

0 commit comments

Comments
 (0)