Skip to content

ONIv2 implementation#57

Draft
aacuevas wants to merge 2 commits intomainfrom
ONIv2
Draft

ONIv2 implementation#57
aacuevas wants to merge 2 commits intomainfrom
ONIv2

Conversation

@aacuevas
Copy link
Collaborator

@aacuevas aacuevas commented Feb 5, 2026

This is a draft PR to discuss the changes related to updating the library to the ONIv2 spec

The first commits contain an updated register interface allowing for batch register operations.

Currently only the ft600 driver translator is compatible with the new API

@aacuevas aacuevas requested a review from jonnew February 5, 2026 20:21
@aacuevas aacuevas self-assigned this Feb 5, 2026
@aacuevas
Copy link
Collaborator Author

aacuevas commented Feb 5, 2026

@jonnew while working on this I ended deviating on the proposals in #34 and I ended with something like this:

liboni/api/liboni/oni.h

Lines 75 to 88 in e95f1d1

typedef enum {
ONI_REG_OP_READ = 0,
ONI_REG_OP_WRITE = 1
} oni_reg_optype_t;
typedef struct {
oni_dev_idx_t dev_idx;
oni_reg_addr_t addr;
oni_reg_optype_t optype;
oni_reg_val_t value;
oni_fifo_time_t timestamp;
oni_fifo_time_t hub_timestamp;
int result;
} oni_reg_operation_t;

ONI_EXPORT int oni_reg_access(const oni_ctx ctx, oni_reg_operation_t* operations, int num);

The reason is that individual function signatures were having too many parameters, which made them confusing.

The main advantage of this new pattern, which is common in many POSIX syscalls, is that now an user can create a batch of arbitrary reads and writes to any device, which is something allowed by the hardware spec.

The disadvantage is that the usage is less obvious. A user needs to create an array of oni_reg_operation_t, set the dev_idx addr optype and value(this one in case of a write), call the method and then read timestamp hub_timestamp value(in case of a read) and result

To make this process easier, I also created some helpers for what's gonna be the most common batch operations:

liboni/api/liboni/oni.h

Lines 117 to 137 in e95f1d1

ONI_EXPORT void oni_create_reg_read_continuous(oni_reg_operation_t *ops,
oni_dev_idx_t dev_idx,
oni_reg_addr_t start,
size_t num);
ONI_EXPORT void oni_create_reg_read_sparse(oni_reg_operation_t *ops,
oni_dev_idx_t dev_idx,
oni_reg_addr_t* addresses,
size_t num);
ONI_EXPORT void oni_create_reg_write_continuous(oni_reg_operation_t *ops,
oni_dev_idx_t dev_idx,
oni_reg_addr_t start,
oni_reg_val_t* values,
size_t num);
ONI_EXPORT void oni_create_reg_write_sparse(oni_reg_operation_t *ops,
oni_dev_idx_t dev_idx,
oni_reg_addr_t *addresses,
oni_reg_val_t *values,
size_t num);

We can discuss different patterns, though. That is the main purpose of this PR, to discuss implementation details.

(note that the old oni_write_reg and oni_read_reg methods still exist and work as before, acting as a wrapper for the new universal method)

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