Skip to content

GPTMR sync is not working #9

@andelf

Description

@andelf

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions