From 92b97cd0f6dfb6f65ecf104fe4f45fcacb2cfbab Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Fri, 8 Nov 2024 14:31:07 +0100 Subject: [PATCH 01/31] Draft for version 2 of the ONI spec - Reorganized controller into separate pages - Introduce procedures for variable word alignments in high-bw streams - Modified register access to allow queued transactions - Introduce the possibility of optional features - Added an expanded address map --- source/hw-spec/controller.rst | 355 ------------------ source/hw-spec/controller/addresses.rst | 141 +++++++ .../channels/configuration_channel.rst | 18 + .../controller/channels/data_frames.rst | 33 ++ source/hw-spec/controller/channels/index.rst | 38 ++ .../controller/channels/read_channel.rst | 31 ++ .../controller/channels/signal_channel.rst | 77 ++++ .../controller/channels/write_channel.rst | 32 ++ source/hw-spec/controller/index.rst | 38 ++ .../hw-spec/controller/register_interface.rst | 123 ++++++ source/hw-spec/dev_table.rst | 6 + source/hw-spec/index.rst | 2 +- 12 files changed, 538 insertions(+), 356 deletions(-) delete mode 100644 source/hw-spec/controller.rst create mode 100644 source/hw-spec/controller/addresses.rst create mode 100644 source/hw-spec/controller/channels/configuration_channel.rst create mode 100644 source/hw-spec/controller/channels/data_frames.rst create mode 100644 source/hw-spec/controller/channels/index.rst create mode 100644 source/hw-spec/controller/channels/read_channel.rst create mode 100644 source/hw-spec/controller/channels/signal_channel.rst create mode 100644 source/hw-spec/controller/channels/write_channel.rst create mode 100644 source/hw-spec/controller/index.rst create mode 100644 source/hw-spec/controller/register_interface.rst diff --git a/source/hw-spec/controller.rst b/source/hw-spec/controller.rst deleted file mode 100644 index 6ae94e6..0000000 --- a/source/hw-spec/controller.rst +++ /dev/null @@ -1,355 +0,0 @@ -.. _controller: - -Controller -========== -The controller's purpose is to interface an ONI hardware system with the host -computer. It aggregates and routes device data and provides transparent access -to all devices, independently of their physical location. The host also -contains a common clock that is used to timestamp data from all devices, -independently of their origin hub. - -Communication between the controller and the host computer shall occur over -four abstract communication channels: - -#. **Read**: Read-only, high-bandwidth stream of device output samples from - controller to host. -#. **Write**: Write-only, high-bandwidth stream of device input samples from - host to controller. -#. **Signal**: Read-only stream of short-messages and asynchronous hardware - events from controller to host. -#. **Configuration**: Bidirectional, addressed access to device registers. - -API access to all these channels is blocking, i.e.: an API call that accesses -any channel will not return until the requested transaction on that channel is -complete. Concurrent access to a single channel by different threads is NOT -permitted. However, channels are independent and concurrent access to -*different* channels MUST be permitted. A stream transaction is defined as a -blocking read or write of a set number of bytes, while a register transaction -is defined as a single register read or write cycle to an individual address. - -The required characteristics of these channels are described in the following -sections. A complete understanding of their use during software development -requires an understanding of the :ref:`oni-api`. - -.. _data-rd-chan: - -Read Channel ------------- - -- **Word size** : 32 bits -- **Channel type** : Stream -- **Direction** : Read - -The *read* channel provides high bandwidth communication from the controller to -the host computer. Data from the read stream of all devices that support it is -aggregated and multiplexed by the controller and sent to the host through this -channel. - -Data should be pushed to this channel as quickly as possible. It is the -responsibility of the host computer to read data from the stream quickly enough -to keep up with data production by the controller. Therefore, it is highly -recommended that an ONI system implements some kind of internal buffering to -ameliorate the effects of uneven reading times caused by computer operating -systems or other software limitations. - -.. _frame: - -Data Frames -~~~~~~~~~~~ - -Data from the read channel is packed in frames. Each frame is a timestamped -`type-length-value-encoded `__ -structure that contains data from a single device :ref:`sample `. -The frame format is: - -:: - - uint64 Common_Timestamp - uint32 Device_Address - uint32 Sample_Size - var Sample - -Where - -- ``Common_Timestamp``: A counter common to all devices generated by the - controller common acquisition clock. -- ``Device_Address``: The address of the device producing the data, as featured - on the :ref:`device table `. -- ``Sample_Size``: The full size of the sample, and must be equal to the - ``Read_Sample_Size`` field of the :ref:`device descriptor `. -- ``Sample``: The complete data sample as described on the :ref:`device sample - format ` section. - -.. _data-wr-chan: - -Write Channel -------------- - -- **Word size** : 32 bits -- **Channel type** : Stream -- **Direction** : Write - -The *write* channel provides high bandwidth communication from the host computer -to the controller, and is used to send data to the devices. - -Data is sent with a :ref:`frame ` format identical to the one used for -read, but without the ``Common_Timestamp`` field. It is the responsibility of -the controller to accept frames at any rate the computer might be sending them. -Currently, there is no defined mechanism to inform the host of any possible -dropped frame on the write channel, although this can be included in an -implementation so long as it does not invalidate any other ONI -requirements. - -.. _sig-chan: - -Signal channel --------------- - -- **Word size** : 8 bits -- **Channel type** : Stream -- **Direction** : Read - -The *signal* channel provides a way for the controller to inform the host of -configuration results, which may be provided with a significant delay. -Additionally, it is the channel over which the controller sends the device table -to the host following a system reset. Signal data MUST be framed into packets -using Consistent Overhead Byte Stuffing -(`COBS `__). -Within this scheme, packets are delimited using 0's and always have the -following format: - -:: - - ... | PACKET_FLAG, data0, data1, ..., data_k | ... - -where ``PACKET_FLAG`` is 32-bit unsigned integer with a single unique bit -setting, ``|`` represents a packet delimiter (in this case, 0), “``,``” are for -visual clarity and are not actually in the data stream, and ``...`` represents -other packets. This stream can be read and ignored until a desired packet is -received. Reading this stream shall block if no data is available, which allows -asynchronous configuration acknowledgment. Valid ``PACKET_FLAG``\ s are: - -============ ========== ===================================== -Flag Value Description -============ ========== ===================================== -NULLSIG 0x00000001 Null signal, ignored by host -CONFIGWACK 0x00000002 Configuration write-acknowledgment -CONFIGWNACK 0x00000004 Configuration no-write-acknowledgment -CONFIGRACK 0x00000008 Configuration read-acknowledgment -CONFIGRNACK 0x00000010 Configuration no-read-acknowledgment -DEVICETABACK 0x00000020 Device table start acknowledgment -DEVICEINST 0x00000040 Device descriptor instance -============ ========== ===================================== - -Following a hardware reset, the signal channel is used to provide the -:ref:`device table ` to the host using the following packet -sequence: - -:: - - ... | DEVICETABACK, uint32 num_devices - | DEVICEINST, uint32 dev_addr_0, device_descriptor dev_0 - | DEVICEINST, uint32 dev_addr_1, device_descriptor dev_1 | - ... - | DEVICEINST, uint32 dev_addr_n, device_descriptor dev_n | ... - -Where ``dev_addr_n`` is the full address of each device as described in the -:ref:`device table ` section and ``dev_n`` is a :ref:`device -descriptor `. - -In addition to providing the device table following reset, the signal channel -is also used to asynchronously acknowledge register access via the -:ref:`configuration channel `. Following a device register read or -write, an CONFIGWACK, CONFIGWNACK, CONFIGRACK, or CONFIGRNACK signal is pushed -onto the signal stream by the controller to indicate the validity of the -transaction. For instance, on a successful register read: - -:: - - ... | CONFIGRACK | ... - -.. _conf-chan: - -Configuration Channel ---------------------- - -- **Word size** : 32 bits -- **Channel type** : Register -- **Direction** : Read-Write - -The *configuration* channel supports addressed access to a set of configuration -registers. There are two classes of registers handled by the configuration -channel: the first set of registers encapsulates a generic device register -programming interface. The remaining registers are for global controller -control and configuration and provide access to acquisition parameters and -state control. - -The interface must use 32-bit values and, at least, 24-bit addressing. The -required register map is as follows: - -========== ========================= ================== -Address Name Type -========== ========================= ================== -0x00000000 Device Address Register interface -0x00000001 Register Address Register interface -0x00000002 Register Value Register interface -0x00000003 Read/Write Register interface -0x00000004 Trigger Register interface -0x00000005 Running Global -0x00000006 Reset Global -0x00000007 System Clock Global -0x00000008 Acquisition Clock Global -0x00000009 Reset Acquisition Counter Global -0x0000000A Hardware Address Global -========== ========================= ================== - -Device Register Programming Interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The device programming interface allows transparent access to each device's -:ref:`register map `. It defines a general purpose bus that hides -the specifics of any particular implementation. It is composed of the following -configuration channel registers: - -- ``Device Address``: The fully qualified address of a device as enumerated in - the :ref:`device table ` and to which communication will be - directed as described below. - -- ``Register Address``: The address of the register within the :ref:`register - map ` of the device located at ``Device Address`` that will be - written to or read from. - -- ``Register Value``: Value to be written to or read from and that corresponds - to the register ``Register Address`` of device located at - ``Device Address``. - -- ``Read/Write``: A flag indicating if a read or write should be performed. 0 - indicates read operation. A value > 0 indicates write operation. - -- ``Trigger``: Set > 0 to trigger either register read or write operation - depending on the state of ``Read/Write``. If ``Read/Write`` is 0, a read is - performed. In this case, after a successful operation, ``Register Value`` is - updated with value stored in the register at ``Register Address`` on the - device at ``Device Address``. If ``Read/Write`` is 1, ``Register Value`` is - written to register at ``Register Address`` on the device at - ``Device Address``. The ``Trigger`` register is always set low by the - controller following transmission even if it is not successful or does not - make sense given the supplied register address and/or value. - -Appropriate values of ``Register Address`` and ``Register Value`` are -determined by: - -- Looking at a device's data sheet if the device is an integrated circuit and - using :ref:`raw registers `. -- Examining the :ref:`ONI Device Datasheet ` for :ref:`managed - registers `. - -Register Read Sequence -^^^^^^^^^^^^^^^^^^^^^^ -When a host requests a device register *read*, the following following sequence -must be performed: - -1. Check the value of ``Trigger``. - - - If it is 0, the procedure can proceed. - - Else, the hardware is busy with a previous transaction and a new one - cannot be issued. - -2. The target device is selected by writing its address, as featured on the - device map, into ``Device Address`` on the controller. -3. The desired register address within the device register map is written into - ``Register Address`` on the controller. -4. The ``Read/Write`` register on the controller is set to 0x00. -5. The ``Trigger`` register on the controller is set to 0x01, triggering - configuration transmission. - - 1. (Controller) A register read is routed by the controller to the - appropriate device. - 2. (Controller) ``Trigger`` is set to 0x00 once the operation finishes. - 3. (Controller) ``CONFIGRACK`` is pushed into the signal stream if the - operation was successful, ``CONFIGRNACK`` is pushed if it failed. - -6. The signal stream must be pumped until either ``CONFIGRACK`` or - ``CONFIGRNACK`` is received indicating that controller has either: - - - Completed reading the specified device register and copied its value to - the ``Register Value`` register. - - Failed to read the register in which case the value of ``Register Value`` - contains invalid data. - -7. If operation was successful, the ``Register Value`` can be read. - -Register Write Sequence -^^^^^^^^^^^^^^^^^^^^^^^ -When a host requests a device register *write*, the following following -sequence must be performed: - -1. Check the value of ``Trigger``. - - - If it is 0, the procedure can proceed. - - Else, the hardware is busy with a previous transaction and a new one - cannot be issued. - -2. The target device is selected by writing its address, as featured on the - device map, into ``Device Address`` on the controller -3. The desired register address within the device register map is written into - ``Register Address`` on the controller. -4. The ``Read/Write`` register on the controller is set to 0x01. -5. The ``Trigger`` register on the controller is set to 0x01, triggering - configuration transmission. - - 1. (Controller) A register write is routed by the controller to the - appropriate device. - 2. (Controller) ``Trigger`` is set to 0x00 once the operation finishes. - 3. (Controller) ``CONFIGWACK`` is pushed into the signal stream if the - operation was successful, ``CONFIGWNACK`` is pushed if it failed. - -6. The signal stream must be pumped until either ``CONFIGWACK`` or - ``CONFIGWNACK`` is received indicating that the controller has either: - - - Successfully completed writing the specified device register. - - Failed to write the register. - -Following successful or unsuccessful device register read or write, the -appropriate ACK or NACK packets *must* be passed to the :ref:`signal channel -` by the controller. If they are not, the register read and write -calls will block indefinitely. - -Global Acquisition Registers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The following global acquisition registers provide information about, and -control over, the entire acquisition system: - -- ``Running``: Set to > 0 to run the system clock and produce data. Set to 0 to - stop the system clock and therefore stop data flow. Results in no other - configuration changes. - -- ``Reset``: Set to > 0 to trigger a hardware reset and send a fresh device - map to the host. Devices are reset but their managed registers might remain - unchanged, depending on their configuration (See the :ref:`Device registers - ` section for more information). Set to 0 by the controller - upon entering the reset state. - -- ``System Clock``: A read-only register specifying the master hardware clock - frequency in Hz. This is the clock used by the controller to perform data - transmission. - -- ``Acquisition Clock``: A read-only register specifying the system common - clock frequency in Hz. This clock is used to generate an acquisition counter - that timestamps data from all the devices. The ``Common_Timestamp`` in the - read :ref:`frame ` header is incremented at this frequency. - -- ``Reset Acquisition Counter``: This register is used to reset the counter - generating the ``Common_Timestamp`` used in the :ref:`device frames `. - A value of 1 will reset the counter to 0 without affecting the ``Running`` - state. A value of 2 will reset the counter and, at the same time, set - ``Running`` to 1, starting data production. - -- ``Hardware Address``: This is used for systems that allow multiple - controllers with a link between them to synchronize their - ``Common_Timestamps``. When resetting the acquisition counter through the - ``Reset acquisition counter`` on a device with a ``Hardware Address`` of 0, - this command will be sent through an external link to all non-zero devices, - synchronizing the counters. Multiple controller support or hardware-based - timestamp synchronization through dedicated links are optional features of an - ONI system. - diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst new file mode 100644 index 0000000..e770921 --- /dev/null +++ b/source/hw-spec/controller/addresses.rst @@ -0,0 +1,141 @@ +.. _addresses: + +ONI Controller address space +================================= + +An ONI :term:`Controller` has a 16-bit address register space, accessible through the :ref:`conf-chan`. + +The full address space is divided into three address blocks and a fourth currently reserved. The address blocks are: + +.. _address_global: + +Operation registers +------------------- + +**Address range:** 0x0000-0x3FFF + + +This address block is dedicated to controlling the operation of the system and accessing :ref:`dev-register`. + +The address map for this block is as follows: + +========== ========================= ================== +Address Name Type +========== ========================= ================== +0x0000 Reset Global +0x0001 Running Global +0x0002 System Clock Global +0x0003 Acquisition Clock Global +0x0004 Reset Acquisition Counter Global +0x0005 Hardware Address Global +0x0006 Device Address Register interface +0x0007 Register Address Register interface +0x0008 Register Value Register interface +0x0009 Read/Write Register interface +0x000A Trigger Register interface +========== ========================= ================== + +Global Acquisition Registers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following global acquisition registers provide information about, and +control over, the entire acquisition system: + +- ``Running``: Set to > 0 to run the system clock and produce data. Set to 0 to + stop the system clock and therefore stop data flow. Results in no other + configuration changes. + +- ``Reset``: Set to > 0 to trigger a hardware reset and send a fresh device + map to the host. Devices are reset but their managed registers might remain + unchanged, depending on their configuration (See the :ref:`Device registers + ` section for more information). Set to 0 by the controller + upon entering the reset state. + +- ``System Clock``: A read-only register specifying the master hardware clock + frequency in Hz. This is the clock used by the controller to perform data + transmission. + +- ``Acquisition Clock``: A read-only register specifying the system common + clock frequency in Hz. This clock is used to generate an acquisition counter + that timestamps data from all the devices. The ``Common_Timestamp`` in the + read :ref:`frame ` header is incremented at this frequency. + +- ``Reset Acquisition Counter``: This register is used to reset the counter + generating the ``Common_Timestamp`` used in the :ref:`device frames `. + A value of 1 will reset the counter to 0 without affecting the ``Running`` + state. A value of 2 will reset the counter and, at the same time, set + ``Running`` to 1, starting data production. + + .. _optional-num-sync-dev: + +- ``Hardware Address``: :ref:`(OPTIONAL) ` This is used for systems that allow multiple + controllers with a link between them to synchronize their + ``Common_Timestamps``. When resetting the acquisition counter through the + ``Reset acquisition counter`` on a device with a ``Hardware Address`` of 0, + this command will be sent through an external link to all non-zero devices, + synchronizing the counters. When supported, synchronization is only required + for controllers sharing a hardware implementation. + +Device Register Interface +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +These registers provide a standardized way to access :ref:`dev-register`. Read and write +procedures to device registers are detailed in :ref:`register_interface`. + +.. _address_spec: + +Specification parameters +------------------------- + +**Address range:** 0x4000-0x7FFF + +This block contains read-only registers that contain information about hardware +capabilities and ONI specification compliance. + +Currently defined addresses are: + +======== =========================== +Address Name +======== =========================== +0x4000 ONI specification version +0x4001 Read stream alignment +0x4002 Write stream alignment +0x4003 Maximum queued device register operations +0x4004 Number of supported synchronized devices +======== =========================== + +- **ONI specification version**: Specifies the version of the ONI specification the controller adheres to. + Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved + +.. _read-word-alignment-reg: + +- **Read stream alignment**: Specifies, in bits, the data word size the hardware implementation of + the :ref:`read channel ` uses for transmission. + +.. _write-word-alignment-reg: + +- **Write stream alignment**: Specifies, in bits, the data word size the hardware implementation of + the :ref:`write channel ` uses for transmission. + +.. _max-devaccess-reg: + +- **Maximum queued device register operations**: Maximum number of operations that can be queued through the + :ref:`register_interface` + +.. _optional-num-sync-dev-reg: + +- **Number of supported synchronized devices**: This register indicates if the optional capability + for :ref:`hardware synchronization` is supported. If 0, this controller can + not synchronize with others. if >0, it indicates the maximum number of controllers that can be synchronized + together. If the value is 0xFFFFFFFF, then there is no upper bound to this number. + + +.. _address_custom: + +Hardware-specific registers +---------------------------- +**Address range:** 0x8000-0xBFFF + +This block is reserved for hardware-specific registers that fall out of the scope of this specification +but might be required for the correct operation of a specific hardware implementation. + +The :term:`Driver Translator` should, to the possible extent, hide these from the :term:`API`. diff --git a/source/hw-spec/controller/channels/configuration_channel.rst b/source/hw-spec/controller/channels/configuration_channel.rst new file mode 100644 index 0000000..a0940ac --- /dev/null +++ b/source/hw-spec/controller/channels/configuration_channel.rst @@ -0,0 +1,18 @@ +.. _conf-chan: + +Configuration Channel +====================== + +- **Data alignment** : 32 bits +- **Channel type** : Register +- **Direction** : Read-Write + +The *configuration* channel supports addressed access to a set of registers. +The interface must use 32-bit values and 16-bit addressing. Controllers must +implement an :ref:`address map` with all the registers required +by the specification. + +This channel is also used to access the :ref:`register map ` +of the individual devices through an interface comprised of specific +:ref:`configuration registers`. + diff --git a/source/hw-spec/controller/channels/data_frames.rst b/source/hw-spec/controller/channels/data_frames.rst new file mode 100644 index 0000000..04227a1 --- /dev/null +++ b/source/hw-spec/controller/channels/data_frames.rst @@ -0,0 +1,33 @@ +.. _frame: + +Data Frames +============ + +Data transmission from the :ref:`read channel` and from the :ref:`write channel` +is packed in frames. Each frame is a timestamped +`type-length-value-encoded `__ +structure that contains data corresponding to a single device :ref:`sample `. +The frame format is: + +:: + + uint32 Device_Address + uint64 Common_Timestamp + uint32 Sample_Size + var Sample + +Where + +- ``Device_Address``: The address of the device producing the data, as featured + on the :ref:`device table `. +- ``Common_Timestamp``: A counter common to all devices generated by the + controller common acquisition clock. On write frames, this field is ignored. +- ``Sample_Size``: The full size of the sample, and must be equal to the + ``Read_Sample_Size`` field of the :ref:`device descriptor ` on read + frames or a multiple of the ``Write_Sample_Size`` on write frames. +- ``Sample``: The complete data sample as described on the :ref:`device sample + format ` section. + + + While a read frame must always contain a single sample as generated by the devices, + write frames can contain multiple samples targeted to the same device. \ No newline at end of file diff --git a/source/hw-spec/controller/channels/index.rst b/source/hw-spec/controller/channels/index.rst new file mode 100644 index 0000000..b204fd1 --- /dev/null +++ b/source/hw-spec/controller/channels/index.rst @@ -0,0 +1,38 @@ +.. _controller_channels: + +Controller communication channels +================================== + +Communication between the controller and the host computer shall occur over +four abstract communication channels: + +#. :ref:`data-rd-chan`: Read-only, high-bandwidth stream of device output :ref:`samples` from + controller to host. +#. :ref:`data-wr-chan`: Write-only, high-bandwidth stream of device input :ref:`samples` from + host to controller. +#. :ref:`sig-chan`: Read-only stream of short-messages and asynchronous hardware + events from controller to host. +#. :ref:`conf-chan`: Bidirectional, addressed access to device registers. + +API access to all these channels is blocking, i.e.: an API call that accesses +any channel will not return until the requested transaction on that channel is +complete. Concurrent access to a single channel by different threads is NOT +permitted. However, channels are independent and concurrent access to +*different* channels MUST be permitted. A stream transaction is defined as a +blocking read or write of a set number of bytes, while a register transaction +is defined as a single register read or write cycle to an individual address. + +The required characteristics of these channels are described in the following +sections. A complete understanding of their use during software development +requires an understanding of the :ref:`oni-api`. + +.. toctree:: + :hidden: + + data_frames + read_channel + write_channel + signal_channel + configuration_channel + + diff --git a/source/hw-spec/controller/channels/read_channel.rst b/source/hw-spec/controller/channels/read_channel.rst new file mode 100644 index 0000000..f60df59 --- /dev/null +++ b/source/hw-spec/controller/channels/read_channel.rst @@ -0,0 +1,31 @@ +.. _data-rd-chan: + +Read Channel +============= + +- **Data alignment** : 8 bits +- **Channel type** : Stream +- **Direction** : Read + +The *read* channel provides high bandwidth communication from the controller to +the host computer. Data from the read stream of all devices that support it is +aggregated and multiplexed by the controller and sent to the host through this +channel in the form of :ref:`frame`. + +Data should be pushed to this channel as quickly as possible. It is the +responsibility of the host computer to read data from the stream quickly enough +to keep up with data production by the controller. Therefore, it is highly +recommended that an ONI system implements some kind of internal buffering to +ameliorate the effects of uneven reading times caused by computer operating +systems or other software limitations. + +.. _read-word-alignment: + +Read word alignment +--------------------- + +Hardware implementations of controllers might require a :ref:`word size` +greater than 8 bits. In that case, the controller is required to increase the ``Read_Sample_Size`` +values of all devices on the :ref:`dev-table` so they fit into the required +word alignment. Extra bytes after the size defined on the :term:`Device Datasheet` +will be padded with 0xFF. \ No newline at end of file diff --git a/source/hw-spec/controller/channels/signal_channel.rst b/source/hw-spec/controller/channels/signal_channel.rst new file mode 100644 index 0000000..f4393aa --- /dev/null +++ b/source/hw-spec/controller/channels/signal_channel.rst @@ -0,0 +1,77 @@ +.. _sig-chan: + +Signal channel +=============== + +- **Data alignment** : 8 bits +- **Channel type** : Stream +- **Direction** : Read + +The *signal* channel provides a way for the controller to inform the host of +configuration results, which may be provided with a significant delay. +Additionally, it is the channel over which the controller sends the device table +to the host following a system reset. Signal data MUST be framed into packets +using Consistent Overhead Byte Stuffing +(`COBS `__). +Within this scheme, packets are delimited using 0's and always have the +following format: + +:: + + ... | PACKET_FLAG, data0, data1, ..., data_k | ... + +where ``PACKET_FLAG`` is 32-bit unsigned integer with a single unique bit +setting, ``|`` represents a packet delimiter (in this case, 0), “``,``” are for +visual clarity and are not actually in the data stream, and ``...`` represents +other packets. This stream can be read and ignored until a desired packet is +received. Reading this stream shall block if no data is available, which allows +asynchronous configuration acknowledgment. Valid ``PACKET_FLAG``\ s are: + +============ ========== ===================================== +Flag Value Description +============ ========== ===================================== +NULLSIG 0x00000001 Null signal, ignored by host +CONFIGWACK 0x00000002 Configuration write-acknowledgment +CONFIGWNACK 0x00000004 Configuration no-write-acknowledgment +CONFIGRACK 0x00000008 Configuration read-acknowledgment +CONFIGRNACK 0x00000010 Configuration no-read-acknowledgment +DEVICETABACK 0x00000020 Device table start acknowledgment +DEVICEINST 0x00000040 Device descriptor instance +============ ========== ===================================== + +Following a hardware reset, the signal channel is used to provide the +:ref:`device table ` to the host using the following packet +sequence: + +:: + + ... | DEVICETABACK, uint32 num_devices + | DEVICEINST, uint32 dev_addr_0, device_descriptor dev_0 + | DEVICEINST, uint32 dev_addr_1, device_descriptor dev_1 | + ... + | DEVICEINST, uint32 dev_addr_n, device_descriptor dev_n | ... + +Where ``dev_addr_n`` is the full address of each device as described in the +:ref:`device table ` section and ``dev_n`` is a :ref:`device +descriptor `. + +In addition to providing the device table following reset, the signal channel +is also used to asynchronously acknowledge register access via the +:ref:`configuration channel `. Following a device register read or +write, an CONFIGWACK, CONFIGWNACK, CONFIGRACK, or CONFIGRNACK signal is pushed +onto the signal stream by the controller to indicate the validity of the +transaction. In the case of a successful read, the CONFIGRACK flag will be +followed by the result of the read operation. In all other cases, the flag +will be sent with no additional data. + +For instance, on a successful register read: + +:: + + ... | CONFIGRACK, uint32 read_value | ... + +While on a succesful register write: + +:: + + ... | CONFIGWACK | ... \ No newline at end of file diff --git a/source/hw-spec/controller/channels/write_channel.rst b/source/hw-spec/controller/channels/write_channel.rst new file mode 100644 index 0000000..eb92707 --- /dev/null +++ b/source/hw-spec/controller/channels/write_channel.rst @@ -0,0 +1,32 @@ +.. _data-wr-chan: + +Write Channel +============== + +- **Data alignment** : 8 bits +- **Channel type** : Stream +- **Direction** : Write + +The *write* channel provides high bandwidth communication from the host computer +to the controller, and is used to send data to the devices. + +Data is sent through :ref:`frame` with their respective ``Common_Timestamp`` field +set to 0. Multiple samples can be sent in a single write frame. In this case, the +``Sample_Size`` field will be equal to the ``Write_Sample_Size`` multiplied by the +number of sent samples. + +It is the responsibility of the controller to accept frames at any rate the +computer might be sending them. Currently, there is no defined mechanism to +inform the host of any possible dropped frame on the write channel, +although this can be included in an implementation so long as it does not +invalidate any other ONI requirements. + +.. _write-word-alignment: + +Write word alignment +--------------------- + +Hardware implementations of controllers might require a :ref:`word size` +greater than 8 bits. In that case, the host will keep the specified sample sizes and just add +padding bytes with the value 0xFF at the end of a frame to align with the required word size. +The controller must ignore this padding bytes. \ No newline at end of file diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst new file mode 100644 index 0000000..6a6912c --- /dev/null +++ b/source/hw-spec/controller/index.rst @@ -0,0 +1,38 @@ +.. _controller: + +Controller +========== +The :term:`controller`'s purpose is to interface an ONI hardware system with the host +computer. It aggregates and routes device data and provides transparent access +to all devices, independently of their physical location. The host also +contains a common clock that is used to timestamp data from all devices, +independently of their origin hub. + +.. _controller_params: + +Hardware-specific parameters +----------------------------- + +Different ONI-compliant controller implementations might specify hardware-specific parameters related to standard ONI elements. +These need to be informed through a :ref:`specific address space ` reserved for ONI compliance parameters. +:term:`Driver translators ` can use this information to hide hardware-specific details to the +relevant :term:`API`. + +Optional features +^^^^^^^^^^^^^^^^^^^ + +Some features defined in the specification will be marked with the text ``(OPTIONAL)``. These features are not mandatory, +so different hardware implementations of a controller might chose to implement them or not. The ONI compliance +address space has specific registers for each declared optional feature which determine the availability of each +optional feature and its parameters, if applicable. + + +Communication +------------- + +.. toctree:: + :maxdepth: 1 + + channels/index + addresses + register_interface \ No newline at end of file diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst new file mode 100644 index 0000000..d19c250 --- /dev/null +++ b/source/hw-spec/controller/register_interface.rst @@ -0,0 +1,123 @@ +.. _register_interface: + +Device Register Programming Interface +====================================== + +The device programming interface allows transparent access to each device's +:ref:`register map `. It defines a general purpose bus that hides +the specifics of any particular implementation. + +Using this interface, the host adds device register access requests to an internal +queue. The controller will execute the requests in order. The :term:`Driver Translator` +and :term:`API` must ensure that the number of pending requests in the does not +exceed the :ref:`maximum queue size`. + +The register programming interface is composed of the following +:ref:`conf-chan` registers, which are used to insert requests into the queue: + +- ``Device Address``: The fully qualified address of a device as enumerated in + the :ref:`device table ` and to which communication will be + directed as described below. + +- ``Register Address``: The address of the register within the :ref:`register + map ` of the device located at ``Device Address`` that will be + written to or read from. + +- ``Register Value``: Value to be written to the register ``Register Address`` + of device located at ``Device Address``. For compatibility with older versions + of the specification, reading this register will return the value of the last + successful read operation. Using this register for reading the value this way + is not recommended. + +- ``Read/Write``: A flag indicating if a read or write should be performed. 0 + indicates read operation. A value > 0 indicates write operation. + +- ``Trigger``: Set > 0 to add either a register read or write operation + depending on the state of ``Read/Write``. If ``Read/Write`` is 0, a read + operation is queued. If ``Read/Write`` is 1, an operation to write ``Register Value`` + to the register at ``Register Address`` on the device at ``Device Address`` is queued. + Reading the ``Triger`` register returns 0 if the queue is empty or 1 if there are + pending operations. + +Appropriate values of ``Register Address`` and ``Register Value`` are +determined by: + +- Looking at a device's data sheet if the device is an integrated circuit and + using :ref:`raw registers `. +- Examining the :ref:`ONI Device Datasheet ` for :ref:`managed + registers `. + +Register Read Sequence +------------------------- + +When a host requests one of more device register *reads*, the following following sequence +must be performed: + +1. Check the value of ``Trigger``. + + - If it is 0, the queue is empty and the procedure can safely proceed. + - Else, there are transactions pending on the queue. Since the + exact number of pending elements is unknown, adding new transactions + is not recommended. + +2. For each register read transaction to be added to the queue: + + 1. The target device is selected by writing its address, as featured on the + device map, into ``Device Address`` on the controller. + 2. The desired register address within the device register map is written into + ``Register Address`` on the controller. + 3. The ``Read/Write`` register on the controller is set to 0x00. + 4. The ``Trigger`` register on the controller is set to 0x01, inserting the + operation on the queue. + 5. Repeat as needed until al read transactions have been queued. + +3. For each element on the queue, the controller will: + + 1. Route a register read operation to the appropriate device. + 2. Push ``CONFIGRACK`` followed by the read value into the signal stream if the + operation was successful, or ``CONFIGRNACK`` if it failed. + +4. The signal stream must be pumped until all ``CONFIGRACK`` or + ``CONFIGRNACK`` corresponding to all the requested transactions + are received indicating that the controller has finished execution. + +Register Write Sequence +------------------------- + +When a host requests one or more device register *writes*, the following following +sequence must be performed: + +1. Check the value of ``Trigger``. + + - If it is 0, the queue is empty and the procedure can safely proceed. + - Else, there are transactions pending on the queue. Since the + exact number of pending elements is unknown, adding new transactions + is not recommended. + +2. For each register write transaction to be added to the queue: + + 1. The target device is selected by writing its address, as featured on the + device map, into ``Device Address`` on the controller + 2. The desired register address within the device register map is written into + ``Register Address`` on the controller. + 3. The ``Read/Write`` register on the controller is set to 0x01. + 4. The value to be written into the device register is written into + the ``Register Value`` register in the controller. + 5. The ``Trigger`` register on the controller is set to 0x01, inserting the + operation on the queue. + 6. Repeat as needed until al read transactions have been queued. + +3. For each element on the queue, the controller will: + + 1. Route a register write operation to the appropriate device. + 2. Push ``CONFIGWACK`` into the signal stream if the operation was successful, + or ``CONFIGRNACK`` if it failed. + +4. The signal stream must be pumped until all ``CONFIGWACK`` or + ``CONFIGWNACK`` corresponding to all the requested transactions + are received indicating that the controller has finished execution. + +Following successful or unsuccessful device register read or write, the +appropriate ACK or NACK packets *must* be passed to the :ref:`signal channel +` by the controller. If they are not, the register read and write +calls will block indefinitely. \ No newline at end of file diff --git a/source/hw-spec/dev_table.rst b/source/hw-spec/dev_table.rst index 3e53aee..f7aee51 100644 --- a/source/hw-spec/dev_table.rst +++ b/source/hw-spec/dev_table.rst @@ -32,6 +32,12 @@ of :ref:`device descriptors `. - 8 - 0 +.. note:: The ``Read_Sample_Size`` reported on the device table might differ from the + one specified on the :term:`Device Datasheet` and :ref:`dev-desc` due to adjustments + required to comply to specific :ref:`hardware word size requirements`. + In this case, the host must ignore the extra bytes and decode the data as specified on the + datasheet. + .. _dev-address: Device Address diff --git a/source/hw-spec/index.rst b/source/hw-spec/index.rst index 2ff1d3a..befeec0 100755 --- a/source/hw-spec/index.rst +++ b/source/hw-spec/index.rst @@ -21,6 +21,6 @@ ONI Hardware Specification dev_table devices hubs - controller + controller/index From 82ebd1fc07bd347322dce55dddcdb96e5701c4c2 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 11 Nov 2024 15:30:31 +0100 Subject: [PATCH 02/31] Fix titles --- source/hw-spec/controller/addresses.rst | 2 +- source/hw-spec/controller/channels/index.rst | 2 +- source/hw-spec/controller/channels/read_channel.rst | 2 +- source/hw-spec/controller/channels/signal_channel.rst | 2 +- source/hw-spec/controller/channels/write_channel.rst | 2 +- source/hw-spec/controller/index.rst | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index e770921..d262566 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -1,6 +1,6 @@ .. _addresses: -ONI Controller address space +Controller Address Space ================================= An ONI :term:`Controller` has a 16-bit address register space, accessible through the :ref:`conf-chan`. diff --git a/source/hw-spec/controller/channels/index.rst b/source/hw-spec/controller/channels/index.rst index b204fd1..5572219 100644 --- a/source/hw-spec/controller/channels/index.rst +++ b/source/hw-spec/controller/channels/index.rst @@ -1,6 +1,6 @@ .. _controller_channels: -Controller communication channels +Controller Communication Channels ================================== Communication between the controller and the host computer shall occur over diff --git a/source/hw-spec/controller/channels/read_channel.rst b/source/hw-spec/controller/channels/read_channel.rst index f60df59..2517767 100644 --- a/source/hw-spec/controller/channels/read_channel.rst +++ b/source/hw-spec/controller/channels/read_channel.rst @@ -21,7 +21,7 @@ systems or other software limitations. .. _read-word-alignment: -Read word alignment +Read Word Alignment --------------------- Hardware implementations of controllers might require a :ref:`word size` diff --git a/source/hw-spec/controller/channels/signal_channel.rst b/source/hw-spec/controller/channels/signal_channel.rst index f4393aa..fe19f1f 100644 --- a/source/hw-spec/controller/channels/signal_channel.rst +++ b/source/hw-spec/controller/channels/signal_channel.rst @@ -1,6 +1,6 @@ .. _sig-chan: -Signal channel +Signal Channel =============== - **Data alignment** : 8 bits diff --git a/source/hw-spec/controller/channels/write_channel.rst b/source/hw-spec/controller/channels/write_channel.rst index eb92707..fc2a532 100644 --- a/source/hw-spec/controller/channels/write_channel.rst +++ b/source/hw-spec/controller/channels/write_channel.rst @@ -23,7 +23,7 @@ invalidate any other ONI requirements. .. _write-word-alignment: -Write word alignment +Write Word Alignment --------------------- Hardware implementations of controllers might require a :ref:`word size` diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index 6a6912c..d6413c6 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -10,7 +10,7 @@ independently of their origin hub. .. _controller_params: -Hardware-specific parameters +Hardware-specific Parameters ----------------------------- Different ONI-compliant controller implementations might specify hardware-specific parameters related to standard ONI elements. @@ -18,7 +18,7 @@ These need to be informed through a :ref:`specific address space ` :term:`Driver translators ` can use this information to hide hardware-specific details to the relevant :term:`API`. -Optional features +Optional Features ^^^^^^^^^^^^^^^^^^^ Some features defined in the specification will be marked with the text ``(OPTIONAL)``. These features are not mandatory, From df3f95ff79c4609d73e9bdae79658ece4bf02ad3 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 11 Nov 2024 15:54:36 +0100 Subject: [PATCH 03/31] Add address space overview --- source/hw-spec/controller/addresses.rst | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index d262566..d2adf17 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -7,6 +7,14 @@ An ONI :term:`Controller` has a 16-bit address register space, accessible throug The full address space is divided into three address blocks and a fourth currently reserved. The address blocks are: +:ref:`address_global`: 0x0000-0x3FFF + +:ref:`address_spec`: 0x4000-0x7FFF + +:ref:`address_custom`: 0x8000-0xBFFF + +:ref:`address_reserved`: xC000-0xFFFF + .. _address_global: Operation registers @@ -37,8 +45,8 @@ Address Name Type Global Acquisition Registers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following global acquisition registers provide information about, and -control over, the entire acquisition system: +The following global acquisition registers govern acquisition over a single +controller. - ``Running``: Set to > 0 to run the system clock and produce data. Set to 0 to stop the system clock and therefore stop data flow. Results in no other @@ -139,3 +147,10 @@ This block is reserved for hardware-specific registers that fall out of the scop but might be required for the correct operation of a specific hardware implementation. The :term:`Driver Translator` should, to the possible extent, hide these from the :term:`API`. + +.. _address_reserved: + +Reserved +---------- + +This address space is currently unused and must be reserved for future updates. \ No newline at end of file From 4b832f548a67d56f694a209bee19a8fc559fca1b Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 18 Nov 2024 15:55:30 +0100 Subject: [PATCH 04/31] Rewrite channel access concurrency description --- source/hw-spec/controller/channels/index.rst | 21 ++++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/source/hw-spec/controller/channels/index.rst b/source/hw-spec/controller/channels/index.rst index 5572219..ff285f3 100644 --- a/source/hw-spec/controller/channels/index.rst +++ b/source/hw-spec/controller/channels/index.rst @@ -14,17 +14,16 @@ four abstract communication channels: events from controller to host. #. :ref:`conf-chan`: Bidirectional, addressed access to device registers. -API access to all these channels is blocking, i.e.: an API call that accesses -any channel will not return until the requested transaction on that channel is -complete. Concurrent access to a single channel by different threads is NOT -permitted. However, channels are independent and concurrent access to -*different* channels MUST be permitted. A stream transaction is defined as a -blocking read or write of a set number of bytes, while a register transaction -is defined as a single register read or write cycle to an individual address. - -The required characteristics of these channels are described in the following -sections. A complete understanding of their use during software development -requires an understanding of the :ref:`oni-api`. +These channels are implemented by the combination of the controller hardware and the :term:`Driver Translator`. + +Concurrent access to a single channel by the host MUST NOT be permitted. However, individual +channels MUST be able to be accessed independently. + +.. note:: Concurrent access requirements relate only to the hardware implementation. Functions in + a high-level :term:`API` MAY introduce their own access dependencies and concurrency limitations. + +The required characteristics of the controller channels are described in the following +sections. .. toctree:: :hidden: From b6d1a3eb3da66a23a81a0512981491dfa64e5545 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 18 Nov 2024 19:45:19 +0100 Subject: [PATCH 05/31] Split device page --- source/hw-spec/devices.rst | 244 -------------------------- source/hw-spec/devices/datasheet.rst | 75 ++++++++ source/hw-spec/devices/descriptor.rst | 30 ++++ source/hw-spec/devices/devid.rst | 24 +++ source/hw-spec/{ => devices}/hubs.rst | 0 source/hw-spec/devices/index.rst | 34 ++++ source/hw-spec/devices/registers.rst | 66 +++++++ source/hw-spec/devices/sample.rst | 25 +++ source/hw-spec/devices/special.rst | 84 +++++++++ source/hw-spec/index.rst | 3 +- 10 files changed, 339 insertions(+), 246 deletions(-) delete mode 100644 source/hw-spec/devices.rst create mode 100644 source/hw-spec/devices/datasheet.rst create mode 100644 source/hw-spec/devices/descriptor.rst create mode 100644 source/hw-spec/devices/devid.rst rename source/hw-spec/{ => devices}/hubs.rst (100%) create mode 100644 source/hw-spec/devices/index.rst create mode 100644 source/hw-spec/devices/registers.rst create mode 100644 source/hw-spec/devices/sample.rst create mode 100644 source/hw-spec/devices/special.rst diff --git a/source/hw-spec/devices.rst b/source/hw-spec/devices.rst deleted file mode 100644 index ea3bd18..0000000 --- a/source/hw-spec/devices.rst +++ /dev/null @@ -1,244 +0,0 @@ -.. _device: - -Devices -======= -Devices are the endpoint of most ONI transactions. They can represent a -physical element interfacing with the environment (e.g., an external sensor with -a digital communication interface), something programmed within the firmware to -emulate this (e.g., a digital logic module on an FPGA) or a purely internal data -source (e.g., a controller based digital logic module that generates system -status reports). A device exposes the following :ref:`communication channels -`: - -- A MANDATORY register interface -- An OPTIONAL read stream -- An OPTIONAL write stream - -Communication over streams follows a specific :ref:`sample format -`, while the register interface must comply with a specific bus -communication cycle. Details on each are provided in following sections. Device -developers MUST provide a :ref:`datasheet ` describing the -register map, stream data format, along with general behavior of the device in -order to reach ONI-compliance. - -.. _dev-id: - -Device ID ---------- -Different types of devices MUST have a unique identification integer called a -Device ID. Device IDs are 32-bit integers with the following format: - -:: - - Reserved(8-bit).Company(8-bit).Device(16-bit) - -- ``Reserved``: Reserved for future specification revision. Currently ignored. -- ``Company``: Any person, lab, institute, informal group, or company can - communicate with Open Ephys in order to to obtain a unique 8-bit “Company” - value, and thus be included in the automatic listings of existing ONI API - implementations. Open Ephys is 0x00. -- ``Device``: 16-bit Device ID. This number identifies not only the type of - data produced or consumed by a device, but also a particular implementation. - For instance, the same sensor will have a unique Device ID for each digital - module implementation that is used to communicate with it. This number can - optionally be divided in two 8-bit values so long as the resulting 16-bit - integer is unique within a particular “Company” (there is no need for unary - or monotonic increments when new devices are introduced). - -.. _dev-desc: - -Device Descriptor ------------------ -A device MUST expose a descriptor that is read by the :ref:`controller -` following a reset and that is incorporated into the :ref:`device -table `. The descriptor must contain the following information: - -:: - - uint32 Device_ID - uint32 Device_Version - uint32 Read_Sample_Size - uint32 Write_Sample_Size - -- ``Device_ID``: :ref:`As previously described. `. -- ``Device_Version``: A version number to distinguish between implementations - of a singular device type. Different versions that address minor issues MUST - NOT change the device's sample data format or alter an existing register - map. However, register additions that do not affect the existing register map - are allowed. Any change that warrants a modification of a device's streaming - data format, read size, write size, or existing register map MUST be - implemented as a new :ref:`Device ID `. -- ``Read_Sample_Size``: The length in bytes of a single :ref:`device sample - ` produced by the device and sent to the :ref:`read stream - `. -- ``Write_Sample_Size``: The length in bytes of a single :ref:`device - sample ` consumed by the device from the :ref:`write stream - `. - -.. _dev-sample: - -Device Sample Format --------------------- -Data passed over the read or write streams are transmitted in unit packets, -or “samples”. A sample transmitted over the read stream MUST have the following -format: - -:: - - uint64 Hub_Timestamp (Read Stream Only) - var Payload - -- ``Hub_Timestamp``: For samples produced by the device and sent to the read - stream, this is a common counter for all devices in a :ref:`Hub `, - indicating the time of sample capture. For samples consumed by the device - from the write stream, this value is reserved. -- ``Payload``: Device-specific data. - - - For :ref:`read streams `, this data must be of :ref:`Read Sample - Size ` - 8. - - For :ref:`write streams `, this data must be of :ref:`Write Sample - Size `. Thus, the whole sample packet fits into the sample - size specified in the :ref:`device descriptor `. - -.. _dev-register: - -Device Registers ----------------- - -.. _reg-type: - -Register Type -~~~~~~~~~~~~~ - -Device registers can be separated into two types: - -- **Raw registers**: Those that correspond 1:1 to the physical register space - of an external electrical component (e.g., the register map in the - manufacturer datasheet of a sensor IC). -- **Managed registers**: Those designed to interface exclusively with an ONI - system, usually implemented in firmware and described in a :ref:`ONI Device - Datasheet `. - -Raw registers provide a direct window to the underlying hardware. On the other -hand, managed registers provide flexibility and abstract control over device -state. For instance, managed registers may provide access to abstract properties -that require access to multiple physical registers in hardware, which can all be -completed in a single register read or write cycle. Thus the firmware can -manage low-level raw access to the hardware, while exposing only high-level -abstract registers in order to simplify the interface to user applications. - -Register Access and Update -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Registers, independently of their :ref:`type `, can be defined as -Read-Write, Read-Only or Write-Only. All registers MUST have a valid value at -power-on. Whenever a device receives a reset request generated by the -controller, registers might either be reset to their power-on value or keep -their current value. This can be defined independently for each register. - -All register writes, regardless of reset behavior, MUST be immediate (i.e., for -a Read-Write register, reading a register after being written must reflect the -new value). However, the *effects* of a register might not occur until the next -reset. An example of this type of behavior is registers that operate on the -:ref:`device descriptor `. The descriptor must be static during runtime, -but registers affecting it might take action after a reset, providing an updated -descriptor to the controller. - -Register access, bit-field definitions, reset behavior, and time of effect MUST -be specified in the hardware datasheet for raw registers or the :ref:`ONI Device -Datasheet ` for managed registers. - -.. _dev-reg-map: - -Register Map -~~~~~~~~~~~~ - -A device can optionally implement raw registers and MUST implement at least one -managed register, ``ENABLE``, a Read-Write register that takes effect after -reset. When ``ENABLE`` is disabled, the device must not produce any data -through the :ref:`read stream `. - -The location of the managed registers depends on the existence of raw -registers. If the device implements raw registers, those are mapped to -addresses 0x0000 to 0x7FFF, corresponding to the same address map of the -underlying hardware, and managed registers start from 0x80000. If no raw -registers are present, managed registers start from 0x0000 instead. - -The ``ENABLE`` register MUST be the first of the managed registers, at 0x0000 if -no raw registers are present, 0x8000 if raw registers are implemented. - -.. _dev-datasheet: - -Device Datasheet ----------------- -All ONI-compliant devices MUST have a corresponding datasheet that provides -information on register programming and data IO. The datasheet must be served -publicly. It can be a text file, PDF, or website. The required datasheet -sections and information are described below. - -Preamble -~~~~~~~~ -The following information is required in the preamble: - -1. **Informal device name**: Name of the device. There are no textual - requirements for this field. (e.g., ChipXYX, Chip XYX, and My~Chip-12ab!, are - all valid). -2. **Author(s)**: Device firmware or chip creator(s). Can be a person/people or - a company, group, or organization. -3. **Device Version**: The :ref:`device version ` that this datasheet - corresponds to. -4. **Device ID**: The :ref:`device ID ` that this datasheet corresponds - to. - -Description -~~~~~~~~~~~ -A textual description of the functionality of the device. This can be simple or -detailed and is meant to be useful for upstream hardware and software develops -for understanding the nature of the device during their work. - -Register Map -~~~~~~~~~~~~ - -Raw Registers -^^^^^^^^^^^^^^^^^^^ -If the device uses :ref:`raw registers `, then a link to the -manufacturer's datasheet is all that is required so long as it contains the -register documentation equivalent to that required by :ref:`managed registers -`. However, the register map can also be reproduced for -clarity or if the manufacturer's datasheet is missing required information. - -Managed Registers -^^^^^^^^^^^^^^^^^ -If the device uses :ref:`managed registers `, a table that describes the -managed register map is required. There are no formatting requirements for this -table, but it MUST contain the following columns: - -- **Address**: Register address within the :ref:`register map `. -- **Name**: Human readable name for the register. Only capital ASCII letters - and underscores are allowed, with no spaces or special characters (e.g. - ``VALID`` and ``ALSO_VALID`` vs. ``NotValid`` and ``ALSO-NOT-VALID``). -- **Access**: Read-only, write-only, or read-write. -- **Time of Effect**: When does a register write affect hardware state? - Immediately or following reset? -- **POR Value**: Power-on reset default value. -- **Reset Action**: Upon a reset, what happens to the register? Does it - maintain its previous state or get reset to some value? If the latter, then - what value? -- **Description**: Word description of the register's function. - -Additional columns are permitted so long as their information does not conflict -with that in the required columns. - -Read Frame Format -~~~~~~~~~~~~~~~~~ -If the device produces frames, a -`bitfield `__ diagram describing the -frame structure is required. Bits can be grouped into words as is convenient. If -no frames are produced, then a statement of such is required. - -Write Frame Format -~~~~~~~~~~~~~~~~~~ -If the device accepts frames, a -`bitfield `__ diagram describing the -frame structure is required. Bits can be grouped into words as is convenient. If -no frames are accepted, then a statement of such is required. diff --git a/source/hw-spec/devices/datasheet.rst b/source/hw-spec/devices/datasheet.rst new file mode 100644 index 0000000..5385eda --- /dev/null +++ b/source/hw-spec/devices/datasheet.rst @@ -0,0 +1,75 @@ +.. _dev-datasheet: + +Device Datasheet +---------------- +All ONI-compliant devices MUST have a corresponding datasheet that provides +information on register programming and data IO. The datasheet must be served +publicly. It can be a text file, PDF, or website. The required datasheet +sections and information are described below. + +Preamble +~~~~~~~~ +The following information is required in the preamble: + +1. **Informal device name**: Name of the device. There are no textual + requirements for this field. (e.g., ChipXYX, Chip XYX, and My~Chip-12ab!, are + all valid). +2. **Author(s)**: Device firmware or chip creator(s). Can be a person/people or + a company, group, or organization. +3. **Device Version**: The :ref:`device version ` that this datasheet + corresponds to. +4. **Device ID**: The :ref:`device ID ` that this datasheet corresponds + to. + +Description +~~~~~~~~~~~ +A textual description of the functionality of the device. This can be simple or +detailed and is meant to be useful for upstream hardware and software develops +for understanding the nature of the device during their work. + +Register Map +~~~~~~~~~~~~ + +Raw Registers +^^^^^^^^^^^^^^^^^^^ +If the device uses :ref:`raw registers `, then a link to the +manufacturer's datasheet is all that is required so long as it contains the +register documentation equivalent to that required by :ref:`managed registers +`. However, the register map can also be reproduced for +clarity or if the manufacturer's datasheet is missing required information. + +Managed Registers +^^^^^^^^^^^^^^^^^ +If the device uses :ref:`managed registers `, a table that describes the +managed register map is required. There are no formatting requirements for this +table, but it MUST contain the following columns: + +- **Address**: Register address within the :ref:`register map `. +- **Name**: Human readable name for the register. Only capital ASCII letters + and underscores are allowed, with no spaces or special characters (e.g. + ``VALID`` and ``ALSO_VALID`` vs. ``NotValid`` and ``ALSO-NOT-VALID``). +- **Access**: Read-only, write-only, or read-write. +- **Time of Effect**: When does a register write affect hardware state? + Immediately or following reset? +- **POR Value**: Power-on reset default value. +- **Reset Action**: Upon a reset, what happens to the register? Does it + maintain its previous state or get reset to some value? If the latter, then + what value? +- **Description**: Word description of the register's function. + +Additional columns are permitted so long as their information does not conflict +with that in the required columns. + +Read Frame Format +~~~~~~~~~~~~~~~~~ +If the device produces frames, a +`bitfield `__ diagram describing the +frame structure is required. Bits can be grouped into words as is convenient. If +no frames are produced, then a statement of such is required. + +Write Frame Format +~~~~~~~~~~~~~~~~~~ +If the device accepts frames, a +`bitfield `__ diagram describing the +frame structure is required. Bits can be grouped into words as is convenient. If +no frames are accepted, then a statement of such is required. \ No newline at end of file diff --git a/source/hw-spec/devices/descriptor.rst b/source/hw-spec/devices/descriptor.rst new file mode 100644 index 0000000..ac19103 --- /dev/null +++ b/source/hw-spec/devices/descriptor.rst @@ -0,0 +1,30 @@ +.. _dev-desc: + +Device Descriptor +================== + +A device MUST expose a descriptor that is read by the :ref:`controller +` following a reset and that is incorporated into the :ref:`device +table `. The descriptor must contain the following information: + +:: + + uint32 Device_ID + uint32 Device_Version + uint32 Read_Sample_Size + uint32 Write_Sample_Size + +- ``Device_ID``: :ref:`As previously described. `. +- ``Device_Version``: A version number to distinguish between implementations + of a singular device type. Different versions that address minor issues MUST + NOT change the device's sample data format or alter an existing register + map. However, register additions that do not affect the existing register map + are allowed. Any change that warrants a modification of a device's streaming + data format, read size, write size, or existing register map MUST be + implemented as a new :ref:`Device ID `. +- ``Read_Sample_Size``: The length in bytes of a single :ref:`device sample + ` produced by the device and sent to the :ref:`read stream + `. +- ``Write_Sample_Size``: The length in bytes of a single :ref:`device + sample ` consumed by the device from the :ref:`write stream + `. \ No newline at end of file diff --git a/source/hw-spec/devices/devid.rst b/source/hw-spec/devices/devid.rst new file mode 100644 index 0000000..a53d5c2 --- /dev/null +++ b/source/hw-spec/devices/devid.rst @@ -0,0 +1,24 @@ +.. _dev-id: + +Device ID +========= +Device implementations MUST declare a unique identification integer called a Device ID. +Devices sharing an ID are assumed to be the same and share the same :ref:`dev-datasheet`. +Device IDs are 32-bit integers with the following format: + +:: + + Reserved(8-bit).Company(8-bit).Device(16-bit) + +- ``Reserved``: Reserved for future specification revision. Currently ignored. +- ``Company``: Any person, lab, institute, informal group, or company can + communicate with Open Ephys in order to to obtain a unique 8-bit “Company” + value, and thus be included in the automatic listings of existing ONI API + implementations. Open Ephys is 0x00. +- ``Device``: 16-bit Device ID. This number identifies not only the type of + data produced or consumed by a device, but also a particular implementation. + For instance, the same sensor will have a unique Device ID for each digital + module implementation that is used to communicate with it. This number can + optionally be divided in two 8-bit values so long as the resulting 16-bit + integer is unique within a particular “Company” (there is no need for unary + or monotonic increments when new devices are introduced). diff --git a/source/hw-spec/hubs.rst b/source/hw-spec/devices/hubs.rst similarity index 100% rename from source/hw-spec/hubs.rst rename to source/hw-spec/devices/hubs.rst diff --git a/source/hw-spec/devices/index.rst b/source/hw-spec/devices/index.rst new file mode 100644 index 0000000..fb29142 --- /dev/null +++ b/source/hw-spec/devices/index.rst @@ -0,0 +1,34 @@ +.. _device: + +Devices +======= +Devices are the endpoint of most ONI transactions. They can represent a +physical element interfacing with the environment (e.g., an external sensor with +a digital communication interface), something programmed within the firmware to +emulate this (e.g., a digital logic module on an FPGA) or a purely internal data +source (e.g., a controller based digital logic module that generates system +status reports). A device MUST expose the following :ref:`communication channels +`: + +- A REQUIRED register interface +- An OPTIONAL read stream +- An OPTIONAL write stream + +Communication over streams MUST follow a specific :ref:`sample format +`, while the register interface must comply with a specific bus +communication cycle. Details on each are provided in following sections. Device +developers MUST provide a :ref:`datasheet ` describing the +register map, stream data format, along with general behavior of the device in +order to reach ONI-compliance. + +.. toctree:: + :hidden: + + devid + descriptor + sample + descriptor + registers + datasheet + hubs + special diff --git a/source/hw-spec/devices/registers.rst b/source/hw-spec/devices/registers.rst new file mode 100644 index 0000000..ce05c64 --- /dev/null +++ b/source/hw-spec/devices/registers.rst @@ -0,0 +1,66 @@ +.. _dev-register: + +Device Registers +================== + +.. _reg-type: + +Register Type +-------------- + +Device registers can be separated into two types: + +- **Raw registers**: Those that correspond 1:1 to the physical register space + of an external electrical component (e.g., the register map in the + manufacturer datasheet of a sensor IC). +- **Managed registers**: Those designed to interface exclusively with an ONI + system, usually implemented in firmware and described in a :ref:`ONI Device + Datasheet `. + +Raw registers provide a direct window to the underlying hardware. On the other +hand, managed registers provide flexibility and abstract control over device +state. For instance, managed registers may provide access to abstract properties +that require access to multiple physical registers in hardware, which can all be +completed in a single register read or write cycle. Thus the firmware can +manage low-level raw access to the hardware, while exposing only high-level +abstract registers in order to simplify the interface to user applications. + +Register Access and Update +----------------------------- + +Registers, independently of their :ref:`type `, can be defined as +Read-Write, Read-Only or Write-Only. All registers MUST have a valid value at +power-on. Whenever a device receives a reset request generated by the +controller, registers might either be reset to their power-on value or keep +their current value. This can be defined independently for each register. + +All register writes, regardless of reset behavior, MUST be immediate (i.e., for +a Read-Write register, reading a register after being written must reflect the +new value). However, the *effects* of a register might not occur until the next +reset. An example of this type of behavior is registers that operate on the +:ref:`device descriptor `. The descriptor must be static during runtime, +but registers affecting it might take action after a reset, providing an updated +descriptor to the controller. + +Register access, bit-field definitions, reset behavior, and time of effect MUST +be specified in the hardware datasheet for raw registers or the :ref:`ONI Device +Datasheet ` for managed registers. + +.. _dev-reg-map: + +Register Map +------------- + +A device can optionally implement raw registers and MUST implement at least one +managed register, ``ENABLE``, a Read-Write register that takes effect after +reset. When ``ENABLE`` is disabled, the device must not produce any data +through the :ref:`read stream `. + +The location of the managed registers depends on the existence of raw +registers. If the device implements raw registers, those are mapped to +addresses 0x0000 to 0x7FFF, corresponding to the same address map of the +underlying hardware, and managed registers start from 0x80000. If no raw +registers are present, managed registers start from 0x0000 instead. + +The ``ENABLE`` register MUST be the first of the managed registers, at 0x0000 if +no raw registers are present, 0x8000 if raw registers are implemented. \ No newline at end of file diff --git a/source/hw-spec/devices/sample.rst b/source/hw-spec/devices/sample.rst new file mode 100644 index 0000000..c8142f8 --- /dev/null +++ b/source/hw-spec/devices/sample.rst @@ -0,0 +1,25 @@ +.. _dev-sample: + +Device Sample Format +===================== + +Data passed over the read or write streams are transmitted in unit packets, +or “samples”. A sample transmitted over the read stream MUST have the following +format: + +:: + + uint64 Hub_Timestamp (Read Stream Only) + var Payload + +- ``Hub_Timestamp``: For samples produced by the device and sent to the read + stream, this is a common counter for all devices in a :ref:`Hub `, + indicating the time of sample capture. For samples consumed by the device + from the write stream, this value is reserved. +- ``Payload``: Device-specific data. + + - For :ref:`read streams `, this data must be of :ref:`Read Sample + Size ` - 8. + - For :ref:`write streams `, this data must be of :ref:`Write Sample + Size `. Thus, the whole sample packet fits into the sample + size specified in the :ref:`device descriptor `. \ No newline at end of file diff --git a/source/hw-spec/devices/special.rst b/source/hw-spec/devices/special.rst new file mode 100644 index 0000000..f609547 --- /dev/null +++ b/source/hw-spec/devices/special.rst @@ -0,0 +1,84 @@ +.. _special-devs: + +Special Devices +================ +There are two kinds of special devices that are required by this specification: +An information device on each hub and a heartbeat device in local hub 0. + +Information Device +-------------------- +Every hub in an ONI system must feature a special device, located at +:ref:`Device_Address ` 0xFE, which supplies information about the hub. +Because this device is required to exist at a fixed address, it is not listed +in the device table and, thus, has no :ref:`device descriptor `. The only +communication channel it must expose is the register interface, and it must not +include any streams. The required register map is: + +======= ================================ +Address Register +======= ================================ +0x0000 Hardware ID +0x0001 Hardware revision +0x0002 Firmware version +0x0003 (OPTIONAL) Safe firmware version +0x0004 Hub clock frequency +0x0005 Hub data latency +======= ================================ + +Although all register reads are 32-bits in nature, not all registers make use of +the complete width. The detailed meaning of each register is: + +- **Hardware ID**: A 32-bit value that uniquely identifies the hub. It has a + similar format to the :ref:`Device ID `: + + :: + + Reserved(8-bit).Company(8-bit).Hub(16-bit) + + - ``Reserved``: Reserved for future specification revision. Currently + ignored. + - ``Company``: Any person, lab, institute, informal group, or company can + communicate with Open Ephys in order to to obtain a unique 8-bit “Company” + value, and thus be included in the automatic listings of existing ONI API + implementations. Open Ephys is 0x00. + - ``Hub``: 16-bit Hub ID. This number usually identifies a physical product + and would correspond to a stock keeping unit SKU or part number in a + commercial setting. However, there is no formal restriction on these bits + other than uniqueness. + +- **Hardware revision**: A 16-bit value identifying changes in the hardware + that do not affect the overall operation of the hub and, therefore, do not + require a new ID. These are typically related to a PCB revision. + +- **Firmware version**: A 16-bit value specifying firmware or gateware version + of the main component driving the hub (e.g., an FPGA, microcontroller, or + EEPROM for logic-free hubs). + +- **Safe firmware version**: (Optional) For hubs that allow online updates of + the firmware, 16-bit version of the fallback safe image, if any. + +- **Hub clock frequency**: 32-bit value holding the frequency, in Hz, of the + hub clock that drives the *Hub_Timestamp* passed to the devices. + +- **Hub data latency**: 32-bit value representing the average latency, in + nanoseconds, of the physical link between the hub and the controller. Usually + 0 in local hubs. + +All 16-bit versions are in the format of: + +:: + + Major(8-bit).Minor(8-bit). + +For example, 0x0103 would imply version 1.3. In the case of the information +device located on hub 0, the versions refer to the physical controller hardware +and its firmware, where that hub is located. + +Heartbeat Device +------------------ +Local hub 0 must contain a “heartbeat device”. This is a simple device that +periodically produces :ref:`samples ` containing only the ``Hub +Timestamp`` and an empty payload, at a minimum rate of 10 Hz. Its ``ENABLE`` +register must be fixed and always active. This device ensures that API calls +accessing the read stream are guaranteed to be unblocked in the case that no +other devices in the system are producing data. diff --git a/source/hw-spec/index.rst b/source/hw-spec/index.rst index befeec0..4db648a 100755 --- a/source/hw-spec/index.rst +++ b/source/hw-spec/index.rst @@ -19,8 +19,7 @@ ONI Hardware Specification hierarchy comm_channels dev_table - devices - hubs + devices/index controller/index From b5d42eb9449b6dbceaa721a9b8b92d6814ecf3c8 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 18 Nov 2024 20:36:19 +0100 Subject: [PATCH 06/31] Remove grammatically erroneous commas --- source/hw-spec/devices/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/hw-spec/devices/index.rst b/source/hw-spec/devices/index.rst index fb29142..e9f7969 100644 --- a/source/hw-spec/devices/index.rst +++ b/source/hw-spec/devices/index.rst @@ -3,10 +3,10 @@ Devices ======= Devices are the endpoint of most ONI transactions. They can represent a -physical element interfacing with the environment (e.g., an external sensor with +physical element interfacing with the environment (e.g. an external sensor with a digital communication interface), something programmed within the firmware to -emulate this (e.g., a digital logic module on an FPGA) or a purely internal data -source (e.g., a controller based digital logic module that generates system +emulate this (e.g. a digital logic module on an FPGA) or a purely internal data +source (e.g. a controller based digital logic module that generates system status reports). A device MUST expose the following :ref:`communication channels `: From ac96c870818aea8b14432152e0b7d384297c7535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aar=C3=B3n=20Cuevas=20L=C3=B3pez?= Date: Mon, 18 Nov 2024 20:55:07 +0100 Subject: [PATCH 07/31] Remove special devices section from hubs Redundant since it is on its own file. --- source/hw-spec/devices/hubs.rst | 83 --------------------------------- 1 file changed, 83 deletions(-) diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/devices/hubs.rst index ab4b3b1..0eeabe7 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/devices/hubs.rst @@ -33,87 +33,4 @@ with the controller through a specific link. Changes in the device collection, the communications link or the general hardware architecture require a new identifier. -.. _special-devs: -Special Devices ---------------- -There are two kinds of special devices that are required by this specification: -An information device on each hub and a heartbeat device in local hub 0. - -Information Device -~~~~~~~~~~~~~~~~~~ -Every hub in an ONI system must feature a special device, located at -:ref:`Device_Address ` 0xFE, which supplies information about the hub. -Because this device is required to exist at a fixed address, it is not listed -in the device table and, thus, has no :ref:`device descriptor `. The only -communication channel it must expose is the register interface, and it must not -include any streams. The required register map is: - -======= ================================ -Address Register -======= ================================ -0x0000 Hardware ID -0x0001 Hardware revision -0x0002 Firmware version -0x0003 (OPTIONAL) Safe firmware version -0x0004 Hub clock frequency -0x0005 Hub data latency -======= ================================ - -Although all register reads are 32-bits in nature, not all registers make use of -the complete width. The detailed meaning of each register is: - -- **Hardware ID**: A 32-bit value that uniquely identifies the hub. It has a - similar format to the :ref:`Device ID `: - - :: - - Reserved(8-bit).Company(8-bit).Hub(16-bit) - - - ``Reserved``: Reserved for future specification revision. Currently - ignored. - - ``Company``: Any person, lab, institute, informal group, or company can - communicate with Open Ephys in order to to obtain a unique 8-bit “Company” - value, and thus be included in the automatic listings of existing ONI API - implementations. Open Ephys is 0x00. - - ``Hub``: 16-bit Hub ID. This number usually identifies a physical product - and would correspond to a stock keeping unit SKU or part number in a - commercial setting. However, there is no formal restriction on these bits - other than uniqueness. - -- **Hardware revision**: A 16-bit value identifying changes in the hardware - that do not affect the overall operation of the hub and, therefore, do not - require a new ID. These are typically related to a PCB revision. - -- **Firmware version**: A 16-bit value specifying firmware or gateware version - of the main component driving the hub (e.g., an FPGA, microcontroller, or - EEPROM for logic-free hubs). - -- **Safe firmware version**: (Optional) For hubs that allow online updates of - the firmware, 16-bit version of the fallback safe image, if any. - -- **Hub clock frequency**: 32-bit value holding the frequency, in Hz, of the - hub clock that drives the *Hub_Timestamp* passed to the devices. - -- **Hub data latency**: 32-bit value representing the average latency, in - nanoseconds, of the physical link between the hub and the controller. Usually - 0 in local hubs. - -All 16-bit versions are in the format of: - -:: - - Major(8-bit).Minor(8-bit). - -For example, 0x0103 would imply version 1.3. In the case of the information -device located on hub 0, the versions refer to the physical controller hardware -and its firmware, where that hub is located. - -Heartbeat Device -~~~~~~~~~~~~~~~~ -Local hub 0 must contain a “heartbeat device”. This is a simple device that -periodically produces :ref:`samples ` containing only the ``Hub -Timestamp`` and an empty payload, at a minimum rate of 10 Hz. Its ``ENABLE`` -register must be fixed and always active. This device ensures that API calls -accessing the read stream are guaranteed to be unblocked in the case that no -other devices in the system are producing data. From d66d17e3d7bd755a4a6c441d408997202864c7b2 Mon Sep 17 00:00:00 2001 From: jonnew Date: Mon, 18 Nov 2024 15:29:31 -0500 Subject: [PATCH 08/31] Fix duplicate sections and text - Special devices was duplicated - Device descriptor was duplicated --- source/hw-spec/devices/descriptor.rst | 6 +- source/hw-spec/devices/hubs.rst | 89 +-------------------------- source/hw-spec/devices/index.rst | 3 +- 3 files changed, 6 insertions(+), 92 deletions(-) diff --git a/source/hw-spec/devices/descriptor.rst b/source/hw-spec/devices/descriptor.rst index ac19103..18135af 100644 --- a/source/hw-spec/devices/descriptor.rst +++ b/source/hw-spec/devices/descriptor.rst @@ -14,10 +14,10 @@ table `. The descriptor must contain the following information: uint32 Read_Sample_Size uint32 Write_Sample_Size -- ``Device_ID``: :ref:`As previously described. `. +- ``Device_ID``: :ref:`As previously described `. - ``Device_Version``: A version number to distinguish between implementations - of a singular device type. Different versions that address minor issues MUST - NOT change the device's sample data format or alter an existing register + of a singular device type. Different versions MUST + NOT change the device's sample data format or alter an existing register map. However, register additions that do not affect the existing register map are allowed. Any change that warrants a modification of a device's streaming data format, read size, write size, or existing register map MUST be diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/devices/hubs.rst index ab4b3b1..07305b5 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/devices/hubs.rst @@ -3,8 +3,8 @@ Hubs ==== Hubs are collections of devices sharing a common clock. They can be independent -hardware aggregates connected to the controller (e.g., a headstage for neural -acquisition) or a logical partition of existing hardware (e.g., a collection of +hardware aggregates connected to the controller (e.g. a headstage for neural +acquisition) or a logical partition of existing hardware (e.g. a collection of devices implemented in the same firmware as the controller). Hubs that exist on hardware that is physically separated from the :ref:`controller ` are referred to as remote hubs, while hubs existing on the controller are local hubs. @@ -32,88 +32,3 @@ particular collection of devices on a specific hardware platform communicating with the controller through a specific link. Changes in the device collection, the communications link or the general hardware architecture require a new identifier. - -.. _special-devs: - -Special Devices ---------------- -There are two kinds of special devices that are required by this specification: -An information device on each hub and a heartbeat device in local hub 0. - -Information Device -~~~~~~~~~~~~~~~~~~ -Every hub in an ONI system must feature a special device, located at -:ref:`Device_Address ` 0xFE, which supplies information about the hub. -Because this device is required to exist at a fixed address, it is not listed -in the device table and, thus, has no :ref:`device descriptor `. The only -communication channel it must expose is the register interface, and it must not -include any streams. The required register map is: - -======= ================================ -Address Register -======= ================================ -0x0000 Hardware ID -0x0001 Hardware revision -0x0002 Firmware version -0x0003 (OPTIONAL) Safe firmware version -0x0004 Hub clock frequency -0x0005 Hub data latency -======= ================================ - -Although all register reads are 32-bits in nature, not all registers make use of -the complete width. The detailed meaning of each register is: - -- **Hardware ID**: A 32-bit value that uniquely identifies the hub. It has a - similar format to the :ref:`Device ID `: - - :: - - Reserved(8-bit).Company(8-bit).Hub(16-bit) - - - ``Reserved``: Reserved for future specification revision. Currently - ignored. - - ``Company``: Any person, lab, institute, informal group, or company can - communicate with Open Ephys in order to to obtain a unique 8-bit “Company” - value, and thus be included in the automatic listings of existing ONI API - implementations. Open Ephys is 0x00. - - ``Hub``: 16-bit Hub ID. This number usually identifies a physical product - and would correspond to a stock keeping unit SKU or part number in a - commercial setting. However, there is no formal restriction on these bits - other than uniqueness. - -- **Hardware revision**: A 16-bit value identifying changes in the hardware - that do not affect the overall operation of the hub and, therefore, do not - require a new ID. These are typically related to a PCB revision. - -- **Firmware version**: A 16-bit value specifying firmware or gateware version - of the main component driving the hub (e.g., an FPGA, microcontroller, or - EEPROM for logic-free hubs). - -- **Safe firmware version**: (Optional) For hubs that allow online updates of - the firmware, 16-bit version of the fallback safe image, if any. - -- **Hub clock frequency**: 32-bit value holding the frequency, in Hz, of the - hub clock that drives the *Hub_Timestamp* passed to the devices. - -- **Hub data latency**: 32-bit value representing the average latency, in - nanoseconds, of the physical link between the hub and the controller. Usually - 0 in local hubs. - -All 16-bit versions are in the format of: - -:: - - Major(8-bit).Minor(8-bit). - -For example, 0x0103 would imply version 1.3. In the case of the information -device located on hub 0, the versions refer to the physical controller hardware -and its firmware, where that hub is located. - -Heartbeat Device -~~~~~~~~~~~~~~~~ -Local hub 0 must contain a “heartbeat device”. This is a simple device that -periodically produces :ref:`samples ` containing only the ``Hub -Timestamp`` and an empty payload, at a minimum rate of 10 Hz. Its ``ENABLE`` -register must be fixed and always active. This device ensures that API calls -accessing the read stream are guaranteed to be unblocked in the case that no -other devices in the system are producing data. diff --git a/source/hw-spec/devices/index.rst b/source/hw-spec/devices/index.rst index e9f7969..2426034 100644 --- a/source/hw-spec/devices/index.rst +++ b/source/hw-spec/devices/index.rst @@ -7,7 +7,7 @@ physical element interfacing with the environment (e.g. an external sensor with a digital communication interface), something programmed within the firmware to emulate this (e.g. a digital logic module on an FPGA) or a purely internal data source (e.g. a controller based digital logic module that generates system -status reports). A device MUST expose the following :ref:`communication channels +status reports). A device exposes the following :ref:`communication channels `: - A REQUIRED register interface @@ -27,7 +27,6 @@ order to reach ONI-compliance. devid descriptor sample - descriptor registers datasheet hubs From d1deb0568393a8593ded0258c2dcd79798153064 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Tue, 19 Nov 2024 03:09:21 +0100 Subject: [PATCH 09/31] Clarify text for hub clocks --- source/hw-spec/devices/hubs.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/devices/hubs.rst index 07305b5..eba71b4 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/devices/hubs.rst @@ -2,11 +2,17 @@ Hubs ==== -Hubs are collections of devices sharing a common clock. They can be independent -hardware aggregates connected to the controller (e.g. a headstage for neural -acquisition) or a logical partition of existing hardware (e.g. a collection of -devices implemented in the same firmware as the controller). Hubs that exist on -hardware that is physically separated from the :ref:`controller ` are + +Devices MUST be grouped in logical or physical collections, called Hubs. +They can be independent hardware aggregates connected to the controller +(e.g. a headstage for neural acquisition) or a logical partition of existing hardware +(e.g. a collection of devices implemented in the same firmware as the controller). + +Every hub MUST have access to a high-resolution timer. All devices within +a hub MUST use this clock to generate the ``Hub_Timestamp`` value of their +:ref:`data samples `. + +Hubs that exist on hardware that is physically separated from the :ref:`controller ` are referred to as remote hubs, while hubs existing on the controller are local hubs. An ONI-compliant system MUST implement at least one local hub, located at :ref:`Hub_Index 0 ` and sharing the clock of controller's main @@ -14,9 +20,6 @@ state machine, and can implement up to 253 additional hubs, local or remote. All devices reflecting or modifying the :ref:`controller ` state and/or reporting errors or similar status messages must be implemented in local hub 0. -Every hub MUST have access to a high-resolution timer that is used by all its devices -to generate a ``Hub_Timestamp`` for a :ref:`data sample `. - Data from all the devices of a hub is collected and passed to the controller. The specific interface between a hub and the controller is highly implementation-dependent and, thus, not in the scope of this document. In From f73121d2600a14e11d5bab8d6bb2e8c9a0814088 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Tue, 19 Nov 2024 17:34:50 +0100 Subject: [PATCH 10/31] Update text related to hub clocks --- source/hw-spec/devices/hubs.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/devices/hubs.rst index eba71b4..3625c9f 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/devices/hubs.rst @@ -8,9 +8,9 @@ They can be independent hardware aggregates connected to the controller (e.g. a headstage for neural acquisition) or a logical partition of existing hardware (e.g. a collection of devices implemented in the same firmware as the controller). -Every hub MUST have access to a high-resolution timer. All devices within -a hub MUST use this clock to generate the ``Hub_Timestamp`` value of their -:ref:`data samples `. +Every hub MUST have access to a counter driven by a high resolution clock. +All devices within a hub MUST use the values of this counter for the the +``hubclk_cnt`` field of their :ref:`data samples `. Hubs that exist on hardware that is physically separated from the :ref:`controller ` are referred to as remote hubs, while hubs existing on the controller are local hubs. From 6c83557dfb3b170b9d1c33b490a25e05c14c2fb4 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Tue, 19 Nov 2024 17:42:34 +0100 Subject: [PATCH 11/31] Update device sample definitions - Change hub conter name - Split write and read frames --- source/hw-spec/devices/sample.rst | 39 ++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/source/hw-spec/devices/sample.rst b/source/hw-spec/devices/sample.rst index c8142f8..f39df91 100644 --- a/source/hw-spec/devices/sample.rst +++ b/source/hw-spec/devices/sample.rst @@ -4,22 +4,33 @@ Device Sample Format ===================== Data passed over the read or write streams are transmitted in unit packets, -or “samples”. A sample transmitted over the read stream MUST have the following -format: +or “samples”. + +Read samples +------------- +These are the samples produced by the devices and sent through the +:ref:`read stream ` to the controller. +Read samples MUST have the following format: :: - uint64 Hub_Timestamp (Read Stream Only) - var Payload + uint64 hubclk_cnt + var hayload + +- ``hubclk_cnt``: Hub Clock Counter. This is the common counter for all devices in + a :ref:`Hub `, indicating the time of sample capture. +- ``payload``: Device-specific data. This data MUST be + :ref:`Read Sample Size ` - 8 bytes long. + +Write samples +------------- +These are the samples generated by the host and sent to the devices +trough the :ref:`write stream `. +Write samples MUST have the following format. + +:: -- ``Hub_Timestamp``: For samples produced by the device and sent to the read - stream, this is a common counter for all devices in a :ref:`Hub `, - indicating the time of sample capture. For samples consumed by the device - from the write stream, this value is reserved. -- ``Payload``: Device-specific data. + var payload - - For :ref:`read streams `, this data must be of :ref:`Read Sample - Size ` - 8. - - For :ref:`write streams `, this data must be of :ref:`Write Sample - Size `. Thus, the whole sample packet fits into the sample - size specified in the :ref:`device descriptor `. \ No newline at end of file +- ``payload``: Device-specific data. This data MUST be + :ref:`Write Sample Size ` bytes long. \ No newline at end of file From 4a5951f7e1afe5d39fa17249820260fcc70f09af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aar=C3=B3n=20Cuevas=20L=C3=B3pez?= Date: Tue, 19 Nov 2024 17:46:22 +0100 Subject: [PATCH 12/31] Clarify text for concurrent access --- source/hw-spec/controller/channels/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/hw-spec/controller/channels/index.rst b/source/hw-spec/controller/channels/index.rst index ff285f3..1ba85e5 100644 --- a/source/hw-spec/controller/channels/index.rst +++ b/source/hw-spec/controller/channels/index.rst @@ -16,8 +16,8 @@ four abstract communication channels: These channels are implemented by the combination of the controller hardware and the :term:`Driver Translator`. -Concurrent access to a single channel by the host MUST NOT be permitted. However, individual -channels MUST be able to be accessed independently. +Concurrent access to a single channel by the host (e.g. by multiple threads of execution or applications) is +NOT permitted. However, individual channels MUST be able to be accessed independently. .. note:: Concurrent access requirements relate only to the hardware implementation. Functions in a high-level :term:`API` MAY introduce their own access dependencies and concurrency limitations. From ab049f45141bf14f0ed3d13e32cac9c8bce5c061 Mon Sep 17 00:00:00 2001 From: jonnew Date: Tue, 19 Nov 2024 11:50:17 -0500 Subject: [PATCH 13/31] Manually "rebase" branches issue-1 and issue-3 on oni-v2 - An actual rebase was too difficult, so I brought those branches over manually --- source/api/liboni/liboni-example.rst | 32 ++++++------ source/api/liboni/oni.rst | 19 ++++--- source/api/liboni/onidefs.rst | 11 +---- .../controller/channels/data_frames.rst | 10 ++-- .../hw-spec/controller/register_interface.rst | 49 ++++++++++--------- source/hw-spec/devices/datasheet.rst | 4 ++ source/hw-spec/devices/descriptor.rst | 29 +++++++---- source/hw-spec/devices/hubs.rst | 4 +- source/hw-spec/devices/registers.rst | 34 ++++++++----- source/hw-spec/devices/sample.rst | 18 +++---- source/hw-spec/devices/special.rst | 40 +++++++-------- 11 files changed, 133 insertions(+), 117 deletions(-) diff --git a/source/api/liboni/liboni-example.rst b/source/api/liboni/liboni-example.rst index bdc6600..ad84d5b 100644 --- a/source/api/liboni/liboni-example.rst +++ b/source/api/liboni/liboni-example.rst @@ -255,23 +255,23 @@ Reading Data Frames ******************************************** :struct:`oni_frame_t`'s are minimal packets containing metadata and raw binary data blocks from a single device within the device table. A -:struct:`oni_size_t` is defined as +:struct:`oni_frame_t` is defined as .. code-block:: c - struct oni_frame { - const uint64_t dev_idx; // Device index that produced or accepts the frame - const uint32_t data_sz; // Size in bytes of data buffer - const uint64_t time; // Frame time (ACQCLKHZ) - uint8_t *data; // Raw data block + struct oni_frame_t { + const oni_size_t dev_idx; // Device index that produced or accepts the frame + const oni_size_t data_sz; // Size in bytes of data buffer + const oni_counter_t acqclk_cnt; // Acquisition clock (ACQCLKHZ) count at frame creation + uint8_t *data; // Raw data block }; where ``dev_idx`` is the fully qualified device index within the device table -(hub.index), ``data_sz`` is the size in bytes of the raw data block, ``time`` -is the system clock count that indicates the frame creation time, and, ``data`` -is a pointer to the raw data block. A single frame can be read from an -acquisition context after it is started (see :ref:`start_ctx`) using repeated -calls to ``oni_read_frame`` as follows: +(hub.index), ``data_sz`` is the size in bytes of the raw data block, +``acqclk_cnt`` is the acquisition clock count that indicates the frame creation +time, and, ``data`` is a pointer to the raw data block. A single frame can be +read from an acquisition context after it is started (see :ref:`start_ctx`) +using repeated calls to ``oni_read_frame`` as follows: .. code-block:: c @@ -310,9 +310,9 @@ steps to reading frames. // Required elements to create frame oni_frame_t *frame = NULL; - size_t dev_idx = 256; - size_t data_sz = 8; // or 16, 24, 32, etc - char data[] = {0, 1, 2, 3, 4, 5, 6, 7}; + const size_t dev_idx = 256; + const size_t data_sz = 8; // Multiple of write size presented in device table + char data[] = {0, 1, 2, 3, 4, 5, 6, 7}; // Must be data_sz bytes long // Create a frame oni_create_frame(ctx, &frame, dev_idx, data, data_sz); @@ -324,8 +324,8 @@ steps to reading frames. oni_destroy_frame(frame); First, a frame is created using a call to ``oni_create_frame`` (analogous to -``oni_read_frame``, except that frame data is provided by the user instead of -the hardware). In the preceding example, it is assumed that the user has +``oni_read_frame``, except that frame data is provided by the caller instead of +the hardware). In the preceding example, it is assumed that the caller has queried the device table to ensure that the device with qualified index 256 is writable and has a write size of 8 bytes. If the device at ``dev_idx`` does not accept writes or ``data``/``data_sz`` are not a multiple of the device write diff --git a/source/api/liboni/oni.rst b/source/api/liboni/oni.rst index f5f91e1..41122bf 100644 --- a/source/api/liboni/oni.rst +++ b/source/api/liboni/oni.rst @@ -121,24 +121,23 @@ Frame --------------------------------------- .. struct:: oni_frame_t - .. member:: const oni_fifo_time_t time - Frame time (:macro:`ONI_OPT_ACQCLKHZ` host clock counter). - - .. member:: const oni_fifo_dat_t dev_idx + .. member:: const oni_size_t dev_idx Device index that produced or accepts the frame. + .. member:: const oni_counter_t acqclk_cnt + + Acquisition clock (:macro:`ONI_OPT_ACQCLKHZ`) count at the time + of frame creation. + .. member:: const oni_fifo_dat_t data_sz Size of data in bytes. .. member:: 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. + Pointer to a ``data_sz``-byte continuous data block. An ONI-compliant data frame implementation. :struct:`oni_frame_t`'s are produced by calls to :func:`oni_read_frame` and consumed by calls to @@ -346,7 +345,7 @@ needed during the development of user-facing software. :ref:`liboni_example_set_buffers`). :struct:`oni_frame_t`'s created during calls to :func:`oni_read_frame` are zero-copy views into this buffer. - .. attention:: It is the user's responsibility to free the resources allocated by + .. attention:: It is the caller's responsibility to free the resources allocated by this call by passing the resulting frame pointer to :func:`oni_destroy_frame`. @@ -360,7 +359,7 @@ needed during the development of user-facing software. Create an :struct:`oni_frame_t` for consumption by :func:`oni_write_frame`. - .. attention:: It is the user's responsibility to free the resources allocated by + .. attention:: It is the caller's responsibility to free the resources allocated by this call by passing the resulting frame pointer to :func:`oni_destroy_frame` diff --git a/source/api/liboni/onidefs.rst b/source/api/liboni/onidefs.rst index eed94ff..8b1d8a3 100644 --- a/source/api/liboni/onidefs.rst +++ b/source/api/liboni/onidefs.rst @@ -10,9 +10,6 @@ Macro and constant definitions common to both :ref:`oni.h` and :ref:`onidriver.h Integer Types --------------------------------------- -.. warning:: All of these types will be almost certainly be deprecated in - future API revisions to handle drivers with different channel bit widths. - .. type:: uint32_t oni_size_t Data sizes are 32-bit uints. @@ -33,13 +30,9 @@ Integer Types Registers have 32-bit values. -.. type:: uint32_t oni_fifo_dat_t - - FIFOs use 32-bit words. - -.. type:: uint64_t oni_fifo_time_t +.. type:: uint64_t oni_counter_t - FIFO bound timers use 64-bit words. + Counters use 64-bit words. .. _onidef_context_options: diff --git a/source/hw-spec/controller/channels/data_frames.rst b/source/hw-spec/controller/channels/data_frames.rst index 04227a1..58d99d6 100644 --- a/source/hw-spec/controller/channels/data_frames.rst +++ b/source/hw-spec/controller/channels/data_frames.rst @@ -3,10 +3,11 @@ Data Frames ============ -Data transmission from the :ref:`read channel` and from the :ref:`write channel` -is packed in frames. Each frame is a timestamped -`type-length-value-encoded `__ -structure that contains data corresponding to a single device :ref:`sample `. +Data transmission from the :ref:`read channel` and from the +:ref:`write channel` is packed in frames. Each frame is a +timestamped `type-length-value-encoded +`__ structure +that contains data corresponding to a single device :ref:`sample `. The frame format is: :: @@ -28,6 +29,5 @@ Where - ``Sample``: The complete data sample as described on the :ref:`device sample format ` section. - While a read frame must always contain a single sample as generated by the devices, write frames can contain multiple samples targeted to the same device. \ No newline at end of file diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst index d19c250..8c3536d 100644 --- a/source/hw-spec/controller/register_interface.rst +++ b/source/hw-spec/controller/register_interface.rst @@ -30,14 +30,14 @@ The register programming interface is composed of the following is not recommended. - ``Read/Write``: A flag indicating if a read or write should be performed. 0 - indicates read operation. A value > 0 indicates write operation. - -- ``Trigger``: Set > 0 to add either a register read or write operation - depending on the state of ``Read/Write``. If ``Read/Write`` is 0, a read - operation is queued. If ``Read/Write`` is 1, an operation to write ``Register Value`` - to the register at ``Register Address`` on the device at ``Device Address`` is queued. - Reading the ``Triger`` register returns 0 if the queue is empty or 1 if there are - pending operations. + indicates a read operation. A value of 0x00000001 indicates a write operation. + +- ``Trigger``: Set to 0x00000001 to add either a register read or write + operation depending on the state of ``Read/Write``. If ``Read/Write`` is + 0x00000000, a read operation is queued. If ``Read/Write`` is 1, an operation + to write ``Register Value`` to the register at ``Register Address`` on the + device at ``Device Address`` is queued. Reading the ``Trigger`` register + returns 0x00000000 if the queue is empty or 1 if there are pending operations. Appropriate values of ``Register Address`` and ``Register Value`` are determined by: @@ -55,21 +55,22 @@ must be performed: 1. Check the value of ``Trigger``. - - If it is 0, the queue is empty and the procedure can safely proceed. + - If it is 0x00000000, the queue is empty and the procedure can safely proceed. - Else, there are transactions pending on the queue. Since the exact number of pending elements is unknown, adding new transactions is not recommended. -2. For each register read transaction to be added to the queue: +2. For each register read transaction to be added to the queue: 1. The target device is selected by writing its address, as featured on the device map, into ``Device Address`` on the controller. - 2. The desired register address within the device register map is written into - ``Register Address`` on the controller. - 3. The ``Read/Write`` register on the controller is set to 0x00. - 4. The ``Trigger`` register on the controller is set to 0x01, inserting the - operation on the queue. - 5. Repeat as needed until al read transactions have been queued. + 2. The desired register address within the device register map is written + into ``Register Address`` on the controller. + 3. The ``Read/Write`` register on the controller is set to 0x00000000. + 4. The ``Trigger`` register on the controller is set to 0x00000001, inserting + the operation on the queue. + 5. The host repeats steps 1-4 as needed until all read transactions have been + queued. 3. For each element on the queue, the controller will: @@ -84,12 +85,12 @@ must be performed: Register Write Sequence ------------------------- -When a host requests one or more device register *writes*, the following following -sequence must be performed: +When a host requests one or more device register *writes*, the following +following sequence must be performed: 1. Check the value of ``Trigger``. - - If it is 0, the queue is empty and the procedure can safely proceed. + - If it is 0x00000000, the queue is empty and the procedure can safely proceed. - Else, there are transactions pending on the queue. Since the exact number of pending elements is unknown, adding new transactions is not recommended. @@ -98,13 +99,13 @@ sequence must be performed: 1. The target device is selected by writing its address, as featured on the device map, into ``Device Address`` on the controller - 2. The desired register address within the device register map is written into - ``Register Address`` on the controller. - 3. The ``Read/Write`` register on the controller is set to 0x01. + 2. The desired register address within the device register map is written + into ``Register Address`` on the controller. + 3. The ``Read/Write`` register on the controller is set to 0x00000001. 4. The value to be written into the device register is written into the ``Register Value`` register in the controller. - 5. The ``Trigger`` register on the controller is set to 0x01, inserting the - operation on the queue. + 5. The ``Trigger`` register on the controller is set to 0x00000001, inserting + the operation on the queue. 6. Repeat as needed until al read transactions have been queued. 3. For each element on the queue, the controller will: diff --git a/source/hw-spec/devices/datasheet.rst b/source/hw-spec/devices/datasheet.rst index 5385eda..dd35a43 100644 --- a/source/hw-spec/devices/datasheet.rst +++ b/source/hw-spec/devices/datasheet.rst @@ -60,6 +60,8 @@ table, but it MUST contain the following columns: Additional columns are permitted so long as their information does not conflict with that in the required columns. +.. _dev-datasheet-read-format: + Read Frame Format ~~~~~~~~~~~~~~~~~ If the device produces frames, a @@ -67,6 +69,8 @@ If the device produces frames, a frame structure is required. Bits can be grouped into words as is convenient. If no frames are produced, then a statement of such is required. +.. _dev-datasheet-write-format: + Write Frame Format ~~~~~~~~~~~~~~~~~~ If the device accepts frames, a diff --git a/source/hw-spec/devices/descriptor.rst b/source/hw-spec/devices/descriptor.rst index 18135af..49722e0 100644 --- a/source/hw-spec/devices/descriptor.rst +++ b/source/hw-spec/devices/descriptor.rst @@ -9,22 +9,31 @@ table `. The descriptor must contain the following information: :: - uint32 Device_ID - uint32 Device_Version - uint32 Read_Sample_Size - uint32 Write_Sample_Size + uint32 device_id + uint32 device_ver + uint32 rd_samp_size + uint32 wr_samp_size -- ``Device_ID``: :ref:`As previously described `. -- ``Device_Version``: A version number to distinguish between implementations +- ``device_id``: :ref:`As previously described `. +- ``device_ver``: A version number to distinguish between implementations of a singular device type. Different versions MUST NOT change the device's sample data format or alter an existing register map. However, register additions that do not affect the existing register map are allowed. Any change that warrants a modification of a device's streaming data format, read size, write size, or existing register map MUST be implemented as a new :ref:`Device ID `. -- ``Read_Sample_Size``: The length in bytes of a single :ref:`device sample +- ``rd_samp_size``: The length in bytes of a single :ref:`device sample ` produced by the device and sent to the :ref:`read stream - `. -- ``Write_Sample_Size``: The length in bytes of a single :ref:`device + `. This value must be *at least* as a large as the number of + bytes in the Device Sample indicated by the :ref:`dev-datasheet-read-format`. +- ``wr_samp_size``: The length in bytes of a single :ref:`device sample ` consumed by the device from the :ref:`write stream - `. \ No newline at end of file + `.This value must be *at least* as a large as the number of + bytes in the Device Sample indicated by the :ref:`dev-datasheet-write-format`. + + .. note:: ``Read_Sample_Size`` and ``Write_Sample_Size`` may include trailing padding + bytes that are a result of data alignment requirments imposed by different underlying + hardware and drivers. Different types of ONI-compliant :ref:`controller` + may present different ``rd_samp_size`` and ``wr_samp_size`` for Devices + with identical :ref:`Device IDs `. The API's functionality must not be + affected by this. \ No newline at end of file diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/devices/hubs.rst index 07305b5..8bc9a38 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/devices/hubs.rst @@ -14,8 +14,8 @@ state machine, and can implement up to 253 additional hubs, local or remote. All devices reflecting or modifying the :ref:`controller ` state and/or reporting errors or similar status messages must be implemented in local hub 0. -Every hub MUST have access to a high-resolution timer that is used by all its devices -to generate a ``Hub_Timestamp`` for a :ref:`data sample `. +Every hub MUST have access to a high-resolution timer that is used by all its +devices to generate a ``hubclk_cnt`` for a :ref:`data sample `. Data from all the devices of a hub is collected and passed to the controller. The specific interface between a hub and the controller is highly diff --git a/source/hw-spec/devices/registers.rst b/source/hw-spec/devices/registers.rst index ce05c64..83a04d8 100644 --- a/source/hw-spec/devices/registers.rst +++ b/source/hw-spec/devices/registers.rst @@ -52,15 +52,25 @@ Register Map ------------- A device can optionally implement raw registers and MUST implement at least one -managed register, ``ENABLE``, a Read-Write register that takes effect after -reset. When ``ENABLE`` is disabled, the device must not produce any data -through the :ref:`read stream `. - -The location of the managed registers depends on the existence of raw -registers. If the device implements raw registers, those are mapped to -addresses 0x0000 to 0x7FFF, corresponding to the same address map of the -underlying hardware, and managed registers start from 0x80000. If no raw -registers are present, managed registers start from 0x0000 instead. - -The ``ENABLE`` register MUST be the first of the managed registers, at 0x0000 if -no raw registers are present, 0x8000 if raw registers are implemented. \ No newline at end of file +managed register, ``ENABLE``. This register's behavior MUST conform the +following rules: + +- Bits 31 down to 1 of the ``ENABLE`` are reserved. +- For devices that produce data through the :ref:`data-rd-chan`, ``ENABLE`` is a + Read/Write register that takes effect after reset. When ``ENABLE`` is set to + 0x00000000, the device MUST NOT produce any data on the :ref:`data-rd-chan`. + When ``ENABLE`` is set to 0x00000001, the device it MUST produce data + :ref:`data-rd-chan` in accordance with behavior documented on its + :ref:`dev-datasheet`. +- For devices that do not produce data through the :ref:`data-rd-chan`, + ``ENABLE`` is a Read-Only register with value 0. Attempting to write to the + register results in ``CONFIGWNACK`` on the :ref:`sig-chan`. + +The location of the managed registers depends on the existence of raw registers. +If the device implements raw registers, those are mapped to addresses 0x00000000 +to 0x00007FFF, corresponding to the same address map of the underlying hardware, +and managed registers start from 0x00008000. If no raw registers are present, +managed registers start from 0x00000000 instead. + +The ``ENABLE`` register MUST be the first of the managed registers, at 0x00000000 if +no raw registers are present, 0x00008000 if raw registers are implemented. \ No newline at end of file diff --git a/source/hw-spec/devices/sample.rst b/source/hw-spec/devices/sample.rst index c8142f8..ef392b5 100644 --- a/source/hw-spec/devices/sample.rst +++ b/source/hw-spec/devices/sample.rst @@ -9,17 +9,17 @@ format: :: - uint64 Hub_Timestamp (Read Stream Only) - var Payload + uint64 hubclk_cnt (Read Stream Only) + var payload -- ``Hub_Timestamp``: For samples produced by the device and sent to the read +- ``hubclk_cnt``: For samples produced by the device and sent to the read stream, this is a common counter for all devices in a :ref:`Hub `, indicating the time of sample capture. For samples consumed by the device from the write stream, this value is reserved. -- ``Payload``: Device-specific data. +- ``payload``: Device-specific data. - - For :ref:`read streams `, this data must be of :ref:`Read Sample - Size ` - 8. - - For :ref:`write streams `, this data must be of :ref:`Write Sample - Size `. Thus, the whole sample packet fits into the sample - size specified in the :ref:`device descriptor `. \ No newline at end of file + - For :ref:`read streams `, this data must be *at least* + :ref:`rd_samp_size ` - 8 bytes long. + - For :ref:`write streams `, this data must be of + :ref:`wr_samp_size `. Thus, the whole sample packet fits into the + sample size specified in the :ref:`device descriptor `. \ No newline at end of file diff --git a/source/hw-spec/devices/special.rst b/source/hw-spec/devices/special.rst index f609547..b19c7ec 100644 --- a/source/hw-spec/devices/special.rst +++ b/source/hw-spec/devices/special.rst @@ -7,23 +7,23 @@ An information device on each hub and a heartbeat device in local hub 0. Information Device -------------------- -Every hub in an ONI system must feature a special device, located at -:ref:`Device_Address ` 0xFE, which supplies information about the hub. -Because this device is required to exist at a fixed address, it is not listed -in the device table and, thus, has no :ref:`device descriptor `. The only -communication channel it must expose is the register interface, and it must not -include any streams. The required register map is: - -======= ================================ -Address Register -======= ================================ -0x0000 Hardware ID -0x0001 Hardware revision -0x0002 Firmware version -0x0003 (OPTIONAL) Safe firmware version -0x0004 Hub clock frequency -0x0005 Hub data latency -======= ================================ +Every hub in an ONI system MUST feature a special device, located at +:ref:`Device_Address ` 0xXXXXXXFE, which supplies information about the +hub. Because this device is required to exist at a fixed address, it is not +listed in the device table and, thus, has no :ref:`device descriptor +`. It MUST expose is the register interface, and it MUST NOT include +any streams. The required register map is: + +========== ================================ +Address Register +========== ================================ +0x00000000 Hardware ID +0x00000001 Hardware revision +0x00000002 Firmware version +0x00000003 (OPTIONAL) Safe firmware version +0x00000004 Hub clock frequency +0x00000005 Hub data latency +========== ================================ Although all register reads are 32-bits in nature, not all registers make use of the complete width. The detailed meaning of each register is: @@ -64,7 +64,7 @@ the complete width. The detailed meaning of each register is: nanoseconds, of the physical link between the hub and the controller. Usually 0 in local hubs. -All 16-bit versions are in the format of: +All 16-bit versions are in the format: :: @@ -77,8 +77,8 @@ and its firmware, where that hub is located. Heartbeat Device ------------------ Local hub 0 must contain a “heartbeat device”. This is a simple device that -periodically produces :ref:`samples ` containing only the ``Hub -Timestamp`` and an empty payload, at a minimum rate of 10 Hz. Its ``ENABLE`` +periodically produces :ref:`samples ` containing only the +``hubclk_cnt`` and an empty payload, at a fixed rate of 100 Hz. Its ``ENABLE`` register must be fixed and always active. This device ensures that API calls accessing the read stream are guaranteed to be unblocked in the case that no other devices in the system are producing data. From 6e716777c46dba1ac2e172e1416b4d47cc242b9a Mon Sep 17 00:00:00 2001 From: jonnew Date: Wed, 20 Nov 2024 12:16:44 -0500 Subject: [PATCH 14/31] Address review comments --- .../controller/channels/read_channel.rst | 11 ++--- .../hw-spec/controller/register_interface.rst | 2 +- source/hw-spec/devices/datasheet.rst | 16 ++++---- source/hw-spec/devices/descriptor.rst | 41 ++++++++----------- source/hw-spec/devices/sample.rst | 12 +++--- source/hw-spec/devices/special.rst | 13 +++--- 6 files changed, 47 insertions(+), 48 deletions(-) diff --git a/source/hw-spec/controller/channels/read_channel.rst b/source/hw-spec/controller/channels/read_channel.rst index 2517767..465c750 100644 --- a/source/hw-spec/controller/channels/read_channel.rst +++ b/source/hw-spec/controller/channels/read_channel.rst @@ -24,8 +24,9 @@ systems or other software limitations. Read Word Alignment --------------------- -Hardware implementations of controllers might require a :ref:`word size` -greater than 8 bits. In that case, the controller is required to increase the ``Read_Sample_Size`` -values of all devices on the :ref:`dev-table` so they fit into the required -word alignment. Extra bytes after the size defined on the :term:`Device Datasheet` -will be padded with 0xFF. \ No newline at end of file +Hardware implementations of controllers might require a :ref:`word +size` greater than 8 bits. In that case, the controller +MUST increase the ``rd_samp_size`` provided each devices' :ref:`dev-desc` within +the :ref:`dev-table` so they fit into the required word alignment. Extra bytes +after the size defined on the :term:`Device Datasheet`'s +:ref:`dev-datasheet-read-format` will be padded with 0xFF. \ No newline at end of file diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst index 8c3536d..fe67200 100644 --- a/source/hw-spec/controller/register_interface.rst +++ b/source/hw-spec/controller/register_interface.rst @@ -86,7 +86,7 @@ Register Write Sequence ------------------------- When a host requests one or more device register *writes*, the following -following sequence must be performed: +sequence must be performed: 1. Check the value of ``Trigger``. diff --git a/source/hw-spec/devices/datasheet.rst b/source/hw-spec/devices/datasheet.rst index dd35a43..2b4f6ff 100644 --- a/source/hw-spec/devices/datasheet.rst +++ b/source/hw-spec/devices/datasheet.rst @@ -64,16 +64,16 @@ with that in the required columns. Read Frame Format ~~~~~~~~~~~~~~~~~ -If the device produces frames, a -`bitfield `__ diagram describing the -frame structure is required. Bits can be grouped into words as is convenient. If -no frames are produced, then a statement of such is required. +If the device produces :ref:`samples `, a `bitfield +`__ diagram describing the frame +structure is required. Bits can be grouped into words as is convenient. If no +frames are produced, then a statement of such is required. .. _dev-datasheet-write-format: Write Frame Format ~~~~~~~~~~~~~~~~~~ -If the device accepts frames, a -`bitfield `__ diagram describing the -frame structure is required. Bits can be grouped into words as is convenient. If -no frames are accepted, then a statement of such is required. \ No newline at end of file +If the device accepts :ref:`samples `, a `bitfield +`__ diagram describing the frame +structure is required. Bits can be grouped into words as is convenient. If no +frames are accepted, then a statement of such is required. \ No newline at end of file diff --git a/source/hw-spec/devices/descriptor.rst b/source/hw-spec/devices/descriptor.rst index 49722e0..ad89bc3 100644 --- a/source/hw-spec/devices/descriptor.rst +++ b/source/hw-spec/devices/descriptor.rst @@ -14,26 +14,21 @@ table `. The descriptor must contain the following information: uint32 rd_samp_size uint32 wr_samp_size -- ``device_id``: :ref:`As previously described `. -- ``device_ver``: A version number to distinguish between implementations - of a singular device type. Different versions MUST - NOT change the device's sample data format or alter an existing register - map. However, register additions that do not affect the existing register map - are allowed. Any change that warrants a modification of a device's streaming - data format, read size, write size, or existing register map MUST be - implemented as a new :ref:`Device ID `. -- ``rd_samp_size``: The length in bytes of a single :ref:`device sample - ` produced by the device and sent to the :ref:`read stream - `. This value must be *at least* as a large as the number of - bytes in the Device Sample indicated by the :ref:`dev-datasheet-read-format`. -- ``wr_samp_size``: The length in bytes of a single :ref:`device - sample ` consumed by the device from the :ref:`write stream - `.This value must be *at least* as a large as the number of - bytes in the Device Sample indicated by the :ref:`dev-datasheet-write-format`. - - .. note:: ``Read_Sample_Size`` and ``Write_Sample_Size`` may include trailing padding - bytes that are a result of data alignment requirments imposed by different underlying - hardware and drivers. Different types of ONI-compliant :ref:`controller` - may present different ``rd_samp_size`` and ``wr_samp_size`` for Devices - with identical :ref:`Device IDs `. The API's functionality must not be - affected by this. \ No newline at end of file +- ``device_id``: :ref:`dev-id`. +- ``device_ver``: Device version. A version number to distinguish between + implementations of a singular device type. Different versions MUST NOT change + the device's sample data format or alter an existing register map. However, + register additions that do not affect the existing register map are allowed. + Any change that warrants a modification of a device's streaming data format, + read size, write size, or existing register map MUST be implemented as a new + :ref:`Device ID `. +- ``rd_samp_size``: Read sample size. The length in bytes of a single + :ref:`device sample ` produced by the device and sent to the + :ref:`read stream `. This value must be *at least* as a large as + the number of bytes in the Device Sample indicated by the + :ref:`dev-datasheet-read-format`. +- ``wr_samp_size``: Write sample size. The length in bytes of a single + :ref:`device sample ` consumed by the device from the :ref:`write + stream `.This value must be *at least* as a large as the number + of bytes in the Device Sample indicated by the + :ref:`dev-datasheet-write-format`. \ No newline at end of file diff --git a/source/hw-spec/devices/sample.rst b/source/hw-spec/devices/sample.rst index ef392b5..3c067d8 100644 --- a/source/hw-spec/devices/sample.rst +++ b/source/hw-spec/devices/sample.rst @@ -3,8 +3,8 @@ Device Sample Format ===================== -Data passed over the read or write streams are transmitted in unit packets, -or “samples”. A sample transmitted over the read stream MUST have the following +Data passed over the read or write streams are transmitted in unit packets, or +“samples”. A sample transmitted over the read stream MUST have the following format: :: @@ -14,12 +14,12 @@ format: - ``hubclk_cnt``: For samples produced by the device and sent to the read stream, this is a common counter for all devices in a :ref:`Hub `, - indicating the time of sample capture. For samples consumed by the device - from the write stream, this value is reserved. + indicating the time of sample capture. For samples consumed by the device from + the write stream, this value is reserved. - ``payload``: Device-specific data. - - For :ref:`read streams `, this data must be *at least* - :ref:`rd_samp_size ` - 8 bytes long. + - For :ref:`read streams `, this data must be :ref:`rd_samp_size + ` - 8 bytes long. - For :ref:`write streams `, this data must be of :ref:`wr_samp_size `. Thus, the whole sample packet fits into the sample size specified in the :ref:`device descriptor `. \ No newline at end of file diff --git a/source/hw-spec/devices/special.rst b/source/hw-spec/devices/special.rst index b19c7ec..f8fdc07 100644 --- a/source/hw-spec/devices/special.rst +++ b/source/hw-spec/devices/special.rst @@ -8,9 +8,9 @@ An information device on each hub and a heartbeat device in local hub 0. Information Device -------------------- Every hub in an ONI system MUST feature a special device, located at -:ref:`Device_Address ` 0xXXXXXXFE, which supplies information about the -hub. Because this device is required to exist at a fixed address, it is not -listed in the device table and, thus, has no :ref:`device descriptor +:ref:`Device_Index ` 0xFE within the hub, which supplies information +about the hub. Because this device is required to exist at a fixed address, it +is not listed in the device table and, thus, has no :ref:`device descriptor `. It MUST expose is the register interface, and it MUST NOT include any streams. The required register map is: @@ -76,9 +76,12 @@ and its firmware, where that hub is located. Heartbeat Device ------------------ -Local hub 0 must contain a “heartbeat device”. This is a simple device that +Local hub 0 MUST contain a “heartbeat device”. This is a simple device that periodically produces :ref:`samples ` containing only the ``hubclk_cnt`` and an empty payload, at a fixed rate of 100 Hz. Its ``ENABLE`` -register must be fixed and always active. This device ensures that API calls +register must be read-only and always active. This device ensures that API calls accessing the read stream are guaranteed to be unblocked in the case that no other devices in the system are producing data. + +Other, identical heartbeat devices but with configurable ``ENABLE`` and data +rate MAY exist as part of any hub. From fe8d9327b278d52ab09f4aa533e8cb5f0cba6059 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Thu, 21 Nov 2024 03:31:37 +0100 Subject: [PATCH 15/31] Address review comments --- source/hw-spec/devices/sample.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/devices/sample.rst b/source/hw-spec/devices/sample.rst index cf1de62..194379c 100644 --- a/source/hw-spec/devices/sample.rst +++ b/source/hw-spec/devices/sample.rst @@ -4,7 +4,7 @@ Device Sample Format ===================== Data passed over the read or write streams are transmitted in unit packets, -or samples. +or "samples". Read samples ------------- @@ -15,11 +15,11 @@ Read samples MUST have the following format: :: uint64 hubclk_cnt - var hayload + var payload - ``hubclk_cnt``: Hub Clock Counter. This is the common counter for all devices in a :ref:`Hub `, indicating the time of sample capture. -- ``payload``: Device-specific data. This data MUST be +- ``payload``: :ref:`Device-specific` data. This data MUST be :ref:`Read Sample Size ` - 8 bytes long. Write samples @@ -32,5 +32,5 @@ Write samples MUST have the following format. var payload -- ``payload``: Device-specific data. This data MUST be +- ``payload``: :ref:`Device-specific` data. This data MUST be :ref:`Write Sample Size ` bytes long. \ No newline at end of file From d4a3505431ddab27a1edad0c77be5cbf1f09a36e Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Thu, 21 Nov 2024 05:54:12 +0100 Subject: [PATCH 16/31] Update data frame format to C-style --- .../controller/channels/data_frames.rst | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/hw-spec/controller/channels/data_frames.rst b/source/hw-spec/controller/channels/data_frames.rst index 58d99d6..dca3c5f 100644 --- a/source/hw-spec/controller/channels/data_frames.rst +++ b/source/hw-spec/controller/channels/data_frames.rst @@ -12,21 +12,21 @@ The frame format is: :: - uint32 Device_Address - uint64 Common_Timestamp - uint32 Sample_Size - var Sample + uint32 dev_addr + uint64 acqclk_cnt + uint32 sample_sz + var sample Where -- ``Device_Address``: The address of the device producing the data, as featured +- ``dev_addr``: Device Address. The address of the device producing the data, as featured on the :ref:`device table `. -- ``Common_Timestamp``: A counter common to all devices generated by the +- ``acqclk_cnt``: Acquisition counter. A counter common to all devices generated by the controller common acquisition clock. On write frames, this field is ignored. -- ``Sample_Size``: The full size of the sample, and must be equal to the - ``Read_Sample_Size`` field of the :ref:`device descriptor ` on read - frames or a multiple of the ``Write_Sample_Size`` on write frames. -- ``Sample``: The complete data sample as described on the :ref:`device sample +- ``sample_sz``: Sample Size. The full size of the sample, and must be equal to the + ``rd_samp_size`` field of the :ref:`device descriptor ` on read + frames or a multiple of the ``wr_samp_size`` on write frames. +- ``sample``: The complete data sample as described on the :ref:`device sample format ` section. While a read frame must always contain a single sample as generated by the devices, From 1205c607958382b3dacee4cf91bb09ea64ad6c07 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Thu, 21 Nov 2024 05:54:32 +0100 Subject: [PATCH 17/31] Clarify acquisition counter definition --- source/hw-spec/controller/index.rst | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index d6413c6..f713569 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -4,9 +4,26 @@ Controller ========== The :term:`controller`'s purpose is to interface an ONI hardware system with the host computer. It aggregates and routes device data and provides transparent access -to all devices, independently of their physical location. The host also -contains a common clock that is used to timestamp data from all devices, -independently of their origin hub. +to all devices, independently of their physical location. + +.. _acq_clk: + +Acquisition counter +--------------------- + +The controller MUST have access to a high resolution clock. The tick count from this +clock is used to synchronize data from all devices independently of their origin hub. +The controller MUST capture the counter value when receiving a :ref:`sample` +and use that value for the ``acqclk_cnt`` field of the :ref:`frame`. + +.. note:: The controller adds the acquisition counter when it receives the samples + and proceeds to create the associated frame. However, due to hub to controller + transmission delays, this time may have an offset from sample creation time. + To account for this, the hubs contain a register indicating the measured + transmission delay. Users can use this value to more precisely synchronize + samples between hubs. + +.. todo:: update note admonition to links after the register map is updated .. _controller_params: @@ -32,7 +49,7 @@ Communication .. toctree:: :maxdepth: 1 - + channels/index addresses register_interface \ No newline at end of file From 47e63165bc60b856d6101a31a0f427e3761ad938 Mon Sep 17 00:00:00 2001 From: jonnew Date: Thu, 21 Nov 2024 09:46:41 -0500 Subject: [PATCH 18/31] Reference network topology on hierarchy page - Reference the formal concept of a network topology and note that ONI hardware is arranged in a tiered star similar to USB --- source/hw-spec/hierarchy.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/source/hw-spec/hierarchy.rst b/source/hw-spec/hierarchy.rst index 1490ff6..29dfae2 100644 --- a/source/hw-spec/hierarchy.rst +++ b/source/hw-spec/hierarchy.rst @@ -1,7 +1,7 @@ .. _ONI-hierarchy: -Hardware Hierarchy -================== +Hardware Topology +========================= Any ONI-compliant system is comprised of at least three hierarchical hardware elements: @@ -12,9 +12,10 @@ elements: - :ref:`Device ` -These hardware elements are managed by a single host computer where they are -governed by an :term:`Acquisition Context`. The complete connectivity of the -hardware hierarchy is shown below. +These hardware elements are managed within a single host computer where they are +governed by a single :term:`Acquisition Context`. An ONI system is arranged in a +`tiered-star network `__ similar +to that of, e.g., USB, which is shown here: :: @@ -50,9 +51,10 @@ hardware hierarchy is shown below. | +--- Controller P -An ONI-compliant hardware system must have at least a one controller, hub, and -device. Hubs can be independent hardware elements that communicate with the -controller, or can share the same hardware. For instance, an FPGA can run the -controller logic, contain a hub with local devices, and connect to external hubs -through a digital link. Device groups operating in different clock domains, even -if they lie in the same physical hardware, must form independent hubs. +An ONI-compliant hardware system must have at least a single Host, a single +Controller, a single Hub, and a single Device. Hubs can be physically separate +hardware elements that communicate with the controller, or can share the same +hardware. For instance, an FPGA can run the controller logic, contain a hub with +local devices, and connect to external hubs through a digital link. Device +groups operating in different clock domains, even if they lie in the same +physical hardware, must form independent hubs. From 09f0b1c90573c658fa2198273c4b4dfdfc2d9651 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Thu, 21 Nov 2024 17:32:06 +0100 Subject: [PATCH 19/31] Address review comments --- source/hw-spec/controller/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index f713569..c364e56 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -8,18 +8,18 @@ to all devices, independently of their physical location. .. _acq_clk: -Acquisition counter +Acquisition Counter --------------------- The controller MUST have access to a high resolution clock. The tick count from this clock is used to synchronize data from all devices independently of their origin hub. The controller MUST capture the counter value when receiving a :ref:`sample` -and use that value for the ``acqclk_cnt`` field of the :ref:`frame`. +and use that value for the ``acqclk_cnt`` field of the corresponding :ref:`frame`. .. note:: The controller adds the acquisition counter when it receives the samples and proceeds to create the associated frame. However, due to hub to controller transmission delays, this time may have an offset from sample creation time. - To account for this, the hubs contain a register indicating the measured + To account for this, hubs contain a register indicating the measured transmission delay. Users can use this value to more precisely synchronize samples between hubs. @@ -49,7 +49,7 @@ Communication .. toctree:: :maxdepth: 1 - + channels/index addresses register_interface \ No newline at end of file From 4c629d56839e59552ab769c33edb6e52d6a79743 Mon Sep 17 00:00:00 2001 From: jonnew Date: Thu, 21 Nov 2024 13:06:04 -0500 Subject: [PATCH 20/31] Clarify the meaning of the Trigger register - Add and note to clarify the precise meaning of the Trigger register within the device register programming interface on the controller. --- .../hw-spec/controller/register_interface.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst index fe67200..617cebf 100644 --- a/source/hw-spec/controller/register_interface.rst +++ b/source/hw-spec/controller/register_interface.rst @@ -38,6 +38,24 @@ The register programming interface is composed of the following to write ``Register Value`` to the register at ``Register Address`` on the device at ``Device Address`` is queued. Reading the ``Trigger`` register returns 0x00000000 if the queue is empty or 1 if there are pending operations. + + .. note :: + + In order to conform with the register reading and writing sequences that + are described in the following sections, the meaning of the ``Trigger`` + register differs depending on if it is being read or written to. + Specifically, + + - When reading the ``Trigger`` register, the returned value indicates if + the the device register read or write transaction queue is empty (value + is 0x00000000) or has pending transactions that have not yet been + executed (value is 0x00000001). + + - When a value is written to the ``Trigger`` register, a request is sent + to the controller to insert a device register read or write transaction + into its queue. Note that this does not directly affect a the value of + ``Trigger`` as this value will always reflect the state indicated in the + previous bullet point. Appropriate values of ``Register Address`` and ``Register Value`` are determined by: From 67c64acb48abe9e243a37a5866cb65bb4d2aa1be Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Fri, 22 Nov 2024 04:33:19 +0100 Subject: [PATCH 21/31] Improve register maps - Name controller registers - Name hub info device registers - specift gub info device address map - add hub datasheet requirement - clarify optional controller features --- source/hw-spec/controller/addresses.rst | 114 ++++++++++-------- source/hw-spec/controller/index.rst | 7 +- .../hw-spec/controller/register_interface.rst | 58 ++++----- source/hw-spec/devices/hubs.rst | 77 ++++++++++++ source/hw-spec/devices/special.rst | 82 ++++++++----- 5 files changed, 225 insertions(+), 113 deletions(-) diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index d2adf17..cbf35f9 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -13,7 +13,7 @@ The full address space is divided into three address blocks and a fourth current :ref:`address_custom`: 0x8000-0xBFFF -:ref:`address_reserved`: xC000-0xFFFF +:ref:`address_reserved`: 0xC000-0xFFFF .. _address_global: @@ -30,17 +30,17 @@ The address map for this block is as follows: ========== ========================= ================== Address Name Type ========== ========================= ================== -0x0000 Reset Global -0x0001 Running Global -0x0002 System Clock Global -0x0003 Acquisition Clock Global -0x0004 Reset Acquisition Counter Global -0x0005 Hardware Address Global -0x0006 Device Address Register interface -0x0007 Register Address Register interface -0x0008 Register Value Register interface -0x0009 Read/Write Register interface -0x000A Trigger Register interface +0x0000 RESET Global +0x0001 ACQ_RUNNING Global +0x0002 SYS_CLK_HZ Global +0x0003 ACQ_CLK_HZ Global +0x0004 ACQ_CNT_RESET Global +0x0005 SYNC_HW_ADDR Global +0x0006 RI_DEV_ADDR Register interface +0x0007 RI_REG_ADDR Register interface +0x0008 RI_REG_VAL Register interface +0x0009 RI_RW Register interface +0x000A RI_TRIGGER Register interface ========== ========================= ================== Global Acquisition Registers @@ -48,40 +48,46 @@ Global Acquisition Registers The following global acquisition registers govern acquisition over a single controller. -- ``Running``: Set to > 0 to run the system clock and produce data. Set to 0 to - stop the system clock and therefore stop data flow. Results in no other +- ``ACQ_RUNNING``: Acquisition Running. Set to 0x00000001 to run the system clock and produce data. + Set to 0x00000000 to stop the system clock and therefore stop data flow. Results in no other configuration changes. -- ``Reset``: Set to > 0 to trigger a hardware reset and send a fresh device +- ``RESET``: Set to 0x00000001 to trigger a hardware reset and send a fresh device map to the host. Devices are reset but their managed registers might remain unchanged, depending on their configuration (See the :ref:`Device registers - ` section for more information). Set to 0 by the controller + ` section for more information). Set to 0x00000000 by the controller upon entering the reset state. -- ``System Clock``: A read-only register specifying the master hardware clock - frequency in Hz. This is the clock used by the controller to perform data - transmission. +- ``SYS_CLK_HZ``: System Clock. A read-only register specifying the controller + main hardware clock frequency in Hz. This is the clock used by the controller + to perform data transmission. -- ``Acquisition Clock``: A read-only register specifying the system common - clock frequency in Hz. This clock is used to generate an acquisition counter - that timestamps data from all the devices. The ``Common_Timestamp`` in the - read :ref:`frame ` header is incremented at this frequency. +- ``ACQ_CLK_HZ``: Acquisition Clock. A read-only register specifying the + :ref:`Acquisition Counter` frequency in Hz. This clock is used to + generate an acquisition counter that timestamps data from all the devices. + The ``acqclk_cnt`` in the read :ref:`frame ` header is incremented at this frequency. -- ``Reset Acquisition Counter``: This register is used to reset the counter - generating the ``Common_Timestamp`` used in the :ref:`device frames `. - A value of 1 will reset the counter to 0 without affecting the ``Running`` - state. A value of 2 will reset the counter and, at the same time, set - ``Running`` to 1, starting data production. +- ``ACQ_CNT_RESET``: Reset Acquisition Counter. This register is used to reset the :ref:`counter` + generating the ``acqclk_cnt`` used in the :ref:`device frames `. + A value of 0x00000001 will reset the counter to 0 without affecting the ``Running`` + state. A value of 0x00000002 will reset the counter and, at the same time, set + ``Running`` to 0x00000001, starting data production. .. _optional-num-sync-dev: -- ``Hardware Address``: :ref:`(OPTIONAL) ` This is used for systems that allow multiple - controllers with a link between them to synchronize their - ``Common_Timestamps``. When resetting the acquisition counter through the - ``Reset acquisition counter`` on a device with a ``Hardware Address`` of 0, - this command will be sent through an external link to all non-zero devices, - synchronizing the counters. When supported, synchronization is only required - for controllers sharing a hardware implementation. +- ``SYNC_HW_ADDR``: Hardware address. This register MAY be used for implementations that allow multiple + controllers with a link between them to synchronize their :ref:`acquisition counters`. + The presence and limits of this capability are indicated in + the :ref:`ONI_ATTR_NUM_SYNC_DEVS` register. + In configurations that support hardware synchronization, resetting the acquisition counter through + ``ACQ_CNT_RESET`` on a device with a ``SYNC_HW_ADDR`` of 0 will broadcast a hardware signal + to all connected non-zero controllers, resetting all counters simultaneously. + + .. note:: Hardware synchronization is guaranteed only among controllers with the same hardware + implementation. Synchronization between controllers with different implementations is not assured, + even if they support this capability. + +Other addresses in this block are reserved and MUST NOT be used. Device Register Interface ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,38 +110,40 @@ Currently defined addresses are: ======== =========================== Address Name ======== =========================== -0x4000 ONI specification version -0x4001 Read stream alignment -0x4002 Write stream alignment -0x4003 Maximum queued device register operations -0x4004 Number of supported synchronized devices +0x4000 ONI_SPEC_VER +0x4001 ONI_ATTR_READ_STR_ALIGN +0x4002 ONI_ATTR_WRITE_STR_ALIGN +0x4003 ONI_ATTR_MAX_REGISTER_Q +0x4004 ONI_ATTR_NUM_SYNC_DEVS ======== =========================== -- **ONI specification version**: Specifies the version of the ONI specification the controller adheres to. - Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved +- ``ONI_SPEC_VER``: ONI specification version. Specifies the version of the ONI specification the + controller adheres to. Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved .. _read-word-alignment-reg: -- **Read stream alignment**: Specifies, in bits, the data word size the hardware implementation of - the :ref:`read channel ` uses for transmission. +- ``ONI_ATTR_READ_STR_ALIGN``: Read stream alignment. Specifies, in bits, the data word size the hardware + implementation of the :ref:`read channel ` uses for transmission. .. _write-word-alignment-reg: -- **Write stream alignment**: Specifies, in bits, the data word size the hardware implementation of - the :ref:`write channel ` uses for transmission. +- ``ONI_ATTR_WRITE_STR_ALIGN``: Write stream alignment. Specifies, in bits, the data word size the hardware + implementation of the :ref:`write channel ` uses for transmission. .. _max-devaccess-reg: -- **Maximum queued device register operations**: Maximum number of operations that can be queued through the - :ref:`register_interface` +- ``ONI_ATTR_MAX_REGISTER_Q``: Maximum queued device register operations. Maximum number of operations that + can be queued through the :ref:`register_interface`. .. _optional-num-sync-dev-reg: -- **Number of supported synchronized devices**: This register indicates if the optional capability +- ``ONI_ATTR_NUM_SYNC_DEVS``: Number of supported synchronized devices: This register indicates if the optional capability for :ref:`hardware synchronization` is supported. If 0, this controller can - not synchronize with others. if >0, it indicates the maximum number of controllers that can be synchronized + not synchronize with others. if > 0, it indicates the maximum number of controllers that can be synchronized together. If the value is 0xFFFFFFFF, then there is no upper bound to this number. +Other addresses in this block are reserved and MUST NOT be used. + .. _address_custom: @@ -148,6 +156,12 @@ but might be required for the correct operation of a specific hardware implement The :term:`Driver Translator` should, to the possible extent, hide these from the :term:`API`. +.. note:: These addresses SHOULD be reserved for low-level configuration of the hardware. Most + hardware-specific operations SHOULD, if possible, be implemented either in + :ref:`hardware specific registers` in the controller hub-0 + :ref:`hub information device` or in dedicated devices to access these hardware + characteristics (e.g. hub link controllers). + .. _address_reserved: Reserved diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index d6413c6..03c47bb 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -21,10 +21,9 @@ relevant :term:`API`. Optional Features ^^^^^^^^^^^^^^^^^^^ -Some features defined in the specification will be marked with the text ``(OPTIONAL)``. These features are not mandatory, -so different hardware implementations of a controller might chose to implement them or not. The ONI compliance -address space has specific registers for each declared optional feature which determine the availability of each -optional feature and its parameters, if applicable. +The specification includes features that MAY or MAY NOT be implemented in controller hardware. +The :ref:`ONI compliance address space ` includes registers to determine the availability +of each optional feature and its parameters, if applicable. Communication diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst index fe67200..1633da3 100644 --- a/source/hw-spec/controller/register_interface.rst +++ b/source/hw-spec/controller/register_interface.rst @@ -15,31 +15,31 @@ exceed the :ref:`maximum queue size`. The register programming interface is composed of the following :ref:`conf-chan` registers, which are used to insert requests into the queue: -- ``Device Address``: The fully qualified address of a device as enumerated in - the :ref:`device table ` and to which communication will be - directed as described below. +- ``RI_DEV_ADDR``: Device Address. The fully qualified address of a device as + enumerated in the :ref:`device table ` and to which communication + will be directed as described below. -- ``Register Address``: The address of the register within the :ref:`register - map ` of the device located at ``Device Address`` that will be - written to or read from. +- ``RI_REG_ADDR``: Register Address. The address of the register within + the :ref:`register map ` of the device located at ``RI_DEV_ADDR`` + that will be written to or read from. -- ``Register Value``: Value to be written to the register ``Register Address`` - of device located at ``Device Address``. For compatibility with older versions - of the specification, reading this register will return the value of the last - successful read operation. Using this register for reading the value this way - is not recommended. +- ``RI_REG_VAL``: Register Value. Value to be written to the register + ``RI_REG_ADDR`` of device located at ``RI_DEV_ADDR``. For compatibility with + older versions of the specification, reading this register will return the value + of the last successful read operation. Using this register for reading the value + this way is not recommended. -- ``Read/Write``: A flag indicating if a read or write should be performed. 0 +- ``RI_RW``: Read/Write. A flag indicating if a read or write should be performed. 0 indicates a read operation. A value of 0x00000001 indicates a write operation. -- ``Trigger``: Set to 0x00000001 to add either a register read or write - operation depending on the state of ``Read/Write``. If ``Read/Write`` is - 0x00000000, a read operation is queued. If ``Read/Write`` is 1, an operation - to write ``Register Value`` to the register at ``Register Address`` on the - device at ``Device Address`` is queued. Reading the ``Trigger`` register +- ``RI_TRIGGER``: Trigger. Set to 0x00000001 to add either a register read or write + operation depending on the state of ``RI_RW``. If ``RI_RW`` is + 0x00000000, a read operation is queued. If ``RI_RW`` is 1, an operation + to write ``RI_REG_VAL`` to the register at ``Ri_REG_ADDR`` on the + device at ``RI_DEV_ADDR`` is queued. Reading the ``RI_TRIGGER`` register returns 0x00000000 if the queue is empty or 1 if there are pending operations. -Appropriate values of ``Register Address`` and ``Register Value`` are +Appropriate values of ``RI_REG_ADDR`` and ``RI_REG_VAL`` are determined by: - Looking at a device's data sheet if the device is an integrated circuit and @@ -53,7 +53,7 @@ Register Read Sequence When a host requests one of more device register *reads*, the following following sequence must be performed: -1. Check the value of ``Trigger``. +1. Check the value of ``RI_TRIGGER``. - If it is 0x00000000, the queue is empty and the procedure can safely proceed. - Else, there are transactions pending on the queue. Since the @@ -63,11 +63,11 @@ must be performed: 2. For each register read transaction to be added to the queue: 1. The target device is selected by writing its address, as featured on the - device map, into ``Device Address`` on the controller. + device map, into ``RI_DEV_ADDR`` on the controller. 2. The desired register address within the device register map is written - into ``Register Address`` on the controller. - 3. The ``Read/Write`` register on the controller is set to 0x00000000. - 4. The ``Trigger`` register on the controller is set to 0x00000001, inserting + into ``RI_REG_ADDR`` on the controller. + 3. The ``RI_RW`` register on the controller is set to 0x00000000. + 4. The ``RI_TRIGGER`` register on the controller is set to 0x00000001, inserting the operation on the queue. 5. The host repeats steps 1-4 as needed until all read transactions have been queued. @@ -88,7 +88,7 @@ Register Write Sequence When a host requests one or more device register *writes*, the following sequence must be performed: -1. Check the value of ``Trigger``. +1. Check the value of ``RI_TRIGGER``. - If it is 0x00000000, the queue is empty and the procedure can safely proceed. - Else, there are transactions pending on the queue. Since the @@ -98,13 +98,13 @@ sequence must be performed: 2. For each register write transaction to be added to the queue: 1. The target device is selected by writing its address, as featured on the - device map, into ``Device Address`` on the controller + device map, into ``RI_DEV_ADDR`` on the controller 2. The desired register address within the device register map is written - into ``Register Address`` on the controller. - 3. The ``Read/Write`` register on the controller is set to 0x00000001. + into ``RI_REG_ADDR`` on the controller. + 3. The ``RI_RW`` register on the controller is set to 0x00000001. 4. The value to be written into the device register is written into - the ``Register Value`` register in the controller. - 5. The ``Trigger`` register on the controller is set to 0x00000001, inserting + the ``RI_REG_VAL`` register in the controller. + 5. The ``RI_TRIGGER`` register on the controller is set to 0x00000001, inserting the operation on the queue. 6. Repeat as needed until al read transactions have been queued. diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/devices/hubs.rst index 3625c9f..d688458 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/devices/hubs.rst @@ -29,9 +29,86 @@ common for a remote hub to feature a centralized IC (e.g., an FPGA or microcontroller) integrating the device controllers and communication interface to fill this duty, but other schemes are possible. +.. _hub_id: + +Hub Hardware ID +---------------- + Multiple hubs are differentiated through a unique identifier, or Hardware ID. This identifier represents a specific implementation of a hub, defined by a particular collection of devices on a specific hardware platform communicating with the controller through a specific link. Changes in the device collection, the communications link or the general hardware architecture require a new identifier. + +Hub Hardware IDs are 32-bit values with the following format: + +:: + + Reserved(8-bit).Company(8-bit).Hub(16-bit) + +- ``Reserved``: Reserved for future specification revision. Currently + ignored. +- ``Company``: Any person, lab, institute, informal group, or company can + communicate with Open Ephys in order to to obtain a unique 8-bit “Company” + value, and thus be included in the automatic listings of existing ONI API + implementations. Open Ephys is 0x00. +- ``Hub``: 16-bit Hub ID. This number usually identifies a physical product + and would correspond to a stock keeping unit SKU or part number in a + commercial setting. However, there is no formal restriction on these bits + other than uniqueness. + + + +.. _hub-datasheet: + +Hub Datasheet +--------------- +All ONI-compliant hubs MUST have a corresponding datasheet that provides +information on its devices and connectivity. The datasheet must be served +publicly. It can be a text file, PDF, or website. The required datasheet +sections and information are described below. + +Preamble +~~~~~~~~ +The following information MUST be included in the preamble: + +1. **Informal hub name**: Name of the hub. There are no textual + requirements for this field. (e.g., Headstage64, Neuropixels2.0e, are + all valid). +2. **Author(s)**: Hub creator(s). Can be a person/people or + a company, group, or organization. +3. **Hub Hardware ID**: The :ref:`hub ID` that this datasheet corresponds + to. +4. **Connection type**: Must be ``local`` for local hubs or ``remote`` for remote hubs. +5. **Connection name**: Name of the connection interface between the hub and the controller. + There are no textual requirements for this field. (e.g, ONIX1-local, ONIX1-Coax, AcqBoard-Rhythm, + are all valid) + +.. note:: The connection name is not regulated and only provides a general idea of the + type of connection used. Complete connectivity compatibility lists should be provided + by the manufacturer of controller and hub hardware. + +Device Map +~~~~~~~~~~~ + +The datasheet MUST include a map of the devices included on it. It must include +the following information: + +1. **Device index**: 0-based index of the device within the hub +2. **Device ID**: :ref:`Device ID`. +3. **Informal device name**: Device name as stated on its :ref:`datasheet`. + +The special :ref:`Hub Information Device` MAY NOT appear on this table, +as its existence is mandatory and assumed. + +Hardware Specific Registers +----------------------------- + +If the hub implements :ref:`hardware specific registers` +on its :ref:`Hub Information Device`, the datasheet MUST include +a complete list and description of these. + +Any complex procedure regarding these registers (e.g. firmware update procedures) +SHOULD be documented in this section. + diff --git a/source/hw-spec/devices/special.rst b/source/hw-spec/devices/special.rst index f8fdc07..30700a6 100644 --- a/source/hw-spec/devices/special.rst +++ b/source/hw-spec/devices/special.rst @@ -5,6 +5,8 @@ Special Devices There are two kinds of special devices that are required by this specification: An information device on each hub and a heartbeat device in local hub 0. +.. _hub_info_dev: + Information Device -------------------- Every hub in an ONI system MUST feature a special device, located at @@ -12,58 +14,66 @@ Every hub in an ONI system MUST feature a special device, located at about the hub. Because this device is required to exist at a fixed address, it is not listed in the device table and, thus, has no :ref:`device descriptor `. It MUST expose is the register interface, and it MUST NOT include -any streams. The required register map is: +any streams. The register map is divided in two ranges: + +:ref:`hub_addr_common`: 0x00000000 - 0x00007FFF + +:ref:`hub_addr_hw_specific`: 0x00008000 - 0xFFFFFFFF + +.. _hub_addr_common: + +Common Registers +^^^^^^^^^^^^^^^^^^^^^^ + +**Address range:** 0x00000000 - 0x00007FFF + +The registers in this block provide general information about the hub. +All Hub Information Devices MUST provide the following registers: ========== ================================ Address Register ========== ================================ -0x00000000 Hardware ID -0x00000001 Hardware revision -0x00000002 Firmware version -0x00000003 (OPTIONAL) Safe firmware version -0x00000004 Hub clock frequency -0x00000005 Hub data latency +0x00000000 HUB_HW_ID +0x00000001 HUB_HW_REV +0x00000002 HUB_FW_VER +0x00000003 HUB_SAFE_FW_VER +0x00000004 HUB_CLK_HZ +0x00000005 HUB_TX_LATENCY +0x00000006 HUB_ONI_SPEC_VER ========== ================================ Although all register reads are 32-bits in nature, not all registers make use of the complete width. The detailed meaning of each register is: -- **Hardware ID**: A 32-bit value that uniquely identifies the hub. It has a - similar format to the :ref:`Device ID `: - - :: - - Reserved(8-bit).Company(8-bit).Hub(16-bit) +- ``HUB_HW_ID``: :ref:`hub_id`. - - ``Reserved``: Reserved for future specification revision. Currently - ignored. - - ``Company``: Any person, lab, institute, informal group, or company can - communicate with Open Ephys in order to to obtain a unique 8-bit “Company” - value, and thus be included in the automatic listings of existing ONI API - implementations. Open Ephys is 0x00. - - ``Hub``: 16-bit Hub ID. This number usually identifies a physical product - and would correspond to a stock keeping unit SKU or part number in a - commercial setting. However, there is no formal restriction on these bits - other than uniqueness. - -- **Hardware revision**: A 16-bit value identifying changes in the hardware +- ``HUB_HW_REV``: Hardware revision. A 16-bit value identifying changes in the hardware that do not affect the overall operation of the hub and, therefore, do not require a new ID. These are typically related to a PCB revision. -- **Firmware version**: A 16-bit value specifying firmware or gateware version +- ``HUB_FW_VER``: Firmware version. A 16-bit value specifying firmware or gateware version of the main component driving the hub (e.g., an FPGA, microcontroller, or EEPROM for logic-free hubs). -- **Safe firmware version**: (Optional) For hubs that allow online updates of - the firmware, 16-bit version of the fallback safe image, if any. +- ``HUB_SAFE_FW_VER``: Safe firmware version. Hubs MAY allow online updates of + their firmware and MAY include a fallback safe image as update protection. + If such an image is available, this register contains its 16-bit version. + If not applicable, this register must read 0xFFFFFFFF. -- **Hub clock frequency**: 32-bit value holding the frequency, in Hz, of the +- ``HUB_CLK_HZ``: Hub clock frequency. 32-bit value holding the frequency, in Hz, of the hub clock that drives the *Hub_Timestamp* passed to the devices. -- **Hub data latency**: 32-bit value representing the average latency, in +.. _hub_tx_latency: + +- ``HUB_TX_LATENCY``: Data transmission latency. 32-bit value representing the average latency, in nanoseconds, of the physical link between the hub and the controller. Usually 0 in local hubs. +- ``HUB_ONI_SPEC_VER``: ONI specification version. Specifies the version of the ONI specification the + hub adheres to. Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved + +Other addresses in this block are reserved and MUST NOT be used. + All 16-bit versions are in the format: :: @@ -74,6 +84,18 @@ For example, 0x0103 would imply version 1.3. In the case of the information device located on hub 0, the versions refer to the physical controller hardware and its firmware, where that hub is located. +.. _hub_addr_hw_specific: + +Hardware Specific Registers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**Address range:** 0x00008000 - 0xFFFFFFFF + +This address range contains registers that are specific for the hardware implementation +of the hub (e.g. Firmware update registers, buffer memory status, etc...) + +A detailed list of the registers of each hub MUST be available on their :ref:`datasheet`. + Heartbeat Device ------------------ Local hub 0 MUST contain a “heartbeat device”. This is a simple device that From a9365554ccecc802327cc03fb8fbfe1bab514785 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Fri, 22 Nov 2024 04:40:19 +0100 Subject: [PATCH 22/31] Add link to latency register in acquisition counter admonition --- source/hw-spec/controller/index.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index 1419393..1b85e38 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -19,12 +19,10 @@ and use that value for the ``acqclk_cnt`` field of the corresponding :ref:`frame .. note:: The controller adds the acquisition counter when it receives the samples and proceeds to create the associated frame. However, due to hub to controller transmission delays, this time may have an offset from sample creation time. - To account for this, hubs contain a register indicating the measured - transmission delay. Users can use this value to more precisely synchronize + To account for this, hubs contain a :ref:`register` indicating the measured + transmission latency. Users can use this value to more precisely synchronize samples between hubs. -.. todo:: update note admonition to links after the register map is updated - .. _controller_params: Hardware-specific Parameters From 2f54f2be3d082794ef7328e4e4fcddc9f2b8c7f4 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Fri, 22 Nov 2024 18:05:42 +0100 Subject: [PATCH 23/31] Reword device channel list --- source/hw-spec/devices/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/devices/index.rst b/source/hw-spec/devices/index.rst index 2426034..6c72837 100644 --- a/source/hw-spec/devices/index.rst +++ b/source/hw-spec/devices/index.rst @@ -7,12 +7,12 @@ physical element interfacing with the environment (e.g. an external sensor with a digital communication interface), something programmed within the firmware to emulate this (e.g. a digital logic module on an FPGA) or a purely internal data source (e.g. a controller based digital logic module that generates system -status reports). A device exposes the following :ref:`communication channels +status reports). A device exposes a set of :ref:`communication channels `: -- A REQUIRED register interface -- An OPTIONAL read stream -- An OPTIONAL write stream +- It MUST expose a register interface +- It MAY expose a read stream +- It MAY expose a write stream Communication over streams MUST follow a specific :ref:`sample format `, while the register interface must comply with a specific bus From 05d507c9db080e763f4feef49eb073adc41944a4 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Fri, 22 Nov 2024 18:33:45 +0100 Subject: [PATCH 24/31] Clarify register description - Add glossary term for registers - Specify cotroller and device registers con channel types page --- source/hw-spec/comm_channels.rst | 15 ++++++++++----- source/hw-spec/glossary.rst | 6 ++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/hw-spec/comm_channels.rst b/source/hw-spec/comm_channels.rst index 4a737ce..7988f70 100644 --- a/source/hw-spec/comm_channels.rst +++ b/source/hw-spec/comm_channels.rst @@ -16,9 +16,14 @@ the system: :Write: Streams that transmit data to a device from the host computer. Register Channel - A synchronous, bidirectional, N-bit, addressed digital bus. Each address is - a 32-bit value. Registers can be Read-only, Write-only or Read-Write. This - channel also has signals to indicate a successful or failed completion of a - register access operation. (e.g., An access to an non-existent address or a - non-allowed operation will return an error.) + A synchronous, bidirectional, addressed digital bus to access :term:`registers`. + Registers can be Read-only, Write-only or Read/Write. Channels of this type + MUST indicate a successful or failed completion of a register access operation. + (e.g., An access to an non-existent address or a non-allowed operation will signal an error.) + + .. note:: Both the controller and the devices can hold registers. Controller registers are + arranged in a fixed :ref:`address map` and accessed through the + :ref:`configuration channel`. :ref:`Device registers` + follow the address map defined on each device :ref:`datasheet` + and are accessed through the :ref:`device register interface`. diff --git a/source/hw-spec/glossary.rst b/source/hw-spec/glossary.rst index 1f4fedc..baa7e3b 100644 --- a/source/hw-spec/glossary.rst +++ b/source/hw-spec/glossary.rst @@ -114,3 +114,9 @@ elements and/or its context within the specification. a :term:`Hub` that is separated from the :term:`Controller` (e.g., a wire or wireless communication channel) or it could be a bus inside of the :term:`Controller` in the case of a local hub. + + Register + A 32-bit addressed value. + + .. seealso:: :term:`Register Channel` + From 242e21cab619a9337ecc99fe0c5f80ad6c095156 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Fri, 22 Nov 2024 19:04:22 +0100 Subject: [PATCH 25/31] Address review on addresses.rst --- source/hw-spec/controller/addresses.rst | 42 +++++++++++++------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index cbf35f9..f67786a 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -48,23 +48,24 @@ Global Acquisition Registers The following global acquisition registers govern acquisition over a single controller. +- ``RESET``: System Reset. Set to 0x00000001 to trigger a hardware reset and send a fresh device + map to the host. Devices are reset but their managed registers might remain + unchanged, depending on their configuration (See the :ref:`Device registers + ` section for more information). This reggister is set to 0x00000000 + by the controller upon entering the reset state. + - ``ACQ_RUNNING``: Acquisition Running. Set to 0x00000001 to run the system clock and produce data. Set to 0x00000000 to stop the system clock and therefore stop data flow. Results in no other configuration changes. -- ``RESET``: Set to 0x00000001 to trigger a hardware reset and send a fresh device - map to the host. Devices are reset but their managed registers might remain - unchanged, depending on their configuration (See the :ref:`Device registers - ` section for more information). Set to 0x00000000 by the controller - upon entering the reset state. - - ``SYS_CLK_HZ``: System Clock. A read-only register specifying the controller main hardware clock frequency in Hz. This is the clock used by the controller to perform data transmission. - ``ACQ_CLK_HZ``: Acquisition Clock. A read-only register specifying the :ref:`Acquisition Counter` frequency in Hz. This clock is used to - generate an acquisition counter that timestamps data from all the devices. + generate an acquisition counter, common to all devices, that timestamps samples + when packaged into frames by the controller. The ``acqclk_cnt`` in the read :ref:`frame ` header is incremented at this frequency. - ``ACQ_CNT_RESET``: Reset Acquisition Counter. This register is used to reset the :ref:`counter` @@ -80,12 +81,12 @@ controller. The presence and limits of this capability are indicated in the :ref:`ONI_ATTR_NUM_SYNC_DEVS` register. In configurations that support hardware synchronization, resetting the acquisition counter through - ``ACQ_CNT_RESET`` on a device with a ``SYNC_HW_ADDR`` of 0 will broadcast a hardware signal + ``ACQ_CNT_RESET`` on a device with a ``SYNC_HW_ADDR`` of 0x00000000 will broadcast a hardware signal to all connected non-zero controllers, resetting all counters simultaneously. .. note:: Hardware synchronization is guaranteed only among controllers with the same hardware - implementation. Synchronization between controllers with different implementations is not assured, - even if they support this capability. + implementation and that indicate support for this capability. Synchronization between controllers + with different implementations is not assured, even if they indicate support for this capability. Other addresses in this block are reserved and MUST NOT be used. @@ -107,15 +108,15 @@ capabilities and ONI specification compliance. Currently defined addresses are: -======== =========================== +======== =============================== Address Name -======== =========================== +======== =============================== 0x4000 ONI_SPEC_VER 0x4001 ONI_ATTR_READ_STR_ALIGN 0x4002 ONI_ATTR_WRITE_STR_ALIGN -0x4003 ONI_ATTR_MAX_REGISTER_Q +0x4003 ONI_ATTR_MAX_REGISTER_Q_SIZE 0x4004 ONI_ATTR_NUM_SYNC_DEVS -======== =========================== +======== =============================== - ``ONI_SPEC_VER``: ONI specification version. Specifies the version of the ONI specification the controller adheres to. Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved @@ -123,16 +124,18 @@ Address Name .. _read-word-alignment-reg: - ``ONI_ATTR_READ_STR_ALIGN``: Read stream alignment. Specifies, in bits, the data word size the hardware - implementation of the :ref:`read channel ` uses for transmission. + implementation of the :ref:`read channel ` uses for transmission. This value must be divisible + by 8. .. _write-word-alignment-reg: - ``ONI_ATTR_WRITE_STR_ALIGN``: Write stream alignment. Specifies, in bits, the data word size the hardware - implementation of the :ref:`write channel ` uses for transmission. + implementation of the :ref:`write channel ` uses for transmission. This value must be divisible + by 8. .. _max-devaccess-reg: -- ``ONI_ATTR_MAX_REGISTER_Q``: Maximum queued device register operations. Maximum number of operations that +- ``ONI_ATTR_MAX_REGISTER_Q_SIZE``: Maximum queued device register operations. Maximum number of operations that can be queued through the :ref:`register_interface`. .. _optional-num-sync-dev-reg: @@ -154,13 +157,12 @@ Hardware-specific registers This block is reserved for hardware-specific registers that fall out of the scope of this specification but might be required for the correct operation of a specific hardware implementation. -The :term:`Driver Translator` should, to the possible extent, hide these from the :term:`API`. - .. note:: These addresses SHOULD be reserved for low-level configuration of the hardware. Most hardware-specific operations SHOULD, if possible, be implemented either in :ref:`hardware specific registers` in the controller hub-0 :ref:`hub information device` or in dedicated devices to access these hardware - characteristics (e.g. hub link controllers). + characteristics (e.g. hub link controllers). When registers in this block are used, the + :term:`Driver Translator` should, to the possible extent, hide these from the :term:`API`. .. _address_reserved: From b5f21e1528061c615d8b90d300b6cc6fa78b8810 Mon Sep 17 00:00:00 2001 From: jonnew Date: Mon, 25 Nov 2024 15:43:21 -0500 Subject: [PATCH 26/31] Address review comments --- source/hw-spec/controller/register_interface.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst index 617cebf..0f49abe 100644 --- a/source/hw-spec/controller/register_interface.rst +++ b/source/hw-spec/controller/register_interface.rst @@ -51,11 +51,12 @@ The register programming interface is composed of the following is 0x00000000) or has pending transactions that have not yet been executed (value is 0x00000001). - - When a value is written to the ``Trigger`` register, a request is sent - to the controller to insert a device register read or write transaction - into its queue. Note that this does not directly affect a the value of - ``Trigger`` as this value will always reflect the state indicated in the - previous bullet point. + - When a value of 0x00000001 is written to the ``Trigger`` register, a + request is sent to the controller to insert a device register read or + write transaction into its queue. If any other value is written, no + operation is performed. Note that writing a value to this register does + not directly affect a its read value, as that will always reflect the + state indicated in the previous bullet point. Appropriate values of ``Register Address`` and ``Register Value`` are determined by: From 693b0c9c5a49914a667ccc1c9daf86abc2c07770 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 25 Nov 2024 23:48:40 +0100 Subject: [PATCH 27/31] Address further reviews to issues-40-42 --- source/hw-spec/controller/addresses.rst | 11 ++++------ source/hw-spec/devices/datasheet.rst | 5 +++-- source/hw-spec/devices/index.rst | 1 - source/hw-spec/devices/special.rst | 29 +++++++++++++++---------- source/hw-spec/{devices => }/hubs.rst | 26 +++++++++------------- source/hw-spec/index.rst | 1 + 6 files changed, 36 insertions(+), 37 deletions(-) rename source/hw-spec/{devices => }/hubs.rst (82%) diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index f67786a..da64389 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -7,13 +7,10 @@ An ONI :term:`Controller` has a 16-bit address register space, accessible throug The full address space is divided into three address blocks and a fourth currently reserved. The address blocks are: -:ref:`address_global`: 0x0000-0x3FFF - -:ref:`address_spec`: 0x4000-0x7FFF - -:ref:`address_custom`: 0x8000-0xBFFF - -:ref:`address_reserved`: 0xC000-0xFFFF +- :ref:`address_global`: 0x0000-0x3FFF +- :ref:`address_spec`: 0x4000-0x7FFF +- :ref:`address_custom`: 0x8000-0xBFFF +- :ref:`address_reserved`: 0xC000-0xFFFF .. _address_global: diff --git a/source/hw-spec/devices/datasheet.rst b/source/hw-spec/devices/datasheet.rst index 2b4f6ff..575f2ac 100644 --- a/source/hw-spec/devices/datasheet.rst +++ b/source/hw-spec/devices/datasheet.rst @@ -11,8 +11,9 @@ Preamble ~~~~~~~~ The following information is required in the preamble: -1. **Informal device name**: Name of the device. There are no textual - requirements for this field. (e.g., ChipXYX, Chip XYX, and My~Chip-12ab!, are +1. **Informal Device Name**: Name of the device. This field MUST contain only alphanumeric + characters and punctuation marks (i.e. ``?!*+-_~.()``). Other characters, including special + characters MUST NOT be used (e.g., ChipXYX, Chip XYX, and My~Chip-12ab!, are all valid). 2. **Author(s)**: Device firmware or chip creator(s). Can be a person/people or a company, group, or organization. diff --git a/source/hw-spec/devices/index.rst b/source/hw-spec/devices/index.rst index 2426034..c15a335 100644 --- a/source/hw-spec/devices/index.rst +++ b/source/hw-spec/devices/index.rst @@ -29,5 +29,4 @@ order to reach ONI-compliance. sample registers datasheet - hubs special diff --git a/source/hw-spec/devices/special.rst b/source/hw-spec/devices/special.rst index 30700a6..25f6cbc 100644 --- a/source/hw-spec/devices/special.rst +++ b/source/hw-spec/devices/special.rst @@ -2,8 +2,11 @@ Special Devices ================ -There are two kinds of special devices that are required by this specification: -An information device on each hub and a heartbeat device in local hub 0. +There are two kinds of special devices that are required by this specification. +These devices are tied to specific :ref:`hubs`. The required devices are: + +- An :ref:`hub_info_dev` on each hub +- A :ref:`hub_heartbeat` in local hub 0. .. _hub_info_dev: @@ -16,16 +19,15 @@ is not listed in the device table and, thus, has no :ref:`device descriptor `. It MUST expose is the register interface, and it MUST NOT include any streams. The register map is divided in two ranges: -:ref:`hub_addr_common`: 0x00000000 - 0x00007FFF - -:ref:`hub_addr_hw_specific`: 0x00008000 - 0xFFFFFFFF +- :ref:`hub_addr_common`: 0x00000000 - 0x00007FFF +- :ref:`hub_addr_hw_specific`: 0x00008000 - 0xFFFFFFFF .. _hub_addr_common: Common Registers ^^^^^^^^^^^^^^^^^^^^^^ -**Address range:** 0x00000000 - 0x00007FFF +**Address Range:** 0x00000000 - 0x00007FFF The registers in this block provide general information about the hub. All Hub Information Devices MUST provide the following registers: @@ -80,22 +82,27 @@ All 16-bit versions are in the format: Major(8-bit).Minor(8-bit). -For example, 0x0103 would imply version 1.3. In the case of the information -device located on hub 0, the versions refer to the physical controller hardware -and its firmware, where that hub is located. +For example, 0x0103 would imply version 1.3. + +In the case of the information +device located on hub 0, the versions MUST refer to the physical controller hardware +and its firmware, where that hub is located, while ``HUB_CLK_HZ`` MUST be equivalent +to the ``ACQ_CLK_HZ`` :ref:`controller register`. .. _hub_addr_hw_specific: Hardware Specific Registers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**Address range:** 0x00008000 - 0xFFFFFFFF +**Address Range:** 0x00008000 - 0xFFFFFFFF This address range contains registers that are specific for the hardware implementation -of the hub (e.g. Firmware update registers, buffer memory status, etc...) +of the hub (e.g., firmware update registers, buffer memory status, etc...) A detailed list of the registers of each hub MUST be available on their :ref:`datasheet`. +.. _hub_heartbeat: + Heartbeat Device ------------------ Local hub 0 MUST contain a “heartbeat device”. This is a simple device that diff --git a/source/hw-spec/devices/hubs.rst b/source/hw-spec/hubs.rst similarity index 82% rename from source/hw-spec/devices/hubs.rst rename to source/hw-spec/hubs.rst index d688458..a2768cc 100644 --- a/source/hw-spec/devices/hubs.rst +++ b/source/hw-spec/hubs.rst @@ -58,8 +58,6 @@ Hub Hardware IDs are 32-bit values with the following format: commercial setting. However, there is no formal restriction on these bits other than uniqueness. - - .. _hub-datasheet: Hub Datasheet @@ -73,33 +71,29 @@ Preamble ~~~~~~~~ The following information MUST be included in the preamble: -1. **Informal hub name**: Name of the hub. There are no textual - requirements for this field. (e.g., Headstage64, Neuropixels2.0e, are +1. **Informal Hub Name**: Name of the hub. This field MUST contain only alphanumeric + characters and punctuation marks (i.e. ``?!*+-_~.()``). Other characters, including special + characters MUST NOT be used (e.g., Headstage64, Neuropixels2.0e, are all valid). 2. **Author(s)**: Hub creator(s). Can be a person/people or a company, group, or organization. 3. **Hub Hardware ID**: The :ref:`hub ID` that this datasheet corresponds to. -4. **Connection type**: Must be ``local`` for local hubs or ``remote`` for remote hubs. -5. **Connection name**: Name of the connection interface between the hub and the controller. - There are no textual requirements for this field. (e.g, ONIX1-local, ONIX1-Coax, AcqBoard-Rhythm, - are all valid) - -.. note:: The connection name is not regulated and only provides a general idea of the - type of connection used. Complete connectivity compatibility lists should be provided - by the manufacturer of controller and hub hardware. +4. **Connection Type**: MUST be ``local`` for local hubs or ``remote`` for remote hubs. +5. **Notes**: Other relevant information for the hub not covered by this specification. + For remote hubs, this field SHOULD include some description of the physical + connection to the controller. Device Map ~~~~~~~~~~~ - The datasheet MUST include a map of the devices included on it. It must include the following information: -1. **Device index**: 0-based index of the device within the hub +1. **Device Index**: 0-based index of the device within the hub 2. **Device ID**: :ref:`Device ID`. -3. **Informal device name**: Device name as stated on its :ref:`datasheet`. +3. **Informal Device Name**: Device name as stated on its :ref:`datasheet`. -The special :ref:`Hub Information Device` MAY NOT appear on this table, +The special :ref:`Hub Information Device` SHOULD NOT appear on this table, as its existence is mandatory and assumed. Hardware Specific Registers diff --git a/source/hw-spec/index.rst b/source/hw-spec/index.rst index 4db648a..41a91ef 100755 --- a/source/hw-spec/index.rst +++ b/source/hw-spec/index.rst @@ -20,6 +20,7 @@ ONI Hardware Specification comm_channels dev_table devices/index + hubs controller/index From b423c29be0e6dd8f3d89062394d13306e5f65210 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Mon, 25 Nov 2024 23:52:56 +0100 Subject: [PATCH 28/31] Address reviews in issue 39 --- source/hw-spec/comm_channels.rst | 2 +- source/hw-spec/controller/register_interface.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/comm_channels.rst b/source/hw-spec/comm_channels.rst index 7988f70..9d6d70c 100644 --- a/source/hw-spec/comm_channels.rst +++ b/source/hw-spec/comm_channels.rst @@ -19,7 +19,7 @@ the system: A synchronous, bidirectional, addressed digital bus to access :term:`registers`. Registers can be Read-only, Write-only or Read/Write. Channels of this type MUST indicate a successful or failed completion of a register access operation. - (e.g., An access to an non-existent address or a non-allowed operation will signal an error.) + (e.g., an access to an non-existent address or a non-allowed operation will signal an error.) .. note:: Both the controller and the devices can hold registers. Controller registers are arranged in a fixed :ref:`address map` and accessed through the diff --git a/source/hw-spec/controller/register_interface.rst b/source/hw-spec/controller/register_interface.rst index fe67200..e53f877 100644 --- a/source/hw-spec/controller/register_interface.rst +++ b/source/hw-spec/controller/register_interface.rst @@ -1,9 +1,9 @@ .. _register_interface: -Device Register Programming Interface +Device Register Interface ====================================== -The device programming interface allows transparent access to each device's +The device interface allows transparent access to each device's :ref:`register map `. It defines a general purpose bus that hides the specifics of any particular implementation. @@ -12,7 +12,7 @@ queue. The controller will execute the requests in order. The :term:`Driver Tran and :term:`API` must ensure that the number of pending requests in the does not exceed the :ref:`maximum queue size`. -The register programming interface is composed of the following +The register interface is composed of the following :ref:`conf-chan` registers, which are used to insert requests into the queue: - ``Device Address``: The fully qualified address of a device as enumerated in From 8e54020396224c2a6639f5776b7ad2864b29983a Mon Sep 17 00:00:00 2001 From: bparks13 Date: Tue, 21 Jan 2025 09:36:03 -0500 Subject: [PATCH 29/31] Style pass: All titles must be camel case --- source/hw-spec/controller/addresses.rst | 6 +++--- source/hw-spec/controller/index.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index da64389..a94e3e5 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -14,7 +14,7 @@ The full address space is divided into three address blocks and a fourth current .. _address_global: -Operation registers +Operation Registers ------------------- **Address range:** 0x0000-0x3FFF @@ -95,7 +95,7 @@ procedures to device registers are detailed in :ref:`register_interface`. .. _address_spec: -Specification parameters +Specification Parameters ------------------------- **Address range:** 0x4000-0x7FFF @@ -147,7 +147,7 @@ Other addresses in this block are reserved and MUST NOT be used. .. _address_custom: -Hardware-specific registers +Hardware-Specific Registers ---------------------------- **Address range:** 0x8000-0xBFFF diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index 1b85e38..339082c 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -25,7 +25,7 @@ and use that value for the ``acqclk_cnt`` field of the corresponding :ref:`frame .. _controller_params: -Hardware-specific Parameters +Hardware-Specific Parameters ----------------------------- Different ONI-compliant controller implementations might specify hardware-specific parameters related to standard ONI elements. From bb277b411534de218e74c99cbde8ad9af2334544 Mon Sep 17 00:00:00 2001 From: bparks13 Date: Tue, 21 Jan 2025 09:53:57 -0500 Subject: [PATCH 30/31] Style pass: read/write --- source/hw-spec/controller/channels/configuration_channel.rst | 2 +- source/hw-spec/devices/datasheet.rst | 2 +- source/hw-spec/devices/registers.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hw-spec/controller/channels/configuration_channel.rst b/source/hw-spec/controller/channels/configuration_channel.rst index a0940ac..d2baa1f 100644 --- a/source/hw-spec/controller/channels/configuration_channel.rst +++ b/source/hw-spec/controller/channels/configuration_channel.rst @@ -5,7 +5,7 @@ Configuration Channel - **Data alignment** : 32 bits - **Channel type** : Register -- **Direction** : Read-Write +- **Direction** : Read/Write The *configuration* channel supports addressed access to a set of registers. The interface must use 32-bit values and 16-bit addressing. Controllers must diff --git a/source/hw-spec/devices/datasheet.rst b/source/hw-spec/devices/datasheet.rst index 575f2ac..25025f9 100644 --- a/source/hw-spec/devices/datasheet.rst +++ b/source/hw-spec/devices/datasheet.rst @@ -49,7 +49,7 @@ table, but it MUST contain the following columns: - **Name**: Human readable name for the register. Only capital ASCII letters and underscores are allowed, with no spaces or special characters (e.g. ``VALID`` and ``ALSO_VALID`` vs. ``NotValid`` and ``ALSO-NOT-VALID``). -- **Access**: Read-only, write-only, or read-write. +- **Access**: Read-only, write-only, or read/write. - **Time of Effect**: When does a register write affect hardware state? Immediately or following reset? - **POR Value**: Power-on reset default value. diff --git a/source/hw-spec/devices/registers.rst b/source/hw-spec/devices/registers.rst index 83a04d8..599e820 100644 --- a/source/hw-spec/devices/registers.rst +++ b/source/hw-spec/devices/registers.rst @@ -29,13 +29,13 @@ Register Access and Update ----------------------------- Registers, independently of their :ref:`type `, can be defined as -Read-Write, Read-Only or Write-Only. All registers MUST have a valid value at +Read/Write, Read-Only or Write-Only. All registers MUST have a valid value at power-on. Whenever a device receives a reset request generated by the controller, registers might either be reset to their power-on value or keep their current value. This can be defined independently for each register. All register writes, regardless of reset behavior, MUST be immediate (i.e., for -a Read-Write register, reading a register after being written must reflect the +a Read/Write register, reading a register after being written must reflect the new value). However, the *effects* of a register might not occur until the next reset. An example of this type of behavior is registers that operate on the :ref:`device descriptor `. The descriptor must be static during runtime, From f7b42a3a5ffc10f3aef760a57207c0227d8450d1 Mon Sep 17 00:00:00 2001 From: bparks13 Date: Tue, 21 Jan 2025 16:03:19 -0500 Subject: [PATCH 31/31] Style pass: grammar, spelling, formatting, etc. --- .../doxygen-xml/classoni_1_1_context.xml | 2 +- .../clroni/doxygen-xml/classoni_1_1_hub.xml | 2 +- source/api/liboni/liboni-example.rst | 2 +- source/api/liboni/oni.rst | 2 +- source/api/liboni/onix.rst | 4 +- source/hw-spec/comm_channels.rst | 2 +- source/hw-spec/controller/addresses.rst | 13 +++-- source/hw-spec/controller/channels/index.rst | 2 +- source/hw-spec/controller/index.rst | 4 +- source/hw-spec/devices/datasheet.rst | 8 +-- source/hw-spec/devices/index.rst | 6 +-- source/hw-spec/devices/registers.rst | 2 +- source/hw-spec/devices/sample.rst | 2 +- source/hw-spec/devices/special.rst | 10 ++-- source/hw-spec/glossary.rst | 49 +++++++++---------- source/hw-spec/hierarchy.rst | 2 +- source/hw-spec/hubs.rst | 18 +++---- 17 files changed, 68 insertions(+), 62 deletions(-) diff --git a/source/api/bindings/clroni/doxygen-xml/classoni_1_1_context.xml b/source/api/bindings/clroni/doxygen-xml/classoni_1_1_context.xml index 06df7e8..98ef22f 100644 --- a/source/api/bindings/clroni/doxygen-xml/classoni_1_1_context.xml +++ b/source/api/bindings/clroni/doxygen-xml/classoni_1_1_context.xml @@ -360,7 +360,7 @@ ONIException -Thrown when there is an error during hardware initialization (e.g. an invalid device table). +Thrown when there is an error during hardware initialization (e.g., an invalid device table). diff --git a/source/api/bindings/clroni/doxygen-xml/classoni_1_1_hub.xml b/source/api/bindings/clroni/doxygen-xml/classoni_1_1_hub.xml index 2b7677a..037e719 100644 --- a/source/api/bindings/clroni/doxygen-xml/classoni_1_1_hub.xml +++ b/source/api/bindings/clroni/doxygen-xml/classoni_1_1_hub.xml @@ -25,7 +25,7 @@ HardwareID -ONIX hub hardware ID (e.g. host or headstage type). +ONIX hub hardware ID (e.g., host or headstage type). diff --git a/source/api/liboni/liboni-example.rst b/source/api/liboni/liboni-example.rst index ad84d5b..328b4ec 100644 --- a/source/api/liboni/liboni-example.rst +++ b/source/api/liboni/liboni-example.rst @@ -179,7 +179,7 @@ bandwidths, and required response latencies. The buffer sizes default to the minimum size for a given device table (the maximum frame read and write sizes across devices in the table aligned to the bus width of hardware communication link). This provides the lowest latency, but is optimal only for very low -bandwidth acquisition and deterministic and low-latency threads (e.g. those +bandwidth acquisition and deterministic and low-latency threads (e.g., those found on real-time operating system). On a normal computer, these buffers can be set manually to optimize the bandwidth/latency trade off. For example, to set the buffer read and write sizes to 1024 and 8192 bytes respectively, use diff --git a/source/api/liboni/oni.rst b/source/api/liboni/oni.rst index 41122bf..7be8b81 100644 --- a/source/api/liboni/oni.rst +++ b/source/api/liboni/oni.rst @@ -323,7 +323,7 @@ needed during the development of user-facing software. 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 + 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 :ref:`ONI-device datasheet `. diff --git a/source/api/liboni/onix.rst b/source/api/liboni/onix.rst index 208329a..2dde577 100644 --- a/source/api/liboni/onix.rst +++ b/source/api/liboni/onix.rst @@ -15,8 +15,8 @@ ONI specification and are not required to use the API. .. attention:: Many of the devices in this enumeration have no ready-made route to use in high-level software. This is true for a variety of reasons. For instance, they may be prototype hardware or test fixture that we wish to - maintain for backward compatibility (e.g. :macro:`ONIX_TESTREG0`). Or, they - may be a low level device (e.g. :macro:`ONIX_AD7617`) that is used in the + maintain for backward compatibility (e.g., :macro:`ONIX_TESTREG0`). Or, they + may be a low level device (e.g., :macro:`ONIX_AD7617`) that is used in the background by other, higher order devices in the list (e.g. :macro:`ONIX_FMCANALOG1R3`). diff --git a/source/hw-spec/comm_channels.rst b/source/hw-spec/comm_channels.rst index 9d6d70c..3b0ea88 100644 --- a/source/hw-spec/comm_channels.rst +++ b/source/hw-spec/comm_channels.rst @@ -19,7 +19,7 @@ the system: A synchronous, bidirectional, addressed digital bus to access :term:`registers`. Registers can be Read-only, Write-only or Read/Write. Channels of this type MUST indicate a successful or failed completion of a register access operation. - (e.g., an access to an non-existent address or a non-allowed operation will signal an error.) + (e.g., an access to a non-existent address or a non-allowed operation will signal an error.) .. note:: Both the controller and the devices can hold registers. Controller registers are arranged in a fixed :ref:`address map` and accessed through the diff --git a/source/hw-spec/controller/addresses.rst b/source/hw-spec/controller/addresses.rst index a94e3e5..6db1345 100644 --- a/source/hw-spec/controller/addresses.rst +++ b/source/hw-spec/controller/addresses.rst @@ -71,7 +71,7 @@ controller. state. A value of 0x00000002 will reset the counter and, at the same time, set ``Running`` to 0x00000001, starting data production. - .. _optional-num-sync-dev: +.. _optional-num-sync-dev: - ``SYNC_HW_ADDR``: Hardware address. This register MAY be used for implementations that allow multiple controllers with a link between them to synchronize their :ref:`acquisition counters`. @@ -116,7 +116,11 @@ Address Name ======== =============================== - ``ONI_SPEC_VER``: ONI specification version. Specifies the version of the ONI specification the - controller adheres to. Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved + controller adheres to. Format is: + + :: + + Major(8-bit).Minor(8-bit).Patch(8-bit).Reserved(8-bit) .. _read-word-alignment-reg: @@ -137,14 +141,13 @@ Address Name .. _optional-num-sync-dev-reg: -- ``ONI_ATTR_NUM_SYNC_DEVS``: Number of supported synchronized devices: This register indicates if the optional capability +- ``ONI_ATTR_NUM_SYNC_DEVS``: Number of supported synchronized devices. This register indicates if the optional capability for :ref:`hardware synchronization` is supported. If 0, this controller can not synchronize with others. if > 0, it indicates the maximum number of controllers that can be synchronized together. If the value is 0xFFFFFFFF, then there is no upper bound to this number. Other addresses in this block are reserved and MUST NOT be used. - .. _address_custom: Hardware-Specific Registers @@ -158,7 +161,7 @@ but might be required for the correct operation of a specific hardware implement hardware-specific operations SHOULD, if possible, be implemented either in :ref:`hardware specific registers` in the controller hub-0 :ref:`hub information device` or in dedicated devices to access these hardware - characteristics (e.g. hub link controllers). When registers in this block are used, the + characteristics (e.g., hub link controllers). When registers in this block are used, the :term:`Driver Translator` should, to the possible extent, hide these from the :term:`API`. .. _address_reserved: diff --git a/source/hw-spec/controller/channels/index.rst b/source/hw-spec/controller/channels/index.rst index 1ba85e5..34b6c5c 100644 --- a/source/hw-spec/controller/channels/index.rst +++ b/source/hw-spec/controller/channels/index.rst @@ -16,7 +16,7 @@ four abstract communication channels: These channels are implemented by the combination of the controller hardware and the :term:`Driver Translator`. -Concurrent access to a single channel by the host (e.g. by multiple threads of execution or applications) is +Concurrent access to a single channel by the host (e.g., by multiple threads of execution or applications) is NOT permitted. However, individual channels MUST be able to be accessed independently. .. note:: Concurrent access requirements relate only to the hardware implementation. Functions in diff --git a/source/hw-spec/controller/index.rst b/source/hw-spec/controller/index.rst index 339082c..8a6b961 100644 --- a/source/hw-spec/controller/index.rst +++ b/source/hw-spec/controller/index.rst @@ -2,7 +2,7 @@ Controller ========== -The :term:`controller`'s purpose is to interface an ONI hardware system with the host +The :term:`controller's ` purpose is to interface an ONI hardware system with the host computer. It aggregates and routes device data and provides transparent access to all devices, independently of their physical location. @@ -19,7 +19,7 @@ and use that value for the ``acqclk_cnt`` field of the corresponding :ref:`frame .. note:: The controller adds the acquisition counter when it receives the samples and proceeds to create the associated frame. However, due to hub to controller transmission delays, this time may have an offset from sample creation time. - To account for this, hubs contain a :ref:`register` indicating the measured + To account for this, hubs contain a :ref:`register ` indicating the measured transmission latency. Users can use this value to more precisely synchronize samples between hubs. diff --git a/source/hw-spec/devices/datasheet.rst b/source/hw-spec/devices/datasheet.rst index 25025f9..d7a77cd 100644 --- a/source/hw-spec/devices/datasheet.rst +++ b/source/hw-spec/devices/datasheet.rst @@ -12,10 +12,10 @@ Preamble The following information is required in the preamble: 1. **Informal Device Name**: Name of the device. This field MUST contain only alphanumeric - characters and punctuation marks (i.e. ``?!*+-_~.()``). Other characters, including special + characters and punctuation marks (i.e., ``?!*+-_~.()``). Other characters, including special characters MUST NOT be used (e.g., ChipXYX, Chip XYX, and My~Chip-12ab!, are all valid). -2. **Author(s)**: Device firmware or chip creator(s). Can be a person/people or +2. **Author(s)**: Device firmware or chip creator(s). Can be a person/people, or a company, group, or organization. 3. **Device Version**: The :ref:`device version ` that this datasheet corresponds to. @@ -25,7 +25,7 @@ The following information is required in the preamble: Description ~~~~~~~~~~~ A textual description of the functionality of the device. This can be simple or -detailed and is meant to be useful for upstream hardware and software develops +detailed and is meant to be useful for upstream hardware and software developers for understanding the nature of the device during their work. Register Map @@ -49,7 +49,7 @@ table, but it MUST contain the following columns: - **Name**: Human readable name for the register. Only capital ASCII letters and underscores are allowed, with no spaces or special characters (e.g. ``VALID`` and ``ALSO_VALID`` vs. ``NotValid`` and ``ALSO-NOT-VALID``). -- **Access**: Read-only, write-only, or read/write. +- **Access**: Read-only, Write-only, or Read/Write. - **Time of Effect**: When does a register write affect hardware state? Immediately or following reset? - **POR Value**: Power-on reset default value. diff --git a/source/hw-spec/devices/index.rst b/source/hw-spec/devices/index.rst index 9b58f47..31c2b93 100644 --- a/source/hw-spec/devices/index.rst +++ b/source/hw-spec/devices/index.rst @@ -3,10 +3,10 @@ Devices ======= Devices are the endpoint of most ONI transactions. They can represent a -physical element interfacing with the environment (e.g. an external sensor with +physical element interfacing with the environment (e.g., an external sensor with a digital communication interface), something programmed within the firmware to -emulate this (e.g. a digital logic module on an FPGA) or a purely internal data -source (e.g. a controller based digital logic module that generates system +emulate this (e.g., a digital logic module on an FPGA) or a purely internal data +source (e.g., a controller based digital logic module that generates system status reports). A device exposes a set of :ref:`communication channels `: diff --git a/source/hw-spec/devices/registers.rst b/source/hw-spec/devices/registers.rst index 599e820..35cd735 100644 --- a/source/hw-spec/devices/registers.rst +++ b/source/hw-spec/devices/registers.rst @@ -59,7 +59,7 @@ following rules: - For devices that produce data through the :ref:`data-rd-chan`, ``ENABLE`` is a Read/Write register that takes effect after reset. When ``ENABLE`` is set to 0x00000000, the device MUST NOT produce any data on the :ref:`data-rd-chan`. - When ``ENABLE`` is set to 0x00000001, the device it MUST produce data + When ``ENABLE`` is set to 0x00000001, the device MUST produce data on the :ref:`data-rd-chan` in accordance with behavior documented on its :ref:`dev-datasheet`. - For devices that do not produce data through the :ref:`data-rd-chan`, diff --git a/source/hw-spec/devices/sample.rst b/source/hw-spec/devices/sample.rst index 194379c..de808a2 100644 --- a/source/hw-spec/devices/sample.rst +++ b/source/hw-spec/devices/sample.rst @@ -6,7 +6,7 @@ Device Sample Format Data passed over the read or write streams are transmitted in unit packets, or "samples". -Read samples +Read Samples ------------- These are the samples produced by the devices and sent through the :ref:`read stream ` to the controller. diff --git a/source/hw-spec/devices/special.rst b/source/hw-spec/devices/special.rst index 25f6cbc..e14f05f 100644 --- a/source/hw-spec/devices/special.rst +++ b/source/hw-spec/devices/special.rst @@ -16,7 +16,7 @@ Every hub in an ONI system MUST feature a special device, located at :ref:`Device_Index ` 0xFE within the hub, which supplies information about the hub. Because this device is required to exist at a fixed address, it is not listed in the device table and, thus, has no :ref:`device descriptor -`. It MUST expose is the register interface, and it MUST NOT include +`. It MUST expose the register interface, and it MUST NOT include any streams. The register map is divided in two ranges: - :ref:`hub_addr_common`: 0x00000000 - 0x00007FFF @@ -72,7 +72,11 @@ the complete width. The detailed meaning of each register is: 0 in local hubs. - ``HUB_ONI_SPEC_VER``: ONI specification version. Specifies the version of the ONI specification the - hub adheres to. Format is, bits 31-24: Major, 23-16: Minor, 15-8: patch, 7-0: reserved + hub adheres to. Format is: + + :: + + Major(8-bit).Minor(8-bit).Patch(8-bit).Reserved(8-bit) Other addresses in this block are reserved and MUST NOT be used. @@ -80,7 +84,7 @@ All 16-bit versions are in the format: :: - Major(8-bit).Minor(8-bit). + Major(8-bit).Minor(8-bit). For example, 0x0103 would imply version 1.3. diff --git a/source/hw-spec/glossary.rst b/source/hw-spec/glossary.rst index baa7e3b..23354b9 100644 --- a/source/hw-spec/glossary.rst +++ b/source/hw-spec/glossary.rst @@ -2,7 +2,7 @@ Glossary of Terms ================= -Here we provide glossary of terms used terms in this specification. A complete +Here we provide glossary of terms used in this specification. A complete understanding of the term may require knowledge of interaction with other elements and/or its context within the specification. @@ -12,19 +12,19 @@ elements and/or its context within the specification. .. note:: Can be abbreviated as "Context". - A top-level :term:`API` element that holds acquisition state, a - :term:`Device Table`, and :term:`Driver Translator` state in order to + A top-level :term:`API` element that holds the acquisition state, a + :term:`Device Table`, and the :term:`Driver Translator` state in order to communicate with a single :term:`Controller`. A context is manipulated and interacted with using :term:`API` function calls, and ultimately affects - hardware state over the :term:`Host Interconnect` via a :term:`Driver + the hardware state over the :term:`Host Interconnect` via a :term:`Driver Translator`. Multiple contexts can coexist on a single host system and these may each use a different :term:`Driver Translator` and/or physical interface. API - ONI application programming interface that can be used to develop software - to acquire from and control ONI-compliant hardware. + ONI application programming interface (API) that can be used to develop + software to acquire from and control ONI-compliant hardware. .. seealso:: :ref:`oni-api` @@ -35,23 +35,22 @@ elements and/or its context within the specification. coexist in a single :term:`Host Computer` and need not use the same :term:`Driver Translator`. Controllers communicate via :term:`API` calls that manipulate an :term:`Acquisition Context` and a :term:`Device Table`, - which affect controller state using the driver translator. :term:`Hubs + which affects controller state using the driver translator. :term:`Hubs ` are connected to the controller where data to/from their devices is packed and transmitted to/from the host computer. The controller contains a - main clock which provides a common timestamp to all incoming data, and that + main clock which provides a common timestamp to all incoming data, and can be synchronized with other controllers. .. seealso:: :ref:`Controller Specification ` Device - A configurable piece of hardware with its own register address space - (e.g., an integrated circuit) or a digital “core” that emulates this. - Devices may or may not produce and/or accept :term:`streaming data ` , but that must at least implement a minimal :term:`register - programming channel `. They must be documented, using a - :term:`Device Datasheet`. Devices are the endpoints for most communication - operations and often are the hardware interfacing with the physical - environment. + A configurable piece of hardware with its own register address space (e.g., + an integrated circuit) or a digital “core” that emulates this. Devices may + or may not produce and/or accept :term:`streaming data `, + but must implement a minimal :term:`register programming channel `. They must be documented, using a :term:`Device Datasheet`. + Devices are the endpoints for most communication operations and often are + the hardware interfacing with the physical environment. .. seealso:: :ref:`Device Specification ` @@ -71,7 +70,7 @@ elements and/or its context within the specification. Device Table A collection of :term:`device addresses ` and corresponding metadata for all :ref:`devices ` governed by a :term:`controller - `. The device table contains all meta-information required to + `. The device table contains all meta-information required for proper interaction with each device (e.g., packet read-size, packet write-size, burst read cycles, etc.). @@ -97,14 +96,14 @@ elements and/or its context within the specification. Hub A collection of :term:`Devices ` that communicate with a - :term:`Controller` over a :term:`Port` and share a common - clock. All data acquired by :term:`devices ` in the same Hub are - timestamped by this clock. Different Hubs may be governed by asynchronous - clocks. A Hub either forms a portion of the :term:`Device Table` or the - entire :term:`Device Table` if it contains all the :term:`devices ` - within the :term:`Acquisition Context`. Hubs can be exist in separate - hardware from the :term:`Controller` (remote hubs) or within the - :term:`Controller` (local hubs). + :term:`Controller` over a :term:`Port` and share a common clock. All data + acquired by :term:`devices ` in the same Hub are timestamped by this + clock. Different Hubs may be governed by asynchronous clocks. A Hub either + forms a portion of the :term:`Device Table` or the entire :term:`Device + Table` if it contains all the :term:`devices ` within the + :term:`Acquisition Context`. Hubs can exist in separate hardware from the + :term:`Controller` (remote hubs) or within the :term:`Controller` (local + hubs). .. seealso:: :ref:`Hub Specification ` diff --git a/source/hw-spec/hierarchy.rst b/source/hw-spec/hierarchy.rst index 29dfae2..fbdd1c7 100644 --- a/source/hw-spec/hierarchy.rst +++ b/source/hw-spec/hierarchy.rst @@ -15,7 +15,7 @@ elements: These hardware elements are managed within a single host computer where they are governed by a single :term:`Acquisition Context`. An ONI system is arranged in a `tiered-star network `__ similar -to that of, e.g., USB, which is shown here: +to that of USB, which is shown here: :: diff --git a/source/hw-spec/hubs.rst b/source/hw-spec/hubs.rst index a2768cc..06dd039 100644 --- a/source/hw-spec/hubs.rst +++ b/source/hw-spec/hubs.rst @@ -5,17 +5,17 @@ Hubs Devices MUST be grouped in logical or physical collections, called Hubs. They can be independent hardware aggregates connected to the controller -(e.g. a headstage for neural acquisition) or a logical partition of existing hardware -(e.g. a collection of devices implemented in the same firmware as the controller). +(e.g., a headstage for neural acquisition) or a logical partition of existing hardware +(e.g., a collection of devices implemented in the same firmware as the controller). Every hub MUST have access to a counter driven by a high resolution clock. -All devices within a hub MUST use the values of this counter for the the +All devices within a hub MUST use the values of this counter for the ``hubclk_cnt`` field of their :ref:`data samples `. Hubs that exist on hardware that is physically separated from the :ref:`controller ` are referred to as remote hubs, while hubs existing on the controller are local hubs. An ONI-compliant system MUST implement at least one local hub, located at -:ref:`Hub_Index 0 ` and sharing the clock of controller's main +:ref:`Hub_Index 0 ` that shares the clock of controller's main state machine, and can implement up to 253 additional hubs, local or remote. All devices reflecting or modifying the :ref:`controller ` state and/or reporting errors or similar status messages must be implemented in local hub 0. @@ -38,7 +38,7 @@ Multiple hubs are differentiated through a unique identifier, or Hardware ID. This identifier represents a specific implementation of a hub, defined by a particular collection of devices on a specific hardware platform communicating with the controller through a specific link. Changes in the device collection, -the communications link or the general hardware architecture require a new +the communications link, or the general hardware architecture require a new identifier. Hub Hardware IDs are 32-bit values with the following format: @@ -54,7 +54,7 @@ Hub Hardware IDs are 32-bit values with the following format: value, and thus be included in the automatic listings of existing ONI API implementations. Open Ephys is 0x00. - ``Hub``: 16-bit Hub ID. This number usually identifies a physical product - and would correspond to a stock keeping unit SKU or part number in a + and would correspond to a stock keeping unit (SKU) or part number in a commercial setting. However, there is no formal restriction on these bits other than uniqueness. @@ -72,10 +72,10 @@ Preamble The following information MUST be included in the preamble: 1. **Informal Hub Name**: Name of the hub. This field MUST contain only alphanumeric - characters and punctuation marks (i.e. ``?!*+-_~.()``). Other characters, including special + characters and punctuation marks (i.e., ``?!*+-_~.()``). Other characters, including special characters MUST NOT be used (e.g., Headstage64, Neuropixels2.0e, are all valid). -2. **Author(s)**: Hub creator(s). Can be a person/people or +2. **Author(s)**: Hub creator(s). Can be a person/people, or a company, group, or organization. 3. **Hub Hardware ID**: The :ref:`hub ID` that this datasheet corresponds to. @@ -103,6 +103,6 @@ If the hub implements :ref:`hardware specific registers` on its :ref:`Hub Information Device`, the datasheet MUST include a complete list and description of these. -Any complex procedure regarding these registers (e.g. firmware update procedures) +Any complex procedure regarding these registers (e.g., firmware update procedures) SHOULD be documented in this section.