Skip to content

Commit 7794446

Browse files
authored
Merge pull request #27 from hnez/iio-buffering
adc: iio: hardware: add buffering support to the powerboard ADC
2 parents 60a84f0 + 7b71bd9 commit 7794446

File tree

9 files changed

+357
-229
lines changed

9 files changed

+357
-229
lines changed

src/adc.rs

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,12 @@ pub struct Adc {
7878

7979
impl Adc {
8080
pub async fn new(bb: &mut BrokerBuilder) -> Result<Self> {
81-
let iio_thread = IioThread::new().await?;
81+
let stm32_thread = IioThread::new_stm32().await?;
82+
let powerboard_thread = IioThread::new_powerboard().await?;
8283

8384
let adc = Self {
8485
usb_host_curr: AdcChannel {
85-
fast: iio_thread.clone().get_channel("usb-host-curr").unwrap(),
86+
fast: stm32_thread.clone().get_channel("usb-host-curr").unwrap(),
8687
topic: bb.topic(
8788
"/v1/usb/host/total/feedback/current",
8889
true,
@@ -93,7 +94,7 @@ impl Adc {
9394
),
9495
},
9596
usb_host1_curr: AdcChannel {
96-
fast: iio_thread.clone().get_channel("usb-host1-curr").unwrap(),
97+
fast: stm32_thread.clone().get_channel("usb-host1-curr").unwrap(),
9798
topic: bb.topic(
9899
"/v1/usb/host/port1/feedback/current",
99100
true,
@@ -104,7 +105,7 @@ impl Adc {
104105
),
105106
},
106107
usb_host2_curr: AdcChannel {
107-
fast: iio_thread.clone().get_channel("usb-host2-curr").unwrap(),
108+
fast: stm32_thread.clone().get_channel("usb-host2-curr").unwrap(),
108109
topic: bb.topic(
109110
"/v1/usb/host/port2/feedback/current",
110111
true,
@@ -115,7 +116,7 @@ impl Adc {
115116
),
116117
},
117118
usb_host3_curr: AdcChannel {
118-
fast: iio_thread.clone().get_channel("usb-host3-curr").unwrap(),
119+
fast: stm32_thread.clone().get_channel("usb-host3-curr").unwrap(),
119120
topic: bb.topic(
120121
"/v1/usb/host/port3/feedback/current",
121122
true,
@@ -126,7 +127,7 @@ impl Adc {
126127
),
127128
},
128129
out0_volt: AdcChannel {
129-
fast: iio_thread.clone().get_channel("out0-volt").unwrap(),
130+
fast: stm32_thread.clone().get_channel("out0-volt").unwrap(),
130131
topic: bb.topic(
131132
"/v1/output/out_0/feedback/voltage",
132133
true,
@@ -137,7 +138,7 @@ impl Adc {
137138
),
138139
},
139140
out1_volt: AdcChannel {
140-
fast: iio_thread.clone().get_channel("out1-volt").unwrap(),
141+
fast: stm32_thread.clone().get_channel("out1-volt").unwrap(),
141142
topic: bb.topic(
142143
"/v1/output/out_1/feedback/voltage",
143144
true,
@@ -148,7 +149,7 @@ impl Adc {
148149
),
149150
},
150151
iobus_curr: AdcChannel {
151-
fast: iio_thread.clone().get_channel("iobus-curr").unwrap(),
152+
fast: stm32_thread.clone().get_channel("iobus-curr").unwrap(),
152153
topic: bb.topic(
153154
"/v1/iobus/feedback/current",
154155
true,
@@ -159,7 +160,7 @@ impl Adc {
159160
),
160161
},
161162
iobus_volt: AdcChannel {
162-
fast: iio_thread.clone().get_channel("iobus-volt").unwrap(),
163+
fast: stm32_thread.clone().get_channel("iobus-volt").unwrap(),
163164
topic: bb.topic(
164165
"/v1/iobus/feedback/voltage",
165166
true,
@@ -170,7 +171,7 @@ impl Adc {
170171
),
171172
},
172173
pwr_volt: AdcChannel {
173-
fast: iio_thread.clone().get_channel("pwr-volt").unwrap(),
174+
fast: powerboard_thread.clone().get_channel("pwr-volt").unwrap(),
174175
topic: bb.topic(
175176
"/v1/dut/feedback/voltage",
176177
true,
@@ -181,7 +182,7 @@ impl Adc {
181182
),
182183
},
183184
pwr_curr: AdcChannel {
184-
fast: iio_thread.get_channel("pwr-curr").unwrap(),
185+
fast: powerboard_thread.get_channel("pwr-curr").unwrap(),
185186
topic: bb.topic(
186187
"/v1/dut/feedback/current",
187188
true,
@@ -194,50 +195,36 @@ impl Adc {
194195
time: bb.topic_ro("/v1/tac/time/now", None),
195196
};
196197

197-
let adc_clone = adc.clone();
198+
let channels = [
199+
adc.usb_host_curr.clone(),
200+
adc.usb_host1_curr.clone(),
201+
adc.usb_host2_curr.clone(),
202+
adc.usb_host3_curr.clone(),
203+
adc.out0_volt.clone(),
204+
adc.out1_volt.clone(),
205+
adc.iobus_curr.clone(),
206+
adc.iobus_volt.clone(),
207+
adc.pwr_volt.clone(),
208+
adc.pwr_curr.clone(),
209+
];
210+
211+
let time = adc.time.clone();
198212

199213
// Spawn an async task to transfer values from the Atomic value based
200214
// "fast" interface to the broker based "slow" interface.
201215
spawn(async move {
202216
loop {
203217
sleep(SLOW_INTERVAL).await;
204218

205-
adc_clone
206-
.usb_host_curr
207-
.topic
208-
.set(adc_clone.usb_host_curr.fast.get());
209-
adc_clone
210-
.usb_host1_curr
211-
.topic
212-
.set(adc_clone.usb_host1_curr.fast.get());
213-
adc_clone
214-
.usb_host2_curr
215-
.topic
216-
.set(adc_clone.usb_host2_curr.fast.get());
217-
adc_clone
218-
.usb_host3_curr
219-
.topic
220-
.set(adc_clone.usb_host3_curr.fast.get());
221-
adc_clone
222-
.out0_volt
223-
.topic
224-
.set(adc_clone.out0_volt.fast.get());
225-
adc_clone
226-
.out1_volt
227-
.topic
228-
.set(adc_clone.out1_volt.fast.get());
229-
adc_clone
230-
.iobus_curr
231-
.topic
232-
.set(adc_clone.iobus_curr.fast.get());
233-
adc_clone
234-
.iobus_volt
235-
.topic
236-
.set(adc_clone.iobus_volt.fast.get());
237-
adc_clone.pwr_volt.topic.set(adc_clone.pwr_volt.fast.get());
238-
adc_clone.pwr_curr.topic.set(adc_clone.pwr_curr.fast.get());
239-
240-
adc_clone.time.set(Timestamp::now());
219+
for channel in &channels {
220+
if let Ok(val) = channel.fast.get() {
221+
// The adc channel topic should likely be wrapped in a Result
222+
// or otherwise be able to contain an error state.
223+
channel.topic.set(val)
224+
}
225+
}
226+
227+
time.set(Timestamp::now());
241228
}
242229
});
243230

src/adc/iio/demo_mode.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ use crate::measurement::{Measurement, Timestamp};
2929
// We need to somehow get the output states from digital_io/gpio/demo_mode.rs
3030
// to here. We could clobber the actual business code even more, or do dirty
3131
// mutable globals stuff.
32-
pub static DEMO_MAGIC: Mutex<Option<Arc<IioThread>>> = Mutex::new(None);
32+
pub static DEMO_MAGIC_STM32: Mutex<Option<Arc<IioThread>>> = Mutex::new(None);
33+
pub static DEMO_MAGIC_POWERBOARD: Mutex<Option<Arc<IioThread>>> = Mutex::new(None);
3334

3435
pub struct CalibratedChannelInner {
3536
name: &'static str,
@@ -97,18 +98,18 @@ impl CalibratedChannel {
9798
pub fn try_get_multiple<const N: usize>(
9899
&self,
99100
channels: [&Self; N],
100-
) -> Option<[Measurement; N]> {
101+
) -> Result<[Measurement; N]> {
101102
let ts = Timestamp::now();
102103
let mut results = [Measurement { ts, value: 0.0 }; N];
103104

104105
for i in 0..N {
105-
results[i].value = channels[i].get().value;
106+
results[i].value = channels[i].get().unwrap().value;
106107
}
107108

108-
Some(results)
109+
Ok(results)
109110
}
110111

111-
pub fn get(&self) -> Measurement {
112+
pub fn get(&self) -> Result<Measurement> {
112113
let ts = Timestamp::now();
113114

114115
let dt = {
@@ -134,13 +135,13 @@ impl CalibratedChannel {
134135
.inner
135136
.parents
136137
.iter()
137-
.map(|p| p.get().value)
138+
.map(|p| p.get().unwrap().value)
138139
.sum::<f32>();
139140
value += nominal;
140141

141142
self.inner.value.store(value.to_bits(), Ordering::Relaxed);
142143

143-
Measurement { ts, value }
144+
Ok(Measurement { ts, value })
144145
}
145146

146147
pub fn set(&self, state: bool) {
@@ -153,10 +154,10 @@ pub struct IioThread {
153154
}
154155

155156
impl IioThread {
156-
pub async fn new() -> Result<Arc<Self>> {
157-
let mut demo_magic = block_on(DEMO_MAGIC.lock());
157+
pub async fn new_stm32() -> Result<Arc<Self>> {
158+
let mut demo_magic = block_on(DEMO_MAGIC_STM32.lock());
158159

159-
// Only ever set up a single demo_mode "IioThread"
160+
// Only ever set up a single demo_mode "IioThread" per ADC
160161
if let Some(this) = &*demo_magic {
161162
return Ok(this.clone());
162163
}
@@ -179,6 +180,24 @@ impl IioThread {
179180
CalibratedChannel::with_exponential("out1-volt", 0.0, -3.3, 0.002, 0.2, 0.1),
180181
CalibratedChannel::with_exponential("iobus-curr", 0.15, 0.0, 0.001, 0.2, 0.01),
181182
CalibratedChannel::with_exponential("iobus-volt", 12.2, 0.0, 0.1, 0.2, 1.0),
183+
];
184+
185+
let this = Arc::new(Self { channels });
186+
187+
*demo_magic = Some(this.clone());
188+
189+
Ok(this)
190+
}
191+
192+
pub async fn new_powerboard() -> Result<Arc<Self>> {
193+
let mut demo_magic = block_on(DEMO_MAGIC_POWERBOARD.lock());
194+
195+
// Only ever set up a single demo_mode "IioThread" per ADC
196+
if let Some(this) = &*demo_magic {
197+
return Ok(this.clone());
198+
}
199+
200+
let channels = vec![
182201
CalibratedChannel::with_exponential("pwr-volt", 24.0, 0.0, 0.02, 0.2, 2.0),
183202
CalibratedChannel::with_exponential("pwr-curr", 1.2, 0.0, 0.002, 0.2, 0.01),
184203
];

0 commit comments

Comments
 (0)