Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger mechanism for pattern and signal generator #149

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/libm2k/enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@ namespace libm2k {
};


/**
* @enum M2K_TRIGGER_OUT_SOURCE
* @brief Select the triggering source for a DeviceOut
*/
enum M2K_TRIGGER_OUT_SOURCE {
SRC_OUT_NONE = 0, ///< SRC_OUT_NONE - no trigger events
SRC_OUT_TRIGGER_IN = 1, ///< SRC_OUT_TRIGGER_IN - trigger events on the TI(trigger in) pin trigger the Output interface
SRC_OUT_TRIGGER_OUT = 2, ///< SRC_OUT_TRIGGER_OUT - trigger events on the TO(trigger out) pin trigger the Output interface
SRC_OUT_ANALOG_IN = 3, ///< SRC_OUT_ANALOG_IN - trigger events on the AnalogIn interface trigger the Output interface
SRC_OUT_DIGITAL_IN = 4, ///< SRC_OUT_DIGITAL_IN - trigger events on the DigitalIn interface trigger the Output interface
};


/**
* @struct SETTINGS
* @brief Triggering system
Expand Down
84 changes: 84 additions & 0 deletions include/libm2k/m2khardwaretrigger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,90 @@ class LIBM2K_API M2kHardwareTrigger
* @note Only available from firmware v0.24.
*/
virtual M2K_TRIGGER_SOURCE_DIGITAL getDigitalSource() const;


/**
* @brief Select which interface triggers the DigitalOut.
* @param src: of type M2K_TRIGGER_OUT_SOURCE:\n
* SRC_OUT_NONE - no trigger events
* SRC_OUT_TRIGGER_IN - trigger events on the TI(trigger in) pin trigger the DigitalOut interface;\n
* SRC_OUT_TRIGGER_OUT - trigger events on the TO(trigger out) pin trigger the DigitalOut interface;\n
* SRC_OUT_ANALOG_IN - trigger events on the AnalogIn interface trigger the DigitalOut interface;\n
* SRC_OUT_DIGITAL_IN - trigger events on the DigitalIn interface trigger the DigitalOut interface;\n
* @note Only available from firmware v0.26.
*/
virtual void setDigitalOutSource(M2K_TRIGGER_OUT_SOURCE src) = 0;


/**
* @brief Retrieve the source of the DigitalOut interface trigger event.
* @return M2K_TRIGGER_OUT_SOURCE :\n
* SRC_OUT_NONE;\n
* SRC_OUT_TRIGGER_IN;\n
* SRC_OUT_TRIGGER_OUT;\n
* SRC_OUT_ANALOG_IN;\n
* SRC_OUT_DIGITAL_IN;\n
* @note Only available from firmware v0.26.
*/
virtual M2K_TRIGGER_OUT_SOURCE getDigitalOutSource() const = 0;


/**
* @brief Set the trigger condition for the TI/TO in order to trigger the DigitalOut interface
* @param cond the specific trigger condition
*
* @note to have any effect the digital out source must be set to TI or TO
*/
virtual void setDigitalOutCondition(M2K_TRIGGER_CONDITION_DIGITAL cond) = 0;


/**
* @brief Get the trigger condition of the TI/TO pins that triggers the DigitalOut interface
* @return the trigger condition
*/
virtual M2K_TRIGGER_CONDITION_DIGITAL getDigitalOutCondition() const = 0;


/**
* @brief Select which interface triggers the AnalogOut.
* @param src: of type M2K_TRIGGER_OUT_SOURCE:\n
* SRC_OUT_NONE - no trigger events
* SRC_OUT_TRIGGER_IN - trigger events on the TI(trigger in) pin trigger the DigitalOut interface;\n
* SRC_OUT_TRIGGER_OUT - trigger events on the TO(trigger out) pin trigger the DigitalOut interface;\n
* SRC_OUT_ANALOG_IN - trigger events on the AnalogIn interface trigger the DigitalOut interface;\n
* SRC_OUT_DIGITAL_IN - trigger events on the DigitalIn interface trigger the DigitalOut interface;\n
* @note Only available from firmware v0.26.
*/
virtual void setAnalogOutSource(M2K_TRIGGER_OUT_SOURCE src) = 0;


