use std::num::{NonZeroU32, NonZeroU64};
use crate::machine::{Machine, Target};
use crate::sidecar::InterruptLine;
use crate::soc::Error;
use crate::machine::armv7m;
use crate::soc::stm32f427;
use crate::soc::stm32f427::peripherals::gpio::Gpio;
use crate::soc::stm32f427::peripherals::tim::Tim;
pub const NAME: &str = "pixracer";
pub const MCU: &str = "stm32f427";
const CLOCK_HZ: NonZeroU64 = NonZeroU64::new(168_000_000).expect("a running clock");
const REFCLK_DIVIDER: NonZeroU32 = NonZeroU32::new(8).expect("a divider divides");
const PRIORITY_BITS: u8 = 4;
const BOOT: &str = "flash";
const ICOUNT_SHIFT: u32 = 2;
const TIM2_CLOCK_HZ: NonZeroU64 = NonZeroU64::new(16_000_000).expect("sixteen million");
pub fn machine() -> Result<Machine, Error> {
let soc = stm32f427::builder()
.bind("GPIOA", Gpio::default())
.bind("TIM2", Tim::with_clock(TIM2_CLOCK_HZ))
.build()?;
let sidecar = armv7m::Core {
model: armv7m::Model::M4,
clock_hz: CLOCK_HZ,
interrupt_lines: NonZeroU32::new(u32::from(soc.cpu().interrupt_lines))
.expect("an SoC with interrupts"),
priority_bits: PRIORITY_BITS,
refclk_divider: REFCLK_DIVIDER,
icount_shift: ICOUNT_SHIFT,
boot: BOOT,
}
.command();
Ok(Machine {
name: NAME,
targets: vec![Target {
name: MCU,
soc,
sidecar,
interrupt_line: InterruptLine::new,
}],
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_machine_routes_every_cpu_line_and_no_more() {
let machine = machine().unwrap();
let [target] = &machine.targets[..] else {
panic!("one MCU on the board");
};
let lines = target.soc.cpu().interrupt_lines;
assert!((target.interrupt_line)(lines - 1).is_some());
assert_eq!(machine.name, NAME);
assert_eq!(target.sidecar.binary, armv7m::BINARY);
}
#[test]
fn the_machine_takes_its_interrupt_count_from_the_part() {
let machine = machine().unwrap();
let target = &machine.targets[0];
let declared = target
.sidecar
.properties
.iter()
.find(|property| property.name == "num-irq")
.expect("the machine is told its interrupt count");
assert_eq!(
declared.value,
target.soc.cpu().interrupt_lines.to_string(),
"the count the engine is given is the count the SoC has"
);
}
}