00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #define DEBUG 0 //Making this 1 will slightly alter command timings
00058 #if DEBUG
00059 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
00060 #else
00061 #define PRINTF(...)
00062 #endif
00063 #define DEBUGSERIAL 0 //Making this 1 will significantly alter command timings
00064
00065 #include "contiki.h"
00066 #include "contiki-lib.h"
00067 #include "contiki-net.h"
00068 #include "webserver-nogui.h"
00069 #include "httpd-cgi.h"
00070 #include "raven-lcd.h"
00071
00072 #include <string.h>
00073 #include <stdio.h>
00074 #include <avr/pgmspace.h>
00075 #include <avr/eeprom.h>
00076 #include <avr/sleep.h>
00077 #include <dev/watchdog.h>
00078
00079 static u8_t count = 0;
00080 static u8_t seqno;
00081 uip_ipaddr_t dest_addr;
00082
00083 #define MAX_CMD_LEN 20
00084 static struct{
00085 u8_t frame[MAX_CMD_LEN];
00086 u8_t ndx;
00087 u8_t len;
00088 u8_t cmd;
00089 u8_t done;
00090 } cmd;
00091
00092 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00093 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
00094 #define PING6_DATALEN 16
00095
00096 void rs232_send(uint8_t port, unsigned char c);
00097
00098
00099
00100
00101 void
00102 raven_ping6(void)
00103 {
00104 #define PING_GOOGLE 0
00105
00106 UIP_IP_BUF->vtc = 0x60;
00107 UIP_IP_BUF->tcflow = 1;
00108 UIP_IP_BUF->flow = 0;
00109 UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
00110 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
00111 #if PING_GOOGLE
00112 if (seqno==1) {
00113 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, uip_ds6_defrt_choose());
00114 } else if (seqno==2) {
00115 uip_ip6addr(&UIP_IP_BUF->destipaddr,0x2001,0x4860,0x800f,0x0000,0x0000,0x0000,0x0000,0x0093);
00116 } else if (seqno==3) {
00117 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, uip_ds6_defrt_choose());
00118 } else {
00119
00120 uip_ip6addr(&UIP_IP_BUF->destipaddr,0x2001,0x0420,0x0000,0x0010,0x0250,0x8bff,0xfee8,0xf800);
00121 }
00122 #else
00123 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, uip_ds6_defrt_choose());
00124 #endif
00125
00126 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
00127 UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST;
00128 UIP_ICMP_BUF->icode = 0;
00129
00130 memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4);
00131
00132 memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN,
00133 count, PING6_DATALEN);
00134
00135
00136 uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN;
00137 UIP_IP_BUF->len[0] = (u8_t)((uip_len - 40) >> 8);
00138 UIP_IP_BUF->len[1] = (u8_t)((uip_len - 40) & 0x00FF);
00139
00140 UIP_ICMP_BUF->icmpchksum = 0;
00141 UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
00142
00143
00144 tcpip_ipv6_output();
00145 }
00146 #if defined(__AVR_ATmega128RFA1__)
00147
00148
00149 static void
00150 send_frame(uint8_t cmd, uint8_t len, uint8_t *payload)
00151 {
00152 }
00153 #else
00154
00155
00156 static void
00157 send_frame(uint8_t cmd, uint8_t len, uint8_t *payload)
00158 {
00159 uint8_t i;
00160
00161 rs232_send(0, SOF_CHAR);
00162 rs232_send(0, len);
00163 rs232_send(0, cmd);
00164 for (i=0;i<len;i++)
00165 rs232_send(0,*payload++);
00166 rs232_send(0, EOF_CHAR);
00167 }
00168 #endif
00169 char serial_char_received;
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 void micro_sleep(uint8_t howlong)
00183 {
00184 uint8_t saved_sreg = SREG, saved_howlong = howlong;
00185 #if AVR_CONF_USE32KCRYSTAL
00186
00187 uint8_t savedTCNT2=TCNT2, savedTCCR2A=TCCR2A, savedTCCR2B = TCCR2B, savedOCR2A = OCR2A;
00188 #endif
00189
00190
00191
00192
00193 set_sleep_mode(SLEEP_MODE_PWR_SAVE);
00194 if (howlong==0) howlong=3;
00195 cli();
00196 ASSR |= (1 << AS2);
00197 TCCR2A =(1<<WGM21);
00198 TCCR2B =((1<<CS22)|(1<<CS21)|(1<<CS20));
00199
00200 OCR2A = howlong*32;
00201
00202 SREG = saved_sreg;
00203
00204
00205
00206
00207
00208
00209
00210
00211 TCNT2 = 0;
00212 watchdog_stop();
00213 while(ASSR & (1 << TCN2UB));
00214 TIMSK2 |= (1 << OCIE2A);
00215 SMCR |= (1 << SE);
00216 while (1) {
00217
00218
00219 serial_char_received=0;
00220 sleep_mode();
00221
00222
00223 extern void clock_adjust_seconds(uint8_t howmany);
00224 clock_adjust_seconds(howlong);
00225
00226
00227 PRINTF(".");
00228 if (saved_howlong) break;
00229 PRINTF("%d",serial_char_received);
00230 if (serial_char_received) break;
00231 }
00232
00233 SMCR &= ~(1 << SE);
00234
00235 #if AVR_CONF_USE32KCRYSTAL
00236
00237
00238 cli();
00239 TCCR2A = savedTCCR2A;
00240 TCCR2B = savedTCCR2B;
00241 OCR2A = savedOCR2A;
00242 TCNT2 = savedTCNT2;
00243 sei();
00244 #else
00245 TIMSK2 &= ~(1 << OCIE2A);
00246 #endif
00247
00248 watchdog_start();
00249 }
00250 #if !AVR_CONF_USE32KCRYSTAL
00251
00252
00253
00254 ISR(TIMER2_COMPA_vect)
00255 {
00256
00257 }
00258 #endif
00259
00260 #if DEBUGSERIAL
00261 u8_t serialcount;
00262 char dbuf[30];
00263 #endif
00264
00265
00266 extern uint16_t ledtimer;
00267 static u8_t
00268 raven_gui_loop(process_event_t ev, process_data_t data)
00269 {
00270 uint8_t i,activeconnections,radio_state;
00271
00272
00273 #if DEBUGSERIAL
00274 printf_P(PSTR("Buffer [%d]="),serialcount);
00275 serialcount=0;
00276 for (i=0;i<30;i++) {
00277 printf_P(PSTR(" %d"),dbuf[i]);
00278 dbuf[i]=0;
00279 }
00280 #endif
00281 if(ev == tcpip_icmp6_event) switch(*((uint8_t *)data)) {
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 case ICMP6_ECHO_REQUEST:
00292
00293
00294 PORTE|=(1<<PE1);ledtimer=1000;
00295 break;
00296 case ICMP6_ECHO_REPLY:
00297
00298
00299 break;
00300
00301 } else switch (ev) {
00302 case SERIAL_CMD:
00303
00304
00305 PRINTF("\nCommand %d length %d done %d",cmd.cmd,cmd.len,cmd.done);
00306 if (cmd.done){
00307
00308 switch (cmd.cmd){
00309 case SEND_PING:
00310
00311 seqno = cmd.frame[0];
00312 raven_ping6();
00313 break;
00314 case SEND_TEMP:
00315
00316
00317 break;
00318 case SEND_ADC2:
00319
00320
00321 break;
00322 case SEND_SLEEP:
00323
00324 if (cmd.frame[0]==0) {
00325
00326 } else {
00327
00328
00329
00330 activeconnections=0;
00331 for(i = 0; i < UIP_CONNS; ++i) {
00332 if((uip_conns[i].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) activeconnections++;
00333 }
00334 if (activeconnections) {
00335 PRINTF("\nWaiting for %d connections",activeconnections);
00336 break;
00337 }
00338 }
00339 radio_state = NETSTACK_RADIO.off();
00340 PRINTF ("\nsleep %d radio state %d...",cmd.frame[0],radio_state);
00341
00342
00343 PRINTF("\nSleeping...");
00344 micro_sleep(cmd.frame[0]);
00345
00346 radio_state = NETSTACK_RADIO.on();
00347 if (radio_state > 0) {
00348 PRINTF("Awake!");
00349 } else {
00350 PRINTF("Radio wake error %d\n",radio_state);
00351 }
00352 break;
00353 case SEND_WAKE:
00354
00355 send_frame(REPORT_WAKE, 0, 0);
00356 break;
00357 default:
00358 break;
00359 }
00360
00361 cmd.done = 0;
00362 }
00363 break;
00364 default:
00365 break;
00366 }
00367 return 0;
00368 }
00369
00370
00371
00372
00373
00374
00375 int raven_lcd_serial_input(unsigned char ch)
00376 {
00377
00378
00379 if (ch) serial_char_received++;
00380 #if DEBUGSERIAL
00381 if (serialcount<25) dbuf[serialcount]=ch;
00382 serialcount++;
00383 #endif
00384
00385
00386
00387
00388 switch (cmd.ndx){
00389 case 0:
00390
00391 if (ch == 0x01){
00392
00393 } else {
00394 #if DEBUGSERIAL
00395 dbuf[25]++;
00396 #endif
00397 return 0;
00398 }
00399 break;
00400 case 1:
00401
00402 cmd.len = ch;
00403 break;
00404 case 2:
00405
00406 cmd.cmd = ch;
00407 break;
00408 default:
00409
00410 if (cmd.ndx >= (MAX_CMD_LEN+3)) {
00411 cmd.ndx=0;
00412 #if DEBUGSERIAL
00413 dbuf[26]++;
00414 #endif
00415 return 0;
00416 }
00417 if (cmd.ndx >= cmd.len+3){
00418
00419 if (ch == 0x04){
00420 cmd.done = 1;
00421 #if DEBUGSERIAL
00422 dbuf[27]++;
00423 #endif
00424 process_post(&raven_lcd_process, SERIAL_CMD, 0);
00425 } else {
00426
00427 #if DEBUGSERIAL
00428 dbuf[28]++;
00429 #endif
00430 }
00431 cmd.ndx=0;
00432 return 0;
00433 } else {
00434
00435 cmd.frame[cmd.ndx - 3] = ch;
00436 }
00437 break;
00438 }
00439
00440 cmd.ndx++;
00441 return 0;
00442 }
00443
00444
00445 void
00446 raven_lcd_show_text(char *text) {
00447 uint8_t textlen=strlen(text)+1;
00448 if (textlen > MAX_CMD_LEN) textlen=MAX_CMD_LEN;
00449 send_frame(REPORT_TEXT_MSG, textlen, (uint8_t *) text);
00450 }
00451
00452 #if WEBSERVER
00453 static void
00454 lcd_show_servername(void) {
00455
00456
00457 extern uint8_t server_name[16];
00458
00459 char buf[sizeof(server_name)+1];
00460 eeprom_read_block (buf,server_name, sizeof(server_name));
00461 buf[sizeof(server_name)]=0;
00462 raven_lcd_show_text(buf);
00463 }
00464 #endif
00465
00466 PROCESS(raven_lcd_process, "Raven LCD interface process");
00467 PROCESS_THREAD(raven_lcd_process, ev, data)
00468 {
00469
00470 PROCESS_BEGIN();
00471
00472 #if WEBSERVER
00473 lcd_show_servername();
00474 #endif
00475
00476
00477 if(icmp6_new(NULL) == 0) {
00478
00479 while(1) {
00480 PROCESS_YIELD();
00481
00482 raven_gui_loop(ev, data);
00483 }
00484 }
00485 PROCESS_END();
00486 }
00487
00488