Skip to content

Commit 24bd697

Browse files
authored
Merge pull request #29 from hnez/iobus-limits
iobus: display power supply overload notifications
2 parents f18e3f0 + ccc30b8 commit 24bd697

File tree

11 files changed

+211
-140
lines changed

11 files changed

+211
-140
lines changed

src/digital_io.rs

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
use async_std::prelude::*;
1919
use async_std::sync::Arc;
20-
use async_std::task::{spawn, spawn_blocking};
20+
use async_std::task::spawn;
2121

2222
use crate::broker::{BrokerBuilder, Topic};
2323
use crate::led::BlinkPattern;
@@ -40,14 +40,13 @@ mod gpio {
4040
pub use hardware::*;
4141
}
4242

43-
pub use gpio::{find_line, EventRequestFlags, EventType, LineHandle, LineRequestFlags};
43+
pub use gpio::{find_line, LineHandle, LineRequestFlags};
4444

4545
pub struct DigitalIo {
4646
pub out_0: Arc<Topic<bool>>,
4747
pub out_1: Arc<Topic<bool>>,
4848
pub uart_rx_en: Arc<Topic<bool>>,
4949
pub uart_tx_en: Arc<Topic<bool>>,
50-
pub iobus_flt_fb: Arc<Topic<bool>>,
5150
}
5251

5352
/// Handle a GPIO line whose state is completely defined by the broker framework
@@ -82,38 +81,6 @@ fn handle_line_wo(
8281
topic
8382
}
8483

