cube2rust/
spi.rs

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        // search config for SPI1, SPI2, etc..
24        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        // string looks like this 3.0 MBits/s
51        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);