Skip to content

[stm32] SimplePWM.waveform DMA transfer incorrect(?) for 32-bit timers #4788

@northernpaws

Description

@northernpaws

I believe this may be related to #2522 and #3704.

On an STM32H734ZIxT I've configured SimplePWM with 32-bit TIM5, a 800kHz cycle, APB1 running at 240MHz, so full duty cycle is 300.

If I use the set_duty_cycle and related methods on SimplePWM all the timing is correct on my scope.

However, one I start trying to feed it data with DMA via SimplePWM.waveform things start to go a little funny. Firstly, if I try to feed it anything in less them multiples of 2, i.e. [300], I hit the assertion from here. I understand why, but my expectation considering the waveform method takes in u16s and the PR linked above was that it would handle the data differences.

To actually get correct waveforms out of it, I need to pad them with 0's, i.e. [300, 0, 150, 0] for 1 full duty cycle, and then one half cycle:

// Configure the pin to PWM
let pwm_pin = PwmPin::new(p.PA3, OutputType::PushPull);

// Given this system frequency and pwm frequency the max duty cycle will be 300.
let mut pwm = SimplePwm::new(
        TIM5,
        None,
        None,
        None,
        Some(pwm_pin),
        // PWM_FREQ = 1 / data_transfer_time = 1 / 1.25us = 800kHz
        Hertz::khz(800),
        CountingMode::EdgeAlignedUp,
);
    
// Enable the channel corresponding to the PWM channel above.
let mut pwm_channel = pwm.ch4();
pwm_channel.enable();

// Make sure PWM output keep low on first start.
//
// This duty cycle is reset to after the DMA waveform has been transmitted.
pwm_channel.set_duty_cycle(0);

let mut led_dma = p.DMA2_CH4;
let duty = &[300, 0, 0, 0, 150, 0, 0, 0];
loop {
    pwm.waveform::<embassy_stm32::timer::Ch4>(led_dma.reborrow(), duty)
        .await;
   Timer::after_millis(600).await;
}

If anything is written in the second half-word, then the timing becomes really strange - a fairly consistent 30us cycle time, followed by a consistent 80us gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions