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:
parent
bd9808827f
commit
bf2cca90be
@ -191,6 +191,33 @@ pub struct I2C<'d, T, DM: crate::Mode> {
|
|||||||
phantom: PhantomData<DM>,
|
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")]
|
#[cfg(feature = "embedded-hal-02")]
|
||||||
impl<T, DM: crate::Mode> embedded_hal_02::blocking::i2c::Read for I2C<'_, T, DM>
|
impl<T, DM: crate::Mode> embedded_hal_02::blocking::i2c::Read for I2C<'_, T, DM>
|
||||||
where
|
where
|
||||||
@ -199,7 +226,7 @@ where
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::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;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::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],
|
bytes: &[u8],
|
||||||
buffer: &mut [u8],
|
buffer: &mut [u8],
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
self.peripheral.master_write_read(address, bytes, buffer)
|
self.write_read(address, bytes, buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -391,6 +391,46 @@ pub struct Spi<'d, T, M> {
|
|||||||
_mode: PhantomData<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>
|
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
||||||
where
|
where
|
||||||
T: Instance,
|
T: Instance,
|
||||||
@ -736,11 +776,11 @@ where
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn read(&mut self) -> nb::Result<u8, Self::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> {
|
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;
|
type Error = Error;
|
||||||
|
|
||||||
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::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;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
||||||
self.spi.write_bytes(words)?;
|
self.write_bytes(words)
|
||||||
self.spi.flush()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,12 +7,10 @@
|
|||||||
//! - SCL => GPIO5
|
//! - SCL => GPIO5
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embedded-hal-02
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal_02::blocking::i2c::WriteRead;
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{clock::ClockControl, gpio::IO, i2c::I2C, peripherals::Peripherals, prelude::*};
|
use esp_hal::{clock::ClockControl, gpio::IO, i2c::I2C, peripherals::Peripherals, prelude::*};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
|
|||||||
@ -14,12 +14,10 @@
|
|||||||
//! data.
|
//! data.
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embedded-hal-02
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal_02::blocking::spi::Transfer;
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
|
|||||||
@ -66,8 +66,7 @@ mod tests {
|
|||||||
let write = [0xde, 0xad, 0xbe, 0xef];
|
let write = [0xde, 0xad, 0xbe, 0xef];
|
||||||
let mut read: [u8; 4] = [0x00u8; 4];
|
let mut read: [u8; 4] = [0x00u8; 4];
|
||||||
|
|
||||||
ctx.spi
|
SpiBus::transfer(&mut ctx.spi, &mut read[..], &write[..])
|
||||||
.transfer(&mut read[..], &write[..])
|
|
||||||
.expect("Symmetric transfer failed");
|
.expect("Symmetric transfer failed");
|
||||||
assert_eq!(write, read);
|
assert_eq!(write, read);
|
||||||
}
|
}
|
||||||
@ -77,8 +76,7 @@ mod tests {
|
|||||||
let write = [0xde, 0xad, 0xbe, 0xef];
|
let write = [0xde, 0xad, 0xbe, 0xef];
|
||||||
let mut read: [u8; 4] = [0x00; 4];
|
let mut read: [u8; 4] = [0x00; 4];
|
||||||
|
|
||||||
ctx.spi
|
SpiBus::transfer(&mut ctx.spi, &mut read[0..2], &write[..])
|
||||||
.transfer(&mut read[0..2], &write[..])
|
|
||||||
.expect("Asymmetric transfer failed");
|
.expect("Asymmetric transfer failed");
|
||||||
assert_eq!(write[0], read[0]);
|
assert_eq!(write[0], read[0]);
|
||||||
assert_eq!(read[2], 0x00u8);
|
assert_eq!(read[2], 0x00u8);
|
||||||
@ -92,9 +90,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
let mut read = [0x00u8; 4096];
|
let mut read = [0x00u8; 4096];
|
||||||
|
|
||||||
ctx.spi
|
SpiBus::transfer(&mut ctx.spi, &mut read[..], &write[..]).expect("Huge transfer failed");
|
||||||
.transfer(&mut read[..], &write[..])
|
|
||||||
.expect("Huge transfer failed");
|
|
||||||
assert_eq!(write, read);
|
assert_eq!(write, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user