38 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
40 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
48 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
55 uint8_t debugflowsize, debugflow[DEBUGFLOWSIZE];
56 #define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c
62 #include <util/delay.h>
67 #include "dev/watchdog.h"
73 #include "lib/sensors.h"
74 #include "dev/button-sensor.h"
75 #include "dev/acc-sensor.h"
78 #include "dev/battery-sensor.h"
83 #if RF230BB //radio driver using contiki core mac
89 #else //radio driver using Atmel/Cisco 802.15.4'ish MAC
91 #include "sicslowmac.h"
97 #include "contiki-net.h"
98 #include "contiki-lib.h"
99 #include "sys/node-id.h"
101 #include "dev/rs232.h"
103 #include "dev/slip.h"
106 #include "httpd-fs.h"
107 #include "httpd-cgi.h"
115 #include "net/ipv6/uip-ds6.h"
117 void uip_debug_ipaddr_print(
const uip_ipaddr_t *addr);
124 #if (APP_SETTINGS_DELETE == 1)
125 #include "settings_delete.h"
127 #if (APP_SETTINGS_SET == 1)
128 #include "settings_set.h"
134 #ifndef INGA_CONF_PERIODIC
135 #define INGA_PERIODIC 1
137 #define INGA_PERIODIC INGA_CONF_PERIODIC
141 #ifndef INGA_CONF_PERIODIC_ROUTES
142 #define INGA_PERIODIC_ROUTES 0
144 #define INGA_PERIODIC_ROUTES INGA_CONF_PERIODIC_ROUTES
145 #if INGA_PERIODIC_ROUTES > 0 && !UIP_CONF_IPV6
146 #error Periodic routes only supported for IPv6
150 #ifndef INGA_CONF_PERIODIC_STAMPS
151 #define PER_STAMPS 60
153 #define PER_STAMPS INGA_CONF_PERIODIC_STAMPS
156 #ifndef INGA_CONF_PERIODIC_STACK
157 #define INGA_PERIODIC_STACK 60
159 #define INGA_PERIODIC_STACK INGA_CONF_PERIODIC_STACK
163 #ifndef USART_BAUD_INGA
164 #define USART_BAUD_INGA USART_BAUD_19200
169 #if (__AVR_LIBC_VERSION__ >= 10700UL)
171 #include <avr/signature.h>
176 const unsigned char B2;
177 const unsigned char B1;
178 const unsigned char B0;
180 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
188 #define INGA_CONF_RANDOM_BSN_SEQNO 1
189 #if INGA_CONF_RANDOM_BSN_SEQNO || INGA_CONF_RANDOM_MAC
198 for( i = 0; i < 4; i++) {
202 printf(
"rng issues %d\n", j);
210 generate_new_eui64(uint8_t eui64[8])
213 eui64[1] = rng_get_uint8();
214 eui64[2] = rng_get_uint8();
217 eui64[5] = rng_get_uint8();
218 eui64[6] = rng_get_uint8();
219 eui64[7] = rng_get_uint8();
229 struct inga_config_s {
230 uint8_t eui64_addr[8];
231 uint8_t radio_channel;
232 uint8_t radio_tx_power;
236 struct inga_config_s inga_cfg;
239 unsigned short node_id = NODE_ID;
241 void node_id_restore(
void) {
245 void node_id_burn(
unsigned short node_id) {
248 PRINTF(
"New Node ID: %04X\n", settings_nodeid);
250 PRINTF(
"Error: Error while writing NodeID to EEPROM\n");
254 #define CONVERTTXPOWER 1
255 #if CONVERTTXPOWER //adds ~120 bytes to program flash size
257 const char txonesdigit[16]
PROGMEM = {
'3',
'2',
'2',
'1',
'1',
'0',
'0',
'1',
'2',
'3',
'4',
'5',
'7',
'9',
'2',
'7'};
258 const char txtenthsdigit[16] PROGMEM = {
'0',
'8',
'3',
'8',
'3',
'7',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0'};
259 static void printtxpower(
void) {
260 uint8_t power = rf230_get_txpower() & 0xf;
261 char sign = (power < 0x7 ?
'+' :
'-');
262 char tens = (power > 0xD ?
'1' :
'0');
263 char ones = pgm_read_byte(&txonesdigit[power]);
264 char tenths = pgm_read_byte(&txtenthsdigit[power]);
266 printf_P(PSTR(
"%c%c.%cdBm"), sign, ones, tenths);
268 printf_P(PSTR(
"%c%c%c.%cdBm"), sign, tens, ones, tenths);
276 #ifndef INGA_CONF_BOOTSCREEN
277 #define INGA_BOOTSCREEN 1
279 #define INGA_BOOTSCREEN INGA_CONF_BOOTSCREEN
283 #ifndef INGA_CONF_BOOTSCREEN_NET
284 #define INGA_BOOTSCREEN_NET 1
286 #define INGA_BOOTSCREEN_NET INGA_CONF_BOOTSCREEN_NET
289 #ifndef INGA_CONF_BOOTSCREEN_NETSTACK
290 #define INGA_BOOTSCREEN_NETSTACK 1
292 #define INGA_BOOTSCREEN_NETSTACK INGA_CONF_BOOTSCREEN_NETSTACK
295 #ifndef INGA_CONF_BOOTSCREEN_RADIO
296 #define INGA_BOOTSCREEN_RADIO 1
298 #define INGA_BOOTSCREEN_RADIO INGA_CONF_BOOTSCREEN_RADIO
301 #ifndef INGA_CONF_BOOTSCREEN_SENSORS
302 #define INGA_BOOTSCREEN_SENSORS 1
304 #define INGA_BOOTSCREEN_SENSORS INGA_CONF_BOOTSCREEN_SENSORS
308 #define INGA_BOOTSCREEN_NET 0
309 #define INGA_BOOTSCREEN_NETSTACK 0
310 #define INGA_BOOTSCREEN_RADIO 0
311 #define INGA_BOOTSCREEN_SENSORS 0
314 #if INGA_BOOTSCREEN_SENSORS
315 const char msg_ok[6] PROGMEM =
"[OK]\n";
316 const char msg_err[7] PROGMEM =
"[N/A]\n";
317 #define CHECK_SENSOR(name, sensor) \
318 printf_P(PSTR(" " name ": ")); \
319 printf_P(sensor.status(SENSORS_READY) ? msg_ok : msg_err);
322 #define eui64_is_null(eui64) \
323 ((eui64[0] == 0x00) \
324 && (eui64[1] == 0x00) \
325 && (eui64[2] == 0x00) \
326 && (eui64[3] == 0x00) \
327 && (eui64[4] == 0x00) \
328 && (eui64[5] == 0x00) \
329 && (eui64[6] == 0x00) \
330 && (eui64[7] == 0x00))
332 #define pan_addr_from_eui64(eui64) \
333 (uint16_t) (eui64[0] + eui64[1] + eui64[2] + eui64[3] + eui64[4] + eui64[5] + eui64[6] + eui64[7]);
336 load_config(
struct inga_config_s* cfg)
339 #ifndef NODE_CONF_EUI64
343 PRINTD(
"EUI-64 not in EEPROM\n");
346 cfg->eui64_addr = {NODE_EUI64};
350 #ifndef RADIO_CONF_PAN_ID
354 cfg->pan_id = RADIO_PAN_ID;
355 PRINTD(
"PanID not in EEPROM - using default (0x%04x)\n", cfg->pan_id);
358 cfg->pan_id = RADIO_PAN_ID;
366 PRINTD(
"PanAddr not in EEPROM\n");
369 cfg->pan_adr = NODE_ID;
373 #ifndef RADIO_CONF_TX_POWER
377 cfg->radio_tx_power = RADIO_TX_POWER;
378 PRINTD(
"Radio TXPower not in EEPROM - using default (%d)\n", cfg->radio_tx_power);
381 cfg->radio_tx_power = RADIO_TX_POWER;
385 #ifndef RADIO_CONF_CHANNEL
389 cfg->radio_channel = RADIO_CHANNEL;
390 PRINTD(
"Radio Channel not in EEPROM - using default (%d)\n", cfg->radio_channel);
393 cfg->radio_channel = RADIO_CHANNEL;
399 PRINTD(
"Wrote new IEEE Addr to EEPROM.\n");
401 PRINTD(
"Failed writing IEEE Addr to EEPROM.\n");
408 memset(cfg->eui64_addr, 0,
sizeof(cfg->eui64_addr));
409 cfg->eui64_addr[6] = (node_id >> 8);
410 cfg->eui64_addr[7] = node_id & 0xFF;
412 cfg->eui64_addr[0] = node_id & 0xFF;
413 cfg->eui64_addr[1] = (node_id >> 8);
415 cfg->pan_addr = node_id;
418 if(eui64_is_null(cfg->eui64_addr)) {
419 generate_new_eui64(cfg->eui64_addr);
422 if(cfg->pan_addr == 0) {
423 cfg->pan_addr = pan_addr_from_eui64(cfg->eui64_addr);
427 #if INGA_BOOTSCREEN_NET
428 PRINTA(
"WPAN Info:\n");
429 PRINTA(
" EUI-64: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n\r",
438 PRINTA(
" PAN ID: 0x%04X\n", cfg->pan_id);
439 PRINTA(
" PAN ADDR: 0x%04X\n", cfg->pan_addr);
445 platform_radio_init(
struct inga_config_s* cfg)
448 NETSTACK_RADIO.init();
450 if (eui64_is_null(cfg->eui64_addr)) {
451 rf230_set_pan_addr( cfg->pan_id, cfg->pan_addr,
NULL);
453 rf230_set_pan_addr( cfg->pan_id, cfg->pan_addr, cfg->eui64_addr);
456 rf230_set_channel(cfg->radio_channel);
463 NETSTACK_NETWORK.init();
465 #if INGA_BOOTSCREEN_NETSTACK
466 PRINTA(
"Netstack info:\n");
467 PRINTA(
" NET: %s\n MAC: %s\n RDC: %s\n",
468 NETSTACK_NETWORK.name,
473 #if INGA_BOOTSCREEN_RADIO
474 PRINTA(
"Radio info:\n");
475 PRINTA(
" Check rate %lu Hz\n Channel: %u\n Power: %u",
476 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 :
477 NETSTACK_RDC.channel_check_interval()),
479 rf230_get_txpower());
494 extern void *watchdog_return_addr;
495 extern uint8_t mcusr_mirror;
498 void *wdt_addr = watchdog_return_addr;
505 rs232_init(RS232_PORT_0, USART_BAUD_INGA, USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
507 rs232_redirect_stdout(RS232_PORT_0);
513 PRINTA(
"\n*******Booting %s*******\nReset reason: ", CONTIKI_VERSION_STRING);
515 if (mcusr_mirror & _BV(JTRF))
517 if (mcusr_mirror & _BV(WDRF))
519 if (mcusr_mirror & _BV(BORF))
520 PRINTA(
"Brown-out ");
521 if (mcusr_mirror & _BV(EXTRF))
523 if (mcusr_mirror & _BV(PORF))
526 if (mcusr_mirror & _BV(WDRF))
527 PRINTA(
"Watchdog possibly occured at address %p\n", wdt_addr);
532 #if INGA_PERIODIC_STACK
533 #define STACK_FREE_MARK 0x4242
540 extern uint16_t __bss_end;
541 uint16_t p = (uint16_t) & __bss_end;
543 *(uint16_t *) p = STACK_FREE_MARK;
545 }
while (p < SP - 10);
553 #if INGA_CONF_RANDOM_BSN_SEQNO
561 #ifdef MICRO_SD_PWR_PIN
563 MICRO_SD_PWR_PORT_DDR |= (1 << MICRO_SD_PWR_PIN);
577 #if (APP_SETTINGS_SET == 1)
581 #if (APP_SETTINGS_DELETE == 1)
586 load_config(&inga_cfg);
591 #if LINKADDR_SIZE == 2
593 #elif LINKADDR_SIZE == 8
597 #error LINKADDR_SIZE not supported
602 platform_radio_init(&inga_cfg);
611 #if INGA_BOOTSCREEN_NET
612 PRINTA(
"IPv6 info:\n");
613 PRINTA(
" Tentative link-local IPv6 address ");
615 lladdr = uip_ds6_get_link_local(-1);
616 uip_debug_ipaddr_print(&(lladdr->ipaddr));
619 #if UIP_CONF_IPV6_RPL
620 PRINTA(
" RPL Enabled\n");
623 PRINTA(
" Routing Enabled, TCP_MSS: %u\n",
UIP_TCP_MSS);
629 #if INGA_BOOTSCREEN_NET
630 PRINTA(
"rime address:\n ");
632 for (i = 0; i <
sizeof (linkaddr_t); i++) {
633 PRINTA(
"%02x.", addr.u8[i]);
643 #if INGA_BOOTSCREEN_SENSORS
644 PRINTA(
"Sensors:\n");
645 CHECK_SENSOR(
"Button", button_sensor);
646 CHECK_SENSOR(
"Accelerometer", acc_sensor);
647 CHECK_SENSOR(
"Gyroscope", gyro_sensor);
648 CHECK_SENSOR(
"Pressure", pressure_sensor);
649 CHECK_SENSOR(
"Battery", battery_sensor);
653 PRINTA(
"******* Online *******\n\n");
662 static uint32_t clocktime;
674 extern volatile unsigned long radioontime;
675 PRINTF(
"%u(%u)s\n", clocktime, radioontime);
677 PRINTF(
"%us\n", clocktime);
682 #if INGA_PERIODIC_ROUTES
689 PRINTA(
"\nAddresses [%u max]\n", UIP_DS6_ADDR_NB);
690 for (i = 0; i < UIP_DS6_ADDR_NB; i++) {
691 if (uip_ds6_if.addr_list[i].isused) {
693 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
698 PRINTA(
"\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
700 for(nbr = nbr_table_head(ds6_neighbors);
702 nbr = nbr_table_next(ds6_neighbors, nbr)) {
704 uip_debug_ipaddr_print(&nbr->ipaddr);
707 if (nbr->isrouter) PRINTA(
" router");
708 switch (nbr->state) {
710 PRINTA(
" INCOMPLETE");
713 PRINTA(
" REACHABLE");
728 if (!any) PRINTA(
" <none>\n");
730 PRINTA(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
737 uip_debug_ipaddr_print(&r->ipaddr);
738 PRINTA(
"/%u (via ", r->length);
739 uip_debug_ipaddr_print(uip_ds6_route_nexthop(r));
740 PRINTA(
") %lus\n", r->state.lifetime);
743 if (!any) PRINTA(
" <none>\n");
744 PRINTA(
"\n---------\n");
748 #if INGA_PERIODIC_STACK
751 extern uint16_t __bss_end;
752 uint16_t p = (uint16_t) & __bss_end;
754 if (*(uint16_t *) p != STACK_FREE_MARK) {
755 PRINTF(
"Never-used stack > %d bytes\n", p - (uint16_t) & __bss_end);
759 }
while (p < RAMEND - 10);
770 SENSORS(&button_sensor, &acc_sensor, &gyro_sensor, &pressure_sensor, &battery_sensor);
778 autostart_start(autostart_processes);
786 debugflow[debugflowsize] = 0;
787 PRINTF(
"%s", debugflow);
804 log_message(
char *m1,
char *m2)
806 PRINTF(
"%s%s\n", m1, m2);