-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PWM DMA burst #107
Comments
Is it possible that the issue is with measuring the duty cycle rather than generating the signal? In case it's useful, I have a working example of PWM DMA burst tested on a STM32H747I-DISCO. I wasn't able to get #![no_main]
#![no_std]
use cortex_m::delay::Delay;
use hal::{
clocks::Clocks,
dma::{self, Dma, DmaChannel, DmaInput, DmaPeriph},
gpio::{Pin, PinMode, Port},
pac,
timer::{OutputCompare, TimChannel, Timer, TimerConfig, TimerInterrupt},
};
use defmt_rtt as _;
use panic_probe as _;
// Calculate the DMA offset by taking the Adddress Offset for
// the associated CCR channel in the RM register table, and dividing by 4.
const TIMX_CCR1_OFFSET: u8 = 0x34;
// 10 duty cycles from 10% to 80% assuming max duty cycle is 5332
const DUTY_CYCLES: [u16; 8] = [533, 1066, 1600, 2133, 2666, 3199, 3732, 4266];
#[cortex_m_rt::entry]
fn main() -> ! {
let cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
let clock_cfg = Clocks::default();
clock_cfg.setup().unwrap();
let mut delay = Delay::new(cp.SYST, clock_cfg.systick());
// Generate a PWM signal with 50% duty cycle and 2400 Hz frequency on PC6 (TIM3_CH1)
// TIM3_CH1 is connected to PC6 as alternate function 2
let _pwm_pin = Pin::new(Port::C, 6, PinMode::Alt(2));
let mut pwm_timer = Timer::new_tim3(
dp.TIM3,
37_500.,
TimerConfig::default(),
&clock_cfg,
);
pwm_timer.enable_pwm_output(TimChannel::C1, OutputCompare::Pwm1, 0.5);
let _dma = Dma::new(dp.DMA1);
dma::mux(DmaPeriph::Dma1, DmaChannel::C1, DmaInput::Tim3Up);
pwm_timer.enable_interrupt(TimerInterrupt::UpdateDma);
loop {
delay.delay_ms(2000);
pwm_timer.enable();
defmt::info!("Generating 50% duty cycle PWM signal");
delay.delay_ms(5);
// Set duty cycle using DMA
unsafe {
pwm_timer.write_dma_burst(
&DUTY_CYCLES,
TIMX_CCR1_OFFSET / 4,
1,
DmaChannel::C1,
dma::ChannelCfg {
circular: dma::Circular::Enabled,
..Default::default()
},
false,
DmaPeriph::Dma1,
);
}
defmt::info!("Generating 10% to 80% duty cycle PWM signal");
}
} |
Hey! I don't know what's going on. That's possible. Timer shenanigans on STM32 are tricky! LMK if you come up with anything; would love to get this fixed. |
@akhilles Hello, I tried your example, but it's not working for me either. Some parts of the code differ between the G4 and H7 chips. Anyway, I tried to set up the project in CubeIDE. The The |
LMK if you come up with anything. I've used the burst DMA on G4 only; haven't tried on other MCUs. (And only for one specific use case that may not generalize) I suspect the fix is something simple, but I'm not sure what it is. What I would do: See if you can get it working using the Reference manual and PAC directly, then post the results here, and/or compare to what the HAL functions are doing. |
Hi! After a few hours of searching, I finally managed to achieve what I wanted, and even more. Now, I know two ways to solve the problem. I’ll clean up the code and post it later. So I tried to figure out what was wrong with the HAL library code but couldn't find anything suspicious. Everything looks correct, even the parts I had doubts about turned out fine. In the end, just one line placed in the right spot fixed everything:
I’m not sure why the mux doesn’t need to be enabled for the H7 chip; it seems to work differently. Also, note that the mux must be enabled before specifying the routing. |
Nice find! It might be a good idea to enable the DMA mux RCC clock for G4 targets automatically when calling |
Nice find! I agree that it would be nice to enable it on G4 in I also wish the docs could be easily hosted/built for all targets: The |
Hi, thanks for the help. If anyone has encountered a problem working with DMA, you can check out example with a deep dive into registers. |
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:
cargo:
output:
The text was updated successfully, but these errors were encountered: