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()
51            .load(firmware, None, Some(mcu), Some(frequency), None)
52            .flash_to(&mut avr);
53
54        // Safety: `avr` lives as long as `adc`, `spis` etc.
55        let adc = unsafe { Adc::new(&avr) };
56        let spis = unsafe { Self::init_spis(&avr) };
57        let twis = unsafe { Self::init_twis(&avr) };
58        let uarts = unsafe { Self::init_uarts(&mut avr) };
59
60        Self {
61            avr,
62            adc,
63            spis,
64            twis,
65            uarts,
66        }
67    }
68
69    unsafe fn init_spis(avr: &Avr) -> HashMap<u8, Spi> {
70        let mut spis = HashMap::new();
71
72        for id in 0..8 {
73            if let Some(spi) = unsafe { Spi::new(id, avr) } {
74                spis.insert(id, spi);
75            } else {
76                break;
77            }
78        }
79
80        spis
81    }
82
83    unsafe fn init_twis(avr: &Avr) -> HashMap<u8, Twi> {
84        let mut twis = HashMap::new();
85
86        for id in 0..8 {
87            if let Some(twi) = unsafe { Twi::new(id, avr) } {
88                twis.insert(id, twi);
89            } else {
90                break;
91            }
92        }
93
94        twis
95    }
96
97    unsafe fn init_uarts(avr: &mut Avr) -> HashMap<char, Uart> {
98        let mut uarts = HashMap::new();
99
100        for id in 0..8 {
101            let id = (b'0' + id) as char;
102
103            if let Some(uart) = unsafe { Uart::new(id, avr) } {
104                uarts.insert(id, uart);
105            } else {
106                break;
107            }
108        }
109
110        uarts
111    }
112
113    pub fn step(&mut self) -> StepOutcome {
114        for uart in self.uarts.values_mut() {
115            uart.flush();
116        }
117
118        let cycle = self.avr.cycle();
119        let state = self.avr.run();
120        let tt = (self.avr.cycle() - cycle).max(1);
121        let tt = AvrDuration::new(self.avr.frequency(), tt);
122
123        StepOutcome { state, tt }
124    }
125
126    pub fn read_spi(&mut self, id: u8) -> Option<u8> {
127        self.spi(id).read()
128    }
129
130    pub fn write_spi(&mut self, id: u8, byte: u8) {
131        self.spi(id).write(byte)
132    }
133
134    pub fn set_twi_slave(&mut self, id: u8, slave: impl TwiSlave + 'static) {
135        self.twi(id).set_slave(slave);
136    }
137
138    pub fn read_uart(&mut self, id: char) -> Option<u8> {
139        self.uart(id).read()
140    }
141
142    pub fn write_uart(&mut self, id: char, byte: u8) {
143        self.uart(id).write(byte)
144    }
145
146    pub fn get_digital_pin(&mut self, port: char, pin: u8) -> bool {
147        Port::get_pin(&mut self.avr, port, pin)
148    }
149
150    pub fn set_digital_pin(&mut self, port: char, pin: u8, high: bool) {
151        Port::set_pin(&self.avr, port, pin, high);
152    }
153
154    pub fn set_analog_pin(&mut self, pin: u8, voltage: u32) {
155        self.adc
156            .as_mut()
157            .expect("Current AVR doesn't have ADC")
158            .set_voltage(pin, voltage);
159    }
160
161    fn spi(&mut self, id: u8) -> &mut Spi {
162        self.spis
163            .get_mut(&id)
164            .unwrap_or_else(|| panic!("Current AVR doesn't have SPI{}", id))
165    }
166
167    fn twi(&mut self, id: u8) -> &mut Twi {
168        self.twis
169            .get_mut(&id)
170            .unwrap_or_else(|| panic!("Current AVR doesn't have TWI{}", id))
171    }
172
173    fn uart(&mut self, id: char) -> &mut Uart {
174        self.uarts
175            .get_mut(&id)
176            .unwrap_or_else(|| panic!("Current AVR doesn't have UART{}", id))
177    }
178}
179
180#[derive(Clone, Copy, Debug, PartialEq, Eq)]
181pub struct StepOutcome {
182    /// AVR's state after the instruction
183    pub state: AvrState,
184
185    /// How long it took to execute the instruction, in AVR cycles; approximate;
186    /// always greater than zero
187    pub tt: AvrDuration,
188}