oni.h#
Version Macros#
See https://semver.org/ for a complete explanation of these macro definitions.
-
ONI_VERSION_MAJOR#
MAJOR version for incompatible API changes
-
ONI_VERSION_MINOR#
MINOR version for added functionality that is backwards compatible
-
ONI_VERSION_PATCH#
PATCH version for backwards compatible bug fixes
-
ONI_MAKE_VERSION(major, minor, patch)#
Defined as
MAJOR * 10000 + MINOR * 100 + PATCH
Provides compile-time access to the API version.
-
ONI_VERSION#
Compile-time API version. Defined as
ONI_MAKE_VERSION(ONI_VERSION_MAJOR ONI_VERSION_MINOR, ONI_VERSION_PATCH).
Acquisition Context#
-
typedef struct oni_ctx_impl *oni_ctx#
An ONI-compliant acquisition context implementation.
oni_ctx
is an opaque handle to a structure which manages hardware state.Attention
Context details are hidden in the implementation file (
oni.c
). Direct manipulation ofoni_ctx
data members is never necessary or correct.Each
oni_ctx
instance manages the device driver, device table, read and write buffers, acquisition run state, etc. Following a hardware reset, which is triggered either by a call tooni_init_ctx()
oroni_set_opt()
using theONI_OPT_RESET
context option, the context run state is set toUNINITIALIZED
and the device table is pushed onto the host signal stream by the host hardware as COBS-encoded packets. On the signal stream, the device table is organized as follows,... | DEVICEMAPACK, uint32_t num_devices | DEVICEINST, oni_device_t dev_0 | DEVICEINST, oni_device_t dev_1 | ... | DEVICEINST, oni_device_t dev_n | ...
where “|” represents a packet delimiter. During a call to
oni_init_ctx()
, the device table is decoded from the signal stream. It can then be examined using calls tooni_get_opt()
using theONI_OPT_DEVICETABLE
option. After the device table is received, the context run state becomesIDLE
. A call tooni_set_opt()
with theONI_OPT_RUNNING
option can then be used to start acquisition uy transitioning the context run state toRUNNING
.
Device#
-
struct oni_device_t#
-
oni_size_t idx#
Fully qualified RSV.RSV.HUB.IDX device table index.
- RSV:
8-bit unsigned integer (reserved).
- HUB:
8-bit unsigned integer indicating the hub index.
- IDX:
8-bit unsigned integer indicating the device index.
-
oni_dev_id_t id#
Device ID number (see onix.h for ONIX-specific definitions).
-
oni_size_t read_size#
Device data read size per frame in bytes.
-
oni_size_t write_size#
Device data write size per frame in bytes.
An ONI-compliant device implementation. An
oni_device_t
describes one of potentially many pieces of hardware managed by anoni_ctx
. Examples of individual devices might include ephys chips, IMUs, optical stimulators, camera sensors, etc.Tip
Look at device index definitions in onix.h to see available ONIX-specific device definitions and enum ranges that will not interfere with ONIX for custom or closed-source projects.
A device table is read from hardware and stored in the current context via a call to
oni_init_ctx()
. This table can be examined via calls tooni_get_opt()
using theONI_OPT_DEVICETABLE
option.-
oni_size_t idx#
Frame#
-
struct oni_frame_t#
-
const oni_fifo_time_t time#
Frame time (
ONI_OPT_ACQCLKHZ
host clock counter).
-
const oni_fifo_dat_t dev_idx#
Device index that produced or accepts the frame.
-
const oni_fifo_dat_t data_sz#
Size of data in bytes.
-
uint8_t *data#
Raw data block. This pointer is a zero-copy “view” into a private, referenced-counted buffer managed by the acquisition context. The handle to this buffer is hidden by the API using some C
union
magic.
An ONI-compliant data frame implementation.
oni_frame_t
’s are produced by calls tooni_read_frame()
and consumed by calls tooni_write_frame()
.See also
oni_create_frame()
Create frames for use with
oni_write_frame()
.oni_write_frame()
Write frames to hardware.
oni_read_frame()
Read frames from hardware.
oni_destroy_frame()
Free a frame and underlying resources allocated by
oni_create_frame()
oroni_read_frame()
.
-
const oni_fifo_time_t time#
Functions#
The functions in oni.h form the basis of the API and are all that is needed during the development of user-facing software.
-
oni_ctx oni_create_ctx(const char *drv_name)
-
int oni_init_ctx(oni_ctx ctx, int host_idx)
-
int oni_destroy_ctx(oni_ctx ctx)
-
int oni_get_opt(oni_ctx ctx, int option, void *value, size_t *size)
-
int oni_set_opt(oni_ctx ctx, int option, const void *value, size_t size)
-
int oni_get_driver_opt(const oni_ctx ctx, int drv_opt, void *value, size_t *size)
-
int oni_set_driver_opt(oni_ctx ctx, int drv_opt, const void *value, size_t size)
-
int oni_read_reg(const oni_ctx ctx, oni_dev_idx_t dev_idx, oni_reg_addr_t addr, oni_reg_val_t *value)
-
int oni_write_reg(const oni_ctx ctx, oni_dev_idx_t dev_idx, oni_reg_addr_t addr, oni_reg_val_t value)
-
int oni_read_frame(const oni_ctx ctx, oni_frame_t **frame)
-
int oni_create_frame(const oni_ctx ctx, oni_frame_t **frame, oni_dev_idx_t dev_idx, void *data, size_t data_sz)
-
int oni_write_frame(const oni_ctx ctx, const oni_frame_t *frame)
-
void oni_destroy_frame(oni_frame_t *frame)
-
void oni_version(int *major, int *minor, int *patch)
-
const char *oni_error_str(int err)
-
oni_ctx oni_create_ctx(const char *drv_name)#
Creates an acquisition context,
oni_ctx
, which is an opaque handle to a structure that manages device drivers, the device table, data streaming, memory management, etc. On success the selected driver is loaded and anoni_ctx
is allocated and created, and its handle is passed to the user. Many API functions take aoni_ctx
as a first argument.- Parameters:
drv_name – A string specifying the device driver used by the context to control hardware. This string corresponds a compiled implementation of onidriver.h that has the name
libonidriver_<drv_name>.<so/dll>
. If this library is not on the dynamic library search path, the function will error.
- Returns:
An opaque handle to the newly created context if successful. Otherwise it shall return
NULL
and seterrno
toEAGAIN
.- Example:
See also
oni_get_opt()
Inspect
oni_ctx
state.oni_set_opt()
Modify
oni_ctx
state.
-
int oni_init_ctx(oni_ctx ctx, int host_idx)#
Initialize an acquisition context. This function initializes the selected device driver, opens all communication channels, and acquires a device table that maps out the device control and streaming hierarchy. Specifically, during a successful call to
oni_init_ctx()
, the following events occur:All required data streams are opened.
A hardware reset issued using
ONI_OPT_RESET
.A device table is obtained from the hardware.
The minimal
ONI_OPT_BLOCKREADSIZE
andONI_OPT_BLOCKWRITESIZE
values are calculated and stored.The context run state is moved from
UNINITIALIZED
toIDLE
.
- Parameters:
ctx – The acquisition context to be initialized.
host_idx – The index of the hardware we are going to manage using the initialized context and driver. A value of -1 will attempt to open the default host index and is useful if there is only a single ONIX host managed by driver selected in
oni_create_ctx()
.
- Returns:
0 on success otherwise see Error Codes.
- Example:
-
int oni_destroy_ctx(oni_ctx ctx)#
Terminate a context and free bound resources. During context destruction, all resources allocated by
oni_create_ctx()
andoni_init_ctx()
are freed. This function can be called from any context run state. When called, an interrupt signal (TODO: Which?) is raised and any blocking operations will return immediately. Attached resources (device drivers, data buffers, etc.) are closed and their resources freed.- Parameters:
ctx – The acquisition context to close.
- Returns:
0 on success otherwise see Error Codes.
- Example:
-
int oni_get_opt(oni_ctx ctx, int option, void *value, size_t *size)#
Retrieves the option specified by the
option
argument within the acquisition contextctx
and stores it in thevalue
buffer. Thesize
provides a pointer to the size of thevalue
buffer, in bytes. Upon successful completiononi_get_opt()
modifies the value pointed to bysize
to indicate the actual size of the option value stored in the buffer. If the value pointed to by size is too small to store the value, the function will error. Additionally, some context options are write-only and others can only be read in certain acquisition states. If these constraints are disobeyed, the function will error. See Context Options for a description of each possibleoption
, including access constraints.- Parameters:
ctx –
oni_ctx
context to read an option from.option – Selected option to read. See Context Options for valid options.
value – buffer to store value of
option
after it is read.size – Pointer to the size of
value
buffer (including terminating null character, if applicable) in bytes.
- Returns:
0 on success otherwise see Error Codes.
- Example:
See Examining the Device Table and Setting Read and Write Buffer Sizes.
See also
- Context Options
Valid context options with access and type specifications.
-
int oni_set_opt(oni_ctx ctx, int option, const void *value, size_t size)#
Sets the option specified by the
option
argument within the acquisition contextctx
to the contents of thevalue
buffer. Thesize
indicates the size of thevalue
buffer, in bytes. Upon successful completion,oni_set_opt()
modifies the value pointed to bysize
to indicate the actual size of the option value stored in the functions will error. Additionally, some context options are read-only and others can only be written in certain acquisition states. If these constraints are disobeyed, the function will error. See Context Options for description of each possibleoption
, including access constraints.- Parameters:
ctx –
oni_ctx
context to read an option from.option – Selected option to set. See Context Options for valid options.
value – buffer containing data to be written to
option
.size – Size of
value
buffer (including terminating null character, if applicable) in bytes.
- Returns:
0 on success otherwise see Error Codes.
- Example:
See Examining the Device Table and Setting Read and Write Buffer Sizes.
See also
- Context Options
Valid context options with access and type specifications.
-
int oni_read_reg(const oni_ctx ctx, oni_dev_idx_t dev_idx, oni_reg_addr_t addr, oni_reg_val_t *value)#
Read the value of a configuration register from a specific device within the current device table. This can be used to verify the success of calls to
oni_write_reg()
or to obtain state information about devices managed by the current acquisition context. Register specifications (addresses, read- and write-access, and descriptions) are provided on the ONI-device datasheet.- Parameters:
ctx –
oni_ctx
context that manages the requested device.dev_idx – fully-qualified device index within the device table.
addr – Address of register to be read.
value – Pointer to an unsigned integer that will store the value of the register at
addr
ondev_idx
.
- Returns:
0 on success otherwise see Error Codes.
- Example:
-
int oni_write_reg(const oni_ctx ctx, oni_dev_idx_t dev_idx, oni_reg_addr_t addr, oni_reg_val_t value)#
Change the value of a configuration register from specific devices within the current device table. This can be used to change the functionality of devices, e.g. set filter bandwidth, select active channels, or change stimulation parameters. Register specifications (addresses, read- and write-access, acceptable values, and descriptions) are provided on the ONI-device datasheet.
- Parameters:
ctx –
oni_ctx
context that manages the requested device.dev_idx – fully-qualified device index within the device table.
addr – Address of register to be read.
value – Value to write to the register at
addr
ondev_idx
.
- Returns:
0 on success otherwise see Error Codes.
- Example:
-
int oni_read_frame(const oni_ctx ctx, oni_frame_t **frame)#
Read high-bandwidth data from the data input channel.
oni_read_frame()
allocates host memory and populates it with a singleoni_frame_t
struct using the data input stream. This call will block until enough data is available on the stream to construct an underlying block buffer (seeONI_OPT_BLOCKREADSIZE
and Setting Read and Write Buffer Sizes).oni_frame_t
’s created during calls tooni_read_frame()
are zero-copy views into this buffer.Attention
It is the user’s responsibility to free the resources allocated by this call by passing the resulting frame pointer to
oni_destroy_frame()
.- Parameters:
ctx –
oni_ctx
context that manages the high-bandwidth input channel that the frame will be read from.frame – NULL pointer to reference using internal memory.
- Returns:
0 on success otherwise see Error Codes.
- Example:
See Reading Data Frames.
-
int oni_create_frame(const oni_ctx ctx, oni_frame_t **frame, oni_dev_idx_t dev_idx, void *data, size_t data_sz)#
Create an
oni_frame_t
for consumption byoni_write_frame()
.Attention
It is the user’s responsibility to free the resources allocated by this call by passing the resulting frame pointer to
oni_destroy_frame()
- Parameters:
ctx –
oni_ctx
context that manages the high-bandwidth output channel that the frame will be written through.frame – NULL pointer to reference using internal memory.
dev_idx – fully-qualified device index within the device table that the frame will be written to.
data – Raw data block to be copied into the frame.
data_sz – Size of
data
in byes.
- Returns:
0 on success otherwise see Error Codes.
- Example:
See Writing Data Frames.
Attention
data_sz
Must beAn integer multiple of the selected
dev_idx
’s write size as indicated within the device tableSmaller than the internal write block memory size (see
ONI_OPT_BLOCKWRITESIZE
and Setting Read and Write Buffer Sizes)
-
int oni_write_frame(const oni_ctx ctx, const oni_frame_t *frame)#
Write an
oni_frame_t
to a particular device within the device table using the high-bandwidth output channel.- Parameters:
ctx –
oni_ctx
context that manages the high-bandwidth output channel that the frame will be written throughframe – Pointer to frame created during a call to
oni_create_frame()
- Returns:
0 on success otherwise see Error Codes
- Example:
Tip
Frames created by using
oni_create_frame()
can be written to a device multiple times by using them as input arguments tooni_write_frame()
multiple times. This allows pre-allocation of frame resources for improved latency and determinism in closed-loop applications.
-
void oni_destroy_frame(oni_frame_t *frame)#
Note
Each call to
oni_create_frame()
oroni_read_frame()
must be matched by a call tooni_destroy_frame()
to prevent memory leaks.
-
void oni_version(int *major, int *minor, int *patch)#
Report the liboni library version. This library uses Semantic Versioning. Briefly, the major revision is for incompatible API changes. Minor version is for backwards compatible changes. The patch number is for backwards compatible bug fixes. When this function returns, input pointers will reference the library’s version.
- Parameters:
major – major library version for incompatible API changes.
minor – minor library version for backwards compatible changes.
patch – patch number for backwards compatible bug fixes.
-
oni_driver_info_t *oni_get_driver_info(const oni_ctx ctx)#
Reports a Driver Information structure containing the name of the driver translator loaded for a given context as well as its semantic versioning version.
- Parameters:
ctx –
oni_ctx
context of which the loaded driver translator information will be reported.
- Returns:
A pointer to a constant structure containing the driver translator information.
-
const char *oni_error_str(int err)#
Convert a return code (see Error Codes) into a human readable string.
- Parameters:
err – The error code to convert.