After a lot of tweaking and twiddling with the timing of the ContikiMAC code and the mechanisms in the CC2420 driver, things seem to work somewhat stable now - knock on wood!

This commit is contained in:
adamdunkels 2010-04-04 07:49:30 +00:00
parent a637ddaf4e
commit be117afe04
2 changed files with 45 additions and 37 deletions

View File

@ -28,7 +28,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* @(#)$Id: cc2420.c,v 1.49 2010/04/03 16:01:00 adamdunkels Exp $ * @(#)$Id: cc2420.c,v 1.50 2010/04/04 07:49:30 adamdunkels Exp $
*/ */
/* /*
* This code is almost device independent and should be easy to port. * This code is almost device independent and should be easy to port.
@ -183,29 +183,31 @@ static uint8_t locked, lock_on, lock_off;
static void static void
on(void) on(void)
{ {
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
/* PRINTF("on\n");*/ /* PRINTF("on\n");*/
receive_on = 1; receive_on = 1;
ENABLE_FIFOP_INT(); ENABLE_FIFOP_INT();
strobe(CC2420_SRXON); strobe(CC2420_SRXON);
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
leds_on(LEDS_GREEN);
} }
static void static void
off(void) off(void)
{ {
leds_on(LEDS_GREEN);
/* PRINTF("off\n");*/ /* PRINTF("off\n");*/
receive_on = 0; receive_on = 0;
/* Wait for transmission to end before turning radio off. */ /* Wait for transmission to end before turning radio off. */
while(status() & BV(CC2420_TX_ACTIVE)); while(status() & BV(CC2420_TX_ACTIVE));
flushrx();
strobe(CC2420_SRFOFF); strobe(CC2420_SRFOFF);
DISABLE_FIFOP_INT();
ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
DISABLE_FIFOP_INT();
leds_off(LEDS_GREEN); leds_off(LEDS_GREEN);
if(!FIFOP_IS_1) {
flushrx();
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#define GET_LOCK() locked++ #define GET_LOCK() locked++
@ -314,6 +316,8 @@ cc2420_init(void)
cc2420_set_pan_addr(0xffff, 0x0000, NULL); cc2420_set_pan_addr(0xffff, 0x0000, NULL);
cc2420_set_channel(26); cc2420_set_channel(26);
flushrx();
process_start(&cc2420_process, NULL); process_start(&cc2420_process, NULL);
return 1; return 1;
} }
@ -347,7 +351,7 @@ cc2420_transmit(unsigned short payload_len)
* transmission starts. * transmission starts.
*/ */
#ifdef TMOTE_SKY #ifdef TMOTE_SKY
#define LOOP_20_SYMBOLS 400 /* 326us (msp430 @ 2.4576MHz) */ #define LOOP_20_SYMBOLS 800 /* 326us (msp430 @ 2.4576MHz) */
#elif __AVR__ #elif __AVR__
#define LOOP_20_SYMBOLS 500 /* XXX */ #define LOOP_20_SYMBOLS 500 /* XXX */
#endif #endif
@ -708,17 +712,17 @@ cc2420_read(void *buf, unsigned short bufsize)
len = AUX_LEN; len = AUX_LEN;
} }
/* Clean up in case of FIFO overflow! This happens for every full if(FIFOP_IS_1) {
* length frame and is signaled by FIFOP = 1 and FIFO = 0. if(!FIFO_IS_1) {
*/ /* Clean up in case of FIFO overflow! This happens for every
if(FIFOP_IS_1 && !FIFO_IS_1) { * full length frame and is signaled by FIFOP = 1 and FIFO =
/* printf("cc2420_read: FIFOP_IS_1 1\n");*/ * 0. */
flushrx(); flushrx();
} else if(FIFOP_IS_1) { } else {
/* Another packet has been received and needs attention. */ /* Another packet has been received and needs attention. */
/* printf("attention\n");*/
process_poll(&cc2420_process); process_poll(&cc2420_process);
} }
}
RELEASE_LOCK(); RELEASE_LOCK();

View File

