Fixed wrong first cycle_start
The first time that powercycle() runs, cycle_start is incremented by CHECK_TIME twice which causes the second cycle to be late. This commit fixes this.
This commit is contained in:
parent
0313a429e2
commit
ac6a1c5255
1 changed files with 54 additions and 42 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue