blob: 55973e189f4f6db562efc356f4c17dd7650c1b6d [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
use anyhow::Result;
use std::collections::HashMap;
use std::time::Duration;
use crate::chip::earlgrey::{PinmuxInsel, PinmuxMioOut, PinmuxOutsel, PinmuxPeripheralIn};
use crate::io::uart::Uart;
use crate::test_utils::e2e_command::TestCommand;
use crate::test_utils::rpc::{UartRecv, UartSend};
use crate::test_utils::status::Status;
// Bring in the auto-generated sources.
use crate::chip::earlgrey::ujson_alias::*;
include!(env!("pinmux_config"));
impl Default for PinmuxConfig {
fn default() -> Self {
Self {
input: PinmuxInputSelection {
peripheral: Default::default(),
selector: Default::default(),
},
output: PinmuxOutputSelection {
mio: Default::default(),
selector: Default::default(),
},
}
}
}
impl PinmuxConfig {
pub fn configure(
uart: &dyn Uart,
inputs: Option<&HashMap<PinmuxPeripheralIn, PinmuxInsel>>,
outputs: Option<&HashMap<PinmuxMioOut, PinmuxOutsel>>,
) -> Result<()> {
// The PinmuxConfig struct can carry a limited number of input
// and output configurations. We'll take the whole config and
// chunk it into as many PinmuxConfig commands as necessary.
let len = std::cmp::max(
inputs.map(|h| h.len()).unwrap_or(0),
outputs.map(|h| h.len()).unwrap_or(0),
);
let df_ik = PinmuxPeripheralIn::default();
let df_iv = PinmuxInsel::default();
let df_ok = PinmuxMioOut::default();
let df_ov = PinmuxOutsel::default();
let mut inputs = inputs.map(|h| h.iter());
let mut outputs = outputs.map(|h| h.iter());
let mut i = 0;
while i < len {
let mut config = Self::default();
for _ in 0..config.input.peripheral.capacity() {
let (ik, iv) = inputs
.as_mut()
.and_then(|i| i.next())
.unwrap_or((&df_ik, &df_iv));
let (ok, ov) = outputs
.as_mut()
.and_then(|i| i.next())
.unwrap_or((&df_ok, &df_ov));
config.input.peripheral.push(*ik);
config.input.selector.push(*iv);
config.output.mio.push(*ok);
config.output.selector.push(*ov);
i += 1;
}
TestCommand::PinmuxConfig.send(uart)?;
config.send(uart)?;
Status::recv(uart, Duration::from_secs(300), false)?;
}
Ok(())
}
}