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

Remove Async/Blocking and Periodic/Target modes from systimer and timg #2542

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

MabezDev
Copy link
Member

Thank you for your contribution!

We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:

Submission Checklist 📝

  • I have updated existing examples or added new ones (if applicable).
  • I have used cargo xtask fmt-packages command to ensure that all changed code is formatted correctly.
  • My changes were added to the CHANGELOG.md in the proper section.
  • I have added necessary changes to user code to the Migration Guide.
  • My changes are in accordance to the esp-rs API guidelines

Extra:

Pull Request Details 📖

This PR removes much of the logic out of the lower level timers, and instead moves the logic to the OneShot and Periodic timer drivers.

cc: #2321

I will do a follow up PR which adds the mode to the timer drivers, and implement into_async and the eh traits there, as this PR got surprising large surprisingly quick.

@@ -22,7 +22,7 @@ cfg-if = "1.0.0"
chrono = { version = "0.4.38", default-features = false }
critical-section = "1.1.3"
defmt = { version = "0.3.8", optional = true }
delegate = "0.12.0"
delegate = "0.13.0"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add's support for delegating async fns

///
/// Requires the correct `InterruptHandler` to be installed to function
/// correctly.
async fn wait(&self);
Copy link
Member Author

@MabezDev MabezDev Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried an API where it just returned a future, but it was noisy and I had trouble getting delegate to play ball with the types.

I think this should be fine, but let me know.

@@ -105,22 +104,40 @@ pub trait Timer: crate::private::Sealed {
/// Has the timer triggered?
fn is_interrupt_set(&self) -> bool;

/// Asynchronously wait for the timer interrupt to fire.
///
/// Requires the correct `InterruptHandler` to be installed to function
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deliberately decoupled the async fn from installing the correct interrupt handler, as this is a low level trait and if a user is reaching for it they probably want to register there own handler which could also call the async one once they're done doing what they need to do with it.

Self(AnyTimerInner::SystimerAlarmTarget(value))
crate::any_peripheral! {
/// Any Timer peripheral.
pub peripheral AnyTimer {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh this works for timers, too? 🤣

impl From<systimer::Alarm<'static, systimer::Target, Blocking>> for AnyTimer {
fn from(value: systimer::Alarm<'static, systimer::Target, Blocking>) -> Self {
Self(AnyTimerInner::SystimerAlarmTarget(value))
crate::any_peripheral! {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro is very handy :D

@@ -1,173 +0,0 @@
//! Async Delay Test
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will re-add this test in the next PR, for now the functionality is removed.

let mut alarm: Alarm<'_, Target, _, _, _> = Alarm::new(systimer.comparator0, &unit);
run_test_oneshot_timer(&mut alarm);
}
// FIXME (mabez)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some work to get going again, will do it in the follow up PR

Self: Into<AnyTimer>,
{
}
impl<T: esp_hal::timer::timg::Instance> IntoAnyTimer for TimgTimer<T> where Self: Into<AnyTimer> {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the other peripherals, Instance implies Into<AnyInstance> (+ 'static). I think we can do the same to timers as well. That may also mean IntoAnyTimer is meaningless, though I don't quite remember why I needed it in the first place - probably blanket impl'ing TimerCollection runs into some coherence rules.

}

alarm.set_interrupt_handler(handler);
alarm.set_interrupt_handler(match alarm.comparator.channel() {
Copy link
Contributor

@bugadani bugadani Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfortunately problematic because we can overwrite the user's interrupt handler without notice. If we offer an async API OR configurable interrupt handlers, we should have the Async/Blocking distinction.

If not, we should at least make sure we don't expose the functionality to users, and only them properly in the public API. I think this (adding a private::internal to the async fn in the trait), along with the Mode on Periodic/OneShot should suffice.

@@ -7,74 +7,14 @@
//! timer which can be used, for example, to generate tick interrupts for an
//! operating system, or simply as a general-purpose timer.
//!
//! ## Configuration
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you accidentally delete too much? Some of it still looks relevant.

Comment on lines -96 to +33
pub unit0: SpecificUnit<'d, 0>,
pub unit0: AnyUnit<'d>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to keep the specific ones here and accept impl Into<AnyUnit> in Alarm::new(....)?

asynch::AlarmFuture::new(self).await
}

fn async_interrupt_handler(&self) -> InterruptHandler {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Long term) Should the interrupt priority be decided down here?

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

Successfully merging this pull request may close these issues.

3 participants