forked from arduino/TFTP-Bootloader
/
main.c
150 lines (128 loc) · 3.66 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* Name: main.c
* Author: .
* Copyright: Arduino
* License: GPL http://www.gnu.org/licenses/gpl-2.0.html
* Project: tftpboot
* Function: Bootloader core
* Version: 0.2 support for USB flashing
*/
#include <avr/eeprom.h>
#include <avr/boot.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include "util.h"
#include "spi.h"
#include "net.h"
#include "tftp.h"
#include "serial.h"
#include "neteeprom.h"
#include "watchdog.h"
#include "debug.h"
#include "debug_main.h"
#if defined(ANNOUNCE)
#include "announce.h"
#endif
//int main(void) __attribute__((naked)) __attribute__((section(".init9")));
//void (*appStart)(void) __attribute__((naked)) = 0x0000;
//void (*appStart)(void) = 0x0000;
int main(void)
{
/* Disable the watchdog timer to prevent
* eternal reset loop of doom and despair */
MCUSR = 0;
wdt_disable();
wdt_enable(WDTO_8S);
// Wait to ensure startup of W5100
_delay_ms(200);
/* This code makes the following assumptions:
* No interrupts will execute
* SP points to RAMEND
* r1 contains zero */
//cli();
asm volatile("clr __zero_reg__");
#if defined(__AVR_ATmega8__)
SP = RAMEND; // This is done by hardware reset
#endif
// Prescaler=0, ClkIO Period = 62,5ns
// TCCR1B values:
// 0x01 -> ClkIO/1 -> 62,5ns period, 4ms max
// 0x02 -> ClkIO/8 -> 500ns period, 32ms max
// 0X03 -> ClkIO/64 -> 4us period, 256ms max
// 0x04 -> ClkIO/256 -> 16us period, 1024ms max
// 0x05 -> ClkIO/1024 -> 64us period, 4096ms max
// Set up Timer 1 as timekeeper for LED flashing
TCCR1B = _BV(CS12) | _BV(CS10); // Same thing as TCCR1B = 0x05;
/* Write version information in the EEPROM */
if(eeprom_read_byte(EEPROM_MAJVER) != ARIADNE_MAJVER)
eeprom_write_byte(EEPROM_MAJVER, ARIADNE_MAJVER);
if(eeprom_read_byte(EEPROM_MINVER) != ARIADNE_MINVER)
eeprom_write_byte(EEPROM_MINVER, ARIADNE_MINVER);
/* Initialize UART communication */
serialInit();
DBG_MAIN(tracePGMlnMain(mDebugMain_TITLE);)
DBG_BTN(
DBG_MAIN_EX(tracePGMlnMain(mDebugMain_BTN);)
buttonInit();
)
/* Initalize SPI communication */
DBG_MAIN_EX(tracePGMlnMain(mDebugMain_SPI);)
spiInit();
/* Initialize networking */
DBG_MAIN_EX(tracePGMlnMain(mDebugMain_NET);)
netInit();
/* Initialize the UDP socket for tftp */
DBG_MAIN_EX(tracePGMlnMain(mDebugMain_TFTP);)
tftpInit();
/* This code is to be used with the java-client inherited from the
* Arduino project. We don't support it and it adds about
* 600 bytes to the binary. So off it goes */
#if defined(ANNOUNCE)
DBG_MAIN_EX(tracePGMlnMain(mDebugMain_ANN);)
announceInit();
#endif
serialFlashing = FALSE;
tftpFlashing = FALSE;
for(;;) {
// If there is no serial flashing under way, poll tftp
if(!serialFlashing)
// If tftp recieved a FINAL_ACK, break
if(tftpPoll() == 0)
break;
// If there is no tftp flashing, poll serial
if(!tftpFlashing)
// If flashing is done exit
if(serialPoll() == 0)
break;
/* As explained above this goes out */
#if defined(ANNOUNCE)
announcePoll();
#endif
if(timedOut()) {
if(eeprom_read_byte(EEPROM_IMG_STAT) == EEPROM_IMG_OK_VALUE) break;
//TODO: determine the conditions for reseting server OR reseting socket
if(tftpFlashing == TRUE) {
// Delete first page of flash memory
boot_page_erase(0);
// Reinitialize TFTP
tftpInit();
// Reset the timeout counter
resetTick();
// Unset tftp flag
tftpFlashing = FALSE;
}
}
wdt_reset();
/* Blink the notification led */
updateLed();
}
/* Exit to user application */
wdt_disable(); // Disable wdt again just before user app starts
DBG_MAIN(tracePGMlnMain(mDebugMain_EXIT);)
asm volatile(
"clr r30 \n\t"
"clr r31 \n\t"
"ijmp \n\t"
);
//appStart();
//return(0); /* never reached */
}