Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

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

No branches or pull requests

1 participant