Project

General

Profile

Revision 156

Added by Kevin Woo about 14 years ago

Added a packet parser and ack generator to the bootloader. Also added the new mesages to the tooltron.h file

View differences:

bootloader.c
1
/*
2
    1-24-09
3
    Copyright Spark Fun Electronics? 2009
4
    Nathan Seidle
5
    
6
    Wireless bootloader for the ATmega168 and XBee Series 1 modules
7
	
8
	This is a small (728 byte) serial bootloader designed to be a robust solution for remote reset and wireless
9
	booloading. It's not extremely fast, but is very hardy.
10
    
11
	The remote unit (the AVR usually) broadcasts the non-visible character ASCII(6). It then waits for a response
12
	over the serial link for the non-visible character ASCII(5). If received, the remote unit enters bootloading mode.
13
	If the correct character 5 is not received, the remote unit jumps to the beginning of the regular program code.
14
	
15
	Bootloading includes checksum calculation, and timeouts. Timeouts is most important because a wireless
16
	link does not always deliver segments of the serial stream in a deterministic fashion - a good wireless unit
17
	will buffer all sorts of stuff, making the connection stream irregular in throughput.
18
	
19
	This bootloader accepts a pure binary stream (not an intel hex file format). All file parsing is done on the 
20
	base side (usually a beefy computer with lots of extra processing ability).
21
	
22
	Things I learned from testing:
23
	
24
	XBee series 2.5 units have their uses, but not here. I beat my head against the wall trying to form a sensible link and failed.
25
	Ultimately, plugging series 1 in, it worked wonderfully. If you need point-to-point, series 1 is wonderful. If you really
26
	need true mesh node networking, Series 2.5 is good.
27
	
28
	XBee Series 2.5 ships with CTS enabled! That's why the AT commands through hyperterminal were not working. Grr.
29
	
30
	To get a Series 2.5 link to work, you must configure device on XBee Explorer as Coordinator, and the device in your arduino board as the end device.
31
	
32
	Trying to use Series 2.5 for a good point-to-point link:
33
	With CTS Enabled, 19200bps, Packetization Timeout at 3 (default), still bit errors, even with 1ms delay between characters
34
	With CTS Enabled, 19200bps, Packetization Timeout at 0, with 1ms delay between characters helps a lot, but will get character errors if there is RF interferance (units further than a few feet apart)
35 1

  
36
	With CTS/RTS Enabled, 19200bps, Packet timeout at 0, no delay but with flow control, we have very solid link -> one way!
37
	while( (PIND & (1<<CTS)) != 0); //Don't send anything to the XBee, it is thinking
38
	
39
	You do not seem to need CTS/RTS/DTR to read or program an XBee.
40 2

  
41
	With XB24-ZB unit, the end device can transmit all it wants, the coordinator seems to die after a few seconds. This
42
	was the ultimate downfall of the series 2.5 for me. The link would work, but the coordinator would drop off after a few
43
	seconds? Series 1 did not do this.
44
	
45
	All of the following code works exceptionally well with Series 1 "XB24" "XBee 802.15.4" "v10CD" firmware
46
	
47
	To configure the XBees, follow "Lady Ada wireless arduino" info
48

  
49
	Series 1 module settings:
50
	Baud: 19200
51
	No flow control (CTS is left on as default)
52
	No change to packetization timeout (default = 3?)
53
	
54
	RTS on XBee board goes up and down with the com advanced trick NOT checked, and hardware control turned ON under terminal
55

  
56
	In VB, turn handshaking off. When RTSEnable = True, the RTS pin goes low, resetting the AVR
57

  
58
	Wireless:
59
	38 seconds to load 14500 code words (most of the space) at 38400 / 8MHz (internal osc)
60
	38 seconds to load 14500 code words (most of the space) at 19200 / 8MHz (internal osc)
61
	Wired:
62
	11 seconds to load 14500 code words (most of the space) at 19200 / 8MHz (internal osc)
63
	so you see, there is no benefit to a higher baud rate. The XBee protocol is the bottleneck
64

  
65
	How to read the flash contents to file : 
66
	avrdude -c stk200 -p m168 -P lpt1 -Uflash:r:bl.hex:i
67
	This will dump the current flash contents of an AVR to a read-able hex file called "bl.hex". This
68
	was very helpful when testing whether flash writing was actually working.
69

  
70
	Oh, and if you happen to be using an XBee with a UFL antenna connector (and don't have a UFL antenna sitting around)
71
	you can convert it to a wire antenna simply by soldering in a short wire into the XBee. It may not be the best, 
72
	but it works.
73

  
74
*/
75

  
76

  
77 3
#include <avr/io.h>
78 4
#include <util/delay.h>
79 5
#include <avr/boot.h>
80 6

  
7
#include "tooltron.h"
81 8
#include "uart.h"
82 9

  
83 10
#define TRUE	0
84 11
#define FALSE	1
85 12

  
13
#define ADDR    18
14

  
15

  
86 16
#define MAX_WAIT_IN_CYCLES 800000
87 17

  
88 18
//Status LED
......
109 39

  
110 40
char getch(void);
111 41

  
42
typedef enum {
43
    sd,
44
    src,
45
    dest,
46
    comd,
47
    read,
48
    cs,
49
    ack
50
} state_t;
51

  
52

  
53
char parse_packet(char *mbuf) {
54
  uint8_t r;        // Byte from the network
55
  uint8_t crc;      // Running checksum of the packet
56
  uint8_t cmd;      // The command received
57
  uint8_t pos;      // Position in the message buffer
58
  uint8_t lim;      // Max number of bytes to read into the message buf
59
  state_t state;    // State machine
60

  
61
  while (1) {
62
    // Wait for the next byte
63
    while ((uart_get_byte(&r)) < 0);
64

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

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

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

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

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

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

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

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

  
127
            break;
128

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

  
135
void send_ack(void) {
136
    uart_send_byte(DELIM);
137
    uart_send_byte(ADDR);
138
    uart_send_byte(SERVER);
139
    uart_send_byte(TT_ACK);
140
    uart_send_byte(ACK_CRC);
141
}
142

  
112 143
int main(void)
113 144
{
114 145
  uint8_t check_sum = 0;
......
128 159
  //Check to see if the computer responded
129 160
  uint32_t count = 0;
130 161
  uint8_t resp;
162

  
131 163
  while(uart_get_byte(&resp) == -1) {
132 164
    count++;
133 165
    if (count > MAX_WAIT_IN_CYCLES)

Also available in: Unified diff