debugging

This commit is contained in:
Priec
2025-10-31 10:26:33 +01:00
parent f56fe0561b
commit 172dd899f9
2 changed files with 82 additions and 7 deletions

View File

@@ -33,6 +33,49 @@ const UART_CFG: UartConfig = UartConfig {
stop_bits: StopBits::One, 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] #[embassy_executor::main]
async fn main(spawner: Spawner) { async fn main(spawner: Spawner) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
@@ -40,8 +83,9 @@ async fn main(spawner: Spawner) {
// PA2 is the TX "wire" // PA2 is the TX "wire"
let _pa2 = Output::new(p.PA2, Level::High, Speed::VeryHigh); let _pa2 = Output::new(p.PA2, Level::High, Speed::VeryHigh);
drop(_pa2); // drop(_pa2);
init_tim6_for_uart(p.TIM6, BAUD, OVERSAMPLE); init_tim6_for_uart(p.TIM6, BAUD, OVERSAMPLE);
dump_tim6_regs();
// Start DMA consumer task // Start DMA consumer task
spawner.spawn(dma_tx_task(p.GPDMA1_CH0)).unwrap(); 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); let w = u32::from_le_bytes(b);
info!("DMA write 0x{:08X} -> GPIOA.BSRR", w); 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();
}
}
} }
} }

View File

@@ -6,6 +6,7 @@ use embassy_stm32::{
timer::low_level::Timer, timer::low_level::Timer,
Peri, Peri,
}; };
use embassy_stm32::pac::timer::vals::Urs;
/// Initializes TIM6 to tick at `baud * oversample` frequency. /// Initializes TIM6 to tick at `baud * oversample` frequency.
/// Each TIM6 update event triggers one DMA beat. /// 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 ll = Timer::new(tim6);
let f_tim6 = rcc::frequency::<TIM6>().0; let f_tim6 = rcc::frequency::<TIM6>().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) // Compute ARR (prescaler=0)
let arr = (f_tim6 / target).saturating_sub(1) as u16; 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().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| { ll.regs_basic().cr1().write(|w| {
w.set_opm(false); w.set_opm(false);
w.set_cen(true); w.set_cen(true);
w.set_udis(false);
w.set_urs(Urs::ANY_EVENT);
}); });
} }