use crate::codegen::{extract_mcu_pins, generate_pins_rs, McuInfo};
use crate::netlist::Netlist;
use crate::parser::{Circuit, CircuitElement, Component, Net, Port};
pub fn chip(component_id: &str, name: &str) -> CircuitElement {
CircuitElement::Component(Component {
component_id: Some(component_id.to_string()),
kind: Some("chip".to_string()),
name: Some(name.to_string()),
})
}
pub fn net(net_id: &str, name: &str) -> CircuitElement {
CircuitElement::Net(Net {
net_id: Some(net_id.to_string()),
name: Some(name.to_string()),
})
}
pub fn port(port_id: &str, name: &str, net_id: &str, component: &str, pin: u32) -> CircuitElement {
CircuitElement::Port(Port {
port_id: Some(port_id.to_string()),
name: Some(name.to_string()),
net_id: Some(net_id.to_string()),
source_component_id: Some(component.to_string()),
pin_number: Some(pin),
..Default::default()
})
}
fn circuit(elements: Vec<CircuitElement>) -> Circuit {
Circuit {
elements,
raw_elements: Vec::new(),
}
}
pub fn mcu_circuit_fixture() -> Circuit {
circuit(vec![
chip("U1", "ESP32-S3"),
chip("CAM1", "OV2640"),
net("n_cam_d0", "CAM_D0"),
port("U1.GPIO4", "GPIO4", "n_cam_d0", "U1", 4),
port("CAM1.D0", "D0", "n_cam_d0", "CAM1", 1),
net("n_modem_tx", "MODEM_TX"),
port("U1.GPIO43", "GPIO43", "n_modem_tx", "U1", 43),
port("MODEM1.RXD", "RXD", "n_modem_tx", "MODEM1", 2),
])
}
pub fn mcu_with_nets(chip_name: &str, pins: &[(&str, &str, u32)]) -> Circuit {
let mut elements = vec![chip("U1", chip_name)];
for (i, (label, net_name, pin_number)) in pins.iter().enumerate() {
let net_id = format!("n{i}");
elements.push(net(&net_id, net_name));
elements.push(port(
&format!("U1.{label}"),
label,
&net_id,
"U1",
*pin_number,
));
elements.push(port(&format!("J{i}.1"), "A", &net_id, &format!("J{i}"), 1));
}
circuit(elements)
}
pub fn generate(
chip_name: &str,
target: Option<&str>,
pins: &[(&str, &str, u32)],
) -> (McuInfo, String) {
let circuit = mcu_with_nets(chip_name, pins);
let netlist = Netlist::from_circuit(&circuit);
let info = extract_mcu_pins(&circuit, &netlist, target).expect("MCU must be found");
let code = generate_pins_rs(&info, "Evil\nfn injected() {}");
(info, code)
}