Skip to content
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

I2C: Add long read support #334

Open
omeh-a opened this issue Jan 28, 2025 · 4 comments · May be fixed by #336
Open

I2C: Add long read support #334

omeh-a opened this issue Jan 28, 2025 · 4 comments · May be fixed by #336
Labels
drivers Issues pertaining to driver code for a device class enhancement New feature or request protocol Issues pertaining to protocols for interfacing with drivers

Comments

@omeh-a
Copy link
Member

omeh-a commented Jan 28, 2025

Currently, our I2C protocol can only express a continuous read of up to 256 bytes. This is because the token-chain representation of a transaction is a single READ token followed by a single byte representing length and we have no way to designate a follow-on read. Once the bytes specified are processed, the READ is terminated. For certain I2C devices such as memory chips (EEPROM, flash) or displays, arbitrarily long (or rather simply longer than 256 byte) reads may be helpful or necessary.

This can be trivially resolved by adding a new token, READC, which specifies a continued read. All current I2C drivers work by incrementally parsing the token chain, therefore this ideally should be implemented such that a READC designates a read which will NOT be terminated after the final byte. A chain of READC tokens, each specifying another up to 256 bytes, may be continued indefinitely this way. A chain of READCs must then be followed with a regular READ to terminate the transaction.

This approach is somewhat spatially inefficient (still transferring 16 bits per 256 bytes read) but is trivial to implement. Alternatively, we may instead implement an alternative scheme to allow a single READ address more than 8 bits, but this would require rewriting significant amounts of the protocol and would still require the ability to chain as above to support arbitrarily long reads.

@omeh-a omeh-a added drivers Issues pertaining to driver code for a device class enhancement New feature or request protocol Issues pertaining to protocols for interfacing with drivers labels Jan 28, 2025
@Ivan-Velickovic
Copy link
Collaborator

I don't quite understand what problem this solves, if you have to terminate the READC that means you know how many reads you need to do, so why not do multiple READ requests anyways?

@omeh-a
Copy link
Member Author

omeh-a commented Jan 28, 2025

I don't quite understand what problem this solves, if you have to terminate the READC that means you know how many reads you need to do, so why not do multiple READ requests anyways?

A new read means halting streaming. For devices like memory, this means incurring a performance hit to reset the control circuitry between segments since they usually have a dedicated hardware path to stream bytes at max speed while they're engaged. Without breaking the read into multiple, you can avoid that entirely.

On the scale of fast mode I2C, this means a reset once every 4 milliseconds for no reason while streaming data. It's not a problem for the two devices we have driver support for currently, but it may be in the future. This change would require only a few lines of code worth of change but could drastically improve performance for high-bandwidth devices.

@Ivan-Velickovic
Copy link
Collaborator

Can you point to documentation on this? I'm surprised performance is a concern with I2C, I thought the whole point of it was that it was a low bandwidth device hence no DMA.

Do all I2C devices implement continuous mode?

@omeh-a
Copy link
Member Author

omeh-a commented Jan 28, 2025

Can you point to documentation on this? I'm surprised performance is a concern with I2C, I thought the whole point of it was that it was a low bandwidth device hence no DMA.

Do all I2C devices implement continuous mode?

The trouble with I2C is that this isn't a part of the standard, devices just happen to do this type of thing optionally to improve their performance (referred to as "quirks" by some papers).

This isn't about a different mode and there's no DMA, it's more that we currently have an edge case that we fail to cover because of our transport abstraction. E.g. the Meson I2C hardware supports arbitrarily long reads like this by just continuing to send DATA tokens after a ADDR_READ until the final byte is a DATA_END. Right now, we have no way to indicate that two blocks of reads are related and the DATA_END token is always sent every 256 bytes.

Re: performance - I2C can go relatively fast for an embedded serial interface and there are lots of peripherals that care about bandwidth that use it still (cameras, displays, memory, human interface devices).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
drivers Issues pertaining to driver code for a device class enhancement New feature or request protocol Issues pertaining to protocols for interfacing with drivers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants