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!