use crate::util::parse_khz;
use espf::context::ParsedNode;
use espf::diag::EspfError;
use espforge_bindings::components::attrs::Issue;
use espforge_bindings::components::generated_elements::i2c as schema;
#[derive(Debug, Clone)]
pub struct I2cPeripheral {
pub id: String,
pub peripheral: String,
pub sda: u8,
pub scl: u8,
pub khz: u32,
}
fn i2c_peripheral_name(n: &ParsedNode) -> Result<String, EspfError> {
let id = n.id;
if id == "i2c0" || id == "i2c1" || id == "i2c2" {
return Ok(id.to_ascii_uppercase());
}
Err(EspfError::at_node(
n,
"invalid i2c id",
format!("<i2c id=\"{id}\">: the id must be i2c0, i2c1 or i2c2"),
))
}
pub fn lower_i2c(n: &ParsedNode) -> Result<I2cPeripheral, EspfError> {
let attrs = schema::Attrs::from_node(n)
.map_err(|issue| EspfError::at_node(n, "invalid i2c pin", message(n.id, issue)))?;
let khz = parse_khz(attrs.frequency.value, "i2c", n.id)
.map_err(|m| EspfError::at_node(n, "invalid i2c frequency", m))?;
Ok(I2cPeripheral {
id: n.id.to_string(),
peripheral: i2c_peripheral_name(n)?,
sda: attrs.sda.value,
scl: attrs.scl.value,
khz,
})
}
fn message(id: &str, issue: Issue<'_>) -> String {
match issue {
Issue::Missing { attr } | Issue::Invalid { attr, .. } => {
format!("<i2c id=\"{id}\"> needs a numeric {attr}=\"...\"")
}
}
}