PWM on STM32C0xx and STM32F40xx not reaching potential period time

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
Engemil
Posts: 31
Joined: Thu Dec 19, 2024 12:50 am
Has thanked: 9 times
Been thanked: 7 times

PWM on STM32C0xx and STM32F40xx not reaching potential period time

Postby Engemil » Fri Aug 29, 2025 11:01 pm

Hi!

I've been experimenting this week with the PWM driver for both a Nucleo-C071RB board and a Nucleo-F401RE board.

I seem not to be able to reach periods of 1.25us (trying to build a simple ws2812 example).

ChibiOS: stable_21.11.x branch
Boards: NUCLEO-C071RB (48MHz clock) and NUCLEO-F401RE (84MHz clock)
Chips: STM32C071RB and STM32F401RE

Addtional Information:
- I have tested both boards with a simple STM32CubeIDE PWM example, and I can confirm it works by reaching 1.25us periods.
- I tested also with CH_DBG_ENABLE_ASSERTS enabled


Here is my example code

Code: Select all

#include "ch.h"
#include "hal.h"

// STM32C071RB Pin A6, AF1, TIM3_CH1, PWM3 channel 1 as 0 (0 ... 3)
#define APP_PWM_DRIVER        &PWMD3
#define APP_PWM_LINE          PAL_LINE(GPIOA, 6U)
#define APP_PWM_LINE_MODE     PAL_MODE_ALTERNATE(1)
#define APP_PWM_LINE_CHANNEL  0 // NB: Channel 0 is TIMx_CH1 (since channels are 0..3, even though in the docs they are 1..4)

static void pwmpcb(PWMDriver *pwmp) {
  (void)pwmp;
}

static void pwmc1cb(PWMDriver *pwmp) {
  (void)pwmp;
}

/* PWM configuration structure. */
static PWMConfig pwmcfg = {
    24000000, /* PWM timer clock in Hz (uint32_t) */ // Also tried 48000000, 8000000
    30, /* Initial PWM period in ticks (pwmcnt_t)*/ // Also tried 60, 10. Note: Works with 500 but period is too long
    pwmpcb, /* PWM Periodic callback pointer (pwmcallback_t) */
    {
        {PWM_OUTPUT_ACTIVE_HIGH, pwmc1cb}, /* CH1 mode and callback */
        {PWM_OUTPUT_DISABLED, NULL}, /* CH2 mode and callback */
        {PWM_OUTPUT_DISABLED, NULL}, /* CH3 mode and callback */
        {PWM_OUTPUT_DISABLED, NULL} /* CH4 mode and callback */
    }, /* Channels configurations (PWMChannelConfig)*/
    0, /* TIM CR2 (Control Register 2) register initialization data (uint32_t) */
    0, /* TIM BDTR (break & dead-time) register initialization data (uint32_t) */
    0 /* TIM DIER (DMA/Interrupt Enable Register) register initialization data (uint32_t) */
};

int main(void) {
    halInit();
    chSysInit();

    /* Initialize PIN for PWM */
    palSetLineMode(APP_PWM_LINE, APP_PWM_LINE_MODE);
   
    /* Start PWM Driver */
    pwmStart(APP_PWM_DRIVER, &pwmcfg);
    /* Enable PWM periodic notification */
    pwmEnablePeriodicNotification(APP_PWM_DRIVER);
   
    while (true) {
        /* Starts the PWM channel 1 and set duty cycle % (100% = 10000) */
        pwmEnableChannel(APP_PWM_DRIVER, APP_PWM_LINE_CHANNEL, PWM_PERCENTAGE_TO_WIDTH(APP_PWM_DRIVER, 5000));
        pwmEnableChannelNotification(APP_PWM_DRIVER, APP_PWM_LINE_CHANNEL);
        chThdSleepMilliseconds(200);

        /* Stops the PWM channel 0 */
        pwmDisableChannel(APP_PWM_DRIVER, APP_PWM_LINE_CHANNEL);
        chThdSleepMilliseconds(200);
    }
}



Any idea what might be causing it?

I read through some of the other posts related to the pwm driver, and am I "locked" to implement the PWM driver through DMA at such speed?

User avatar
Giovanni
Site Admin
Posts: 14704
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1146 times
Been thanked: 960 times

Re: PWM on STM32C0xx and STM32F40xx not reaching potential period time

Postby Giovanni » Sat Aug 30, 2025 2:26 pm

Hi,

What is the timer input clock? that comes from mcuconf.h, it must be a multiple of the clock you specified in the configuration structure. See the RCC section in the STM32 RM.

Giovanni

Engemil
Posts: 31
Joined: Thu Dec 19, 2024 12:50 am
Has thanked: 9 times
Been thanked: 7 times

Re: PWM on STM32C0xx and STM32F40xx not reaching potential period time

Postby Engemil » Sat Aug 30, 2025 8:55 pm

Alright, I just double checked the numbers, and it seems to be alright.

But, I just discovered something I didn't think would have affected the example code. If I commented out the following lines

Code: Select all

pwmEnablePeriodicNotification(APP_PWM_DRIVER);


Code: Select all

pwmEnableChannelNotification(APP_PWM_DRIVER, APP_PWM_LINE_CHANNEL);


Now it is running good!

I'll look into the use of DMA to see how I can offload the CPU for further functionalities :)

If there is something else I should look into, I'm open to hear ;)

User avatar
Giovanni
Site Admin
Posts: 14704
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1146 times
Been thanked: 960 times

Re: PWM on STM32C0xx and STM32F40xx not reaching potential period time

Postby Giovanni » Sat Aug 30, 2025 9:02 pm

Well, a notification with a period of 1.25 uS is a bit much to handle for a C0, CPU is likely flooded.

You can use DMA to write PWM-related registers directly (ARR and comparators), the DMA could be triggered by another timer (GPT driver) if you need accurate timings for updates.

You could also use the SPI driver for generating dynamically arbitrary signals (SPI circular mode), it is a bit a waste of resources however, better use PWM.

Giovanni


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 126 guests