Revision 168
Bootloader almost works except for ctors end stuff
bootloader.c | ||
---|---|---|
14 | 14 |
#define MAX_WAIT_IN_CYCLES 800000 |
15 | 15 |
#define MAX_TIMEOUT 60000 // Seconds to wait before exiting bootloader mode |
16 | 16 |
#define MAIN_ADDR 0x000 |
17 |
#define BOOT_ADDR 0x5A0 |
|
18 |
#define JUMP_ADDR 0x590 |
|
17 |
#define BOOT_START 0x500 |
|
19 | 18 |
|
20 | 19 |
//Status LED |
21 | 20 |
#define LED_DDR DDRB |
... | ... | |
25 | 24 |
//Function prototypes |
26 | 25 |
void __init(void) __attribute__((naked)); |
27 | 26 |
|
28 |
//void onboard_program_write(uint16_t page, uint8_t *buf); |
|
29 |
void (*main_start)(void) = BOOT_ADDR - 2; |
|
30 | 27 |
|
31 |
|
|
32 | 28 |
typedef enum { |
33 | 29 |
sd, |
34 | 30 |
src, |
... | ... | |
39 | 35 |
ack |
40 | 36 |
} state_t; |
41 | 37 |
|
38 |
typedef union { |
|
39 |
uint8_t bytes[2]; |
|
40 |
int16_t sword; |
|
41 |
} rjump_t; |
|
42 |
|
|
42 | 43 |
// Redirect all unused interrupts to reti |
43 | 44 |
EMPTY_INTERRUPT(__vector_default); |
44 | 45 |
extern void __ctors_end(void) __attribute__((__noreturn__)); |
... | ... | |
97 | 98 |
} |
98 | 99 |
|
99 | 100 |
BOOTLOADER_SECTION char parse_packet(uint8_t *mbuf) { |
100 |
uint8_t r = 0; // Byte from the network |
|
101 |
uint8_t crc = 0; // Running checksum of the packet |
|
102 |
uint8_t cmd = 0; // The command received |
|
103 |
uint8_t pos = 0; // Position in the message buffer |
|
104 |
uint8_t lim = 0; // Max number of bytes to read into the message buf |
|
105 |
state_t state = sd; // State machine |
|
106 |
uint16_t count; |
|
107 |
//reset_timer(); |
|
101 |
uint8_t r; // Byte from the network |
|
102 |
uint8_t crc; // Running checksum of the packet |
|
103 |
uint8_t cmd; // The command received |
|
104 |
uint8_t pos; // Position in the message buffer |
|
105 |
uint8_t lim; // Max number of bytes to read into the message buf |
|
106 |
state_t state; // State machine |
|
107 |
uint16_t count; |
|
108 |
|
|
109 |
r = 0; |
|
110 |
crc = 0; |
|
111 |
cmd = 0; |
|
112 |
pos = 0; |
|
113 |
lim = 0; |
|
114 |
state = sd; |
|
108 | 115 |
count = 0; |
109 | 116 |
|
110 | 117 |
while (1) { |
... | ... | |
202 | 209 |
|
203 | 210 |
for (i=0; i < SPM_PAGESIZE; i+=2){ |
204 | 211 |
// Set up little-endian word. |
205 |
boot_page_fill (i, buf[i] | (buf[i+1] <<8)); |
|
212 |
boot_page_fill (page + i, buf[i] | (buf[i+1] <<8));
|
|
206 | 213 |
} |
207 | 214 |
|
208 | 215 |
boot_page_write (page); // Store buffer in flash page. |
209 | 216 |
boot_spm_busy_wait(); // Wait until the memory is written. |
210 | 217 |
} |
211 | 218 |
|
212 |
BOOTLOADER_SECTION void __init(void) {
|
|
219 |
BOOTLOADER_SECTION void main(void) {
|
|
213 | 220 |
uint8_t mbuf[PROGD_PACKET_SIZE]; |
214 |
uint8_t jbuf[2] = {0, 0};
|
|
221 |
rjump_t jbuf;
|
|
215 | 222 |
uint16_t caddr = MAIN_ADDR; |
216 |
uint8_t iteration = 0;
|
|
223 |
uint8_t iteration; |
|
217 | 224 |
uint8_t resp; |
218 |
uint16_t prog_len = 0;
|
|
225 |
uint16_t prog_len; |
|
219 | 226 |
uint8_t i; |
227 |
void (*main_start)(void); |
|
228 |
|
|
229 |
main_start = BOOT_START - 2; |
|
230 |
iteration = 0; |
|
220 | 231 |
|
221 | 232 |
init_uart(51); //MAGIC NUMBER?? |
222 | 233 |
|
... | ... | |
226 | 237 |
|
227 | 238 |
//Start bootloading process |
228 | 239 |
send_packet(TT_BOOT); |
229 |
PORTB |= _BV(PORTB0); |
|
230 | 240 |
|
231 | 241 |
resp = parse_packet(mbuf); |
232 | 242 |
if (resp == TT_PROGM) { |
233 | 243 |
prog_len = mbuf[0]; |
234 | 244 |
prog_len |= mbuf[1] << 8; |
235 | 245 |
} else { |
236 |
PORTB = 0; |
|
246 |
//PORTB = 0;
|
|
237 | 247 |
main_start(); |
238 | 248 |
} |
239 | 249 |
send_packet(TT_ACK); |
... | ... | |
244 | 254 |
if (resp == TT_PROGD) { |
245 | 255 |
if (iteration == 0) { |
246 | 256 |
// Store the jump to user code |
247 |
jbuf[0] = mbuf[0]; |
|
248 |
jbuf[1] = mbuf[1]; |
|
257 |
jbuf.bytes[0] = mbuf[0]; |
|
258 |
jbuf.bytes[1] = mbuf[1]; |
|
259 |
|
|
260 |
jbuf.sword &= 0x0FFF; |
|
261 |
jbuf.sword -= BOOT_START >> 1; |
|
262 |
jbuf.sword &= 0x0FFF; |
|
263 |
jbuf.sword |= 0xC000; |
|
249 | 264 |
|
250 |
*((uint16_t*)mbuf) = pgm_read_word(MAIN_ADDR); |
|
265 |
mbuf[0] = pgm_read_byte(MAIN_ADDR); |
|
266 |
mbuf[1] = pgm_read_byte(MAIN_ADDR + 1); |
|
267 |
//PORTB &= ~_BV(PORTB0); |
|
268 |
//while(1); |
|
251 | 269 |
|
252 | 270 |
iteration = 1; |
253 |
} |
|
271 |
} /*else { |
|
272 |
PORTB &= ~_BV(PORTB1); |
|
273 |
while(1); |
|
274 |
}*/ |
|
254 | 275 |
|
276 |
|
|
255 | 277 |
onboard_program_write(caddr, mbuf); |
256 | 278 |
caddr += PROGD_PACKET_SIZE; |
257 | 279 |
} else { |
258 | 280 |
//main_start(); |
281 |
PORTB &= ~_BV(PORTB2); |
|
259 | 282 |
while(1); |
260 | 283 |
} |
261 | 284 |
|
... | ... | |
266 | 289 |
mbuf[i]= 0; |
267 | 290 |
} |
268 | 291 |
|
269 |
mbuf[PROGD_PACKET_SIZE-2] = jbuf[0]; |
|
270 |
mbuf[PROGD_PACKET_SIZE-1] = jbuf[1]; |
|
292 |
mbuf[PROGD_PACKET_SIZE-2] = jbuf.bytes[0];
|
|
293 |
mbuf[PROGD_PACKET_SIZE-1] = jbuf.bytes[1];
|
|
271 | 294 |
|
272 |
onboard_program_write(JUMP_ADDR, mbuf);
|
|
295 |
onboard_program_write(BOOT_START - SPM_PAGESIZE, mbuf);
|
|
273 | 296 |
|
274 | 297 |
PORTB = 0; |
275 | 298 |
main_start(); |
... | ... | |
279 | 302 |
} |
280 | 303 |
} |
281 | 304 |
|
282 |
|
|
305 |
/* |
|
283 | 306 |
int main (void) { |
284 | 307 |
while(1); |
285 |
} |
|
308 |
}*/ |
Also available in: Unified diff