WMT-GmbH / pn532

no_std implementation of the Pn532 protocol using embedded_hal traits
Apache License 2.0
20 stars 19 forks source link

How to use i2c interface with esp-idf-hal? #6

Open JohnTheCoolingFan opened 1 year ago

JohnTheCoolingFan commented 1 year ago

esp-idf-hal is implementation of embedded-hal for esp32. I cannot find any type that implements i2c::Transactional from embedded_hal. Am I missing something?

dimpolo commented 1 year ago

Thanks for the report!

I looked around the esp-idf-hal a bit, you're not missing anything 😃.

Basically we have three options here:

The one where I do the work:

I2CDriver does have an impl of the embedded-hal v1.0.0 version of the I2c trait and that trait includes a transaction method. We could add a eh1 feature flag I2CInterface in terms of the new trait.

I definitely want to make this happen but I won't get to this until in a couple of weeks. (I would of course welcome a PR 😉)

The one where the esp crew does the work:

You could open an issue over there asking for an implementation of Transactional (or even write a PR yourself). They have been very helpful and open to suggestions in my experience.

The one where you do the work:

You can implement Interface yourself on a wrapper type of I2CDriver.

struct I2CWrapper<'a>(I2CDriver<'a>);

impl<'a> pn532::Interface for I2CWrapper<'a> {
    ...
}

You can have a look at https://github.com/WMT-GmbH/pn532/blob/master/src/i2c.rs#L30-L60. I'll be glad to help you out if questions come up.

JohnTheCoolingFan commented 1 year ago

Thank you for such a great reply! I'll report it to esp crew and maybe do a PR, as I think that's an error from their side.

liebman commented 5 months ago

Will be fixed "soon-ish": https://github.com/esp-rs/esp-hal/pull/1505

dimpolo commented 5 months ago

Thanks for your work!

LimesKey commented 4 months ago

I'm having some issues doing this fix,


    struct I2CWrapper<'a>(I2cDriver<'a>);

    impl<'a> pn532::Interface for I2CWrapper<'a> {
        type Error = ErrorKind;

        fn write(&mut self, frame: &[u8]) -> Result<(), Self::Error> {
            I2CWrapper::write(self, frame)
        }

        fn wait_ready(&mut self) -> Poll<Result<(), Self::Error>> {
            I2CWrapper::wait_ready(self)
        }

        fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
            I2CWrapper::read(self, buf)
        }
    }

    let mut pn532 = Pn532::new(I2CWrapper(i2cdriver), config);
    if let Err(e) = pn532.process(&Request::sam_configuration(SAMMode::Normal, false), 0, 50.ms()){

I'm getting, the method process exists for struct Pn532<I2CWrapper<'_>, Config, _>, but its trait bounds were not satisfied the following trait bounds were not satisfied: esp_idf_svc::hal::i2c::config::Config: embedded_hal::timer::CountDown, on "process".

liebman commented 4 months ago

Pn532 needs to implement for embedded-hal 1.0 traits.