AnsweredAssumed Answered

QN9080DK PWM getting stuck

Question asked by Andrew Clifford on Feb 24, 2019
Latest reply on Apr 22, 2019 by Andrew Clifford

Firstly, apologies if this is in the wrong section. I could work out which seciton QN9080 questions should be in (Kinetis/Automotive/LPC/Wireless?)!


I am using the QN9080Dk development board and have been trying to set up a PWM with both varying frequency and period. I am trying to flash the LEDs on the board with the PWM, with a fixed on-time of 10 ms, but a frequency that varies with the angle measured from the on-board accelerometer (MMA8652). This is updated at 10 Hz.


I have tried several ways of doing this, but in every case (if I can get it to work at all), it works for a few seconds and then seems to "lock" either on or off. Whether the LED is left on or off seems random, but it doesn't recover.


All the parts I am using have come from the QN9080DK SDK. The program I working with is the lpc_i2c_read_accel_value_transfer demo project, with GPIO parts taken from gpio_led_output and  the timer parts from simple_pwm.


I was initially using the CTIMER_SetupPwm function, but I wasn't clear whether I had to stop and start the PWM to use this. Stopping and starting the PWM didn't help the problem, so I took the CTIMER_UpdatePwmDutycycle function, copied it and modified it to update the duty cycle AND the period. I called this function CTIMER_UpdatePwm and it is below:


static void CTIMER_UpdatePwm(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent, uint32_t pwmFreq_Hz, uint32_t srcClock_Hz)
uint32_t pulsePeriod = 0, period;
uint32_t timerClock = srcClock_Hz / (base->PR + 1);

/* Match channel 3 defines the PWM period */
period = base->MR[kCTIMER_Match_3];

/* Calculate PWM period match value */
period = (timerClock / pwmFreq_Hz) - 1;

/* Calculate pulse width match value */
pulsePeriod = (period * dutyCyclePercent) / 100;

/* For 0% dutycyle, make pulse period greater than period so the event will never occur */
if (dutyCyclePercent == 0)
pulsePeriod = period + 1;
pulsePeriod = (period * (100 - dutyCyclePercent)) / 100;

/* Update period */
base->MR[kCTIMER_Match_3] = period;
/* Update dutycycle */
base->MR[matchChannel] = pulsePeriod;

This works in the same way - i.e. it seems to work perfectly to start with and then freezes after a few seconds.

If I set the PWM going and don't try changing it, everything seems to work fine. It has been running on my desk for the last 45 minutes with no problem. Unfortunately I need it to change!


I assum I am doing something silly, but I can't find any information on the best way to update the PWM details on the fly and am tearing my hair out!