Skip to content
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

GPTMR sync is not working #9

Open
andelf opened this issue Jun 26, 2024 · 0 comments
Open

GPTMR sync is not working #9

andelf opened this issue Jun 26, 2024 · 0 comments

Comments

@andelf
Copy link
Collaborator

andelf commented Jun 26, 2024

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant