Project

General

Profile

Revision 189

Added by Kevin Woo about 14 years ago

Breaking up more of the bootloader into separate files

View differences:

trunk/bootloader/bootloader.h
1
#ifndef _BOOTLOADER_H_
2
#define _BOOTLOADER_H_
3

  
4
#include <avr/io.h>
5
#include <avr/boot.h>
6
#include <avr/wdt.h>
7
#include <tooltron.h>
8
#include "rs485_poll.h"
9
#include "packet.h"
10

  
11
/** @brief This is the address of the tool. Change this pre program instance */
12
#define ADDR    18
13

  
14
#endif
trunk/bootloader/packet.c
1
#include <tooltron.h>
2
#include <packet.h>
3

  
4

  
5
/**
6
 * @brief Packet handler states
7
 * @param sd Looking for a start delimiter
8
 * @param src Looking for a source
9
 * @param dest Looking for a destination
10
 * @param comd Looking for a command
11
 * @param read Reading data payload
12
 * @param cs Calcualting the checksum and returning
13
 */
14
typedef enum {
15
    sd,   
16
    src,  
17
    dest, 
18
    comd, 
19
    read, 
20
    cs    
21
} state_t;
22

  
23
/**
24
 * @brief Parses a tooltron packet
25
 * 
26
 * This is a state machine that parses the packet. It uses a software 
27
 * counter to track timeout status. The timeout is not reset unless
28
 * a fully valid packet is found. It will fail if there is a timeout,
29
 * crc error, or any error in the packet. All data will be placed in
30
 * mbuf. Note that mbuf must be able to handle PROGD_PACKET_SIZE
31
 * bytes.
32
 *
33
 * @pre mbuf is PROGD_PACKET_SIZE bytes large
34
 * @param mbuf Buffer to write the packet data payload to if there is one
35
 * @return the command received or TT_BAD on any error
36
 */
37
char parse_packet(uint8_t *mbuf) {
38
  uint8_t r;        // Byte from the network
39
  uint8_t crc;      // Running checksum of the packet
40
  uint8_t cmd;      // The command received
41
  uint8_t pos;      // Position in the message buffer
42
  uint8_t lim;      // Max number of bytes to read into the message buf
43
  state_t state;    // State machine
44
  uint16_t count;
45

  
46
  r = 0;
47
  crc = 0;
48
  cmd = 0;
49
  pos = 0;
50
  lim = 0;
51
  state = sd;
52
  count = 0;
53

  
54
  while (1) {
55
    // Wait for the next byte
56
    while ((rs485_get_byte(&r)) < 0) {
57
        if (count >= MAX_TIMEOUT) {
58
            return TT_BAD;
59
        } else {
60
            count++;
61
        }
62
    }
63

  
64
    switch (state) {
65
        case sd:
66
            if (r == DELIM) {
67
                state = src;
68
            }
69
            break;
70

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

  
80
        case dest:
81
            if (r == DELIM) {
82
                state = src;
83
            } else if (r == ADDR) {
84
                crc ^= r;
85
                state = comd;
86
            } else {
87
                state = sd;
88
            }
89
            break;
90

  
91
        case comd:
92
            cmd = r;
93
            crc ^= r;
94

  
95
            if (r == DELIM) {
96
                state = src;
97
            } else if (r == TT_PROGM) {
98
                lim = PROGM_PACKET_SIZE;
99
                state = read;
100
            } else if (r == TT_PROGD) {
101
                lim = PROGD_PACKET_SIZE;
102
                state = read;
103
            } else {
104
                state = cs;
105
            }
106
            break;
107

  
108
        case read:
109
            mbuf[pos] = r;
110
            crc ^= r;
111
            pos++;
112

  
113
            if (pos == lim) {
114
                state = cs;
115
            }
116

  
117
            break;
118
       
119
        case cs:
120
            if (r == crc) {
121
                return cmd;
122
            } else {
123
                return TT_BAD;
124
            }
125

  
126
            break;
127

  
128
        default:
129
            return TT_BAD;
130
    }
131
  }
132
}
133

  
134
/**
135
 * @brief Sends a packet of type cmd onto the network
136
 * @param cmd The command to send
137
 */
138
void send_packet(uint8_t cmd) {
139
    rs485_send_byte(DELIM);
140
    rs485_send_byte(ADDR);
141
    rs485_send_byte(SERVER);
142
    rs485_send_byte(cmd);
143
    rs485_send_byte(ACK_CRC ^ cmd);
144
}
145

  
trunk/bootloader/bootloader.c
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;
trunk/bootloader/packet.h
1
#ifndef _PACKET_H_
2
#define _PACKET_H_
3

  
4
#include "packet.h"
5
#include "rs485_poll.h"
6
#include "bootloader.h"
7

  
8
/** @brief Max time to wait until we exit the packet handler */
9
#define MAX_TIMEOUT 60000
10

  
11
char parse_packet(uint8_t *mbuf);
12
void send_packet(uint8_t cmd);
13

  
14

  
15
#endif

Also available in: Unified diff