Пример #1
0
/*---------------------------------------------------------------------------*/
void
lpm_exit()
{
  if((REG(SYS_CTRL_PMCTL) & SYS_CTRL_PMCTL_PM3) == SYS_CTRL_PMCTL_PM0) {
    /* We either just exited PM0 or we were not sleeping in the first place.
     * We don't need to do anything clever */
    return;
  }

  LPM_STATS_ADD(REG(SYS_CTRL_PMCTL) & SYS_CTRL_PMCTL_PM3,
                RTIMER_NOW() - sleep_enter_time);

  /* Adjust the system clock, since it was not counting while we were sleeping
   * We need to convert sleep duration from rtimer ticks to clock ticks and
   * this will cost us some accuracy */
  clock_adjust((clock_time_t)
               ((RTIMER_NOW() - sleep_enter_time) / RTIMER_CLOCK_TICK_RATIO));

  /* Restore system clock to the 32 MHz XOSC */
  select_32_mhz_xosc();

  /* Restore PMCTL to PM0 for next pass */
  REG(SYS_CTRL_PMCTL) = SYS_CTRL_PMCTL_PM0;

  /* Remember IRQ energest for next pass */
  ENERGEST_IRQ_SAVE(irq_energest);

  ENERGEST_ON(ENERGEST_TYPE_CPU);
  ENERGEST_OFF(ENERGEST_TYPE_LPM);
}
Пример #2
0
/*
 * Routine to put is in PM0. We also need to do some housekeeping if the stats
 * or the energest module is enabled
 */
static void
enter_pm0(void)
{
  ENERGEST_OFF(ENERGEST_TYPE_CPU);
  ENERGEST_ON(ENERGEST_TYPE_LPM);

  /* We are only interested in IRQ energest while idle or in LPM */
  ENERGEST_IRQ_RESTORE(irq_energest);

  /*
   * After PM0 we don't need to adjust the system clock. Thus, saving the time
   * we enter Deep Sleep is only required if we are keeping stats.
   */
  if(LPM_CONF_STATS) {
    sleep_enter_time = RTIMER_NOW();
  }

  assert_wfi();

  /* We reach here when the interrupt context that woke us up has returned */
  LPM_STATS_ADD(0, RTIMER_NOW() - sleep_enter_time);

  /* Remember IRQ energest for next pass */
  ENERGEST_IRQ_SAVE(irq_energest);

  ENERGEST_ON(ENERGEST_TYPE_CPU);
  ENERGEST_OFF(ENERGEST_TYPE_LPM);
}
Пример #3
0
Файл: lpm.c Проект: 1uk3/contiki
/*---------------------------------------------------------------------------*/
void
lpm_exit()
{
  if((REG(SYS_CTRL_PMCTL) & SYS_CTRL_PMCTL_PM3) == SYS_CTRL_PMCTL_PM0) {
    /* We either just exited PM0 or we were not sleeping in the first place.
     * We don't need to do anything clever */
    return;
  }

  /*
   * When returning from PM1/2, the sleep timer value (used by RTIMER_NOW()) is
   * not up-to-date until a positive edge on the 32-kHz clock has been detected
   * after the system clock restarted. To ensure an updated value is read, wait
   * for a positive transition on the 32-kHz clock by polling the
   * SYS_CTRL_CLOCK_STA.SYNC_32K bit, before reading the sleep timer value.
   */
  while(REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_SYNC_32K);
  while(!(REG(SYS_CTRL_CLOCK_STA) & SYS_CTRL_CLOCK_STA_SYNC_32K));

  LPM_STATS_ADD(REG(SYS_CTRL_PMCTL) & SYS_CTRL_PMCTL_PM3,
                RTIMER_NOW() - sleep_enter_time);

  /* Adjust the system clock, since it was not counting while we were sleeping
   * We need to convert sleep duration from rtimer ticks to clock ticks and
   * this will cost us some accuracy */
  clock_adjust((clock_time_t)
               ((RTIMER_NOW() - sleep_enter_time) / RTIMER_CLOCK_TICK_RATIO));

  /* Restore system clock to the 32 MHz XOSC */
  select_32_mhz_xosc();

  /* Restore PMCTL to PM0 for next pass */
  REG(SYS_CTRL_PMCTL) = SYS_CTRL_PMCTL_PM0;

  /* Remember IRQ energest for next pass */
  ENERGEST_IRQ_SAVE(irq_energest);

  ENERGEST_ON(ENERGEST_TYPE_CPU);
  ENERGEST_OFF(ENERGEST_TYPE_LPM);
}
Пример #4
0
/*
 * Routine to put is in PM0. We also need to do some housekeeping if the stats
 * or the energest module is enabled
 */
static void
enter_pm0(void)
{
  ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);

  /* We are only interested in IRQ energest while idle or in LPM */
  ENERGEST_IRQ_RESTORE(irq_energest);

  /* Remember the current time so we can keep stats when we wake up */
  if(LPM_CONF_STATS) {
    sleep_enter_time = RTIMER_NOW();
  }

  assert_wfi();

  /* We reach here when the interrupt context that woke us up has returned */
  LPM_STATS_ADD(0, RTIMER_NOW() - sleep_enter_time);

  /* Remember IRQ energest for next pass */
  ENERGEST_IRQ_SAVE(irq_energest);

  ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
}