opentitanlib/test_utils/
pinmux_config.rs1use std::cmp;
6use std::collections::HashMap;
7use std::time::Duration;
8
9use anyhow::Result;
10
11use ot_hal::dif::pinmux::PinmuxPadAttr;
12use ot_hal::top::earlgrey::{PinmuxInsel, PinmuxMioOut, PinmuxOutsel, PinmuxPeripheralIn};
13
14use crate::io::uart::Uart;
15use crate::test_utils::e2e_command::TestCommand;
16use crate::test_utils::rpc::{ConsoleRecv, ConsoleSend};
17use crate::test_utils::status::Status;
18
19#[allow(non_camel_case_types)]
22type pinmux_peripheral_in_t = PinmuxPeripheralIn;
23#[allow(non_camel_case_types)]
24type pinmux_insel_t = PinmuxInsel;
25#[allow(non_camel_case_types)]
26type pinmux_mio_out_t = PinmuxMioOut;
27#[allow(non_camel_case_types)]
28type pinmux_outsel_t = PinmuxOutsel;
29
30include!(env!("pinmux_config"));
32
33const CONFIG_CAP: usize = 16;
35
36impl PinmuxConfig {
37 pub fn configure(
38 uart: &dyn Uart,
39 inputs: Option<&HashMap<PinmuxPeripheralIn, PinmuxInsel>>,
40 outputs: Option<&HashMap<PinmuxMioOut, PinmuxOutsel>>,
41 attrs: Option<&HashMap<PinmuxMioOut, PinmuxPadAttr>>,
42 ) -> Result<()> {
43 let mut inputs: Vec<_> = inputs
48 .into_iter()
49 .flat_map(HashMap::iter)
50 .map(|(&key, &value)| (key, value))
51 .collect();
52 let mut outputs: Vec<_> = outputs
53 .into_iter()
54 .flat_map(HashMap::iter)
55 .map(|(&key, &value)| (key, value))
56 .collect();
57 let mut attrs: Vec<_> = attrs
58 .into_iter()
59 .flat_map(HashMap::iter)
60 .map(|(&key, &value)| (key, value.bits()))
61 .collect();
62
63 let len = cmp::max(cmp::max(inputs.len(), outputs.len()), attrs.len())
64 .next_multiple_of(CONFIG_CAP);
65
66 inputs.resize_with(len, Default::default);
67 outputs.resize_with(len, Default::default);
68 attrs.resize_with(len, Default::default);
69
70 while !inputs.is_empty() && !outputs.is_empty() && !attrs.is_empty() {
71 let (in_peripherals, in_selectors) = inputs.drain(..CONFIG_CAP).unzip();
72 let (out_mios, out_selectors) = outputs.drain(..CONFIG_CAP).unzip();
73 let (attr_mios, attr_flags) = attrs.drain(..CONFIG_CAP).unzip();
74
75 let config = PinmuxConfig {
76 input: PinmuxInputSelection {
77 peripheral: in_peripherals,
78 selector: in_selectors,
79 },
80 output: PinmuxOutputSelection {
81 mio: out_mios,
82 selector: out_selectors,
83 },
84 attrs: PinmuxAttrConfig {
85 mio: attr_mios,
86 flags: attr_flags,
87 },
88 };
89
90 TestCommand::PinmuxConfig.send(uart)?;
91 config.send(uart)?;
92 Status::recv(uart, Duration::from_secs(300), false)?;
93 }
94
95 Ok(())
96 }
97}