Showing posts with label PWM. Show all posts
Showing posts with label PWM. Show all posts

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.