Reply
Highlighted
Posts: 8
Registered: ‎03-25-2017
Accepted Solution

EFR32MG1 TIMER1->CNT help

[ Edited ]

Hi There,

 

Will warn you I'm a noob. Working through the maker's guide for the IoT but with EFR32MG1 Mighty Gecko. Having issues with TIMER1->CNT.

 

If I set the TIMER_Init_TypeDef timerInit.prescale to timerPrescale1024. And set the TIMER_TopSet for TIMER1 as (HFPER_clock/1024) I can see that the TIMER1_QRQHandler method is being called every second (LED is flashing on/off every second). My issue is with a function get_time_in_ms() which should return the current passage of time. When I call the method delay_ms(1000), it gets stuck in the while loop because the get_time_in_ms() function is not working correctly. Debugging I have realized that the TIMER1->CNT is not going above ~ 17. This doesn't make sense to me as the TIMER1_QRQHandler method is correctly being called at every count of 13672 defined by the TIMER_TopSet. Now if i change the prescale to timerPrescale1, I can see that the TIMER1->CNT will now get up to ~ 14000 before resetting. I guess my question is, what's going on? What is the relationship between TIMER1->CNT and the TIMER_TopSet. From code below, shouldn't TIMER1->CNT be 13672 the instance the TIMER1_QRQHandler method is called when overflow is hit? Thanks in advance for any help/advice.

 

#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_emu.h"
#include "em_rmu.h"
#include "em_timer.h"
#include <stdio.h>

#define LED_PORT  gpioPortD
#define LED_PIN   14

#define DEBUG_BREAK                                   __asm__("BKPT #0");
#define ONE_MILLISECOND_BASE_VALUE_COUNT             1000
#define ONE_SECOND_TIMER_COUNT                        13672
#define MILLISECOND_DIVISOR                           13.672

volatile uint64_t base_value = 0;
volatile bool timer1_overflow = false;
volatile bool light_on = false;

void TIMER1_IRQHandler(void)
{
      timer1_overflow = true;
      base_value += ONE_MILLISECOND_BASE_VALUE_COUNT;
      TIMER_IntClear(TIMER1, TIMER_IF_OF);

      light_on = !light_on;

	  if (light_on==true)
	  {
		GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0);
	  }
	  else
	  {
		GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 1);
	  }
}

uint64_t get_time_in_ms()
{
      // Clear our overflow indicator
      timer1_overflow = false;

      // Get the current count
      uint16_t count = TIMER1->CNT;

      // Get a copy of the base value
      uint64_t copy_of_base_value = base_value;

      // Now check to make sure that the ISR didn't fire while in here
      // If it did, then grab the values again
      if (timer1_overflow)
      {
            count = TIMER1->CNT;
            copy_of_base_value = base_value;
      }

      // Put a DEBUG_BREAK here to check the count. The contents of 
      // count doesn't get larger than 17. Needs to be less than 17 for this 
      // for the DEBUG_BREAK to be actioned.
      if (count > 17)
      {
  	  DEBUG_BREAK;
      }

      // Now calculate the number of milliseconds the program has run
      return copy_of_base_value + count / MILLISECOND_DIVISOR;
}

void delay_ms(uint64_t milliseconds)
{
      uint64_t trigger_time = get_time_in_ms() + milliseconds;
      while (get_time_in_ms() < trigger_time)
//Logic is getting stuck in this while loop because
//get_time_in_ms() is not working correctly ; } int main(void) { CHIP_Init(); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_TIMER1, true); // Create a timerInit object, based on the API default TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; timerInit.prescale = timerPrescale1024; TIMER_IntEnable(TIMER1, TIMER_IF_OF); // Enable TIMER0 interrupt vector in NVIC NVIC_EnableIRQ(TIMER1_IRQn); TIMER_Init(TIMER1, &timerInit); // Set TIMER Top value TIMER_TopSet(TIMER1, ONE_SECOND_TIMER_COUNT); // Wait for the timer to get going while (TIMER1->CNT == 0) ; while (1) {
//Logic get's stuck here delay_ms(1000); GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 1); delay_ms(1000); GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0); } }

Drew

 

Posts: 8
Registered: ‎03-25-2017

Re: EFR32MG1 TIMER1->CNT help

Above code works fine. Was debuggin for hours and couldn't figure out why CNT wasn't working. Don't know what I changed or what was wrong but counter works as expected using the above implementation. Apologies for post.