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
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
147 const struct uip_fallback_interface rpl_interface = {
151 #if RPL_BORDER_ROUTER
152 #include "net/rpl/rpl.h"
155 const uint16_t dag_id[] PROGMEM = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
157 PROCESS(border_router_process,
"RPL Border Router");
166 char buf[
sizeof(dag_id)];
167 memcpy_P(buf,dag_id,
sizeof(dag_id));
168 dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)buf);
175 PRINTD(
"created a new RPL dag\n");
177 #if UIP_CONF_ROUTER_RECEIVE_RA
183 uip_ip6addr(&ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x200);
185 rpl_set_prefix(dag, &ipaddr, 64);
209 #include <avr/signature.h>
212 typedef struct {
const unsigned char B2;
const unsigned char B1;
const unsigned char B0;} __signature_t;
213 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
221 FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
224 const uint8_t default_mac_address[8] PROGMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
225 #ifdef CHANNEL_802_15_4
226 const uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
228 const uint8_t default_channel PROGMEM = 26;
230 #ifdef IEEE802154_PANID
231 const uint16_t default_panid PROGMEM = IEEE802154_PANID;
233 const uint16_t default_panid PROGMEM = 0xABCD;
235 #ifdef IEEE802154_PANADDR
236 const uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
238 const uint16_t default_panaddr PROGMEM = 0;
240 #ifdef RF230_MAX_TX_POWER
241 const uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
243 const uint8_t default_txpower PROGMEM = 0;
246 #if JACKDAW_CONF_RANDOM_MAC
249 generate_new_eui64(uint8_t eui64[8]) {
251 eui64[1] = rng_get_uint8();
252 eui64[2] = rng_get_uint8();
255 eui64[5] = rng_get_uint8();
256 eui64[6] = rng_get_uint8();
257 eui64[7] = rng_get_uint8();
261 #if !JACKDAW_CONF_USE_SETTINGS
270 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
271 #ifdef CHANNEL_802_15_4
272 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
274 uint8_t eemem_channel[2] EMEM = {26, ~26};
276 #ifdef IEEE802154_PANID
277 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
279 uint16_t eemem_panid EEMEM = 0xABCD;
281 #ifdef IEEE802154_PANADDR
282 uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR;
284 uint16_t eemem_panaddr EEMEM = 0;
286 #ifdef RF230_MAX_TX_POWER
287 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
289 uint8_t eemem_txpower EEMEM = 0;
291 static uint8_t get_channel_from_eeprom() {
293 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
294 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
297 #if JACKDAW_CONF_RANDOM_MAC
298 PRINTA(
"Generating random MAC address.\n");
299 generate_new_eui64(&mac);
301 {uint8_t i;
for (i=0;i<8;i++) mac[i] = pgm_read_byte_near(default_mac_address+i);}
303 eeprom_write_block(&mac, &eemem_mac_address, 8);
304 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid));
305 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
306 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
307 x[0] = pgm_read_byte_near(&default_channel);
309 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
313 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
314 eeprom_read_block ((
void *)macptr, &eemem_mac_address, 8);
315 return macptr[0]!=0xFF;
317 static uint16_t get_panid_from_eeprom(
void) {
318 return eeprom_read_word(&eemem_panid);
320 static uint16_t get_panaddr_from_eeprom(
void) {
321 return eeprom_read_word (&eemem_panaddr);
323 static uint8_t get_txpower_from_eeprom(
void)
325 return eeprom_read_byte(&eemem_txpower);
330 static uint8_t get_channel_from_eeprom() {
332 if(!x) x = pgm_read_byte_near(&default_channel);
335 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
338 PRINTD(
"<=Get EEPROM MAC address.\n");
341 #if JACKDAW_CONF_RANDOM_MAC
342 PRINTA(
"--Generating random MAC address.\n");
343 generate_new_eui64(macptr);
345 {uint8_t i;
for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
348 PRINTA(
"->Set EEPROM MAC address.\n");
351 static uint16_t get_panid_from_eeprom(
void) {
355 PRINTD(
"<-Get EEPROM PAN ID of %04x.\n",x);
357 x=pgm_read_word_near(&default_panid);
359 PRINTA(
"->Set EEPROM PAN ID to %04x.\n",x);
364 static uint16_t get_panaddr_from_eeprom(
void) {
368 PRINTD(
"<-Get EEPROM PAN address of %04x.\n",x);
370 x=pgm_read_word_near(&default_panaddr);
372 PRINTA(
"->Set EEPROM PAN address to %04x.\n",x);
377 static uint8_t get_txpower_from_eeprom(
void) {
381 PRINTD(
"<-Get EEPROM tx power of %d. (0=max)\n",x);
383 x=pgm_read_byte_near(&default_txpower);
385 PRINTA(
"->Set EEPROM tx power of %d. (0=max)\n",x);
394 static void initialize(
void) {
399 #if CONFIG_STACK_MONITOR
404 extern uint16_t __bss_end;
405 uint16_t p=(uint16_t)&__bss_end;
407 *(uint16_t *)p = 0x4242;
432 while (ADCSRA&(1<<ADSC));
433 PRINTD(
"ADC=%d\n",ADC);
439 rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
441 rs232_redirect_stdout(RS232_PORT_0);
443 PRINTA(
"\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
465 for (i=0;i<65535;i++) {
471 PRINTA(
"\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
475 if (!stdout) Led3_on();
478 #if JACKDAW_CONF_USE_SETTINGS
479 PRINTA(
"Settings manager will be used.\n");
482 *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel);
483 if((uint8_t)x[0]!=(uint8_t)~x[1]) {
484 PRINTA(
"Invalid EEPROM settings detected. Rewriting with default values.\n");
485 get_channel_from_eeprom();
493 NETSTACK_RADIO.init();
497 memset(&tmp_addr, 0,
sizeof(linkaddr_t));
499 if(get_eui64_from_eeprom(tmp_addr.u8));
504 #if NETSTACK_CONF_WITH_IPV6
509 get_panid_from_eeprom(),
510 get_panaddr_from_eeprom(),
511 (uint8_t *)&tmp_addr.u8
514 rf230_set_channel(get_channel_from_eeprom());
515 rf230_set_txpower(get_txpower_from_eeprom());
523 NETSTACK_NETWORK.init();
526 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]);
527 PRINTA(
"%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
528 if (NETSTACK_RDC.channel_check_interval) {
530 tmp=
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
531 NETSTACK_RDC.channel_check_interval());
532 if (tmp<65535) PRINTA(
", check rate %u Hz",tmp);
537 #if UIP_CONF_IPV6_RPL
538 #if RPL_BORDER_ROUTER
541 PRINTD (
"RPL Border Router Started\n");
544 PRINTD (
"RPL Started\n");
547 extern struct process httpd_process;
549 PRINTD (
"Webserver Started\n");
556 #if NETSTACK_CONF_WITH_IPV6 || NETSTACK_CONF_WITH_IPV4
572 autostart_start(autostart_processes);
579 PRINTA(
"Online. Type ? for Jackdaw menu.\n");
592 asm volatile (
"clr r1");
599 for(p = PROCESS_LIST();p !=
NULL; p = ((
struct process *)p->next)) {
600 PRINTA(
"Process=%p Thread=%p Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p));
611 #ifdef RF230_MIN_RX_POWER
613 if (rf230_last_rssi != lastprint) {
614 PRINTA(
"%u ",rf230_last_rssi);
615 lastprint=rf230_last_rssi;
623 extern uint8_t rf230_calibrated;
624 if (rf230_calibrated) {
625 PRINTA(
"\nRF230 calibrated!\n");
641 if ((rtime%STAMPS)==0) {
642 PRINTA(
"%us ",rtime);
643 if (rtime%STAMPS*10) PRINTA(
"\n");
648 #if PINGS && UIP_CONF_IPV6_RPL
649 extern void raven_ping6(
void);
650 if ((rtime%PINGS)==1) {
656 #if ROUTES && UIP_CONF_IPV6_RPL
657 if ((rtime%ROUTES)==2) {
664 PRINTA(
"\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
665 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
666 if (uip_ds6_if.addr_list[i].isused) {
667 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
671 PRINTA(
"\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS);
673 for(nbr = nbr_table_head(ds6_neighbors);
675 nbr = nbr_table_next(ds6_neighbors, nbr)) {
676 uip_debug_ipaddr_print(&nbr->ipaddr);
680 if (j) PRINTA(
" <none>");
681 PRINTA(
"\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
683 for(r = uip_ds6_route_head();
685 r = uip_ds6_route_next(r)) {
687 uip_debug_ipaddr_print(&r->ipaddr);
688 PRINTA(
"/%u (via ", r->length);
689 uip_debug_ipaddr_print(uip_ds6_route_nexthop(r));
691 PRINTA(
") %lus\n", r->state.lifetime);
698 if (j) PRINTA(
" <none>");
699 PRINTA(
"\n---------\n");
703 #if STACKMONITOR && CONFIG_STACK_MONITOR
704 if ((rtime%STACKMONITOR)==3) {
705 extern uint16_t __bss_end;
706 uint16_t p=(uint16_t)&__bss_end;
708 if (*(uint16_t *)p != 0x4242) {
709 PRINTA(
"Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
713 }
while (p<RAMEND-10);
722 extern uint8_t debugflowsize,debugflow[];
724 debugflow[debugflowsize]=0;
725 PRINTA(
"%s",debugflow);
This file contains the USB driver routines.
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.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
#define SETTINGS_KEY_PAN_ADDR
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.
#define RTIMER_NOW()
Get the current clock time.
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
Header file for the managed memory allocator
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
void random_init(unsigned short seed)
Seed the cc2538 random number generator.
This file contains radio driver code.
void clock_init(void)
Initialize the clock library.
#define SETTINGS_KEY_EUI64
EUI64 Address, 8 bytes.
Example glue code between the existing MAC code and the Contiki mac interface.
An entry in the nbr cache.
#define SETTINGS_KEY_PAN_ID
int process_run(void)
Run the system once - call poll handlers and process one event.
Interface structure (contains all the interface variables)
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.
802.15.4 frame creation and parsing functions
#define PROCESS_YIELD()
Yield the currently running process.
void rs232_init(void)
Initialize the RS232 module.
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.
This file manages the RNDIS task.
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
void watchdog_periodic(void)
Writes the WDT clear sequence.
uint8_t settings_check(settings_key_t key, uint8_t index)
Checks to see if the given key exists.
#define CLOCK_SECOND
A second, measured in system clock time.
This file manages the USB task either device/host or both.
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
#define SETTINGS_KEY_CHANNEL
void process_start(struct process *p, process_data_t data)
Start a process.
int main(void)
This is main...
uip_ds6_addr_t * uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
Add a unicast address to the interface.
void rtimer_init(void)
Initialize the real-time scheduler.
void watchdog_init(void)
Copyright (c) 2014, Analog Devices, Inc.
static uint8_t output(const uip_lladdr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
void process_init(void)
Initialize the process module.
void ctimer_init(void)
Initialize the callback timer library.
uip_ds6_netif_t uip_ds6_if
The single interface.
Representation of a real-time task.
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01) ...
An entry in the routing table.
#define PROCESS_PAUSE()
Yield the process for a short while.
void mac_LowpanToEthernet(void)
Take a packet received over the 802.15.4 link, and send it out over ethernet, performing any translat...
uint64_t macLongAddr
Our own long address.
#define SETTINGS_KEY_TXPOWER
#define PROCESS_BEGIN()
Define the beginning of a process.