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));

    /* Initialize RTC */
    lp_ticker_init();

    /* 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);
}
Exemple #2
0
void rtcSetup(){
	RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;

	/* Enabling clock to LE configuration register */
	CMU_ClockEnable(cmuClock_CORELE, true);

	/* Selecting crystal oscillator to drive LF clock */
	CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);

	/* 32 clock division to save energy */
	CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32768);

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

	/* Initialize RTC */
	rtcInit.enable   = false;  /* Do not start RTC after initialization is complete. */
	rtcInit.debugRun = false;  /* Halt RTC when debugging. */
	rtcInit.comp0Top = true;   /* Wrap around on COMP0 match. */
	RTC_Init(&rtcInit);

	/* Interrupt every minute */
	RTC_CompareSet(0, ((RTC_FREQ / CLOCK_DIVISION) * 10 ) - 1 );

	/* Enable interrupt */
	NVIC_EnableIRQ(RTC_IRQn);
	RTC_IntEnable(RTC_IEN_COMP0);

	/* Start Counter */
	RTC_Enable(true);

}
/**************************************************************************//**
 * @brief RTC_IRQHandler
 * Interrupt Service Routine for RTC which is used as system tick counter in EM2
 *****************************************************************************/
void RTC_IRQHandler(void)
{
  /* If using preemption, also force a context switch. */
#if (configUSE_PREEMPTION == 1)
  port_NVIC_INT_CTRL_REG = port_NVIC_PENDSVSET_BIT;
#endif /* (configUSE_PREEMPTION == 1) */
  /* Set RTC interrupt to one system tick period*/
  RTC_Enable(false);
  RTC_CompareSet(0, ulTimerReloadValueForOneTick);
  /* Restart the counter */
#if (configUSE_TICKLESS_IDLE == 1)
  /* Set flag that interrupt was made*/
  intTickFlag = true;
#endif /* (configUSE_TICKLESS_IDLE == 1) */

  /* Critical section which protect incrementing the tick*/
  ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
  {
    xTaskIncrementTick();
  }
  portCLEAR_INTERRUPT_MASK_FROM_ISR(0);
  /* Clear interrupt */
  RTC_IntClear(_RTC_IFC_MASK);
  RTC_CounterReset();
}
Exemple #4
0
/***************************************************************************//**
 * @brief RTC trigger enable
 * @param msec Enable trigger in msec
 * @param cb Callback invoked when @p msec elapsed
 ******************************************************************************/
void RTCDRV_Trigger(uint32_t msec, void (*cb)(void))
{
  /* Disable RTC - this will also reset the counter. */
  RTC_Enable(false);

  /* Auto init if not configured already */
  if (!rtcInitialized)
  {
    /* Default to LFRCO as clock source and prescale by 32. */
    RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32);
  }

  /* Register callback */
  rtcCb = cb;

  /* Clear interrupt source */
  RTC_IntClear(RTC_IF_COMP0);

  /* Calculate trigger value in ticks based on 32768Hz clock */
  RTC_CompareSet(0, (rtcFreq * msec) / 1000);

  /* Enable RTC */
  RTC_Enable(true);

  /* Enable interrupt on COMP0 */
  RTC_IntEnable(RTC_IF_COMP0);
}
Exemple #5
0
/**************************************************************************//**
 * @brief Enables LFACLK and selects LFXO as clock source for RTC
 *        Sets up the RTC to generate an interrupt every minute.
 *****************************************************************************/
void rtcSetup(void)
{
  RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;

  /* Enable LE domain registers */
  CMU_ClockEnable(cmuClock_CORELE, true);

  /* Enable LFXO as LFACLK in CMU. This will also start LFXO */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);

  /* Set a clock divisor of 32 to reduce power conumption. */
  CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32);

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

  /* Initialize RTC */
  rtcInit.enable   = false;  /* Do not start RTC after initialization is complete. */
  rtcInit.debugRun = false;  /* Halt RTC when debugging. */
  rtcInit.comp0Top = true;   /* Wrap around on COMP0 match. */
  RTC_Init(&rtcInit);

  /* Interrupt every minute */
  RTC_CompareSet(0, ((RTC_FREQ / 32) * 60 ) - 1 );

  /* Enable interrupt */
  NVIC_EnableIRQ(RTC_IRQn);
  RTC_IntEnable(RTC_IEN_COMP0);

  /* Start Counter */
  RTC_Enable(true);
}
/**************************************************************************//**
 * @brief Enables LFACLK and selects LFXO as clock source for RTC
 *        Sets up the RTC to generate an interrupt every second.
 *****************************************************************************/
static void rtcSetup(unsigned int frequency)
{
  RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;

  palClockSetup(cmuClock_LFA);

  /* Set the prescaler. */
  CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_2 );
  
  /* Enable RTC clock */
  CMU_ClockEnable(cmuClock_RTC, true);

  /* Initialize RTC */
  rtcInit.enable   = false;  /* Do not start RTC after initialization is complete. */
  rtcInit.debugRun = false;  /* Halt RTC when debugging. */
  rtcInit.comp0Top = true;   /* Wrap around on COMP0 match. */

  RTC_Init(&rtcInit);

  /* Interrupt at given frequency. */
  RTC_CompareSet(0, ((CMU_ClockFreqGet(cmuClock_RTC) / frequency) - 1) & _RTC_COMP0_MASK );

#ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
  /* Enable interrupt */
  NVIC_EnableIRQ(RTC_IRQn);
  RTC_IntEnable(RTC_IEN_COMP0);
#endif
  RTC_CounterReset();
  /* Start Counter */
  RTC_Enable(true);
}
// Stores the hours/mins for clock time, start time, or stop time
void set_clock_time(int index, uint16_t hours, uint16_t minutes)
{
	// Set the time clock
	if (index == 0)
	{
		// Midnight is time zero
		RTC_CounterReset();
		// 3600 seconds per hour, 60 seconds per minute
		RTC->CNT = hours * 3600 + minutes * 60;
	}
	else if (index == 1)
	{
		// Add 1 second so that RTC interrupt source is clear,
		// and not to confuse with the clock minute updates
		time_keeper.timer_start_seconds = hours * 3600 + minutes * 60 + 1;

		// Set up the RTC to trigger a start event
		RTC_CompareSet(0, time_keeper.timer_start_seconds);

		// Save for next program event
		start_hours = hours;
		start_minutes = minutes;
	}
	else if (index == 2)
	{
		// Add 1 second so that RTC interrupt source is clear,
		// and not to confuse with the clock minute updates
		time_keeper.timer_stop_seconds = hours * 3600 + minutes * 60 + 1;

		// Save for next program event
		stop_hours = hours;
		stop_minutes = minutes;
	}
}
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);
  }
}
/**************************************************************************//**
 * @brief vPortSetupTimerInterrupt
 * Override the default definition of vPortSetupTimerInterrupt() that is weakly
 * defined in the FreeRTOS Cortex-M3, which set source of system tick interrupt
 *****************************************************************************/
void vPortSetupTimerInterrupt(void)
{
  /* Set our data about timer used as system ticks*/
  ulTimerReloadValueForOneTick = SYSTICK_LOAD_VALUE ;
  #if (configUSE_TICKLESS_IDLE == 1)
  xMaximumPossibleSuppressedTicks = TIMER_CAPACITY / (SYSTICK_LOAD_VALUE);
  ulStoppedTimerCompensation      = TIMER_COMPENSATION / (configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ);
#endif /* (configUSE_TICKLESS_IDLE == 1) */
  /* Configure RTC as system tick source */
  /* Structure of RTC init */
  RTC_Init_TypeDef init;
#if (configCRYSTAL_IN_EM2 == 1)
  /* LFXO setup */
  /* For cut D, use 70% boost */
  CMU->CTRL    = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | CMU_CTRL_LFXOBOOST_70PCENT;
  #if defined( EMU_AUXCTRL_REDLFXOBOOST )
  EMU->AUXCTRL = (EMU->AUXCTRL & ~_EMU_AUXCTRL_REDLFXOBOOST_MASK) | EMU_AUXCTRL_REDLFXOBOOST;
  #endif
#else
  /* RC oscillator */
  CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
#endif
  /* Ensure LE modules are accessible */
  CMU_ClockEnable(cmuClock_CORELE, true);
#if (configCRYSTAL_IN_EM2 == 1)
  /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
#else
  /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
#endif
  /* Set 2 times divider to reduce energy*/
  CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_2);

  /* 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 */
  /* Initialization of RTC */
  RTC_Init(&init);

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

  /* Tick interrupt MUST execute at the lowest interrupt priority. */
  NVIC_SetPriority(RTC_IRQn, 255);

  /* Enable interrupts */
  NVIC_ClearPendingIRQ(RTC_IRQn);
  NVIC_EnableIRQ(RTC_IRQn);
  RTC_CompareSet(0, SYSTICK_LOAD_VALUE);
  RTC_IntClear(RTC_IFC_COMP0);
  RTC_IntEnable(RTC_IF_COMP0);
  RTC_Enable(true);
  //RTC_CounterReset();
}
Exemple #10
0
void lp_ticker_set_interrupt(timestamp_t timestamp)
{
    RTC_IntDisable(RTC_IF_COMP0);
    RTC_IntClear(RTC_IF_COMP0);
    RTC_FreezeEnable(true);
    RTC_CompareSet(0, (uint32_t) (timestamp & RTC_MAX_VALUE));
    RTC_FreezeEnable(false);
    RTC_IntEnable(RTC_IF_COMP0);
}
/**************************************************************************//**
 * @brief Initialize Real Time Counter
 *****************************************************************************/
void initRTC()
{
  /* Starting LFXO and waiting until it is stable */
  CMU_OscillatorEnable(cmuOsc_LFXO, true, true);

  /* Routing the LFXO clock to the RTC */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
  CMU_ClockEnable(cmuClock_RTC, true);

  /* Enabling clock to the interface of the low energy modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

  const RTC_Init_TypeDef rtcInit =
  {
    .enable   = true,
    .debugRun = false,
    .comp0Top = true,
  };

  RTC_Init(&rtcInit);

  /* Set comapre value for compare register 0 */
  RTC_CompareSet(0, RTC_COUNT_BETWEEN_WAKEUP);

  /* Enable interrupt for compare register 0 */
  RTC_IntEnable(RTC_IFC_COMP0);

  /* Enabling Interrupt from RTC */
  NVIC_EnableIRQ(RTC_IRQn);

  RTC_Enable(false);
}

/**************************************************************************//**
 * @brief Initialize General Purpuse Input/Output
 *****************************************************************************/
void initGPIO()
{
  /* Enable clock for GPIO module */
  CMU_ClockEnable(cmuClock_GPIO, true);

  /* Configure pin PB9/PD8 (Push Button 1) and PB10/PB11 (Push Button 2) as an input,
   * so that we can read their values. */
  GPIO_PinModeSet(PB0_PORT, PB0_PIN, gpioModeInput, 1);
  GPIO_PinModeSet(PB1_PORT, PB1_PIN, gpioModeInput, 1);

  /* Enable GPIO_ODD and GPIO_EVEN interrupts in NVIC */
  NVIC_EnableIRQ(GPIO_ODD_IRQn);
  NVIC_EnableIRQ(GPIO_EVEN_IRQn);

  /* Configure interrupts on falling edge for pins B9/D8 (Push Button 1),
   * B10/B11 (Push Button 2) and D3 */
  GPIO_IntConfig(PB0_PORT, PB0_PIN, true, true, true);
  GPIO_IntConfig(PB1_PORT, PB1_PIN, true, true, true);
}
Exemple #12
0
/*---------------------------------------------------------------------------*/
void
rtimer_arch_schedule(rtimer_clock_t t)
{
  // Program Alarm
  RTC_IntClear(RTC_IF_COMP0);

  // Enable Alarm 0 preventing overflow !!!
  RTC_CompareSet(0, (t & 0xFFFFFF));
  PRINTF("Now %u, comp0 = %u\r\n", rtimer_arch_now(), t);

  RTC_IntEnable(RTC_IF_COMP0);
}
Exemple #13
0
/**************************************************************************//**
 * @brief Enables LFACLK and selects LFXO as clock source for RTC
 *        Sets up the RTC to generate an interrupt every second.
 *****************************************************************************/
static void rtcSetup(unsigned int frequency)
{
  RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;

  /* Enable LE domain registers */
  if ( !( CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE) )
  {
    CMU_ClockEnable(cmuClock_CORELE, true);
  }

#ifdef PAL_RTC_CLOCK_LFXO
  /* LFA with LFXO setup is relatively time consuming. Therefore, check if it
     already enabled before calling. */
  if ( !(CMU->STATUS & CMU_STATUS_LFXOENS) )
  {
    CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
  }
  if ( cmuSelect_LFXO != CMU_ClockSelectGet(cmuClock_LFA) )
  {
    CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
  }
#elif defined PAL_RTC_CLOCK_LFRCO
  /* Enable LFACLK in CMU (will also enable LFRCO oscillator if not enabled) */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
#elif defined PAL_RTC_CLOCK_ULFRCO
  /* Enable LFACLK in CMU (will also enable ULFRCO oscillator if not enabled) */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_ULFRCO);
#else
#error No clock source for RTC defined.
#endif

  /* Set the prescaler. */
  CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_1 );

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

  /* Initialize RTC */
  rtcInit.enable   = false;  /* Do not start RTC after initialization is complete. */
  rtcInit.debugRun = false;  /* Halt RTC when debugging. */
  rtcInit.comp0Top = true;   /* Wrap around on COMP0 match. */
  RTC_Init(&rtcInit);

  /* Interrupt at given frequency. */
  RTC_CompareSet(0, (CMU_ClockFreqGet(cmuClock_RTC) / frequency) - 1 );

  /* Enable interrupt */
  NVIC_EnableIRQ(RTC_IRQn);
  RTC_IntEnable(RTC_IEN_COMP0);

  /* Start Counter */
  RTC_Enable(true);
}
/******************************************************************************
 * @brief   Configure RTC
 *
 *****************************************************************************/
