1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
use crate::*;
/// Provides access to the SPI interface.
///
/// See: [`Spi::read()`] and [`Spi::write()`].
pub struct Spi<'a> {
sim: &'a mut AvrSimulator,
id: u8,
}
impl<'a> Spi<'a> {
pub(crate) fn new(sim: &'a mut AvrSimulator, id: u8) -> Self {
Self { sim, id }
}
/// Retrieves a value from AVR.
///
/// See: [`Readable`].
/// See also: [`Self::try_read_byte()`].
///
/// # Examples
///
/// ```no_run
/// # use avr_tester::*;
/// # fn avr() -> AvrTester { panic!() }
/// #
/// let mut avr = avr();
///
/// // Retrieves a single byte:
/// // (when the input buffer is empty, panics.)
/// assert_eq!(72, avr.spi0().read::<u8>());
///
/// // Retrieves the entire buffer:
/// // (when it's empty, returns an empty vector.)
/// assert_eq!(vec![72, 101, 108, 108, 111], avr.spi0().read::<Vec<u8>>());
///
/// // Retrieves `n` bytes from the buffer:
/// // (when there's not enough bytes, panics.)
/// assert_eq!([72, 101, 108, 108, 111], avr.spi0().read::<[u8; 5]>());
///
/// // Retrieves the entire input buffer and converts it into string:
/// // (when it's empty, returns an empty string.)
/// assert_eq!("Hello", avr.spi0().read::<String>());
/// ```
pub fn read<T>(&mut self) -> T
where
T: Readable,
{
T::read(self)
}
/// Transmits a value to AVR.
///
/// See: [`Writable`].
///
/// # Examples
///
/// ```no_run
/// # use avr_tester::*;
/// # fn avr() -> AvrTester { panic!() }
/// #
/// let mut avr = avr();
///
/// // Transmits a single byte:
/// avr.spi0().write(123);
///
/// // Transmits many bytes:
/// avr.spi0().write([10, 20, 30]);
///
/// // Transmits a string:
/// avr.spi0().write("Hello!");
///
/// // Strings are transmitted as a series of their bytes, so the above is
/// // equivalent to:
/// avr.spi0().write([72, 101, 108, 108, 111, 33]);
/// // H e l l o !
/// ```
pub fn write<T>(&mut self, value: T)
where
T: Writable,
{
value.write(self);
}
}
impl Reader for Spi<'_> {
fn read_byte(&mut self) -> u8 {
self.try_read_byte().expect(
"SPI's buffer is empty - got no more bytes to read; if you're \
receiving a large buffer, try running the simulator for a bit \
longer so that the simulated AVR has more time to respond",
)
}
fn try_read_byte(&mut self) -> Option<u8> {
self.sim.read_spi(self.id)
}
}
impl Writer for Spi<'_> {
fn write_byte(&mut self, value: u8) {
self.sim.write_spi(self.id, value);
}
}
/// Asynchronous equivalent of [`Spi`].
///
/// See [`avr_rt()`] for more details.
pub struct SpiAsync {
id: u8,
}
impl SpiAsync {
pub(crate) fn new(id: u8) -> Self {
Self { id }
}
/// Asynchronous equivalent of [`Spi::read()`].
pub fn read<T>(&self) -> T
where
T: Readable,
{
self.with(|spi| spi.read())
}
/// Asynchronous equivalent of [`Spi::write()`].
pub fn write<T>(&mut self, value: T)
where
T: Writable,
{
self.with(|spi| spi.write(value))
}
fn with<T>(&self, f: impl FnOnce(&mut Spi) -> T) -> T {
ComponentRuntime::with(|rt| {
let mut spi = Spi::new(rt.sim(), self.id);
f(&mut spi)
})
}
}
impl Reader for SpiAsync {
fn read_byte(&mut self) -> u8 {
self.with(|spi| spi.read_byte())
}
fn try_read_byte(&mut self) -> Option<u8> {
self.with(|spi| spi.try_read_byte())
}
}
impl Writer for SpiAsync {
fn write_byte(&mut self, value: u8) {
self.with(|spi| spi.write_byte(value))
}
}