void init_lowlevel(void) { Leds_init(); Leds_off(); if (checkForFinger()) { #ifdef WINXPSP2 usb_mode = mass_storage; #else fingerPresent = 1; #endif } return; }
void init_lowlevel(void) { Leds_init(); Leds_off(); if (checkForFinger()) { if(bootloader_is_present()) Jump_To_Bootloader(); #ifdef WINXPSP2 usb_mode = mass_storage; #else fingerPresent = 1; #endif } return; }
/*-----------------------------Low level initialization--------------------*/ static void initialize(void) { watchdog_init(); watchdog_start(); #if CONFIG_STACK_MONITOR /* Simple stack pointer highwater monitor. The 'm' command in cdc_task.c * looks for the first overwritten magic number. */ { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { *(uint16_t *)p = 0x4242; p+=100; } while (p<RAMEND-100); } #endif /* Initialize hardware */ // Checks for "finger", jumps to DFU if present. init_lowlevel(); /* Clock */ clock_init(); #if USB_CONF_RS232 /* Use rs232 port for serial out (tx, rx, gnd are the three pads behind jackdaw leds */ rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Redirect stdout to second port */ rs232_redirect_stdout(RS232_PORT_0); #if ANNOUNCE printf_P(PSTR("\n\n\n********BOOTING CONTIKI*********\n")); #endif #endif Leds_init(); /* rtimer init needed for low power protocols */ rtimer_init(); /* Process subsystem. */ process_init(); /* etimer process must be started before ctimer init */ process_start(&etimer_process, NULL); #if RF230BB ctimer_init(); /* Start radio and radio receive process */ /* Note this starts RF230 process, so must be done after process_init */ NETSTACK_RADIO.init(); /* Set addresses BEFORE starting tcpip process */ memset(&tmp_addr, 0, sizeof(rimeaddr_t)); if(!get_eui64_from_eeprom(tmp_addr.u8)) { #if JACKDAW_CONF_RANDOM_MAC // It doesn't look like we have a valid EUI-64 address // so let's try to make a new one from scratch. Leds_off(); Led2_on(); generate_new_eui64(tmp_addr.u8); if(!set_eui64_to_eeprom(tmp_addr.u8)) { watchdog_periodic(); int i; for(i=0;i<20;i++) { Led1_toggle(); _delay_ms(100); } Led1_off(); } Led2_off(); #else tmp_addr.u8[0]=0x02; tmp_addr.u8[1]=0x12; tmp_addr.u8[2]=0x13; tmp_addr.u8[3]=0xff; tmp_addr.u8[4]=0xfe; tmp_addr.u8[5]=0x14; tmp_addr.u8[6]=0x15; tmp_addr.u8[7]=0x16; #endif /* JACKDAW_CONF_RANDOM_MAC */ } //Fix MAC address init_net(); #if UIP_CONF_IPV6 memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8); #endif rf230_set_pan_addr( get_panid_from_eeprom(), get_panaddr_from_eeprom(), (uint8_t *)&tmp_addr.u8 ); #if JACKDAW_CONF_USE_SETTINGS /* Allow radio code to overrite power for testing miniature Raven mesh */ #ifndef RF230_MAX_TX_POWER rf230_set_txpower(settings_get_uint8(SETTINGS_KEY_TXPOWER,0)); #endif #endif rimeaddr_set_node_addr(&tmp_addr); /* Initialize stack protocols */ queuebuf_init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); NETSTACK_NETWORK.init(); rf230_set_channel(get_channel_from_eeprom()); #if ANNOUNCE && USB_CONF_RS232 printf_P(PSTR("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]); printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); if (NETSTACK_RDC.channel_check_interval) { unsigned short tmp; tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ NETSTACK_RDC.channel_check_interval()); if (tmp<65535) printf_P(PSTR(", check rate %u Hz"),tmp); } printf_P(PSTR("\n")); #endif #if UIP_CONF_IPV6_RPL #if RPL_BORDER_ROUTER process_start(&tcpip_process, NULL); process_start(&border_router_process, NULL); PRINTF ("RPL Border Router Started\n"); #else process_start(&tcpip_process, NULL); PRINTF ("RPL Started\n"); #endif #if RPL_HTTPD_SERVER extern struct process httpd_process; process_start(&httpd_process, NULL); PRINTF ("Webserver Started\n"); #endif #endif /* UIP_CONF_IPV6_RPL */ #else /* RF230BB */ /* The order of starting these is important! */ process_start(&mac_process, NULL); process_start(&tcpip_process, NULL); #endif /* RF230BB */ /* Setup USB */ process_start(&usb_process, NULL); #if USB_CONF_SERIAL process_start(&cdc_process, NULL); #endif process_start(&usb_eth_process, NULL); #if USB_CONF_STORAGE process_start(&storage_process, NULL); #endif #if ANNOUNCE #if USB_CONF_SERIAL&&!USB_CONF_RS232 {unsigned short i; printf_P(PSTR("\n\n\n********BOOTING CONTIKI*********\n\r")); /* Allow USB CDC to keep up with printfs */ for (i=0;i<8000;i++) process_run(); #if RF230BB printf_P(PSTR("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]); for (i=0;i<8000;i++) process_run(); printf_P(PSTR("%s %s, channel %u"),NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); if (NETSTACK_RDC.channel_check_interval) { i=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ NETSTACK_RDC.channel_check_interval()); if (i<65535) printf_P(PSTR(", check rate %u Hz"),i); } printf_P(PSTR("\n\r")); for (i=0;i<8000;i++) process_run(); #endif /* RF230BB */ printf_P(PSTR("System online.\n\r")); } #elif USB_CONF_RS232 printf_P(PSTR("System online.\n")); #endif #endif /* ANNOUNCE */ }
/*-----------------------------Low level initialization--------------------*/ static void initialize(void) { watchdog_init(); watchdog_start(); #if CONFIG_STACK_MONITOR /* Simple stack pointer highwater monitor. The 'm' command in cdc_task.c * looks for the first overwritten magic number. */ { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { *(uint16_t *)p = 0x4242; p+=100; } while (p<SP-100); //don't overwrite our own stack } #endif /* Initialize hardware */ // Checks for "finger", jumps to DFU if present. init_lowlevel(); /* Clock */ clock_init(); /* Leds are referred to by number to prevent any possible confusion :) */ /* Led0 Blue Led1 Red Led2 Green Led3 Yellow */ Leds_init(); Led1_on(); /* Get a random (or probably different) seed for the 802.15.4 packet sequence number. * Some layers will ignore duplicates found in a history (e.g. Contikimac) * causing the initial packets to be ignored after a short-cycle restart. */ ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock ADCSRA|=1<<ADSC; //Start conversion while (ADCSRA&(1<<ADSC)); //Wait till done PRINTD("ADC=%d\n",ADC); random_init(ADC); ADCSRA=0; //Disable ADC #if USB_CONF_RS232 /* Use rs232 port for serial out (tx, rx, gnd are the three pads behind jackdaw leds */ rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Redirect stdout to second port */ rs232_redirect_stdout(RS232_PORT_0); #if ANNOUNCE PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); #endif #endif /* rtimer init needed for low power protocols */ rtimer_init(); /* Process subsystem. */ process_init(); /* etimer process must be started before USB or ctimer init */ process_start(&etimer_process, NULL); Led2_on(); /* Now we can start USB enumeration */ process_start(&usb_process, NULL); /* Start CDC enumeration, bearing in mind that it may fail */ /* Hopefully we'll get a stdout for startup messages, if we don't already */ #if USB_CONF_SERIAL process_start(&cdc_process, NULL); {unsigned short i; for (i=0;i<65535;i++) { process_run(); watchdog_periodic(); if (stdout) break; } #if !USB_CONF_RS232 PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); #endif } #endif if (!stdout) Led3_on(); #if RF230BB #if JACKDAW_CONF_USE_SETTINGS PRINTA("Settings manager will be used.\n"); #else {uint8_t x[2]; *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel); if((uint8_t)x[0]!=(uint8_t)~x[1]) { PRINTA("Invalid EEPROM settings detected. Rewriting with default values.\n"); get_channel_from_eeprom(); } } #endif ctimer_init(); /* Start radio and radio receive process */ /* Note this starts RF230 process, so must be done after process_init */ NETSTACK_RADIO.init(); /* Set addresses BEFORE starting tcpip process */ memset(&tmp_addr, 0, sizeof(rimeaddr_t)); if(get_eui64_from_eeprom(tmp_addr.u8)); //Fix MAC address init_net(); #if UIP_CONF_IPV6 memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8); #endif rf230_set_pan_addr( get_panid_from_eeprom(), get_panaddr_from_eeprom(), (uint8_t *)&tmp_addr.u8 ); rf230_set_channel(get_channel_from_eeprom()); rf230_set_txpower(get_txpower_from_eeprom()); rimeaddr_set_node_addr(&tmp_addr); /* Initialize stack protocols */ queuebuf_init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); NETSTACK_NETWORK.init(); #if ANNOUNCE 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]); PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); if (NETSTACK_RDC.channel_check_interval) { unsigned short tmp; tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ NETSTACK_RDC.channel_check_interval()); if (tmp<65535) PRINTA(", check rate %u Hz",tmp); } PRINTA("\n"); #endif #if UIP_CONF_IPV6_RPL #if RPL_BORDER_ROUTER process_start(&tcpip_process, NULL); process_start(&border_router_process, NULL); PRINTD ("RPL Border Router Started\n"); #else process_start(&tcpip_process, NULL); PRINTD ("RPL Started\n"); #endif #if RPL_HTTPD_SERVER extern struct process httpd_process; process_start(&httpd_process, NULL); PRINTD ("Webserver Started\n"); #endif #endif /* UIP_CONF_IPV6_RPL */ #else /* RF230BB */ /* The order of starting these is important! */ process_start(&mac_process, NULL); process_start(&tcpip_process, NULL); #endif /* RF230BB */ /* Start ethernet network and storage process */ process_start(&usb_eth_process, NULL); #if USB_CONF_STORAGE process_start(&storage_process, NULL); #endif /* Autostart other processes */ /* There are none in the default build so autostart_processes will be unresolved in the link. */ /* The AUTOSTART_PROCESSES macro which defines it can only be used in the .co module. */ /* See /examples/ravenusbstick/ravenusb.c for an autostart template. */ #if 0 autostart_start(autostart_processes); #endif #if ANNOUNCE #if USB_CONF_RS232 PRINTA("Online.\n"); #else PRINTA("Online. Type ? for Jackdaw menu.\n"); #endif #endif Leds_off(); }
/** \brief Process incomming char on debug port */ void menu_process(char c) { static enum menustate_enum /* Defines an enumeration type */ { normal, channel } menustate = normal; static char channel_string[3]; static uint8_t channel_string_i = 0; int tempchannel; if (menustate == channel) { switch(c) { case '\r': case '\n': channel_string[channel_string_i] = 0; //Will return zero in event of error... tempchannel = atoi(channel_string); //Bounds check only if user had real input if ( ((channel_string_i) && (tempchannel < 11)) || (tempchannel > 26)) { PRINTF_P(PSTR("\n\rInvalid input\n\r")); } //If valid input, change it if (tempchannel) { radio_set_operating_channel(tempchannel); eeprom_write_byte(9, tempchannel); //Write channel eeprom_write_byte(10, ~tempchannel); //Bit inverse as check } menustate = normal; break; case '\b': if (channel_string_i) channel_string_i--; break; default: if (channel_string_i > 1) { menustate = normal; PRINTF_P(PSTR("\n\rInput too long!\n\r")); break; } channel_string[channel_string_i] = c; channel_string_i++; } } else { uint8_t i; switch(c) { case '\r': case '\n': break; case 'h': case '?': menu_print(); break; case 's': PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r")); usbstick_mode.sendToRf = 0; usbstick_mode.translate = 0; break; case 'n': PRINTF_P(PSTR("Jackdaw now in network mode\n\r")); usbstick_mode.sendToRf = 1; usbstick_mode.translate = 1; break; case '6': if (usbstick_mode.sicslowpan) { PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r")); usbstick_mode.sicslowpan = 0; } else { PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r")); usbstick_mode.sicslowpan = 1; } break; case 'r': if (usbstick_mode.raw) { PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r")); usbstick_mode.raw = 0; } else { PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r")); usbstick_mode.raw = 1; } break; case 'c': PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel()); menustate = channel; channel_string_i = 0; break; case 'm': PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will ")); if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));} PRINTF_P(PSTR("send data over RF\n\r * Will ")); if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));} PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will ")); if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));} PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will ")); if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));} PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r ")); PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel()); break; case 'u': //Mass storage mode usb_mode = mass_storage; //No more serial port stdout = NULL; //RNDIS is over rndis_state = rndis_uninitialized; Leds_off(); //Deatch USB Usb_detach(); //Wait a few seconds for(i = 0; i < 50; i++) _delay_ms(100); //Attach USB Usb_attach(); break; default: PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c); break; } } return; }
void nodeSleep(u16 tenthSeconds) { // ************** Power down the other board peripherals Leds_off(); // ************** Power down the radio // wait for radio to be done u8 state = BUSY_TX_ARET; while (state == BUSY_TX_ARET || state == BUSY_RX_AACK) state = radioGetTrxState(); // Now put radio to sleep radioEnterSleepMode(); // TODO: figure out what needs to be put to sleep to minimize current consumption // ************** Power down the on-chip modules // PRR = 0xbf; ??? // Disable ADC // ADCSRA &= ~(1 << ADEN); // Turn off comparator // ACSR |= (1 << // turn off ports etc // Turn off BOD // This should only be done once -- No need to do it over again /* AVR_ENTER_CRITICAL_REGION(); #define BODS 6 #define BODSE 5 MCUCR |= (1 << BODSE) | (1<< BODS); MCUCR &= ~(1 << BODSE); AVR_LEAVE_CRITICAL_REGION(); */ // ************** Set the timer to wake up // Set TIMER2 Asyncronous Mode. ASSR |= (1 << AS2); // Set TIMER2 Prescaler to 1024. TCCR2B |= ((1 << CS22)|(1 << CS21)|(1 << CS20)); // Wait for TCNT2 write to finish. while(ASSR & (1 << TCR2BUB)) ; // Sleep as many times as needed to sleep for the full time while (tenthSeconds) { // This is to get the node manually out of sleeping mode -- // Might take up to 7.5Sec to detect button press // if (BUTTON_PRESSED() ) { Led1_on(); macConfig.sleeping = false; while (BUTTON_PRESSED()) ; Led1_off(); break; // exit the Sleeping loop } // Set TIMER2 output compare register from user. if (tenthSeconds > 75) { // Just decrement by the max timeout OCR2A = 240; // 7.5 seconds, max timeout tenthSeconds -= 75; } else { // Can measure the remaining time in one timer cycle tenthSeconds = tenthSeconds * 16 / 5; if (!tenthSeconds) tenthSeconds++; OCR2A = tenthSeconds; tenthSeconds = 0; } // Wait for OCR2 write to finish. while(ASSR & (1 << OCR2AUB)) ; // Reset TIMER2 timer counter value. TCNT2 = 0; // Wait for TCNT2 write to finish before entering sleep. while(ASSR & (1 << TCN2UB)) ; // Clear interrupt flag TIFR2 |= (1 << OCF2A); // Enable TIMER2 output compare interrupt. TIMSK2 |= (1 << OCIE2A); // ************** Go to sleep AVR_ENTER_CRITICAL_REGION(); set_sleep_mode( SLEEP_MODE_PWR_SAVE); sleep_enable(); sei(); sleep_cpu(); // sleeping right here sleep_disable(); AVR_LEAVE_CRITICAL_REGION(); wdt_disable(); } // ************** Awake now, wake up everything // PRR = 0x03; ?? if (SERIAL) serial_init(NULL); debugMsgStr("\r\nNode slept"); if ( macConfig.associated) HAL_ADC_INIT(); // Bring SPI port back up (must re-init after sleep) radio_spi_init(); // Wake up radio. radioLeaveSleepMode(); // Set RF212 to 250KB mode. // TODO: do I need to call this?? //radioSetup900(); radioSetTrxState(PLL_ON); }