@ -28,7 +28,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: contikimac.c,v 1.24 2010/04/03 13:28:30 adamdunkels Exp $ * $Id: contikimac.c,v 1.25 2010/04/04 07:49:31 adamdunkels Exp $
*/ */
/** /**
@ -115,12 +115,12 @@ struct announcement_msg {
#define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000 #define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000
#define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500 #define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500
#define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 100 #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
#define SHORTEST_PACKET_SIZE 43 #define SHORTEST_PACKET_SIZE 43
#define MAX_SILENCE_PERIODS 5 #define MAX_SILENCE_PERIODS 5
#define MAX_NONACTIVITY_PERIODIC 30 #define MAX_NONACTIVITY_PERIODIC 10
/* The cycle time for announcements. */ /* The cycle time for announcements. */
#ifdef ANNOUNCEMENT_CONF_PERIOD #ifdef ANNOUNCEMENT_CONF_PERIOD
@ -206,7 +206,7 @@ on(void)
static void static void
off(void) off(void)
{ {
if(contikimac_is_on && radio_is_on != 0 && is_streaming == 0 && is_snooping == 0) { if(contikimac_is_on && radio_is_on != 0 && is_streaming == 0/* && is_snooping == 0*/) {
radio_is_on = 0; radio_is_on = 0;
NETSTACK_RADIO.off(); NETSTACK_RADIO.off();
} }
@ -293,7 +293,7 @@ powercycle(struct rtimer *t, void *ptr)
t0 = RTIMER_NOW(); t0 = RTIMER_NOW();
if(we_are_sending == 0) { if(we_are_sending == 0) {
powercycle_turn_radio_on(); powercycle_turn_radio_on();
#if 1 #if 0
#if NURTIMER #if NURTIMER
while(RTIMER_CLOCK_LT(t0, RTIMER_NOW(), t0 + CCA_CHECK_TIME)); while(RTIMER_CLOCK_LT(t0, RTIMER_NOW(), t0 + CCA_CHECK_TIME));
#else #else
@ -312,7 +312,7 @@ powercycle(struct rtimer *t, void *ptr)
} }
powercycle_turn_radio_off(); powercycle_turn_radio_off();
} }
schedule_powercycle(t, CCA_SLEEP_TIME + CCA_CHECK_TIME); schedule_powercycle(t, CCA_SLEEP_TIME);
PT_YIELD(&pt); PT_YIELD(&pt);
} }
@ -387,13 +387,13 @@ powercycle(struct rtimer *t, void *ptr)
compower_accumulate(&compower_idle_activity); compower_accumulate(&compower_idle_activity);
#endif /* CONTIKIMAC_CONF_COMPOWER */ #endif /* CONTIKIMAC_CONF_COMPOWER */
} }
} while(0 && (is_snooping) && } while(is_snooping &&
RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - 8 * CHECK_TIME * CCA_COUNT_MAX)); RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME));
if(is_snooping) { if(is_snooping) {
leds_on(LEDS_RED); leds_on(LEDS_RED);
} }
if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - 4)) { if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME)) {
schedule_powercycle(t, CYCLE_TIME - (RTIMER_NOW() - cycle_start) + 1); schedule_powercycle(t, CYCLE_TIME - (RTIMER_NOW() - cycle_start) + 1);
/* printf("cycle_start 0x%02x now 0x%02x wait 0x%02x\n", /* printf("cycle_start 0x%02x now 0x%02x wait 0x%02x\n",
cycle_start, RTIMER_NOW(), CYCLE_TIME - (RTIMER_NOW() - cycle_start));*/ cycle_start, RTIMER_NOW(), CYCLE_TIME - (RTIMER_NOW() - cycle_start));*/
@ -537,6 +537,8 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
} }
stream_until = RTIMER_NOW() + DEFAULT_STREAM_TIME; stream_until = RTIMER_NOW() + DEFAULT_STREAM_TIME;
is_streaming = 1; is_streaming = 1;
} else {
is_streaming = 0;
} }
} }
@ -679,9 +681,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
watchdog_periodic(); watchdog_periodic();
/* if(is_known_receiver && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { if(is_known_receiver && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) {
break; break;
}*/ }
len = 0; len = 0;
@ -691,8 +693,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
{ {
rtimer_clock_t wt; rtimer_clock_t wt;
rtimer_clock_t now = RTIMER_NOW(); rtimer_clock_t now = RTIMER_NOW();
int ret;
NETSTACK_RADIO.transmit(transmit_len); ret = NETSTACK_RADIO.transmit(transmit_len);
wt = RTIMER_NOW(); wt = RTIMER_NOW();
#if NURTIMER #if NURTIMER
@ -775,7 +778,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
} }
#if WITH_PHASE_OPTIMIZATION #if WITH_PHASE_OPTIMIZATION
if(!first_transmission) { /* if(!first_transmission)*/ {
/* COOJA_DEBUG_PRINTF("first phase 0x%02x\n", encounter_time % CYCLE_TIME);*/ /* COOJA_DEBUG_PRINTF("first phase 0x%02x\n", encounter_time % CYCLE_TIME);*/
@ -1002,6 +1005,7 @@ init(void)
static int static int
turn_on(void) turn_on(void)
{ {
if(contikimac_is_on == 0) {
contikimac_is_on = 1; contikimac_is_on = 1;
#if NURTIMER #if NURTIMER
rtimer_schedule(&rt, CYCLE_TIME, 1); rtimer_schedule(&rt, CYCLE_TIME, 1);
@ -1009,7 +1013,7 @@ turn_on(void)
rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1,
(void (*)(struct rtimer *, void *))powercycle, NULL); (void (*)(struct rtimer *, void *))powercycle, NULL);
#endif #endif
}
return 1; return 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/