From 172dd899f9e2215cbdb834424fa2267cb2dde51e Mon Sep 17 00:00:00 2001 From: Priec Date: Fri, 31 Oct 2025 10:26:33 +0100 Subject: [PATCH] debugging --- dma_gpio/src/bin/main.rs | 60 +++++++++++++++++++++++++++++++++++++-- dma_gpio/src/dma_timer.rs | 29 +++++++++++++++---- 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/dma_gpio/src/bin/main.rs b/dma_gpio/src/bin/main.rs index 1728d5d..07b1a88 100644 --- a/dma_gpio/src/bin/main.rs +++ b/dma_gpio/src/bin/main.rs @@ -33,6 +33,49 @@ const UART_CFG: UartConfig = UartConfig { stop_bits: StopBits::One, }; +fn dump_tim6_regs() { + // PAC path for STM32U5: module `tim6`, type `Tim6` with ptr() + use embassy_stm32::pac::timer::TimBasic; + let tim = unsafe { TimBasic::from_ptr(0x4000_1000usize as _) }; + let sr = tim.sr().read(); + let dier = tim.dier().read(); + let cr1 = tim.cr1().read(); + let arr = tim.arr().read().arr(); + let psc = tim.psc().read(); + info!( + "TIM6: CR1.CEN={} DIER.UDE={} SR.UIF={} PSC={} ARR={}", + cr1.cen(), + dier.ude(), + sr.uif(), + psc, + arr + ); +} + +fn dump_dma_ch0_regs() { + // PAC path for GPDMA1: module `gpdma1`, type `Gpdma1` + use embassy_stm32::pac::gpdma::Gpdma; + let dma = unsafe { Gpdma::from_ptr(0x4002_0000usize as _) }; + let ch = dma.ch(0); + let cr = ch.cr().read(); + let tr1 = ch.tr1().read(); + let tr2 = ch.tr2().read(); + let br1 = ch.br1().read(); + info!( + "GPDMA1_CH0: EN={} PRIO={} SDW={} DDW={} SINC={} DINC={} REQSEL={} SWREQ={} DREQ={} BNDT={}", + cr.en(), + cr.prio(), + tr1.sdw(), + tr1.ddw(), + tr1.sinc(), + tr1.dinc(), + tr2.reqsel(), + tr2.swreq(), + tr2.dreq(), + br1.bndt() + ); +} + #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_stm32::init(Default::default()); @@ -40,8 +83,9 @@ async fn main(spawner: Spawner) { // PA2 is the TX "wire" let _pa2 = Output::new(p.PA2, Level::High, Speed::VeryHigh); - drop(_pa2); + // drop(_pa2); init_tim6_for_uart(p.TIM6, BAUD, OVERSAMPLE); + dump_tim6_regs(); // Start DMA consumer task spawner.spawn(dma_tx_task(p.GPDMA1_CH0)).unwrap(); @@ -73,6 +117,18 @@ async fn dma_tx_task(ch: Peri<'static, GPDMA1_CH0>) { let w = u32::from_le_bytes(b); info!("DMA write 0x{:08X} -> GPIOA.BSRR", w); - tx.write_word(w).await; + match embassy_time::with_timeout( + Duration::from_millis(20), + tx.write_word(w), + ) + .await + { + Ok(()) => {} + Err(_) => { + warn!("DMA timeout: no TIM6 request (wrong DMAMUX req?)"); + dump_tim6_regs(); + dump_dma_ch0_regs(); + } + } } } diff --git a/dma_gpio/src/dma_timer.rs b/dma_gpio/src/dma_timer.rs index 52bf1c0..ff7baf6 100644 --- a/dma_gpio/src/dma_timer.rs +++ b/dma_gpio/src/dma_timer.rs @@ -6,6 +6,7 @@ use embassy_stm32::{ timer::low_level::Timer, Peri, }; +use embassy_stm32::pac::timer::vals::Urs; /// Initializes TIM6 to tick at `baud * oversample` frequency. /// Each TIM6 update event triggers one DMA beat. @@ -14,16 +15,34 @@ pub fn init_tim6_for_uart<'d>(tim6: Peri<'d, TIM6>, baud: u32, oversample: u16) let ll = Timer::new(tim6); let f_tim6 = rcc::frequency::().0; - let target = baud.saturating_mul(oversample.max(1) as u32); + let target = baud.saturating_mul(oversample.max(1) as u32).max(1); - // Compute ARR for desired frequency (16-bit timer) - let arr = (f_tim6 / target).saturating_sub(1) as u16; + // Compute ARR (prescaler=0) + let mut arr = (f_tim6 / target).saturating_sub(1) as u16; + if arr == 0 { + arr = 1; + } - // Apply registers + ll.regs_basic().cr1().write(|w| { + w.set_cen(false); + w.set_opm(false); + w.set_udis(false); // boolean field: false = allow UEV + w.set_urs(Urs::ANY_EVENT); // enum field: DMA+interrupts on any event + }); + + // Write prescaler directly (simple u16 register) + ll.regs_basic().psc().write_value(0u16); + + // Set ARR, enable DMA request, issue first update ll.regs_basic().arr().write(|w| w.set_arr(arr)); - ll.regs_basic().dier().write(|w| w.set_ude(true)); + ll.regs_basic().dier().modify(|w| w.set_ude(true)); + ll.regs_basic().egr().write(|w| w.set_ug(true)); + + // Start timer ll.regs_basic().cr1().write(|w| { w.set_opm(false); w.set_cen(true); + w.set_udis(false); + w.set_urs(Urs::ANY_EVENT); }); }