-
Notifications
You must be signed in to change notification settings - Fork 783
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
Add support for transactions to Twim in embassy-nrf #3257
Conversation
7c41c16
to
fcf87a6
Compare
Ok, I think this is ready to merge. I've tested all supported combinations of operations on an nrf52840 and everything works as expected. The main limitation is that consecutive Read operations are not supported (and will panic). The issue is that the Twim hardware does not support suspending at the end of a read operation. If you set the SUSPEND task in response to the LASTRX event it will ACK the last byte of the current operation. When you then resume it will read one more byte from the peripheral before starting a new operation. For example, what we would want on the bus for the transaction
However this does not appear to be possible. The sequence of events and tasks:
Note that the first byte of The This behavior is sufficiently non-standard that I think it's better to simply not support consecutive read operations. Instead I've written the transaction support to avoid ever suspending after a read operation. |
Due to Twim hardware limitations
fcf87a6
to
55805de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you!
Adds support for the
embedded_hal(_async)::i2c::I2c::transaction()
method to theTwim
peripheral inembassy_nrf
.The inherent
transaction
methods also take an additionalstop
parameter to allow the user to suspend the bus following a transaction. This allows for operations like reading a register from a peripheral, modifying it, then writing it back all in a single I2C transaction.A few nRF chips (specifically the nrf52832, nrf5340, and nrf9120) lack the LASTRX_SUSPEND short. This means they can't automatically enter the suspend state after a read operation, which is needed for certain (uncommon) operation sequences. Therefore, a manual implementation of the short has been added to the interrupt handler for those chips.
Lastly, I discovered a case of UB related to copying write buffers into RAM.
setup_write
andsetup_write_read
would allocate a buffer on the stack if the initial setup failed with aBufferNotInRAM
error. However, they would then immediately return after setting up the I2C transaction and DMA, meaning the DMA engine would be pointing to stack memory that was no longer owned. This PR fixes that issue by providing an optional buffer parameter toset_tx_buffer
so that the buffer can be passed in from an outer scope that is valid for the entire transaction.