85-
/// Handle a GPIO line whose state is completely defined by itself
86-
/// (e.g. there is no way to manipulate it via the broker framework).
87-
fn handle_line_ro(bb: &mut BrokerBuilder, path: &str, line_name: &str) -> Arc<Topic<bool>> {
88-
let topic = bb.topic_ro(path, None);
89-
let line = find_line(line_name).unwrap();
90-
91-
let topic_thread = topic.clone();
92-
93-
let src = line
94-
.events(
95-
LineRequestFlags::INPUT,
96-
EventRequestFlags::BOTH_EDGES,
97-
"tacd",
98-
)
99-
.unwrap();
100-
101-
spawn_blocking(move || {
102-
topic_thread.set(src.get_value().unwrap() != 0);
103-
104-
for ev in src {
105-
let state = match ev.unwrap().event_type() {
106-
EventType::RisingEdge => true,
107-
EventType::FallingEdge => false,
108-
};
109-
110-
topic_thread.set(state);
111-
}
112-
});
113-
114-
topic
115-
}
116-
11784
impl DigitalIo {
11885
pub fn new(
11986
bb: &mut BrokerBuilder,
@@ -140,14 +107,12 @@ impl DigitalIo {
140107

141108
let uart_rx_en = handle_line_wo(bb, "/v1/uart/rx/enabled", "UART_RX_EN", true, true, None);
142109
let uart_tx_en = handle_line_wo(bb, "/v1/uart/tx/enabled", "UART_TX_EN", true, true, None);
143-
let iobus_flt_fb = handle_line_ro(bb, "/v1/iobus/feedback/fault", "IOBUS_FLT_FB");
144110

145111
Self {
146112
out_0,
147113
out_1,
148114
uart_rx_en,
149115
uart_tx_en,
150-
iobus_flt_fb,
151116
}
152117
}
153118
}

src/digital_io/gpio/demo_mode.rs

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
// with this program; if not, write to the Free Software Foundation, Inc.,
1616
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1717

18-
use std::iter::Iterator;
19-
use std::thread::sleep;
20-
use std::time::Duration;
21-
2218
use anyhow::Result;
2319
use async_std::task::block_on;
2420

@@ -39,14 +35,6 @@ impl LineHandle {
3935
match self.name.as_str() {
4036
"OUT_0" => iio_thread.get_channel("out0-volt").unwrap().set(val != 0),
4137
"OUT_1" => iio_thread.get_channel("out1-volt").unwrap().set(val != 0),
42-
"IOBUS_PWR_EN" => {
43-
iio_thread
44-
.clone()
45-
.get_channel("iobus-curr")
46-
.unwrap()
47-
.set(val != 0);
48-
iio_thread.get_channel("iobus-volt").unwrap().set(val != 0);
49-
}
5038
"DUT_PWR_EN" => {
5139
iio_thread
5240
.clone()
@@ -62,49 +50,9 @@ impl LineHandle {
6250
}
6351
}
6452

65-
pub struct LineEvent(u8);
66-
67-
impl LineEvent {
68-
pub fn event_type(&self) -> EventType {
69-
match self.0 {
70-
0 => EventType::FallingEdge,
71-
_ => EventType::RisingEdge,
72-
}
73-
}
74-
}
75-
76-
pub struct LineEventHandle {}
77-
78-
impl LineEventHandle {
79-
pub fn get_value(&self) -> Result<u8, ()> {
80-
Ok(0)
81-
}
82-
}
83-
84-
impl Iterator for LineEventHandle {
85-
type Item = Result<LineEvent, ()>;
86-
87-
fn next(&mut self) -> Option<Self::Item> {
88-
loop {
89-
sleep(Duration::from_secs(1000));
90-
}
91-
}
92-
}
93-
94-
pub enum EventType {
95-
RisingEdge,
96-
FallingEdge,
97-
}
98-
99-
#[allow(non_camel_case_types)]
100-
pub enum EventRequestFlags {
101-
BOTH_EDGES,
102-
}
103-
10453
#[allow(clippy::upper_case_acronyms)]
10554
pub enum LineRequestFlags {
10655
OUTPUT,
107-
INPUT,
10856
}
10957

11058
pub struct FindDecoy {
@@ -121,15 +69,6 @@ impl FindDecoy {
12169

12270
Ok(line_handle)
12371
}
124-
125-
pub fn events(
126-
&self,
127-
_: LineRequestFlags,
128-
_: EventRequestFlags,
129-
_: &str,
130-
) -> Result<LineEventHandle, ()> {
131-
Ok(LineEventHandle {})
132-
}
13372
}
13473

13574
pub fn find_line(name: &str) -> Result<FindDecoy> {

src/digital_io/gpio/test.rs

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -41,26 +41,11 @@ impl LineHandle {
4141

4242
pub struct LineEvent(u8);
4343

44-
impl LineEvent {
45-
pub fn event_type(&self) -> EventType {
46-
match self.0 {
47-
0 => EventType::FallingEdge,
48-
_ => EventType::RisingEdge,
49-
}
50-
}
51-
}
52-
5344
pub struct LineEventHandle {
5445
val: Arc<AtomicU8>,
5546
prev_val: u8,
5647
}
5748

58-
impl LineEventHandle {
59-
pub fn get_value(&self) -> Result<u8, ()> {
60-
Ok(self.val.load(Ordering::Relaxed))
61-
}
62-
}
63-
6449
impl Iterator for LineEventHandle {
6550
type Item = Result<LineEvent, ()>;
6651

@@ -78,20 +63,9 @@ impl Iterator for LineEventHandle {
7863
}
7964
}
8065

81-
pub enum EventType {
82-
RisingEdge,
83-
FallingEdge,
84-
}
85-
86-
#[allow(non_camel_case_types)]
87-
pub enum EventRequestFlags {
88-
BOTH_EDGES,
89-
}
90-
9166
#[allow(clippy::upper_case_acronyms)]
9267
pub enum LineRequestFlags {
9368
OUTPUT,
94-
INPUT,
9569
}
9670

9771
pub struct FindDecoy {
@@ -109,18 +83,6 @@ impl FindDecoy {
10983
})
11084
}
11185

112-
pub fn events(
113-
&self,
114-
_: LineRequestFlags,
115-
_: EventRequestFlags,
116-
_: &str,
117-
) -> Result<LineEventHandle> {
118-
Ok(LineEventHandle {
119-
val: self.val.clone(),
120-
prev_val: self.val.load(Ordering::Relaxed),
121-
})
122-
}
123-
12486
pub fn stub_get(&self) -> u8 {
12587
self.val.load(Ordering::Relaxed)
12688
}

src/iobus.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ use async_std::task::{sleep, spawn};
2222

2323
use serde::{Deserialize, Serialize};
2424

25+
use crate::adc::CalibratedChannel;
2526
use crate::broker::{BrokerBuilder, Topic};
2627

28+
const CURRENT_MAX: f32 = 0.2;
29+
const VOLTAGE_MIN: f32 = 10.0;
30+
2731
#[cfg(feature = "demo_mode")]
2832
mod http {
2933
use super::{LSSState, Nodes, ServerInfo};
@@ -97,15 +101,23 @@ pub struct ServerInfo {
97101
}
98102

99103
pub struct IoBus {
104+
pub supply_fault: Arc<Topic<bool>>,
100105
pub server_info: Arc<Topic<ServerInfo>>,
101106
pub nodes: Arc<Topic<Nodes>>,
102107
}
103108

104109
impl IoBus {
105-
pub fn new(bb: &mut BrokerBuilder) -> Self {
110+
pub fn new(
111+
bb: &mut BrokerBuilder,
112+
iobus_pwr_en: Arc<Topic<bool>>,
113+
iobus_curr: CalibratedChannel,
114+
iobus_volt: CalibratedChannel,
115+
) -> Self {
116+
let supply_fault = bb.topic_ro("/v1/iobus/feedback/fault", None);
106117
let server_info = bb.topic_ro("/v1/iobus/server/info", None);
107118
let nodes = bb.topic_ro("/v1/iobus/server/nodes", None);
108119

120+
let supply_fault_task = supply_fault.clone();
109121
let server_info_task = server_info.clone();
110122
let nodes_task = nodes.clone();
111123

@@ -125,10 +137,24 @@ impl IoBus {
125137
nodes_task.set_if_changed(nodes);
126138
}
127139

140+
// Report the power supply health
141+
let pwr_en = iobus_pwr_en.try_get().unwrap_or(false);
142+
let current = iobus_curr.get();
143+
let voltage = iobus_volt.get();
144+
145+
let undervolt = pwr_en && (voltage.value < VOLTAGE_MIN);
146+
let overcurrent = current.value > CURRENT_MAX;
147+
148+
supply_fault_task.set_if_changed(undervolt || overcurrent);
149+
128150
sleep(Duration::from_secs(1)).await;
129151
}
130152
});
131153

132-
Self { server_info, nodes }
154+
Self {
155+
supply_fault,
156+
server_info,
157+
nodes,
158+
}
133159
}
134160
}

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,12 @@ async fn main() -> Result<(), std::io::Error> {
8484

8585
// Expose other software on the TAC via the broker framework by connecting
8686
// to them via HTTP / DBus APIs.
87-
let iobus = IoBus::new(&mut bb);
87+
let iobus = IoBus::new(
88+
&mut bb,
89+
regulators.iobus_pwr_en.clone(),
90+
adc.iobus_curr.fast.clone(),
91+
adc.iobus_volt.fast.clone(),
92+
);
8893
let (network, rauc, systemd) = {
8994
let dbus = DbusSession::new(&mut bb, led.eth_dut.clone(), led.eth_lab.clone()).await;
9095

src/regulators.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,22 @@ use crate::broker::{BrokerBuilder, Topic};
2525
mod reg {
2626
use std::io::Result;
2727

28+
use async_std::task::block_on;
29+
30+
use crate::adc::IioThread;
31+
2832
pub fn regulator_set(name: &str, state: bool) -> Result<()> {
33+
if name == "output_iobus_12v" {
34+
let iio_thread = block_on(IioThread::new()).unwrap();
35+
36+
iio_thread
37+
.clone()
38+
.get_channel("iobus-curr")
39+
.unwrap()
40+
.set(state);
41+
iio_thread.get_channel("iobus-volt").unwrap().set(state);
42+
}
43+
2944
let state = if state { "enabled" } else { "disabled" };
3045
println!("Regulator: would set {name} to {state} but don't feel like it");
3146

src/ui/screens.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use serde::{Deserialize, Serialize};
2929
mod dig_out;
3030
mod help;
3131
mod iobus;
32+
mod iobus_health;
3233
mod locator;
3334
mod power;
3435
mod reboot;
@@ -43,6 +44,7 @@ mod usb;
4344
use dig_out::DigOutScreen;
4445
use help::HelpScreen;
4546
use iobus::IoBusScreen;
47+
use iobus_health::IoBusHealthScreen;
4648
use locator::LocatorScreen;
4749
use power::PowerScreen;
4850
use reboot::RebootConfirmScreen;
@@ -75,6 +77,7 @@ pub enum NormalScreen {
7577
#[derive(Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug)]
7678
pub enum AlertScreen {
7779
ScreenSaver,
80+
IoBusHealth,
7881
Locator,
7982
RebootConfirm,
8083
UpdateAvailable,
@@ -185,6 +188,7 @@ pub(super) fn init(
185188
Box::new(UartScreen::new()),
186189
Box::new(UsbScreen::new()),
187190
Box::new(HelpScreen::new(alerts, &res.setup_mode.show_help)),
191+
Box::new(IoBusHealthScreen::new(alerts, &res.iobus.supply_fault)),
188192
Box::new(UpdateInstallationScreen::new(
189193
alerts,
190194
&res.rauc.operation,

src/ui/screens/iobus.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl ActivatableScreen for IoBusScreen {
111111

112112
widgets.push(|display| {
113113
DynamicWidget::indicator(
114-
ui.res.dig_io.iobus_flt_fb.clone(),
114+
ui.res.iobus.supply_fault.clone(),
115115
display,
116116
row_anchor(2) + OFFSET_INDICATOR,
117117
Box::new(|state: &bool| match *state {

0 commit comments

Comments
 (0)