diff --git a/core/net/mac/contikimac/contikimac.c b/core/net/mac/contikimac/contikimac.c index 104478282..290273fa1 100644 --- a/core/net/mac/contikimac/contikimac.c +++ b/core/net/mac/contikimac/contikimac.c @@ -289,9 +289,15 @@ off(void) } } /*---------------------------------------------------------------------------*/ -static volatile rtimer_clock_t cycle_start; static void powercycle_wrapper(struct rtimer *t, void *ptr); static char powercycle(struct rtimer *t, void *ptr); +/*---------------------------------------------------------------------------*/ +static volatile rtimer_clock_t cycle_start; +#if SYNC_CYCLE_STARTS +static volatile rtimer_clock_t sync_cycle_start; +static volatile uint8_t sync_cycle_phase; +#endif +/*---------------------------------------------------------------------------*/ static void schedule_powercycle(struct rtimer *t, rtimer_clock_t time) { @@ -340,7 +346,7 @@ powercycle_turn_radio_off(void) #if CONTIKIMAC_CONF_COMPOWER uint8_t was_on = radio_is_on; #endif /* CONTIKIMAC_CONF_COMPOWER */ - + if(we_are_sending == 0 && we_are_receiving_burst == 0) { off(); #if CONTIKIMAC_CONF_COMPOWER @@ -365,13 +371,34 @@ powercycle_wrapper(struct rtimer *t, void *ptr) powercycle(t, ptr); } /*---------------------------------------------------------------------------*/ +static void +advance_cycle_start(void) +{ + #if SYNC_CYCLE_STARTS + + /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple + of CHANNEL_CHECK_RATE */ + if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { + sync_cycle_phase = 0; + sync_cycle_start += RTIMER_ARCH_SECOND; + cycle_start = sync_cycle_start; + } else if( (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535) { + uint32_t phase_time = sync_cycle_phase*RTIMER_ARCH_SECOND; + + cycle_start = sync_cycle_start + phase_time/NETSTACK_RDC_CHANNEL_CHECK_RATE; + } else { + unsigned phase_time = sync_cycle_phase*RTIMER_ARCH_SECOND; + + cycle_start = sync_cycle_start + phase_time/NETSTACK_RDC_CHANNEL_CHECK_RATE; + } + #endif + + cycle_start += CYCLE_TIME; +} +/*---------------------------------------------------------------------------*/ static char powercycle(struct rtimer *t, void *ptr) { -#if SYNC_CYCLE_STARTS - static volatile rtimer_clock_t sync_cycle_start; - static volatile uint8_t sync_cycle_phase; -#endif PT_BEGIN(&pt); @@ -385,24 +412,6 @@ powercycle(struct rtimer *t, void *ptr) static uint8_t packet_seen; static uint8_t count; -#if SYNC_CYCLE_STARTS - /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple - of CHANNEL_CHECK_RATE */ - if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { - sync_cycle_phase = 0; - sync_cycle_start += RTIMER_ARCH_SECOND; - cycle_start = sync_cycle_start; - } else { -#if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535 - cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE; -#else - cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE; -#endif - } -#else - cycle_start += CYCLE_TIME; -#endif - packet_seen = 0; for(count = 0; count < CCA_COUNT_MAX; ++count) { @@ -483,22 +492,25 @@ powercycle(struct rtimer *t, void *ptr) } } - if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) { + advance_cycle_start(); + + if(RTIMER_CLOCK_LT(RTIMER_NOW() , cycle_start - CHECK_TIME * 4)) { /* Schedule the next powercycle interrupt, or sleep the mcu - until then. Sleeping will not exit from this interrupt, so - ensure an occasional wake cycle or foreground processing will - be blocked until a packet is detected */ + until then. Sleeping will not exit from this interrupt, so + ensure an occasional wake cycle or foreground processing will + be blocked until a packet is detected */ #if RDC_CONF_MCU_SLEEP + static uint8_t sleepcycle; if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { - rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start)); + rtimer_arch_sleep(RTIMER_NOW() - cycle_start); } else { sleepcycle = 0; - schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); + schedule_powercycle_fixed(t, cycle_start); PT_YIELD(&pt); } #else - schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); + schedule_powercycle_fixed(t, cycle_start); PT_YIELD(&pt); #endif } @@ -549,13 +561,13 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, int len; uint8_t seqno; #endif - + /* Exit if RDC and radio were explicitly turned off */ if(!contikimac_is_on && !contikimac_keep_radio_on) { PRINTF("contikimac: radio is turned off\n"); return MAC_TX_ERR_FATAL; } - + if(packetbuf_totlen() == 0) { PRINTF("contikimac: send_packet data len 0\n"); return MAC_TX_ERR_FATAL; @@ -597,10 +609,10 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, return MAC_TX_ERR_FATAL; } } - + transmit_len = packetbuf_totlen(); NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len); - + if(!is_broadcast && !is_receiver_awake) { #if WITH_PHASE_OPTIMIZATION ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), @@ -612,9 +624,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, if(ret != PHASE_UNKNOWN) { is_known_receiver = 1; } -#endif /* WITH_PHASE_OPTIMIZATION */ +#endif /* WITH_PHASE_OPTIMIZATION */ } - + /* By setting we_are_sending to one, we ensure that the rtimer @@ -632,7 +644,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet()); return MAC_TX_COLLISION; } - + /* Switch off the radio to ensure that we didn't start sending while the radio was doing a channel check. */ off(); @@ -838,7 +850,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) int ret; int is_receiver_awake; int pending; - + if(buf_list == NULL) { return; } @@ -850,7 +862,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1); return; } - + /* Create and secure frames in advance */ curr = buf_list; do { @@ -867,13 +879,13 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); return; } - + packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1); queuebuf_update_from_packetbuf(curr->buf); } curr = next; } while(next != NULL); - + /* The receiver needs to be awoken before we send */ is_receiver_awake = 0; curr = buf_list;