avr_simulator/
lib.rs

1//! Oxidized interface for simavr.
2//!
3//! The main purpose of this crate is to serve as a building block for the
4//! `avr-tester` crate, providing a safe and curated access to simavr.
5//!
6//! See: [`AvrSimulator::new()`].
7
8mod adc;
9mod avr;
10mod duration;
11mod firmware;
12mod ioctl;
13mod logging;
14mod port;
15mod spi;
16mod state;
17mod twi;
18mod uart;
19
20use self::adc::*;
21use self::avr::*;
22pub use self::duration::*;
23use self::firmware::*;
24use self::ioctl::*;
25use self::port::*;
26use self::spi::*;
27pub use self::state::*;
28use self::twi::*;
29pub use self::twi::{TwiPacket, TwiSlave};
30use self::uart::*;
31pub use simavr_ffi as ffi;
32use std::collections::HashMap;
33use std::path::Path;
34
35#[derive(Debug)]
36pub struct AvrSimulator {
37    avr: Avr,
38    adc: Option<Adc>,
39    spis: HashMap<u8, Spi>,
40    twis: HashMap<u8, Twi>,
41    uarts: HashMap<char, Uart>,
42}
43
44impl AvrSimulator {
45    pub fn new(mcu: &str, frequency: u32, firmware: impl AsRef<Path>) -> Self {
46        logging::init();
47
48        let mut avr = Avr::new(mcu, frequency);
49
50        Firmware::new().load_elf(firmware).flash_to(&mut avr);
51
52        // Safety: `avr` lives as long as `adc`, `spis` etc.
53        let adc = unsafe { Adc::new(&avr) };
54        let spis = unsafe { Self::init_spis(&avr) };
55        let twis = unsafe { Self::init_twis(&avr) };
56        let uarts = unsafe { Self::init_uarts(&mut avr) };
57
58        Self {
59            avr,
60            adc,
61            spis,
62            twis,
63            uarts,
64        }
65    }
66
67    unsafe fn init_spis(avr: &Avr) -> HashMap<u8, Spi> {
68        let mut spis = HashMap::new();
69
70        for id in 0..8 {
71            if let Some(spi) = Spi::new(id, avr) {
72                spis.insert(id, spi);
73            } else {
74                break;
75            }
76        }
77
78        spis
79    }
80
81    unsafe fn init_twis(avr: &Avr) -> HashMap<u8, Twi> {
82        let mut twis = HashMap::new();
83
84        for id in 0..8 {
85            if let Some(twi) = Twi::new(id, avr) {
86                twis.insert(id, twi);
87            } else {
88                break;
89            }
90        }
91
92        twis
93    }
94
95    unsafe fn init_uarts(avr: &mut Avr) -> HashMap<char, Uart> {
96        let mut uarts = HashMap::new();
97
98        for id in 0..8 {
99            let id = (b'0' + id) as char;
100
101            if let Some(uart) = Uart::new(id, avr) {
102                uarts.insert(id, uart);
103            } else {
104                break;
105            }
106        }
107
108        uarts
109    }
110
111    pub fn step(&mut self) -> StepOutcome {
112        for spi in self.spis.values_mut() {
113            spi.flush();
114        }
115
116        for uart in self.uarts.values_mut() {
117            uart.flush();
118        }
119
120        let cycle = self.avr.cycle();
121        let state = self.avr.run();
122        let tt = (self.avr.cycle() - cycle).max(1);
123        let tt = AvrDuration::new(self.avr.frequency(), tt);
124
125        for spi in self.spis.values_mut() {
126            spi.tick(tt.as_cycles());
127        }
128
129        StepOutcome { state, tt }
130    }
131
132    pub fn read_spi(&mut self, id: u8) -> Option<u8> {
133        self.spi(id).read()
134    }
135
136    pub fn write_spi(&mut self, id: u8, byte: u8) {
137        self.spi(id).write(byte)
138    }
139
140    pub fn set_twi_slave(&mut self, id: u8, slave: impl TwiSlave + 'static) {
141        self.twi(id).set_slave(slave);
142    }
143
144    pub fn read_uart(&mut self, id: char) -> Option<u8> {
145        self.uart(id).read()
146    }
147
148    pub fn write_uart(&mut self, id: char, byte: u8) {
149        self.uart(id).write(byte)
150    }
151
152    pub fn get_digital_pin(&mut self, port: char, pin: u8) -> bool {
153        Port::get_pin(&mut self.avr, port, pin)
154    }
155
156    pub fn set_digital_pin(&mut self, port: char, pin: u8, high: bool) {
157        Port::set_pin(&self.avr, port, pin, high);
158    }
159
160    pub fn set_analog_pin(&mut self, pin: u8, voltage: u32) {
161        self.adc
162            .as_mut()
163            .expect("Current AVR doesn't have ADC")
164            .set_voltage(pin, voltage);
165    }
166
167    fn spi(&mut self, id: u8) -> &mut Spi {
168        self.spis
169            .get_mut(&id)
170            .unwrap_or_else(|| panic!("Current AVR doesn't have SPI{}", id))
171    }
172
173    fn twi(&mut self, id: u8) -> &mut Twi {
174        self.twis
175            .get_mut(&id)
176            .unwrap_or_else(|| panic!("Current AVR doesn't have TWI{}", id))
177    }
178
179    fn uart(&mut self, id: char) -> &mut Uart {
180        self.uarts
181            .get_mut(&id)
182            .unwrap_or_else(|| panic!("Current AVR doesn't have UART{}", id))
183    }
184}
185
186#[derive(Clone, Copy, Debug, PartialEq, Eq)]
187pub struct StepOutcome {
188    /// AVR's state after the instruction
189    pub state: AvrState,
190
191    /// How long it took to execute the instruction, in AVR cycles; approximate;
192    /// always greater than zero
193    pub tt: AvrDuration,
194}