diff --git a/Cargo.lock b/Cargo.lock index a9f1f9b47072..e2e40ddd1c1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,7 +157,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "profirust" -version = "0.2.0" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2442d1945c741cd17b53e5f9319ab63444f4ed211b4fce763e1bf9a50a0ef04" dependencies = [ "bitflags 2.6.0", "bitvec", diff --git a/Cargo.toml b/Cargo.toml index 0bf2b8133501..5a2ebc42674c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,8 @@ edition = "2021" [dependencies] env_logger = "0.11.5" log = "0.4.22" -profirust = { version = "0.2.0", path = "../profirust", default-features = false, features = ["phy-linux", "std"] } + +[dependencies.profirust] +version = "0.4.0" +default-features = false +features = ["phy-linux", "std"] diff --git a/src/main.rs b/src/main.rs index f03f9ca3a8ab..02e609e57e9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,13 +28,14 @@ fn main() -> ! { // We use a rather large T_slot time because USB-RS485 converters // can induce large delays at times. .slot_bits(2500) - // .token_rotation_bits(512) + // 2 Sekunden Watchdog Timeout + .watchdog_timeout(profirust::time::Duration::from_secs(2)) .build_verified(&dp_master), ); // We must not poll() too often or to little. T_slot / 2 seems to be a good compromise. let sleep_time: std::time::Duration = (fdl.parameters().slot_time() / 2).into(); - log::info!("Connecting to the bus..."); + log::info!("Verbindung mit dem Bus wird aufgebaut..."); let mut phy = phy::LinuxRs485Phy::new(BUS_DEVICE, fdl.parameters().baudrate); fdl.set_online(); @@ -55,11 +56,12 @@ fn main() -> ! { if valve_terminal.is_running(&mut dp_master) { tester_io.set_state(tester_io::TesterStatus::ValveTerminalConnected); + } else if valve_terminal.error() { + tester_io.set_state(tester_io::TesterStatus::Error); } else { tester_io.set_state(tester_io::TesterStatus::Ready); } - let scanner_event = dp_scanner.take_last_event(); match scanner_event { Some(dp::scan::DpScanEvent::PeripheralFound(desc)) => { diff --git a/src/tester_io.rs b/src/tester_io.rs index b8a36b1650c8..b7ae9bede574 100644 --- a/src/tester_io.rs +++ b/src/tester_io.rs @@ -9,6 +9,7 @@ //! ## Ausgänge //! - Leuchtmelder "Test-Station bereit" //! - Leuchtmelder "Ventilinsel erkannt" +//! - Leuchtmelder "Fehler beim Parametrieren" use profirust::dp; @@ -19,6 +20,8 @@ pub enum TesterStatus { Ready, /// Ventilinsel erkannt und verbunden ValveTerminalConnected, + /// Fehler beim Konfigurieren/Parametrieren der Ventilinsel + Error, } pub struct TesterIo { @@ -92,15 +95,17 @@ impl TesterIo { // Die 8 Eingänge der ET200B werden auf die 8 Bits für die Ventile gemapped. let pi_i = peripheral.pi_i(); for (i, valve) in self.valve_states.iter_mut().enumerate() { - *valve = pi_i[i / 8] & (1 << (i % 8)) != 0; + *valve = pi_i[i / 8] & (1 << (i % 8)) != 0; } // Ausgänge: // - Bit 0: Leuchtmelder "Test-Station bereit" // - Bit 1: Leuchtmelder "Ventilinsel erkannt" + // - Bit 2: Leuchtmelder "Parametrier-Fehler" let outputs = match self.tester_status { TesterStatus::Ready => 0x01, TesterStatus::ValveTerminalConnected => 0x02, + TesterStatus::Error => 0x04, }; peripheral.pi_q_mut()[0] = outputs; } diff --git a/src/valve_terminal.rs b/src/valve_terminal.rs index 049fd4ee09c6..3970bc0a8568 100644 --- a/src/valve_terminal.rs +++ b/src/valve_terminal.rs @@ -13,6 +13,7 @@ const VALVE_TERMINAL_IDENT_NUMBER: u16 = 0x0a35; pub struct ValveTerminal { peripheral: dp::PeripheralHandle, address: profirust::Address, + error: bool, valve_states: [bool; 8], } @@ -68,6 +69,7 @@ impl ValveTerminal { Self { peripheral: handle, address: default_address, + error: false, valve_states: [false; 8], } } @@ -90,6 +92,8 @@ impl ValveTerminal { peripheral.reset_address(address); peripheral.pi_q_mut().fill(0u8); self.valve_states = [false; 8]; + self.error = false; + self.address = address; } } @@ -100,7 +104,48 @@ impl ValveTerminal { } } + pub fn error(&self) -> bool { + self.error + } + pub fn update(&mut self, dp_master: &mut dp::DpMaster, events: &dp::DpEvents) { + if let Some((handle, event)) = events.peripheral { + if handle.address() == self.address { + match event { + dp::PeripheralEvent::Configured => { + log::info!("Ventilinsel #{} erfolgreich parametriert!", self.address); + } + dp::PeripheralEvent::ConfigError => { + self.error = true; + log::warn!( + "Fehler beim Konfigurieren der Ventilinsel #{}.", + self.address + ); + } + dp::PeripheralEvent::ParameterError => { + self.error = true; + log::warn!( + "Fehler beim Parametrieren der Ventilinsel #{}.", + self.address + ); + } + dp::PeripheralEvent::Diagnostics => { + let peripheral = dp_master.get_mut(self.peripheral); + let diagnostics = peripheral.last_diagnostics().unwrap(); + log::info!( + "Diagnostics von Ventilinsel #{} gemeldet: {:#?}", + self.address, + diagnostics + ); + } + dp::PeripheralEvent::Offline => { + log::info!("Ventilinsel #{} antwortet nicht mehr.", self.address); + } + _ => (), + } + } + } + let peripheral = dp_master.get_mut(self.peripheral); if peripheral.is_running() && events.cycle_completed { let pi_q = peripheral.pi_q_mut();