Contiki 3.x
cdc_task.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /*! \file platform/avr-ravenusb/cdc_task.c **********************************************************
3  *
4  * \brief
5  * Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device
6  *
7  * \addtogroup usbstick
8  *
9  * \author
10  * Colin O'Flynn <coflynn@newae.com>
11  *
12  ******************************************************************************/
13 /* Copyright (c) 2008 ATMEL Corporation
14  All rights reserved.
15 
16  Redistribution and use in source and binary forms, with or without
17  modification, are permitted provided that the following conditions are met:
18 
19  * Redistributions of source code must retain the above copyright
20  notice, this list of conditions and the following disclaimer.
21  * Redistributions in binary form must reproduce the above copyright
22  notice, this list of conditions and the following disclaimer in
23  the documentation and/or other materials provided with the
24  distribution.
25  * Neither the name of the copyright holders nor the names of
26  contributors may be used to endorse or promote products derived
27  from this software without specific prior written permission.
28 
29  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  POSSIBILITY OF SUCH DAMAGE.
40 */
41 /**
42  \ingroup usbstick
43  \defgroup cdctask CDC Task
44  @{
45  */
46 
47 //_____ I N C L U D E S ___________________________________________________
48 
49 
50 #include "contiki.h"
51 #include "sys/cc.h"
52 #include "usb_drv.h"
53 #include "usb_descriptors.h"
54 #include "usb_specific_request.h"
55 #include "cdc_task.h"
56 #include "serial/uart_usb_lib.h"
57 #include "rndis/rndis_protocol.h"
58 #include "rndis/rndis_task.h"
59 #include "sicslow_ethernet.h"
60 #if RF230BB
61 #include "rf230bb.h"
62 #else
63 #include "radio.h"
64 #endif
65 
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include "dev/watchdog.h"
69 #include "rng.h"
70 
71 #include "bootloader.h"
72 
73 #include <avr/pgmspace.h>
74 #include <avr/eeprom.h>
75 #include <avr/wdt.h>
76 #include <util/delay.h>
77 
78 #if UIP_CONF_IPV6_RPL
79 // Include needs to be up here instead of embedded in the other
80 // UIP_CONF_IPV6_RPL block, as doxygen seems not to be compatible with
81 // #includes embedded in other functions and spits out a warning.
82 #include "rpl.h"
83 #endif
84 
85 #if JACKDAW_CONF_USE_SETTINGS
86 #include "settings.h"
87 #endif
88 
89 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
90 #define PRINTF printf
91 #define PRINTF_P printf_P
92 
93 //_____ M A C R O S ________________________________________________________
94 
95 
96 #define bzero(ptr,size) memset(ptr,0,size)
97 
98 //_____ D E F I N I T I O N S ______________________________________________
99 
100 
101 #define IAD_TIMEOUT_DETACH 300
102 #define IAD_TIMEOUT_ATTACH 600
103 
104 //_____ D E C L A R A T I O N S ____________________________________________
105 
106 
107 void menu_print(void);
108 void menu_process(char c);
109 
110 extern char usb_busy;
111 
112 //! Counter for USB Serial port
113 extern U8 tx_counter;
114 
115 //! Timers for LEDs
116 uint8_t led3_timer;
117 
118 
119 //! previous configuration
121 
122 
123 static uint8_t timer = 0;
124 static struct etimer et;
125 
126 #define CONVERTTXPOWER 1
127 #if CONVERTTXPOWER //adds ~120 bytes to program flash size
128 const char txonesdigit[16] PROGMEM = {'3','2','2','1','1','0','0','1','2','3','4','5','7','9','2','7'};
129 const char txtenthsdigit[16] PROGMEM = {'0','6','1','6','1','5','2','2','2','2','2','2','2','2','2','2'};
130 static void printtxpower(void) {
131  uint8_t power=rf230_get_txpower()&0xf;
132  char sign=(power<6?'+':'-');
133  char tens=(power>14?'1':'0');
134  char ones=pgm_read_byte(&txonesdigit[power]);
135  char tenths=pgm_read_byte(&txtenthsdigit[power]);
136  if (tens=='0') {tens=sign;sign=' ';}
137  PRINTF_P(PSTR("%c%c%c.%cdBm"),sign,tens,ones,tenths);
138 }
139 #endif
140 
141 PROCESS(cdc_process, "CDC serial process");
142 
143 /**
144  * \brief Communication Data Class (CDC) Process
145  *
146  * This is the link between USB and the "good stuff". In this routine data
147  * is received and processed by CDC-ACM Class
148  */
149 PROCESS_THREAD(cdc_process, ev, data_proc)
150 {
151  PROCESS_BEGIN();
152 
153 #if USB_CONF_RS232
154  static FILE *rs232_stdout,*usb_stdout;
155  rs232_stdout=stdout;
156 #endif
157 
158  while(1) {
159  // turn off LED's if necessary
160  if (led3_timer) led3_timer--;
161  else Led3_off();
162 
163  if(Is_device_enumerated()) {
164  // If the configuration is different than the last time we checked...
165  if((uart_usb_get_control_line_state()&1)!=previous_uart_usb_control_line_state) {
166  previous_uart_usb_control_line_state = uart_usb_get_control_line_state()&1;
167  static FILE* previous_stdout;
168 
170  previous_stdout = stdout;
171  uart_usb_init();
172  uart_usb_set_stdout();
173  // menu_print(); do this later
174  } else {
175  stdout = previous_stdout;
176  }
177 #if USB_CONF_RS232
178  usb_stdout=stdout;
179 #endif
180  }
181 
182  //Flush buffer if timeout
183  if(timer >= 4 && tx_counter!=0 ){
184  timer = 0;
185  uart_usb_flush();
186  } else {
187  timer++;
188  }
189 
190 #if USB_CONF_RS232
191  stdout=usb_stdout;
192 #endif
193  while (uart_usb_test_hit()){
194  menu_process(uart_usb_getchar()); // See what they want
195  }
196 #if USB_CONF_RS232
197  if (usbstick_mode.debugOn) {
198  stdout=rs232_stdout;
199  } else {
200  stdout=NULL;
201  }
202 #endif
203  }//if (Is_device_enumerated())
204 
205 
206 
207  if (USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
208  etimer_set(&et, CLOCK_SECOND/80);
209  } else {
211  }
212 
214 
215  } // while(1)
216 
217  PROCESS_END();
218 }
219 
220 /**
221  \brief Print debug menu
222  */
223 void menu_print(void)
224 {
225  PRINTF_P(PSTR("\n\r*********** Jackdaw Menu **********\n\r"));
226  PRINTF_P(PSTR(" [Built "__DATE__"] \n\r"));
227 // PRINTF_P(PSTR("* *\n\r"));
228  PRINTF_P(PSTR("* m Print current mode *\n\r"));
229  PRINTF_P(PSTR("* s Set to sniffer mode *\n\r"));
230  PRINTF_P(PSTR("* n Set to network mode *\n\r"));
231  PRINTF_P(PSTR("* c Set RF channel *\n\r"));
232  PRINTF_P(PSTR("* p Set RF power *\n\r"));
233  PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r"));
234  PRINTF_P(PSTR("* r Toggle raw mode *\n\r"));
235 #if USB_CONF_RS232
236  PRINTF_P(PSTR("* d Toggle RS232 output *\n\r"));
237 #endif
238 #if RF230BB && RF230_CONF_SNEEZER
239  PRINTF_P(PSTR("* S Enable sneezer mode *\n\r"));
240 #endif
241 #if UIP_CONF_IPV6_RPL
242  PRINTF_P(PSTR("* N RPL Neighbors *\n\r"));
243  PRINTF_P(PSTR("* G RPL Global Repair *\n\r"));
244 #endif
245  PRINTF_P(PSTR("* e Energy Scan *\n\r"));
246 #if USB_CONF_STORAGE
247  PRINTF_P(PSTR("* u Switch to mass-storage*\n\r"));
248 #endif
249  if(bootloader_is_present())
250  PRINTF_P(PSTR("* D Switch to DFU mode *\n\r"));
251  PRINTF_P(PSTR("* R Reset (via WDT) *\n\r"));
252  PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
253  PRINTF_P(PSTR("* *\n\r"));
254  PRINTF_P(PSTR("* Make selection at any time by *\n\r"));
255  PRINTF_P(PSTR("* pressing your choice on keyboard*\n\r"));
256  PRINTF_P(PSTR("***********************************\n\r"));
257 }
258 
259 #if UIP_CONF_IPV6_RPL
260 static void
261 ipaddr_add(const uip_ipaddr_t *addr)
262 {
263  uint16_t a;
264  int8_t i, f;
265  for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
266  a = (addr->u8[i] << 8) + addr->u8[i + 1];
267  if(a == 0 && f >= 0) {
268  if(f++ == 0) PRINTF_P(PSTR("::"));
269  } else {
270  if(f > 0) {
271  f = -1;
272  } else if(i > 0) {
273  PRINTF_P(PSTR(":"));
274  }
275  PRINTF_P(PSTR("%x"),a);
276  }
277  }
278 }
279 #endif
280 
281 /**
282  \brief Process incomming char on debug port
283  */
284 void menu_process(char c)
285 {
286 
287  static enum menustate_enum /* Defines an enumeration type */
288  {
289  normal,
290  channel,
291  txpower
292  } menustate = normal;
293 
294  static char channel_string[3];
295  static uint8_t channel_string_i;// = 0;
296 
297  int tempchannel;
298 
299  if (menustate == channel) {
300 
301  switch(c) {
302  case '\r':
303  case '\n':
304 
305  if (channel_string_i) {
306  channel_string[channel_string_i] = 0;
307  tempchannel = atoi(channel_string);
308 
309 #if RF230BB
310  if ((tempchannel < 11) || (tempchannel > 26)) {
311  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
312  } else {
313  rf230_set_channel(tempchannel);
314 #else
315  if(radio_set_operating_channel(tempchannel)!=RADIO_SUCCESS) {
316  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
317  } else {
318 #endif
319 #if JACKDAW_CONF_USE_SETTINGS
320  if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)==SETTINGS_STATUS_OK) {
321  PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel);
322  } else {
323  PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
324  }
325 #else
326  PRINTF_P(PSTR("\n\rChannel changed to %d.\n\r"),tempchannel);
327 #endif
328  }
329  } else {
330  PRINTF_P(PSTR("\n\rChannel unchanged.\n\r"));
331  }
332 
333  menustate = normal;
334  break;
335 
336  case '\b':
337 
338  if (channel_string_i) {
339  channel_string_i--;
340  PRINTF_P(PSTR("\b \b"));
341  }
342  break;
343 
344  case '0':
345  case '1':
346  case '2':
347  case '3':
348  case '4':
349  case '5':
350  case '6':
351  case '7':
352  case '8':
353  case '9':
354  if (channel_string_i > 1) {
355  // This time the user has gone too far.
356  // Beep at them.
357  putc('\a', stdout);
358  //uart_usb_putchar('\a');
359  break;
360  }
361  putc(c, stdout);
362  //uart_usb_putchar(c);
363 
364  channel_string[channel_string_i] = c;
365  channel_string_i++;
366  break;
367 
368  default:
369  break;
370  }
371  } else if (menustate == txpower) {
372 
373  switch(c) {
374  case '\r':
375  case '\n':
376 
377  if (channel_string_i) {
378  channel_string[channel_string_i] = 0;
379  tempchannel = atoi(channel_string);
380 #if RF230BB
381  if ((tempchannel < 0) || (tempchannel > 15)) {
382  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
383  } else {
384  PRINTF_P(PSTR(" ")); //for some reason needs a print here to clear the string input...
385  rf230_set_txpower(tempchannel);
386 #else
387  if(radio_set_tx_power_level(tempchannel)!=RADIO_SUCCESS) {
388  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
389  } else {
390 #endif
391 #if JACKDAW_CONF_USE_SETTINGS
392  if(settings_set_uint8(SETTINGS_KEY_TXPOWER, tempchannel)==SETTINGS_STATUS_OK) {
393  PRINTF_P(PSTR("\n\rTransmit power changed to %d, and stored in EEPROM.\n\r"),tempchannel);
394  } else {
395  PRINTF_P(PSTR("\n\rTransmit power changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
396  }
397 #else
398  PRINTF_P(PSTR("\n\rTransmit power changed to %d.\n\r"),tempchannel);
399 #endif
400  }
401  } else {
402  PRINTF_P(PSTR("\n\rTransmit power unchanged.\n\r"));
403  }
404 
405  menustate = normal;
406  break;
407 
408  case '\b':
409 
410  if (channel_string_i) {
411  channel_string_i--;
412  PRINTF_P(PSTR("\b \b"));
413  }
414  break;
415 
416  case '0':
417  case '1':
418  case '2':
419  case '3':
420  case '4':
421  case '5':
422  case '6':
423  case '7':
424  case '8':
425  case '9':
426  if (channel_string_i > 1) {
427  // This time the user has gone too far.
428  // Beep at them.
429  putc('\a', stdout);
430  //uart_usb_putchar('\a');
431  break;
432  }
433  putc(c, stdout);
434  //uart_usb_putchar(c);
435 
436  channel_string[channel_string_i] = c;
437  channel_string_i++;
438  break;
439 
440  default:
441  break;
442  }
443 
444  } else {
445 
446  uint8_t i;
447 
448  /* Any attempt to read an RF230 register in sneeze mode (e.g. rssi) will hang the MCU */
449  /* So convert any command into a sneeze off */
450  if (usbstick_mode.sneeze) c='S';
451 
452  switch(c) {
453  case '\r':
454  case '\n':
455  break;
456 
457  case 'h':
458  case '?':
459  menu_print();
460  break;
461  case '-':
462  PRINTF_P(PSTR("Bringing interface down\n\r"));
463  usb_eth_set_active(0);
464  break;
465  case '=':
466  case '+':
467  PRINTF_P(PSTR("Bringing interface up\n\r"));
468  usb_eth_set_active(1);
469  break;
470 #if JACKDAW_CONF_RANDOM_MAC
471  case 'T':
472  // Test "strong" random number generator of R Quattlebaum
473  // This can potentially reboot the stick!
474  PRINTF_P(PSTR("RNG Output: "));
475  {
476  uint8_t value = rng_get_uint8();
477  uint8_t i;
478  for(i=0;i<8;i++) {
479  uart_usb_putchar(((value>>(7-i))&1)?'1':'0');
480  }
481  PRINTF_P(PSTR("\n\r"));
482  uart_usb_flush();
484  }
485  break;
486 #endif
487  case 's':
488  PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r"));
489  usbstick_mode.sendToRf = 0;
490  usbstick_mode.translate = 0;
491 #if RF230BB
492  rf230_listen_channel(rf230_get_channel());
493 #else
495 #endif
496  break;
497 
498 #if RF230BB && RF230_CONF_SNEEZER
499  case 'S':
500  if (usbstick_mode.sneeze) {
501  rf230_warm_reset();
502  PRINTF_P(PSTR("Jackdaw now behaving itself.\n\r"));
503  usbstick_mode.sneeze = 0;
504  } else {
505  if (rf230_get_txpower()<3)
506  PRINTF_P(PSTR("*****WARNING Radio may overheat in this mode*******\n\r"));
507  rf230_start_sneeze();
508  PRINTF_P(PSTR("********Jackdaw is continuously broadcasting*******\n\r"));
509 #if CONVERTTXPOWER
510  PRINTF_P(PSTR("*********on channel %2d with power "),rf230_get_channel());
511  printtxpower();
512  PRINTF_P(PSTR("*********\n\r"));
513 #else
514  PRINTF_P(PSTR("************on channel %2d with power %2d************\n\r"),rf230_get_channel(),rf230_get_txpower());
515 #endif
516  PRINTF_P(PSTR("Press any key to stop.\n\r"));
518  usbstick_mode.sneeze = 1;
519  }
520  break;
521 #endif
522 
523  case 'n':
524  PRINTF_P(PSTR("Jackdaw now in network mode\n\r"));
525  usbstick_mode.sendToRf = 1;
526  usbstick_mode.translate = 1;
527 #if RF230BB
528  rf230_set_channel(rf230_get_channel());
529 #else
530  radio_set_trx_state(RX_AACK_ON); //TODO: Use startup state which may be RX_ON
531 #endif
532  break;
533 
534  case '6':
535  if (usbstick_mode.sicslowpan) {
536  PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r"));
537  usbstick_mode.sicslowpan = 0;
538  } else {
539  PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r"));
540  usbstick_mode.sicslowpan = 1;
541  }
542 
543  break;
544 
545  case 'r':
546  if (usbstick_mode.raw) {
547  PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r"));
548  usbstick_mode.raw = 0;
549  } else {
550  PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r"));
551  usbstick_mode.raw = 1;
552  }
553  break;
554 #if USB_CONF_RS232
555  case 'd':
556  if (usbstick_mode.debugOn) {
557  PRINTF_P(PSTR("Jackdaw does not output debug strings\n\r"));
558  usbstick_mode.debugOn = 0;
559  } else {
560  PRINTF_P(PSTR("Jackdaw now outputs debug strings\n\r"));
561  usbstick_mode.debugOn = 1;
562  }
563  break;
564 #endif
565 
566 
567  case 'c':
568 #if RF230BB
569  PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel());
570 #else
571  PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel());
572 #endif
573  menustate = channel;
574  channel_string_i = 0;
575  break;
576 
577  case 'p':
578 #if RF230BB
579  PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), rf230_get_txpower());
580 #else
581 // PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), ?_power());;
582 #endif
583  menustate = txpower;
584  channel_string_i = 0;
585  break;
586 
587 
588 #if UIP_CONF_IPV6_RPL
590  case 'N':
591  { uint8_t i,j;
593  PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB);
594  for (i=0;i<UIP_DS6_ADDR_NB;i++) {
595  if (uip_ds6_if.addr_list[i].isused) {
596  ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
597  PRINTF_P(PSTR("\n\r"));
598  }
599  }
600  PRINTF_P(PSTR("\n\rNeighbors [%u max]\n\r"),NBR_TABLE_MAX_NEIGHBORS);
601 
602  for(nbr = nbr_table_head(ds6_neighbors);
603  nbr != NULL;
604  nbr = nbr_table_next(ds6_neighbors, nbr)) {
605  ipaddr_add(&nbr->ipaddr);
606  PRINTF_P(PSTR("\n\r"));
607  j=0;
608  }
609  if (j) PRINTF_P(PSTR(" <none>"));
610  PRINTF_P(PSTR("\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB);
612  for(route = uip_ds6_route_head();
613  route != NULL;
614  route = uip_ds6_route_next(route)) {
615  ipaddr_add(&route->ipaddr);
616  PRINTF_P(PSTR("/%u (via "), route->length);
617  ipaddr_add(uip_ds6_route_nexthop(route));
618  if(route->state.lifetime < 600) {
619  PRINTF_P(PSTR(") %lus\n\r"), route->state.lifetime);
620  } else {
621  PRINTF_P(PSTR(")\n\r"));
622  }
623  j=0;
624  }
625  if (j) PRINTF_P(PSTR(" <none>"));
626  PRINTF_P(PSTR("\n\r---------\n\r"));
627  break;
628  }
629 
630  case 'G':
631  PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_root(RPL_DEFAULT_INSTANCE));
632  break;
633 
634  case 'L':
635  rpl_local_repair(rpl_get_any_dag());
636  PRINTF_P(PSTR("Local repair initiated\n\r"));
637  break;
638 
639  case 'Z': //zap the routing table
640  PRINTF_P(PSTR("Not implemented.\n\r"));
641  break;
642 #endif
643 
644  case 'm':
645  PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will "));
646  if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));}
647  PRINTF_P(PSTR("send data over RF\n\r * Will "));
648  if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));}
649  PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will "));
650  if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));}
651  PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will "));
652  if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));}
653 
654 #if USB_CONF_RS232
655  PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r * Will "));
656  if (usbstick_mode.debugOn == 0) { PRINTF_P(PSTR("not "));}
657  PRINTF_P(PSTR("Output RS232 debug strings\n\r"));
658 #else
659  PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r"));
660 #endif
661 
662  PRINTF_P(PSTR(" * USB Ethernet MAC: %02x:%02x:%02x:%02x:%02x:%02x\n"),
663  ((uint8_t *)&usb_ethernet_addr)[0],
664  ((uint8_t *)&usb_ethernet_addr)[1],
665  ((uint8_t *)&usb_ethernet_addr)[2],
666  ((uint8_t *)&usb_ethernet_addr)[3],
667  ((uint8_t *)&usb_ethernet_addr)[4],
668  ((uint8_t *)&usb_ethernet_addr)[5]
669  );
670  extern uint64_t macLongAddr;
671  PRINTF_P(PSTR(" * 802.15.4 EUI-64: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"),
672  ((uint8_t *)&macLongAddr)[0],
673  ((uint8_t *)&macLongAddr)[1],
674  ((uint8_t *)&macLongAddr)[2],
675  ((uint8_t *)&macLongAddr)[3],
676  ((uint8_t *)&macLongAddr)[4],
677  ((uint8_t *)&macLongAddr)[5],
678  ((uint8_t *)&macLongAddr)[6],
679  ((uint8_t *)&macLongAddr)[7]
680  );
681 #if RF230BB
682 #if CONVERTTXPOWER
683  PRINTF_P(PSTR(" * Operates on channel %d with TX power "),rf230_get_channel());
684  printtxpower();
685  PRINTF_P(PSTR("\n\r"));
686 #else //just show the raw value
687  PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel());
688  PRINTF_P(PSTR(" * TX Power(0=+3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower());
689 #endif
690  if (rf230_smallest_rssi) {
691  PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/%ddBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1),-91+(rf230_smallest_rssi-1));
692  rf230_smallest_rssi=0;
693  } else {
694  PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1));
695  }
696 
697 #else /* RF230BB */
698  PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel());
699  PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), radio_get_tx_power_level());
700  {
701  PRINTF_P(PSTR(" * Current RSSI: "));
702  int8_t rssi = 0;
704  PRINTF_P(PSTR("%ddB\n\r"), -91+3*(rssi-1));
705  else
706  PRINTF_P(PSTR("Unknown\n\r"));
707  }
708 
709 #endif /* RF230BB */
710 
711  PRINTF_P(PSTR(" * Configuration: %d, USB<->ETH is "), usb_configuration_nb);
712  if (usb_eth_is_active == 0) PRINTF_P(PSTR("not "));
713  PRINTF_P(PSTR("active\n\r"));
714 
715 #if CONFIG_STACK_MONITOR
716 /* See contiki-raven-main.c for initialization of the magic numbers */
717 {
718 extern uint16_t __bss_end;
719 uint16_t p=(uint16_t)&__bss_end;
720  do {
721  if (*(uint16_t *)p != 0x4242) {
722  printf_P(PSTR(" * Never-used stack > %d bytes\n\r"),p-(uint16_t)&__bss_end);
723  break;
724  }
725  p+=100;
726  } while (p<RAMEND-100);
727 }
728 #endif
729 
730  break;
731 
732  case 'e':
733  PRINTF_P(PSTR("Energy Scan:\n"));
734  uart_usb_flush();
735  {
736  uint8_t i;
737  uint16_t j;
738 #if RF230BB
739  uint8_t previous_channel = rf230_get_channel();
740 #else // RF230BB
741  uint8_t previous_channel = radio_get_operating_channel();
742 #endif
743  int8_t RSSI, maxRSSI[17];
744  uint16_t accRSSI[17];
745 
746  bzero((void*)accRSSI,sizeof(accRSSI));
747  bzero((void*)maxRSSI,sizeof(maxRSSI));
748 
749  for(j=0;j<(1<<12);j++) {
750  for(i=11;i<=26;i++) {
751 #if RF230BB
752  rf230_listen_channel(i);
753 #else // RF230BB
755 #endif
756  _delay_us(3*10);
757 #if RF230BB
758  RSSI = rf230_rssi(); //multiplies rssi register by 3 for consistency with energy-detect register
759 #else // RF230BB
760  radio_get_rssi_value(&RSSI);
761  RSSI*=3;
762 #endif
763  maxRSSI[i-11]=MAX(maxRSSI[i-11],RSSI);
764  accRSSI[i-11]+=RSSI;
765  }
766  if(j&(1<<7)) {
767  Led3_on();
768  if(!(j&((1<<7)-1))) {
769  PRINTF_P(PSTR("."));
770  uart_usb_flush();
771  }
772  }
773  else
774  Led3_off();
776  }
777 #if RF230BB
778  rf230_set_channel(previous_channel);
779 #else // RF230BB
780  radio_set_operating_channel(previous_channel);
781 #endif
782  PRINTF_P(PSTR("\n"));
783  for(i=11;i<=26;i++) {
784  uint8_t activity=MIN(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
785  PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1));
786  for(;activity--;maxRSSI[i-11]--) {
787  PRINTF_P(PSTR("#"));
788  }
789  for(;maxRSSI[i-11]>0;maxRSSI[i-11]--) {
790  PRINTF_P(PSTR(":"));
791  }
792  PRINTF_P(PSTR("\n"));
793  uart_usb_flush();
794  }
795 
796  }
797  PRINTF_P(PSTR("Done.\n"));
798  uart_usb_flush();
799 
800  break;
801 
802 
803  case 'D':
804  {
805  PRINTF_P(PSTR("Entering DFU Mode...\n\r"));
806  uart_usb_flush();
807  Leds_on();
808  for(i = 0; i < 10; i++)_delay_ms(100);
809  Leds_off();
810  Jump_To_Bootloader();
811  }
812  break;
813  case 'R':
814  {
815  PRINTF_P(PSTR("Resetting...\n\r"));
816  uart_usb_flush();
817  Leds_on();
818  for(i = 0; i < 10; i++)_delay_ms(100);
819  Usb_detach();
820  for(i = 0; i < 20; i++)_delay_ms(100);
821  watchdog_reboot();
822  }
823  break;
824 
825 #if USB_CONF_STORAGE
826  case 'u':
827 
828  //Mass storage mode
829  usb_mode = mass_storage;
830 
831  //No more serial port
832  stdout = NULL;
833 #if USB_CONF_RS232
834 // usb_stdout = NULL;
835 #endif
836 
837  //RNDIS is over
838  rndis_state = rndis_uninitialized;
839  Leds_off();
840 
841  //Deatch USB
842  Usb_detach();
843 
844  //Wait a few seconds
845  for(i = 0; i < 50; i++)
847  _delay_ms(100);
848 
849  //Attach USB
850  Usb_attach();
851 
852 
853  break;
854 #endif
855 
856  default:
857  PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c);
858  break;
859  }
860 
861 
862  }
863 
864  return;
865 
866 }
867 
868 
869 /**
870  @brief This will enable the VCP_TRX_END LED for a period
871 */
872 void vcptx_end_led(void)
873 {
874  Led3_on();
875  led3_timer = 5;
876 }
877 /** @} */
878 
int uart_usb_putchar(int data_to_send)
This function fills the USB transmit buffer with the new data.
Definition: uart_usb_lib.c:206
This file contains the USB driver routines.
U8 usb_configuration_nb
Public : (U8) usb_configuration_nb Store the number of the USB configuration used by the USB device w...
U8 tx_counter
Counter for USB Serial port.
Definition: uart_usb_lib.c:81
bit uart_usb_test_hit(void)
This function checks if a character has been received on the USB bus.
Definition: uart_usb_lib.c:241
radio_status_t radio_set_trx_state(uint8_t new_state)
This function will change the current state of the radio transceiver's internal state machine...
Definition: radio.c:809
static uip_ds6_addr_t * addr
Pointer to a router list entry.
Definition: uip-nd6.c:124
RNDIS Defines
uint8_t radio_get_tx_power_level(void)
This function will read and return the output power level.
Definition: radio.c:374
#define Usb_attach()
attaches to USB bus
Definition: usb_drv.h:369
Default definitions of C compiler quirk work-arounds.
The requested service was performed successfully.
Definition: radio.h:106
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition: etimer.c:177
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
char uart_usb_getchar(void)
This function reads one byte from the USB bus.
Definition: uart_usb_lib.c:270
static struct etimer et
NIC receiver thread.
Definition: lanc111.c:1133
A timer.
Definition: timer.h:86
Settings Manager.
A timer.
Definition: etimer.h:76
This file contains the user callback functions corresponding to the application.
void uart_usb_init(void)
Initializes the uart_usb library.
Definition: uart_usb_lib.c:154
static uint8_t previous_uart_usb_control_line_state
previous configuration
Definition: cdc_task.c:120
This file contains radio driver code.
#define Usb_detach()
detaches from USB bus
Definition: usb_drv.h:367
An entry in the nbr cache.
Definition: uip-ds6-nbr.h:70
radio_status_t radio_set_operating_channel(uint8_t channel)
This function will change the operating channel.
Definition: radio.c:329
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition: process.h:157
static uip_ds6_route_t * route
The next route to use.
Definition: res_routes.c:31
void watchdog_reboot(void)
Keeps control until the WDT throws a reset signal.
Definition: watchdog.c:43
Interface structure (contains all the interface variables)
Definition: uip-ds6.h:242
#define Is_device_enumerated()
Returns true when device connected and correctly enumerated with an host.
This file manages the CDC task for the virtual COM port.
#define NULL
The null pointer.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
Definition: uip-nd6.c:122
This file contains the usb parameters that uniquely identify the application through descriptor table...
This file manages the RNDIS task.
PROCESS_THREAD(cdc_process, ev, data_proc)
Communication Data Class (CDC) Process.
Definition: cdc_task.c:149
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
Definition: etimer.c:213
uint8_t led3_timer
Timers for LEDs.
Definition: cdc_task.c:116
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64
void menu_print(void)
Print debug menu.
Definition: cdc_task.c:223
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
#define SETTINGS_KEY_CHANNEL
Definition: settings.h:119
radio_status_t radio_get_rssi_value(uint8_t *rssi)
This function returns the Received Signal Strength Indication.
Definition: radio.c:485
uint8_t radio_get_operating_channel(void)
This function will return the channel used by the radio transceiver.
Definition: radio.c:313
radio_status_t radio_set_tx_power_level(uint8_t power_level)
This function will change the output power level.
Definition: radio.c:391
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition: uip-ds6.c:71
void vcptx_end_led(void)
This will enable the VCP_TRX_END LED for a period.
Definition: cdc_task.c:872
#define RX_AACK_ON
Constant RX_AACK_ON for sub-register SR_TRX_STATUS.
#define RX_ON
Constant RX_ON for sub-register SR_TRX_STATUS.
void uart_usb_flush(void)
This function sends the data stored in the USB transmit buffer.
Definition: uart_usb_lib.c:299
An entry in the routing table.
uint64_t macLongAddr
Our own long address.
Definition: mac.c:145
#define SETTINGS_KEY_TXPOWER
Definition: settings.h:120
void menu_process(char c)
Process incomming char on debug port.
Definition: cdc_task.c:284
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120