From 521c132e348054e6326e9c9387516b0e98743092 Mon Sep 17 00:00:00 2001 From: Torin Cooper-Bennun Date: Tue, 23 Apr 2024 12:33:27 +0100 Subject: [PATCH] stm32: can: fd: introduce BusErrorMode with docs and Properties getter --- embassy-stm32/src/can/enums.rs | 18 ++++++++++++++++++ embassy-stm32/src/can/fdcan.rs | 14 +++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/can/enums.rs b/embassy-stm32/src/can/enums.rs index 4d89c84d1..a5cca424d 100644 --- a/embassy-stm32/src/can/enums.rs +++ b/embassy-stm32/src/can/enums.rs @@ -29,6 +29,24 @@ pub enum BusError { BusWarning, } +/// Bus error modes. +/// +/// Contrary to the `BusError` enum which also includes last-seen acute protocol +/// errors, this enum includes only the mutually exclusive bus error modes. +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum BusErrorMode { + /// Error active mode (default). Controller will transmit an active error + /// frame upon protocol error. + ErrorActive, + /// Error passive mode. An error counter exceeded 127. Controller will + /// transmit a passive error frame upon protocol error. + ErrorPassive, + /// Bus off mode. The transmit error counter exceeded 255. Controller is not + /// participating in bus traffic. + BusOff, +} + /// Frame Create Errors #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 0df74a778..faf8a1176 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -859,9 +859,17 @@ impl Properties { T::registers().regs.ecr().read().tec() } - /// Get the current Bus-Off state - pub fn bus_off(&self) -> bool { - T::registers().regs.psr().read().bo() + /// Get the current bus error mode + pub fn bus_error_mode(&self) -> BusErrorMode { + // This read will clear LEC and DLEC. This is not ideal, but protocol + // error reporting in this driver should have a big ol' FIXME on it + // anyway! + let psr = T::regs().psr().read(); + match (psr.bo(), psr.ep()) { + (false, false) => BusErrorMode::ErrorActive, + (false, true) => BusErrorMode::ErrorPassive, + (true, _) => BusErrorMode::BusOff, + } } }