Skip to content

(embassy-rp): Add I2C master implementation #914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 27, 2022

Conversation

MathiasKoch
Copy link
Contributor

@MathiasKoch MathiasKoch commented Aug 19, 2022

This PR adds both blocking and DMA based async implementations of I2C master.

Both E-H 0.2 & E-H 1.0 abstractions are implemented as well.

Questions & concerns:

@MathiasKoch MathiasKoch changed the title (embassy-rp): Add I2C implementation (embassy-rp): Add I2C master implementation Aug 29, 2022
@Dirbaio
Copy link
Member

Dirbaio commented Aug 30, 2022

Do we need an I2C interrupt handler (for transfer done, abort & error handling?) (async only)

I dunno the hardware details. It's possible that if you wait just for rxing the data, the bus takes a bit more time to become idle (for example to do the stop condition). The current embedded-hal trait says nothing about how to handle that, the new trait rust-embedded/embedded-hal#392 has a flush method to force waiting until bus idle, so maybe that'll need the interrupt?

Do we need to add some automatic attempt at unblocking an I2C bus in case of failures (see ref: https://github.com/fivdi/pico-i2c-dma/blob/7ebfd553f3ce5b5b210d53102b0ecca158172633/src/i2c_dma.c#L116-L142)

I think that's to workaround i2c devices on the bus getting stuck, not the i2c master peripheral itself getting stuck, right? In that case I'd say no. nrf and stm32 doesn't have that either. Also the user can implement that on their own with GPIO (I've done it for the nRF once).

Should I add vectored_{read, write} implementations?

probably best not to do it for now. I'd wait until the new i2c trait is in rust-embedded/embedded-hal#392, that'll allow transferring multiple buffers in a single transaction without vectored_* stuff.

Copy link
Contributor

@Jacobious52 Jacobious52 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed a few things using this PR to get some simple I2C working on the Pico.

Awesome driver! Hope this can get finished and merged soon 🚀

pub struct I2c<'d, T: Instance, M: Mode> {
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
dma_buf: [u16; 256],
Copy link
Contributor

@jsgf jsgf Sep 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think DMA is winning much here, if we need to statically allocate this buffer and copy the payload data to it. Given that i2c is pretty slow, it wouldn't be the end of the world to take an interrupt for each byte each time the fifo drains, at least for low speed devices.

DMA might be useful for demanding applications, but it seems to me that the default impl would be better simple and low overhead. I imagine we'd want a standard i2c implemented with pio as well (and maybe pio+dma) so in principle we'd want to support multiple impls anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would agree with this.

Thoughts @Dirbaio

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very unfortunate the i2c design doesn't allow DMAing directly from the buffer, yes... Whether that makes using DMA not worth it.. I dunno! I'm OK with whatever you guys decide.

Re pio-i2c, I'd imagine that'd be a different struct.

@MathiasKoch
Copy link
Contributor Author

Given that i have no hardware to test async I2C with, I am inclined to split the blocking and async parts into two PR's here, so we can merge the blocking part & continue working on the async part?

@MathiasKoch
Copy link
Contributor Author

Moved the async part into #978.

This PR with just the blocking implementation should be good to go now 👍

@MathiasKoch MathiasKoch marked this pull request as ready for review September 27, 2022 05:57
Copy link
Member

@Dirbaio Dirbaio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say "write a HIL test" but there's no i2c device in the HIL rig to talk to... Something we'll have to do someday, same for stm32. I trust you tested it on real HW :)

Thanks for your great work! 🚀

bors r+

@bors
Copy link
Contributor

bors bot commented Sep 27, 2022

Merge conflict.

@Dirbaio
Copy link
Member

Dirbaio commented Sep 27, 2022

bah

@Dirbaio
Copy link
Member

Dirbaio commented Sep 27, 2022

rebased

bors r+

@bors
Copy link
Contributor

bors bot commented Sep 27, 2022

Build succeeded:

@bors bors bot merged commit 9bb43ff into embassy-rs:master Sep 27, 2022
bors bot added a commit that referenced this pull request Oct 12, 2022
984: rp pico async i2c implementation r=Dirbaio a=jsgf

This implements an interrupt-driven async i2c master. It is based on #914, a bit of #978 and `@ithinuel's` https://github.com/ithinuel/rp2040-async-i2c.git

This is still work-in-progress, and is currently untested.

1006: Removes some of the code duplication for UarteWithIdle r=Dirbaio a=huntc

This PR removes some of the code duplications for `UarteWithIdle` at the slight expense of requiring a split when using idle processing. As the nRF example illustrates though given the LoC removed, this expense seems worth the benefit in terms of maintenance, and the avoidance of copying over methods. My main motivation for this PR was actually due to the `event_endtx` method not having been copied across to the idle-related code.

Tested the uart_idle example on my nRF52840-dk, and from within my app. Both appear to work fine.

Co-authored-by: Jeremy Fitzhardinge <[email protected]>
Co-authored-by: huntc <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants