mirror of
git://projects.qi-hardware.com/antorcha.git
synced 2024-12-22 18:22:05 +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)
|
||||
|
||||
2 0 0 Reset (64 bytes reset secret)
|
||||
|
||||
4 0 N Unlock secret (64 bytes payload)
|
||||
4 1..N-1 N Firmware binary (64 bytes payload)
|
||||
4 N N First half of hash
|
||||
|
@ -30,7 +30,7 @@ OBJCOPY = $(AVR_PREFIX)objcopy
|
||||
#OBJDUMP = $(AVR_PREFIX)objdump
|
||||
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)
|
||||
COMMON_OBJS = rf.o spi.o
|
||||
|
||||
@ -87,7 +87,7 @@ clean:
|
||||
rm -f version.c version.d version.o
|
||||
|
||||
nosecrets:
|
||||
rm -f unlock-secret.inc image-secret.inc
|
||||
rm -f unlock-secret.inc reset-secret.inc image-secret.inc
|
||||
|
||||
# ----- Build version ---------------------------------------------------------
|
||||
|
||||
@ -129,10 +129,14 @@ SECRET = { dd if=$(RANDOM) iflag=fullblock bs=$(1) count=1 status=noxfer | \
|
||||
unlock-secret.inc:
|
||||
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
|
||||
|
||||
reset-secret.inc:
|
||||
$(BUILD) $(call SECRET,64) >$@ || { rm -f $@; exit 1; }
|
||||
|
||||
image-secret.inc:
|
||||
$(BUILD) $(call SECRET,128) >$@ || { rm -f $@; exit 1; }
|
||||
|
||||
fw.o: unlock-secret.inc
|
||||
reset.o: unlock-secret.inc
|
||||
|
||||
# ----- Dependencies ----------------------------------------------------------
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include "dispatch.h"
|
||||
|
||||
|
||||
|
||||
static const struct handler *protos[] = {
|
||||
&reset_handler,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -39,12 +39,6 @@ int main(void)
|
||||
* 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) {
|
||||
got = rf_recv(buf, sizeof(buf));
|
||||
if (got > 2)
|
||||
|
12
fw/boot.c
12
fw/boot.c
@ -57,9 +57,19 @@ int main(void)
|
||||
PORTD = 0;
|
||||
DDRD = 0xff;
|
||||
|
||||
/* disable pull-ups */
|
||||
/* Disable pull-ups */
|
||||
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();
|
||||
|
||||
/*
|
||||
|
@ -26,6 +26,8 @@ struct handler {
|
||||
};
|
||||
|
||||
|
||||
extern struct handler reset_handler;
|
||||
|
||||
bool dispatch(const uint8_t *buf, uint8_t len, const struct handler **protos);
|
||||
|
||||
#endif /* !PROTO_H */
|
||||
|
6
fw/fw.c
6
fw/fw.c
@ -15,6 +15,9 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define F_CPU 8000000UL
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "flash.h"
|
||||
#include "proto.h"
|
||||
@ -54,8 +57,9 @@ bool fw_packet(const uint8_t *buf, uint8_t len)
|
||||
static uint8_t limit;
|
||||
uint8_t ack[] = { FIRMWARE+1, buf[1], buf[2] };
|
||||
|
||||
/* short (barely visible) flash to indicate reception */
|
||||
/* short flash to indicate reception */
|
||||
SET(LED_B7);
|
||||
_delay_ms(1);
|
||||
CLR(LED_B7);
|
||||
|
||||
/* Check packet for formal validity */
|
||||
|
@ -18,6 +18,7 @@
|
||||
enum pck_type {
|
||||
PING = 0, /* version query */
|
||||
PONG = 1, /* version response */
|
||||
RESET = 2, /* reset to boot loader */
|
||||
FIRMWARE = 4, /* firmware upload */
|
||||
FIRMWARE_ACK = 5, /* firmware upload acknowledgement */
|
||||
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 */
|
||||
memcpy(tmp, buf, len);
|
||||
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
|
||||
flush_interrupts(dsc);
|
||||
atrf_buf_write(dsc, tmp, len+2);
|
||||
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
|
||||
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 tx_buf[PAYLOAD+3] = { type, seq, last };
|
||||
uint8_t rx_buf[10];
|
||||
int got;
|
||||
|
||||
assert(len == PAYLOAD);
|
||||
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) {
|
||||
rf_send(dsc, tx_buf, sizeof(tx_buf));
|
||||
packet_noack(dsc, type, seq, last, payload, len);
|
||||
if (verbose)
|
||||
write(2, ">", 1);
|
||||
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);
|
||||
last = (len+63)/64;
|
||||
seq = 0;
|
||||
packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
|
||||
packet(dsc, FIRMWARE, seq++, last, unlock_secret, PAYLOAD);
|
||||
while (len >= PAYLOAD) {
|
||||
packet(dsc, FIRMWARE, seq++, last, buf, PAYLOAD);
|
||||
|
Loading…
Reference in New Issue
Block a user