Reply
Posts: 27
Registered: ‎11-17-2016
Accepted Solution

the first PWM pulse cannot be generated

Every time the MCU starts to generate the PWM, the first PWM waveform can not always be output. In other words, after the PWM has been set successfully and the timer start to work , but no waveform is generated before the timer overflow. All subsequent performance is normal. Using the chip EFM32G880, in order to verify the problem, I have used the official evaluation board (EFM32G890 chip), and used the official case program, but I found that there will encounter such a problem too.

Posts: 256
Registered: ‎09-18-2015

Re: the first PWM pulse cannot be generated

Source code, please? Smiley Sad

Posts: 27
Registered: ‎11-17-2016

Re: the first PWM pulse cannot be generated

@JohnB 

My main configuration of timer has uploaded.

 

thank you.

Posts: 256
Registered: ‎09-18-2015

Re: the first PWM pulse cannot be generated

[ Edited ]

Hi damon,

 

Have you looked at our PWM example in AN0014?

 

You're using emlib functions elsewhere in your code, but opted to write registers directly for your PWM initialization, which seems kind of painful unless you are absolutely strapped for space (and even then, emlib is pretty efficient).

 

Here's the relevant example, for your reference:

 

#include "em_device.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "em_prs.h"
#include "em_system.h"
#include "em_timer.h"
#include "em_chip.h"

/* Define PWM frequency value */
#define PWM_FREQ 10000

/**************************************************************************//**
 * @brief TIMER0_IRQHandler
 * Interrupt Service Routine TIMER0 Interrupt Line
 *****************************************************************************/
void TIMER0_IRQHandler(void)
{ 
  uint32_t compareValue;
  
  /* Clear flag for TIMER0 overflow interrupt */
  TIMER_IntClear(TIMER0, TIMER_IF_OF);

  compareValue = TIMER_CaptureGet(TIMER0, 0);
  /* increment duty-cycle or reset if reached TOP value */
  if( compareValue == TIMER_TopGet(TIMER0))
    TIMER_CompareBufSet(TIMER0, 0, 0);
  else
    TIMER_CompareBufSet(TIMER0, 0, ++compareValue);
}

int main(void) { /* Initialize chip */ CHIP_Init(); /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Enable clock for TIMER0 module */ CMU_ClockEnable(cmuClock_TIMER0, true); /* Set CC0 location 3 pin (PD1) as output */ GPIO_PinModeSet(gpioPortD, 1, gpioModePushPull, 0); /* 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 = false, .outInvert = false, }; /* Configure CC channel 0 */ TIMER_InitCC(TIMER0, 0, &timerCCInit); /* Route CC0 to location 3 (PD1) and enable pin */ TIMER0->ROUTE |= (TIMER_ROUTE_CC0PEN | TIMER_ROUTE_LOCATION_LOC3); /* Set Top Value */ TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_HFPER)/PWM_FREQ); /* Set compare value starting at 0 - it will be incremented in the interrupt handler */ TIMER_CompareBufSet(TIMER0, 0, 0); /* Select timer parameters */ TIMER_Init_TypeDef timerInit = { .enable = true, .debugRun = true, .prescale = timerPrescale64, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; /* Enable overflow interrupt */ TIMER_IntEnable(TIMER0, TIMER_IF_OF); /* Enable TIMER0 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER0_IRQn); /* Configure timer */ TIMER_Init(TIMER0, &timerInit); while(1) { /* Go to EM1 */ EMU_EnterEM1(); } }
Posts: 27
Registered: ‎11-17-2016

Re: the first PWM pulse cannot be generated

@JohnB

 

Thanks for your working.

The problem is that the Timer cannot generate PWM at the first period(it can generated other PWM normally), and I monitor the vlaue of all related register,without finding the reason.

 

At first I operated the register directly,but encounter the problem,then I have used the PWM example in AN0014,but I find nearly all configuration is as same as mine project.I use the example in AN0014 to run at my board(efm32g880) and the Gecko Starter Kit(efm32g890),but the problem appeared again.

 

I have read your code, but while I have used it before without solving my problem.

 

Now, I have changed to letimer generating the PWM, If possible I hope you can check the timer generating PWM at first period.

 

thank you again.

 

Posts: 1,583
Registered: ‎10-14-2014

Re: the first PWM pulse cannot be generated

@damon

Could you try the attached code on our STK,

I see the PD1 (PWM output) toggle when the interrupt was entered. I made minor change based on AN0014.

 

 

WeiguoLu
Posts: 27
Registered: ‎11-17-2016

Re: the first PWM pulse cannot be generated

@delu

 

My meaning is that the pwm signal cannot be generated at the first time period.Like the pic below, the mcu cannot generate the PWM at this period using timer, but by experience, I can use letimer to generate the PWM at this period.

 

Posts: 1,583
Registered: ‎10-14-2014

Re: the first PWM pulse cannot be generated

[ Edited ]

Ok, I got what you mean now.

 

WeiguoLu
Posts: 27
Registered: ‎11-17-2016

Re: the first PWM pulse cannot be generated

@delu

 

But I want to know  if the timer of this MCU has such features that cannot generate PWM at first period.

Posts: 2
Registered: ‎03-10-2017

Re: the first PWM pulse cannot be generated

You' must be using emlib functions elsewhere in your code, but opted to write registers directly for your PWM initialization, which makes emlib pretty efficient

Thanks

Software Developer

Driver Whiz.

Highlighted
Posts: 2,728
Registered: ‎02-07-2002

Re: the first PWM pulse cannot be generated

I'm going to guess here how the PWM works. When the timer overflows it sets the output pin and resets the timer. When the compare value is reached it clears the output pin. Now consider what happens at startup. The timer is at 0, but it did not overflow to get there, and thus the pin is not set. At the compare value the pin is cleared, but it already was, so nothing happens. Now how to 'fix' this? Initialize the timer to its top value (or top-1) and let it overflow as soon as possible.

Posts: 1
Registered: ‎03-11-2017

Re: the first PWM pulse cannot be generated

I had the exact same problem and the solution was what @vanmierlo described above. If you start the timer from value 0 then the first overflow event does not happen until one full period.

Posts: 27
Registered: ‎11-17-2016

Re: the first PWM pulse cannot be generated

@vanmierlo

Thanks for your detail answer.

The cnt of timer can be write and read,but the cnt of letimer just can be read. now I know their cnt both count from 0 , but they work differently.

After reading your answer,If I want to generate the first PWM by timer,I also assume that I can reset cnt to 0 and use the IFS to set overflow interrupt flag at the beginning.

Thank you again.

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

Re: the first PWM pulse cannot be generated

LETIMER counts down, sets PWM at compare match and clears it at underflow. You cannot write LETIMER_CNT but you can clear it to 0. This would result in immediate underflow and thus does not skip the first period.

 

I'm not sure what you want to achieve by setting a flag in IFS. I would not assume it does anything else but set the flag and trigger the interrupt. But Figure 19.18. TIMER Up-count PWM Generation (EFM32 RefMan v1.10) seems to indicate the PWM is set not at overflow, but at the transition from 0 to 1. So starting with TIMER_CNT at 0 zero should set the PWM then.