Revision 201
- Setup bootloader to initialize pins to a known safe state
- Pulled pindefs for the toolbox out of the toolbox into common/toolbox_pindefs.h
- Shared toolbox pindefs with the bootloader
- Replaced all raw pin names with the #defined names
- Optimizied out some bytes out of the bootloader by sharing variables
trunk/toolbox/main.c | ||
---|---|---|
30 | 30 |
#include <util/delay.h> |
31 | 31 |
#include <tooltron.h> |
32 | 32 |
#include "jumptable.h" |
33 |
#include <toolbox_pindefs.h> |
|
33 | 34 |
#define TOOLBOX |
34 | 35 |
#define RELAY _BV(PORTD4) |
35 | 36 |
#define VAC_SENSE _BV(PIND3) |
... | ... | |
45 | 46 |
#define ADDR 18 |
46 | 47 |
#define DELIM '^' |
47 | 48 |
#define SERVER 1 |
48 |
#define TURNON 'O' |
|
49 |
#define TURNON 'O' 'O''0'
|
|
49 | 50 |
|
50 | 51 |
/*** |
51 | 52 |
* TWAIT - minutes to wait before green button is pressed to kill power |
... | ... | |
205 | 206 |
|
206 | 207 |
if (r == (packet[0] ^ packet[1] ^ packet[2])) { |
207 | 208 |
|
208 |
if (packet[2] == TURNON) {
|
|
209 |
if (packet[2] == TT_TON) {
|
|
209 | 210 |
state = ack; |
210 | 211 |
break; |
211 | 212 |
} |
trunk/common/toolbox_pindefs.h | ||
---|---|---|
1 |
#ifndef _TOOLBOX_PIN_DEFS_H_ |
|
2 |
#define _TOOLBOX_PIN_DEFS_H_ |
|
3 |
|
|
4 |
#include <avr/io.h> |
|
5 |
|
|
6 |
// Relay |
|
7 |
#define RELAY_PORT PORTD |
|
8 |
#define RELAY _BV(PORTD4) |
|
9 |
|
|
10 |
// AC Voltage Sense |
|
11 |
#define VAC_PORT PORTD |
|
12 |
#define VAC_SENSE _BV(PIND3) |
|
13 |
|
|
14 |
// Buttons |
|
15 |
#define BUT_PORT PINB |
|
16 |
#define BUT_RED _BV(PINB4) |
|
17 |
#define BUT_BLACK _BV(PINB3) |
|
18 |
|
|
19 |
// LEDs |
|
20 |
#define LED_PORT PORTB |
|
21 |
#define LED_GREEN _BV(PORTB2) |
|
22 |
#define LED_YELLOW _BV(PORTB1) |
|
23 |
#define LED_RED _BV(PORTB0) |
|
24 |
|
|
25 |
#endif |
trunk/common/tooltron.h | ||
---|---|---|
25 | 25 |
// Commonly used message bytes |
26 | 26 |
#define DELIM '^' |
27 | 27 |
#define SERVER 1 |
28 |
#define ACK_CRC ADDR ^ SERVER |
|
29 | 28 |
|
30 | 29 |
// These are the bytes used in the messaage types |
31 |
#define TT_GET_KEY 'k' // Get a key from the keyboard |
|
32 |
#define TT_ACK 'a' // Ack |
|
33 |
#define TT_NACK 'n' // Nack |
|
34 |
#define TT_TO 'f' // State timeout |
|
35 |
#define TT_TIMEOUT 't' // Packet timeout |
|
36 |
#define TT_RESET 'r' // Tool reset request |
|
37 |
#define TT_BOOT 'b' // Tool boot message |
|
38 |
#define TT_PROGM 'p' // Program mode request |
|
39 |
#define TT_PROGD 'd' // Program data |
|
40 |
#define TT_BAD 0 // If there was a packet parsing error |
|
30 |
#define TT_GET_KEY 'k' // Get a key from the keyboard |
|
31 |
#define TT_ACK 'a' // Ack |
|
32 |
#define TT_NACK 'n' // Nack |
|
33 |
#define TT_TON 'o' // Turn the tool on |
|
34 |
#define TT_TO 'f' // State timeout |
|
35 |
#define TT_TIMEOUT 't' // Packet timeout |
|
36 |
#define TT_RESET 'r' // Tool reset request |
|
37 |
#define TT_BOOT 'b' // Tool boot message |
|
38 |
#define TT_PROGM 'p' // Program mode request |
|
39 |
#define TT_PROGD 'd' // Program data |
|
40 |
#define TT_BAD 0 // If there was a packet parsing error |
|
41 | 41 |
|
42 | 42 |
// Number of bytes that the PROGx packets have in the payload |
43 | 43 |
#define PROGM_PACKET_SIZE 2 |
... | ... | |
49 | 49 |
// Memory locations |
50 | 50 |
#define MAIN_ADDR 0x0 // User code starts here |
51 | 51 |
#define BOOT_START 0x400 // Bootloader code starts here |
52 |
#define EEPROM_ADDR 1 // Location of the node's address in the EEPROM |
|
52 | 53 |
|
53 | 54 |
/****** Utility Definitions ******/ |
54 |
#define TRUE 0 |
|
55 |
#define FALSE 1 |
|
55 |
#define TRUE 0x00 |
|
56 |
#define FALSE 0x01 |
|
57 |
#define ON 0x01 |
|
58 |
#define OFF 0x00 |
|
56 | 59 |
#endif |
trunk/bootloader/bootloader.h | ||
---|---|---|
6 | 6 |
#include <avr/wdt.h> |
7 | 7 |
#include <avr/fuse.h> |
8 | 8 |
#include <tooltron.h> |
9 |
#include <toolbox_pindefs.h> |
|
9 | 10 |
#include "rs485_poll.h" |
10 | 11 |
#include "packet.h" |
11 | 12 |
|
12 |
/** @brief This is the address of the tool. Change this pre program instance */ |
|
13 |
//#define ADDR 18 |
|
14 |
|
|
15 | 13 |
#endif |
trunk/bootloader/bootloader.c | ||
---|---|---|
13 | 13 |
// Error thresholds |
14 | 14 |
#define MAX_RETRIES 5 // Number of times to retry before giving up |
15 | 15 |
|
16 |
//Status LED |
|
17 |
#define LED_DDR DDRB |
|
18 |
#define LED_PORT PORTB |
|
19 |
#define LED PORTB1 |
|
20 |
|
|
21 | 16 |
/** |
22 | 17 |
* Where we store the jump to user code. The jump address is in words |
23 | 18 |
* due to how the rjmp instruction works. It is 1 word below the bootloader |
... | ... | |
51 | 46 |
int main(void) { |
52 | 47 |
uint8_t mbuf[PROGD_PACKET_SIZE]; |
53 | 48 |
rjump_t jbuf; |
54 |
uint16_t caddr = MAIN_ADDR;
|
|
55 |
uint8_t iteration;
|
|
49 |
uint16_t caddr; |
|
50 |
uint16_t prog_len;
|
|
56 | 51 |
uint8_t resp; |
57 |
uint16_t prog_len; |
|
58 | 52 |
uint8_t i; |
59 | 53 |
uint8_t retries; |
60 | 54 |
uint8_t addr; |
61 | 55 |
uint8_t boot; |
62 | 56 |
|
63 |
retry_jpnt: |
|
64 |
iteration = 0; |
|
57 |
// This is where we jump to if we fail out because of retries |
|
58 |
retry_jpnt: |
|
59 |
|
|
60 |
// We set the variables here |
|
61 |
caddr = MAIN_ADDR; |
|
65 | 62 |
retries = 0; |
66 |
boot = 0; |
|
67 |
addr = eeprom_read_byte(EEPROM_ADDR); |
|
68 |
//set LED pins as output |
|
69 |
LED_DDR = 0x07; |
|
70 |
PORTB = 0x00; |
|
63 |
boot = FALSE; |
|
71 | 64 |
|
72 |
|
|
65 |
// Grab the address from EEPROM |
|
66 |
addr = eeprom_read_byte((void*)EEPROM_ADDR); |
|
67 |
|
|
68 |
// Initialize the Pins |
|
69 |
DDRB = LED_GREEN | LED_YELLOW | LED_RED; // Set the LED pins as outputs |
|
70 |
PORTB = 0x00; // LEDs on == in bootloader |
|
71 |
DDRD = RELAY; // Set Relay as an output |
|
72 |
PORTD = 0x00; // Turn relay off |
|
73 |
|
|
73 | 74 |
// Clear the watchdog timer |
74 | 75 |
if (MCUSR & _BV(WDRF)) { |
75 | 76 |
MCUSR &= ~_BV(WDRF); |
76 | 77 |
wdt_disable(); |
77 | 78 |
WDTCSR = 0; |
78 |
boot = 1;
|
|
79 |
boot = TRUE;
|
|
79 | 80 |
} |
80 | 81 |
|
81 |
if (!(PINB & (_BV(PINB3) | _BV(PINB4)))) { |
|
82 |
PORTB |= 0x01; |
|
83 |
boot = 1; |
|
82 |
if (!(BUT_PORT & (BUT_RED | BUT_BLACK))) { |
|
83 |
boot = TRUE; |
|
84 | 84 |
} |
85 | 85 |
|
86 |
// Initialize the RS485 |
|
86 | 87 |
rs485_init(BAUD9600); |
87 | 88 |
|
88 |
//Start bootloading process |
|
89 |
if (boot == 0) { |
|
90 |
PORTB |= 0x07; |
|
91 |
main_start(); |
|
89 |
//Execute user code if we aren't supposed to enter bootloading mode |
|
90 |
if (boot == FALSE) { |
|
91 |
goto run_user_code; |
|
92 | 92 |
} |
93 | 93 |
|
94 |
// Send the boot packet |
|
94 | 95 |
send_packet(TT_BOOT, addr); |
95 | 96 |
resp = parse_packet(mbuf, addr); |
96 | 97 |
|
... | ... | |
108 | 109 |
|
109 | 110 |
// Run user code |
110 | 111 |
} else { |
111 |
PORTB = 0x07; |
|
112 |
run_user_code: |
|
113 |
LED_PORT = LED_GREEN | LED_YELLOW | LED_RED; |
|
112 | 114 |
main_start(); |
113 | 115 |
} |
114 | 116 |
|
... | ... | |
119 | 121 |
|
120 | 122 |
if (resp == TT_PROGD) { |
121 | 123 |
// We need to muck with the reset vector jump in the first page |
122 |
if (iteration == 0) {
|
|
124 |
if (caddr == MAIN_ADDR) {
|
|
123 | 125 |
// Store the jump to user code |
124 | 126 |
jbuf.bytes[0] = mbuf[0]; |
125 | 127 |
jbuf.bytes[1] = mbuf[1]; |
... | ... | |
134 | 136 |
// Rewrite the reset vector to jump to the bootloader |
135 | 137 |
mbuf[0] = (BOOT_START/2 - 1) & 0xFF; |
136 | 138 |
mbuf[1] = 0xC0 | (((BOOT_START/2 - 1) >> 8) & 0x0F); |
137 |
|
|
138 |
iteration = 1; |
|
139 | 139 |
} |
140 | 140 |
|
141 | 141 |
// Write the page to the flash |
... | ... | |
167 | 167 |
|
168 | 168 |
onboard_program_write(BOOT_START - SPM_PAGESIZE, mbuf); |
169 | 169 |
|
170 |
PORTB = 0x07;
|
|
171 |
main_start();
|
|
170 |
// Jump to user code that we just wrote
|
|
171 |
goto run_user_code;
|
|
172 | 172 |
} else { |
173 | 173 |
prog_len -= PROGD_PACKET_SIZE; |
174 | 174 |
} |
trunk/programmer/test/main.c | ||
---|---|---|
28 | 28 |
#include <stdint.h> |
29 | 29 |
#include <util/delay.h> |
30 | 30 |
#include <avr/wdt.h> |
31 |
#include <avr/eeprom.h> |
|
31 | 32 |
|
32 | 33 |
#define RELAY _BV(PORTD4) |
33 | 34 |
#define VAC_SENSE _BV(PIND3) |
... | ... | |
54 | 55 |
#define TWARN 1 |
55 | 56 |
#define TMAX 2 |
56 | 57 |
|
58 |
|
|
57 | 59 |
uint8_t sec; |
58 | 60 |
uint8_t min; |
59 | 61 |
|
... | ... | |
98 | 100 |
uint8_t packet[3]; |
99 | 101 |
uint8_t ms_timer=0; |
100 | 102 |
|
103 |
uint8_t myaddr; |
|
101 | 104 |
/***** Start Start-up Sequence *****/ |
102 | 105 |
init_pins(); //Set pin directions |
103 | 106 |
// init_uart(51); //Set registers for uart |
104 | 107 |
/***** End Start-up Sequence *****/ |
105 | 108 |
|
106 | 109 |
uint8_t r; |
107 |
|
|
108 |
PORTB &= ~_BV(PORTB0); |
|
109 | 110 |
|
110 |
_delay_ms(1000); |
|
111 |
PORTB |= _BV(PORTB0); |
|
112 |
_delay_ms(1000); |
|
113 |
reset(); |
|
111 |
//eeprom_write_byte(1, 18); |
|
114 | 112 |
|
113 |
PORTB = 0x7; |
|
114 |
|
|
115 |
//myaddr = eeprom_read_byte(1); |
|
116 |
//if (myaddr == 18) { |
|
117 |
// PORTB = 0x7; |
|
118 |
//} |
|
119 |
//_delay_ms(1000); |
|
120 |
//PORTB |= _BV(PORTB0); |
|
121 |
//_delay_ms(1000); |
|
122 |
//reset(); |
|
123 |
|
|
115 | 124 |
while(1) { |
125 |
_delay_ms(1000); |
|
126 |
PORTB |= _BV(PORTB0); |
|
127 |
_delay_ms(1000); |
|
128 |
PORTB &= ~_BV(PORTB0); |
|
116 | 129 |
} |
117 | 130 |
|
118 | 131 |
return 0; |
Also available in: Unified diff