| // 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(()) |
| } |
| } |