Module design#
pw_daq: None
Design concept#
The design of pw_daq is based around an abstract DAQ device. This device is
made up of blocks which each provide some
consistent set of functionality. Examples of blocks are UART, DigitalIO, PWM,
ADC, DAC, etc.
Each block provides a set of endpoints,
which can either be an Event or an Action. Events are emitted when a relevant
physical event or block state change occurs and may carry an associated output
value. Actions may be invoked with an input value (InValue). Actions either
cause some physical action (possibly leading to an Event) or change the state
of the block.
block
columns 2
daq:2
digital0
uart0
digital1
uart1
digital2
i2c0
adc0
spi0
adc1
pwm0
dac0
pwm1
Blocks#
Blocks are a virtual resource that a backend will tie to a specific hardware peripheral, set of peripherals, or other resource on the concrete DAQ device.
Blocks typically represent a real peripheral or other basic functionality which can be used to monitor or interact with the connected hardware system. Some examples include DigitalIO, ADC, DAC, PWM, UART, and Timer blocks.
Blocks are “created” dynamically and only operate after creation. If two blocks share the same hardware resources (e.g. pin mappings) the DAQ backend may disallow two blocks from existing at the same time.
A backend does not need to map blocks to the exact physical capabilities of a
DAQ. For instance, the LabJack DAQs have programmable muxes for digital inputs
and outputs, but a backend could reasonably tie digital0 to a single pin.
Instances of blocks are named using the <block_type><N> format, where
<block_type> is one of the types listed below and <N> is a number
representing the index of the peripheral or function, e.g. uart1 or
digital0. The mapping between index number and actual hardware is defined
by the backend in use.
Attributes#
Blocks may have attributes associated with them—essentially configuration options that can be set at creation or changed dynamically (depending on the backend in use), such as a UART block’s baud rate.
Attributes may have a limited set of valid values. These values will be defined below in Block details.
Attributes may have a default value (if no other value is specified at creation, the attribute will start with this value). Default values will be specified in Block details. If no default is specified, the attribute must be specified at creation of the block.
Traits#
Attributes can have “traits”. Traits define the specific abilities and interactions an attribute can have. The below table defines all traits defined by the abstract DAQ. Additional traits may be defined by a backend.
Trait |
Values |
Description |
|---|---|---|
|
Defines when an attribute can be modified. |
|
|
The attribute is immutable. It cannot be changed even at block creation. |
|
|
The attribute is mutable at init-time only (at block creation). |
|
|
The attribute is run-time mutable (noted as (empty) in diagrams, or
|
Note
In the attribute tables below, a trailing asterisk (*) on a value
indicates that it is the default value when the attribute is not explicitly
specified. const attributes do not have a default as they cannot be
changed, even at block creation.
The abstract DAQ defines traits for all attributes; each backend may be less
restrictive than what the abstract DAQ defines, for example allowing an
attribute to be modified at run-time when it is marked as init. However, a
backend should not be more restrictive than the abstract DAQ. This ensures a
moderate level of interoperability between different backends. In either case,
any divergence from the abstract DAQ interface should be well documented.
Endpoints#
Endpoints are either Events or Actions associated with a Block. Endpoints are
specified using the following notation: <block>.<endpoint>, where
<block> is the specific name of the owning block, e.g. digital1, and
.<endpoint> is the name of the Event or Action, e.g. .write. So in this
example, the Endpoint would be noted as: digital1.write.
Note
The leading . is used in documentation to indicate an Event or Action
outside the context of a specific Block. When specified on the command line,
however, the Action or Event will always be paired with a Block to form a
complete endpoint.
Events#
Events are Endpoints that are “emitted” when a change of state happens in the associated Block or some hardware event occurs. Event endpoints generate Event instances, which are the actual occurrence.
An Event instance contains three pieces of information:
The timestamp (in local DAQ time) at which the event occurred.
The endpoint that created the event (including the block index).
Optionally, a data value associated with the event. See the individual block documentation for more details on the values.
Note
All pw_daq timestamps are stored as 64-bit integers and represent
nanoseconds since the DAQ device’s epoch.
Some caveats to keep in mind:
The resolution of the DAQ clock may be lower. The minimum resolution is guaranteed to be microsecond granularity.
Resolution is not accuracy. The timestamps may have jitter or offsets from the actual event times. This is backend-specific.
Timestamps are guaranteed to be monotonic except across a reset or power cycle.
A DAQ device logs Event instances as they occur. The size of this log depends on the concrete DAQ being used.
Actions#
Actions are Endpoints that may be invoked either directly via do or via
on triggers. They represent an action that the block may take.
Actions may accept a single input value (InValue) as an argument and return
a resulting value, for example uart0.tx takes a character (or byte) as
input and returns a bool to indicate success or failure.
If an action is invoked via an on trigger the returned result is discarded.
Backends#
Backends are concrete implementations of the abstract DAQ which support an
actual DAQ device. They implement the abstract backend interface necessary to
provide the functionality of pw_daq. See pw_daq backends for
details on the backend design, API, and supported backends.
Important
While a backend can be less restrictive than the abstract DAQ, it cannot be
more restrictive. For example, if the abstract DAQ declares an attribute as
init, the backend can allow run-time modification (less restrictive) but
cannot change it to const. Either way, the backend should document
divergence from the abstract DAQ.
Backend defined (BED)#
If a block, attribute, endpoint, trait, etc. is not specified by the abstract
DAQ and is expected to be defined by the backend in use, it will be marked as
BED. If an attribute is marked BED, the backend also defines whether and
what the default value is.
Notation#
Throughout this documentation we will use the following notation to define Blocks and their Endpoints.
classDiagram
class block {
attribute [traits]
> event(outvalue)
< action(invalue) result
}
Detailed design#
An abstract DAQ device supports these commands:
Block Commands:
create- Create a block.list- List all current blocks.destroy- Tear down the specified block.set- Set an attribute on a block.get- Get an attribute from a block.
Endpoint Commands:
on- When the specified Event occurs, invoke the supplied Action.listen- Stream new Events from the given event endpoint.do- Invoke the specified Action and return the result.
Log Commands:
dump- Dump all Event logs from the DAQ device.clear- Clear all Event logs.usage- Get stats on log usage and capacity.
Device Commands:
info- List information about the connected DAQ device or backend.capabilities- List all capabilities of the DAQ.reset- Reset the DAQ device state.
Additional commands may be supported by specific DAQ backends. See the backend specific documentation for details.
Note
on commands can only be triggered using Events, not Actions.
Note
do commands can only invoke Actions, not Events.
Block details#
The blocks supported by the abstract DAQ device are:
digital- A digital input/output peripheral. Can either be input or output and supports configurations such as pull-up/pull-down.adc- An analog input peripheral.dac- An analog output peripheral.pwm- A Pulse Width Modulation peripheral.uart- A UART peripheral. Supports standard baud rates and both RX and TX.spi- A SPI peripheral.i2c- An I2C peripheral.timer- A timer function. Supports both one-shot and periodic at a specified period.stopwatch- A stopwatch function to track time between events.lut- A lookup table.
Note
A * in the tables below denotes the default value for an attribute.
Digital#
Represents a digital GPIO which may be either input, output, or open drain. In
input and output mode, the pin may take on either high or low states.
Note
In open drain mode, the terminology is active or inactive since the
actual physical voltage on the pin is typically inverted. However, throughout
the documentation we use high and active and low and
inactive interchangeably.
classDiagram
class digital {
pin [const]
direction [init]
initial [init]
pull
> change(state)
> risingedge()
> fallingedge()
< write(state) success
< read() state
}
Attributes#
Attribute |
Traits |
Values |
Description |
|---|---|---|---|
|
|
|
The pin identifier (e.g. |
|
|
|
The direction of the digital block. |
|
|
|
The initial value of the pin. Only valid in output or open drain mode. |
|
|
|
Pull-up or pull-down setting. Only valid in input or open drain mode. |
Endpoints#
The following tables define the valid Events and Actions supported by a Digital GPIO block.
Event |
OutValue |
Description |
|---|---|---|
|
|
Indicates the pin state changed. OutValue indicates whether the new
state is |
|
N/A |
Indicates the digital input went from low to high. Only valid for input mode. |
|
N/A |
Indicates the digital input went from high to low. Only valid for input mode. |
Action |
InValue |
Result |
Description |
|---|---|---|---|
|
|
|
Write the new state to the pin. InValue is the new state to write:
|
|
N/A |
|
Read the current state of the pin. Valid in all modes. In open drain mode returns the drive state, not the pin state. |
ADC#
TBD
classDiagram
class adc {
pin [const]
vrefpos [const]
vrefneg [const]
samplebits [const]
samplerate [init]
scalemultiplier [init]
scaleoffset [init]
> sampled(value)
> started()
> stopped(count)
< sample() value
< start() success
< stop() success
}
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by an ADC block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
DAC#
TBD
classDiagram
class dac {
pin [const]
vrefpos [const]
vrefneg [const]
databits [const]
> conversion(value)
< convert(value) success
}
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by a DAC block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
PWM#
TBD
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by a PWM block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
UART#
Represents a UART peripheral which may have both RX and TX capabilities.
classDiagram
class uart {
txpin [const]
rxpin [const]
baudrate [init]
databits [init]
parity [init]
stopbits [init]
loopback [init]
> rx(character)
> sent(character)
> break()
> error(error)
< tx(character) success
}
Attributes#
Attribute |
Traits |
Values |
Description |
|---|---|---|---|
|
|
|
The pin identifier (e.g. |
|
|
|
The pin identifier (e.g. |
|
|
|
The baud rate to configure. Not all baud rates may be supported. |
|
|
|
The number of data bits in a byte. |
|
|
|
Whether a parity bit is included. |
|
|
|
The number of stop bits framing a byte. |
|
|
|
Whether to automatically loop received characters back to the transmit channel. |
Endpoints#
The following tables define the valid Events and Actions supported by a UART block.
Event |
OutValue |
Description |
|---|---|---|
|
|
Indicates that a character has been received on the UART RX channel. The OutValue is the received character. |
|
|
Indicates that a character has been sent on the UART TX channel. The OutValue is the sent character. |
|
N/A |
Indicates a break character was received. |
|
|
Indicates an error occurred on either the TX or RX channel. The definition of the error code returned is specific to the backend and DAQ device. |
Action |
InValue |
Result |
Description |
|---|---|---|---|
|
|
|
Write the given character to the TX channel. |
SPI#
TBD
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by a SPI block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
I2C#
TBD
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by an I2C block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
Timer#
TBD
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by a Timer block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
Stopwatch#
TBD
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by a Stopwatch block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |
LUT#
TBD
Attributes#
Endpoints#
The following tables define the valid Events and Actions supported by a LUT block.
Event |
OutValue |
Description |
|---|---|---|
TBD |
TBD |
TBD |
Action |
InValue |
Result |
Description |
|---|---|---|---|
TBD |
TBD |
TBD |
TBD |