mirror of
git://projects.qi-hardware.com/antorcha.git
synced 2024-11-22 08:57:31 +02:00
RESET protocol to jump from application to boot loader without power cycling
This commit is contained in:
parent
683056bca7
commit
cc4b5607c7
2
PROTOCOL
2
PROTOCOL
@ -7,6 +7,8 @@ Protocol
|
|||||||
|
|
||||||
1 0 0 Pong (maybe return version string in the future)
|
1 0 0 Pong (maybe return version string in the future)
|
||||||
|
|
||||||
|
2 0 0 Reset (64 bytes reset secret)
|
||||||
|
|
||||||
4 0 N Unlock secret (64 bytes payload)
|
4 0 N Unlock secret (64 bytes payload)
|
||||||
4 1..N-1 N Firmware binary (64 bytes payload)
|
4 1..N-1 N Firmware binary (64 bytes payload)
|
||||||
4 N N First half of hash
|
4 N N First half of hash
|
||||||
|
@ -30,7 +30,7 @@ OBJCOPY = $(AVR_PREFIX)objcopy
|
|||||||
#OBJDUMP = $(AVR_PREFIX)objdump
|
#OBJDUMP = $(AVR_PREFIX)objdump
|
||||||
SIZE = $(AVR_PREFIX)size
|
SIZE = $(AVR_PREFIX)size
|
||||||
|
|
||||||
OBJS = $(NAME).o dispatch.o hash.o $(COMMON_OBJS)
|
OBJS = $(NAME).o dispatch.o hash.o reset.o $(COMMON_OBJS)
|
||||||
BOOT_OBJS = boot.o flash.o fw.o $(COMMON_OBJS)
|
BOOT_OBJS = boot.o flash.o fw.o $(COMMON_OBJS)
|
||||||
COMMON_OBJS = rf.o spi.o
|
COMMON_OBJS = rf.o spi.o
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ clean:
|
|||||||
rm -f version.c version.d version.o
|
rm -f version.c version.d version.o
|
||||||
|
|
||||||
nosecrets:
|
nosecrets:
|
||||||
rm -f unlock-secret.inc image-secret.inc
|
rm -f unlock-secret.inc reset-secret.inc image-secret.inc
|
||||||
|
|
||||||
# ----- Build version ---------------------------------------------------------
|
# ----- Build version ---------------------------------------------------------
|
||||||
|
|
||||||
@ -129,10 +129,14 @@ SECRET = { dd if=$(RANDOM) iflag=fullblock bs=$(1) count=1 status=noxfer | \
|
|||||||
unlock-secret.inc:
|
unlock-secret.inc:
|
||||||
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
|
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
|
||||||
|
|
||||||
|
reset-secret.inc:
|
||||||
|
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
|
||||||
|
|
||||||
image-secret.inc:
|
image-secret.inc:
|
||||||
$(BUILD) $(call SECRET,128) >$@ || { rm -f $@; exit 1; }
|
$(BUILD) $(call SECRET,128) >$@ || { rm -f $@; exit 1; }
|
||||||
|
|
||||||
fw.o: unlock-secret.inc
|
fw.o: unlock-secret.inc
|
||||||
|
reset.o: unlock-secret.inc
|
||||||
|
|
||||||
# ----- Dependencies ----------------------------------------------------------
|
# ----- Dependencies ----------------------------------------------------------
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
#include "dispatch.h"
|
#include "dispatch.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const struct handler *protos[] = {
|
static const struct handler *protos[] = {
|
||||||
|
&reset_handler,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,12 +39,6 @@ int main(void)
|
|||||||
* It has also brought up RF and the underlying SPI.
|
* It has also brought up RF and the underlying SPI.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (1) {
|
|
||||||
SET(LED_B8);
|
|
||||||
_delay_ms(100);
|
|
||||||
CLR(LED_B8);
|
|
||||||
_delay_ms(100);
|
|
||||||
}
|
|
||||||
while (1) {
|
while (1) {
|
||||||
got = rf_recv(buf, sizeof(buf));
|
got = rf_recv(buf, sizeof(buf));
|
||||||
if (got > 2)
|
if (got > 2)
|
||||||
|
12
fw/boot.c
12
fw/boot.c
@ -57,9 +57,19 @@ int main(void)
|
|||||||
PORTD = 0;
|
PORTD = 0;
|
||||||
DDRD = 0xff;
|
DDRD = 0xff;
|
||||||
|
|
||||||
/* disable pull-ups */
|
/* Disable pull-ups */
|
||||||
MCUCR |= 1 << PUD;
|
MCUCR |= 1 << PUD;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the watchdog timer, in case the boot loader has been
|
||||||
|
* entered by a watchdog reset commanded by the application.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MCUSR = 0; /* Remove override */
|
||||||
|
WDTCSR |= 1 << WDCE; /* Enable change */
|
||||||
|
WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
|
||||||
|
change */
|
||||||
|
|
||||||
rf_init();
|
rf_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,6 +26,8 @@ struct handler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern struct handler reset_handler;
|
||||||
|
|
||||||
bool dispatch(const uint8_t *buf, uint8_t len, const struct handler **protos);
|
bool dispatch(const uint8_t *buf, uint8_t len, const struct handler **protos);
|
||||||
|
|
||||||
#endif /* !PROTO_H */
|
#endif /* !PROTO_H */
|
||||||
|
6
fw/fw.c
6
fw/fw.c
@ -15,6 +15,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define F_CPU 8000000UL
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
@ -54,8 +57,9 @@ bool fw_packet(const uint8_t *buf, uint8_t len)
|
|||||||
static uint8_t limit;
|
static uint8_t limit;
|
||||||
uint8_t ack[] = { FIRMWARE+1, buf[1], buf[2] };
|
uint8_t ack[] = { FIRMWARE+1, buf[1], buf[2] };
|
||||||
|
|
||||||
/* short (barely visible) flash to indicate reception */
|
/* short flash to indicate reception */
|
||||||
SET(LED_B7);
|
SET(LED_B7);
|
||||||
|
_delay_ms(1);
|
||||||
CLR(LED_B7);
|
CLR(LED_B7);
|
||||||
|
|
||||||
/* Check packet for formal validity */
|
/* Check packet for formal validity */
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
enum pck_type {
|
enum pck_type {
|
||||||
PING = 0, /* version query */
|
PING = 0, /* version query */
|
||||||
PONG = 1, /* version response */
|
PONG = 1, /* version response */
|
||||||
|
RESET = 2, /* reset to boot loader */
|
||||||
FIRMWARE = 4, /* firmware upload */
|
FIRMWARE = 4, /* firmware upload */
|
||||||
FIRMWARE_ACK = 5, /* firmware upload acknowledgement */
|
FIRMWARE_ACK = 5, /* firmware upload acknowledgement */
|
||||||
IMAGE = 6, /* image upload */
|
IMAGE = 6, /* image upload */
|
||||||
|
@ -49,6 +49,7 @@ static void rf_send(struct atrf_dsc *dsc, void *buf, int len)
|
|||||||
/* Copy the message to append the CRC placeholders */
|
/* Copy the message to append the CRC placeholders */
|
||||||
memcpy(tmp, buf, len);
|
memcpy(tmp, buf, len);
|
||||||
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
|
||||||
|
flush_interrupts(dsc);
|
||||||
atrf_buf_write(dsc, tmp, len+2);
|
atrf_buf_write(dsc, tmp, len+2);
|
||||||
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
|
||||||
wait_for_interrupt(dsc, IRQ_TRX_END,
|
wait_for_interrupt(dsc, IRQ_TRX_END,
|
||||||
@ -98,17 +99,25 @@ static void ping(struct atrf_dsc *dsc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void packet(struct atrf_dsc *dsc,
|
static void packet_noack(struct atrf_dsc *dsc,
|
||||||
uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
|
uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
|
||||||
{
|
{
|
||||||
uint8_t tx_buf[PAYLOAD+3] = { type, seq, last };
|
uint8_t tx_buf[PAYLOAD+3] = { type, seq, last };
|
||||||
uint8_t rx_buf[10];
|
|
||||||
int got;
|
|
||||||
|
|
||||||
assert(len == PAYLOAD);
|
assert(len == PAYLOAD);
|
||||||
memcpy(tx_buf+3, payload, len);
|
memcpy(tx_buf+3, payload, len);
|
||||||
|
rf_send(dsc, tx_buf, sizeof(tx_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void packet(struct atrf_dsc *dsc,
|
||||||
|
uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
|
||||||
|
{
|
||||||
|
uint8_t rx_buf[10];
|
||||||
|
int got;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
rf_send(dsc, tx_buf, sizeof(tx_buf));
|
packet_noack(dsc, type, seq, last, payload, len);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
write(2, ">", 1);
|
write(2, ">", 1);
|
||||||
got = rf_recv(dsc, rx_buf, sizeof(rx_buf));
|
got = rf_recv(dsc, rx_buf, sizeof(rx_buf));
|
||||||
@ -146,6 +155,7 @@ static void send_firmware(struct atrf_dsc *dsc, void *buf, int len)
|
|||||||
write(2, "firmware ", 9);
|
write(2, "firmware ", 9);
|
||||||
last = (len+63)/64;
|
last = (len+63)/64;
|
||||||
seq = 0;
|
seq = 0;
|
||||||
|
packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
|
||||||
packet(dsc, FIRMWARE, seq++, last, unlock_secret, PAYLOAD);
|
packet(dsc, FIRMWARE, seq++, last, unlock_secret, PAYLOAD);
|
||||||
while (len >= PAYLOAD) {
|
while (len >= PAYLOAD) {
|
||||||
packet(dsc, FIRMWARE, seq++, last, buf, PAYLOAD);
|
packet(dsc, FIRMWARE, seq++, last, buf, PAYLOAD);
|
||||||
|
Loading…
Reference in New Issue
Block a user