1use crate::*;
2use std::convert::TryFrom;
3
4const MAX_SPIS: u8 = 6;
5
6#[derive(Debug)]
7pub struct SPI {
8 pub name_lower: String,
9 pub name_upper: String,
10 pub phase: Option<CLKPhase>,
11 pub polarity: Option<CLKPolarity>,
12 pub prescaler: BaudRatePrescaler,
13 pub baudrate: BaudRate,
14}
15
16pub fn get_spis(config: &ConfigParams<'_>) -> anyhow::Result<Vec<SPI>> {
17 let mut spis = Vec::new();
18
19 for i in 1..=MAX_SPIS {
20 let name_lower = f!("spi{i}");
21 let name_upper = name_lower.to_ascii_uppercase();
22
23 if let Some(spi_params) = config.get::<str>(&name_upper) {
25 let prescaler = parse_mandatory_param(spi_params, "BaudRatePrescaler")?;
26 let baudrate = parse_mandatory_param(spi_params, "CalculateBaudRate")?;
27 let phase = parse_optional_param(spi_params, "CLKPhase")?;
28 let polarity = parse_optional_param(spi_params, "CLKPolarity")?;
29
30 spis.push(SPI {
31 name_lower,
32 name_upper,
33 phase,
34 polarity,
35 prescaler,
36 baudrate,
37 });
38 }
39 }
40 Ok(spis)
41}
42
43#[derive(Debug, Copy, Clone, PartialEq)]
44pub struct BaudRate(pub u32);
45
46impl TryFrom<&str> for BaudRate {
47 type Error = anyhow::Error;
48
49 fn try_from(string: &str) -> Result<Self, Self::Error> {
50 let parts: Vec<&str> = string.split(' ').collect();
52
53 let (&freq, &unit) = match &parts[..] {
54 [freq, unit] => (freq, unit),
55 _ => bail!("{}", string),
56 };
57
58 let freq: f32 = freq
59 .parse()
60 .map_err(|_| anyhow!("{} invalid Baudrate", string))?;
61
62 let freq = match unit {
63 "MBits/s" => freq * 1_000_000f32,
64 "kBits/s" => freq * 1_000f32,
65 "Bits/s" => freq,
66 _ => bail!("Unknown unit {}", string),
67 };
68
69 Ok(BaudRate(freq as u32))
70 }
71}
72
73parameter!(
74 CLKPhase,
75 [SPI_PHASE_1EDGE, SPI_PHASE_2EDGE],
76 default = SPI_PHASE_1EDGE
77);
78
79parameter!(
80 CLKPolarity,
81 [SPI_POLARITY_LOW, SPI_POLARITY_HIGH],
82 default = SPI_POLARITY_LOW
83);
84
85parameter!(
86 BaudRatePrescaler,
87 [
88 SPI_BAUDRATEPRESCALER_2,
89 SPI_BAUDRATEPRESCALER_4,
90 SPI_BAUDRATEPRESCALER_8,
91 SPI_BAUDRATEPRESCALER_16,
92 SPI_BAUDRATEPRESCALER_32,
93 SPI_BAUDRATEPRESCALER_64,
94 SPI_BAUDRATEPRESCALER_128,
95 SPI_BAUDRATEPRESCALER_256
96 ]
97);