stm32-hal icon indicating copy to clipboard operation
stm32-hal copied to clipboard

PWM DMA burst

Open dkotTech opened this issue 1 year ago • 10 comments

Hi, I am working on an example that demonstrates the usage of a DRV8844 motor driver with PWM and DMA.

However, something is not working as expected. The duty cycle does not change after a DMA write request.

full src link

code:


#![no_main]
#![no_std]

use defmt_rtt as _;
use panic_probe as _;

use hal::{
    self,
    clocks::Clocks,
    dma,
    dma::{ChannelCfg, Dma, DmaChannel, DmaInput, DmaPeriph},
    gpio::{Pin, PinMode, Port},
    pac,
    pac::{TIM2, TIM3},
    timer::{
        OutputCompare, TimChannel, Timer, TimerConfig,
        TimerInterrupt,
    },
};
pub static BUF: [u16; 4] = [1, 2, 3, 4];

#[rtic::app(device = pac, peripherals = true)]
mod app {
    use super::*;

    #[shared]
    struct Shared {}

    #[local]
    struct Local {
        timer_pwd: Timer<TIM2>,
        timer: Timer<TIM3>,
    }

    #[init]
    fn init(ctx: init::Context) -> (Shared, Local) {
        let dp = ctx.device;

        let clock_cfg = Clocks::default();
        clock_cfg.setup().unwrap();

        Pin::new(Port::A, 0, PinMode::Alt(1));

        let mut dma = Dma::new(dp.DMA1);
        dma::mux(DmaPeriph::Dma1, DmaChannel::C1, DmaInput::Tim2Up);

        let mut timer_pwd = Timer::new_tim2(
            dp.TIM2,
            20_000.,
            TimerConfig::default(),
            &clock_cfg,
        );

        timer_pwd.enable_pwm_output(TimChannel::C1, OutputCompare::Pwm1, 0.1);

        timer_pwd.enable_interrupt(TimerInterrupt::UpdateDma);

        unsafe {
            timer_pwd.write_dma_burst(
                &BUF,
                13,
                4,
                DmaChannel::C1,
                ChannelCfg ::default(),
                true,
                DmaPeriph::Dma1,
            );
        }

        let mut timer = Timer::new_tim3(dp.TIM3, 0.2, Default::default(), &clock_cfg);
        timer.enable_interrupt(TimerInterrupt::Update);
        timer.enable();

        (Shared {}, Local { timer_pwd, timer })
    }

    #[task(binds = TIM3, local=[timer_pwd, timer, a: i32 = 0], priority = 1)]
    fn on_dma1_complete(cx: on_dma1_complete::Context) {
        cx.local.timer.clear_interrupt(TimerInterrupt::Update);

        defmt::println!("psc: {:?}", cx.local.timer_pwd.regs.psc.read().bits());
        defmt::println!("arr: {:?}", cx.local.timer_pwd.regs.arr.read().bits());
        defmt::println!("rcr: {:?}", cx.local.timer_pwd.regs.rcr.read().bits());

        defmt::println!(
            "cx.local.timer_pwd1: {:?}",
            cx.local.timer_pwd.get_duty(TimChannel::C1)
        );
        defmt::println!(
            "cx.local.timer_pwd2: {:?}",
            cx.local.timer_pwd.get_duty(TimChannel::C2)
        );
        defmt::println!(
            "cx.local.timer_pwd3: {:?}",
            cx.local.timer_pwd.get_duty(TimChannel::C3)
        );
        defmt::println!(
            "cx.local.timer_pwd4: {:?}",
            cx.local.timer_pwd.get_duty(TimChannel::C4)
        );
    }
}

#[defmt::panic_handler]
fn panic() -> ! {
    cortex_m::asm::udf()
}

cargo:

[package]
name = "pwm-dma-example"
version = "0.1.0"
edition = "2021"

[dependencies]
defmt = "0.3.4"
defmt-rtt = "0.4.0"
panic-probe = { version = "0.3.1", features = ["print-defmt"] }

cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
hal = { package = "stm32-hal2", version = "^1.8.3", features = ["g431", "g4rt"]}
rtic = { version = "2.1.1", features = ["cortex-m", "thumbv7-backend", "rtic-monotonics"] }

output:

<lvl> psc: 0
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:82  
<lvl> arr: 8499
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:83  
<lvl> rcr: 0
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:84  
<lvl> cx.local.timer_pwd1: 849
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:86  
<lvl> cx.local.timer_pwd2: 0
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:90  
<lvl> cx.local.timer_pwd3: 0
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:94  
<lvl> cx.local.timer_pwd4: 0
└─ dma_pwm::app::on_dma1_complete @ dma_pwm/src/main.rs:98 

dkotTech avatar Jul 20 '24 22:07 dkotTech