embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.31k stars 732 forks source link

stm32: I2C "transaction" not supported #1417

Open ctron opened 1 year ago

ctron commented 1 year ago

The "transaction" functions of STM32 still seems to be contain todo!.

ctron commented 1 year ago

Having the ability to perform two read operations seems to be a requirement for the default PN532 firmware.

sgoll commented 6 months ago

@Dirbaio Out of curiosity, what is the current state of I2C transaction support? Is there a rough draft somewhere how one possible implementation could or should look like?

I am asking because I would be willing to flesh out an implementation (at least for I2C v1 because that is the only platform that I have hardware access to) but I'm unsure if there exists some exploratory prior art that should be considered, e.g. an implementation sketch or some draft of a possible internal interface.

I have seen that for I2C v2, there already exist some methods that could be used in the transactions implementation, such as the vectored methods write_vectored()/blocking_write_vectored().

The main issue is that we cannot easily get slices of &[&[u8]] from adjacent &[Operation] elements. So I was starting to think along the lines of some internal helper trait such as AsOperation, to avoid using the embedded_hal structs directly within the implementations.

// mod.rs

pub trait AsOperation {
    fn as_operation(&mut self) -> Operation;
}

pub enum Operation<'a> {
    Read(&'a mut [u8]),
    Write(&'a [u8]),
}

impl AsOperation for embedded_hal_1::i2c::Operation<'_> {
    fn as_operation(&mut self) -> Operation {
        match self {
            embedded_hal_1::i2c::Operation::Read(read) => Operation::Read(read),
            embedded_hal_1::i2c::Operation::Write(write) => Operation::Write(write),
        }
    }
}

// v1.rs

impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
    pub fn blocking_transaction<O: AsOperation>(&mut self, addr: u8, operations: &mut [O]) -> Result<(), Error> {
        todo!()
    }
}
Dirbaio commented 6 months ago

There's been no work on this afaik, so a PR would be very welcome :)

maybe I'd avoid the complexity of defining our own Operation and converting? since embedded-hal 1.0 is supposed to be "stable forever" maybe we can just reexport embedded-hal's.