void rtcSetup(void)
{
  RTC_Init_TypeDef rtcInit;

  /* Select LFXO as clock source for the RTC */
  CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
  CMU_ClockEnable(cmuClock_RTC, true);
  
  /* Set RTC pre-scaler */
  CMU_ClockDivSet(cmuClock_RTC,cmuClkDiv_1);
   
  /* Enable clock to low energy modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

  /* RTC configuration struct */
  rtcInit.debugRun  = false;
  rtcInit.comp0Top  = false;
  rtcInit.enable    = false;

  /* Initialize RTC */
  RTC_Init(&rtcInit);

  /* Set RTC compare value for first display update */
  RTC_CompareSet(0, RTC_COUNTS_BETWEEN_DISPLAY );
  
  /* Set RTC compare value for first temperature compensation */
  RTC_CompareSet(1, RTC_COUNTS_BETWEEN_TC );

  /* Enable COMP0 interrupt to trigger display update, */
  /*        COMP1 interrupt to trigger temperature compensation, and */
  /*        OF interrupt to keep track of counter overflows */
  RTC_IntEnable(RTC_IEN_COMP0 | RTC_IEN_COMP1 | RTC_IEN_OF );
  
  /* Enable RTC interrupts */
  NVIC_ClearPendingIRQ(RTC_IRQn);
  NVIC_EnableIRQ(RTC_IRQn);

  /* Enable RTC */
  RTC_Enable(true);
}
Exemple #15
0
/**************************************************************************//**
 * @brief  Delay function, does not depend on interrupts.
 *****************************************************************************/
static void Delay( uint32_t msec )
{
/* RTC frequency is LFXO divided by 32 (prescaler) */
#define RTC_FREQ (32768 / 32)

  RTC_IntDisable( RTC_IF_COMP0 );
  RTC_IntClear( RTC_IF_COMP0 );
  RTC_CompareSet( 0, (RTC_FREQ * msec ) / 1000 ); /* Calculate trigger value */

  RTC_Enable( true );
  while ( !( RTC_IntGet() & RTC_IF_COMP0 ) );     /* Wait for trigger */
  RTC_Enable( false );
}
/***************************************************************************//**
 * @brief RTC Interrupt Handler
 *
 ******************************************************************************/
void RTC_IRQHandler(void)
{
  /* Interrupt source: compare match 0 */
  /*   Increment compare value and update TFT display */
  if ( RTC_IntGet() & RTC_IF_COMP0 )
  {
    RTC_CompareSet(0,RTC->COMP0 + RTC_COUNTS_BETWEEN_DISPLAY);
    RTC_IntClear(RTC_IFC_COMP0);

    /* Set flag for display update */
    doDisplayUpdate = true;
  }


  /* Interrupt source: compare match 1 */
  /*   Increment compare value and compensate for temperature drift */
  if ( RTC_IntGet() & RTC_IF_COMP1 )
  {
    RTC_CompareSet(1,RTC->COMP1 + RTC_COUNTS_BETWEEN_TC);
    RTC_IntClear(RTC_IFC_COMP1);
  
    /* Set flag for temperature compensation */
    doTemperatureCompensation = true;
  }


  /* Interrupt source: counter overflow */
  /*   Increase overflow counter and update display */
  if ( RTC_IntGet() & RTC_IF_OF )
  {
    clockOverflow( );
    RTC_IntClear(RTC_IFC_OF);

    /* Set flag for display update */
    doDisplayUpdate = true;
  }

}
error_t hw_timer_schedule(hwtimer_id_t timer_id, hwtimer_tick_t tick )
{
	if(timer_id >= HWTIMER_NUM)
		return ESIZE;
	if(!timer_inited)
		return EOFF;

	start_atomic();
	   RTC_IntDisable(RTC_IEN_COMP1);
	   RTC_CompareSet( 1, tick );
	   RTC_IntClear(RTC_IEN_COMP1);
	   RTC_IntEnable(RTC_IEN_COMP1);
	end_atomic();
}
Exemple #18
0
void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
{
    rtt_state.alarm_cb = cb;
    rtt_state.alarm_arg = arg;

    /* disable interrupt so it doesn't accidentally trigger */
    RTC_IntDisable(RTC_IEN_COMP0);

    /* set compare register */
    RTC_CompareSet(0, alarm & RTT_MAX_VALUE);

    /* enable the interrupt */
    RTC_IntClear(RTC_IFC_COMP0);
    RTC_IntEnable(RTC_IEN_COMP0);
}
/**************************************************************************//**
 * @brief PCNT0_IRQHandler
 * Interrupt Service Routine for PCNT0 Interrupt Line
 *****************************************************************************/
void PCNT0_IRQHandler(void)
{
  PCNT_IntGet(PCNT0);
  PCNT_IntClear(PCNT0, PCNT_IEN_DIRCNG);

  /* Enable clock for LCD. */
  CMU_ClockEnable(cmuClock_LCD, true);
  /* Wait until SYNCBUSY_CTRL flag is cleared. */
  LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL);
  /* Enable LCD. */
  LCD_Enable(true);
  /* Write PCNT counter number the LCD */
  SegmentLCD_Write(PCNT_DIRCHANGE_STRING);

  /* Disable RTC first to reset counter */
  RTC_Enable(false);
  /* Set compare value */
  RTC_CompareSet(0, RTC_COMP_VALUE);
  /* Enable RTC */
  RTC_Enable(true);
}
/**************************************************************************//**
 * @brief Enables LFACLK and selects LFXO as clock source for RTC.
 *        Sets up the RTC to count at 1024 Hz.
 *        The counter should not be cleared on a compare match and keep running.
 *        Interrupts should be cleared and enabled.
 *        The counter should run.
 *****************************************************************************/
error_t hw_timer_init(hwtimer_id_t timer_id, uint8_t frequency, timer_callback_t compare_callback, timer_callback_t overflow_callback)
{
    if(timer_id >= HWTIMER_NUM)
    	return ESIZE;
    if(timer_inited)
    	return EALREADY;
    if(frequency != HWTIMER_FREQ_1MS && frequency != HWTIMER_FREQ_32K)
    	return EINVAL;
	
    start_atomic();
		compare_f = compare_callback;
		overflow_f = overflow_callback;
		timer_inited = true;

		/* Configuring clocks in the Clock Management Unit (CMU) */
		startLfxoForRtc(frequency);

		RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;
		rtcInit.enable   = false;   /* Don't enable RTC after init has run */
		rtcInit.comp0Top = true;   /* Clear counter on compare 0 match: cmp 0 is used to limit the value of the rtc to 0xffff */
		rtcInit.debugRun = false;   /* Counter shall not keep running during debug halt. */


		/* Initialize the RTC */
		RTC_Init(&rtcInit);

		//disable all rtc interrupts while we're still configuring
		RTC_IntDisable(RTC_IEN_OF | RTC_IEN_COMP0 | RTC_IEN_COMP1);
		RTC_IntClear(RTC_IFC_OF | RTC_IFC_COMP0 | RTC_IFC_COMP1);
		//Set maximum value for the RTC
		RTC_CompareSet( 0, 0x0000FFFF );
		RTC_CounterReset();

		RTC_IntEnable(RTC_IEN_COMP0);

		NVIC_EnableIRQ(RTC_IRQn);
		RTC_Enable(true);
    end_atomic();
    return SUCCESS;
}
Exemple #21
0
void portInitClock(void)
{

#define LFO_FREQUENCY              32768

#if PORTCFG_RTC_LFXO != 0
  /* Starting LFRCO and waiting until it is stable */
  CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
  /* Routing the LFRCO clock to the RTC */
  CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
#else
  /* Starting LFRCO and waiting until it is stable */
  CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
  /* Routing the LFRCO clock to the RTC */
  CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFRCO);
#endif

  CMU_ClockEnable(cmuClock_RTC, true);

  /* Enabling clock to the interface of the low energy modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

  RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;

  rtcInit.enable   = true;      /* Enable RTC after init has run */
  rtcInit.comp0Top = true;      /* Clear counter on compare match */
  rtcInit.debugRun = false;     /* Counter shall keep running during debug halt. */

  /* Setting the compare value of the RTC */
  RTC_CompareSet(0, (LFO_FREQUENCY / HZ) - 1);

  /* Enabling Interrupt from RTC */
  RTC_IntEnable(RTC_IFC_COMP0);
  NVIC_EnableIRQ(RTC_IRQn);
  NVIC_SetPriority(RTC_IRQn, PORT_SYSTICK_PRI);

  /* Initialize the RTC */
  RTC_Init(&rtcInit);

}
Exemple #22
0
void rtcSetDelay(int menuItem){
	int delay;
	switch (menuItem)
	{
		case 0:
			delay = 10;
			break;
		case 1:
			delay = 3600 * 12;
			break;
		case 2:
			delay = 3600 * 24;
			break;
		case 3:
			delay = 3600 * 48;
			break;
	}
	/* Interrupt every minute */
	RTC_CompareSet(0, ((RTC_FREQ / CLOCK_DIVISION) * delay ) - 1 );

	/* Start Counter */
	RTC_Enable(true);
}
Exemple #23
0
/********************************************//**
 * \brief configure RTC to run from 32K external crystal
 * configure RTC divider to count seconds
 * \param
 * \param
 * \return
 *
 ***********************************************/
void initClock(void)
{
    // set RTC to generate interrupts every second time and date will be maintained by software
    /* Starting LFXO and waiting until it is stable */
    CMU_OscillatorEnable(cmuOsc_LFXO, true, true);

    /* Routing the LFXO clock to the RTC */
    CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
    CMU_ClockEnable(cmuClock_RTC, true);
    /* Enabling clock to the interface of the low energy modules */
    CMU_ClockEnable(cmuClock_CORELE, true);

    /* Setting up RTC */
    /* Prescaler of 15 = 1 s of resolution and overflow each 194 days */
    CMU_ClockDivSet(cmuClock_RTC,cmuClkDiv_32768);
    RTC_CompareSet(0, RTC_COUNT_BETWEEN_WAKEUP);
    RTC_IntEnable(RTC_IFC_COMP0);

    /* Enabling Interrupt from RTC */
    NVIC_EnableIRQ(RTC_IRQn);

    RTC_Init_TypeDef rtcInit = RTC_INIT_DEFAULT;
    RTC_Init(&rtcInit);
}
/***************************************************************************//**
 * @brief RTC trigger enable
 * @param msec Enable trigger in msec
 * @param cb Callback invoked when @p msec elapsed
 ******************************************************************************/
