55 #include "contiki-net.h"
56 #include "sys/clock.h"
58 #include "dev/watchdog.h"
65 #define DEBUG DEBUG_NONE
68 #if BATMON_CONF_ENABLED
69 void batmon_log(uint8_t trigger);
71 #define LOG_TRIGGER_OAP_DISCO_START 0x01
72 #define LOG_TRIGGER_OAP_DISCO_DONE 0x02
73 #define LOG_TRIGGER_OAP_DISCO_ABORT 0x03
75 #define batmon_log(t) do { } while(0);
79 static struct disco_request_pdu *req;
80 static struct disco_response_pdu resp;
81 static struct disco_seed seed;
83 static uint8_t sector;
84 static uint16_t interval;
85 static struct ctimer disco_timer;
87 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
88 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
93 __xdata
__at(BOOTTY_CMD_LOCATION) static uint8_t bd;
95 static
void timer_handler(
void *p);
101 n740_analog_deactivate();
103 n740_analog_activate();
104 state = DISCO_STATE_LISTENING;
105 memset(&seed, 0,
sizeof(seed));
107 batmon_log(LOG_TRIGGER_OAP_DISCO_ABORT);
111 restart_timer(uint16_t t) CC_NON_BANKED
115 ctimer_set(&disco_timer, interval, timer_handler, &state);
119 timer_handler(
void *p)
126 if(*s == DISCO_STATE_PREPARING) {
127 n740_analog_deactivate();
129 n740_analog_activate();
132 restart_timer(DISCO_TIMEOUT_PREPARE);
134 PRINTF(
"Disco: Erased %u\n", sector);
135 if((sector & 1) == 0) {
137 PRINTF(
"Disco: Next %u\n", sector);
138 n740_analog_deactivate();
140 n740_analog_activate();
141 restart_timer(DISCO_TIMEOUT_PREPARE);
143 PRINTF(
"Disco: Ready\n");
144 *s = DISCO_STATE_READY;
145 resp.status = DISCO_CMD_INIT;
146 restart_timer(DISCO_TIMEOUT_ABORT);
147 server_conn->
rport = seed.port;
149 uip_udp_packet_send(server_conn, &resp, DISCO_RESP_LEN_INIT);
153 server_conn->
rport = 0;
156 }
else if(*s == DISCO_STATE_READY) {
158 }
else if(*s == DISCO_STATE_REBOOTING) {
164 is_protected(uint8_t a) CC_NON_BANKED
169 return SECTOR_PROTECTED;
174 if(a >= (32 - (1 << bp))) {
175 return SECTOR_PROTECTED;
177 return SECTOR_UNPROTECTED;
181 cmd_init() CC_NON_BANKED
183 PRINTF(
"Disco: Init 0x%02x\n", req->addr[0]);
186 resp.status = DISCO_ERR_BAD_LEN;
187 return DISCO_RESP_LEN_ERR;
189 n740_analog_deactivate();
191 sector = 2 * req->addr[0];
192 if(is_protected(sector) == SECTOR_PROTECTED
193 || is_protected(sector + 1) == SECTOR_PROTECTED) {
194 resp.status = DISCO_ERR_PROTECTED;
195 n740_analog_activate();
196 return DISCO_RESP_LEN_ERR;
199 n740_analog_activate();
200 state = DISCO_STATE_PREPARING;
201 restart_timer(DISCO_TIMEOUT_PREPARE);
204 seed.port = UIP_UDP_BUF->srcport;
206 PRINTF(
"Disco: OK\n");
208 batmon_log(LOG_TRIGGER_OAP_DISCO_START);
210 return DISCO_RESPONSE_NONE;
214 cmd_write() CC_NON_BANKED
216 PRINTF(
"Disco: Write 0x%02x%02x%02x\n", req->addr[0], req->addr[1],
219 resp.status = DISCO_ERR_BAD_LEN;
220 return DISCO_RESP_LEN_ERR;
222 restart_timer(DISCO_TIMEOUT_ABORT);
223 n740_analog_deactivate();
224 m25p16_pp(req->addr, req->data, DISCO_FLEN_DATA);
227 n740_analog_activate();
228 resp.status = DISCO_CMD_WRITE;
229 memcpy(resp.addr, req->addr, DISCO_FLEN_ADDR);
230 return DISCO_RESP_LEN_WRITE;
234 cmd_switch() CC_NON_BANKED
236 PRINTF(
"Disco: Switch 0x%02x\n", req->addr[0]);
238 resp.status = DISCO_ERR_BAD_LEN;
239 return DISCO_RESP_LEN_ERR;
241 if(req->addr[0] > 15) {
242 resp.status = DISCO_ERR_BAD_OFFSET;
243 return DISCO_RESP_LEN_ERR;
246 bd = BOOTTY_CMD_COPY_IMAGE;
249 resp.status = DISCO_CMD_SWITCH;
250 resp.addr[0] = req->addr[0];
252 restart_timer(DISCO_TIMEOUT_REBOOT);
253 state = DISCO_STATE_REBOOTING;
255 return DISCO_RESP_LEN_SWITCH;
259 cmd_done() CC_NON_BANKED
261 PRINTF(
"Disco: Done\n");
263 resp.status = DISCO_ERR_BAD_LEN;
264 return DISCO_RESP_LEN_ERR;
266 resp.status = DISCO_CMD_DONE;
268 batmon_log(LOG_TRIGGER_OAP_DISCO_DONE);
270 return DISCO_RESP_LEN_DONE;
274 event_handler(process_event_t ev) CC_NON_BANKED
276 uint8_t rv = DISCO_RESPONSE_NONE;
283 if(req->cmd == DISCO_CMD_DONE) {
288 if(req->cmd == DISCO_CMD_SWITCH) {
293 case DISCO_STATE_LISTENING:
295 if(req->cmd == DISCO_CMD_INIT) {
299 case DISCO_STATE_PREPARING:
300 PRINTF(
"Disco: Not Ready\n");
301 resp.status = DISCO_ERR_NOT_READY;
302 rv = DISCO_RESP_LEN_ERR;
304 case DISCO_STATE_READY:
306 if(req->cmd == DISCO_CMD_WRITE) {
308 }
else if(req->cmd == DISCO_CMD_INIT) {
309 resp.status = DISCO_ERR_INIT_DONE;
310 rv = DISCO_RESP_LEN_ERR;
311 }
else if(req->cmd == DISCO_CMD_SWITCH) {
319 PROCESS(disco_process,
"Disco Server Process");
327 PRINTF(
"Disco Server\n");
332 state = DISCO_STATE_LISTENING;
336 len = event_handler(ev);
339 server_conn->
rport = UIP_UDP_BUF->srcport;
341 uip_udp_packet_send(server_conn, &resp, len);
344 server_conn->
rport = 0;