Skip to content

i2c: support writes with a list of buffers (v2) - #4763

Closed
dpgeorge wants to merge 10 commits into
micropython:masterfrom
dpgeorge:extmod-i2c-partial-transactions-v2
Closed

dpgeorge wants to merge 10 commits into
micropython:masterfrom
dpgeorge:extmod-i2c-partial-transactions-v2

Conversation

@dpgeorge

@dpgeorge dpgeorge commented May 8, 2019

Copy link
Copy Markdown
Member

This is an alternative implementation to #4746 that uses a different C-level API. Instead of start_addr(), read_part() and write_part(), it has a single C function transfer(). This function takes an array of buffers to read/write, which should be done all at once.

The reason to reimplement it this way is that it makes it much easier for the various ports to satisfy the C-level API. With the implementation in #4746 it's rather difficult since ports would usually need to cache incoming buffers until the last one, and the return value (eg error code) from the intermediate calls would not be useful.

The PR here includes updates to the stm32, nrf and zephyr ports. All other ports just use software I2C so they are OK.

Also, instead of overloading i2c.writeto() to allow a list of buffers, the implementation here adds the new "vector" method i2c.writevto(), to see how that would look (discussed in #4020).

@dpgeorge

Copy link
Copy Markdown
Member Author

Merged in 606ea2b through 02afc0d

@dpgeorge dpgeorge closed this May 20, 2019
@dpgeorge
dpgeorge deleted the extmod-i2c-partial-transactions-v2 branch May 20, 2019 05:10
dpgeorge added a commit that referenced this pull request May 20, 2019
This allows to efficiently send to an I2C slave data that is made up of
more than one buffer.  Instead of needing to allocate temporary memory to
combine buffers together this new method allows to pass in a tuple or list
of buffers.  The name is based on the POSIX function writev() which has
similar intentions and signature.

The reasons for taking this approach (compared to having an interface with
separate start/write/stop methods) are:
- It's a backwards compatible extension.
- It's convenient for the user.
- It's efficient because there is only one Python call, then the C code can
  do everything in one go.
- It's efficient on the I2C bus because the implementation can do
  everything in one go without pauses between blocks of bytes.
- It should be possible to implement this extension in all ports, for
  hardware and software I2C.

Further discussion is found in issue #3482, PR #4020 and PR #4763.
tannewt pushed a commit to tannewt/circuitpython that referenced this pull request May 27, 2021
Taccart pushed a commit to Taccart/micropython that referenced this pull request May 23, 2026
This allows to efficiently send to an I2C slave data that is made up of
more than one buffer.  Instead of needing to allocate temporary memory to
combine buffers together this new method allows to pass in a tuple or list
of buffers.  The name is based on the POSIX function writev() which has
similar intentions and signature.

The reasons for taking this approach (compared to having an interface with
separate start/write/stop methods) are:
- It's a backwards compatible extension.
- It's convenient for the user.
- It's efficient because there is only one Python call, then the C code can
  do everything in one go.
- It's efficient on the I2C bus because the implementation can do
  everything in one go without pauses between blocks of bytes.
- It should be possible to implement this extension in all ports, for
  hardware and software I2C.

Further discussion is found in issue micropython#3482, PR micropython#4020 and PR micropython#4763.
jakub-vesely pushed a commit to jakub-vesely/micropython that referenced this pull request Sep 21, 2026
This allows to efficiently send to an I2C slave data that is made up of
more than one buffer.  Instead of needing to allocate temporary memory to
combine buffers together this new method allows to pass in a tuple or list
of buffers.  The name is based on the POSIX function writev() which has
similar intentions and signature.

The reasons for taking this approach (compared to having an interface with
separate start/write/stop methods) are:
- It's a backwards compatible extension.
- It's convenient for the user.
- It's efficient because there is only one Python call, then the C code can
  do everything in one go.
- It's efficient on the I2C bus because the implementation can do
  everything in one go without pauses between blocks of bytes.
- It should be possible to implement this extension in all ports, for
  hardware and software I2C.

Further discussion is found in issue micropython#3482, PR micropython#4020 and PR micropython#4763.
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.

1 participant