Skip to content

add timer_src_clk_sys feature to support running RP2350x timer at s… #4157

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions embassy-rp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ critical-section-impl = ["critical-section/restore-state-u8"]
unstable-pac = []

## Enable the timer for use with `embassy-time` with a 1MHz tick rate.
time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-1_000_000", "dep:embassy-time-queue-utils"]
#time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-1_000_000", "dep:embassy-time-queue-utils"]
time-driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils"]

## Enable ROM function cache. This will store the address of a ROM function when first used, improving performance of subsequent calls.
rom-func-cache = []
Expand Down Expand Up @@ -122,7 +123,15 @@ _rp235x = ["rp-pac/rp235x"]
rp235xa = ["_rp235x"]
## Configure the hal for use with the rp235xB
rp235xb = ["_rp235x"]

## Add a feature which configures `embassy-time-driver` with 150MHz `tick`s. This is an indication
## by the upstream crate that the RP2350's `TIMER`s are configured with the system clock as their
## source (typically 150MHz), instead of the usual 1MHz.
## Compilation flag checks in `lib.rs` ensure this feature is only used together with `_rp235x`
timer-src-clk-sys = [
"dep:embassy-time-driver",
"embassy-time-driver?/tick-hz-150_000_000",
"dep:embassy-time-queue-utils",
]
# hack around cortex-m peripherals being wrong when running tests.
_test = []

Expand Down
13 changes: 13 additions & 0 deletions embassy-rp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
//! ## Feature flags
#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]

//! ## Compatible feature flags
// `timer-src-clk-sys` only makes sense on RP235x silicon.
#[cfg(all(feature = "timer-src-clk-sys", not(feature = "_rp235x"),))]
compile_error!(
"`embassy-rp` feature `timer-src-clk-sys` requires an `rp235x` feature (either `rp235xa` or \
`rp235xb`) to be enabled."
);

// // Prevent users from selecting both timer drivers (although this condition causes a redefinition
// // error in our deps before this code can halt the compilation with an explanation...)
// #[cfg(all(feature = "timer-src-clk-sys", feature = "time-driver"))]
// compile_error!("Enable only one of `time-driver` or `timer-src-clk-sys`.");

// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;

Expand Down
12 changes: 12 additions & 0 deletions embassy-rp/src/time_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use embassy_time_queue_utils::Queue;
use pac::TIMER;
#[cfg(feature = "_rp235x")]
use pac::TIMER0 as TIMER;
#[cfg(all(feature = "_rp235x", feature = "timer-src-clk-sys"))]
use rp_pac::timer::vals::ClkSys;

use crate::interrupt::InterruptExt;
use crate::{interrupt, pac};
Expand Down Expand Up @@ -129,6 +131,16 @@ pub unsafe fn init() {
{
interrupt::TIMER0_IRQ_0.enable();
}
#[cfg(all(feature = "_rp235x", feature = "timer-src-clk-sys"))]
{
// The PAC currently only defines `TIMER0` as `TIMER` even though the RP2350 also has
// `TIMER1`.
let timer_0 = TIMER;
// Switch `SOURCE` to `CLK_SYS` (instead of 1 µs tick)
timer_0.source().write(|w| w.set_clk_sys(ClkSys::CLK_SYS));
// Lock configuration--`TIMER0` now read-only (until reset)
timer_0.locked().write(|w| w.set_locked(true));
}
}

#[cfg(all(feature = "rt", feature = "rp2040"))]
Expand Down
46 changes: 22 additions & 24 deletions embassy-rp/src/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,35 +655,33 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
}

async fn setup(&mut self) -> [u8; 8] {
loop {
trace!("SETUP read waiting");
let regs = T::regs();
regs.inte().write_set(|w| w.set_setup_req(true));
trace!("SETUP read waiting");
let regs = T::regs();
regs.inte().write_set(|w| w.set_setup_req(true));

poll_fn(|cx| {
EP_OUT_WAKERS[0].register(cx.waker());
let regs = T::regs();
if regs.sie_status().read().setup_rec() {
Poll::Ready(())
} else {
Poll::Pending
}
})
.await;
poll_fn(|cx| {
EP_OUT_WAKERS[0].register(cx.waker());
let regs = T::regs();
if regs.sie_status().read().setup_rec() {
Poll::Ready(())
} else {
Poll::Pending
}
})
.await;

let mut buf = [0; 8];
EndpointBuffer::<T>::new(0, 8).read(&mut buf);
let mut buf = [0; 8];
EndpointBuffer::<T>::new(0, 8).read(&mut buf);

let regs = T::regs();
regs.sie_status().write(|w| w.set_setup_rec(true));
let regs = T::regs();
regs.sie_status().write(|w| w.set_setup_rec(true));

// set PID to 0, so (after toggling) first DATA is PID 1
T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));
// set PID to 0, so (after toggling) first DATA is PID 1
T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));

trace!("SETUP read ok");
return buf;
}
trace!("SETUP read ok");
return buf;
}

async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> {
Expand Down