Provide native APIs for I2C/SPI functionality currently handled by embedded-hal@0.2.x traits (#1386)

* Provide native APIs for SPI functionality currently handled by `embedded-hal` traits

* Provide APIs for I2C functionality currently handled by `embedded-hal` traits

* Rebase and update HIL test for SPI to get it building again
This commit is contained in:
Jesse Braham 2024-04-04 14:09:35 +00:00 committed by GitHub
parent bd9808827f
commit bf2cca90be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 77 additions and 20 deletions

View File

@ -191,6 +191,33 @@ pub struct I2C<'d, T, DM: crate::Mode> {
phantom: PhantomData<DM>,
}
impl<T, DM> I2C<'_, T, DM>
where
T: Instance,
DM: crate::Mode,
{
/// Reads enough bytes from slave with `address` to fill `buffer`
pub fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
self.peripheral.master_read(address, buffer)
}
/// Writes bytes to slave with address `address`
pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
self.peripheral.master_write(addr, bytes)
}
/// Writes bytes to slave with address `address` and then reads enough bytes
/// to fill `buffer` *in a single transaction*
pub fn write_read(
&mut self,
address: u8,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Error> {
self.peripheral.master_write_read(address, bytes, buffer)
}
}
#[cfg(feature = "embedded-hal-02")]
impl<T, DM: crate::Mode> embedded_hal_02::blocking::i2c::Read for I2C<'_, T, DM>
where
@ -199,7 +226,7 @@ where
type Error = Error;
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.peripheral.master_read(address, buffer)
self.read(address, buffer)
}
}
@ -211,7 +238,7 @@ where
type Error = Error;
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.peripheral.master_write(addr, bytes)
self.write(addr, bytes)
}
}
@ -228,7 +255,7 @@ where
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.peripheral.master_write_read(address, bytes, buffer)
self.write_read(address, bytes, buffer)
}
}

View File

@ -391,6 +391,46 @@ pub struct Spi<'d, T, M> {
_mode: PhantomData<M>,
}
impl<'d, T, M> Spi<'d, T, M>
where
T: Instance,
M: IsFullDuplex,
{
/// Read bytes from SPI.
///
/// Sends out a stuffing byte for every byte to read. This function doesn't
/// perform flushing. If you want to read the response to something you
/// have written before, consider using [`Self::transfer`] instead.
pub fn read_byte(&mut self) -> nb::Result<u8, Error> {
self.spi.read_byte()
}
/// Write a byte to SPI.
pub fn write_byte(&mut self, word: u8) -> nb::Result<(), Error> {
self.spi.write_byte(word)
}
/// Write bytes to SPI.
///
/// Copies the content of `words` in chunks of 64 bytes into the SPI
/// transmission FIFO. If `words` is longer than 64 bytes, multiple
/// sequential transfers are performed. This function will return before
/// all bytes of the last chunk to transmit have been sent to the wire. If
/// you must ensure that the whole messages was written correctly, use
/// [`Self::flush`].
pub fn write_bytes(&mut self, words: &[u8]) -> Result<(), Error> {
self.spi.write_bytes(words)?;
self.spi.flush()?;
Ok(())
}
/// Sends `words` to the slave. Returns the `words` received from the slave
pub fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Error> {
self.spi.transfer(words)
}
}
impl<'d, T> Spi<'d, T, FullDuplexMode>
where
T: Instance,
@ -736,11 +776,11 @@ where
type Error = Error;
fn read(&mut self) -> nb::Result<u8, Self::Error> {
self.spi.read_byte()
self.read_byte()
}
fn send(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.spi.write_byte(word)
self.write_byte(word)
}
}
@ -753,7 +793,7 @@ where
type Error = Error;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.spi.transfer(words)
self.transfer(words)
}
}
@ -766,9 +806,7 @@ where
type Error = Error;
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.spi.write_bytes(words)?;
self.spi.flush()?;
Ok(())
self.write_bytes(words)
}
}

View File

@ -7,12 +7,10 @@
//! - SCL => GPIO5
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use embedded_hal_02::blocking::i2c::WriteRead;
use esp_backtrace as _;
use esp_hal::{clock::ClockControl, gpio::IO, i2c::I2C, peripherals::Peripherals, prelude::*};
use esp_println::println;

View File

@ -14,12 +14,10 @@
//! data.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use embedded_hal_02::blocking::spi::Transfer;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,

View File

@ -66,8 +66,7 @@ mod tests {
let write = [0xde, 0xad, 0xbe, 0xef];
let mut read: [u8; 4] = [0x00u8; 4];
ctx.spi
.transfer(&mut read[..], &write[..])
SpiBus::transfer(&mut ctx.spi, &mut read[..], &write[..])
.expect("Symmetric transfer failed");
assert_eq!(write, read);
}
@ -77,8 +76,7 @@ mod tests {
let write = [0xde, 0xad, 0xbe, 0xef];
let mut read: [u8; 4] = [0x00; 4];
ctx.spi
.transfer(&mut read[0..2], &write[..])
SpiBus::transfer(&mut ctx.spi, &mut read[0..2], &write[..])
.expect("Asymmetric transfer failed");
assert_eq!(write[0], read[0]);
assert_eq!(read[2], 0x00u8);
@ -92,9 +90,7 @@ mod tests {
}
let mut read = [0x00u8; 4096];
ctx.spi
.transfer(&mut read[..], &write[..])
.expect("Huge transfer failed");
SpiBus::transfer(&mut ctx.spi, &mut read[..], &write[..]).expect("Huge transfer failed");
assert_eq!(write, read);
}