Revision 189 trunk/bootloader/bootloader.c

bootloader.c (revision 189)
1
#include <avr/io.h>
2
#include <avr/boot.h>
3
#include <avr/wdt.h>
4
#include <tooltron.h>
5
#include <rs485_poll.h>
1
#include "bootloader.h"
6 2

  
7
#define ADDR    18
8 3

  
9 4
// Error thresholds
10
#define MAX_TIMEOUT 60000   // Seconds to wait before exiting bootloader mode
11 5
#define MAX_RETRIES 5       // Number of times to retry before giving up
12 6

  
13 7
//Status LED
......
24 18
} rjump_t;
25 19

  
26 20

  
27
char parse_packet(uint8_t *mbuf) {
28
  uint8_t r;        // Byte from the network
29
  uint8_t crc;      // Running checksum of the packet
30
  uint8_t cmd;      // The command received
31
  uint8_t pos;      // Position in the message buffer
32
  uint8_t lim;      // Max number of bytes to read into the message buf
33
  state_t state;    // State machine
34
  uint16_t count;
35

  
36
  r = 0;
37
  crc = 0;
38
  cmd = 0;
39
  pos = 0;
40
  lim = 0;
41
  state = sd;
42
  count = 0;
43

  
44
  while (1) {
45
    // Wait for the next byte
46
    while ((rs485_get_byte(&r)) < 0) {
47
        if (count >= MAX_TIMEOUT) {
48
            return TT_BAD;
49
        } else {
50
            count++;
51
        }
52
    }
53

  
54
    switch (state) {
55
        case sd:
56
            if (r == DELIM) {
57
                state = src;
58
            }
59
            break;
60

  
61
        case src:
62
            if (r == DELIM) {
63
                state = src;
64
            } else {
65
                crc = r;
66
                state = dest;
67
            }
68
            break;
69

  
70
        case dest:
71
            if (r == DELIM) {
72
                state = src;
73
            } else if (r == ADDR) {
74
                crc ^= r;
75
                state = comd;
76
            } else {
77
                state = sd;
78
            }
79
            break;
80

  
81
        case comd:
82
            cmd = r;
83
            crc ^= r;
84

  
85
            if (r == DELIM) {
86
                state = src;
87
            } else if (r == TT_PROGM) {
88
                lim = PROGM_PACKET_SIZE;
89
                state = read;
90
            } else if (r == TT_PROGD) {
91
                lim = PROGD_PACKET_SIZE;
92
                state = read;
93
            } else {
94
                state = cs;
95
            }
96
            break;
97

  
98
        case read:
99
            mbuf[pos] = r;
100
            crc ^= r;
101
            pos++;
102

  
103
            if (pos == lim) {
104
                state = cs;
105
            }
106

  
107
            break;
108
       
109
        case cs:
110
            if (r == crc) {
111
                return cmd;
112
            } else {
113
                return TT_BAD;
114
            }
115

  
116
            break;
117

  
118
        default:
119
            return TT_BAD;
120
    }
121
  }
122
}
123

  
124
void send_packet(uint8_t cmd) {
125
    rs485_send_byte(DELIM);
126
    rs485_send_byte(ADDR);
127
    rs485_send_byte(SERVER);
128
    rs485_send_byte(cmd);
129
    rs485_send_byte(ACK_CRC ^ cmd);
130
}
131

  
132 21
// SPM_PAGESIZE is set to 32 bytes
133 22
void onboard_program_write(uint16_t page, uint8_t *buf) {
134 23
  uint16_t i;

Also available in: Unified diff