fast PWM clock source with imx8mp

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

fast PWM clock source with imx8mp

588 Views
OrenP
Contributor I

Hello,

I am trying to use the imx8mp's cortex M to create a PWM output for working with the ws2812b LEDs.

The LEDs require a faster clock source than the default, and after checking the clock source possibilities I've found that setting:

pwmConfig.clockSource = kPWM_HighFrequencyClock;

works for the required rates.

I encountered an issue with this clock source that the interrupt no longer triggers when the reload triggers (this is taken from the driver_examples/pwm project).

To be more precise, the interrupt triggers twice at the beginning, then never again, and at the two times that it does, it's not at the expected points where the counter period is complete.

to reproduce this, just take the example and set 

pwmConfig.clockSource = kPWM_HighFrequencyClock;

right after getting the default configuration in the main function.

Labels (1)
0 Kudos
Reply
4 Replies

530 Views
OrenP
Contributor I

The attempt results in the exact same scenario. 
Is there another modification I need to do in order to make this work? or is it just not possible?

0 Kudos
Reply

487 Views
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hi

Here are snippets which has been tested by internal team on M4. You can use it as a reference.

  1. Init and configure PWM4.
    PWM_GetDefaultConfig(&pwmConfig);
    pwmConfig.clockSource = kPWM_PeripheralClock; // Using 24MHz as clock source

    /* Initialize PWM module */
    PWM_Init(DEMO_PWM_BASEADDR, &pwmConfig);

    /* Enable FIFO empty interrupt */
    PWM_EnableInterrupts(DEMO_PWM_BASEADDR, kPWM_FIFOEmptyInterruptEnable);
  2. Init filling samples
    PWM_SetSampleValue(DEMO_PWM_BASEADDR, LED_0_SAMPLE); // LED_0_SAMPLE = 9
    PWM_SetSampleValue(DEMO_PWM_BASEADDR, LED_1_SAMPLE); // LED_1_SAMPLE = 18
    PWM_SetSampleValue(DEMO_PWM_BASEADDR, LED_0_SAMPLE);
    pwm_pr_cnt += 3;
    /* Write the period to the PWM Period Register */
    PWM_SetPeriodValue(DEMO_PWM_BASEADDR, PWM_PERIOD_VALUE); // PWM_PERIOD_VALUE = 28
  3. Filling samples in irq
    /* Gets interrupt kPWM_FIFOEmptyFlag */
    if (PWM_GetStatusFlags(DEMO_PWM_BASEADDR) & kPWM_FIFOEmptyFlag)
    {
        if (pwm_pr_cnt > PWM_PERIOD + RESET_PERIOD) // PWM_PERIOD = 12 *24, RESET_PERIOD = 64
        {
            pwm_pr_cnt = 0;
            PWM_SetSampleValue(DEMO_PWM_BASEADDR, LED_0_SAMPLE);
        }
        else if (pwm_pr_cnt > PWM_PERIOD)
        {
            /* Reset period */
            PWM_SetSampleValue(DEMO_PWM_BASEADDR, 0);
        }
        else
        {
            /* PWM period */
            uint32_t sample_val = (pwm_pr_cnt & 1) ? LED_1_SAMPLE : LED_0_SAMPLE;
            PWM_SetSampleValue(DEMO_PWM_BASEADDR, sample_val);
        }
        pwm_pr_cnt++;
        /* Clear kPWM_FIFOEmptyFlag */
        PWM_clearStatusFlags(DEMO_PWM_BASEADDR, kPWM_FIFOEmptyFlag);
    }
    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
    exception return operation might vector to incorrect interrupt */
    #if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
    #endif



Best Regards
Zhiming

0 Kudos
Reply

528 Views
OrenP
Contributor I

attached is the output, where yellow is the expected PWM output, and the purple is toggled every time the interrupt is triggered (it does not happen again after the 2 toggles that are shown in the picture, and the PWM continues indefinitely without any changes)

WhatsApp Image 2024-07-25 at 13.38.07.jpeg

0 Kudos
Reply

563 Views
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hi
The interrupt process is not suitable for the HighFrequencyClock scenario, you can try kPWM_PeripheralClock using 24MHz as clock source.

Best Regards
Zhiming

0 Kudos
Reply