Exemple #1
0
void lp_ticker_set_interrupt(timestamp_t timestamp)
{
    uint64_t timestamp_ticks;
    uint64_t current_ticks = RTC_CounterGet();
    timestamp_t current_time = ((uint64_t)(current_ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT));


    /* calculate offset value */
    timestamp_t offset = timestamp - current_time;
    if(offset > 0xEFFFFFFF) offset = 100;

    /* map offset to RTC value */
    // ticks = offset * RTC frequency div 1000000
    timestamp_ticks = ((uint64_t)offset * (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)) / 1000000;
    timestamp_ticks += current_ticks;

    /* RTC has 24 bit resolution */
    timestamp_ticks &= 0xFFFFFF;

    /* check for RTC limitation */
    if((timestamp_ticks - RTC_CounterGet()) >= 0x800000) timestamp_ticks = RTC_CounterGet() + 2;

    /* Set callback */
    RTC_FreezeEnable(true);
    RTC_CompareSet(0, (uint32_t)timestamp_ticks);
    RTC_IntEnable(RTC_IF_COMP0);
    RTC_FreezeEnable(false);
}
/******************************************************************************
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  /* Initialize chip */
  CHIP_Init();
  
  /* Enable code view */
  setupSWO();

  /* Initialize LCD */
  SegmentLCD_Init(false);

  /* Enable the HFPER clock */
  CMU_ClockEnable(cmuClock_HFPER, true);

  /* Configure RTC and GPIO */
  rtc_setup();
  gpio_setup();

  /* Stay in this loop forever */
  while (1)
  {
    /* Wait for Push Button 1 to be pressed */
    while (GPIO_PinInGet(PB0_PORT, PB0_PIN)) ;
    /* and released, so that we do not exit the while loop below immediately */
    while (!GPIO_PinInGet(PB0_PORT, PB0_PIN)) ;

    /* Reset time */
    time = 0;

    /* Disable LCD */
    LCD_Enable(true);

    /* Update time until Push Button 1 is pressed again */
    while (1)
    {
      if (RTC_CounterGet() == 0)
      {
        SegmentLCD_Number(++time);
      }

      if (!GPIO_PinInGet(PB0_PORT, PB0_PIN))
        break;
    }

    /* Delay while showing the result on the LCD */
    for (uint32_t delay = 0; delay < 30; delay++)
    {
      /* Wait for the RTC to overflow once */
      while (RTC_CounterGet() != 0) ;
      while (RTC_CounterGet() == 0) ;
    }

    /* Disable LCD */
    LCD_Enable(false);
  }
}
void os_idle_demon(void)
{
  RTC_Init_TypeDef init;
  unsigned int sleep;

  /* The idle demon is a system thread, running when no other thread is      */
  /* ready to run.                                                           */

  /* Enable system clock for RTC */

  /* LFXO setup */
  /* Use 70% boost */
  CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | CMU_CTRL_LFXOBOOST_70PCENT;

  /* Ensure LE modules are accessible */
  CMU_ClockEnable(cmuClock_CORELE, true);

  /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);

  /* Use a 32 division prescaler to reduce power consumption. */
  CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32);

  /* Enable clock to RTC module */
  CMU_ClockEnable(cmuClock_RTC, true);

  init.enable   = false;
  init.debugRun = false;
  init.comp0Top = false; /* Count to max value before wrapping */

  RTC_Init(&init);

  /* Disable interrupt generation from RTC0 */
  RTC_IntDisable(_RTC_IF_MASK);

  /* Enable interrupts */
  NVIC_ClearPendingIRQ(RTC_IRQn);
  NVIC_EnableIRQ(RTC_IRQn);

  for (;;)
  {
    /* os_suspend stops scheduler and returns time to next event in OS_TICK units */
    sleep = os_suspend();
    if (sleep)
    {
      RTC_CompareSet(0, sleep - 1);
      RTC_IntClear(RTC_IFC_COMP0);
      RTC_IntEnable(RTC_IF_COMP0);
      RTC_CounterReset();
      /* Enter EM2 low power mode - could be replaced with EM1 if required */
      EMU_EnterEM2(true);
      /* get information how long we were in sleep */
      sleep = RTC_CounterGet();
      RTC_Enable(false);
    };
    /* resume scheduler providing information how long MCU was sleeping */
    os_resume(sleep);
  }
}
Exemple #4
0
timestamp_t lp_ticker_read()
{
    uint64_t ticks_temp;
    uint64_t ticks = RTC_CounterGet();

    /* ticks = counter tick value
     * timestamp = value in microseconds
     * timestamp = ticks * 1.000.000 / RTC frequency
     */

    ticks_temp = (ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT);
    return (timestamp_t) (ticks_temp & 0xFFFFFFFF);
}
Exemple #5
0
/******************************************************************//**
* @brief
*	Configure RTC device
*
* @details
*
* @note
*
* @param[in] dev
*	Pointer to device descriptor
*
* @param[in] cmd
*	RTC control command
*
* @param[in] args
*	Arguments
*
* @return
*	Error code
*********************************************************************/
static rt_err_t rt_rtc_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
    RT_ASSERT(dev != RT_NULL);

    switch (cmd)
    {
    case RT_DEVICE_CTRL_RTC_GET_TIME:
        *(rt_uint32_t *)args = rtc_time + RTC_CounterGet();
        break;

    case RT_DEVICE_CTRL_RTC_SET_TIME:
    {
        rtc_time = *(rt_uint32_t *)args;

		/* Reset counter */
		RTC_Enable(false);
		RTC_Enable(true);
    }
    break;
    }

    return RT_EOK;
}
Exemple #6
0
timestamp_t lp_ticker_read()
{
    return (timestamp_t) RTC_CounterGet();
}
/**************************************************************************//**
 * @brief vPortSuppressTicksAndSleep
 * Override the default definition of vPortSuppressTicksAndSleep() that is weakly
 * defined in the FreeRTOS Cortex-M3 port layer layer
 *****************************************************************************/
void vPortSuppressTicksAndSleep(portTickType xExpectedIdleTime)
{
  unsigned long ulReloadValue, ulCompleteTickPeriods;
  unsigned int ulRemainingCounter;

  portTickType  xModifiableIdleTime;
  /* Make sure the SysTick reload value does not overflow the counter. */
  if (xExpectedIdleTime > xMaximumPossibleSuppressedTicks)
  {
    xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
  }

  /* Calculate the reload value required to wait xExpectedIdleTime
   * tick periods.
  */
  ulReloadValue = (ulTimerReloadValueForOneTick * (xExpectedIdleTime ));
  if (ulReloadValue > ulStoppedTimerCompensation)
  {
    ulReloadValue -= ulStoppedTimerCompensation;
  }

  /* Stop the System Tick momentarily.  The time the System Tick is stopped for
   * is accounted for as best it can be, but using the tickless mode will
   * inevitably result in some tiny drift of the time maintained by the
   * kernel with respect to calendar time. */

  /* Stop the RTC clock*/
  RTC_Enable(false);
/* Enter a critical section but don't use the taskENTER_CRITICAL()
 * method as that will mask interrupts that should exit sleep mode. */
  INT_Disable();

  /* The tick flag is set to false before sleeping.  If it is true when sleep
   * mode is exited then sleep mode was probably exited because the tick was
   * suppressed for the entire xExpectedIdleTime period. */
  intTickFlag = false;
  /* If a context switch is pending or a task is waiting for the scheduler
   * to be unsuspended then abandon the low power entry. */
  if (eTaskConfirmSleepModeStatus() == eAbortSleep)
  {
    RTC_Enable(true);
    /* Re-enable interrupts - see comments above __disable_interrupt()
     * call above. */
    INT_Enable();
  }
  else
  {
    /* Set the new reload value. */
    ulReloadValue -= RTC_CounterGet();
    RTC_CompareSet(0, ulReloadValue);
    /* Restart the counter*/
    RTC_CounterReset();
    /* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can
     * set its parameter to 0 to indicate that its implementation contains
     * its own wait for interrupt or wait for event instruction, and so wfi
     * should not be executed again.  However, the original expected idle
     * time variable must remain unmodified, so a copy is taken. */
    xModifiableIdleTime = xExpectedIdleTime;
    configPRE_SLEEP_PROCESSING(xModifiableIdleTime);
    if (xModifiableIdleTime > 0)
    {
      SLEEP_Sleep();
      __DSB();
      __ISB();
    }
    configPOST_SLEEP_PROCESSING(xExpectedIdleTime);
    /* Stop SysTick.  Again, the time the SysTick is stopped for is
     * accounted for as best it can be, but using the tickless mode will
     * inevitably result in some tiny drift of the time maintained by the
     * kernel with respect to calendar time. */

    /* Store current counter value */
    ulRemainingCounter = RTC_CounterGet();
    /* Stop the RTC clock*/
    RTC_Enable(false);
    /* Re-enable interrupts */
    INT_Enable();
    if (intTickFlag != false)
    {
      /* The tick interrupt has already executed,
       * Reset the alarm value with whatever remains of this tick period. */
      RTC_CompareSet(0, TIMER_CAPACITY & (ulTimerReloadValueForOneTick - RTC_CounterGet()));

      /* The tick interrupt handler will already have pended the tick
       * processing in the kernel.  As the pending tick will be
       * processed as soon as this function exits, the tick value
       * maintained by the tick is stepped forward by one less than the
       * time spent waiting. */
      ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
    }
    else
    {
      /* Some other interrupt than system tick ended the sleep.
       * Calculate how many tick periods passed while the processor
       * was waiting */
      ulCompleteTickPeriods = ulRemainingCounter / ulTimerReloadValueForOneTick;

      /* The reload value is set to whatever fraction of a single tick
       * period remains. */
      if (ulCompleteTickPeriods == 0)
      {
        ulReloadValue = ulTimerReloadValueForOneTick - ulRemainingCounter;
      }
      else
      {
        ulReloadValue = ulRemainingCounter - (ulCompleteTickPeriods * ulTimerReloadValueForOneTick);
      }
      RTC_CompareSet(0, ulReloadValue);
    }
    /* Restart the RTCounter */
    RTC_CounterReset();
    /* The tick forward by the number of tick periods that
     * remained in a low power state. */
    vTaskStepTick(ulCompleteTickPeriods);
  }
}
Exemple #8
0
uint32_t rtt_get_counter(void)
{
    return RTC_CounterGet();
}
/***************************************************************************//**
* @brief Get value of RTC counter register in miliseconds
 ******************************************************************************/
uint32_t RTC_CounterGetMs(void)
{
	return (RTC_CounterGet() * 1000) / RTC_FREQ;
}
Exemple #10
0
/*---------------------------------------------------------------------------*/
uint32_t rtc_getvalue(void)
{
	return RTC_CounterGet();
}
Exemple #11
0
/*---------------------------------------------------------------------------*/
rtimer_clock_t rtimer_arch_now(void)
{
	return RTC_CounterGet();
}