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?