Contiki 2.6
|
00001 #include "contiki.h" 00002 #include "soc.h" 00003 #include "sys/clock.h" 00004 #include "sys/autostart.h" 00005 #include "dev/serial-line.h" 00006 #include "dev/slip.h" 00007 #include "dev/leds.h" 00008 #include "dev/uart0.h" 00009 #include "dev/dma.h" 00010 #include "dev/cc2530-rf.h" 00011 #include "dev/watchdog.h" 00012 #include "dev/clock-isr.h" 00013 #include "dev/lpm.h" 00014 #include "dev/button-sensor.h" 00015 #include "dev/adc-sensor.h" 00016 #include "dev/leds-arch.h" 00017 #include "net/rime.h" 00018 #include "net/netstack.h" 00019 #include "net/mac/frame802154.h" 00020 #include "debug.h" 00021 #include "cc253x.h" 00022 #include "sfr-bits.h" 00023 #include "contiki-lib.h" 00024 #include "contiki-net.h" 00025 /*---------------------------------------------------------------------------*/ 00026 #if VIZTOOL_CONF_ON 00027 PROCESS_NAME(viztool_process); 00028 #endif 00029 /*---------------------------------------------------------------------------*/ 00030 #if STARTUP_CONF_VERBOSE 00031 #define PUTSTRING(...) putstring(__VA_ARGS__) 00032 #define PUTHEX(...) puthex(__VA_ARGS__) 00033 #define PUTBIN(...) putbin(__VA_ARGS__) 00034 #define PUTCHAR(...) putchar(__VA_ARGS__) 00035 #else 00036 #define PUTSTRING(...) 00037 #define PUTHEX(...) 00038 #define PUTBIN(...) 00039 #define PUTCHAR(...) 00040 #endif 00041 /*---------------------------------------------------------------------------*/ 00042 #if CLOCK_CONF_STACK_FRIENDLY 00043 extern volatile __bit sleep_flag; 00044 #endif 00045 /*---------------------------------------------------------------------------*/ 00046 extern rimeaddr_t rimeaddr_node_addr; 00047 static __data int r; 00048 static __data int len; 00049 /*---------------------------------------------------------------------------*/ 00050 #if ENERGEST_CONF_ON 00051 static unsigned long irq_energest = 0; 00052 #define ENERGEST_IRQ_SAVE(a) do { \ 00053 a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0) 00054 #define ENERGEST_IRQ_RESTORE(a) do { \ 00055 energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0) 00056 #else 00057 #define ENERGEST_IRQ_SAVE(a) do {} while(0) 00058 #define ENERGEST_IRQ_RESTORE(a) do {} while(0) 00059 #endif 00060 /*---------------------------------------------------------------------------*/ 00061 static void 00062 fade(int l) CC_NON_BANKED 00063 { 00064 volatile int i, a; 00065 int k, j; 00066 for(k = 0; k < 400; ++k) { 00067 j = k > 200? 400 - k: k; 00068 00069 leds_on(l); 00070 for(i = 0; i < j; ++i) { 00071 a = i; 00072 } 00073 leds_off(l); 00074 for(i = 0; i < 200 - j; ++i) { 00075 a = i; 00076 } 00077 } 00078 } 00079 /*---------------------------------------------------------------------------*/ 00080 static void 00081 set_rime_addr(void) CC_NON_BANKED 00082 { 00083 char i; 00084 00085 #if CC2530_CONF_MAC_FROM_PRIMARY 00086 __xdata unsigned char * macp = &X_IEEE_ADDR; 00087 #else 00088 __code unsigned char * macp = (__code unsigned char *) 0xFFE8; 00089 #endif 00090 00091 PUTSTRING("Rime is 0x"); 00092 PUTHEX(sizeof(rimeaddr_t)); 00093 PUTSTRING(" bytes long\n"); 00094 00095 #if CC2530_CONF_MAC_FROM_PRIMARY 00096 PUTSTRING("Reading MAC from Info Page\n"); 00097 #else 00098 PUTSTRING("Reading MAC from flash\n"); 00099 00100 /* 00101 * The MAC is always stored in 0xFFE8 of the highest BANK of our flash. This 00102 * maps to address 0xFFF8 of our CODE segment, when this BANK is selected. 00103 * Load the bank, read 8 bytes starting at 0xFFE8 and restore last BANK. 00104 * Since we are called from main(), this MUST be BANK1 or something is very 00105 * wrong. This code can be used even without a bankable firmware. 00106 */ 00107 00108 /* Don't interrupt us to make sure no BANK switching happens while working */ 00109 DISABLE_INTERRUPTS(); 00110 00111 /* Switch to the BANKn, 00112 * map CODE: 0x8000 - 0xFFFF to FLASH: 0xn8000 - 0xnFFFF */ 00113 FMAP = CC2530_LAST_FLASH_BANK; 00114 #endif 00115 00116 for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { 00117 rimeaddr_node_addr.u8[i] = *macp; 00118 macp++; 00119 } 00120 00121 #if !CC2530_CONF_MAC_FROM_PRIMARY 00122 /* Remap 0x8000 - 0xFFFF to BANK1 */ 00123 FMAP = 1; 00124 ENABLE_INTERRUPTS(); 00125 #endif 00126 00127 /* Now the address is stored MSB first */ 00128 #if STARTUP_CONF_VERBOSE 00129 PUTSTRING("Rime configured with address "); 00130 for(i = 0; i < RIMEADDR_SIZE - 1; i++) { 00131 PUTHEX(rimeaddr_node_addr.u8[i]); 00132 PUTCHAR(':'); 00133 } 00134 PUTHEX(rimeaddr_node_addr.u8[i]); 00135 PUTCHAR('\n'); 00136 #endif 00137 00138 cc2530_rf_set_addr(IEEE802154_PANID); 00139 return; 00140 } 00141 /*---------------------------------------------------------------------------*/ 00142 int 00143 main(void) CC_NON_BANKED 00144 { 00145 /* Hardware initialization */ 00146 clock_init(); 00147 soc_init(); 00148 rtimer_init(); 00149 00150 /* Init LEDs here */ 00151 leds_init(); 00152 leds_off(LEDS_ALL); 00153 fade(LEDS_GREEN); 00154 00155 /* initialize process manager. */ 00156 process_init(); 00157 00158 /* Init UART */ 00159 uart0_init(); 00160 00161 #if DMA_ON 00162 dma_init(); 00163 #endif 00164 00165 #if SLIP_ARCH_CONF_ENABLE 00166 slip_arch_init(0); 00167 #else 00168 uart0_set_input(serial_line_input_byte); 00169 serial_line_init(); 00170 #endif 00171 fade(LEDS_RED); 00172 00173 PUTSTRING("##########################################\n"); 00174 putstring(CONTIKI_VERSION_STRING "\n"); 00175 putstring("TI SmartRF05 EB\n"); 00176 switch(CHIPID) { 00177 case 0xA5: 00178 putstring("cc2530"); 00179 break; 00180 case 0xB5: 00181 putstring("cc2531"); 00182 break; 00183 case 0x95: 00184 putstring("cc2533"); 00185 break; 00186 case 0x8D: 00187 putstring("cc2540"); 00188 break; 00189 } 00190 00191 putstring("-" CC2530_FLAVOR_STRING ", "); 00192 puthex(CHIPINFO1 + 1); 00193 putstring("KB SRAM\n"); 00194 00195 PUTSTRING("\nSDCC Build:\n"); 00196 #if STARTUP_CONF_VERBOSE 00197 #ifdef HAVE_SDCC_BANKING 00198 PUTSTRING(" With Banking.\n"); 00199 #endif /* HAVE_SDCC_BANKING */ 00200 #ifdef SDCC_MODEL_LARGE 00201 PUTSTRING(" --model-large\n"); 00202 #endif /* SDCC_MODEL_LARGE */ 00203 #ifdef SDCC_MODEL_HUGE 00204 PUTSTRING(" --model-huge\n"); 00205 #endif /* SDCC_MODEL_HUGE */ 00206 #ifdef SDCC_STACK_AUTO 00207 PUTSTRING(" --stack-auto\n"); 00208 #endif /* SDCC_STACK_AUTO */ 00209 00210 PUTCHAR('\n'); 00211 00212 PUTSTRING(" Net: "); 00213 PUTSTRING(NETSTACK_NETWORK.name); 00214 PUTCHAR('\n'); 00215 PUTSTRING(" MAC: "); 00216 PUTSTRING(NETSTACK_MAC.name); 00217 PUTCHAR('\n'); 00218 PUTSTRING(" RDC: "); 00219 PUTSTRING(NETSTACK_RDC.name); 00220 PUTCHAR('\n'); 00221 00222 PUTSTRING("##########################################\n"); 00223 #endif 00224 00225 watchdog_init(); 00226 00227 /* Initialise the H/W RNG engine. */ 00228 random_init(0); 00229 00230 /* start services */ 00231 process_start(&etimer_process, NULL); 00232 ctimer_init(); 00233 00234 /* initialize the netstack */ 00235 netstack_init(); 00236 set_rime_addr(); 00237 00238 #if BUTTON_SENSOR_ON || ADC_SENSOR_ON 00239 process_start(&sensors_process, NULL); 00240 BUTTON_SENSOR_ACTIVATE(); 00241 ADC_SENSOR_ACTIVATE(); 00242 #endif 00243 00244 #if UIP_CONF_IPV6 00245 memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr)); 00246 queuebuf_init(); 00247 process_start(&tcpip_process, NULL); 00248 #endif /* UIP_CONF_IPV6 */ 00249 00250 #if VIZTOOL_CONF_ON 00251 process_start(&viztool_process, NULL); 00252 #endif 00253 00254 energest_init(); 00255 ENERGEST_ON(ENERGEST_TYPE_CPU); 00256 00257 autostart_start(autostart_processes); 00258 00259 watchdog_start(); 00260 00261 fade(LEDS_YELLOW); 00262 00263 while(1) { 00264 do { 00265 /* Reset watchdog and handle polls and events */ 00266 watchdog_periodic(); 00267 00268 #if CLOCK_CONF_STACK_FRIENDLY 00269 if(sleep_flag) { 00270 if(etimer_pending() && 00271 (etimer_next_expiration_time() - clock_time() - 1) > MAX_TICKS) { 00272 etimer_request_poll(); 00273 } 00274 sleep_flag = 0; 00275 } 00276 #endif 00277 r = process_run(); 00278 } while(r > 0); 00279 len = NETSTACK_RADIO.pending_packet(); 00280 if(len) { 00281 packetbuf_clear(); 00282 len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); 00283 if(len > 0) { 00284 packetbuf_set_datalen(len); 00285 NETSTACK_RDC.input(); 00286 } 00287 } 00288 00289 #if LPM_MODE 00290 #if (LPM_MODE==LPM_MODE_PM2) 00291 SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ 00292 while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ 00293 CLKCON |= OSC; /* Switch to the RCOSC */ 00294 while(!(CLKCON & OSC)); /* Wait till it's happened */ 00295 SLEEP |= OSC_PD; /* Turn the other one off */ 00296 #endif /* LPM_MODE==LPM_MODE_PM2 */ 00297 00298 /* 00299 * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM 00300 * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) 00301 */ 00302 SLEEPCMD = (SLEEPCMD & 0xFC) | (LPM_MODE - 1); 00303 00304 #if (LPM_MODE==LPM_MODE_PM2) 00305 /* 00306 * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or 00307 * no interrupt occurred and we can safely power down 00308 */ 00309 __asm 00310 nop 00311 nop 00312 nop 00313 __endasm; 00314 00315 if(SLEEPCMD & SLEEP_MODE0) { 00316 #endif /* LPM_MODE==LPM_MODE_PM2 */ 00317 00318 ENERGEST_OFF(ENERGEST_TYPE_CPU); 00319 ENERGEST_ON(ENERGEST_TYPE_LPM); 00320 00321 /* We are only interested in IRQ energest while idle or in LPM */ 00322 ENERGEST_IRQ_RESTORE(irq_energest); 00323 00324 /* Go IDLE or Enter PM1 */ 00325 PCON |= PCON_IDLE; 00326 00327 /* First instruction upon exiting PM1 must be a NOP */ 00328 __asm 00329 nop 00330 __endasm; 00331 00332 /* Remember energest IRQ for next pass */ 00333 ENERGEST_IRQ_SAVE(irq_energest); 00334 00335 ENERGEST_ON(ENERGEST_TYPE_CPU); 00336 ENERGEST_OFF(ENERGEST_TYPE_LPM); 00337 00338 #if (LPM_MODE==LPM_MODE_PM2) 00339 SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */ 00340 while(!(SLEEPCMD & SLEEP_XOSC_STB)); /* Wait for XOSC to be stable */ 00341 CLKCONCMD &= ~CLKCONCMD_OSC; /* Switch to the XOSC */ 00342 /* 00343 * On occasion the XOSC is reported stable when in reality it's not. 00344 * We need to wait for a safeguard of 64us or more before selecting it 00345 */ 00346 clock_delay_usec(65); 00347 while(CLKCONCMD & CLKCONCMD_OSC); /* Wait till it's happened */ 00348 } 00349 #endif /* LPM_MODE==LPM_MODE_PM2 */ 00350 #endif /* LPM_MODE */ 00351 } 00352 } 00353 /*---------------------------------------------------------------------------*/