-
Notifications
You must be signed in to change notification settings - Fork 13
Timers #12
base: master
Are you sure you want to change the base?
Timers #12
Conversation
TIMER1 and TIMER2 can now be used for this functionality instead of just TIMER0.
src/timer.rs
Outdated
{ | ||
|
||
// Reset comparison interrupt | ||
self.reset_compare(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Remove duplication from start
I think this is ready for an initial review, I have qualified the functionality of all 5 peripherals on my device. |
src/timer.rs
Outdated
|
||
impl Timer<$RTC> { | ||
/// Construct RTC based timer with prescaler | ||
/// *WARNING* The LFCLK needs to be activated first, e.g. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically, this will breach the embedded-hal Countdown trait contract
Fixes following discussion with @therealprof. Still some open issues, but a lot is down to shortcomings in embedded-hal |
src/lib.rs
Outdated
#![feature(const_fn)] | ||
#![feature(try_from)] | ||
#![feature(duration_as_u128)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should try to get rid of all those features. This should eventually be Rust 2018 stable-able.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I had forgotten about that:
- Remove all 3 2018-incompatible features
I used core::time::Duration
to get it working, but it is expensive in an MCU to use u128s to manipulate time. It seems there are many ongoing discussions about how to handle real unite both in rust and rust-embedded, none nearing conclusion. So for now I will just make 3 types: tick (An nrf51 specific tick, 1/16th of a μs, a μs and a ms.
src/delay.rs
Outdated
macro_rules! delay { | ||
( $($TIM:ty),+ ) => { | ||
$( | ||
impl DelayMs<u32> for Timer<$TIM> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you've renamed Delay
to Timer
? That'll break all some stuff, including your own examples in microbit
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll create an alias to Delay as a structural fix, as that what clients will expect. Behind the scenes though it makes no sense to have a distinction.
src/timer.rs
Outdated
|
||
/// Error to respresent a stopped countdown | ||
#[derive(Debug)] | ||
pub struct CountdownStoppedError; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused
src/timer.rs
Outdated
|
||
impl From<Millis> for Lfticks { | ||
fn from(millis: Millis) -> Self { | ||
Lfticks(u32(f64::from(millis.0) * 32.768).unwrap()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
f64
is a very expensive type on this platform. Is this really necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh my, that is an unacceptably bad bit of code..., it isn't even mathematically correct, apologies:
Lfticks(millis.0 * LFCLK_FREQ)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, it was mathematically correct, ( 32.768 =/= 32_768
)
I need to find a table which lists how expensive various operations are...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this is a Cortex-M0, so no hardware division. And no FPU, so floating point is all emulated.
Don't merge this, I think there is a major flaw with this as is.
Thoughts? |
@droogmic Just from reading the code I'm not sure how conflicting use would be possible. Is this due to Delay being a type alias for a Timer? If so this could be solved by using a type state, i.e. have some general timer initialisation code and then two different types implementing either HAL functionality. |
Ah yeah, that would be option 1, don't actually need macros. |
@therealprof And yes, because of the alias you can make a Delay item with both DelayMs and Timer traits implemented |
After @therealprof review + Move time to a seperate file + Move generic timer/counter implementation to file + Create newtype Delay and Timer from TimCo
@therealprof I am not sure if this is what you meant
|
@droogmic I don't have the time right now to look into your update but typestate programming is something like this: https://github.com/therealprof/stm32f042-hal/blob/master/src/gpio.rs Basically what you had previously but with empty structs for the different possibilities (e.g. Countdown or Delay), functions to move the generic timer into those states and then only impl the traits on the timers which are in that specific state. |
@therealprof Thanks, I'll try that and get back to you. |
Used to seperate Countdown and Delay trait implementation for same Timer struct
@therealprof I have made an attempt, but I am not really happy with the result... |
@therealprof bump, a quick look to see if this is what you meant would be appreciated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good structure-wise (except maybe for the excess blank lines) but I'm a bit lost on how to actually use this, i.e. how do I turn a RTCx or TIMERx peripheral into a timer I can actually call into_delay()
or into_countdown()
on? As a nice litmus test it would be great if you could also come up with a PR that changes the microbit
crate to make use of the changed interface.
@therealprof Not sure type state is the way to go anymore, as the moment the struct specializes most of the methods should probably be removed. I think having 3 different structs would be simpler, where Delay and Countdown structs container a single Timer struct. |
@droogmic Actually I was hoping that instead of |
Based on #8, appears to work as required. It is however, very messy, I am just happy I got it working.
I am not totally up to speed with recent embedded rust developments and roadmap, nor am I very experienced with rust, so a skim read and advice if there is a better standard to follow would be appreciated.
Changes:
Consider / TODO:
start
methodtime.rs
filehal::timer::Periodic
marker trait flag, doesn't apply as for the nrf51 this can be changed at runtime, how is this usually handled?