mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
Ensure bus errors are forwarded only once, enable bus off/passive/warning interrupts
This commit is contained in:
parent
a5b006268b
commit
6e1290b3f1
@ -67,12 +67,20 @@ pub struct SceInterruptHandler<T: Instance> {
|
||||
|
||||
impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterruptHandler<T> {
|
||||
unsafe fn on_interrupt() {
|
||||
// info!("sce irq");
|
||||
info!("sce irq");
|
||||
let msr = T::regs().msr();
|
||||
let msr_val = msr.read();
|
||||
|
||||
if msr_val.erri() {
|
||||
msr.modify(|v| v.set_erri(true));
|
||||
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
|
||||
// downstream code to determine that it has already provided this bus error instance
|
||||
// to the bus message consumer, we are doomed to re-provide a single error instance for
|
||||
// an indefinite amount of time.
|
||||
let ier = T::regs().ier();
|
||||
ier.modify(|i| i.set_errie(false));
|
||||
|
||||
T::state().err_waker.wake();
|
||||
}
|
||||
}
|
||||
@ -180,6 +188,9 @@ impl<'d, T: Instance> Can<'d, T> {
|
||||
w.set_fmpie(0, true);
|
||||
w.set_fmpie(1, true);
|
||||
w.set_tmeie(true);
|
||||
w.set_bofie(true);
|
||||
w.set_epvie(true);
|
||||
w.set_ewgie(true);
|
||||
});
|
||||
|
||||
T::regs().mcr().write(|w| {
|
||||
|
@ -145,7 +145,21 @@ impl Registers {
|
||||
}
|
||||
|
||||
pub fn curr_error(&self) -> Option<BusError> {
|
||||
let err = { self.0.esr().read() };
|
||||
if !self.0.msr().read().erri() {
|
||||
// This ensures that once a single error instance has
|
||||
// been acknowledged and forwared to the bus message consumer
|
||||
// we don't continue to re-forward the same error occurrance for an
|
||||
// in-definite amount of time.
|
||||
return None;
|
||||
}
|
||||
|
||||
// Since we have not already acknowledge the error, and the interrupt was
|
||||
// disabled in the ISR, we will acknowledge the current error and re-enable the interrupt
|
||||
// so futher errors are captured
|
||||
self.0.msr().modify(|m| m.set_erri(true));
|
||||
self.0.ier().modify(|i| i.set_errie(true));
|
||||
|
||||
let err = self.0.esr().read();
|
||||
if err.boff() {
|
||||
return Some(BusError::BusOff);
|
||||
} else if err.epvf() {
|
||||
|
Loading…
Reference in New Issue
Block a user