QN9080DK PWM getting stuck

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

QN9080DK PWM getting stuck

906 Views
andrew_clifford
Contributor II

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;
}
else
{
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!

Thanks,

Andrew

0 Kudos
3 Replies

762 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Andrew,

 

Sorry for the late reply.

 

By any chance, did you check the sctimer_update_dutycycle SDK example?

The process to update the duty cycle is the following:

 

-Disable SCTIMER interrupts.

-Update PWM with SCTIMER_UpdatePwmDutycycle function.

-Delay

-Enable SCTIMER interrupts.

 

I hope this helps.

 

Best regards,

Felipe

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

762 Views
andrew_clifford
Contributor II

Hi Felipe, Thank you your response, I'm sorry i didn't come back sooner, I completely missed the notification of your response!

I will try what you suggest and see how it goes!

Thanks,

Andrew

0 Kudos

762 Views
andrew_clifford
Contributor II

I forgot to say, if required I can upload the enitre project.

0 Kudos