stm32-hal
stm32-hal copied to clipboard
PWM DMA burst
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.
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