hpm-hal
hpm-hal copied to clipboard
GPTMR sync is not working
To Reproduce:
#![no_main]
#![no_std]
use embedded_hal::delay::DelayNs;
use hal::gpio::{Level, Output, Speed};
use hal::pac;
use riscv::delay::McycleDelay;
use {defmt_rtt as _, hpm_hal as hal, riscv_rt as _};
#[hpm_hal::entry]
#[link_section = ".fast"]
fn main() -> ! {
let p = hal::init(Default::default());
let mut delay = McycleDelay::new(hal::sysctl::clocks().hart0.0);
defmt::info!("Board init!");
let mut led = Output::new(p.PA23, Level::Low, Speed::default());
// use the clock, active resource
pac::SYSCTL.clock(pac::clocks::TMR0).modify(|w| {
w.set_mux(hpm_metapac::sysctl::vals::ClockMux::CLK_24M);
w.set_div(1); // actual div = div + 1
});
pac::GPTMR0.channel(0).cr().modify(|w| {
w.set_cen(true);
w.set_swsyncien(true); // 该位置 1 时,计数器会在 SWSYNCT 位置 1 时重载
});
pac::GPTMR0.channel(1).cr().modify(|w| {
w.set_syncflw(true);
w.set_swsyncien(true);
w.set_cen(true);
});
pac::GPTMR0.channel(2).cr().modify(|w| {
w.set_syncflw(true);
w.set_swsyncien(true);
w.set_cen(true);
});
pac::GPTMR0.channel(3).cr().modify(|w| {
w.set_syncflw(true);
w.set_swsyncien(true);
w.set_cen(true);
});
pac::GPTMR0.gcr().modify(|w| w.set_swsynct(0b1111));
defmt::info!(
"reload: {:x} {:x} {:x} {:x}",
pac::GPTMR0.channel(0).rld().read(),
pac::GPTMR0.channel(1).rld().read(),
pac::GPTMR0.channel(2).rld().read(),
pac::GPTMR0.channel(3).rld().read()
);
let mut i = 0;
loop {
i += 1;
delay.delay_ms(1000);
if i % 5 == 4 {
pac::GPTMR0.gcr().modify(|w| w.set_swsynct(0b1111));
}
let n0 = pac::GPTMR0.channel(0).cnt().read();
let n1 = pac::GPTMR0.channel(1).cnt().read();
let n2 = pac::GPTMR0.channel(2).cnt().read();
let n3 = pac::GPTMR0.channel(3).cnt().read();
let x = (n0, n1, n2, n3);
defmt::info!("cnt = {:?}", x);
led.toggle();
}
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
defmt::info!("panic");
loop {}
}
Result:
INFO Board init!
└─ gptmr_sync_bug::__risc_v_rt__main @ examples/gptmr_sync_bug.rs:17
INFO reload: ffffffff ffffffff ffffffff ffffffff
└─ gptmr_sync_bug::__risc_v_rt__main @ examples/gptmr_sync_bug.rs:49
INFO cnt = (12003582, 12003586, 12003590, 12003594)
└─ gptmr_sync_bug::__risc_v_rt__main @ examples/gptmr_sync_bug.rs:72
INFO cnt = (24007396, 24007400, 24007410, 24007414)
└─ gptmr_sync_bug::__risc_v_rt__main @ examples/gptmr_sync_bug.rs:72
INFO cnt = (36014682, 36014686, 36014696, 36014700)
└─ gptmr_sync_bug::__risc_v_rt__main @ examples/gptmr_sync_bug.rs:72
INFO cnt = (2, 6, 16, 20) 😳 <= not synced
└─ gptmr_sync_bug::__risc_v_rt__main @ examples/gptmr_sync_bug.rs:72