Device

enum class xdaq::BasicDeviceStatus : int

Values:

enumerator Success
enumerator Failure
using xdaq::Device = BasicDevice<std::uint32_t, std::uint32_t, BasicDeviceStatus>
template<typename Addr, typename Value, typename Return>
class BasicDevice

Interface for devices with register manipulation and streaming capabilities.

Public Functions

inline virtual return_t set_register_sync(addr_t addr, value_t value, value_t mask = value_mask) noexcept

Synchronously sets a register value and sends it to the device.

Parameters:
  • addr – Address of the register.

  • value – Value to set.

  • mask – Optional mask, defaults to a value of all 1s.

Returns:

return_t Result of the operation.

virtual return_t set_register(addr_t addr, value_t value, value_t mask = value_mask) noexcept = 0

Set a register value without immediately sending it to the device.

Parameters:
  • addr – Address of the register.

  • value – Value to set.

  • mask – Optional mask, defaults to all 1s.

Returns:

return_t Result of the operation.

virtual return_t send_registers() noexcept = 0

Flush pending register writes from the host to the device.

Returns:

return_t Result of the synchronization operation.

inline virtual std::optional<value_t> get_register_sync(addr_t addr) noexcept

Synchronously read a register value from the device.

Parameters:

addr – Address of the register.

Returns:

std::optional<value_t> The register value, or std::nullopt if the operation fails.

virtual value_t get_register(addr_t addr) noexcept = 0

Get a cached register value without fetching the latest value from the device.

Parameters:

addr – Address of the register.

Returns:

value_t The register value.

virtual return_t read_registers() noexcept = 0

Fetch the latest register values from the device to the host.

Returns:

return_t Result of the synchronization operation.

virtual return_t trigger(addr_t addr, int bit) noexcept = 0

Trigger a specific action on the device by setting a bit in a register.

Parameters:
  • addr – Register address.

  • bit – Bit position to set.

Returns:

return_t Result of the operation.

virtual std::size_t write(addr_t addr, std::size_t length, const unsigned char *data) = 0

Write data to the device.

Parameters:
  • addr – Address to write to.

  • length – Number of bytes to write.

  • data – Pointer to the data to write.

Returns:

std::size_t Number of bytes successfully written.

virtual std::size_t read(addr_t addr, std::size_t length, unsigned char *data) = 0

Reads data from the device into the host buffer.

Note

A length of 0 activates discard mode, causing any data in the device’s software/hardware buffer to be removed.

Parameters:
  • addr – Address to read from.

  • length – The number of bytes to read. When set to 0, the function discards any data currently stored in the device’s buffer.

  • data – Pointer to the destination buffer. Ignored if length is 0.

Returns:

std::size_t If reading data, returns the number of bytes successfully read. If in discard mode (when length is 0), returns the total number of bytes discarded. Note that due to potential padding, the discarded count may exceed the actual data amount.

virtual std::unique_ptr<DataStream> start_read_stream(addr_t addr, xdaq::DataStream::receive_callback &&on_receive, std::size_t chunk_size = 0) = 0

Start an asynchronous data stream from the device.

Creates a new DataStream object. Returns nullptr if the device does not support asynchronous streaming or if resources are unavailable.

See DataStream for more details.

Note

The lifetime of any received event is bound to the DataStream instance. Ensure that any captured stack variables remain valid as long as the stream is active.

Parameters:
  • addr – The address to read from.

  • on_receive – Callback function to handle received data.

  • chunk_size – Preferred read chunk size in bytes. When set to 0, the device implementation chooses a default.

Returns:

std::unique_ptr<DataStream>

virtual std::expected<std::string, std::string> get_status() = 0

Get the current status of the device as a JSON-formatted string.

Returns:

std::expected<std::string, std::string> The status string, or an error message if not available.

virtual std::expected<std::string, std::string> get_info() = 0

Get information about the device as a JSON-formatted string.

Returns:

std::expected<std::string, std::string> The information string, or an error message if not available.

struct DataStream

Asynchronous data stream from the device.

This struct provides an efficient mechanism for streaming data from the device. Behavior varies depending on the specific implementation. Memory management, buffer size, and other parameters depend on the OS and device type (e.g., PCIe, USB).

Note

The DataStream will automatically stop when the DataStream object is destroyed.

Public Functions

inline DataStream()

Construct a new DataStream object.

Example usage: Demonstrates basic usage of the DataStream interface for handling events.

auto stream = dev->start_read_stream(
    0xA0, // Address to read from
    [](xdaq::DataStream::Event &&event) {
        if (std::holds_alternative<xdaq::DataStream::Events::Stop>(event)) {
            fmt::println("Stream stopped.");
        } else if (std::holds_alternative<xdaq::DataStream::Events::Error>(event)) {
            const auto &error = std::get<xdaq::DataStream::Events::Error>(event).error;
            fmt::println("Stream error: {}", error);
        } else {
            // data process
            fmt::println("Data received.");
        }
    }
);

if (!stream) {
    fmt::println("Failed to start data stream.");
    return;
}

// Do other work...
stream->stop(); // Stop the stream when done
Parameters:

on_receive – The callback function to handle received data.

virtual void stop() = 0

Request the data stream to stop.

This method signals the data stream to stop. Event may still be received after calling this method until wait_stop is called or the destruction of the DataStream object.

virtual void wait_stop() = 0

Wait for the data stream to fully stop and release resources.

This method acts as a synchronization point, ensuring that no further receive events are processed and that resources associated with the event callback function are released. Although calling this method is optional (the data stream automatically stops when its object is destroyed), you may invoke it to force an immediate stop and resource cleanup.