Root/fw/fw.c

Source at commit 0f17c404d2bf724b17d8443d6b76701f50be673d created 11 years 6 days ago.
By Werner Almesberger, BOOKSHELF: add data sheets of parts for next Tornado iteration
1/*
2 * fw/fw.h - Firmware upload protocol
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdbool.h>
15#include <stdint.h>
16#include <string.h>
17
18#define F_CPU 8000000UL
19#include <util/delay.h>
20
21#include "io.h"
22#include "flash.h"
23#include "proto.h"
24#include "rf.h"
25#include "fw.h"
26
27
28static const uint8_t unlock_secret[PAYLOAD] = {
29    #include "unlock-secret.inc"
30};
31
32
33static bool locked = 1;
34
35
36static bool fw_payload(uint8_t seq, uint8_t limit, const uint8_t *payload)
37{
38    if (!seq) {
39        locked = memcmp(unlock_secret, payload, PAYLOAD) != 0;
40        flash_start();
41        return 1;
42    }
43    if (locked)
44        return 0;
45    if (!flash_can_write(PAYLOAD))
46        return 0;
47    flash_write(payload, PAYLOAD);
48    if (seq == limit)
49        flash_end_write();
50    return 1;
51}
52
53
54bool fw_packet(const uint8_t *buf, uint8_t len)
55{
56    static uint8_t seq = 0;
57    static uint8_t limit;
58    uint8_t ack[] = { FIRMWARE+1, buf[1], buf[2] };
59
60    /* short flash to indicate reception */
61    SET(LED_B7);
62    _delay_ms(1);
63    CLR(LED_B7);
64
65    /* Check packet for formal validity */
66
67    if (len != 64+3)
68        return 0;
69    if (buf[0] != FIRMWARE)
70        return 0;
71    if (buf[1] > buf[2])
72        return 0;
73
74    /* Synchronize sequence numbers */
75
76    if (!buf[1]) {
77        seq = 0;
78        limit = buf[2];
79    } else {
80        if (buf[2] != limit)
81            return 0;
82        if (buf[1]+1 == seq)
83            goto ack;
84        if (buf[1] != seq)
85            return 0;
86    }
87
88    /* Process the payload */
89
90    if (!fw_payload(seq, limit, buf+3))
91        return 0;
92    seq++;
93ack:
94    /* clearly visible short blink to indicate progress */
95    SET(LED_B6);
96    rf_send(ack, sizeof(ack));
97    CLR(LED_B6);
98    return 1;
99}
100

Archive Download this file

Branches:
master
tornado-v1



interactive