Reply
Posts: 37
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: 549
Registered: ‎09-18-2015

Re: the first PWM pulse cannot be generated

Source code, please? Smiley Sad

Posts: 37
Registered: ‎11-17-2016

Re: the first PWM pulse cannot be generated

@JohnB 

My main configuration of timer has uploaded.

 

thank you.

Posts: 549
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: 37
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: 2,310
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: 37
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: 2,310
Registered: ‎10-14-2014

Re: the first PWM pulse cannot be generated

[ Edited ]

Ok, I got what you mean now.

 

WeiguoLu
Posts: 37
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: 4
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: 3,092
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: 2
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: 37
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: 3,092
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.

Posts: 26
Registered: ‎01-24-2017

Re: the first PWM pulse cannot be generated

hey,

I'm trying to generate 2 pwm on the same TIMER.
I can generate 2 PWM but there're some problems:

- rising edges are synchronous

- the two PWM have the same frequency

 

I can have different t_on for each signal but the first i configure takes the frequency of the second.

I would like to have totally independent PWMs on the same timer. Is it possible or do i need to use 2 different timers?

have a nice day Robot Happy

Raphael

Posts: 549
Registered: ‎09-18-2015

Re: the first PWM pulse cannot be generated

Hi @flying_whale,

 

You need two timers Smiley Sad

 

The typical way to generate a PWM on EFM32 is to set the TOP register to get the desired waveform period and to set the compare register (CCV/CCVB) to get your duty cycle. Since there is only one TOP register per timer, your period for all compare registers will be the same.

 

John

Posts: 26
Registered: ‎01-24-2017

Re: the first PWM pulse cannot be generated

thanks for your fast reply Robot Happy

the problem is i need 4 independent PWM Robot Sad

So the only way to achieve it would be to use soft timers?
if i use the gecko_cmd_hardware_set_soft_timer, toggling pins in the callback should allow me to do so?
Or generating 4 independent PWM in unreachable on the BGM121?

Posts: 549
Registered: ‎09-18-2015

Re: the first PWM pulse cannot be generated

Hi @flying_whale,

 

You'll need to ask your question regarding the soft timers in the Bluetooth forum.  The LETIMER might be an option, but only if you've got a low frequency waveform you can run on it since your clock source will be the LFXO, LFRCO, or ULFRCO.

 

I was trying to see if there was a way to do this with the configurable logic functionality in the PRS that allows you to AND and OR channels together. I was thinking there might be a way to use the two other compare channels associated with a timer to set a period and a duty cycle so long as the period is less than or equal to the period of the waveform running on that channel.

 

Ultimately, I can't seem to work around the fact that you still really just need an independent time base (counter) for that fourth channel, and there's not a fourth counter to be had on the chip that you can clock from the HFPERCLK.

 

John

Posts: 2
Registered: ‎03-11-2017

Re: the first PWM pulse cannot be generated


flying_whale wrote:


So the only way to achieve it would be to use soft timers?
if i use the gecko_cmd_hardware_set_soft_timer, toggling pins in the callback should allow me to do so?


Soft timers in the BLE stack have minimum period of 10ms so they can't be used for any practical PWM signal generation.

Posts: 26
Registered: ‎01-24-2017

Re: the first PWM pulse cannot be generated

i thought the soft_timers were using the 32k oscillator, so it would make a 30µs period, it is the smaller period I need for my PWM (I need t_on between 30µs and 1ms) but maybe i have to add the "wake-up" time and the data-processing time. 
So yeah, as you say it's not practical Robot Sad

Anyway, thanks for your replies guys, i will find a way to solve my problem Robot wink

Have a very nice day Robot wink

Rapha

Posts: 549
Registered: ‎09-18-2015

Re: the first PWM pulse cannot be generated

Hi @flying_whale,

 

You could manage part of the 30 µs to 1 ms range with the LETIMER.

 

Assuming you use the LFXO as the LFACLK, your clock tick will be around 30 µs. So, while you wouldn't be able to manage a 30 µs period with the LETIMER, 1 ms is possible (around 32 counts).

 

John