-
Notifications
You must be signed in to change notification settings - Fork 220
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
Draft: alternate ManagedCS trait #350
Conversation
Co-authored-by: Grant Miller <GrantM11235@gmail.com>
r? @therealprof (rust-highfive has picked a reviewer for you, use r? to override) |
|
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.
Nice work! Looks pretty interesting and simple to use.
I think it is not too bad to omit the default implementations. Also in light of the downstream problems caused by these elsewhere.
I see the "unnecessary" boilerplate increase, though.
Is the inner()
method in ManagedCs
necessary? It seems like a method that should rather be part of SpiWithCs
.
One thing I did not understand is why ManagedCsAlt
requires Transactional
(but not ManagedCs
?). Is this just not part of this PR yet? I do not see any related trait bounds.
spi.with_cs(|d| {
spi.with_cs(|d| {
let _ = d.write(&[0xaa, 0xbb, 0xcc]);
Ok(())
});
Ok(())
});
/// blah
pub trait ManagedCs: ErrorType {
/// Inner SPI type
type Inner: ErrorType;
/// Future returned by the `with_cs` method.
type WithCsFuture<'a, R, F, Fut>: Future<Output = Result<R, Self::Error>> + 'a
where
Self: 'a,
R: 'a,
F: FnMut(&'a mut Self::Inner) -> Fut + 'a,
Fut: Future<Output = R> + 'a;
/// Execute the provided closure within a CS assertion
fn with_cs<'a, R, F, Fut>(&'a mut self, f: F) -> Self::WithCsFuture<'a, R, F, Fut>
where
F: FnMut(&'a mut Self::Inner) -> Fut + 'a,
Fut: Future<Output = R> + 'a;
/// Reference the inner SPI object without manipulating CS
fn inner(&mut self) -> &mut Self::Inner;
}
/// [`ManagedCs`] implementation for [`SpiWithCs`] wrapper.
/// Provides `with_cs` function that asserts and deasserts CS
impl<Spi, Pin> ManagedCs for SpiWithCs<Spi, Pin>
where
Spi: ErrorType,
Pin: OutputPin + DigitalErrorType,
{
type Inner = Spi;
type WithCsFuture<'a, R, F, Fut>
where
Self: 'a,
R: 'a,
F: FnMut(&'a mut Self::Inner) -> Fut + 'a,
Fut: Future<Output = R> + 'a,
= impl Future<Output = Result<R, Self::Error>> + 'a;
/// Execute the provided closure within a CS assertion
fn with_cs<'a, R, F, Fut>(&'a mut self, mut f: F) -> Self::WithCsFuture<'a, R, F, Fut>
where
F: FnMut(&'a mut Self::Inner) -> Fut + 'a,
Fut: Future<Output = R> + 'a,
{
async move {
self.cs.set_low().map_err(SpiWithCsError::Pin)?;
let r = f(&mut self.spi).await;
self.cs.set_high().map_err(SpiWithCsError::Pin)?;
Ok(r)
}
}
/// Reference the inner SPI object without manipulating CS
fn inner(&mut self) -> &mut Self::Inner {
&mut self.spi
}
} |
are we talking eliding the default
yep, definitely strange. i think the second has to be a noop, because if you call
yep agreed, i just hadn't decided how to bound the error yet. updated now.
yep, the advantage here is being able to have user code within CS though eh. i think there's no harm in having separate |
/// Executes the provided closure within a CS assertion | ||
fn with_cs<R>( | ||
&mut self, | ||
mut f: impl FnMut(&mut Self::Inner) -> Result<R, Self::Error>, |
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.
These should be FnOnce
, so it can consume captured stuff.
Closing in favour of #351 |
Based on work by @GrantM11235 as an alternative to #245.
There appears to be a choice between a magic / automatic impl that will deal with CS assertion itself, but conflicts with
&mut T
impls, and a more manual option where users will call.with_cs(|p| { ... })
to perform operations which seems rather less complex.(Note that for
ManagedCsAlt
SpiWithCs
must implementTransactional
etc. which it does not yet in this PR, and&mut T
impls are disabled toManagedCs
can compile)Co-authored-by: Grant Miller GrantM11235@gmail.com