Reply
Posts: 2
Registered: ‎03-13-2017

EZR32LG Gecko Frequency Measurement

 Hi,

 

I'm testing a frequency measurement code with a push button on the gecko EZR32LG demo board.

I want to capture the input frequency with the timer capture function and print te frequency to my UART serial port with printf.

 

What is going wrong in the code, who can find it and help me?

 

#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "em_gpio.h"
#include "em_device.h"
#include "em_chip.h"
#include "retargetserial.h"
#include "em_pcnt.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_system.h"
#include "em_timer.h"
#include "em_prs.h"


/* TOP reset value is 0xFFFF so it doesn't need
   to be written for this example */
#define TOP 0xFFFF

/* 13761 Hz -> 14Mhz (clock frequency) / 1024 (prescaler) */
#define TIMER_FREQ 13671

//Gecko demo board button PB0
 #define PB0_PORT gpioPortE
 #define PB0_PIN 3
 #define PB0_PRS_SIGSEL_PIN PRS_CH_CTRL_SIGSEL_GPIOPIN3

/* Use a siprintf which don't support floating point formatting for code sourcery */
#if defined(__ICCARM__) || defined (__CC_ARM) || defined (__CROSSWORKS_ARM)
  #define SPRINTF                  sprintf
#else
  #define SPRINTF                  siprintf
#endif

int count = 0, totalTime;
char totalTimeString[7], overFlowString[8];
/**************************************************************************//**
 * @brief TIMER0_IRQHandler
 * Interrupt Service Routine TIMER0 Interrupt Line
 *****************************************************************************/
void TIMER0_IRQHandler(void)
{
  uint16_t intFlags = TIMER_IntGet(TIMER0);

  TIMER_IntClear(TIMER0, TIMER_IF_OF | TIMER_IF_CC0);

  /* Overflow interrupt occured */
  if(intFlags & TIMER_IF_OF)
  {
    /* Increment the counter with TOP = 0xFFFF */
    count += TOP;

    /* Write overflow number */
    SPRINTF(overFlowString, "OVRFLW%d", count / TOP);
    printf(overFlowString);
  }

  /* Capture interrupt occured */
  if(intFlags & TIMER_IF_CC0)
  {
    /* Calculate total time of button pressing */
    totalTime = count + TIMER_CaptureGet(TIMER0, 0);
    /* Multiply by 1000 to avoid floats */
    totalTime = (totalTime * 1000) / TIMER_FREQ;

    /* Write time in seconds on the LCD */
	SPRINTF(totalTimeString, "%d.%.3d", totalTime/1000, totalTime%1000);
    printf(totalTimeString);

    /* Clear counter */
    count = 0;
   }
}

/**************************************************************************//**
 * @brief  Main function
 * Main is called from __iar_program_start, see assembly startup file
 *****************************************************************************/
int main(void)
{
  /* Initialize chip */
  CHIP_Init();

  /* Initialize LEUART/USART and map LF to CRLF */
  RETARGET_SerialInit();
  RETARGET_SerialCrLf(1);

  printf("\nEZR32 UART Timer Capture Demo\n");

  /* Enable clock for GPIO module */
  CMU_ClockEnable(cmuClock_GPIO, true);

  /* Enable clock for TIMER0 module */
  CMU_ClockEnable(cmuClock_TIMER0, true);

  /* Enable clock for PRS module */
  CMU_ClockEnable(cmuClock_PRS, true);

  /* Configure PB0_PIN as an input for PB0 button with filter and pull-up (dout = 1)*/
  GPIO_PinModeSet(PB0_PORT, PB0_PIN, gpioModeInputPullFilter, 1);

  /* Select PB0_PIN as external interrupt source*/
  GPIO_IntConfig(PB0_PORT, PB0_PIN, false, false, false);

  /* Enable PRS sense on GPIO and disable interrupt sense */
  GPIO_InputSenseSet(GPIO_INSENSE_PRS, _GPIO_INSENSE_RESETVALUE);

  /* Select GPIO as source and PB0_PRS_SIGSEL_PIN as signal for PRS channel 0 */
  PRS_SourceSignalSet(0, PRS_CH_CTRL_SOURCESEL_GPIOH, PB0_PRS_SIGSEL_PIN, prsEdgeOff);

  /* Select CC channel parameters */
  TIMER_InitCC_TypeDef timerCCInit =
  {
    .eventCtrl  = timerEventEveryEdge,
    .edge       = timerEdgeRising,
    .prsSel     = timerPRSSELCh0,
    .cufoa      = timerOutputActionNone,
    .cofoa      = timerOutputActionNone,
    .cmoa       = timerOutputActionNone,
    .mode       = timerCCModeCapture,
    .filter     = true,
    .prsInput   = true,
    .coist      = false,
    .outInvert  = false,
  };

  /* Configure CC channel 0 */
  TIMER_InitCC(TIMER0, 0, &timerCCInit);

  /* Select timer parameters */
  TIMER_Init_TypeDef timerInit =
  {
    .enable     = false,
    .debugRun   = true,
    .prescale   = timerPrescale1024,
    .clkSel     = timerClkSelHFPerClk,
    .fallAction = timerInputActionReloadStart,
    .riseAction = timerInputActionStop,
    .mode       = timerModeUp,
    .dmaClrAct  = false,
    .quadModeX4 = false,
    .oneShot    = false,
    .sync       = false,
  };

  /* Enable overflow and CC0 interrupt */
  TIMER_IntEnable(TIMER0, TIMER_IF_OF | TIMER_IF_CC0);

  /* Enable TIMER0 interrupt vector in NVIC */
  NVIC_EnableIRQ(TIMER0_IRQn);

  /* Configure timer */
  TIMER_Init(TIMER0, &timerInit);

  while(1)
  {
    /* Go to EM1 */
    EMU_EnterEM1();
  }

}

 

Posts: 2,968
Registered: ‎02-07-2002

Re: EZR32LG Gecko Frequency Measurement

Using printf statements in an ISR is a very bad thing. Just set a flag and do the printing in the main loop.