mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 22:32:29 +00:00
Add sleep/wakeup handling for bxCAN peripherals
This commit is contained in:
parent
3e00c1ac52
commit
e65503e255
@ -71,7 +71,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
|
||||
let msr = T::regs().msr();
|
||||
let msr_val = msr.read();
|
||||
|
||||
if msr_val.erri() {
|
||||
if msr_val.slaki() {
|
||||
msr.modify(|m| m.set_slaki(true));
|
||||
T::state().err_waker.wake();
|
||||
} else if msr_val.erri() {
|
||||
info!("Error interrupt");
|
||||
// Disable the interrupt, but don't acknowledge the error, so that it can be
|
||||
// forwarded off the the bus message consumer. If we don't provide some way for
|
||||
@ -251,6 +254,49 @@ impl<'d, T: Instance> Can<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables or disables the peripheral from automatically wakeup when a SOF is detected on the bus
|
||||
/// while the peripheral is in sleep mode
|
||||
pub fn set_automatic_wakeup(&mut self, enabled: bool) {
|
||||
Registers(T::regs()).set_automatic_wakeup(enabled);
|
||||
}
|
||||
|
||||
/// Manually wake the peripheral from sleep mode.
|
||||
///
|
||||
/// Waking the peripheral manually does not trigger a wake-up interrupt.
|
||||
/// This will wait until the peripheral has acknowledged it has awoken from sleep mode
|
||||
pub fn wakeup(&mut self) {
|
||||
Registers(T::regs()).wakeup()
|
||||
}
|
||||
|
||||
/// Check if the peripheral is currently in sleep mode
|
||||
pub fn is_sleeping(&self) -> bool {
|
||||
T::regs().msr().read().slak()
|
||||
}
|
||||
|
||||
/// Put the peripheral in sleep mode
|
||||
///
|
||||
/// When the peripherial is in sleep mode, messages can still be queued for transmission
|
||||
/// and any previously received messages can be read from the receive FIFOs, however
|
||||
/// no messages will be transmitted and no additional messages will be received.
|
||||
///
|
||||
/// If the peripheral has automatic wakeup enabled, when a Start-of-Frame is detected
|
||||
/// the peripheral will automatically wake and receive the incoming message.
|
||||
pub async fn sleep(&mut self) {
|
||||
T::regs().ier().modify(|i| i.set_slkie(true));
|
||||
T::regs().mcr().modify(|m| m.set_sleep(true));
|
||||
|
||||
poll_fn(|cx| {
|
||||
T::state().err_waker.register(cx.waker());
|
||||
if self.is_sleeping() {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
}).await;
|
||||
|
||||
T::regs().ier().modify(|i| i.set_slkie(false));
|
||||
}
|
||||
|
||||
/// Queues the message to be sent.
|
||||
///
|
||||
/// If the TX queue is full, this will wait until there is space, therefore exerting backpressure.
|
||||
|
Loading…
Reference in New Issue
Block a user