void RTC_Trigger(uint32_t msec, void (*cb)(void))
{
  /* Auto init if not configured already */
  if (!rtcInitialized)
  {
    /* Default to LFRCO as clock source */
    RTC_Setup(cmuSelect_LFRCO);
  }

  /* Register callback */
  rtcCb = cb;

  /* Clear interrupt source */
  RTC_IntClear(RTC_IF_COMP0);

  /* Calculate trigger value in ticks based on 32768Hz clock */
  RTC_CompareSet(0, (rtcFreq * msec) / 1000);

  /* Enable RTC */
  RTC_Enable(true);

  /* Enable interrupt on COMP0 */
  RTC_IntEnable(RTC_IF_COMP0);
}
/**************************************************************************//**
 * @brief RTC Setup
 * Produce an interrupt every second
 *****************************************************************************/
void rtc_setup(void)
{
  /* Starting LFXO and waiting until it is stable */
  CMU_OscillatorEnable(cmuOsc_LFXO, true, true);

  /* Routing the LFXO clock to the RTC */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
  CMU_ClockEnable(cmuClock_RTC, true);

  /* Enabling clock to the interface of the low energy modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

  const RTC_Init_TypeDef rtcInit =
  {
    .enable   = true,
    .debugRun = false,
    .comp0Top = true,
  };

  RTC_Init(&rtcInit);

  /* Produce interrupt every second */
  RTC_CompareSet(0, 32768);

  /* Enable interrupt for compare register 0 */
  RTC_IntEnable(RTC_IFC_COMP0);

  /* Enabling interrupt from RTC */
  NVIC_EnableIRQ(RTC_IRQn);
}

/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  /* Initialize chip */
  CHIP_Init();
  
  /* Enable code view */
  setupSWO();

  /* Configure peripherals */
  rtc_setup();

  BSP_LedsInit();

  while (1)
  {
    switch (STATE)
    {
    case EM0:
      break;
    case EM1:
      EMU_EnterEM1();
      break;
    case EM2:
      EMU_EnterEM2(true);
      break;
    }
  }
}
/**************************************************************************//**
 * @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 #27
0
/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void)
{
  unsigned char pucMACArray[8];
  uint32_t      temp;

  /* Chip revision alignment and errata fixes */
  CHIP_Init();

  /* Ensure core frequency has been updated */
  SystemCoreClockUpdate();
  CMU_ClockEnable(cmuClock_ADC0, true);

  /* Setup SysTick Timer for 1 msec interrupts  */
  if (SysTick_Config(SystemCoreClock / 1000)) while (1) ;

  /* Setup ADC for sampling internal temperature sensor. */
  setupSensor();

  /* Spi init*/
  spiInit();


#if LWIP_DHCP
  /* Initialze the lwIP library, using DHCP.*/
  lwIPInit(pucMACArray, 0, 0, 0, IPADDR_USE_DHCP);
#else
  /* Initialze the lwIP library, using Static IP.*/
  lwIPInit(pucMACArray, IPADDR(192, 168, 79, 160), IPADDR(255, 255, 255, 0), \
           IPADDR(192, 168, 79, 1), IPADDR_USE_STATIC);
#endif

  /* Initialize a sample httpd server.*/
  httpd_init();

  /* Start one ADC sample */
  ADC_Start(ADC0, adcStartSingle);

  /* Enable board control interrupts */
  gpioSetup();

  axspi_write_reg(~IMR_RXPKT, P0_IMR);

  /* Start LCD  without boost */
  SegmentLCD_Init(false);

  CMU_ClockEnable(cmuClock_RTC, true);
  /* RTC configuration structure */
  RTC_Init_TypeDef rtcInit = {
    .enable   = false,
    .debugRun = false,
    .comp0Top = true
  };

  /* Initialize RTC */
  RTC_Init(&rtcInit);

  /* Set COMP0 value which will be the top value as well */
  RTC_CompareSet(RTC_COMP, RTC_COMP_VALUE);

  /* Clear all pending interrupts */
  RTC_IntClear(0x7);

  /* Enable COMP0 interrupts */
  RTC_IntEnable(0x2);

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

  RTC_Enable(true);

  while (1)
  {
    /* check temperature flag*/
    if (read_temperature)
    {
      temp = ADC_DataSingleGet(ADC0);

      /* Show Celsius on numeric part of display */
      temperature = (int)(convertToCelsius(temp));

      /* Start a new conversion */
      ADC_Start(ADC0, adcStartSingle);

      /* Reset temperature flag */
      read_temperature = 0;
    }

    if (updateIpFlag)
    {
      switch (ip_field)
      {
      case 1:
      {
        SegmentLCD_Write(IP_ADDR_FIRST_TEXT);
        SegmentLCD_Number(IP_ADDR_FIRST_NUM(lwip_netif.ip_addr.addr));
        ip_field++;
      }
      break;

      case 2:
      {
        SegmentLCD_Write(IP_ADDR_SECOND_TEXT);
        SegmentLCD_Number(IP_ADDR_SECOND_NUM(lwip_netif.ip_addr.addr));
        ip_field++;
      }
      break;

      case 3:
      {
        SegmentLCD_Write(IP_ADDR_THIRD_TEXT);
        SegmentLCD_Number(IP_ADDR_THIRD_NUM(lwip_netif.ip_addr.addr));
        ip_field++;
      }
      break;

      case 4:
      {
        SegmentLCD_Write(IP_ADDR_FOURTH_TEXT);
        SegmentLCD_Number(IP_ADDR_FOURTH_NUM(lwip_netif.ip_addr.addr));
        ip_field = 1;
      }
      break;

      default: break;
      }

      updateIpFlag = false;
    }
  }
}
/**************************************************************************//**
 * @brief Configure RTC
 *****************************************************************************/
