45 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
50 #include <avr/pgmspace.h>
52 #include <avr/eeprom.h>
54 #include <util/delay.h>
59 #include "loader/symbols-def.h"
60 #include "loader/symtab.h"
63 #include "contiki-net.h"
64 #include "contiki-lib.h"
65 #include "contiki-raven.h"
71 #if USB_CONF_SERIAL||USB_CONF_RS232
72 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
82 #include "dev/rs232.h"
87 #include "storage/storage_task.h"
90 #include "dev/watchdog.h"
93 #if JACKDAW_CONF_USE_SETTINGS
97 #if RF230BB //radio driver using contiki core mac
98 #include "radio/rf230bb/rf230bb.h"
100 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
102 #define tmp_addr macLongAddr
103 #else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC
106 #include "sicslowmac.h"
117 #define STACKMONITOR 600
118 uint8_t rtimerflag=1;
121 void rtimercycle(
void) {rtimerflag=1;}
124 #if UIP_CONF_IPV6_RPL
146 const struct uip_fallback_interface rpl_interface = {
150 #if RPL_BORDER_ROUTER
151 #include "net/rpl/rpl.h"
154 const uint16_t dag_id[]
PROGMEM = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
156 PROCESS(border_router_process,
"RPL Border Router");
165 char buf[
sizeof(dag_id)];
166 memcpy_P(buf,dag_id,
sizeof(dag_id));
167 dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)buf);
174 PRINTD(
"created a new RPL dag\n");
176 #if UIP_CONF_ROUTER_RECEIVE_RA
181 uip_ip6addr_t ipaddr;
182 uip_ip6addr(&ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x200);
183 uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
184 rpl_set_prefix(dag, &ipaddr, 64);
208 #include <avr/signature.h>
211 typedef struct {
const unsigned char B2;
const unsigned char B1;
const unsigned char B0;} __signature_t;
212 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
220 FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
223 const uint8_t default_mac_address[8]
PROGMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
224 #ifdef CHANNEL_802_15_4
225 const uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
227 const uint8_t default_channel PROGMEM = 26;
229 #ifdef IEEE802154_PANID
230 const uint16_t default_panid PROGMEM = IEEE802154_PANID;
232 const uint16_t default_panid PROGMEM = 0xABCD;
234 #ifdef IEEE802154_PANADDR
235 const uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
237 const uint16_t default_panaddr PROGMEM = 0;
239 #ifdef RF230_MAX_TX_POWER
240 const uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
242 const uint8_t default_txpower PROGMEM = 0;
245 #if JACKDAW_CONF_RANDOM_MAC
248 generate_new_eui64(uint8_t eui64[8]) {
250 eui64[1] = rng_get_uint8();
251 eui64[2] = rng_get_uint8();
254 eui64[5] = rng_get_uint8();
255 eui64[6] = rng_get_uint8();
256 eui64[7] = rng_get_uint8();
260 #if !JACKDAW_CONF_USE_SETTINGS
269 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
270 #ifdef CHANNEL_802_15_4
271 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
273 uint8_t eemem_channel[2] EMEM = {26, ~26};
275 #ifdef IEEE802154_PANID
276 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
278 uint16_t eemem_panid EEMEM = 0xABCD;
280 #ifdef IEEE802154_PANADDR
281 uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
283 uint16_t eemem_panaddr EEMEM = 0;
285 #ifdef RF230_MAX_TX_POWER
286 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
288 uint8_t eemem_txpower EEMEM = 0;
290 static uint8_t get_channel_from_eeprom() {
292 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
293 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
296 #if JACKDAW_CONF_RANDOM_MAC
297 PRINTA(
"Generating random MAC address.\n");
298 generate_new_eui64(&mac);
300 {uint8_t i;
for (i=0;i<8;i++) mac[i] = pgm_read_byte_near(default_mac_address+i);}
302 eeprom_write_block(&mac, &eemem_mac_address, 8);
303 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
304 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
305 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
306 x[0] = pgm_read_byte_near(&default_channel);
308 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
312 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
313 eeprom_read_block ((
void *)macptr, &eemem_mac_address, 8);
314 return macptr[0]!=0xFF;
316 static uint16_t get_panid_from_eeprom(
void) {
317 return eeprom_read_word(&eemem_panid);
319 static uint16_t get_panaddr_from_eeprom(
void) {
320 return eeprom_read_word (&eemem_panaddr);
322 static uint8_t get_txpower_from_eeprom(
void)
324 return eeprom_read_byte(&eemem_txpower);
329 static uint8_t get_channel_from_eeprom() {
331 if(!x) x = pgm_read_byte_near(&default_channel);
334 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
337 PRINTD(
"<=Get EEPROM MAC address.\n");
340 #if JACKDAW_CONF_RANDOM_MAC
341 PRINTA(
"--Generating random MAC address.\n");
342 generate_new_eui64(macptr);
344 {uint8_t i;
for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
347 PRINTA(
"->Set EEPROM MAC address.\n");
350 static uint16_t get_panid_from_eeprom(
void) {
354 PRINTD(
"<-Get EEPROM PAN ID of %04x.\n",x);
356 x=pgm_read_word_near(&default_panid);
358 PRINTA(
"->Set EEPROM PAN ID to %04x.\n",x);
363 static uint16_t get_panaddr_from_eeprom(
void) {
367 PRINTD(
"<-Get EEPROM PAN address of %04x.\n",x);
369 x=pgm_read_word_near(&default_panaddr);
371 PRINTA(
"->Set EEPROM PAN address to %04x.\n",x);
376 static uint8_t get_txpower_from_eeprom(
void) {
380 PRINTD(
"<-Get EEPROM tx power of %d. (0=max)\n",x);
382 x=pgm_read_byte_near(&default_txpower);
384 PRINTA(
"->Set EEPROM tx power of %d. (0=max)\n",x);
393 static void initialize(
void) {
398 #if CONFIG_STACK_MONITOR
403 extern uint16_t __bss_end;
404 uint16_t p=(uint16_t)&__bss_end;
406 *(uint16_t *)p = 0x4242;
431 while (ADCSRA&(1<<ADSC));
432 PRINTD(
"ADC=%d\n",ADC);
438 rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
440 rs232_redirect_stdout(RS232_PORT_0);
442 PRINTA(
"\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
464 for (i=0;i<65535;i++) {
470 PRINTA(
"\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
474 if (!stdout) Led3_on();
477 #if JACKDAW_CONF_USE_SETTINGS
478 PRINTA(
"Settings manager will be used.\n");
481 *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel);
482 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
483 PRINTA(
"Invalid EEPROM settings detected. Rewriting with default values.\n");
484 get_channel_from_eeprom();
492 NETSTACK_RADIO.init();
496 memset(&tmp_addr, 0,
sizeof(linkaddr_t));
498 if(get_eui64_from_eeprom(tmp_addr.u8));
508 get_panid_from_eeprom(),
509 get_panaddr_from_eeprom(),
510 (uint8_t *)&tmp_addr.u8
513 rf230_set_channel(get_channel_from_eeprom());
514 rf230_set_txpower(get_txpower_from_eeprom());
522 NETSTACK_NETWORK.init();
525 PRINTA(
"MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r",tmp_addr.u8[0],tmp_addr.u8[1],tmp_addr.u8[2],tmp_addr.u8[3],tmp_addr.u8[4],tmp_addr.u8[5],tmp_addr.u8[6],tmp_addr.u8[7]);
526 PRINTA(
"%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
527 if (NETSTACK_RDC.channel_check_interval) {
529 tmp=
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
530 NETSTACK_RDC.channel_check_interval());
531 if (tmp<65535) PRINTA(
", check rate %u Hz",tmp);
536 #if UIP_CONF_IPV6_RPL
537 #if RPL_BORDER_ROUTER
540 PRINTD (
"RPL Border Router Started\n");
543 PRINTD (
"RPL Started\n");
546 extern struct process httpd_process;
548 PRINTD (
"Webserver Started\n");
569 autostart_start(autostart_processes);
576 PRINTA(
"Online. Type ? for Jackdaw menu.\n");
589 asm volatile (
"clr r1");
596 for(p = PROCESS_LIST();p !=
NULL; p = ((
struct process *)p->next)) {
597 PRINTA(
"Process=%p Thread=%p Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p));
608 #ifdef RF230_MIN_RX_POWER
610 if (rf230_last_rssi != lastprint) {
611 PRINTA(
"%u ",rf230_last_rssi);
612 lastprint=rf230_last_rssi;
620 extern uint8_t rf230_calibrated;
621 if (rf230_calibrated) {
622 PRINTA(
"\nRF230 calibrated!\n");
638 if ((rtime%STAMPS)==0) {
639 PRINTA(
"%us ",rtime);
640 if (rtime%STAMPS*10) PRINTA(
"\n");
645 #if PINGS && UIP_CONF_IPV6_RPL
646 extern void raven_ping6(
void);
647 if ((rtime%PINGS)==1) {
653 #if ROUTES && UIP_CONF_IPV6_RPL
654 if ((rtime%ROUTES)==2) {
661 PRINTA(
"\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
662 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
663 if (uip_ds6_if.addr_list[i].isused) {
664 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
668 PRINTA(
"\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
670 for(nbr = nbr_table_head(ds6_neighbors);
672 nbr = nbr_table_next(ds6_neighbors, nbr)) {
673 uip_debug_ipaddr_print(&nbr->ipaddr);
677 if (j) PRINTA(
" <none>");
678 PRINTA(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
680 for(r = uip_ds6_route_head();
682 r = uip_ds6_route_next(r)) {
684 uip_debug_ipaddr_print(&r->ipaddr);
685 PRINTA(
"/%u (via ", r->length);
686 uip_debug_ipaddr_print(uip_ds6_route_nexthop(r));
688 PRINTA(
") %lus\n", r->state.lifetime);
695 if (j) PRINTA(
" <none>");
696 PRINTA(
"\n---------\n");
700 #if STACKMONITOR && CONFIG_STACK_MONITOR
701 if ((rtime%STACKMONITOR)==3) {
702 extern uint16_t __bss_end;
703 uint16_t p=(uint16_t)&__bss_end;
705 if (*(uint16_t *)p != 0x4242) {
706 PRINTA(
"Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
710 }
while (p<RAMEND-10);
719 extern uint8_t debugflowsize,debugflow[];
721 debugflow[debugflowsize]=0;
722 PRINTA(
"%s",debugflow);
void rs232_init(void)
Initialize the RS232 module.
settings_status_t settings_get(settings_key_t key, uint8_t index, uint8_t *value, settings_length_t *value_size)
Fetches the value associated with the given key.
uip_len
The length of the packet in the uip_buf buffer.
An entry in the routing table.
#define SETTINGS_KEY_CHANNEL
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
802.15.4 frame creation and parsing functions
This file manages the USB task either device/host or both.
#define PROCESS_BEGIN()
Define the beginning of a process.
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Header file for the managed memory allocator
int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr)
Post a real-time task.
void rtimer_init(void)
Initialize the real-time scheduler.
uint8_t settings_check(settings_key_t key, uint8_t index)
Checks to see if the given key exists.
Example glue code between the existing MAC code and the Contiki mac interface.
This file contains the USB driver routines.
#define NULL
The null pointer.
void clock_init(void)
Initialize the clock library.
#define SETTINGS_KEY_TXPOWER
int main(void)
This is main...
uint64_t macLongAddr
Our own long address.
void process_init(void)
Initialize the process module.
const uint32_t OIDSupportedList[] PROGMEM
List of supported RNDIS OID's.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01) ...
void random_init(unsigned short seed)
Seed the cc2430 random number generator.
This file manages the RNDIS task.
void watchdog_periodic(void)
Writes the WDT clear sequence.
settings_status_t settings_add(settings_key_t key, const uint8_t *value, settings_length_t value_size)
Adds the given key-value pair to the end of the settings store.
void ctimer_init(void)
Initialize the callback timer library.
#define PROCESS_PAUSE()
Yield the process for a short while.
#define SETTINGS_KEY_EUI64
EUI64 Address, 8 bytes.
#define PROCESS(name, strname)
Declare a process.
This file manages the CDC task for the virtual COM port.
void process_start(struct process *p, process_data_t data)
Start a process.
#define RTIMER_NOW()
Get the current clock time.
Interface structure (contains all the interface variables)
#define PROCESS_YIELD()
Yield the currently running process.
int process_run(void)
Run the system once - call poll handlers and process one event.
#define SETTINGS_KEY_PAN_ID
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
void mac_LowpanToEthernet(void)
Take a packet received over the 802.15.4 link, and send it out over ethernet, performing any translat...
Representation of a real-time task.
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
void watchdog_init(void)
Copyright (c) 2014, Analog Devices, Inc.
#define SETTINGS_KEY_PAN_ADDR
#define CLOCK_SECOND
A second, measured in system clock time.
An entry in the nbr cache.