/*
 * Copyright 2010-2012,2015 Ettus Research LLC
 * Copyright 2018 Ettus Research, a National Instruments Company
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#pragma once

#include <uhd/config.hpp>
#include <uhd/types/time_spec.hpp>
#include <cstdint>

namespace uhd {

/*!
 * Command struct for configuration and control of streaming:
 *
 * A stream command defines how the device sends samples to the host.
 * Streaming is controlled by submitting a stream command to the rx dsp.
 * Granular control over what the device streams to the host can be
 * achieved through submission of multiple (carefully-crafted) commands.
 *
 * The mode parameter controls how streaming is issued to the device:
 *   - "Start continuous" tells the device to stream samples indefinitely.
 *   - "Stop continuous" tells the device to end continuous streaming.
 *   - "Num samps and done" tells the device to stream num samps and
 *      to not expect a future stream command for contiguous samples.
 *   - "Num samps and more" tells the device to stream num samps and
 *      to expect a future stream command for contiguous samples.
 *
 * The stream now parameter controls when the stream begins.
 * When true, the device will begin streaming ASAP. When false,
 * the device will start streaming based on the trigger source.
 * The trigger source TIMED will begin at a time specified by time_spec.
 *
 * Note: When a radio runs at multiple samples per clock cycle, it may not be
 * possible to request samples at any given time, and \p num_samps might have to
 * be an integer multiple of SPC.
 */
struct UHD_API stream_cmd_t
{
    enum stream_mode_t : uint32_t {
        STREAM_MODE_START_CONTINUOUS   = int('a'),
        STREAM_MODE_STOP_CONTINUOUS    = int('o'),
        STREAM_MODE_NUM_SAMPS_AND_DONE = int('d'),
        STREAM_MODE_NUM_SAMPS_AND_MORE = int('m')
    } stream_mode;
    uint64_t num_samps;

    //! When true, the device will begin streaming ASAP.
    //
    // When false, the device will start streaming based on the \p trigger source.
    bool stream_now;
    //! The time spec to use when \p stream_now is false and \p trigger is TIMED
    time_spec_t time_spec;

    //! Trigger source to be used when stream_now is false
    //
    // When \p stream_now is false, the trigger source controls when
    // streaming begins. The default trigger source is TIMED, meaning
    // that streaming will begin when the time specified in time_spec is reached.
    enum class trigger_t {
        //! Start streaming when the time specified in time_spec is reached
        TIMED,
        //! Start streaming when the transmitter is running
        TX_RUNNING,
    } trigger;

    stream_cmd_t(const stream_mode_t& stream_mode);
};

} /* namespace uhd */