/**
* @brief Retrieve the source of the AnalogOut interface trigger event.
* @return M2K_TRIGGER_OUT_SOURCE :\n
* SRC_OUT_NONE;\n
* SRC_OUT_TRIGGER_IN;\n
* SRC_OUT_TRIGGER_OUT;\n
* SRC_OUT_ANALOG_IN;\n
* SRC_OUT_DIGITAL_IN;\n
* @note Only available from firmware v0.26.
*/
virtual M2K_TRIGGER_OUT_SOURCE getAnalogOutSource() const = 0;


/**
* @brief Set the trigger condition for the TI/TO in order to trigger the AnalogOut interface
* @param cond the specific trigger condition
*
* @note to have any effect the digital out source must be set to TI or TO
*/
virtual void setAnalogOutCondition(M2K_TRIGGER_CONDITION_DIGITAL cond) = 0;


/**
* @brief Get the trigger condition of the TI/TO pins that triggers the AnalogOut interface
* @return the trigger condition
*/
virtual M2K_TRIGGER_CONDITION_DIGITAL getAnalogOutCondition() const = 0;
};
}

Expand Down
12 changes: 9 additions & 3 deletions src/m2k_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <digital/m2kdigital_impl.hpp>
#include "m2khardwaretrigger_impl.hpp"
#include "m2khardwaretrigger_v0.24_impl.hpp"
#include "m2khardwaretrigger_v0.26_impl.hpp"
#include "m2kcalibration_impl.hpp"
#include <libm2k/analog/dmm.hpp>
#include "utils/channel.hpp"
Expand Down Expand Up @@ -69,11 +70,16 @@ M2kImpl::M2kImpl(std::string uri, iio_context* ctx, std::string name, bool sync)

m_firmware_version = getFirmwareVersion();

int diff = Utils::compareVersions(m_firmware_version, "v0.24");
if (diff < 0) { //m_firmware_version < 0.24
int diff_v024 = Utils::compareVersions(m_firmware_version, "v0.24");
if (diff_v024 < 0) { //m_firmware_version < 0.24
m_trigger = new M2kHardwareTriggerImpl(ctx);
} else {
m_trigger = new M2kHardwareTriggerV024Impl(ctx);
int diff_v026 = Utils::compareVersions(m_firmware_version, "v0.26");
if (diff_v026 < 0) { // firmware version 0.24, 0.25
m_trigger = new M2kHardwareTriggerV024Impl(ctx);
} else { //firmware version >= 0.26
m_trigger = new M2kHardwareTriggerV026Impl(ctx);
}
}

if (!m_trigger) {
Expand Down
48 changes: 48 additions & 0 deletions src/m2khardwaretrigger_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,3 +570,51 @@ void M2kHardwareTriggerImpl::setCalibParameters(unsigned int chnIdx, double scal
m_scaling[chnIdx] = scaling;
m_offset[chnIdx] = offset;
}

void M2kHardwareTriggerImpl::setDigitalOutSource(M2K_TRIGGER_OUT_SOURCE src)
{
UNUSED(src);
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
}

M2K_TRIGGER_OUT_SOURCE M2kHardwareTriggerImpl::getDigitalOutSource() const
{
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
return SRC_OUT_NONE;
}

void M2kHardwareTriggerImpl::setDigitalOutCondition(M2K_TRIGGER_CONDITION_DIGITAL cond)
{
UNUSED(cond);
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
}

M2K_TRIGGER_CONDITION_DIGITAL M2kHardwareTriggerImpl::getDigitalOutCondition() const
{
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
return NO_TRIGGER_DIGITAL;
}

void M2kHardwareTriggerImpl::setAnalogOutSource(M2K_TRIGGER_OUT_SOURCE src)
{
UNUSED(src);
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
}

M2K_TRIGGER_OUT_SOURCE M2kHardwareTriggerImpl::getAnalogOutSource() const
{
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
return SRC_OUT_NONE;
}

void M2kHardwareTriggerImpl::setAnalogOutCondition(M2K_TRIGGER_CONDITION_DIGITAL cond)
{
UNUSED(cond);
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
}

M2K_TRIGGER_CONDITION_DIGITAL M2kHardwareTriggerImpl::getAnalogOutCondition() const
{
THROW_M2K_EXCEPTION("Invalid firmware version. Minimum required version: v0.26", libm2k::EXC_INVALID_FIRMWARE_VERSION);
return NO_TRIGGER_DIGITAL;
}
9 changes: 9 additions & 0 deletions src/m2khardwaretrigger_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ class M2kHardwareTriggerImpl : public M2kHardwareTrigger
M2K_TRIGGER_CONDITION_DIGITAL getDigitalCondition(DIO_CHANNEL chn);
void setDigitalCondition(DIO_CHANNEL chn, M2K_TRIGGER_CONDITION_DIGITAL cond);

void setDigitalOutSource(M2K_TRIGGER_OUT_SOURCE src) override;
M2K_TRIGGER_OUT_SOURCE getDigitalOutSource() const override;
void setDigitalOutCondition(M2K_TRIGGER_CONDITION_DIGITAL cond) override;
M2K_TRIGGER_CONDITION_DIGITAL getDigitalOutCondition() const override;
void setAnalogOutSource(M2K_TRIGGER_OUT_SOURCE src) override;
M2K_TRIGGER_OUT_SOURCE getAnalogOutSource() const override;
void setAnalogOutCondition(M2K_TRIGGER_CONDITION_DIGITAL cond) override;
M2K_TRIGGER_CONDITION_DIGITAL getAnalogOutCondition() const override;

protected:
struct iio_device *m_trigger_device;
std::vector<Channel *> m_analog_channels;
Expand Down
180 changes: 180 additions & 0 deletions src/m2khardwaretrigger_v0.26_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2020 Analog Devices Inc.
*
* This file is part of libm2k
* (see http://www.github.com/analogdevicesinc/libm2k).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#include "m2khardwaretrigger_v0.26_impl.hpp"
#include <libm2k/m2kexceptions.hpp>
#include <algorithm>


const std::string libm2k::M2kHardwareTriggerV026Impl::m_source_attr = "trigger_src";
const std::string libm2k::M2kHardwareTriggerV026Impl::m_condition_attr = "trigger_condition";


std::vector<std::string> libm2k::M2kHardwareTriggerV026Impl::m_trigger_source = {
"none",
"trigger-i_0",
"trigger-i_1",
"trigger-adc",
"trigger-la",
};

std::vector<std::string> libm2k::M2kHardwareTriggerV026Impl::m_trigger_cond = {
"edge-rising",
"edge-falling",
"level-low",
"level-high",
"edge-any",
"none"
};

libm2k::M2kHardwareTriggerV026Impl::M2kHardwareTriggerV026Impl(struct iio_context *ctx, bool init) :
M2kHardwareTriggerV024Impl(ctx)
{
bool hasTriggerSource;
bool hasTriggerCondition;
m_digital_trigger_device = make_shared<libm2k::utils::DeviceOut>(ctx, "m2k-logic-analyzer-tx");
// both dac a and dac b share the same trigger
m_analog_trigger_device = make_shared<libm2k::utils::DeviceOut>(ctx, "m2k-dac-a");
if (!m_digital_trigger_device) {
THROW_M2K_EXCEPTION("No digital TX trigger available", libm2k::EXC_RUNTIME_ERROR);
}
if (!m_analog_trigger_device) {
THROW_M2K_EXCEPTION("No analog TX trigger available", libm2k::EXC_RUNTIME_ERROR);
}

hasTriggerSource = m_digital_trigger_device->hasGlobalAttribute(m_source_attr);
hasTriggerCondition = m_digital_trigger_device->hasGlobalAttribute(m_condition_attr);
if (!hasTriggerSource || !hasTriggerCondition) {
THROW_M2K_EXCEPTION("Analog TX trigger is not available", libm2k::EXC_RUNTIME_ERROR);
}

hasTriggerSource = m_analog_trigger_device->hasGlobalAttribute(m_source_attr);
hasTriggerCondition = m_analog_trigger_device->hasGlobalAttribute(m_condition_attr);
if (!hasTriggerSource || !hasTriggerCondition) {
THROW_M2K_EXCEPTION("Analog TX trigger is not available", libm2k::EXC_RUNTIME_ERROR);
}

if (init) {
reset();
}
}

void libm2k::M2kHardwareTriggerV026Impl::reset() {
M2kHardwareTriggerV024Impl::reset();
setDigitalOutSource(SRC_OUT_NONE);
setDigitalOutCondition(NO_TRIGGER_DIGITAL);
setAnalogOutSource(SRC_OUT_NONE);
setAnalogOutCondition(NO_TRIGGER_DIGITAL);
}

void libm2k::M2kHardwareTriggerV026Impl::setDigitalOutSource(libm2k::M2K_TRIGGER_OUT_SOURCE src)
{
setTriggerOutSource(src, m_digital_trigger_device);
}

libm2k::M2K_TRIGGER_OUT_SOURCE libm2k::M2kHardwareTriggerV026Impl::getDigitalOutSource() const
{
return getTriggerOutSource(m_digital_trigger_device);
}

void libm2k::M2kHardwareTriggerV026Impl::setDigitalOutCondition(libm2k::M2K_TRIGGER_CONDITION_DIGITAL cond)
{
setTriggerOutCondition(cond, m_digital_trigger_device);
}

libm2k::M2K_TRIGGER_CONDITION_DIGITAL libm2k::M2kHardwareTriggerV026Impl::getDigitalOutCondition() const
{
return getTriggerOutCondition(m_digital_trigger_device);
}

void libm2k::M2kHardwareTriggerV026Impl::setAnalogOutSource(libm2k::M2K_TRIGGER_OUT_SOURCE src)
{
setTriggerOutSource(src, m_analog_trigger_device);
}

libm2k::M2K_TRIGGER_OUT_SOURCE libm2k::M2kHardwareTriggerV026Impl::getAnalogOutSource() const
{
return getTriggerOutSource(m_analog_trigger_device);
}

void libm2k::M2kHardwareTriggerV026Impl::setAnalogOutCondition(libm2k::M2K_TRIGGER_CONDITION_DIGITAL cond)
{
setTriggerOutCondition(cond, m_analog_trigger_device);
}

libm2k::M2K_TRIGGER_CONDITION_DIGITAL libm2k::M2kHardwareTriggerV026Impl::getAnalogOutCondition() const
{
return getTriggerOutCondition(m_analog_trigger_device);
}

void libm2k::M2kHardwareTriggerV026Impl::setTriggerOutSource(libm2k::M2K_TRIGGER_OUT_SOURCE src,
const std::shared_ptr<libm2k::utils::DeviceOut>& device)
{
if (src >= m_trigger_source.size()) {
THROW_M2K_EXCEPTION("M2kHardwareTrigger: "
"the provided source is not supported on "
"the current board; Check the firmware version.",
libm2k::EXC_INVALID_PARAMETER);
}
std::string src_str = m_trigger_source[src];
device->setStringValue(m_source_attr, src_str);
}

libm2k::M2K_TRIGGER_OUT_SOURCE
libm2k::M2kHardwareTriggerV026Impl::getTriggerOutSource(const std::shared_ptr<libm2k::utils::DeviceOut>& device) const
{
std::string buf = device->getStringValue(m_source_attr);

auto it = std::find(m_trigger_source.begin(),
m_trigger_source.end(), buf.c_str());
if (it == m_trigger_source.end()) {
THROW_M2K_EXCEPTION("Unexpected value read from attribute: " + m_source_attr, libm2k::EXC_INVALID_PARAMETER);
}

return static_cast<libm2k::M2K_TRIGGER_OUT_SOURCE>(it - m_trigger_source.begin());
}

void libm2k::M2kHardwareTriggerV026Impl::setTriggerOutCondition(
libm2k::M2K_TRIGGER_CONDITION_DIGITAL cond, const std::shared_ptr<libm2k::utils::DeviceOut>& device)
{
if (cond >= m_trigger_cond.size()) {
THROW_M2K_EXCEPTION("M2kHardwareTrigger: "
"the provided condition is not supported on "
"the current board; Check the firmware version.",
libm2k::EXC_INVALID_PARAMETER);
}
std::string src_str = m_trigger_cond[cond];
device->setStringValue(m_condition_attr, src_str);
}

libm2k::M2K_TRIGGER_CONDITION_DIGITAL
libm2k::M2kHardwareTriggerV026Impl::getTriggerOutCondition(const std::shared_ptr<libm2k::utils::DeviceOut>& device) const
{
std::string buf = device->getStringValue(m_condition_attr);

auto it = std::find(m_trigger_cond.begin(),
m_trigger_cond.end(), buf.c_str());
if (it == m_trigger_cond.end()) {
THROW_M2K_EXCEPTION("Unexpected value read from attribute: " + m_condition_attr, libm2k::EXC_INVALID_PARAMETER);
}

return static_cast<libm2k::M2K_TRIGGER_CONDITION_DIGITAL>(it - m_trigger_cond.begin());
}
Loading