Skip to content

Commit e1e6ef5

Browse files
authored
Merge pull request #66 from hnez/gen3-explicit
Add LXA TAC hardware generation 3 support (explicit generation detection)
2 parents 002ba08 + 382ce79 commit e1e6ef5

File tree

14 files changed

+364
-163
lines changed

14 files changed

+364
-163
lines changed

openapi.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,21 @@ paths:
347347
schema:
348348
type: string
349349

350+
/v1/tac/info/hardware_generation:
351+
get:
352+
summary: Get the LXA TAC hardware generation
353+
tags: [System]
354+
responses:
355+
'200':
356+
content:
357+
application/json:
358+
schema:
359+
type: string
360+
enum:
361+
- Gen1
362+
- Gen2
363+
- Gen3
364+
350365
/v1/tac/setup_mode:
351366
get:
352367
summary: Check if the TAC has completed the set up or is still in setup mode

src/adc.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use async_std::task::sleep;
2323

2424
use crate::broker::{BrokerBuilder, Topic};
2525
use crate::measurement::{Measurement, Timestamp};
26+
use crate::system::HardwareGeneration;
2627
use crate::watched_tasks::WatchedTasksBuilder;
2728

2829
const HISTORY_LENGTH: usize = 200;
@@ -78,9 +79,13 @@ pub struct Adc {
7879
}
7980

