8000 I2C protocol refactor, Meson driver rewrite, added libi2c by omeh-a · Pull Request #434 · au-ts/sddf · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

I2C protocol refactor, Meson driver rewrite, added libi2c #434 < 8000 /h1>
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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

omeh-a
Copy link
Member
@omeh-a omeh-a commented May 23, 2025

This PR is a complete rewrite of our I2C protocol and all extant code for it. The old I2C abstraction was essentially just a recycled version of the ODROID C4's internal i2c hardware protocol, and had a variety of issues. This change will close

This PR depends upon a corresponding change in SDFgen and must be merged in lockstep with it: au-ts/microkit_sdf_gen#15

Protocol

The new protocol is more complex and is designed to offer abstractions familiar to embedded systems engineers as commonly seen in HALs for other platforms. The guiding principle for this design is to offer a friendly interface and corresponding interface library for new users to our ecosystem. I2C requests now describe a single transaction - i.e. a series of operations which are executed together. Each transaction is composed of some number of commands. Commands define a read, write or write-read operation paired with a buffer mapped from the client to operate on.

E.g. a read command includes some buffer and length mapped to the client - the driver will read directly into that buffer without any copying.

Commands exist in the data region** (formerly used for everything) as a simple list. Commands reference a buffer in a new region, the meta** region, which is mapped between the driver and the client. Logically, the meta region is identical to the data region and their separation is just for clarity. Separating meta has benefits for clarity for end users who need to write complex i2c applications - they can treat meta as a safe, self-controlled region of buffers - this means that simply reading i2c/queue.h should be enough context to write a complex application even without libi2c, since data transmission is now fully abstracted to queue operations and installing buffers in meta as you would in a typical embedded HAL.

 |  Request  |
     |
     V
| CMD | CMD | CMD | CMD |
   |     |     |     |
   V     V     V     V
- - - - - - - - - - - - - - (into meta region)
| buf1 | buf2 | buf3 | buf4 |

When clients make requests, they pass a pointer to the meta region in their virtual address space as a destination. The virt translates this address to the corresponding address in the driver using the mappings in the config struct defined by sdfgen.
Note; the current solution for this is suboptimal in my opinion. We could just pass an index to the correct meta region instead of transmitting it from the client every request.

**should consider renaming

libi2c

Libi2c is a user-facing library implementing a blocking API for i2c calls. It uses the new meta region to back buffers - when making requests the end user must offer up any buffer from within the region. Coroutines are used for the blocking aspect: the client using libi2c must set up libco and call libi2c_init to create a configuration structure before use.

Libi2c offers the following core operations:

  • i2c_write(libi2c_conf, i2c_address, buf, len) - write the contents of buffer buf to i2c_address
  • i2c_read(libi2c_conf, i2c_address, buf, len) - read from i2c_address into buffer buf
  • i2c_writeread(libi2c_conf, i2c_address, reg_address, buf, len) - read from register reg_address of i2c_address into buffer buf

Libi2c can work with raw libco or libmicrokitco.

Writing to a register is accomplished by simply putting the register address into the first byte of a write, if only writing.

Users need only worry about supplying valid meta bufs, all other operation is automated using an allocator for commands.

Meson driver rewrite

The meson driver has been fully rewritten for the new protocol and implements a new FSM-based design. The driver now operates entirely around a finite state machine which mirrors handling different parts of the protocol. At a high level, the state machine is summarised as follows:

  • Init: check if there's work to do, otherwise go to sleep
  • Request: there's a request, take from the queue and validate.
  • Cmd_sel: from this request, select one of the i2c commands composing it to run. Load data into driver state
  • Cmd: from current command, pack data into hardware registers. Once done, go to sleep.
  • Cmd_ret (return from irq): command is done, extract result from hardware. Go to response if all commands are done, cmd_sel if current command is done, otherwise back to cmd to continue working on current command
  • Response: send response back to client. Go here from successfully finishing a request or an error in any of the previous states (with error field set in state). Always go back to idle

This design change makes the driver faster, more readable and eliminates a tremendous amount of fragile code. Additionally, this driver structure should trivially work on most other platforms, only requiring changes to s_cmd and s_cmd_ret to match the functionality of the i2c ip block.

@omeh-a omeh-a force-pushed the i2c-protocol-refac branch 8 times, most recently from 809da96 to 635cf7d Compare May 23, 2025 06:10
Signed-off-by: Lesley Rossouw <lesley.rossouw@unsw.edu.au>
@omeh-a omeh-a force-pushed the i2c-protocol-refac branch from 635cf7d to 42c832a Compare May 26, 2025 07:04
@omeh-a omeh-a marked this pull request as ready for review May 26, 2025 07:04
@omeh-a omeh-a requested review from Ivan-Velickovic and wom-bat May 26, 2025 07:04
Signed-off-by: Lesley Rossouw <lesley.rossouw@unsw.edu.au>
@omeh-a omeh-a force-pushed the i2c-protocol-refac branch from 42c832a to c4e2be5 Compare May 28, 2025 05:17
…r platforms

Signed-off-by: Lesley Rossouw <lesley.rossouw@unsw.edu.au>
@omeh-a omeh-a force-pushed the i2c-protocol-refac branch 2 times, most recently from 56b2f40 to d67aac5 Compare June 2, 2025 08:58
Signed-off-by: Lesley Rossouw <lesley.rossouw@unsw.edu.au>
omeh-a added 2 commits June 25, 2025 14:45
…inor bugs in macros + an uninitialised variable usage.

Signed-off-by: Lesley Rossouw <lesley.rossouw@unsw.edu.au>
Signed-off-by: Lesley Rossouw <lesley.rossouw@unsw.edu.au>
@Ivan-Velickovic
Copy link
Collaborator

Seems to be compilation errors in the CI.

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.

2 participants
0