void rtc_setup(void)
{
  CMU_ClockEnable(cmuClock_RTC, true);

  /* Enabling clock to the interface of the low energy modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

  const RTC_Init_TypeDef rtcInit =
  {
    .enable   = true,
    .debugRun = false,
    .comp0Top = true,
  };

  RTC_Init(&rtcInit);

  /* Set overflow every 0.1 seconds */
  RTC_CompareSet(0, 3276);
}

/**************************************************************************//**
 * @brief SWO Setup
 * Enables code view in energyAware Profiler
 *****************************************************************************/
void setupSWO(void)
{
  uint32_t *dwt_ctrl = (uint32_t *) 0xE0001000;
  uint32_t *tpiu_prescaler = (uint32_t *) 0xE0040010;
  uint32_t *tpiu_protocol = (uint32_t *) 0xE00400F0;

  CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
  /* Enable Serial wire output pin */
  GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
#if defined(_EFM32_GIANT_FAMILY)
  /* Set location 0 */
  GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC0;

  /* Enable output on pin - GPIO Port F, Pin 2 */
  GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
  GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
#else
  /* Set location 1 */
  GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
  /* Enable output on pin */
  GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
  GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
#endif
  /* Enable debug clock AUXHFRCO */
  CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;

  while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));

  /* Enable trace in core debug */
  CoreDebug->DHCSR |= 1;
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;

  /* Enable PC and IRQ sampling output */
  *dwt_ctrl = 0x400113FF;
  /* Set TPIU prescaler to 16. */
  *tpiu_prescaler = 0xf;
  /* Set protocol to NRZ */
  *tpiu_protocol = 2;
  /* Unlock ITM and output data */
  ITM->LAR = 0xC5ACCE55;
  ITM->TCR = 0x10009;
}
const hwtimer_info_t* hw_timer_get_info(hwtimer_id_t timer_id)
{
    if(timer_id >= HWTIMER_NUM)
      return NULL;

    static const hwtimer_info_t timer_info = {
      .min_delay_ticks = 0,
    };

    return &timer_info;
}

hwtimer_tick_t hw_timer_getvalue(hwtimer_id_t timer_id)
{
	if(timer_id >= HWTIMER_NUM || (!timer_inited))
		return 0;
	else
	{
		uint32_t value =(uint16_t)(RTC->CNT & 0xFFFF);
		return value;
	}
}

error_t hw_timer_schedule(hwtimer_id_t timer_id, hwtimer_tick_t tick )
{
	if(timer_id >= HWTIMER_NUM)
		return ESIZE;
	if(!timer_inited)
		return EOFF;

	start_atomic();
	   RTC_IntDisable(RTC_IEN_COMP1);
	   RTC_CompareSet( 1, tick );
	   RTC_IntClear(RTC_IEN_COMP1);
	   RTC_IntEnable(RTC_IEN_COMP1);
	end_atomic();
}

error_t hw_timer_cancel(hwtimer_id_t timer_id)
{
	if(timer_id >= HWTIMER_NUM)
		return ESIZE;
	if(!timer_inited)
		return EOFF;

	start_atomic();
	   RTC_IntDisable(RTC_IEN_COMP1);
	   RTC_IntClear(RTC_IEN_COMP1);
	end_atomic();
}

error_t hw_timer_counter_reset(hwtimer_id_t timer_id)
{
	if(timer_id >= HWTIMER_NUM)
		return ESIZE;
	if(!timer_inited)
		return EOFF;

	start_atomic();
		RTC_IntDisable(RTC_IEN_COMP0 | RTC_IEN_COMP1);
		RTC_IntClear(RTC_IEN_COMP0 | RTC_IEN_COMP1);
		RTC_CounterReset();
		RTC_IntEnable(RTC_IEN_COMP0);
	end_atomic();

}

bool hw_timer_is_overflow_pending(hwtimer_id_t timer_id)
{
    if(timer_id >= HWTIMER_NUM)
	return false;
    start_atomic();
	//COMP0 is used to limit thc RTC to 16 bits -> use this one to check
	bool is_pending = !!((RTC_IntGet() & RTC->IEN) & RTC_IFS_COMP0);
    end_atomic();
    return is_pending;	
}
bool hw_timer_is_interrupt_pending(hwtimer_id_t timer_id)
{
    if(timer_id >= HWTIMER_NUM)
	return false;

    start_atomic();
	bool is_pending = !!((RTC_IntGet() & RTC->IEN) & RTC_IFS_COMP1);
    end_atomic();
    return is_pending;	
}



INT_HANDLER(RTC_IRQHandler)
{
	//retrieve flags. We 'OR' this with the enabled interrupts
	//since the COMP1 flag may be set if it wasn't used before (compare register == 0 -> ifs flag set regardless of whether interrupt is enabled)
	//by AND ing with the IEN we make sure we only consider the flags of the ENABLED interrupts
	uint32_t flags = (RTC_IntGet() & RTC->IEN);
	RTC_IntClear(RTC_IFC_OF | RTC_IFC_COMP0 | RTC_IFC_COMP1);

	//evaluate flags to see which one(s) fired:
	if((flags & RTC_IFS_COMP0) && (overflow_f != 0x0))
		overflow_f();
	if((flags & RTC_IFS_COMP1))
	{
		RTC_IntDisable(RTC_IEN_COMP1);
		if(compare_f != 0x0)
			compare_f();
	}
}
/**************************************************************************//**
 * @brief Initialize Real Time Counter
 *****************************************************************************/
void initRTC()
{
  /* Starting LFXO and waiting until it is stable */
  CMU_OscillatorEnable(cmuOsc_LFXO, true, true);

  /* Routing the LFXO clock to the RTC */
  CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
  CMU_ClockEnable(cmuClock_RTC, true);

  /* Enabling clock to the interface of the low energy modules */
  CMU_ClockEnable(cmuClock_CORELE, true);

  const RTC_Init_TypeDef rtcInit =
  {
    .enable   = true,
    .debugRun = false,
    .comp0Top = true,
  };

  RTC_Init(&rtcInit);

  /* Set comapre value for compare register 0 */
  RTC_CompareSet(0, RTC_COUNT_BETWEEN_WAKEUP);

  /* Enable interrupt for compare register 0 */
  RTC_IntEnable(RTC_IFC_COMP0);

  /* Enabling Interrupt from RTC */
  NVIC_EnableIRQ(RTC_IRQn);
}

/**************************************************************************//**
 * @brief Initialize General Purpuse Input/Output
 *****************************************************************************/
void initGPIO()
{
  /* Enable clock for GPIO module */
  CMU_ClockEnable(cmuClock_GPIO, true);

  /* Configure pin PD8/PB9 (Push Button 0) and PB11/PB10 (Push Button 1) as an input,
   * so that we can read their values. */
  GPIO_PinModeSet(PB0_PORT, PB0_PIN, gpioModeInput, 1);
  GPIO_PinModeSet(PB1_PORT, PB1_PIN, gpioModeInput, 1);

  /* Configure pin PD3 as an input. Unlike Push Button 0 and 1 this pin
   * does not have a pull down associated with it. We therefore need to set the
   * mode to InputPull, in order to set a default value of 1 with PinOutSet(). */
  GPIO_PinModeSet(gpioPortD, 3, gpioModeInputPull, 1);
  GPIO_PinOutSet(gpioPortD, 3);

  /* Configure PC0 as a push pull for LED drive */
  GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0);

  /* Enable GPIO_ODD and GPIO_EVEN interrupts in NVIC */
  NVIC_EnableIRQ(GPIO_ODD_IRQn);
  NVIC_EnableIRQ(GPIO_EVEN_IRQn);
  NVIC_EnableIRQ(PendSV_IRQn);

  /* Set priorities - 0 is the highest, 7 is the lowest */
#if defined(_EFM32_GIANT_FAMILY)
  NVIC_SetPriority(GPIO_ODD_IRQn, 2);
  NVIC_SetPriority(GPIO_EVEN_IRQn, 1);
#else
  NVIC_SetPriority(GPIO_EVEN_IRQn, 2);
  NVIC_SetPriority(GPIO_ODD_IRQn, 1);
#endif
  NVIC_SetPriority(RTC_IRQn, 0);
  NVIC_SetPriority(PendSV_IRQn, 3);

  /* Configure interrupts on falling edge for pins D8/B9 (Push Button 0),
   * B11/B10 (Push Button 1) and D3 */
  GPIO_IntConfig(PB0_PORT, PB0_PIN, false, true, true);
  GPIO_IntConfig(PB1_PORT, PB1_PIN, false, true, true);
  GPIO_IntConfig(gpioPortD, 3, false, true, true);
}