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:
Billy Kozak 2015-07-10 15:44:46 -06:00
parent 0313a429e2
commit ac6a1c5255

View File

@ -289,9 +289,15 @@ off(void)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static volatile rtimer_clock_t cycle_start;
static void powercycle_wrapper(struct rtimer *t, void *ptr); static void powercycle_wrapper(struct rtimer *t, void *ptr);
static char powercycle(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 static void
schedule_powercycle(struct rtimer *t, rtimer_clock_t time) schedule_powercycle(struct rtimer *t, rtimer_clock_t time)
{ {
@ -365,13 +371,34 @@ powercycle_wrapper(struct rtimer *t, void *ptr)
powercycle(t, 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 static char
powercycle(struct rtimer *t, void *ptr) 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); PT_BEGIN(&pt);
@ -385,24 +412,6 @@ powercycle(struct rtimer *t, void *ptr)
static uint8_t packet_seen; static uint8_t packet_seen;
static uint8_t count; 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; packet_seen = 0;
for(count = 0; count < CCA_COUNT_MAX; ++count) { 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 /* Schedule the next powercycle interrupt, or sleep the mcu
until then. Sleeping will not exit from this interrupt, so until then. Sleeping will not exit from this interrupt, so
ensure an occasional wake cycle or foreground processing will ensure an occasional wake cycle or foreground processing will
be blocked until a packet is detected */ be blocked until a packet is detected */
#if RDC_CONF_MCU_SLEEP #if RDC_CONF_MCU_SLEEP
static uint8_t sleepcycle; static uint8_t sleepcycle;
if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) { 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 { } else {
sleepcycle = 0; sleepcycle = 0;
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); schedule_powercycle_fixed(t, cycle_start);
PT_YIELD(&pt); PT_YIELD(&pt);
} }
#else #else
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); schedule_powercycle_fixed(t, cycle_start);
PT_YIELD(&pt); PT_YIELD(&pt);
#endif #endif
} }