8081
impl Adc {
81-
pub async fn new(bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder) -> Result<Self> {
82-
let stm32_thread = IioThread::new_stm32(wtb).await?;
83-
let powerboard_thread = IioThread::new_powerboard(wtb).await?;
82+
pub async fn new(
83+
bb: &mut BrokerBuilder,
84+
wtb: &mut WatchedTasksBuilder,
85+
hardware_generation: HardwareGeneration,
86+
) -> Result<Self> {
87+
let stm32_thread = IioThread::new_stm32(wtb, hardware_generation).await?;
88+
let powerboard_thread = IioThread::new_powerboard(wtb, hardware_generation).await?;
8489

8590
let adc = Self {
8691
usb_host_curr: AdcChannel {

src/adc/iio/demo_mode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ pub struct IioThread {
160160
}
161161

162162
impl IioThread {
163-
pub async fn new_stm32<W>(_wtb: &W) -> Result<Arc<Self>> {
163+
pub async fn new_stm32<W, G>(_wtb: &W, _hardware_generation: G) -> Result<Arc<Self>> {
164164
let mut demo_magic = block_on(DEMO_MAGIC_STM32.lock());
165165

166166
// Only ever set up a single demo_mode "IioThread" per ADC
@@ -195,7 +195,7 @@ impl IioThread {
195195
Ok(this)
196196
}
197197

198-
pub async fn new_powerboard<W>(_wtb: &W) -> Result<Arc<Self>> {
198+
pub async fn new_powerboard<W, G>(_wtb: &W, _hardware_generation: G) -> Result<Arc<Self>> {
199199
let mut demo_magic = block_on(DEMO_MAGIC_POWERBOARD.lock());
200200

201201
// Only ever set up a single demo_mode "IioThread" per ADC

src/adc/iio/hardware.rs

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -32,74 +32,12 @@ use log::{debug, error, warn};
3232
use thread_priority::*;
3333

3434
use crate::measurement::{Measurement, Timestamp};
35+
use crate::system::HardwareGeneration;
3536
use crate::watched_tasks::WatchedTasksBuilder;
3637

37-
struct ChannelDesc {
38-
kernel_name: &'static str,
39-
calibration_path: &'static str,
40-
name: &'static str,
41-
}
38+
mod channels;
4239

43-
// Hard coded list of channels using the internal STM32MP1 ADC.
44-
// Consists of the IIO channel name, the location of the calibration data
45-
// in the device tree and an internal name for the channel.
46-
const CHANNELS_STM32: &[ChannelDesc] = &[
47-
ChannelDesc {
48-
kernel_name: "voltage13",
49-
calibration_path: "baseboard-factory-data/usb-host-curr",
50-
name: "usb-host-curr",
51-
},
52-
ChannelDesc {
53-
kernel_name: "voltage15",
54-
calibration_path: "baseboard-factory-data/usb-host1-curr",
55-
name: "usb-host1-curr",
56-
},
57-
ChannelDesc {
58-
kernel_name: "voltage0",
59-
calibration_path: "baseboard-factory-data/usb-host2-curr",
60-
name: "usb-host2-curr",
61-
},
62-
ChannelDesc {
63-
kernel_name: "voltage1",
64-
calibration_path: "baseboard-factory-data/usb-host3-curr",
65-
name: "usb-host3-curr",
66-
},
67-
ChannelDesc {
68-
kernel_name: "voltage2",
69-
calibration_path: "baseboard-factory-data/out0-volt",
70-
name: "out0-volt",
71-
},
72-
ChannelDesc {
73-
kernel_name: "voltage10",
74-
calibration_path: "baseboard-factory-data/out1-volt",
75-
name: "out1-volt",
76-
},
77-
ChannelDesc {
78-
kernel_name: "voltage5",
79-
calibration_path: "baseboard-factory-data/iobus-curr",
80-
name: "iobus-curr",
81-
},
82-
ChannelDesc {
83-
kernel_name: "voltage9",
84-
calibration_path: "baseboard-factory-data/iobus-volt",
85-
name: "iobus-volt",
86-
},
87-
];
88-
89-
// The same as for the STM32MP1 channels but for the discrete ADC on the power
90-
// board.
91-
const CHANNELS_PWR: &[ChannelDesc] = &[
92-
ChannelDesc {
93-
kernel_name: "voltage",
94-
calibration_path: "powerboard-factory-data/pwr-volt",
95-
name: "pwr-volt",
96-
},
97-
ChannelDesc {
98-
kernel_name: "current",
99-
calibration_path: "powerboard-factory-data/pwr-curr",
100-
name: "pwr-curr",
101-
},
102-
];
40+
use channels::{ChannelDesc, Channels};
10341

10442
const TRIGGER_HR_PWR_DIR: &str = "/sys/kernel/config/iio/triggers/hrtimer/tacd-pwr";
10543

@@ -431,33 +369,43 @@ impl IioThread {
431369
Ok(thread)
432370
}
433371

434-
pub async fn new_stm32(wtb: &mut WatchedTasksBuilder) -> Result<Arc<Self>> {
372+
pub async fn new_stm32(
373+
wtb: &mut WatchedTasksBuilder,
374+
hardware_generation: HardwareGeneration,
375+
) -> Result<Arc<Self>> {
376+
let channels = hardware_generation.channels_stm32();
377+
435378
Self::new(
436379
wtb,
437380
"adc-stm32",
438381
"48003000.adc:adc@0",
439382
"tim4_trgo",
440383
80,
441-
CHANNELS_STM32,
384+
channels,
442385
4,
443386
)
444387
.await
445388
}
446389

447-
pub async fn new_powerboard(wtb: &mut WatchedTasksBuilder) -> Result<Arc<Self>> {
390+
pub async fn new_powerboard(
391+
wtb: &mut WatchedTasksBuilder,
392+
hardware_generation: HardwareGeneration,
393+
) -> Result<Arc<Self>> {
448394
let hr_trigger_path = Path::new(TRIGGER_HR_PWR_DIR);
449395

450396
if !hr_trigger_path.is_dir() {
451397
create_dir(hr_trigger_path)?;
452398
}
453399

400+
let channels = hardware_generation.channels_pwr();
401+
454402
Self::new(
455403
wtb,
456404
"adc-powerboard",
457405
"lmp92064",
458406
"tacd-pwr",
459407
20,
460-
CHANNELS_PWR,
408+
channels,
461409
1,
462410
)
463411
.await

src/adc/iio/hardware/channels.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
use crate::system::HardwareGeneration;
2+
3+
pub(super) struct ChannelDesc {
4+
pub kernel_name: &'static str,
5+
pub calibration_path: &'static str,
6+
pub name: &'static str,
7+
}
8+
9+
// Hard coded list of channels using the internal STM32MP1 ADC.
10+
// Consists of the IIO channel name, the location of the calibration data
11+
// in the device tree and an internal name for the channel.
12+
const CHANNELS_STM32_GEN1_GEN2: &[ChannelDesc] = &[
13+
ChannelDesc {
14+
kernel_name: "voltage13",
15+
calibration_path: "baseboard-factory-data/usb-host-curr",
16+
name: "usb-host-curr",
17+
},
18+
ChannelDesc {
19+
kernel_name: "voltage15",
20+
calibration_path: "baseboard-factory-data/usb-host1-curr",
21+
name: "usb-host1-curr",
22+
},
23+
ChannelDesc {
24+
kernel_name: "voltage0",
25+
calibration_path: "baseboard-factory-data/usb-host2-curr",
26+
name: "usb-host2-curr",
27+
},
28+
ChannelDesc {
29+
kernel_name: "voltage1",
30+
calibration_path: "baseboard-factory-data/usb-host3-curr",
31+
name: "usb-host3-curr",
32+
},
33+
ChannelDesc {
34+
kernel_name: "voltage2",
35+
calibration_path: "baseboard-factory-data/out0-volt",
36+
name: "out0-volt",
37+
},
38+
ChannelDesc {
39+
kernel_name: "voltage10",
40+
calibration_path: "baseboard-factory-data/out1-volt",
41+
name: "out1-volt",
42+
},
43+
ChannelDesc {
44+
kernel_name: "voltage5",
45+
calibration_path: "baseboard-factory-data/iobus-curr",
46+
name: "iobus-curr",
47+
},
48+
ChannelDesc {
49+
kernel_name: "voltage9",
50+
calibration_path: "baseboard-factory-data/iobus-volt",
51+
name: "iobus-volt",
52+
},
53+
];
54+
55+
const CHANNELS_STM32_GEN3: &[ChannelDesc] = &[
56+
ChannelDesc {
57+
kernel_name: "voltage13",
58+
calibration_path: "baseboard-factory-data/usb-host-curr",
59+
name: "usb-host-curr",
60+
},
61+
ChannelDesc {
62+
kernel_name: "voltage15",
63+
calibration_path: "baseboard-factory-data/usb-host1-curr",
64+
name: "usb-host1-curr",
65+
},
66+
ChannelDesc {
67+
kernel_name: "voltage18",
68+
calibration_path: "baseboard-factory-data/usb-host2-curr",
69+
name: "usb-host2-curr",
70+
},
71+
ChannelDesc {
72+
kernel_name: "voltage14",
73+
calibration_path: "baseboard-factory-data/usb-host3-curr",
74+
name: "usb-host3-curr",
75+
},
76+
ChannelDesc {
77+
kernel_name: "voltage2",
78+
calibration_path: "baseboard-factory-data/out0-volt",
79+
name: "out0-volt",
80+
},
81+
ChannelDesc {
82+
kernel_name: "voltage10",
83+
calibration_path: "baseboard-factory-data/out1-volt",
84+
name: "out1-volt",
85+
},
86+
ChannelDesc {
87+
kernel_name: "voltage5",
88+
calibration_path: "baseboard-factory-data/iobus-curr",
89+
name: "iobus-curr",
90+
},
91+
ChannelDesc {
92+
kernel_name: "voltage9",
93+
calibration_path: "baseboard-factory-data/iobus-volt",
94+
name: "iobus-volt",
95+
},
96+
];
97+
98+
// The same as for the STM32MP1 channels but for the discrete ADC on the power
99+
// board.
100+
const CHANNELS_PWR: &[ChannelDesc] = &[
101+
ChannelDesc {
102+
kernel_name: "voltage",
103+
calibration_path: "powerboard-factory-data/pwr-volt",
104+
name: "pwr-volt",
105+
},
106+
ChannelDesc {
107+
kernel_name: "current",
108+
calibration_path: "powerboard-factory-data/pwr-curr",
109+
name: "pwr-curr",
110+
},
111+
];
112+
113+
pub(super) trait Channels {
114+
fn channels_stm32(&self) -> &'static [ChannelDesc];
115+
fn channels_pwr(&self) -> &'static [ChannelDesc];
116+
}
117+
118+
impl Channels for HardwareGeneration {
119+
fn channels_stm32(&self) -> &'static [ChannelDesc] {
120+
// LXA TAC hardware generation 3 has move some of the ADC channels around
121+
// so that channel 0 and 1 are no longer used.
122+
// Channel 0 and 1 are special in that they do not use the pinmuxing support
123+
// of the STM32MP1 SoC.
124+
// Instead they are always connected to the ADC.
125+
// This causes issues when the ADC peripheral is put into stanby,
126+
// because current will leak into these pins in that case.
127+
128+
match self {
129+
HardwareGeneration::Gen1 | HardwareGeneration::Gen2 => CHANNELS_STM32_GEN1_GEN2,
130+
HardwareGeneration::Gen3 => CHANNELS_STM32_GEN3,
131+
}
132+
}
133+
134+
fn channels_pwr(&self) -> &'static [ChannelDesc] {
135+
// The pin assignment of the power board is currently independent from the
136+
// hardware generation.
137+
CHANNELS_PWR
138+
}
139+
}

src/adc/iio/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub struct IioThread {
107107
}
108108

109109
impl IioThread {
110-
pub async fn new_stm32<W>(_wtb: &W) -> Result<Arc<Self>> {
110+
pub async fn new_stm32<W, G>(_wtb: &W, _hardware_generation: G) -> Result<Arc<Self>> {
111111
let mut channels = Vec::new();
112112

113113
for name in CHANNELS_STM32 {
@@ -117,7 +117,7 @@ impl IioThread {
117117
Ok(Arc::new(Self { channels }))
118118
}
119119

120-
pub async fn new_powerboard<W>(_wtb: &W) -> Result<Arc<Self>> {
120+
pub async fn new_powerboard<W, G>(_wtb: &W, _hardware_generation: G) -> Result<Arc<Self>> {
121121
let mut channels = Vec::new();
122122

123123
for name in CHANNELS_PWR {

src/digital_io/gpio/demo_mode.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ impl LineHandle {
3232
// It is just a hack to let adc/iio/demo_mode.rs
3333
// communicate with this function so that toggling an output
3434
// has an effect on the measured values.
35-
let iio_thread_stm32 = block_on(IioThread::new_stm32(&())).unwrap();
36-
let iio_thread_pwr = block_on(IioThread::new_powerboard(&())).unwrap();
35+
let iio_thread_stm32 = block_on(IioThread::new_stm32(&(), ())).unwrap();
36+
let iio_thread_pwr = block_on(IioThread::new_powerboard(&(), ())).unwrap();
3737

3838
match self.name.as_str() {
3939
"OUT_0" => iio_thread_stm32
@@ -80,14 +80,6 @@ impl BitOr for LineRequestFlags {
8080
}
8181
}
8282

83-
pub struct ChipDecoy;
84-
85-
impl ChipDecoy {
86-
pub fn label(&self) -> &'static str {
87-
"demo_mode"
88-
}
89-
}
90-
9183
pub struct FindDecoy {
9284
name: String,
9385
}
@@ -102,10 +94,6 @@ impl FindDecoy {
10294

10395
Ok(line_handle)
10496
}
105-
106-
pub fn chip(&self) -> ChipDecoy {
107-
ChipDecoy
108-
}
10997
}
11098

11199
pub fn find_line(name: &str) -> Option<FindDecoy> {

0 commit comments

Comments
 (0)