use crate::soc::{Builder, Cpu, Error, Peripheral, Region, Soc, WriteModify};
use super::generated;
pub static MEMORY: [Region; 5] = [
Region::flash("flash", 0x0800_0000, 2 << 20),
Region::ram("ccm", 0x1000_0000, 64 << 10),
Region::system("system", 0x1FFF_0000, 32 << 10),
Region::ram("sram", 0x2000_0000, 192 << 10),
Region::ram("backup_sram", 0x4002_4000, 4 << 10),
];
const INTERRUPT_LINES: u16 = 91;
const SAI1_INTERRUPT: u16 = 87;
const DMA2D_INTERRUPT: u16 = 90;
pub static CPU: Cpu = Cpu {
interrupt_lines: INTERRUPT_LINES,
..generated::CPU
};
fn instances() -> impl Iterator<Item = Peripheral> {
generated::PERIPHERALS
.iter()
.map(|&peripheral| match peripheral.name {
"SAI1" => Peripheral {
interrupts: &[SAI1_INTERRUPT],
..peripheral
},
"DMA2D" => Peripheral {
interrupts: &[DMA2D_INTERRUPT],
..peripheral
},
_ => peripheral,
})
}
const TIMERS: [&str; 14] = [
"TIM1", "TIM2", "TIM3", "TIM4", "TIM5", "TIM6", "TIM7", "TIM8", "TIM9", "TIM10", "TIM11",
"TIM12", "TIM13", "TIM14",
];
pub fn builder() -> Builder {
TIMERS
.iter()
.fold(Soc::builder(CPU, &MEMORY, instances()), |builder, timer| {
builder.write_modify(timer, "SR", WriteModify::ZeroToClear)
})
}
pub fn soc() -> Result<Soc, Error> {
builder().build()
}
#[cfg(test)]
mod tests {
use crate::soc::{Layout, Width};
use super::generated::spi1;
use super::*;
use crate::time::VirtualNanos;
#[test]
fn the_soc_constructs_with_every_instance() {
let soc = soc().unwrap();
assert_eq!(soc.peripherals().count(), generated::PERIPHERALS.len());
assert_eq!(soc.cpu().interrupt_lines, INTERRUPT_LINES);
assert!(
soc.memory()
.iter()
.any(|region| region.name == "backup_sram")
);
}
#[test]
fn the_lines_the_vendor_omitted_are_filled_in() {
let soc = soc().unwrap();
assert_eq!(
soc.peripheral("SAI1")
.map(|peripheral| peripheral.interrupts),
Some(&[SAI1_INTERRUPT][..])
);
assert_eq!(
soc.peripheral("DMA2D")
.map(|peripheral| peripheral.interrupts),
Some(&[DMA2D_INTERRUPT][..])
);
assert!(
generated::SAI1.interrupts.is_empty(),
"the generated table is the vendor's, untouched"
);
}
#[test]
fn instances_derived_from_a_sibling_share_its_table() {
let soc = soc().unwrap();
let (spi1, spi2) = (
soc.peripheral("SPI1").unwrap(),
soc.peripheral("SPI2").unwrap(),
);
assert!(std::ptr::eq(spi1.registers, spi2.registers));
assert_eq!(spi2.base, 0x4000_3800);
}
#[test]
fn a_register_reads_its_reset_value_through_the_bus() {
let mut soc = soc().unwrap();
let status = generated::SPI1.base + u64::from(spi1::Register::Sr.spec().offset);
assert_eq!(
soc.read(VirtualNanos(0), status, Width::W32),
Ok(0x2),
"SPI_SR resets with TXE set, RM0090 28.5.3"
);
assert_eq!(spi1::cr1::SPE.bit, 6);
}
}