Thursday, January 3, 2019

How to generate PWM on EFR32

The following codes show you how to generate PWM on Silicon Labs EFR32 when button is pressed. In this example, I will use BRD4151A radio board with mainboard BRD4001A to output 1KHz PMW on PC10 pin

#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "em_timer.h"

/* Use 1 kHz for PWM frequency */
#define PWM_FREQ 1000

void emberAfHalButtonIsrCallback(uint8_t button, uint8_t state)
{
  uint32_t topValue;
       
  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_TIMER0, true);
  /* set CC0 location 15 pin (PC10) as output, initially high */
  GPIO_PinModeSet (gpioPortC, 10, gpioModePushPull, 1);
 
  /* select CC channel parameters */
  TIMER_InitCC_TypeDef timerCCInit =
  {
    .eventCtrl  = timerEventEveryEdge,
    .edge       = timerEdgeBoth,
    .prsSel     = timerPRSSELCh0,
    .cufoa      = timerOutputActionNone,
    .cofoa      = timerOutputActionNone,
    .cmoa       = timerOutputActionToggle,
    .mode       = timerCCModePWM,
    .filter     = false,
    .prsInput   = false,
    .coist      = true,
    .outInvert  = false,
  };
 
  /* configure CC channel 0 */
  TIMER_InitCC (TIMER0, 0, &timerCCInit);

  /* route CC0 to location 15 (PC10) and enable pin */
  TIMER0->ROUTELOC0 |= TIMER_ROUTELOC0_CC0LOC_LOC15;
  TIMER0->ROUTEPEN |= TIMER_ROUTEPEN_CC0PEN;

  /* set PWM period */
  topValue = CMU_ClockFreqGet (cmuClock_HFPER) / PWM_FREQ;
  TIMER_TopSet (TIMER0, topValue);

  /* Set PWM duty cycle to 50% */
  TIMER_CompareSet (TIMER0, 0, topValue >> 1);

  /* set timer parameters */
  TIMER_Init_TypeDef timerInit =
  {
    .enable     = true,
    .debugRun   = true,
    .prescale   = timerPrescale1,
    .clkSel     = timerClkSelHFPerClk,
    .fallAction = timerInputActionNone,
    .riseAction = timerInputActionNone,
    .mode       = timerModeUp,
    .dmaClrAct  = false,
    .quadModeX4 = false,
    .oneShot    = false,
    .sync       = false,
  };

  /* configure and start timer */
  TIMER_Init (TIMER0, &timerInit); 
}





p.s. Here, we set route CC0 to location 15 (PC10) according to Table 6.6  Alternate Functionality Overview in efr32mg1 datasheet.


1 comment:

  1. Hi, i am trying to run this code on 500Hz but its not working.
    Could u recommend to do something?

    ReplyDelete