From 1a4348038d0eb57d53475074dca49e8192aeb2d7 Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@ettus.com>
Date: Wed, 8 Mar 2017 09:28:55 -0800
Subject: Initial commit for N3xx development.

- Creates mpm/ subdirectory
- First pass at hardware daemon/MPM
- New code for LMK04828, AD9371
- spidev integration

Contributions by:

Martin Braun <martin.braun@ettus.com>
Derek Kozel <derek.kozel@ettus.com>
Mark Meserve <mark.meserve@ni.com>
Andrej Rode <andrej.rode@ettus.com>
---
 mpm/lib/CMakeLists.txt                             |    28 +
 mpm/lib/lmk04828/CMakeLists.txt                    |    47 +
 mpm/lib/lmk04828/lmk04828_spi_iface.cpp            |    43 +
 mpm/lib/mykonos/CMakeLists.txt                     |    38 +
 mpm/lib/mykonos/ad937x_ctrl.cpp                    |   565 +
 mpm/lib/mykonos/ad937x_ctrl.hpp                    |    68 +
 mpm/lib/mykonos/ad937x_device.cpp                  |   334 +
 mpm/lib/mykonos/ad937x_device.hpp                  |    92 +
 mpm/lib/mykonos/adi/CMakeLists.txt                 |     6 +
 mpm/lib/mykonos/adi/common.h                       |   115 +
 mpm/lib/mykonos/adi/mykonos.c                      | 16678 +++++++++++++++++++
 mpm/lib/mykonos/adi/mykonos.h                      |   242 +
 mpm/lib/mykonos/adi/mykonosMmap.c                  |   129 +
 .../mykonos/adi/mykonos_debug/mykonos_dbgjesd.c    |  1333 ++
 .../mykonos/adi/mykonos_debug/mykonos_dbgjesd.h    |    67 +
 .../mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h  |   160 +
 mpm/lib/mykonos/adi/mykonos_gpio.c                 |  5420 ++++++
 mpm/lib/mykonos/adi/mykonos_gpio.h                 |   166 +
 mpm/lib/mykonos/adi/mykonos_macros.h               |   692 +
 mpm/lib/mykonos/adi/mykonos_user.c                 |   170 +
 mpm/lib/mykonos/adi/mykonos_user.h                 |    78 +
 mpm/lib/mykonos/adi/mykonos_version.h              |    24 +
 mpm/lib/mykonos/adi/t_mykonos.h                    |  1471 ++
 mpm/lib/mykonos/adi/t_mykonos_gpio.h               |   366 +
 mpm/lib/mykonos/adi_ctrl.cpp                       |   215 +
 mpm/lib/mykonos/adi_sample/CMakeLists.txt          |     4 +
 mpm/lib/mykonos/adi_sample/headless.c              |   528 +
 mpm/lib/mykonos/adi_sample/headless.cpp            |   312 +
 mpm/lib/mykonos/adi_sample/headless.h              |    10 +
 mpm/lib/mykonos/adi_sample/mykonos_static_config.c |   516 +
 mpm/lib/mykonos/adi_sample/mykonos_static_config.h |    18 +
 mpm/lib/mykonos/config/CMakeLists.txt              |     4 +
 mpm/lib/mykonos/config/ad937x_config_t.cpp         |   110 +
 mpm/lib/mykonos/config/ad937x_config_t.hpp         |    64 +
 mpm/lib/mykonos/config/ad937x_fir.cpp              |    37 +
 mpm/lib/mykonos/config/ad937x_fir.h                |    22 +
 mpm/lib/mykonos/config/mykonos_default_config.h    |   359 +
 mpm/lib/print_foo.cpp                              |     8 +
 mpm/lib/spi/CMakeLists.txt                         |     8 +
 mpm/lib/spi/mock_spi.cpp                           |   117 +
 mpm/lib/spi/mock_spi.h                             |    10 +
 mpm/lib/spi/spi_config.cpp                         |    37 +
 mpm/lib/spi/spi_config.h                           |    44 +
 mpm/lib/spi/spi_lock.cpp                           |    26 +
 mpm/lib/spi/spi_lock.h                             |    25 +
 mpm/lib/spi/spidev_iface.cpp                       |   155 +
 46 files changed, 30961 insertions(+)
 create mode 100644 mpm/lib/CMakeLists.txt
 create mode 100644 mpm/lib/lmk04828/CMakeLists.txt
 create mode 100644 mpm/lib/lmk04828/lmk04828_spi_iface.cpp
 create mode 100644 mpm/lib/mykonos/CMakeLists.txt
 create mode 100644 mpm/lib/mykonos/ad937x_ctrl.cpp
 create mode 100644 mpm/lib/mykonos/ad937x_ctrl.hpp
 create mode 100644 mpm/lib/mykonos/ad937x_device.cpp
 create mode 100644 mpm/lib/mykonos/ad937x_device.hpp
 create mode 100644 mpm/lib/mykonos/adi/CMakeLists.txt
 create mode 100644 mpm/lib/mykonos/adi/common.h
 create mode 100644 mpm/lib/mykonos/adi/mykonos.c
 create mode 100644 mpm/lib/mykonos/adi/mykonos.h
 create mode 100644 mpm/lib/mykonos/adi/mykonosMmap.c
 create mode 100644 mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.c
 create mode 100644 mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h
 create mode 100644 mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h
 create mode 100644 mpm/lib/mykonos/adi/mykonos_gpio.c
 create mode 100644 mpm/lib/mykonos/adi/mykonos_gpio.h
 create mode 100644 mpm/lib/mykonos/adi/mykonos_macros.h
 create mode 100644 mpm/lib/mykonos/adi/mykonos_user.c
 create mode 100644 mpm/lib/mykonos/adi/mykonos_user.h
 create mode 100644 mpm/lib/mykonos/adi/mykonos_version.h
 create mode 100644 mpm/lib/mykonos/adi/t_mykonos.h
 create mode 100644 mpm/lib/mykonos/adi/t_mykonos_gpio.h
 create mode 100644 mpm/lib/mykonos/adi_ctrl.cpp
 create mode 100644 mpm/lib/mykonos/adi_sample/CMakeLists.txt
 create mode 100644 mpm/lib/mykonos/adi_sample/headless.c
 create mode 100644 mpm/lib/mykonos/adi_sample/headless.cpp
 create mode 100644 mpm/lib/mykonos/adi_sample/headless.h
 create mode 100644 mpm/lib/mykonos/adi_sample/mykonos_static_config.c
 create mode 100644 mpm/lib/mykonos/adi_sample/mykonos_static_config.h
 create mode 100644 mpm/lib/mykonos/config/CMakeLists.txt
 create mode 100644 mpm/lib/mykonos/config/ad937x_config_t.cpp
 create mode 100644 mpm/lib/mykonos/config/ad937x_config_t.hpp
 create mode 100644 mpm/lib/mykonos/config/ad937x_fir.cpp
 create mode 100644 mpm/lib/mykonos/config/ad937x_fir.h
 create mode 100644 mpm/lib/mykonos/config/mykonos_default_config.h
 create mode 100644 mpm/lib/print_foo.cpp
 create mode 100644 mpm/lib/spi/CMakeLists.txt
 create mode 100644 mpm/lib/spi/mock_spi.cpp
 create mode 100644 mpm/lib/spi/mock_spi.h
 create mode 100644 mpm/lib/spi/spi_config.cpp
 create mode 100644 mpm/lib/spi/spi_config.h
 create mode 100644 mpm/lib/spi/spi_lock.cpp
 create mode 100644 mpm/lib/spi/spi_lock.h
 create mode 100644 mpm/lib/spi/spidev_iface.cpp

(limited to 'mpm/lib')

diff --git a/mpm/lib/CMakeLists.txt b/mpm/lib/CMakeLists.txt
new file mode 100644
index 000000000..19dbf6dce
--- /dev/null
+++ b/mpm/lib/CMakeLists.txt
@@ -0,0 +1,28 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+
+ADD_SUBDIRECTORY(spi)
+ADD_SUBDIRECTORY(mykonos)
+ADD_SUBDIRECTORY(lmk04828)
+
+USRP_PERIPHS_ADD_OBJECT(periphs
+  print_foo.cpp)
diff --git a/mpm/lib/lmk04828/CMakeLists.txt b/mpm/lib/lmk04828/CMakeLists.txt
new file mode 100644
index 000000000..4235cb34a
--- /dev/null
+++ b/mpm/lib/lmk04828/CMakeLists.txt
@@ -0,0 +1,47 @@
+MACRO(ETTUS_PYTHON_GEN_SOURCE pyfile outfile)
+    #ensure that the directory exists for outfile
+    GET_FILENAME_COMPONENT(outfile_dir ${outfile} PATH)
+    FILE(MAKE_DIRECTORY ${outfile_dir})
+
+    #make the outfile depend on the python script
+    ADD_CUSTOM_COMMAND(
+        OUTPUT ${outfile} DEPENDS ${pyfile} ${ETTUS_PYTHON_GEN_SOURCE_DEPS}
+        COMMAND ${PYTHON_EXECUTABLE} -B ${pyfile} ${outfile}
+        COMMENT "Generating ${outfile}"
+    )
+
+    #make lmk04828 depend on the outfile
+    LIST(APPEND lmk04828_srcs ${ARGV})
+ENDMACRO(ETTUS_PYTHON_GEN_SOURCE)
+
+####################################################
+# LMK04828
+####################################################
+
+# Register definitions need to be generated
+SET(UHD_HOST_ROOT ${CMAKE_SOURCE_DIR}/../host)
+MESSAGE("uhd host root: ${UHD_HOST_ROOT}")
+SET(UHD_IC_REG_MAP_PATH ${UHD_HOST_ROOT}/lib/ic_reg_maps)
+
+SET(ETTUS_PYTHON_GEN_SOURCE_DEPS ${UHD_IC_REG_MAP_PATH}/common.py)
+ETTUS_PYTHON_GEN_SOURCE(
+    ${UHD_IC_REG_MAP_PATH}/gen_lmk04828_regs.py
+    ${CMAKE_CURRENT_BINARY_DIR}/lmk04828_regs.hpp
+)
+SET(LIBUHD_PYTHON_GEN_SOURCE_DEPS)
+
+
+# LMK04828 driver files
+LIST(APPEND lmk04828_srcs
+    ${UHD_HOST_ROOT}/lib/usrp/common/lmk04828.cpp
+    ${UHD_HOST_ROOT}/lib/types/serial.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/lmk04828_spi_iface.cpp
+    )
+
+# Extra files needed
+LIST(APPEND lmk04828_srcs ${UHD_HOST_ROOT}/lib/exception.cpp)
+
+# For include/uhd/exception.hpp and include/uhd/config.h
+
+USRP_PERIPHS_ADD_OBJECT(lmk04828 ${lmk04828_srcs})
+TARGET_INCLUDE_DIRECTORIES(lmk04828 PUBLIC ${UHD_HOST_ROOT}/include ${CMAKE_CURRENT_BINARY_DIR} ${UHD_HOST_ROOT}/lib/usrp/common)
diff --git a/mpm/lib/lmk04828/lmk04828_spi_iface.cpp b/mpm/lib/lmk04828/lmk04828_spi_iface.cpp
new file mode 100644
index 000000000..e281467e1
--- /dev/null
+++ b/mpm/lib/lmk04828/lmk04828_spi_iface.cpp
@@ -0,0 +1,43 @@
+#include "lmk/lmk04828_spi_iface.hpp"
+#include "uhd/exception.hpp"
+#include <boost/bind.hpp>
+
+lmk04828_spi_iface::lmk04828_spi_iface(uhd::spi_iface::sptr iface) : _spi_iface(iface)
+    {
+        // Use default SPI Config options
+        config = uhd::spi_config_t(uhd::spi_config_t::EDGE_RISE);
+    }
+
+lmk04828_iface::write_fn_t lmk04828_spi_iface::get_write_fn()
+    {
+        return boost::bind(&lmk04828_spi_iface::spi_write, this, _1);
+    }
+
+lmk04828_iface::read_fn_t lmk04828_spi_iface::get_read_fn()
+    {
+        return boost::bind(&lmk04828_spi_iface::spi_read, this, _1);
+    }
+
+void lmk04828_spi_iface::spi_write(std::vector<uint32_t> writes) {
+        for (uint32_t write : writes) {
+            _spi_iface->write_spi(DEFAULT_SLAVE, config, write, LMK_SPI_NUM_BITS);
+        }
+    }
+
+uint8_t lmk04828_spi_iface::spi_read(uint32_t addr) {
+        // Format LMK SPI read transaction
+        // r/w[23] 0[22:21] addr[20:8] data[7:0] = 24 bits
+        uint32_t transaction = 0;
+        transaction |= LMK_SPI_READ_FLAG << LMK_SPI_READ_FLAG_OFFSET;
+        transaction &= LMK_SPI_RESERVED_FIELD_MASK;
+        transaction |= addr << LMK_SPI_READ_ADDR_OFFSET;
+
+        uint32_t data = _spi_iface->read_spi(DEFAULT_SLAVE, config, transaction, LMK_SPI_NUM_BITS);
+
+        if ((data & 0xFFFFFF00) != 0) {
+            // There's more than 8 bits of data!
+            throw uhd::runtime_error("LMK SPI read returned too much data");
+        }
+
+        return data & 0xFF;
+    }
diff --git a/mpm/lib/mykonos/CMakeLists.txt b/mpm/lib/mykonos/CMakeLists.txt
new file mode 100644
index 000000000..03b3ef102
--- /dev/null
+++ b/mpm/lib/mykonos/CMakeLists.txt
@@ -0,0 +1,38 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+MACRO(MYKONOS_APPEND_SOURCES)
+    SET(mykonos_sources ${mykonos_sources})
+    LIST(APPEND mykonos_sources ${ARGV})
+    SET(mykonos_sources ${mykonos_sources} PARENT_SCOPE)
+ENDMACRO(MYKONOS_APPEND_SOURCES)
+
+SET(mykonos_sources
+    ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_ctrl.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_device.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/adi_ctrl.cpp
+)
+
+ADD_SUBDIRECTORY(adi)
+ADD_SUBDIRECTORY(adi_sample)
+ADD_SUBDIRECTORY(config)
+
+USRP_PERIPHS_ADD_OBJECT(mykonos ${mykonos_sources})
diff --git a/mpm/lib/mykonos/ad937x_ctrl.cpp b/mpm/lib/mykonos/ad937x_ctrl.cpp
new file mode 100644
index 000000000..b4ff38139
--- /dev/null
+++ b/mpm/lib/mykonos/ad937x_ctrl.cpp
@@ -0,0 +1,565 @@
+#include "adi/mykonos.h"
+
+#include "ad937x_ctrl.hpp"
+#include "ad937x_device.hpp"
+#include <sstream>
+#include <functional>
+#include <iostream>
+#include <cmath>
+
+uhd::meta_range_t ad937x_ctrl::get_rf_freq_range(void)
+{
+    return uhd::meta_range_t(300e6, 6e9);
+}
+
+uhd::meta_range_t ad937x_ctrl::get_bw_filter_range(void) 
+{
+    // TODO: fix
+    return uhd::meta_range_t(0, 1);
+}
+
+std::vector<double> ad937x_ctrl::get_clock_rates(void)
+{
+    // TODO: fix
+    return { 125e6 };
+}
+
+uhd::meta_range_t ad937x_ctrl::get_gain_range(const std::string &which)
+{
+    auto dir = _get_direction_from_antenna(which);
+    switch (dir)
+    {
+    case uhd::direction_t::RX_DIRECTION:
+        return uhd::meta_range_t(0, 30, 0.5);
+    case uhd::direction_t::TX_DIRECTION:
+        return uhd::meta_range_t(0, 41.95, 0.05);
+    default:
+        throw uhd::runtime_error("ad937x_ctrl got an invalid channel string.");
+        return uhd::meta_range_t();
+    }
+}
+
+std::vector<size_t> ad937x_ctrl::_get_valid_fir_lengths(const std::string& which)
+{
+    auto dir = _get_direction_from_antenna(which);
+    switch (dir)
+    {
+    case uhd::direction_t::RX_DIRECTION:
+        return { 24, 48, 72 };
+    case uhd::direction_t::TX_DIRECTION:
+        return { 16, 32, 48, 64, 80, 96 };
+    default:
+        throw uhd::runtime_error("ad937x_ctrl got an invalid channel string.");
+        return std::vector<size_t>();
+    }
+}
+
+uhd::direction_t ad937x_ctrl::_get_direction_from_antenna(const std::string& antenna)
+{
+    auto sub = antenna.substr(0, 2);
+    if (sub == "RX") {
+        return uhd::direction_t::RX_DIRECTION;
+    }
+    else if (sub == "TX") {
+        return uhd::direction_t::TX_DIRECTION;
+    }
+    else {
+        throw uhd::runtime_error("ad937x_ctrl got an invalid channel string.");
+    }
+    return uhd::direction_t::RX_DIRECTION;
+}
+
+ad937x_device::chain_t ad937x_ctrl::_get_chain_from_antenna(const std::string& antenna)
+{
+    auto sub = antenna.substr(2, 1);
+    if (sub == "1") {
+        return ad937x_device::chain_t::ONE;
+    }
+    else if (sub == "2") {
+        return ad937x_device::chain_t::TWO;
+    }
+    else {
+        throw uhd::runtime_error("ad937x_ctrl got an invalid channel string.");
+    }
+    return ad937x_device::chain_t::ONE;
+}
+
+class ad937x_ctrl_impl : public ad937x_ctrl
+{
+public:
+    // change to uhd::spi_iface
+    static sptr make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface);
+
+    ad937x_ctrl_impl(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface) :
+        spi_l(spi_l),
+        iface(iface)
+    {
+
+    }
+
+    virtual uint8_t get_product_id()
+    {
+        std::lock_guard<spi_lock>(*spi_l);
+        return device.get_product_id();
+    }
+
+    virtual uint8_t get_device_rev()
+    {
+        std::lock_guard<spi_lock>(*spi_l);
+        return device.get_device_rev();
+    }
+    virtual std::string get_api_version()
+    {
+        std::lock_guard<spi_lock>(*spi_l);
+        auto api = device.get_api_version();
+        std::ostringstream ss;
+        ss  << api.silicon_ver << "."
+            << api.major_ver << "."
+            << api.minor_ver << "."
+            << api.build_ver;
+        return ss.str();
+    }
+
+    virtual std::string get_arm_version()
+    {
+        std::lock_guard<spi_lock>(*spi_l);
+        auto arm = device.get_arm_version();
+        std::ostringstream ss;
+        ss  << arm.major_ver << "."
+            << arm.minor_ver << "."
+            << arm.rc_ver;
+        return ss.str();
+    }
+
+    virtual double set_bw_filter(const std::string &which, const double value)
+    {
+        // TODO implement
+        return double();
+    }
+
+    virtual double set_gain(const std::string &which, const double value)
+    {
+        auto dir = _get_direction_from_antenna(which);
+        auto chain = _get_chain_from_antenna(which);
+        return device.set_gain(dir, chain, value);
+    }
+
+    virtual void set_agc(const std::string &which, const bool enable)
+    {
+        auto dir = _get_direction_from_antenna(which);
+        if (dir != uhd::direction_t::RX_DIRECTION)
+        {
+            throw uhd::runtime_error("ad937x_ctrl::set_agc was called on a non-RX channel");
+        }
+        return device.set_agc(dir, enable);
+    }
+
+    virtual void set_agc_mode(const std::string &which, const std::string &mode)
+    {
+        auto dir = _get_direction_from_antenna(which);
+        if (dir != uhd::direction_t::RX_DIRECTION)
+        {
+            throw uhd::runtime_error("ad937x_ctrl::set_agc was called on a non-RX channel");
+        }
+
+        ad937x_device::gain_mode_t gain_mode;
+        if (mode == "automatic")
+        {
+            gain_mode = ad937x_device::gain_mode_t::AUTOMATIC;
+        }
+        else if (mode == "manual") {
+            gain_mode = ad937x_device::gain_mode_t::MANUAL;
+        }
+        else if (mode == "hybrid") {
+            gain_mode = ad937x_device::gain_mode_t::HYBRID;
+        }
+        else {
+            throw uhd::runtime_error("ad937x_ctrl::set_agc_mode was called on a non-RX channel");
+        }
+
+        device.set_agc_mode(dir, gain_mode);
+    }
+
+    virtual double set_clock_rate(const double value)
+    {
+        auto rates = get_clock_rates();
+        auto coerced_value = value;
+        if (std::find(rates.begin(), rates.end(), value) == rates.end())
+        {
+            coerced_value = rates[0];
+        }
+
+        return device.set_clock_rate(coerced_value);
+    }
+
+    virtual void enable_channel(const std::string &which, const bool enable)
+    {
+        auto dir = _get_direction_from_antenna(which);
+        auto chain = _get_chain_from_antenna(which);
+        return device.enable_channel(dir, chain, enable);
+    }
+
+    virtual double set_freq(const std::string &which, const double value)
+    {
+        auto dir = _get_direction_from_antenna(which);
+        auto clipped_value = get_rf_freq_range().clip(value);
+        return device.tune(dir, clipped_value);
+    }
+
+    virtual double get_freq(const std::string &which)
+    {
+        auto dir = _get_direction_from_antenna(which);
+        return device.get_freq(dir);
+    }
+
+    virtual void set_fir(const std::string &which, int8_t gain, const std::vector<int16_t> & fir)
+    {
+        auto lengths = _get_valid_fir_lengths(which);
+        if (std::find(lengths.begin(), lengths.end(), fir.size()) == lengths.end())
+        {
+            throw uhd::value_error("ad937x_ctrl::set_fir got filter of invalid length");
+        }
+
+        ad937x_fir(gain, fir);
+
+    }
+    virtual std::vector<int16_t> get_fir(const std::string &which) = 0;
+
+    virtual int16_t get_temperature() = 0;
+    
+private:
+    ad937x_device device;
+    spi_lock::sptr spi_l;
+    mpm::spi_iface::sptr iface;
+};
+
+const double ad937x_ctrl_impl::MIN_FREQ = 300e6;
+const double ad937x_ctrl_impl::MAX_FREQ = 6e9;
+
+/*
+ad937x_ctrl::sptr ad937x_ctrl_impl::make(
+    spi_lock::sptr spi_l,
+    mpm::spi_iface::sptr iface)
+{
+    return std::make_shared<ad937x_ctrl_impl>(spi_l, iface);
+}
+
+
+void ad937x_ctrl::initialize()
+{
+    //headlessinit(mykonos_config.device);
+    // TODO: finish initialization
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_initialize, mykonos_config.device));
+    }    
+    get_product_id();
+}
+
+ad937x_ctrl::ad937x_ctrl(
+    spi_lock::sptr spi_l, 
+    mpm::spi_iface::sptr iface) :
+    spi_l(spi_l),
+    iface(iface)
+{
+    mpm_sps.spi_iface = iface.get();
+
+    //TODO assert iface->get_chip_select() is 1-8
+    mpm_sps.spi_settings.chipSelectIndex = static_cast<uint8_t>(iface->get_chip_select());
+    mpm_sps.spi_settings.writeBitPolarity = 1;
+    mpm_sps.spi_settings.longInstructionWord = 1; // set to 1 by initialize
+    mpm_sps.spi_settings.MSBFirst = 
+        (iface->get_endianness() == mpm::spi_iface::spi_endianness_t::LSB_FIRST) ? 0 : 1;
+    mpm_sps.spi_settings.CPHA = 0; // set to 0 by initialize
+    mpm_sps.spi_settings.CPOL = 0; // set to 0 by initialize
+    mpm_sps.spi_settings.enSpiStreaming = 1;
+    mpm_sps.spi_settings.autoIncAddrUp = 1;
+    mpm_sps.spi_settings.fourWireMode = 
+        (iface->get_wire_mode() == mpm::spi_iface::spi_wire_mode_t::THREE_WIRE_MODE) ? 0 : 1;
+    mpm_sps.spi_settings.spiClkFreq_Hz = 25000000; 
+
+    initialize();
+}
+
+// helper function to unify error handling
+// bind is bad, but maybe this is justifiable
+void ad937x_ctrl::call_api_function(std::function<mykonosErr_t()> func)
+{
+    auto error = func();
+    if (error != MYKONOS_ERR_OK)
+    {
+        std::cout << getMykonosErrorMessage(error);
+        // TODO: make UHD exception
+        //throw std::exception(getMykonosErrorMessage(error));
+    }
+}
+
+uint8_t ad937x_ctrl::get_product_id()
+{
+    std::lock_guard<spi_lock> lock(*spi_l);
+    uint8_t id;
+    call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id));
+    return id;
+}
+
+double ad937x_ctrl::set_clock_rate(const double req_rate)
+{
+    auto rate = static_cast<decltype(mykonos_config.device->clocks->deviceClock_kHz)>(req_rate / 1000);
+    mykonos_config.device->clocks->deviceClock_kHz = rate;
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_initDigitalClocks, mykonos_config.device));
+    }
+    return static_cast<decltype(set_clock_rate(0))>(rate);
+}
+
+void ad937x_ctrl::_set_active_tx_chains(bool tx1, bool tx2)
+{
+    decltype(mykonos_config.device->tx->txChannels) newTxChannel;
+    if (tx1 && tx2)
+    {
+        newTxChannel = TX1_TX2;
+    }
+    else if (tx1) {
+        newTxChannel = TX1;
+    }
+    else if (tx2) {
+        newTxChannel = TX2;
+    }
+    else {
+        newTxChannel = TXOFF;
+    }
+    mykonos_config.device->tx->txChannels = newTxChannel;
+}
+
+void ad937x_ctrl::_set_active_rx_chains(bool rx1, bool rx2)
+{
+    decltype(mykonos_config.device->rx->rxChannels) newRxChannel;
+    if (rx1 && rx2)
+    {
+        newRxChannel = RX1_RX2;
+    }
+    else if (rx1) {
+        newRxChannel = RX1;
+    }
+    else if (rx2) {
+        newRxChannel = RX2;
+    }
+    else {
+        newRxChannel = RXOFF;
+    }
+    mykonos_config.device->rx->rxChannels = newRxChannel;
+}
+
+void ad937x_ctrl::set_active_chains(direction_t direction, bool channel1, bool channel2)
+{
+    switch (direction)
+    {
+    case TX: _set_active_tx_chains(channel1, channel2); break;
+    case RX: _set_active_rx_chains(channel1, channel2); break;
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+    // TODO: make this apply the setting
+}
+
+double ad937x_ctrl::tune(direction_t direction, const double value)
+{
+    // I'm not really sure why we set the PLL value in the config AND as a function parameter
+    // but here it is
+
+    mykonosRfPllName_t pll;
+    uint64_t integer_value = static_cast<uint64_t>(value);
+    switch (direction)
+    {
+    case TX:
+        pll = TX_PLL;
+        mykonos_config.device->tx->txPllLoFrequency_Hz = integer_value;
+        break;
+    case RX:
+        pll = RX_PLL;
+        mykonos_config.device->rx->rxPllLoFrequency_Hz = integer_value;
+        break;
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_setRfPllFrequency, mykonos_config.device, pll, integer_value));
+    }
+
+    // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide
+    // Furthermore, because coerced is returned as an integer, it's not even accurate
+    uint64_t coerced_pll;
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll));
+    }
+    return static_cast<double>(coerced_pll);
+}
+
+double ad937x_ctrl::get_freq(direction_t direction)
+{
+    mykonosRfPllName_t pll;
+    switch (direction)
+    {
+    case TX: pll = TX_PLL; break;
+    case RX: pll = RX_PLL; break;
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+
+    // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide
+    // Furthermore, because coerced is returned as an integer, it's not even accurate
+    uint64_t coerced_pll;
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll));
+    }
+    return static_cast<double>(coerced_pll);
+    return double();
+}
+
+// RX Gain values are table entries given in mykonos_user.h
+// An array of gain values is programmed at initialization, which the API will then use for its gain values
+// In general, Gain Value = (255 - Gain Table Index)
+uint8_t ad937x_ctrl::_convert_rx_gain(double inGain, double &coercedGain)
+{
+    // TODO: use uhd::meta_range?
+    const static double min_gain = 0;
+    const static double max_gain = 30;
+    const static double gain_step = 0.5;
+
+    coercedGain = inGain;
+    if (coercedGain < min_gain)
+    {
+        coercedGain = min_gain;
+    }
+    if (coercedGain > max_gain)
+    {
+        coercedGain = max_gain;
+    }
+
+    // round to nearest step
+    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step);
+
+    // gain should be a value 0-60, add 195 to make 195-255
+    return static_cast<uint8_t>((coercedGain * 2) + 195);
+}
+
+// TX gain is completely different from RX gain for no good reason so deal with it
+// TX is set as attenuation using a value from 0-41950 mdB
+// Only increments of 50 mdB are valid
+uint16_t ad937x_ctrl::_convert_tx_gain(double inGain, double &coercedGain)
+{
+    // TODO: use uhd::meta_range?
+    const static double min_gain = 0;
+    const static double max_gain = 41.95;
+    const static double gain_step = 0.05;
+
+    coercedGain = inGain;
+    if (coercedGain < min_gain)
+    {
+        coercedGain = min_gain;
+    }
+    if (coercedGain > max_gain)
+    {
+        coercedGain = max_gain;
+    }
+
+    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step);
+
+    // attenuation is inverted and in mdB not dB
+    return static_cast<uint16_t>((max_gain - (coercedGain)) * 1000);
+}
+
+
+double ad937x_ctrl::set_gain(direction_t direction, chain_t chain, const double value)
+{
+    double coerced_value;
+    switch (direction)
+    {
+    case TX:
+    {
+        uint16_t attenuation = _convert_tx_gain(value, coerced_value);
+        std::function<mykonosErr_t(mykonosDevice_t*, uint16_t)> func;
+        switch (chain)
+        {
+        case CHAIN_1:
+            func = MYKONOS_setTx1Attenuation;
+            break;
+        case CHAIN_2:
+            func = MYKONOS_setTx2Attenuation;
+            break;
+        default:
+            // TODO: bad code path exception
+            throw std::exception();
+        }
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(func, mykonos_config.device, attenuation));
+        break;
+    }
+    case RX:
+    {
+        uint8_t gain = _convert_rx_gain(value, coerced_value);
+        std::function<mykonosErr_t(mykonosDevice_t*, uint8_t)> func;
+        switch (chain)
+        {
+        case CHAIN_1:
+            func = MYKONOS_setRx1ManualGain;
+            break;
+        case CHAIN_2:
+            func = MYKONOS_setRx2ManualGain;
+            break;
+        default:
+            // TODO: bad code path exception
+            throw std::exception();
+        }
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(func, mykonos_config.device, gain));
+        break;
+    }
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+    return coerced_value;
+}
+
+double ad937x_ctrl::set_agc_mode(direction_t direction, chain_t chain, gain_mode_t mode)
+{
+    std::lock_guard<spi_lock> lock(*spi_l);
+    switch (direction)
+    {
+    case RX:
+        switch (mode)
+        {
+        case GAIN_MODE_MANUAL:
+            call_api_function(std::bind(MYKONOS_resetRxAgc, mykonos_config.device));
+            break;
+        case GAIN_MODE_SLOW_AGC:
+        case GAIN_MODE_FAST_AGC:
+            // TODO: differentiate these
+            call_api_function(std::bind(MYKONOS_setupRxAgc, mykonos_config.device));
+            break;
+        default:
+            // TODO: bad code path exception
+            throw std::exception();
+        }
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+    return double();
+}
+
+ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface)
+{
+    return std::make_shared<ad937x_ctrl>(spi_l, iface);
+}
+*/
+
diff --git a/mpm/lib/mykonos/ad937x_ctrl.hpp b/mpm/lib/mykonos/ad937x_ctrl.hpp
new file mode 100644
index 000000000..6d36bdf05
--- /dev/null
+++ b/mpm/lib/mykonos/ad937x_ctrl.hpp
@@ -0,0 +1,68 @@
+#pragma once
+
+// TODO: fix path of UHD includes
+#include <../../host/include/uhd/types/direction.hpp>
+#include <../../host/include/uhd/types/ranges.hpp>
+#include <../../host/include/uhd/exception.hpp>
+
+#include "config/ad937x_fir.h"
+#include "adi/t_mykonos.h"
+#include "../spi/spi_lock.h"
+#include "../spi/spi_config.h"
+#include <mpm/spi_iface.hpp>
+#include <mpm/spi/adi_ctrl.hpp>
+#include <boost/noncopyable.hpp>
+#include <functional>
+
+struct ad937x_api_version_t {
+    uint32_t silicon_ver;
+    uint32_t major_ver;
+    uint32_t minor_ver;
+    uint32_t build_ver;
+};
+
+struct ad937x_arm_version_t {
+    uint32_t major_ver;
+    uint32_t minor_ver;
+    uint32_t rc_ver;
+};
+
+class ad937x_ctrl : public boost::noncopyable
+{
+public:
+    typedef std::shared_ptr<ad937x_ctrl> sptr;
+    virtual ~ad937x_ctrl(void) {};
+
+    static uhd::meta_range_t get_rf_freq_range(void);
+    static uhd::meta_range_t get_bw_filter_range(void);
+    static std::vector<double> get_clock_rates(void);
+    static uhd::meta_range_t get_gain_range(const std::string &which);
+
+    virtual uint8_t get_product_id() = 0;
+    virtual uint8_t get_device_rev() = 0;
+    virtual std::string get_api_version() = 0;
+    virtual std::string get_arm_version() = 0;
+
+    virtual double set_bw_filter(const std::string &which, const double value) = 0;
+    virtual double set_gain(const std::string &which, const double value) = 0;
+
+    virtual void set_agc(const std::string &which, const bool enable) = 0;
+    virtual void set_agc_mode(const std::string &which, const std::string &mode) = 0;
+
+    virtual double set_clock_rate(const double value) = 0;
+    virtual void enable_channel(const std::string &which, const bool enable) = 0;
+
+    virtual double set_freq(const std::string &which, const double value) = 0;
+    virtual double get_freq(const std::string &which) = 0;
+
+    virtual void set_fir(const std::string &which, const std::vector<int16_t> & fir) = 0;
+    virtual std::vector<int16_t> get_fir(const std::string &which) = 0;
+
+    virtual int16_t get_temperature() = 0;
+
+protected:
+    static uhd::direction_t _get_direction_from_antenna(const std::string& antenna);
+    static ad937x_device::chain_t _get_chain_from_antenna(const std::string& antenna);
+
+    static std::vector<size_t> _get_valid_fir_lengths(const std::string& which);
+};
\ No newline at end of file
diff --git a/mpm/lib/mykonos/ad937x_device.cpp b/mpm/lib/mykonos/ad937x_device.cpp
new file mode 100644
index 000000000..305ef2965
--- /dev/null
+++ b/mpm/lib/mykonos/ad937x_device.cpp
@@ -0,0 +1,334 @@
+#include "adi/mykonos.h"
+
+#include "ad937x_device.hpp"
+#include <functional>
+#include <iostream>
+#include <cmath>
+
+/*
+ad937x_ctrl::sptr ad937x_ctrl_impl::make(
+    spi_lock::sptr spi_l,
+    mpm::spi_iface::sptr iface)
+{
+    return std::make_shared<ad937x_ctrl_impl>(spi_l, iface);
+}
+
+
+void ad937x_ctrl::initialize()
+{
+    //headlessinit(mykonos_config.device);
+    // TODO: finish initialization
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_initialize, mykonos_config.device));
+    }    
+    get_product_id();
+}
+
+ad937x_ctrl::ad937x_ctrl(
+    spi_lock::sptr spi_l, 
+    mpm::spi_iface::sptr iface) :
+    spi_l(spi_l),
+    iface(iface)
+{
+    mpm_sps.spi_iface = iface.get();
+
+    //TODO assert iface->get_chip_select() is 1-8
+    mpm_sps.spi_settings.chipSelectIndex = static_cast<uint8_t>(iface->get_chip_select());
+    mpm_sps.spi_settings.writeBitPolarity = 1;
+    mpm_sps.spi_settings.longInstructionWord = 1; // set to 1 by initialize
+    mpm_sps.spi_settings.MSBFirst = 
+        (iface->get_endianness() == mpm::spi_iface::spi_endianness_t::LSB_FIRST) ? 0 : 1;
+    mpm_sps.spi_settings.CPHA = 0; // set to 0 by initialize
+    mpm_sps.spi_settings.CPOL = 0; // set to 0 by initialize
+    mpm_sps.spi_settings.enSpiStreaming = 1;
+    mpm_sps.spi_settings.autoIncAddrUp = 1;
+    mpm_sps.spi_settings.fourWireMode = 
+        (iface->get_wire_mode() == mpm::spi_iface::spi_wire_mode_t::THREE_WIRE_MODE) ? 0 : 1;
+    mpm_sps.spi_settings.spiClkFreq_Hz = 25000000; 
+
+    initialize();
+}
+
+// helper function to unify error handling
+// bind is bad, but maybe this is justifiable
+void ad937x_ctrl::call_api_function(std::function<mykonosErr_t()> func)
+{
+    auto error = func();
+    if (error != MYKONOS_ERR_OK)
+    {
+        std::cout << getMykonosErrorMessage(error);
+        // TODO: make UHD exception
+        //throw std::exception(getMykonosErrorMessage(error));
+    }
+}
+
+uint8_t ad937x_ctrl::get_product_id()
+{
+    std::lock_guard<spi_lock> lock(*spi_l);
+    uint8_t id;
+    call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id));
+    return id;
+}
+
+double ad937x_ctrl::set_clock_rate(const double req_rate)
+{
+    auto rate = static_cast<decltype(mykonos_config.device->clocks->deviceClock_kHz)>(req_rate / 1000);
+    mykonos_config.device->clocks->deviceClock_kHz = rate;
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_initDigitalClocks, mykonos_config.device));
+    }
+    return static_cast<decltype(set_clock_rate(0))>(rate);
+}
+
+void ad937x_ctrl::_set_active_tx_chains(bool tx1, bool tx2)
+{
+    decltype(mykonos_config.device->tx->txChannels) newTxChannel;
+    if (tx1 && tx2)
+    {
+        newTxChannel = TX1_TX2;
+    }
+    else if (tx1) {
+        newTxChannel = TX1;
+    }
+    else if (tx2) {
+        newTxChannel = TX2;
+    }
+    else {
+        newTxChannel = TXOFF;
+    }
+    mykonos_config.device->tx->txChannels = newTxChannel;
+}
+
+void ad937x_ctrl::_set_active_rx_chains(bool rx1, bool rx2)
+{
+    decltype(mykonos_config.device->rx->rxChannels) newRxChannel;
+    if (rx1 && rx2)
+    {
+        newRxChannel = RX1_RX2;
+    }
+    else if (rx1) {
+        newRxChannel = RX1;
+    }
+    else if (rx2) {
+        newRxChannel = RX2;
+    }
+    else {
+        newRxChannel = RXOFF;
+    }
+    mykonos_config.device->rx->rxChannels = newRxChannel;
+}
+
+void ad937x_ctrl::set_active_chains(direction_t direction, bool channel1, bool channel2)
+{
+    switch (direction)
+    {
+    case TX: _set_active_tx_chains(channel1, channel2); break;
+    case RX: _set_active_rx_chains(channel1, channel2); break;
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+    // TODO: make this apply the setting
+}
+
+double ad937x_ctrl::tune(direction_t direction, const double value)
+{
+    // I'm not really sure why we set the PLL value in the config AND as a function parameter
+    // but here it is
+
+    mykonosRfPllName_t pll;
+    uint64_t integer_value = static_cast<uint64_t>(value);
+    switch (direction)
+    {
+    case TX:
+        pll = TX_PLL;
+        mykonos_config.device->tx->txPllLoFrequency_Hz = integer_value;
+        break;
+    case RX:
+        pll = RX_PLL;
+        mykonos_config.device->rx->rxPllLoFrequency_Hz = integer_value;
+        break;
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_setRfPllFrequency, mykonos_config.device, pll, integer_value));
+    }
+
+    // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide
+    // Furthermore, because coerced is returned as an integer, it's not even accurate
+    uint64_t coerced_pll;
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll));
+    }
+    return static_cast<double>(coerced_pll);
+}
+
+double ad937x_ctrl::get_freq(direction_t direction)
+{
+    mykonosRfPllName_t pll;
+    switch (direction)
+    {
+    case TX: pll = TX_PLL; break;
+    case RX: pll = RX_PLL; break;
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+
+    // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide
+    // Furthermore, because coerced is returned as an integer, it's not even accurate
+    uint64_t coerced_pll;
+    {
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll));
+    }
+    return static_cast<double>(coerced_pll);
+    return double();
+}
+
+// RX Gain values are table entries given in mykonos_user.h
+// An array of gain values is programmed at initialization, which the API will then use for its gain values
+// In general, Gain Value = (255 - Gain Table Index)
+uint8_t ad937x_ctrl::_convert_rx_gain(double inGain, double &coercedGain)
+{
+    // TODO: use uhd::meta_range?
+    const static double min_gain = 0;
+    const static double max_gain = 30;
+    const static double gain_step = 0.5;
+
+    coercedGain = inGain;
+    if (coercedGain < min_gain)
+    {
+        coercedGain = min_gain;
+    }
+    if (coercedGain > max_gain)
+    {
+        coercedGain = max_gain;
+    }
+
+    // round to nearest step
+    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step);
+
+    // gain should be a value 0-60, add 195 to make 195-255
+    return static_cast<uint8_t>((coercedGain * 2) + 195);
+}
+
+// TX gain is completely different from RX gain for no good reason so deal with it
+// TX is set as attenuation using a value from 0-41950 mdB
+// Only increments of 50 mdB are valid
+uint16_t ad937x_ctrl::_convert_tx_gain(double inGain, double &coercedGain)
+{
+    // TODO: use uhd::meta_range?
+    const static double min_gain = 0;
+    const static double max_gain = 41.95;
+    const static double gain_step = 0.05;
+
+    coercedGain = inGain;
+    if (coercedGain < min_gain)
+    {
+        coercedGain = min_gain;
+    }
+    if (coercedGain > max_gain)
+    {
+        coercedGain = max_gain;
+    }
+
+    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step);
+
+    // attenuation is inverted and in mdB not dB
+    return static_cast<uint16_t>((max_gain - (coercedGain)) * 1000);
+}
+
+
+double ad937x_ctrl::set_gain(direction_t direction, chain_t chain, const double value)
+{
+    double coerced_value;
+    switch (direction)
+    {
+    case TX:
+    {
+        uint16_t attenuation = _convert_tx_gain(value, coerced_value);
+        std::function<mykonosErr_t(mykonosDevice_t*, uint16_t)> func;
+        switch (chain)
+        {
+        case CHAIN_1:
+            func = MYKONOS_setTx1Attenuation;
+            break;
+        case CHAIN_2:
+            func = MYKONOS_setTx2Attenuation;
+            break;
+        default:
+            // TODO: bad code path exception
+            throw std::exception();
+        }
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(func, mykonos_config.device, attenuation));
+        break;
+    }
+    case RX:
+    {
+        uint8_t gain = _convert_rx_gain(value, coerced_value);
+        std::function<mykonosErr_t(mykonosDevice_t*, uint8_t)> func;
+        switch (chain)
+        {
+        case CHAIN_1:
+            func = MYKONOS_setRx1ManualGain;
+            break;
+        case CHAIN_2:
+            func = MYKONOS_setRx2ManualGain;
+            break;
+        default:
+            // TODO: bad code path exception
+            throw std::exception();
+        }
+        std::lock_guard<spi_lock> lock(*spi_l);
+        call_api_function(std::bind(func, mykonos_config.device, gain));
+        break;
+    }
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+    return coerced_value;
+}
+
+double ad937x_ctrl::set_agc_mode(direction_t direction, chain_t chain, gain_mode_t mode)
+{
+    std::lock_guard<spi_lock> lock(*spi_l);
+    switch (direction)
+    {
+    case RX:
+        switch (mode)
+        {
+        case GAIN_MODE_MANUAL:
+            call_api_function(std::bind(MYKONOS_resetRxAgc, mykonos_config.device));
+            break;
+        case GAIN_MODE_SLOW_AGC:
+        case GAIN_MODE_FAST_AGC:
+            // TODO: differentiate these
+            call_api_function(std::bind(MYKONOS_setupRxAgc, mykonos_config.device));
+            break;
+        default:
+            // TODO: bad code path exception
+            throw std::exception();
+        }
+    default:
+        // TODO: bad code path exception
+        throw std::exception();
+    }
+    return double();
+}
+
+ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface)
+{
+    return std::make_shared<ad937x_ctrl>(spi_l, iface);
+}
+*/
+
diff --git a/mpm/lib/mykonos/ad937x_device.hpp b/mpm/lib/mykonos/ad937x_device.hpp
new file mode 100644
index 000000000..c2d159be9
--- /dev/null
+++ b/mpm/lib/mykonos/ad937x_device.hpp
@@ -0,0 +1,92 @@
+#pragma once
+
+// TODO: fix path of UHD includes
+#include <../../host/include/uhd/types/direction.hpp>
+#include <../../host/include/uhd/types/ranges.hpp>
+#include <../../host/include/uhd/exception.hpp>
+
+#include "config/ad937x_config_t.hpp"
+#include "config/ad937x_fir.h"
+#include "adi/t_mykonos.h"
+#include "../spi/spi_lock.h"
+#include "../spi/spi_config.h"
+#include <mpm/spi_iface.hpp>
+#include <mpm/spi/adi_ctrl.hpp>
+#include <boost/noncopyable.hpp>
+#include <functional>
+
+struct ad937x_api_version_t {
+    uint32_t silicon_ver;
+    uint32_t major_ver;
+    uint32_t minor_ver;
+    uint32_t build_ver;
+};
+
+struct ad937x_arm_version_t {
+    uint32_t major_ver;
+    uint32_t minor_ver;
+    uint32_t rc_ver;
+};
+
+class ad937x_device : public boost::noncopyable
+{
+public:
+    enum class gain_mode_t { MANUAL, AUTOMATIC, HYBRID };
+    enum class chain_t { ONE, TWO };
+
+    typedef std::shared_ptr<ad937x_device> sptr;
+    virtual ~ad937x_device(void) {};
+    
+    static uhd::meta_range_t get_rf_freq_range(void);
+    static uhd::meta_range_t get_bw_filter_range(void);
+    static std::vector<double> get_clock_rates(void);
+
+    uhd::meta_range_t get_gain_range(uhd::direction_t direction, chain_t chain);
+
+    uint8_t get_product_id() = 0;
+    uint8_t get_device_rev() = 0;
+    ad937x_api_version_t get_api_version() = 0;
+    ad937x_arm_version_t get_arm_version() = 0;
+
+    double set_bw_filter(const uhd::direction_t direction, const chain_t chain, const double value) = 0;
+    double set_gain(const uhd::direction_t direction, const chain_t chain, const double value) = 0;
+
+    void set_agc(const uhd::direction_t direction, const bool enable) = 0;
+    void set_agc_mode(const uhd::direction_t direction, const gain_mode_t mode) = 0;
+
+    double set_clock_rate(const double value) = 0;
+    void enable_channel(const uhd::direction_t direction, const chain_t chain, const bool enable) = 0;
+
+    double tune(const uhd::direction_t direction, const double value) = 0;
+    double get_freq(const uhd::direction_t direction) = 0;
+
+    void set_fir(const uhd::direction_t direction, const chain_t chain, const ad937x_fir & fir) = 0;
+    ad937x_fir get_fir(const uhd::direction_t direction, const chain_t chain) = 0;
+
+    int16_t get_temperature() = 0;    
+
+private:
+    const static double MIN_FREQ;
+    const static double MAX_FREQ;
+
+    virtual void initialize() = 0;
+
+    spi_lock::sptr spi_l;
+    mpm::spi_iface::sptr iface;
+    mpm_spiSettings_t mpm_sps;
+
+    ad937x_config_t mykonos_config;
+
+    void call_api_function(std::function<mykonosErr_t()> func);
+
+    static uint8_t _convert_rx_gain(double inGain, double &coercedGain);
+    static uint16_t _convert_tx_gain(double inGain, double &coercedGain);
+
+    void _set_active_tx_chains(bool tx1, bool tx2);
+    void _set_active_rx_chains(bool rx1, bool rx2);
+
+    const static spi_device_settings_t spi_device_settings;
+};
+
+const double ad937x_ctrl::MIN_FREQ = 300e6;
+const double ad937x_ctrl::MAX_FREQ = 6e9;
\ No newline at end of file
diff --git a/mpm/lib/mykonos/adi/CMakeLists.txt b/mpm/lib/mykonos/adi/CMakeLists.txt
new file mode 100644
index 000000000..596344eb8
--- /dev/null
+++ b/mpm/lib/mykonos/adi/CMakeLists.txt
@@ -0,0 +1,6 @@
+MYKONOS_APPEND_SOURCES(
+    ${CMAKE_CURRENT_SOURCE_DIR}/mykonos.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_gpio.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_user.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/mykonosMmap.c
+)
diff --git a/mpm/lib/mykonos/adi/common.h b/mpm/lib/mykonos/adi/common.h
new file mode 100644
index 000000000..f39f20ce1
--- /dev/null
+++ b/mpm/lib/mykonos/adi/common.h
@@ -0,0 +1,115 @@
+/**
+ * \file common.h
+ * \brief Contains type definitions and prototype declarations for common.c
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* build project settings include the path to the desired platform folder for correct includes */
+#include "stdint.h"
+
+#define SPIARRAYSIZE 1024
+
+/* assuming 3 byte SPI message - integer math enforces floor() */
+#define SPIARRAYTRIPSIZE ((SPIARRAYSIZE / 3) * 3)
+
+/*========================================
+ * Enums and structures
+ *=======================================*/
+/* proposed to increase number of error return values to make unique for each return */
+typedef enum
+{
+    ADIERR_OK=0,
+    ADIERR_INV_PARM,
+    ADIERR_FAILED
+} ADI_ERR;
+
+/*!< \brief COMMON layer error reporting enumerated types */
+typedef enum
+{
+    COMMONERR_OK=0,
+    COMMONERR_FAILED
+} commonErr_t;
+
+/* bit 0 is MESSAGE, bit 1 is WARNING, bit 2 is ERROR */
+typedef enum
+{
+    ADIHAL_LOG_NONE    = 0x0,
+    ADIHAL_LOG_MESSAGE = 0x1,
+    ADIHAL_LOG_WARNING = 0x2,
+    ADIHAL_LOG_ERROR   = 0x4,
+	ADIHAL_LOG_SPI     = 0x8,
+	ADIHAL_LOG_AXI_REG = 0x10,
+	ADIHAL_LOG_AXI_MEM = 0x20,
+	ADIHAL_LOG_ALL     = 0x3F
+} ADI_LOGLEVEL;
+
+/**
+ * \brief Data structure to hold SPI settings for all system device types
+ */
+typedef struct
+{
+	uint8_t chipSelectIndex;        ///< valid 1~8
+	uint8_t writeBitPolarity;       ///< the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation
+	uint8_t longInstructionWord;    ///< 1 = 16bit instruction word, 0 = 8bit instruction word
+	uint8_t MSBFirst;               ///< 1 = MSBFirst, 0 = LSBFirst
+	uint8_t CPHA;                   ///< clock phase, sets which clock edge the data updates (valid 0 or 1)
+	uint8_t CPOL;                   ///< clock polarity 0 = clock starts low, 1 = clock starts high
+    uint8_t enSpiStreaming;         ///< Not implemented. SW feature to improve SPI throughput.
+    uint8_t autoIncAddrUp;          ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1
+    uint8_t fourWireMode;           ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode.
+    uint32_t spiClkFreq_Hz;         ///< SPI Clk frequency in Hz (default 25000000), platform will use next lowest frequency that it's baud rate generator can create */
+
+} spiSettings_t;
+
+/* global variable so application layer can set the log level */
+extern ADI_LOGLEVEL CMB_LOGLEVEL;
+
+/* close hardware pointers */
+commonErr_t CMB_closeHardware(void);
+
+/* GPIO function */
+commonErr_t CMB_setGPIO(uint32_t GPIO);
+
+/* hardware reset function */
+commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex);
+
+/* SPI read/write functions */
+commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings); /* allows the platform HAL to work with devices with various SPI settings */
+commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex );  /* value of 0 deasserts all chip selects */
+commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data); /* single SPI byte write function */
+commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count);
+commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t *readdata); /* single SPI byte read function */
+commonErr_t CMB_SPIWriteField(spiSettings_t *spiSettings, uint16_t addr, uint8_t  field_val, uint8_t mask, uint8_t start_bit); /* write a field in a single register */
+commonErr_t CMB_SPIReadField (spiSettings_t *spiSettings, uint16_t addr, uint8_t *field_val, uint8_t mask, uint8_t start_bit);	/* read a field in a single register */
+
+/* platform timer functions */
+commonErr_t CMB_wait_ms(uint32_t time_ms);
+commonErr_t CMB_wait_us(uint32_t time_us);
+commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms);
+commonErr_t CMB_setTimeout_us(uint32_t timeOut_us);
+commonErr_t CMB_hasTimeoutExpired();
+
+/* platform logging functions */
+commonErr_t CMB_openLog(const char *filename);
+commonErr_t CMB_closeLog(void);
+commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, uint32_t errorCode, const char *comment);
+commonErr_t CMB_flushLog(void);
+
+/* platform FPGA AXI register read/write functions */
+commonErr_t CMB_regRead(uint32_t offset, uint32_t *data);
+commonErr_t CMB_regWrite(uint32_t offset, uint32_t data);
+
+/* platform DDR3 memory read/write functions */
+commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len);
+commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/mpm/lib/mykonos/adi/mykonos.c b/mpm/lib/mykonos/adi/mykonos.c
new file mode 100644
index 000000000..4688388ff
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos.c
@@ -0,0 +1,16678 @@
+/**
+ *\file mykonos.c
+ *
+ *\brief Contains Mykonos APIs for transceiver configuration and control
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+/**
+ * \mainpage Overview
+ *
+ * This document is intended for use by software engineering professionals and
+ * includes detailed information regarding the data types and function calls
+ * which comprise the Mykonos ANSI C API.
+ * References to "Mykonos" in the API refer to the Analog Devices development name for the AD9371 family of devices.
+ *
+ */
+
+/**
+ * \page Disclaimer Legal Disclaimer
+ * WARRANTY DISCLAIMER: THE SOFTWARE AND ANY RELATED INFORMATION AND/OR ADVICE IS PROVIDED ON AN
+ * �AS IS� BASIS, WITHOUT REPRESENTATIONS, GUARANTEES OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
+ * ORAL OR WRITTEN, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT.
+ */
+
+/**
+ * \page Use Suggested Use
+ * The purpose of this API library is to add abstraction for the low level
+ * SPI control and calculations necessary to control the Mykonos family of transceiver devices
+ *
+ * Add the included source code as required to your baseband processor software build. Please reference the integration document
+ * as well for further instructions.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include "common.h"
+#include "mykonos.h"
+#include "mykonos_gpio.h"
+#include "mykonos_macros.h"
+#include "mykonos_user.h"
+
+/* Private helper functions local to this file */
+static mykonosErr_t MYKONOS_calculateScaledDeviceClk_kHz(mykonosDevice_t *device, uint32_t *scaledRefClk_kHz, uint8_t *deviceClkDiv);
+static mykonosErr_t MYKONOS_calculateDigitalClocks(mykonosDevice_t *device, uint32_t *hsDigClk_kHz, uint32_t *hsDigClkDiv4or5_kHz);
+static mykonosErr_t enableDpdTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable);
+static mykonosErr_t enableClgcTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable);
+
+/**
+ * \brief Verifies the Tx profile members are valid (in range) in the init structure
+ *
+ * If the Tx profile IQ data rate = 0, it is assumed that the Tx profile is
+ * not used.  If Tx IQ data rate > 0, and Tx profile members are out of range,
+ *
+ * \pre This function is private and is not called directly by the user.
+ *
+ * <B>Dependencies</B>
+ * - device->tx->txProfile
+ *
+ * \param device Structure pointer to Mykonos device data structure
+ * \param txProfile txProfile settings to be verified
+ * \param txHsDigClk_kHz Return value of the calculated HS Dig Clock required by the Tx profile
+ *
+ * \retval MYKONOS_ERR_TXPROFILE_IQRATE Profile IQ rate out of range
+ * \retval MYKONOS_ERR_TXPROFILE_RFBW Tx Profile RF bandwidth out of range
+ * \retval MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION Filter interpolation not valid
+ * \retval MYKONOS_ERR_TXPROFILE_FIR_INT FIR filter not valid
+ * \retval MYKONOS_ERR_OK All profile members are valid
+ */
+static mykonosErr_t mykVerifyTxProfile(mykonosDevice_t *device, mykonosTxProfile_t *txProfile, uint32_t *txHsDigClk_kHz)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+    *txHsDigClk_kHz = 0;
+
+    /********************************/
+    /* Check for a valid Tx profile */
+    /********************************/
+
+    if ((txProfile->iqRate_kHz < MIN_TX_IQRATE_KHZ) || (txProfile->iqRate_kHz > MAX_TX_IQRATE_KHZ))
+    {
+        return MYKONOS_ERR_TXPROFILE_IQRATE;
+    }
+
+    if ((txProfile->rfBandwidth_Hz < MIN_TX_RFBW_HZ) || (txProfile->rfBandwidth_Hz > MAX_TX_RFBW_HZ))
+    {
+        return MYKONOS_ERR_TXPROFILE_RFBW;
+    }
+
+    if ((txProfile->thb1Interpolation != 1) && (txProfile->thb1Interpolation != 2))
+    {
+        return MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION;
+    }
+
+    if ((txProfile->thb2Interpolation != 1) && (txProfile->thb2Interpolation != 2))
+    {
+        return MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION;
+    }
+
+    if ((txProfile->txFirInterpolation != 1) && (txProfile->txFirInterpolation != 2) && (txProfile->txFirInterpolation != 4))
+    {
+        return MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION;
+    }
+
+    if ((txProfile->txFir->coefs == NULL) && (txProfile->txFirInterpolation != 1))
+    {
+        return MYKONOS_ERR_TXPROFILE_FIR_COEFS;
+    }
+
+    if ((txProfile->dacDiv != DACDIV_2) && (txProfile->dacDiv != DACDIV_2p5) && (txProfile->dacDiv != DACDIV_4))
+    {
+        return MYKONOS_ERR_TXPROFILE_DACDIV;
+    }
+
+    *txHsDigClk_kHz = (txProfile->iqRate_kHz * txProfile->txFirInterpolation * txProfile->thb1Interpolation * txProfile->thb2Interpolation * txProfile->dacDiv);
+
+    device->profilesValid |= TX_PROFILE_VALID;
+
+    return retVal;
+}
+
+/**
+ * \brief Verifies the Rx profile members are valid (in range) and calculates HS Dig Clock require for the Rx Profile
+ *
+ * Private helper function to verify the Rx profile members are valid (in range)
+ * and calculates HS Dig Clock require for the Rx Profile
+ * If the Rx profile IQ data rate = 0, it is assumed that the Rx profile is
+ * not used.  If Rx IQ data rate > 0, and Rx profile members are out of range.
+ *
+ * \pre This function is private and is not called directly by the user.
+ *
+ * <B>Dependencies</B>
+ * - device->rx->rxProfile
+ *
+ * \param device Structure pointer to Talise device data structure
+ * \param rxChannel receiver channel to be checked
+ * \param rxProfile rxProfile settings to be verified
+ * \param rxHsDigClk_kHz Return value of the calculated HS Dig Clock required by the Rx profile
+ *
+ * \retval MYKONOS_ERR_RXPROFILE_RXCHANNEL Rx channel is not valid.
+ * \retval MYKONOS_ERR_RXPROFILE_IQRATE out of range IQ rate
+ * \retval MYKONOS_ERR_RXPROFILE_RFBW out of range RF bandwidth
+ * \retval MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION not valid filter decimation setting
+ * \retval MYKONOS_ERR_RXPROFILE_FIR_COEFS FIR filter not valid
+ * \retval MYKONOS_ERR_RXPROFILE_ADCDIV not valid ADC divider
+ * \retval MYKONOS_ERR_OK all profile members are valid
+ */
+static mykonosErr_t mykVerifyRxProfile(mykonosDevice_t *device, mykonosRxProfType_t rxChannel, mykonosRxProfile_t *rxProfile, uint32_t *rxHsDigClk_kHz)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t minBwHz = 0;
+    uint32_t maxBwHz = 0;
+
+    *rxHsDigClk_kHz = 0;
+
+    switch (rxChannel)
+    {
+        case MYK_RX_PROFILE:
+            minBwHz = MIN_RX_RFBW_HZ;
+            maxBwHz = MAX_RX_RFBW_HZ;
+            break;
+        case MYK_OBS_PROFILE:
+            minBwHz = MIN_ORX_RFBW_HZ;
+            maxBwHz = MAX_ORX_RFBW_HZ;
+            break;
+        case MYK_SNIFFER_PROFILE:
+            minBwHz = MIN_SNIFFER_RFBW_HZ;
+            maxBwHz = MAX_SNIFFER_RFBW_HZ;
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXPROFILE_RXCHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_RXPROFILE_RXCHANNEL));
+            return MYKONOS_ERR_RXPROFILE_RXCHANNEL;
+    }
+
+    /********************************/
+    /* Check for a valid Rx profile */
+    /********************************/
+    if ((rxProfile->iqRate_kHz < MIN_RX_IQRATE_KHZ) || (rxProfile->iqRate_kHz > MAX_RX_IQRATE_KHZ))
+    {
+        return MYKONOS_ERR_RXPROFILE_IQRATE;
+    }
+
+    /* check for Rx/Obs or Sniffer BW */
+    if ((rxProfile->rfBandwidth_Hz < minBwHz) || (rxProfile->rfBandwidth_Hz > maxBwHz))
+    {
+        return MYKONOS_ERR_RXPROFILE_RFBW;
+    }
+
+    if ((rxProfile->rhb1Decimation != 1) && (rxProfile->rhb1Decimation != 2))
+    {
+        return MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION;
+    }
+
+    if ((rxProfile->rxDec5Decimation != 4) && (rxProfile->rxDec5Decimation != 5))
+    {
+        return MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION;
+    }
+
+    if ((rxProfile->rxFirDecimation != 1) && (rxProfile->rxFirDecimation != 2) && (rxProfile->rxFirDecimation != 4))
+    {
+        return MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION;
+    }
+
+    if ((rxProfile->rxFir->coefs == NULL) && (rxProfile->rxFirDecimation != 1))
+    {
+        return MYKONOS_ERR_RXPROFILE_FIR_COEFS;
+    }
+
+    if ((rxProfile->adcDiv != 1) && (rxProfile->adcDiv != 2))
+    {
+        return MYKONOS_ERR_RXPROFILE_ADCDIV;
+    }
+
+    *rxHsDigClk_kHz = (rxProfile->iqRate_kHz * rxProfile->rxFirDecimation * rxProfile->rhb1Decimation * rxProfile->rxDec5Decimation * rxProfile->adcDiv);
+
+    switch (rxChannel)
+    {
+        case MYK_RX_PROFILE:
+            device->profilesValid |= RX_PROFILE_VALID;
+            break;
+        case MYK_OBS_PROFILE:
+            device->profilesValid |= ORX_PROFILE_VALID;
+            break;
+        case MYK_SNIFFER_PROFILE:
+            device->profilesValid |= SNIFF_PROFILE_VALID;
+            break;
+    }
+
+    return retVal;
+}
+
+/**
+ * \brief Performs a hard reset on the MYKONOS DUT (Toggles RESETB pin on device)
+ *
+ * Toggles the Mykonos devices RESETB pin.  Only resets the device with
+ * the SPI chip select indicated in the device->spiSettings structure.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ *
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_resetDevice(mykonosDevice_t *device)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetDevice()\n");
+#endif
+
+    /* toggle RESETB on device with matching spi chip select index */
+    CMB_hardReset(device->spiSettings->chipSelectIndex);
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads back the silicon revision for the Mykonos Device
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param revision Return value of the Mykonos silicon revision
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getDeviceRev(mykonosDevice_t *device, uint8_t *revision)
+{
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDeviceRev()\n");
+#endif
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_PRODUCT_ID, revision, 0x07, 0);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads back the Product ID for the Mykonos Device
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param productId Return value of the Mykonos product Id
+ *
+ * \retval MYKONOS_ERR_GETPRODUCTID__NULL_PARAM recovery action for bad parameter check
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getProductId(mykonosDevice_t *device, uint8_t *productId)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getProductId()\n");
+#endif
+
+    if (productId == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETPRODUCTID_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETPRODUCTID_NULL_PARAM));
+        return MYKONOS_ERR_GETPRODUCTID_NULL_PARAM;
+    }
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_PRODUCT_ID, productId, 0xF8, 3);
+
+    return retVal;
+}
+
+/**
+ * \brief Get API version number
+ *
+ * This function reads back the version number of the API
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param siVer A pointer to the current silicon version number.
+ * \param majorVer A pointer to the current major version number.
+ * \param minorVer A pointer to the current minor version number.
+ * \param buildVer A pointer to the current build version number.
+ *
+ * \retval MYKONOS_ERR_GET_API_VERSION_NULL_PARAM Null parameter passed to the function.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getApiVersion(mykonosDevice_t *device, uint32_t *siVer, uint32_t *majorVer, uint32_t *minorVer, uint32_t *buildVer)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getApiVersion()\n");
+#endif
+
+    if ((siVer == NULL) || (majorVer == NULL) || (minorVer == NULL) || (buildVer == NULL))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_API_VERSION_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_API_VERSION_NULL_PARAM));
+        return MYKONOS_ERR_GET_API_VERSION_NULL_PARAM;
+    }
+
+    *siVer = (uint32_t)MYKONOS_CURRENT_SI_VERSION;
+    *majorVer = (uint32_t)MYKONOS_CURRENT_MAJOR_VERSION;
+    *minorVer = (uint32_t)MYKONOS_CURRENT_MINOR_VERSION;
+    *buildVer = (uint32_t)MYKONOS_CURRENT_BUILD_VERSION;
+    return retVal;
+}
+
+/**
+ * \brief Sets the Mykonos device SPI settings (3wire/4wire, MSBFirst, etc).
+ *
+ * This function will use the settings in the device->spiSettings structure
+ * to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst,
+ * and 3wire/4wire mode.  The Mykonos device always uses SPI MODE 0 (CPHA=0, CPOL=0).
+ * This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and
+ * longInstructionWord =1 to use a 16bit instruction word.
+ *
+ * <B>Dependencies</B>
+ * - writes device->spiSettings->CPHA = 0
+ * - writes device->spiSettings->CPOL = 0
+ * - writes device->spiSettings->longInstructionWord = 1
+ *
+ * - device->spiSettings->MSBFirst
+ * - device->spiSettings->enSpiStreaming
+ * - device->spiSettings->autoIncAddrUp
+ * - device->spiSettings->fourWireMode
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ *
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_setSpiSettings(mykonosDevice_t *device)
+{
+    //device->spiSettings->enSpiStreaming
+    uint8_t spiReg = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setSpiSettings()\n");
+#endif
+
+    device->spiSettings->CPHA = 0;
+    device->spiSettings->CPOL = 0;
+    device->spiSettings->longInstructionWord = 1;
+
+    if (device->spiSettings->MSBFirst == 0)
+    {
+        spiReg |= 0x42; /* SPI bit is 1=LSB first */
+    }
+
+    if (device->spiSettings->autoIncAddrUp > 0)
+    {
+        spiReg |= 0x24;
+    }
+
+    if (device->spiSettings->fourWireMode > 0)
+    {
+        spiReg |= 0x18;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_0, spiReg);
+
+    if (device->spiSettings->enSpiStreaming > 0)
+    {
+        /* Allow SPI streaming mode: SPI message ends when chip select deasserts */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1, 0x00);
+    }
+    else
+    {
+        /* Force single instruction mode */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1, 0x80);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Verifies the integrity of the Mykonos device data structure.
+ *
+ * The Mykonos device data structure has many pointers to other structures.  The
+ * main purpose of this function to verify that the necessary pointers within the
+ * device data structure have non zero pointers. The focus is on the Rx/Tx/ObsRx
+ * profiles and FIR filters where if a channel is disabled, it may be valid for
+ * some pointers to be NULL. This function updates device->profileValid to remember
+ * which profile pointers are valid.
+ * profileValid[3:0] = {SnifferProfileValid, ObsRxProfileValid, RxProfileValid, TxProfileValid};
+ *
+ * <B>Dependencies</B>
+ * - device (all variables)
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ *
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_verifyDeviceDataStructure(mykonosDevice_t *device)
+{
+    if (device == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER));
+        return MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER;
+    }
+
+    device->profilesValid = 0; /* Reset */
+
+    if (device->spiSettings == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_CHECKDEVSTRUCT_SPI, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_SPI));
+        return MYKONOS_ERR_CHECKDEVSTRUCT_SPI;
+    }
+
+    /* place this writeToLog after verifying the spiSettings structure is not NULL */
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_verifyDeviceDataStructure()\n");
+#endif
+
+    /**************************************************************************
+     * Check Rx stucture pointers
+     **************************************************************************
+     */
+    if (device->rx == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_RX, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_RX));
+        return MYKONOS_ERR_CHECKDEVSTRUCT_RX;
+    }
+    else
+    {
+        if (device->rx->rxChannels == RXOFF)
+        {/* If no Rx channel enabled, ok to have null pointers for rx gain control, framer, and Rx profile/Rx FIR Filter */
+        }
+        else
+        {
+            if ((device->rx->framer == NULL) || (device->rx->rxGainCtrl == NULL) || (device->rx->rxProfile == NULL))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB,
+                        getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB));
+                return MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB;
+            }
+
+            if ((device->rx->rxProfile->rxFir == NULL) && (device->rx->rxProfile->rxFirDecimation != 1))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR,
+                        getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR));
+                return MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR;
+            }
+        }
+    }
+
+    /**************************************************************************
+     * Check Tx stucture pointers
+     **************************************************************************
+     */
+    if (device->tx == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_TX, getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_TX));
+        return MYKONOS_ERR_CHECKDEVSTRUCT_TX;
+    }
+    else
+    {
+        if (device->tx->txChannels == TXOFF)
+        {/* If no Tx channel enabled, ok to have null pointers for deframer, and Tx profile/Tx FIR filter */
+        }
+        else
+        {
+            if ((device->tx->deframer == NULL) || (device->tx->txProfile == NULL))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB,
+                        getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB));
+                return MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB;
+            }
+
+            if ((device->tx->txProfile->txFir == NULL) && (device->tx->txProfile->txFirInterpolation != 1))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR,
+                        getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR));
+                return MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR;
+            }
+        }
+    }
+
+    /**************************************************************************
+     * Check ObsRx stucture pointers
+     **************************************************************************
+     */
+    if (device->obsRx == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX,
+                getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX));
+        return MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX;
+    }
+    else
+    {
+        if (device->obsRx->obsRxChannelsEnable == MYK_OBS_RXOFF)
+        {/* If no ObsRx channel enabled, ok to have null pointers for ObsRx gain control, framer, and ObsRx profile/FIR Filter */
+        }
+        else
+        {
+            if ((device->obsRx->framer == NULL))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER,
+                        getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER));
+                return MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER;
+            }
+
+            if (device->obsRx->snifferProfile != NULL)
+            {
+                if (device->obsRx->snifferGainCtrl == NULL)
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL,
+                            getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL));
+                    return MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL;
+                }
+
+                if ((device->obsRx->snifferProfile->rxFir == NULL) && (device->obsRx->snifferProfile->rxFirDecimation != 1))
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR,
+                            getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR));
+                    return MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR;
+                }
+            }
+
+            if (device->obsRx->orxProfile != NULL)
+            {
+                if (device->obsRx->orxGainCtrl == NULL)
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL,
+                            getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL));
+                    return MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL;
+                }
+
+                if ((device->obsRx->orxProfile->rxFir == NULL) && (device->obsRx->orxProfile->rxFirDecimation != 1))
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR,
+                            getMykonosErrorMessage(MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR));
+                    return MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR;
+                }
+            }
+        }
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Initializes the Mykonos device based on the desired device settings.
+ *
+ * This function initializes the mykonos device, setting up the CLKPLL, digital clocks,
+ * JESD204b settings, FIR Filters, digital filtering.  It does not load the ARM
+ * or perform any of the ARM init calibrations. It also sets the Rx Manual gain indexes and
+ * TxAttenuation settings to the initial values found in the device data structure.  It leaves the
+ * Mykonos in a state ready for multichip sync (which can bring up the JESD204 links), the
+ * ARM to be loaded, and the init calibartions run.
+ *
+ * <B>Dependencies</B>
+ * - device (all variables)
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ *
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_initialize(mykonosDevice_t *device)
+{
+    uint8_t txChannelSettings = 0;
+    uint8_t rxChannelSettings = 0;
+    uint8_t orxChannelSettings = 0;
+    uint8_t sniffChannelSettings = 0;
+    uint8_t adcDacClockRateSelect = 0;
+    uint8_t enableDpd = 0;
+    uint8_t obsRxRealIf = 0;
+    uint8_t enRxHighRejDec5 = 0;
+    uint8_t rxRealIfData = 0;
+    uint8_t txSyncb = 0x00;
+    uint8_t rxSyncb = 0x00;
+    uint8_t orxSyncb = 0x00;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_initialize()\n");
+#endif
+
+    retVal = MYKONOS_verifyDeviceDataStructure(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Verify Rx/Tx and ObsRx profiles are valid combinations */
+    retVal = MYKONOS_verifyProfiles(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Set 3 or 4-wire SPI mode, MSBFirst/LSBfirst in device, pushes CPOL=0, CPHA=0, longInstWord=1 into device->spiSettings */
+    retVal = MYKONOS_setSpiSettings(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Increase SPI_DO drive strength */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_IO_CONTROL, 0x10);
+
+    /* Enable Reference clock - Set REFCLK pad common mode voltage */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_REF_PAD_CONFIG2, 0x07);
+
+    /* Set Mykonos IO pin settings, GPIO direction, enable relevant LVDS pads */
+    /* Enable SYSREF LVDS input pad + 100ohm internal termination */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SYSREF_PAD_CONFIG, 0x12); //Enable SYSREF input buffer
+
+    if (device->tx > 0 && device->tx->txProfile > 0)
+    {
+        /* Check for LVDS/CMOS mode */
+        if (device->tx->deframer->txSyncbMode > 0)
+        {
+            txSyncb = 0xF0;
+        }
+        else
+        {
+            txSyncb = 0x02;
+        }
+
+        /* Enable SYNCOUTB output buffer */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_SYNC_PAD_CONFIG, txSyncb);
+    }
+
+    /* Look at each framer and enable the RXSYNCB used for each framer.
+     * It is possible that they use the same RXSYNCB pin */
+    if (device->rx > 0 && device->rx->framer > 0)
+    {
+        /* Check for LVDS/CMOS mode */
+        if (device->rx->framer->rxSyncbMode > 0)
+        {
+            rxSyncb = 0x00;
+        }
+        else
+        {
+            rxSyncb = 0x12;
+        }
+
+        if (device->rx->framer->obsRxSyncbSelect == 0)
+        {
+            /* Enable SYNCINB0 LVDS/CMOS input buffer */
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_SYNC_CONFIG, rxSyncb);
+        }
+        else
+        {
+            /* Enable SYNCINB1 LVDS/CMOS input buffer */
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_SYNC_CONFIG, rxSyncb);
+        }
+    }
+    if (device->obsRx > 0 && device->obsRx->framer > 0)
+    {
+        /* Check for LVDS/CMOS mode */
+        if (device->obsRx->framer->rxSyncbMode > 0)
+        {
+            orxSyncb = 0x00;
+        }
+        else
+        {
+            orxSyncb = 0x12;
+        }
+
+        if (device->obsRx->framer->obsRxSyncbSelect == 0)
+        {
+            /* Check for rxSyncb and orxSyncb when using the same RXSYNCB */
+            if ((orxSyncb != rxSyncb) && (device->rx->framer->obsRxSyncbSelect == 0))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE));
+                return MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE;
+            }
+
+            /* Enable SYNCINB0 LVDS input buffer */
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_SYNC_CONFIG, orxSyncb);
+        }
+        else
+        {
+            /* Check for rxSyncb and orxSyncb when using the same ORXSYNCB */
+            if ((orxSyncb != rxSyncb) && (device->rx->framer->obsRxSyncbSelect == 1))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE));
+                return MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE;
+            }
+
+            /* Enable SYNCINB1 LVDS input buffer */
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_SYNC_CONFIG, orxSyncb);
+        }
+    }
+
+    /* Set number of device clock cycles per microsecond [round(freq/2) - 1] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_REFERENCE_CLOCK_CYCLES, (uint8_t)((((device->clocks->deviceClock_kHz / 1000) + 1) >> 1) - 1));
+
+    /* Set profile specific digital clock dividers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_1, 0x04); /* Negate Rx2 so phase matches Rx1 */
+
+    if (device->profilesValid & TX_PROFILE_VALID)
+    {
+        txChannelSettings = ((device->tx->txChannels & 0x3) << 6);
+        switch (device->tx->txProfile->thb2Interpolation)
+        {
+            case 1:
+                break; /* keep bit as 0 in bitfield */
+            case 2:
+                txChannelSettings |= 0x20;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION));
+                return MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION;
+        }
+
+        switch (device->tx->txProfile->thb1Interpolation)
+        {
+            case 1:
+                break; /* keep bit as 0 in bitfield */
+            case 2:
+                txChannelSettings |= 0x10;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION));
+                return MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION;
+        }
+
+        if (device->tx->txProfile->txFir == 0)
+        {
+            /* If invalid pointer to FIR filter, Bypass programmable FIR, keep txChannelSettings[1:0] == 0 */
+        }
+        else
+        {
+            switch (device->tx->txProfile->txFirInterpolation)
+            {
+                case 1:
+                    txChannelSettings |= 0x01;
+                    break;
+                case 2:
+                    txChannelSettings |= 0x02;
+                    break;
+                case 4:
+                    txChannelSettings |= 0x03;
+                    break;
+                default:
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION,
+                            getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION));
+                    return MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION;
+            }
+        }
+
+        switch (device->tx->txProfile->dacDiv)
+        {
+            case DACDIV_2:
+                break; /* Keep bit [1]=0 */
+            case DACDIV_2p5:
+                break; /* Keep bit [1]=0, div 2.5 is set when Rx DEC5 filter enabled*/
+            case DACDIV_4:
+                adcDacClockRateSelect |= 2;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_DACDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_DACDIV));
+                return MYKONOS_ERR_INIT_INV_DACDIV;
+        }
+    }
+
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        rxChannelSettings = ((device->rx->rxChannels & 0x3) << 6);
+        switch (device->rx->rxProfile->rxDec5Decimation)
+        {
+            case 4:
+                break; /* keep bit as 0 in bitfield */
+            case 5:
+                rxChannelSettings |= 0x04;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION));
+                return MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION;
+        }
+
+        switch (device->rx->rxProfile->rhb1Decimation)
+        {
+            case 1:
+                break; /* keep bit as 0 in bitfield */
+            case 2:
+                rxChannelSettings |= 0x10;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION));
+                return MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION;
+        }
+
+        if (device->rx->rxProfile->rxFir == 0)
+        {
+            /* If invalid pointer to FIR filter, Bypass programmable FIR, keep rxChannelSettings[1:0] == 0 */
+        }
+        else
+        {
+            switch (device->rx->rxProfile->rxFirDecimation)
+            {
+                case 1:
+                    rxChannelSettings |= 0x01;
+                    break;
+                case 2:
+                    rxChannelSettings |= 0x02;
+                    break;
+                case 4:
+                    rxChannelSettings |= 0x03;
+                    break;
+                default:
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION,
+                            getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION));
+                    return MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION;
+            }
+        }
+
+        switch (device->rx->rxProfile->adcDiv)
+        {
+            case 1:
+                adcDacClockRateSelect |= 0;
+                break;
+            case 2:
+                adcDacClockRateSelect |= 1;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ADCDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ADCDIV));
+                return MYKONOS_ERR_INIT_INV_ADCDIV;
+        }
+
+        rxRealIfData = (device->rx->realIfData > 0) ? 1 : 0;
+        enRxHighRejDec5 = (device->rx->rxProfile->enHighRejDec5 > 0) ? 1 : 0;
+    }
+    else if (device->profilesValid & ORX_PROFILE_VALID)
+    {
+        /* if Rx profile not valid, but ORX profile valid, set RX ADC divider and dec5 to match orx profile setting */
+        /* ARM clock is derived from Rx clocking, so Rx ADC div needs to be set */
+        switch (device->obsRx->orxProfile->rxDec5Decimation)
+        {
+            case 4:
+                break; /* keep bit as 0 in bitfield */
+            case 5:
+                rxChannelSettings |= 0x04;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION));
+                return MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION;
+        }
+
+        switch (device->obsRx->orxProfile->adcDiv)
+        {
+            case 1:
+                adcDacClockRateSelect |= 0;
+                break;
+            case 2:
+                adcDacClockRateSelect |= 1;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ADCDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ADCDIV));
+                return MYKONOS_ERR_INIT_INV_ADCDIV;
+        }
+    }
+    else if (device->profilesValid & SNIFF_PROFILE_VALID)
+    {
+        /* if Rx profile not valid, and ORX profile not valid, set RX ADC divider and dec5 to match sniffer profile setting */
+        /* ARM clock is derived from Rx clocking, so Rx ADC div needs to be set */
+        switch (device->obsRx->snifferProfile->rxDec5Decimation)
+        {
+            case 4:
+                break; /* keep bit as 0 in bitfield */
+            case 5:
+                rxChannelSettings |= 0x04;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION));
+                return MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION;
+        }
+
+        switch (device->obsRx->snifferProfile->adcDiv)
+        {
+            case 1:
+                adcDacClockRateSelect |= 0;
+                break;
+            case 2:
+                adcDacClockRateSelect |= 1;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ADCDIV, getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ADCDIV));
+                return MYKONOS_ERR_INIT_INV_ADCDIV;
+        }
+    }
+
+    /* determine ObsRx ADC Div setting */
+    if (device->profilesValid & ORX_PROFILE_VALID)
+    {
+        switch (device->obsRx->orxProfile->adcDiv)
+        {
+            case 1:
+                break; /* Keep bit[4]=0 */
+            case 2:
+                adcDacClockRateSelect |= 0x10;
+                break; /* Set bit[4]=1 */
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV));
+                return MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV;
+        }
+    }
+    else if (device->profilesValid & SNIFF_PROFILE_VALID)
+    {
+        switch (device->obsRx->snifferProfile->adcDiv)
+        {
+            case 1:
+                break; /* Keep bit[4]=0 */
+            case 2:
+                adcDacClockRateSelect |= 0x10;
+                break; /* Set bit[4]=1 */
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV));
+                return MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV;
+        }
+    }
+    else if (device->profilesValid & RX_PROFILE_VALID)
+    { /* if OBSRX profiles are not valid, set obsRx ADC div to match Rx ADC divider */
+        switch (device->rx->rxProfile->adcDiv)
+        {
+            case 1:
+                break; /* Keep bit[4]=0 */
+            case 2:
+                adcDacClockRateSelect |= 0x10;
+                break; /* Set bit[4]=1 */
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV));
+                return MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV;
+        }
+    }
+
+    /* Determine ORx and Sniffer channel settings */
+    if (device->obsRx > 0)
+    {
+        /* verify pointers in data structure are valid (non-zero) */
+        if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))
+        {
+            if (device->obsRx->realIfData > 0)
+            {
+                obsRxRealIf = 1;
+            }
+        }
+
+        /* TODO: verify that the decimation matches the given IQ rate in the data structure */
+
+        /* Set Sniffer profile (digital filter enables) if sniffer profile enabled (valid pointer) */
+        if (device->profilesValid & SNIFF_PROFILE_VALID)
+        {
+            sniffChannelSettings = 0;
+            switch (device->obsRx->snifferProfile->rhb1Decimation)
+            {
+                case 1:
+                    break;
+                case 2:
+                    sniffChannelSettings |= 0x10;
+                    break;
+                default:
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_SNIFFER_RHB1,
+                            getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_SNIFFER_RHB1));
+                    return MYKONOS_ERR_INIT_INV_SNIFFER_RHB1;
+            }
+
+            if (device->obsRx->snifferProfile->rxFir > 0)
+            {
+
+                switch (device->obsRx->snifferProfile->rxFirDecimation)
+                {
+                    case 1:
+                        sniffChannelSettings |= 0x01;
+                        break;
+                    case 2:
+                        sniffChannelSettings |= 0x02;
+                        break;
+                    case 4:
+                        sniffChannelSettings |= 0x03;
+                        break;
+                    default:
+                        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC,
+                                getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC));
+                        return MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC;
+                }
+            }
+        }
+
+        /* Set ORx profile (digital filter enables) if ORx profile enabled (valid pointer) */
+        if (device->profilesValid & ORX_PROFILE_VALID)
+        {
+            orxChannelSettings = 0;
+            switch (device->obsRx->orxProfile->rhb1Decimation)
+            {
+                case 1:
+                    break;
+                case 2:
+                    orxChannelSettings |= 0x10;
+                    break;
+                default:
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ORX_RHB1,
+                            getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ORX_RHB1));
+                    return MYKONOS_ERR_INIT_INV_ORX_RHB1;
+            }
+
+            if (device->obsRx->orxProfile->rxFir > 0)
+            {/* if pointer to orx rxFIR is valid */
+
+                switch (device->obsRx->orxProfile->rxFirDecimation)
+                {
+                    case 1:
+                        orxChannelSettings |= 0x01;
+                        break;
+                    case 2:
+                        orxChannelSettings |= 0x02;
+                        break;
+                    case 4:
+                        orxChannelSettings |= 0x03;
+                        break;
+                    default:
+                        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC,
+                                getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC));
+                        return MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC;
+                }
+            }
+        }
+    }
+
+    /************************************************************************
+     * Set channel config settings for Rx/Tx/oRx and Sniffer channels
+     ***********************************************************************
+     */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_2, txChannelSettings);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_4, rxChannelSettings);
+
+    /* Set option to use new high rejection DEC5 filters in main Rx1/Rx2 path.  */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_5, ((rxRealIfData << 2) | (enRxHighRejDec5 ? 3 : 0)));
+
+    if (rxRealIfData > 0)
+    {
+        /* Set Rx1 NCO frequency */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_3, 0x40);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_2, 0x00);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_1, 0x01);
+
+        /* Set Rx2 NCO frequency */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_3, 0x40);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_2, 0x00);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_1, 0x01);
+
+        /* Enable NCO for Rx1 and Rx2 to shift data from zero IF to real IF */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_NCO_CONTROL, 3, 0x03, 0);
+    }
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_2, obsRxRealIf, 0x40, 6);
+
+    /* if sniffer profile disabled, Sniffer config reg is set to default = 0x80 */
+    sniffChannelSettings |= 0x80; /* use PFIR coef set B = bit[7]=1*/
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SNIFFER_CONFIGURATION_CONTROL, sniffChannelSettings);
+
+    /* if orx profile not valid, SPI reg for orx config is set to default = 0x00 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_CONFIGURATION_CONTROL, orxChannelSettings);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_LOOPBACK_CONFIGURATION_CONTROL, orxChannelSettings);
+
+    /* Set ADC divider, DAC divider, and ObsRx/sniffer dividers */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_1, adcDacClockRateSelect, 0x13, 0);
+
+    /* Disable ORx digital DC offset - bad default SPI setting for ObsRx DC offset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT, 0x60);
+
+    /* Necessary write for ARM init cals to work */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SNIFF_RXLOGEN_BYTE1, 0x0E);
+
+    /* Increase Sniffer LNA gain */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SNRX_LNA_BIAS_C, 0x0F);
+
+    /* Set the CLKPLL with the frequency from the device data structure */
+    retVal = MYKONOS_initDigitalClocks(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Wait for CLKPLL CP Cal done and CLKPLL Lock  or throw error message */
+    CMB_wait_ms(500);
+    retVal = MYKONOS_waitForEvent(device, CLKPLLCP, 1000000);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    retVal = MYKONOS_waitForEvent(device, CLKPLL_LOCK, 1000000);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Enable digital clocks - this is gated by the CLKPLL being locked */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_0, 0x14);
+
+    /* Set the Tx PFIR synchronization clock */
+    retVal = MYKONOS_setTxPfirSyncClk(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Set the Rx PFIR synchronization clock */
+    retVal = MYKONOS_setRxPfirSyncClk(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if (device->profilesValid & TX_PROFILE_VALID)
+    {
+        /* Set pre TxPFIR Half band filter interpolation */
+        if (device->tx->txProfile->txInputHbInterpolation == 1)
+        {
+            /* disable TX input half band ([3:2]=00) - but allow DPD to still be enabled for tx profiles with wide BW [1] */
+            enableDpd = (device->tx->txProfile->enableDpdDataPath > 0) ? 1 : 0;
+            CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, enableDpd, 0x0E, 1);
+        }
+        else if (device->tx->txProfile->txInputHbInterpolation == 2)
+        {
+            if (device->tx->txProfile->iqRate_kHz > 160000)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE));
+                return MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE;
+            }
+
+            /* enable TX input half band[2]=1, and Enable DPD[1]=1*/
+            CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, 3, 0x0E, 1);
+        }
+        else if (device->tx->txProfile->txInputHbInterpolation == 4)
+        {
+            if (device->tx->txProfile->iqRate_kHz > 80000)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE,
+                        getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE));
+                return MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE;
+            }
+
+            /* enable TX input HB0[3]=1 and Tx input HB[2]=1, and Enable DPD[1]=1*/
+            CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, 7, 0x0E, 1);
+        }
+        else
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM));
+            return MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM;
+        }
+
+        /* Enable SPI Tx Atten mode */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x01, 0x03, 0);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x01, 0x0C, 2);
+
+        /* Set Tx1 Atten step size */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, device->tx->txAttenStepSize, 0x60, 5);
+
+        /* Set Tx2 Atten step size */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, device->tx->txAttenStepSize, 0x60, 5);
+    }
+    else
+    {
+        /* Power down DACs */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_PD_OVERIDE_7_0, 3, 0x0C, 2);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_PD_OVERRIDE_CONTROL_7_0, 3, 0x0C, 2);
+    }
+
+    /* Set RxFE LO Common mode */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXFE1_LOCM, 0xF0);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXFE2_LOCM, 0xF0);
+
+    /* Set Rxloopback LO Common mode */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXLOOPBACK1_CNTRL_1, 0xFF);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RXLOOPBACK2_CNTRL_1, 0xFF);
+
+    /* Setup MGC or AGC Rx gain control */
+    retVal = MYKONOS_setupRxAgc(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Default Rx to use manual gain control until AGC enabled by user */
+    MYKONOS_setRxGainControlMode(device, MGC);
+
+    retVal = MYKONOS_setupObsRxAgc(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Default ObsRx to use manual gain control until AGC enabled by user */
+    MYKONOS_setObsRxGainControlMode(device, MGC);
+
+    /* Disable GPIO select bits by setting to b11 */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_1, 3, 0x30, 4);
+
+    /* Extra settings for ARM calibrations */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT, 0x11);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_LOOPBACK1_CNTRL_4, 0x04);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_LOOPBACK2_CNTRL_4, 0x04);
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2, 0x20, 0x20, 0);
+
+    /* Extra settings for ADC initialisation */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_ADC_FLASH_DELAY, 0x28);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_ADC_FLASH_CTRL, 0x0E);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_ADC_FLASH_DELAY, 0x28);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_ADC_FLASH_CTRL, 0x0E);
+
+    /* Move to Alert ENSM state */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ENSM_CONFIG_7_0, 0x05);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Verifies the init structure profiles are valid combinations
+ *
+ * This function checks that the Rx/Tx/ORx/Sniffer profiles have valid clock rates in
+ * order to operate together.  Rx/Tx and ORx/Sniffer share a common high speed digital
+ * clock. If an invalid combination of profiles is detected, an error will be
+ * returned. If a profile in the init structure is unused, the user should zero
+ * out all members of that particular profile structure.  If a Rx/Tx/ORx/Sniffer profile
+ * has an IQ rate = 0, it is assumed that the profile is disabled.
+ *
+ * \pre This function is private and is not called directly by the user.
+ *
+ * This function uses mykVerifyTxProfile() and mykVerifyRxProfile() as helper functions.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Structure pointer to Mykonos device data structure
+ *
+ * \retval MYKONOS_ERR_PROFILES_HSDIGCLK profiles loaded are not valid
+ * \retval MYKONOS_ERR_OK  Function completed successfully
+ */
+mykonosErr_t MYKONOS_verifyProfiles(mykonosDevice_t *device)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+    uint32_t rxHsDigClk_kHz = 0;
+    uint32_t orxHsDigClk_kHz = 0;
+    uint32_t snifferHsDigClk_kHz = 0;
+    uint32_t txHsDigClk_kHz = 0;
+
+    mykonosRxProfile_t *rxProfile = NULL;
+    mykonosTxProfile_t *txProfile = NULL;
+    mykonosRxProfile_t *orxProfile = NULL;
+    mykonosRxProfile_t *snifferProfile = NULL;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_verifyProfiles()\n");
+#endif
+
+    device->profilesValid = 0;
+
+    /* Check all loaded profiles */
+    if (device->tx->txChannels != TXOFF)
+    {
+        txProfile = device->tx->txProfile;
+        retVal = mykVerifyTxProfile(device, txProfile, &txHsDigClk_kHz);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }
+
+    if (device->rx->rxChannels != RXOFF)
+    {
+        rxProfile = device->rx->rxProfile;
+        retVal = mykVerifyRxProfile(device, MYK_RX_PROFILE, rxProfile, &rxHsDigClk_kHz);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }
+
+    if (device->obsRx->obsRxChannelsEnable != MYK_OBS_RXOFF)
+    {
+        if (device->obsRx->obsRxChannelsEnable & MYK_ORX1_ORX2)
+        {
+            orxProfile = device->obsRx->orxProfile;
+            retVal = mykVerifyRxProfile(device, MYK_OBS_PROFILE, orxProfile, &orxHsDigClk_kHz);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+        }
+
+        if (device->obsRx->obsRxChannelsEnable & MYK_SNRXA_B_C)
+        {
+            snifferProfile = device->obsRx->snifferProfile;
+            retVal = mykVerifyRxProfile(device, MYK_SNIFFER_PROFILE, snifferProfile, &snifferHsDigClk_kHz);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+        }
+    }
+
+    return retVal;
+}
+
+/**
+ * \brief Write indirect registers (Programmable FIRs, Rx gain tables, JESD204B settings).  Must be done after Multi Chip Sync
+ *
+ * The BBP should never need to call this function.  It is called automatically by the initArm function.
+ * This function is a continuation of the MYKONOS_initialize() function.  This part of initialization must be done after
+ * the BBP has completed Multi chip Sync.  These registers include FIR filters, Rx gain tables, and JESD204B framer/deframer
+ * config registers.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device data structure containing settings
+ *                   an error.
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_initSubRegisterTables(mykonosDevice_t *device)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+    /* ------------------------------------------------------------------------------------------- */
+    /* Program submap register tables after digital clocks are up and running and Multi Chip Sync */
+    /* has been completed by BBP */
+    if (device->profilesValid & TX_PROFILE_VALID)
+    {
+        if (device->tx->txProfile->txFir > 0)
+        {
+            retVal = MYKONOS_programFir(device, TX1TX2_FIR, device->tx->txProfile->txFir);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+        }
+    }
+
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        if (device->rx->rxProfile->rxFir > 0)
+        {
+            retVal = MYKONOS_programFir(device, RX1RX2_FIR, device->rx->rxProfile->rxFir);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            /* Load Rx gain table */
+            retVal = MYKONOS_programRxGainTable(device, &RxGainTable[0][0], (sizeof(RxGainTable) >> 2), RX1_RX2_GT);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            retVal = MYKONOS_setRx1ManualGain(device, device->rx->rxGainCtrl->rx1GainIndex);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            retVal = MYKONOS_setRx2ManualGain(device, device->rx->rxGainCtrl->rx2GainIndex);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            /* Enable Digital gain for Rx and ObsRx gain tables */
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DIGITAL_GAIN_CONFIG, 0x80);
+        }
+    }
+
+    if (device->profilesValid & SNIFF_PROFILE_VALID)
+    {
+        if (device->obsRx->snifferProfile->rxFir > 0)
+        {
+            retVal = MYKONOS_programFir(device, OBSRX_B_FIR, device->obsRx->snifferProfile->rxFir);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            /* Load Sniffer Rx gain table */
+            retVal = MYKONOS_programRxGainTable(device, &SnRxGainTable[0][0], (sizeof(SnRxGainTable) >> 2), SNRX_GT);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            retVal = MYKONOS_setObsRxManualGain(device, OBS_SNIFFER_A, device->obsRx->snifferGainCtrl->gainIndex);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+        }
+    }
+
+    if (device->profilesValid & ORX_PROFILE_VALID)
+    {
+        if (device->obsRx->orxProfile->rxFir > 0)
+        {/* if pointer to orx rxFIR is valid */
+            retVal = MYKONOS_programFir(device, OBSRX_A_FIR, device->obsRx->orxProfile->rxFir);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            /* Load ORx gain table */
+            retVal = MYKONOS_programRxGainTable(device, &ORxGainTable[0][0], (sizeof(ORxGainTable) >> 2), ORX_GT);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            retVal = MYKONOS_setObsRxManualGain(device, OBS_RX1_TXLO, device->obsRx->orxGainCtrl->orx1GainIndex);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+
+            retVal = MYKONOS_setObsRxManualGain(device, OBS_RX2_TXLO, device->obsRx->orxGainCtrl->orx2GainIndex);
+            if (retVal != MYKONOS_ERR_OK)
+            {
+                return retVal;
+            }
+        }
+    }
+
+    /* Load Loopback Gain Table for ARM calibrations */
+    {
+        uint8_t loopBackGainTable[6][4] = {
+        /* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */
+        {0, 0, 0, 0}, /* Gain index 255 */
+        {7, 0, 0, 0}, /* Gain index 254 */
+        {13, 0, 1, 1}, /* Gain index 253 */
+        {18, 0, 3, 1}, /* Gain index 252 */
+        {23, 0, 3, 1}, /* Gain index 251 */
+        {28, 0, 0, 0} /* Gain index 250 */
+        };
+        retVal = MYKONOS_programRxGainTable(device, &loopBackGainTable[0][0], (sizeof(loopBackGainTable) >> 2), LOOPBACK_GT);
+    }
+
+    /* Enable Digital gain for ORx/Sniffer/Loopback gain table */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_DIGITAL_GAIN_CONFIG, 0x80);
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RCAL_CONTROL, 0x07);/* Set RCAL code to nominal */
+
+    /* If Valid Rx Profile or valid ObsRx profile, setup serializers */
+    if ((device->profilesValid & RX_PROFILE_VALID) || (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)))
+    {
+        retVal = MYKONOS_setupSerializers(device);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }
+
+    if ((device->rx->rxChannels != RXOFF) && (device->profilesValid & RX_PROFILE_VALID))
+    {
+        retVal = MYKONOS_setupJesd204bFramer(device);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }
+
+    if ((device->obsRx->obsRxChannelsEnable != MYK_OBS_RXOFF) && (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)))
+    {
+        retVal = MYKONOS_setupJesd204bObsRxFramer(device);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }
+
+    if ((device->tx->txChannels != TXOFF) && (device->profilesValid & TX_PROFILE_VALID))
+    {
+        retVal = MYKONOS_setupDeserializers(device);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+
+        retVal = MYKONOS_setupJesd204bDeframer(device);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+
+        retVal = MYKONOS_setTx1Attenuation(device, device->tx->tx1Atten_mdB);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+
+        retVal = MYKONOS_setTx2Attenuation(device, device->tx->tx2Atten_mdB);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs a blocking wait for a Mykonos calibration or Pll Lock
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device data structure containing settings
+ * \param waitEvent the enum value of the event to wait for
+ * \param timeout_us If timeout_us time has passed, function will return with
+ *                   an error.
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent, uint32_t timeout_us)
+{
+    uint16_t spiAddr = 0;
+    uint8_t spiBit = 0;
+    uint8_t doneBitLevel = 0;
+    uint8_t data = 0;
+    mykonosErr_t errCode = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_waitForEvent()\n");
+#endif
+
+    switch (waitEvent)
+    {
+        case CALPLL_LOCK:/* wait for x17F[7]=1 */
+            spiAddr = MYKONOS_ADDR_CALPLL_SDM_CONTROL;
+            spiBit = 7;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CALPLL_LOCK;
+            break;
+        case CLKPLLCP: /* wait for x154[5]=1 */
+            spiAddr = MYKONOS_ADDR_CLK_SYNTH_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLLCP;
+            break;
+        case CLKPLL_LOCK: /* wait for x157[0]=1 */
+            spiAddr = MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLL_LOCK;
+            break;
+        case RF_RXPLLCP:/* wait for x254[5]=1 */
+            spiAddr = MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLLCP;
+            break;
+        case RF_RXPLL_LOCK: /* wait for x257[0]=1 */
+            spiAddr = MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLL_LOCK;
+            break;
+        case RF_TXPLLCP: /* wait for x2C4[5]=1 */
+            spiAddr = MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLLCP;
+            break;
+        case RF_TXPLL_LOCK: /* wait for x2C7[0]=1 */
+            spiAddr = MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLL_LOCK;
+            break;
+        case RF_SNIFFERPLLCP: /* wait for x354[7]=1 */
+            spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLLCP;
+            break;
+        case RF_SNIFFERPLL_LOCK: /* wait for x357[0]=1 */
+            spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLL_LOCK;
+            break;
+        case RXBBF_CALDONE: /* wait for x1B2[5]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXBBFCALDONE;
+            break;
+        case TXBBF_CALDONE:/* wait for x1B2[0]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 0;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXBBFCALDONE;
+            break;
+        case RX_RFDC_CALDONE: /* wait for x1B2[1]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 1;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RFDCCALDONE;
+            break;
+        case RX_ADCTUNER_CALDONE:/* wait for x1B2[7]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 7;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ADCTUNECALDONE;
+            break;
+        case RX1_ADCPROFILE:/* wait for x5DD[5]=0 */
+            spiAddr = MYKONOS_ADDR_RX_ADC1_PRFL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX1ADCPROFILE;
+            break;
+        case RX2_ADCPROFILE:/* wait for x5DE[5]=0 */
+            spiAddr = MYKONOS_ADDR_RX_ADC2_PRFL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX2ADCPROFILE;
+            break;
+        case ORX_ADCPROFILE:/* wait for x5DF[5]=0 */
+            spiAddr = MYKONOS_ADDR_ORX_ADC_PRFL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ORXADCPROFILE;
+            break;
+        case RCAL_CALDONE: /* wait for x1B2[6]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 6;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RCALDONE;
+            break;
+        case ARMBUSY:/* wait for xD30[7]=0 */
+            spiAddr = MYKONOS_ADDR_ARM_CMD;
+            spiBit = 7;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ARMBUSY;
+            break;
+        case INITARM_DONE:
+            spiAddr = MYKONOS_ADDR_ARM_CMD;
+            spiBit = 7;
+            doneBitLevel = 0;
+            errCode = MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_INITARMDONE;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITFOREVENT_INV_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_WAITFOREVENT_INV_PARM));
+            return MYKONOS_ERR_WAITFOREVENT_INV_PARM;
+    }
+
+    CMB_setTimeout_us(timeout_us); /* timeout after desired time */
+
+    do
+    {
+        CMB_SPIReadByte(device->spiSettings, spiAddr, &data);
+
+        /* For SW verification tests, allow API to think all cals are complete*/
+#ifdef MYK_CALS_DONE_SWDEBUG
+        if (doneBitLevel == 0)
+        {
+            data = 0x00;
+        }
+        else
+        {
+            data = 0xFF;
+        }
+#endif
+
+        if (CMB_hasTimeoutExpired() > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, errCode, getMykonosErrorMessage(errCode));
+            return errCode;
+        }
+    } while (((data >> spiBit) & 0x01) != doneBitLevel);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs a readback with no wait for a Mykonos calibration or Pll Lock
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device data structure containing settings
+ * \param waitEvent the enum value of the event to wait for
+ * \param eventDone Return value: 1= calibration event is complete.  0 = Event is still pending
+ * \return Returns enum mykonosErr_t, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_readEventStatus(mykonosDevice_t *device, waitEvent_t waitEvent, uint8_t *eventDone)
+{
+    uint16_t spiAddr = 0;
+    uint8_t data = 0;
+    uint8_t spiBit = 0;
+    uint8_t doneBitLevel = 0;
+
+    switch (waitEvent)
+    {
+        case CALPLL_LOCK:/* wait for x17F[7]=1 */
+            spiAddr = MYKONOS_ADDR_CALPLL_SDM_CONTROL;
+            spiBit = 7;
+            doneBitLevel = 1;
+            break;
+        case CLKPLLCP: /* wait for x154[5]=1 */
+            spiAddr = MYKONOS_ADDR_CLK_SYNTH_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            break;
+        case CLKPLL_LOCK: /* wait for x157[0]=1 */
+            spiAddr = MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            break;
+        case RF_RXPLLCP:/* wait for x254[5]=1 */
+            spiAddr = MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            break;
+        case RF_RXPLL_LOCK: /* wait for x257[0]=1 */
+            spiAddr = MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            break;
+        case RF_TXPLLCP: /* wait for x2C4[5]=1 */
+            spiAddr = MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            break;
+        case RF_TXPLL_LOCK: /* wait for x2C7[0]=1 */
+            spiAddr = MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            break;
+        case RF_SNIFFERPLLCP: /* wait for x354[7]=1 */
+            spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT;
+            spiBit = 5;
+            doneBitLevel = 1;
+            break;
+        case RF_SNIFFERPLL_LOCK: /* wait for x357[0]=1 */
+            spiAddr = MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1;
+            spiBit = 0;
+            doneBitLevel = 1;
+            break;
+        case RXBBF_CALDONE: /* wait for x1B2[5]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            break;
+        case TXBBF_CALDONE:/* wait for x1B2[0]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 0;
+            doneBitLevel = 0;
+            break;
+        case RX_RFDC_CALDONE: /* wait for x1B2[1]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 1;
+            doneBitLevel = 0;
+            break;
+        case RX_ADCTUNER_CALDONE:/* wait for x1B2[7]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 7;
+            doneBitLevel = 0;
+            break;
+        case RX1_ADCPROFILE:/* wait for x5DD[5]=0 */
+            spiAddr = MYKONOS_ADDR_RX_ADC1_PRFL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            break;
+        case RX2_ADCPROFILE:/* wait for x5DE[5]=0 */
+            spiAddr = MYKONOS_ADDR_RX_ADC2_PRFL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            break;
+        case ORX_ADCPROFILE:/* wait for x5DF[5]=0 */
+            spiAddr = MYKONOS_ADDR_ORX_ADC_PRFL;
+            spiBit = 5;
+            doneBitLevel = 0;
+            break;
+        case RCAL_CALDONE: /* wait for x1B2[6]=0 */
+            spiAddr = MYKONOS_ADDR_CALIBRATION_CONTROL;
+            spiBit = 6;
+            doneBitLevel = 0;
+            break;
+        case ARMBUSY:/* wait for xD30[7]=0 */
+            spiAddr = MYKONOS_ADDR_ARM_CMD;
+            spiBit = 7;
+            doneBitLevel = 0;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITFOREVENT_INV_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_WAITFOREVENT_INV_PARM));
+            return MYKONOS_ERR_WAITFOREVENT_INV_PARM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, spiAddr, &data);
+
+    if (doneBitLevel)
+    {
+        *eventDone = (data >> spiBit) & 0x01;
+    }
+    else
+    {
+        *eventDone = ((~(data >> spiBit)) & 0x01);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets the CLKPLL output frequency.
+ *
+ * This code updates the Synth and Loop filter settings based on a VCO
+ * frequency LUT. The VCO frequency break points for the Synth LUT can be
+ * found in an array called vcoFreqArrayMhz.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ * - device->deviceClock_kHz
+ * - device->rxSettings->rxProfile->vcoFreq_kHz
+ * - device->rxSettings->rxProfile->clkPllHsDiv
+ * - device->rxSettings->rxProfile->clkPllVcoDiv
+ *
+ * \param device is structure pointer to the MYKONOS data structure containing settings
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_initDigitalClocks(mykonosDevice_t *device)
+{
+    /* RF Synth variables */
+    /* pull Synth and Loop filter values from a Look Up Table */
+    uint8_t vcoOutLvl;
+    uint8_t vcoVaractor; /* [3:0] */
+    uint8_t vcoBiasRef; /* [2:0] */
+    uint8_t vcoBiasTcf; /* [1:0] */
+    uint8_t vcoCalOffset; /* [3:0] */
+    uint8_t vcoVaractorRef; /* [3:0] */
+    uint8_t loopFilterIcp; /* Icp[5:0] */
+    uint8_t loopFilterC2C1; /* C2[3:0],C1[3:0] */
+    uint8_t loopFilterR1C3; /* R1[3:0],C3[3:0] */
+    uint8_t loopFilterR3; /* R3[3:0] */
+    uint8_t vcoIndex;
+    uint8_t i;
+
+    /* RF PLL variables */
+    uint16_t integerWord;
+    uint32_t fractionalWord;
+    uint32_t fractionalRemainder;
+    uint32_t scaledRefClk_Hz;
+
+    /* common */
+    uint64_t hsDigClk_Hz = 0;
+    uint32_t scaledRefClk_kHz = 0;
+    uint8_t deviceClkDiv = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+    uint8_t clockControl2 = 0;
+    uint8_t sdmSettings = 0;
+    uint8_t hsDiv = 4;
+    uint8_t vcoDiv = 0;
+    uint8_t vcoDivTimes10 = 10;
+
+    /******************RF Synth Section************************/
+    static const uint8_t icp_46p08[53] = {15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 32, 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30,
+            31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 38, 39, 21, 21, 21, 22, 22, 22, 23, 23, 23};
+
+    static const uint8_t icp_61p44[53] = {11, 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+            23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 15, 16, 16, 16, 16, 17, 17, 17, 17};
+
+    static const uint8_t icp_76p8[53] = {9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 17, 18, 18,
+            19, 19, 20, 20, 20, 21, 21, 22, 22, 23, 23, 12, 12, 13, 13, 13, 13, 13, 14, 14};
+
+    static const uint32_t vcoFreqArray_kHz[53] = {12605000UL, 12245000UL, 11906000UL, 11588000UL, 11288000UL, 11007000UL, 10742000UL, 10492000UL, 10258000UL, 10036000UL,
+            9827800UL, 9631100UL, 9445300UL, 9269800UL, 9103600UL, 8946300UL, 8797000UL, 8655300UL, 8520600UL, 8392300UL, 8269900UL, 8153100UL, 8041400UL, 7934400UL,
+            7831800UL, 7733200UL, 7638400UL, 7547100UL, 7459000UL, 7374000UL, 7291900UL, 7212400UL, 7135500UL, 7061000UL, 6988700UL, 6918600UL, 6850600UL, 6784600UL,
+            6720500UL, 6658200UL, 6597800UL, 6539200UL, 6482300UL, 6427000UL, 6373400UL, 6321400UL, 6270900UL, 6222000UL, 6174500UL, 6128400UL, 6083600UL, 6040100UL,
+            5997700UL};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_initDigitalClocks()\n");
+#endif
+
+    retVal = MYKONOS_calculateScaledDeviceClk_kHz(device, &scaledRefClk_kHz, &deviceClkDiv);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    hsDiv = device->clocks->clkPllHsDiv;
+    vcoDiv = device->clocks->clkPllVcoDiv;
+
+    switch (hsDiv)
+    {
+        case 4:
+            hsDiv = 4; /* clockControl2[3:2] = 00 */
+            break;
+        case 5:
+            hsDiv = 5;
+            clockControl2 |= 0x04; /* Set bit[2]=1 */
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_HSDIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_HSDIV));
+            return MYKONOS_ERR_CLKPLL_INV_HSDIV;
+    }
+
+    switch (vcoDiv)
+    {
+        case VCODIV_1:
+            vcoDivTimes10 = 10; /* clockControl2[1:0] = 00 */
+            break;
+        case VCODIV_1p5:
+            vcoDivTimes10 = 15;
+            clockControl2 |= 0x01;
+            break;
+        case VCODIV_2:
+            vcoDivTimes10 = 20;
+            clockControl2 |= 0x02;
+            break;
+        case VCODIV_3:
+            vcoDivTimes10 = 30;
+            clockControl2 |= 0x03;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_VCODIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_VCODIV));
+            return MYKONOS_ERR_CLKPLL_INV_VCODIV;
+    }
+
+    clockControl2 |= ((deviceClkDiv & 3) << 4);
+
+    /* find vco table index based on vco frequency */
+    for (i = 0; device->clocks->clkPllVcoFreq_kHz < vcoFreqArray_kHz[i]; i++)
+    {
+        /* Intentionally blank, for loop exits when condition met, index i used below */
+    }
+    vcoIndex = i + 1;
+
+    if (vcoIndex < 1 || vcoIndex > 53)
+    {
+        /* vco index out of range */
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX));
+        return MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX;
+    }
+
+    /* valid for all refclk frequencies */
+    vcoOutLvl = (vcoIndex <= 16) ? 13 : (vcoIndex > 16 && vcoIndex <= 44) ? 10 : 7;
+    vcoVaractor = (vcoIndex <= 16) ? 0 : (vcoIndex > 16 && vcoIndex <= 44) ? 1 : 3;
+    vcoBiasRef = (vcoIndex <= 7) ? 4 : (vcoIndex > 7 && vcoIndex <= 29) ? 6 : 7;
+    vcoBiasTcf = (vcoIndex <= 29) ? 1 : (vcoIndex > 29 && vcoIndex <= 44) ? 2 : 3;
+
+    vcoVaractorRef = (vcoIndex <= 16) ? 10 : (vcoIndex > 16 && vcoIndex <= 29) ? 11 : (vcoIndex > 29 && vcoIndex <= 32) ? 12 :
+                     (vcoIndex > 32 && vcoIndex <= 44) ? 14 : 12;
+
+    if ((scaledRefClk_kHz >= 40000) && (scaledRefClk_kHz < 53760))
+    { /* Settings designed for 46.08 MHz PLL REFCLK */
+        vcoCalOffset = (vcoIndex <= 2) ? 14 : (vcoIndex > 2 && vcoIndex <= 5) ? 13 : (vcoIndex > 5 && vcoIndex <= 13) ? 12 : (vcoIndex > 13 && vcoIndex <= 16) ? 11 : 15;
+
+        loopFilterIcp = icp_46p08[vcoIndex - 1];
+        loopFilterC2C1 = 0xF6; /* C2=0xF0 */
+        loopFilterR1C3 = 0xD5;
+        loopFilterR3 = 0x0E;
+    }
+    else if ((scaledRefClk_kHz >= 53760) && (scaledRefClk_kHz < 69120))
+    { /* Settings designed for 61.44 MHz PLL REFCLK */
+        vcoCalOffset = (vcoIndex <= 2) ? 14 : (vcoIndex > 2 && vcoIndex <= 5) ? 13 : (vcoIndex > 5 && vcoIndex <= 11) ? 12 : (vcoIndex > 11 && vcoIndex <= 16) ? 11 : 15;
+
+        loopFilterIcp = icp_61p44[vcoIndex - 1];
+        loopFilterC2C1 = 0xF6; /* C2=0xF0 */
+        loopFilterR1C3 = 0xD5;
+        loopFilterR3 = 0x0E;
+    }
+    else if ((scaledRefClk_kHz >= 69120) && (scaledRefClk_kHz <= 80000))
+    { /* Settings designed for 76.8 MHz PLL REFCLK */
+        vcoCalOffset = (vcoIndex <= 2) ? 14 : (vcoIndex > 2 && vcoIndex <= 5) ? 13 : (vcoIndex > 5 && vcoIndex <= 10) ? 12 : (vcoIndex > 10 && vcoIndex <= 16) ? 11 : 15;
+
+        loopFilterIcp = icp_76p8[vcoIndex - 1];
+        loopFilterC2C1 = (vcoIndex == 43) ? 0xF7 : 0xF6; /*C2=0xF0, C1=6 or 7 */
+        loopFilterR1C3 = 0xD5;
+        loopFilterR3 = 0x0E;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_INV_REFCLK, getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_INV_REFCLK));
+        return MYKONOS_ERR_SETRFPLL_INV_REFCLK; /* invalid ref clk */
+    }
+
+    /* Hold CLKPLL digital logic in reset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_4, 0x00);
+
+    /* Set reference clock scaler + HSdiv + VCOdiv */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, clockControl2);
+
+    /*Set VCO cal time */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_CAL_CONTROL, 0x02);
+
+    /* Write Synth Setting regs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_F_VCOTN_BYTE1, ((vcoCalOffset & 0x0F) << 3)); /* Set VCO Cal offset[3:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE1, (0xC0 | (vcoVaractor & 0x0F))); /* Init ALC[3:0], VCO varactor[3:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE2, (0x40 | (vcoOutLvl & 0x0F))); /* VCO output level */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE9, (((vcoBiasTcf & 0x03) << 3) | (vcoBiasRef & 0x07))); /* Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_CAL_REF, 0x30); /* Set VCO cal time (compare length) + Set VCO Cal Ref Tcf[2:0]=0 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL1, 0x70); /* Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL2, (vcoVaractorRef & 0x0F)); /* Set VCO Varactor Reference[3:0] */
+
+    /* Write Loop filter */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE3, (0x80 | (loopFilterIcp & 0x03F))); /* Set Loop Filter Icp[5:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE6, loopFilterC2C1); /* Set Loop Filter C2[3:0] and C1[3:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE7, loopFilterR1C3); /* Set Loop Filter R1[3:0] and C3[3:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_LF_R3, (loopFilterR3 & 0x0F)); /*Set Loop Filter R3[3:0] */
+
+    /* Calculate PLL integer and fractional words with integer math */
+    scaledRefClk_Hz = scaledRefClk_kHz * 1000;
+    hsDigClk_Hz = (((uint64_t)(device->clocks->clkPllVcoFreq_kHz) * 10000) / vcoDivTimes10) / hsDiv;
+    integerWord = (uint16_t)(hsDigClk_Hz / scaledRefClk_Hz);
+    fractionalRemainder = hsDigClk_Hz % scaledRefClk_Hz;
+
+    /* +1 >> 1 is rounding (add .5) */
+    fractionalWord = ((uint32_t)((((uint64_t)fractionalRemainder * 4177920) / (uint64_t)scaledRefClk_Hz) + 1) >> 1);
+
+    /* if fractionalWord rounded up and == PLL modulus, fix it */
+    if (fractionalWord == 2088960)
+    {
+        fractionalWord = 0;
+        integerWord = integerWord + 1;
+    }
+
+    if (fractionalWord > 0)
+    { /* in normal case, the fractional word should be zero and SDM bypassed */
+        CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLKPLL_INV_FRACWORD,
+                getMykonosErrorMessage(MYKONOS_ERR_SETCLKPLL_INV_FRACWORD));
+        /* down graded to warning, do not return error code */
+        //return MYKONOS_ERR_SETCLKPLL_INV_FRACWORD;
+        sdmSettings = 0x20;
+    }
+    else
+    {
+        /* Bypass SDM */
+        sdmSettings = 0xE0;
+    }
+
+    /* Set PLL fractional word[22:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0, (fractionalWord & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1, ((fractionalWord >> 8) & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2, ((fractionalWord >> 16) & 0x7F));
+
+    /* Write PLL integer word [7:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1, (sdmSettings | ((integerWord >> 8) & 0x7)));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0, (integerWord & 0xFF));
+
+    /* Release PLL from reset, and set start VCO cal bit to 0 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_4, 0x80);
+
+    /* Power up CLKPLL */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_0, 0x00);
+    CMB_wait_ms(200); /* Allow PLL time to power up */
+
+    /* Enable Charge pump cal after Charge Pump current set (Icp[5:0]) */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_BYTE5, 0x84);
+
+    /* Start VCO Cal */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_4, 0x81);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets the RF PLL local oscillator frequency (RF carrier frequency).
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the MYKONOS data structure containing settings
+ * \param pllName Name of the PLL to configure
+ * \param rfPllLoFrequency_Hz Desired RF LO frequency
+ *
+ * \return MYKONOS_ERR_OK Function completed successfully
+ * \return MYKONOS_ERR_SETRFPLL_ARMERROR ARM Command to set RF PLL frequency failed
+ */
+mykonosErr_t MYKONOS_setRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t rfPllLoFrequency_Hz)
+{
+    const uint8_t SETCMD_OPCODE = 0x0A;
+    const uint8_t SET_PLL_FREQUENCY = 0x63;
+
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armData[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    uint8_t extData[2] = {0, 0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+
+    armData[0] = (uint8_t)(rfPllLoFrequency_Hz & 0xFF);
+    armData[1] = (uint8_t)((rfPllLoFrequency_Hz >> 8) & 0xFF);
+    armData[2] = (uint8_t)((rfPllLoFrequency_Hz >> 16) & 0xFF);
+    armData[3] = (uint8_t)((rfPllLoFrequency_Hz >> 24) & 0xFF);
+    armData[4] = (uint8_t)((rfPllLoFrequency_Hz >> 32) & 0xFF);
+    armData[5] = (uint8_t)((rfPllLoFrequency_Hz >> 40) & 0xFF);
+    armData[6] = (uint8_t)((rfPllLoFrequency_Hz >> 48) & 0xFF);
+    armData[7] = (uint8_t)((rfPllLoFrequency_Hz >> 56) & 0xFF);
+
+    /* write 64-bit frequency to ARM memory */
+    retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 8);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    extData[0] = SET_PLL_FREQUENCY;
+
+    switch (pllName)
+    {
+        case RX_PLL:
+            extData[1] = 0x00;
+            break;
+        case TX_PLL:
+            extData[1] = 0x01;
+            break;
+        case SNIFFER_PLL:
+            extData[1] = 0x02;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_INV_PLLNAME,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_INV_PLLNAME));
+            return MYKONOS_ERR_SETRFPLL_INV_PLLNAME;
+        }
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, SETCMD_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, SETCMD_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_ARMERROR, getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_ARMERROR));
+            return MYKONOS_ERR_SETRFPLL_ARMERROR;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRFPLL_ARMERROR, getMykonosErrorMessage(MYKONOS_ERR_SETRFPLL_ARMERROR));
+        return MYKONOS_ERR_SETRFPLL_ARMERROR;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Gets the RF PLL local oscillator frequency (RF carrier frequency).
+ *
+ * This function is used to get the RF PLL's frequency.  It can get the RX PLL, TX PLL
+ * Sniffer PLL, and CLKPLL.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ * - device->clocks->deviceClock_kHz
+ *
+ * \param device is structure pointer to the MYKONOS data structure containing settings
+ * \param pllName Name of the PLL for which to read the frequency
+ * \param rfPllLoFrequency_Hz RF LO frequency currently set for the PLL specified
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV Invalid CLKPLL reference clock divider read from Mykonos device
+ * \retval MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV Invalid CLKPLL high speed clock divider read from Mykonos device
+ * \retval MYKONOS_ERR_GETRFPLL_INV_PLLNAME Invalid PLL name, can not get PLL frequency.  Use PLL name ENUM.
+ * \retval MYKONOS_ERR_GETRFPLL_ARMERROR ARM Command to get RF PLL frequency failed
+ * \retval MYKONOS_ERR_GETRFPLL_NULLPARAM rfPllLoFrequency_Hz function parameter pointer is NULL
+ */
+mykonosErr_t MYKONOS_getRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t *rfPllLoFrequency_Hz)
+{
+    const uint8_t RFPLL_LO_FREQUENCY = 0x63;
+
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armData[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    uint8_t extData[2] = {0, 0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    uint8_t getClkPllFrequency = 0;
+
+    uint32_t clkPllIntWord = 0;
+    uint32_t clkPllFracWord = 0;
+    uint8_t clkPllRefClkDiv = 0;
+    uint8_t hsDiv = 0;
+    uint8_t vcoDivTimes10 = 0;
+    uint8_t hsDivReg = 0;
+    uint8_t vcoDivReg = 0;
+    uint8_t clkPllIntWord7_0 = 0;
+    uint8_t clkPllIntWord10_8 = 0;
+    uint8_t clkPllFracWord7_0 = 0;
+    uint8_t clkPllFracWord15_8 = 0;
+    uint8_t clkPllFracWord22_16 = 0;
+    uint64_t refclk_Hz = 0;
+
+    extData[0] = RFPLL_LO_FREQUENCY;
+
+    switch (pllName)
+    {
+        case CLK_PLL:
+            getClkPllFrequency = 1;
+            break;
+        case RX_PLL:
+            extData[1] = 0x00;
+            break;
+        case TX_PLL:
+            extData[1] = 0x01;
+            break;
+        case SNIFFER_PLL:
+            extData[1] = 0x02;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_INV_PLLNAME,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_INV_PLLNAME));
+            return MYKONOS_ERR_GETRFPLL_INV_PLLNAME;
+        }
+    }
+
+    if (getClkPllFrequency > 0)
+    {
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, &hsDivReg, 0x0C, 2);
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, &vcoDivReg, 0x03, 0);
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_2, &clkPllRefClkDiv, 0x70, 4);
+
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0, &clkPllIntWord7_0);
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1, &clkPllIntWord10_8);
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0, &clkPllFracWord7_0);
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1, &clkPllFracWord15_8);
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2, &clkPllFracWord22_16);
+
+        clkPllIntWord = (((uint32_t)(clkPllIntWord10_8 & 0x7) << 8) | clkPllIntWord7_0);
+        clkPllFracWord = (((uint32_t)(clkPllFracWord22_16 & 0x7F) << 16) | ((uint32_t)(clkPllFracWord15_8) << 8) | clkPllFracWord7_0);
+
+        switch (clkPllRefClkDiv)
+        {
+            case 0:
+                refclk_Hz = (uint64_t)(device->clocks->deviceClock_kHz * 1000);
+                break;
+            case 1:
+                refclk_Hz = (uint64_t)((device->clocks->deviceClock_kHz * 1000) >> 1);
+                break; /* div 2 */
+            case 2:
+                refclk_Hz = (uint64_t)((device->clocks->deviceClock_kHz * 1000) >> 2);
+                break; /* div 4 */
+            case 3:
+                refclk_Hz = (uint64_t)((device->clocks->deviceClock_kHz * 1000) << 1);
+                break; /* times 2 */
+            default:
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV,
+                        getMykonosErrorMessage(MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV));
+                return MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV;
+            }
+        }
+
+        switch (vcoDivReg)
+        {
+            case 0:
+                vcoDivTimes10 = 10;
+                break;
+            case 1:
+                vcoDivTimes10 = 15;
+                break;
+            case 2:
+                vcoDivTimes10 = 20;
+                break;
+            case 3:
+                vcoDivTimes10 = 30;
+                break;
+        }
+
+        switch (hsDivReg)
+        {
+            case 0:
+                hsDiv = 4;
+                break;
+            case 1:
+                hsDiv = 5;
+                break;
+            default:
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV,
+                        getMykonosErrorMessage(MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV));
+                return MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV;
+            }
+        }
+
+        /* round to nearest Hz for fractional word (fractional modulus = 2088960) */
+        *rfPllLoFrequency_Hz = (uint64_t)(((refclk_Hz * clkPllIntWord) + (((refclk_Hz * clkPllFracWord / 1044480) + 1) >> 1)) * hsDiv * vcoDivTimes10 / 10);
+    }
+    else
+    {
+        retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+
+        timeoutMs = 1000;
+        retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            if (cmdStatusByte > 0)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_ARMERROR,
+                        getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_ARMERROR));
+                return MYKONOS_ERR_GETRFPLL_ARMERROR;
+            }
+
+            return retVal;
+        }
+
+        /* read 64-bit frequency from ARM memory */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 8, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_ARMERROR, getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_ARMERROR));
+            return MYKONOS_ERR_GETRFPLL_ARMERROR;
+        }
+
+        if (rfPllLoFrequency_Hz == NULL)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRFPLL_NULLPARAM,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETRFPLL_NULLPARAM));
+            return MYKONOS_ERR_GETRFPLL_NULLPARAM;
+        }
+
+        *rfPllLoFrequency_Hz = (uint64_t)((uint64_t)(armData[0])) | ((uint64_t)(armData[1]) << 8) | ((uint64_t)(armData[2]) << 16) | ((uint64_t)(armData[3]) << 24)
+                | ((uint64_t)(armData[4]) << 32) | ((uint64_t)(armData[5]) << 40) | ((uint64_t)(armData[6]) << 48) | ((uint64_t)(armData[7]) << 56);
+    }
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Checks if the PLLs are locked
+ *
+ * This function updates the pllLockStatus pointer with a lock status it per
+ * PLL.
+ * pllLockStatus[0] = CLKPLL Locked
+ * pllLockStatus[1] = RX_PLL Locked
+ * pllLockStatus[2] = TX_PLL Locked
+ * pllLockStatus[3] = SNIFFER_PLL Locked
+ * pllLockStatus[4] = CAL_PLL Locked
+ *
+ * \param device the Mykonos device data structure
+ * \param pllLockStatus Lock status bit per PLL
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_checkPllsLockStatus(mykonosDevice_t *device, uint8_t *pllLockStatus)
+{
+    uint8_t readData = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_checkPllsLockStatus()\n");
+#endif
+
+    if (pllLockStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM));
+        return MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM;
+    }
+
+    *pllLockStatus = 0;
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0);
+    *pllLockStatus = readData;
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0);
+    *pllLockStatus = *pllLockStatus | (readData << 1);
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0);
+    *pllLockStatus = *pllLockStatus | (readData << 2);
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1, &readData, 0x01, 0);
+    *pllLockStatus = *pllLockStatus | (readData << 3);
+
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CALPLL_SDM_CONTROL, &readData, 0x80, 7);
+    *pllLockStatus = *pllLockStatus | (readData << 4);
+
+    return MYKONOS_ERR_OK;
+}
+
+/*
+ *****************************************************************************
+ * Shared Data path functions
+ *****************************************************************************
+ */
+
+/**
+ * \brief Sets the digital Tx PFIR SYNC clock divider.
+ *
+ * This function is a helper function.  It is called automatically in
+ * MYKONOS_initialize() and should not need to be called by the BBIC.
+ *
+ * This function sets the digital clock divider that is used to synchronize the
+ * Tx PFIR each time the Tx channel power up.  The Sync clock must
+ * be set equal to or slower than the FIR processing clock.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->txProfile->txFir
+ * - device->tx->txProfile->txFir->numFirCoefs
+ * - device->tx->txProfile->txFirInterpolation
+ * - device->tx->txProfile->iqRate_kHz
+ *
+ * \param device Pointer to the Mykonos data structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM: Invalid number of Tx FIR coefficients
+ * \retval MYKONOS_ERR_TXFIR_INV_NUMROWS Invalid number of PFIR coefficient rows
+ * \retval MYKONOS_ERR_TXFIR_TAPSEXCEEDED Too many Tx PFIR taps for the IQ sample rate.  FIR processing clock can not run fast enough to handle the number of taps
+ */
+mykonosErr_t MYKONOS_setTxPfirSyncClk(mykonosDevice_t *device)
+{
+    const uint8_t numTapMultiple = 16;
+    const uint8_t maxNumTaps = 96;
+    uint8_t effectiveRows = 0;
+    uint8_t numRows = 0;
+    uint32_t dpClk_kHz = 0;
+    uint32_t syncClk_kHz = 0;
+    uint32_t hsDigClkDiv4or5_kHz = 0;
+    uint8_t syncDiv = 0;
+
+    if (((device->profilesValid & TX_PROFILE_VALID) > 0) && (device->tx->txProfile->txFir != NULL))
+    {
+        /* Calculate number of FIR rows for number of Taps */
+        if ((device->tx->txProfile->txFir->numFirCoefs % numTapMultiple == 0) && (device->tx->txProfile->txFir->numFirCoefs > 0)
+                && (device->tx->txProfile->txFir->numFirCoefs <= maxNumTaps))
+        {
+            numRows = (device->tx->txProfile->txFir->numFirCoefs / numTapMultiple);
+        }
+        else
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM));
+            return MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM;
+        }
+
+        effectiveRows = ((numRows + (device->tx->txProfile->txFirInterpolation - 1)) / device->tx->txProfile->txFirInterpolation);
+
+        /* round up to next power of 2 */
+        switch (effectiveRows)
+        {
+            case 1:
+                effectiveRows = 1;
+                break;
+            case 2:
+                effectiveRows = 2;
+                break;
+            case 3: /* fall through */
+            case 4:
+                effectiveRows = 4;
+                break;
+            case 5: /* fall through */
+            case 6: /* fall through */
+            case 7: /* fall through */
+            case 8:
+                effectiveRows = 8;
+                break;
+            default:
+            {
+                /* invalid number of FIR taps */
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_NUMROWS,
+                        getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_NUMROWS));
+                return MYKONOS_ERR_TXFIR_INV_NUMROWS;
+            }
+        }
+
+        dpClk_kHz = (device->tx->txProfile->iqRate_kHz * device->tx->txProfile->txInputHbInterpolation * device->tx->txProfile->txFirInterpolation * effectiveRows);
+
+        /* FIR DPCLK can only run at max of 500MHz */
+        if (dpClk_kHz > 500000)
+        {
+            /* Max number of Tx PFIR taps exceeded for Tx Profile */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_TAPSEXCEEDED,
+                    getMykonosErrorMessage(MYKONOS_ERR_TXFIR_TAPSEXCEEDED));
+            return MYKONOS_ERR_TXFIR_TAPSEXCEEDED;
+        }
+
+        /* SYNC CLOCK is the PFIR output rate / 2 */
+        syncClk_kHz = device->tx->txProfile->iqRate_kHz * device->tx->txProfile->txFirInterpolation / 2;
+        MYKONOS_calculateDigitalClocks(device, NULL, &hsDigClkDiv4or5_kHz);
+
+        /* Select correct divider setting for SYNCCLK - must be == syncClk_kHz or slower */
+        for (syncDiv = 0; syncDiv < 5; syncDiv++)
+        {
+            if ((hsDigClkDiv4or5_kHz / (4 << syncDiv)) <= syncClk_kHz)
+            {
+                break;
+            }
+        }
+
+        /* Write Tx PFIR SYNC Clock divider */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_5, syncDiv, 0x70, 4);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets the digital Rx PFIR SYNC clock divider.
+ *
+ * This function is a helper function.  It is called automatically in
+ * MYKONOS_initialize() and should not need to be called by the BBIC.
+ *
+ * This function sets the digital clock divider that is used to synchronize the
+ * Rx/ORx/Sniffer PFIRs each time the channels power up.  The Sync clock must
+ * be set equal to or slower than the slowest Rx/ORx/Sniffer PFIR processing
+ * clock.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->rx->rxProfile->rxFir
+ * - device->rx->rxProfile->rxFir->numFirCoefs
+ * - device->rx->rxProfile->iqRate_kHz
+ * - device->obsRx->orxProfile->rxFir
+ * - device->obsRx->orxProfile->rxFir->numFirCoefs
+ * - device->obsRx->orxProfile->iqRate_kHz
+ * - device->obsRx->snifferProfile->rxFir
+ * - device->obsRx->snifferProfile->rxFir->numFirCoefs
+ * - device->obsRx->snifferProfile->iqRate_kHz
+ *
+ * \param device Pointer to the Mykonos data structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_RXFIR_TAPSEXCEEDED ERROR: the number of Rx FIR taps exceeds the number of taps accommodated by the FIR processing clock
+ * \retval MYKONOS_ERR_ORXFIR_TAPSEXCEEDED ERROR: the number of ORx FIR Taps exceeds the number of taps accommodated by the FIR processing clock
+ * \retval MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED ERROR: the number of sniffer FIR taps exceeds the number of taps accommodated by the FIR processing clock
+ */
+mykonosErr_t MYKONOS_setRxPfirSyncClk(mykonosDevice_t *device)
+{
+    uint32_t rxDpClk_kHz = 0;
+    uint32_t orxDpClk_kHz = 0;
+    uint32_t snRxDpClk_kHz = 0;
+    uint32_t slowestIqRate_kHz = 0;
+    uint32_t syncClk_kHz = 0;
+    uint8_t effectiveRxNumRows = 0;
+    uint8_t effectiveOrxNumRows = 0;
+    uint8_t effectiveSnrxNumRows = 0;
+
+    uint32_t hsDigClkDiv4or5_kHz = 0;
+    uint8_t syncDiv = 0;
+
+    /**
+     * Calculate Rx SYNC Clock divider for Rx PFIR.  Same Rx SYNC Clock is used
+     * for Rx, ORx, and Sniffer PFIRs, and must be slow enough to handle the slowest
+     * PFIR rate.
+     **/
+
+    if (((device->profilesValid & RX_PROFILE_VALID) > 0) && (device->rx->rxProfile->rxFir != NULL))
+    {
+        switch (device->rx->rxProfile->rxFir->numFirCoefs)
+        {
+            case 24:
+                effectiveRxNumRows = 1;
+                break;
+            case 48:
+                effectiveRxNumRows = 2;
+                break;
+            case 72:
+                effectiveRxNumRows = 4;
+                break;
+        }
+
+        rxDpClk_kHz = device->rx->rxProfile->iqRate_kHz * effectiveRxNumRows;
+
+        if (rxDpClk_kHz > 500000)
+        {
+            /* Max number of Rx PFIR taps exceeded for Profile */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFIR_TAPSEXCEEDED,
+                    getMykonosErrorMessage(MYKONOS_ERR_RXFIR_TAPSEXCEEDED));
+            return MYKONOS_ERR_RXFIR_TAPSEXCEEDED;
+        }
+
+        slowestIqRate_kHz = device->rx->rxProfile->iqRate_kHz;
+    }
+
+    if (((device->profilesValid & ORX_PROFILE_VALID) > 0) && (device->obsRx->orxProfile->rxFir != NULL))
+    {
+        switch (device->obsRx->orxProfile->rxFir->numFirCoefs)
+        {
+            case 24:
+                effectiveOrxNumRows = 1;
+                break;
+            case 48:
+                effectiveOrxNumRows = 2;
+                break;
+            case 72:
+                effectiveOrxNumRows = 4;
+                break;
+        }
+
+        orxDpClk_kHz = device->obsRx->orxProfile->iqRate_kHz * effectiveOrxNumRows;
+
+        if (orxDpClk_kHz > 500000)
+        {
+            /* Max number of ORx PFIR taps exceeded for Profile */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ORXFIR_TAPSEXCEEDED,
+                    getMykonosErrorMessage(MYKONOS_ERR_ORXFIR_TAPSEXCEEDED));
+            return MYKONOS_ERR_ORXFIR_TAPSEXCEEDED;
+        }
+
+        if ((slowestIqRate_kHz == 0) || (slowestIqRate_kHz > device->obsRx->orxProfile->iqRate_kHz))
+        {
+            slowestIqRate_kHz = device->obsRx->orxProfile->iqRate_kHz;
+
+        }
+    }
+
+    if (((device->profilesValid & SNIFF_PROFILE_VALID) > 0) && (device->obsRx->snifferProfile->rxFir != NULL))
+    {
+        switch (device->obsRx->snifferProfile->rxFir->numFirCoefs)
+        {
+            case 24:
+                effectiveSnrxNumRows = 1;
+                break;
+            case 48:
+                effectiveSnrxNumRows = 2;
+                break;
+            case 72:
+                effectiveSnrxNumRows = 4;
+                break;
+        }
+
+        snRxDpClk_kHz = device->obsRx->snifferProfile->iqRate_kHz * effectiveSnrxNumRows;
+
+        if (snRxDpClk_kHz > 500000)
+        {
+            /* Max number of ORx PFIR taps exceeded for Profile */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED,
+                    getMykonosErrorMessage(MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED));
+            return MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED;
+        }
+
+        if ((slowestIqRate_kHz == 0) || (slowestIqRate_kHz > device->obsRx->snifferProfile->iqRate_kHz))
+        {
+            slowestIqRate_kHz = device->obsRx->snifferProfile->iqRate_kHz;
+        }
+    }
+
+    /* SYNC CLOCK should be FIR output rate / 2 */
+    syncClk_kHz = (slowestIqRate_kHz / 2);
+    MYKONOS_calculateDigitalClocks(device, NULL, &hsDigClkDiv4or5_kHz);
+
+    /* Select correct divider setting for SYNCCLK - must be == syncClk_kHz or slower */
+    for (syncDiv = 0; syncDiv < 5; syncDiv++)
+    {
+        if ((hsDigClkDiv4or5_kHz / (4 << syncDiv)) <= syncClk_kHz)
+        {
+            break;
+        }
+    }
+
+    /* Write Rx PFIR SYNC Clock divider */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_5, syncDiv, 0x07, 0);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Configures one or more FIR filters in the device
+ *
+ * The device stores up to 6 FIR filters (2Rx, 2Obs Rx/Sniffer, and 2Tx).
+ * Rx filters can have 24, 48, or 72 taps.  Tx filters can have 16, 32,
+ * 48, 64, 80, or 96 taps.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param filterToProgram Name of the desired filter to program
+ * \param firFilter Pointer to the filter to write into the device
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_PROGRAMFIR_NULL_PARM ERROR: firFilter parameter is a NULL pointer
+ * \retval MYKONOS_ERR_PROGRAMFIR_COEFS_NULL ERROR: firFilter->coefs is a NULL pointer
+ * \retval MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM ERROR: Invalid FIR filter name in filterToProgram parameter
+ * \retval MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM ERROR: Invalid number of taps for the filter
+ * \retval MYKONOS_ERR_RXFIR_INV_GAIN_PARM ERROR: Rx FIR filter has invalid gain setting
+ * \retval MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM ERROR: OBSRX_A (ORX) FIR filter has invalid gain setting
+ * \retval MYKONOS_ERR_SRXFIR_INV_GAIN_PARM ERROR: OBSRX_B (Sniffer) FIR filter has invalid gain setting
+ * \retval MYKONOS_ERR_TXFIR_INV_GAIN_PARM ERROR: Tx FIR filter has invalid gain setting
+ */
+mykonosErr_t MYKONOS_programFir(mykonosDevice_t *device, mykonosfirName_t filterToProgram, mykonosFir_t *firFilter)
+{
+    uint8_t filterSelect = 0;
+    uint8_t i = 0;
+    uint8_t numTapsReg = 0;
+    uint8_t numTapMultiple = 24; /* Rx=24, Tx=16 */
+    uint8_t maxNumTaps = 72; /* Rx=72, Tx=96 */
+    uint8_t filterGain = 0;
+
+#if MYK_ENABLE_SPIWRITEARRAY == 1
+    uint32_t addrIndex = 0;
+    uint32_t dataIndex = 0;
+    uint32_t spiBufferSize = ((MYK_SPIWRITEARRAY_BUFFERSIZE / 6) * 6); /* Make buffer size a multiple of 6 */
+    uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0};
+    uint8_t dataArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0};
+#endif
+
+    const uint8_t COEF_WRITE_EN = 0x40;
+    const uint8_t PROGRAM_CLK_EN = 0x80;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_programFir()\n");
+#endif
+
+    if (firFilter == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_NULL_PARM));
+        return MYKONOS_ERR_PROGRAMFIR_NULL_PARM;
+    }
+
+    if (firFilter->coefs == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_COEFS_NULL,
+                getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_COEFS_NULL));
+        return MYKONOS_ERR_PROGRAMFIR_COEFS_NULL;
+    }
+
+    switch (filterToProgram)
+    {
+        case TX1_FIR:
+            filterSelect = 0x01;
+            numTapMultiple = 16;
+            maxNumTaps = 96;
+            break;
+        case TX2_FIR:
+            filterSelect = 0x02;
+            numTapMultiple = 16;
+            maxNumTaps = 96;
+            break;
+        case TX1TX2_FIR:
+            filterSelect = 0x03;
+            numTapMultiple = 16;
+            maxNumTaps = 96;
+            break;
+        case RX1_FIR:
+            filterSelect = 0x04;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case RX2_FIR:
+            filterSelect = 0x08;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case RX1RX2_FIR:
+            filterSelect = 0x0C;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case OBSRX_A_FIR:
+            filterSelect = 0x10;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case OBSRX_B_FIR:
+            filterSelect = 0x20;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM));
+            return MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM;
+    }
+
+    /* Calculate register value for number of Taps */
+    if ((firFilter->numFirCoefs % numTapMultiple == 0) && (firFilter->numFirCoefs > 0) && (firFilter->numFirCoefs <= maxNumTaps))
+    {
+        numTapsReg = (firFilter->numFirCoefs / numTapMultiple) - 1;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM));
+        return MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM;
+    }
+
+    /* Select which FIR filter to program coeffs for */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect)); //select filter and enable the programming clock
+
+#if (MYK_ENABLE_SPIWRITEARRAY == 0)
+
+    /* write filter coefficients */
+    for (i = 0; i < firFilter->numFirCoefs; i++)
+    {
+        /* Write Low byte of 16bit coefficient */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, (i * 2));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, (firFilter->coefs[i] & 0xFF));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect)); /* write enable (self clearing) */
+
+        /* Write High Byte of 16bit coefficient */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, ((i * 2) + 1));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, ((firFilter->coefs[i] >> 8) & 0xFF));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect));/* write enable (self clearing) */
+    }
+
+#elif (MYK_ENABLE_SPIWRITEARRAY == 1)
+
+    addrIndex = 0;
+    dataIndex = 0;
+    for (i = 0; i < firFilter->numFirCoefs; i++)
+    {
+        addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_ADDR;
+        addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_DATA;
+        addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_CTL;
+        addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_ADDR;
+        addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_DATA;
+        addrArray[addrIndex++] = MYKONOS_ADDR_PFIR_COEFF_CTL;
+
+        dataArray[dataIndex++] = (i * 2);
+        dataArray[dataIndex++] = (firFilter->coefs[i] & 0xFF);
+        dataArray[dataIndex++] = (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect);
+        dataArray[dataIndex++] = ((i * 2) + 1);
+        dataArray[dataIndex++] = ((firFilter->coefs[i] >> 8) & 0xFF);
+        dataArray[dataIndex++] = (PROGRAM_CLK_EN | COEF_WRITE_EN | filterSelect);
+
+        /* Send full buffer size when possible */
+        /* spiBufferSize set to multiple of 6 at top of function */
+        if (addrIndex >= spiBufferSize)
+        {
+            CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex);
+            dataIndex = 0;
+            addrIndex = 0;
+        }
+    }
+
+    if (addrIndex > 0)
+    {
+        CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex);
+    }
+
+#endif
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, filterSelect); /* clear Program clock enable */
+    /* write filter gain and #taps */
+    if (filterToProgram == RX1_FIR || filterToProgram == RX2_FIR || filterToProgram == RX1RX2_FIR)
+    {
+        /* Write Rx FIR #taps */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, numTapsReg, 0x60, 5);
+
+        /* Set Rx filter gain */
+        switch (firFilter->gain_dB)
+        {
+            case -12:
+                filterGain = 0x00;
+                break;
+            case -6:
+                filterGain = 0x01;
+                break;
+            case 0:
+                filterGain = 0x02;
+                break;
+            case 6:
+                filterGain = 0x03;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_RXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_RXFIR_INV_GAIN_PARM;
+        }
+
+        /* Write Rx filter gain */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_GAIN, filterGain, 0x03, 0);
+    }
+    else if (filterToProgram == OBSRX_A_FIR)
+    {
+        /* Write Obs Rx FIR A #taps */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, numTapsReg, 0x06, 1);
+
+        /* Set Rx filter gain */
+        switch (firFilter->gain_dB)
+        {
+            case -12:
+                filterGain = 0x00;
+                break;
+            case -6:
+                filterGain = 0x01;
+                break;
+            case 0:
+                filterGain = 0x02;
+                break;
+            case 6:
+                filterGain = 0x03;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM;
+        }
+
+        /* Write Obs Rx filter gain */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, filterGain, 0x03, 0);
+    }
+    else if (filterToProgram == OBSRX_B_FIR)
+    {
+        /* Write Obs Rx FIR B #taps */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, numTapsReg, 0x18, 3);
+
+        /* Set Rx filter gain */
+        switch (firFilter->gain_dB)
+        {
+            case -12:
+                filterGain = 0x00;
+                break;
+            case -6:
+                filterGain = 0x01;
+                break;
+            case 0:
+                filterGain = 0x02;
+                break;
+            case 6:
+                filterGain = 0x03;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SRXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_SRXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_SRXFIR_INV_GAIN_PARM;
+        }
+
+        /* Write Obs Rx filter gain */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, filterGain, 0x60, 5);
+    }
+    else if (filterToProgram == TX1_FIR || filterToProgram == TX2_FIR || filterToProgram == TX1TX2_FIR)
+    {
+        /* Write number of Taps */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, numTapsReg, 0xE0, 5);
+
+        switch (firFilter->gain_dB)
+        {
+            case 0:
+                filterGain = 0;
+                break;
+            case 6:
+                filterGain = 1;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_TXFIR_INV_GAIN_PARM;
+        }
+
+        /* Write Tx Filter gain */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, filterGain, 0x01, 0);
+
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the FIR filter programmed into the device
+ *
+ * The device stores up to 6 FIR filters (2Rx, 2Obs Rx/Sniffer, and 2Tx).
+ * Rx filters can have 24, 48, or 72 taps.  Tx filters can have 16, 32,
+ * 48, 64, 80, or 96 taps.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param filterToRead Name of the desired filter to be read
+ * \param firFilter Pointer to the filter to be read from the device
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READFIR_NULL_PARM ERROR: firFilter parameter is a NULL pointer
+ * \retval MYKONOS_ERR_READFIR_COEFS_NULL ERROR: firFilter->coefs is a NULL pointer
+ * \retval MYKONOS_ERR_READFIR_INV_FIRNAME_PARM ERROR: Invalid FIR filter name in filterToRead parameter
+ * \retval MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM ERROR: Invalid number of taps for the filter
+ * \retval MYKONOS_ERR_RXFIR_INV_GAIN_PARM ERROR: Rx FIR filter has invalid gain setting
+ * \retval MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM ERROR: OBSRX_A (ORX) FIR filter has invalid gain setting
+ * \retval MYKONOS_ERR_SRXFIR_INV_GAIN_PARM ERROR: OBSRX_B (Sniffer) FIR filter has invalid gain setting
+ * \retval MYKONOS_ERR_TXFIR_INV_GAIN_PARM ERROR: Tx FIR filter has invalid gain setting
+ */
+mykonosErr_t MYKONOS_readFir(mykonosDevice_t *device, mykonosfirName_t filterToRead, mykonosFir_t *firFilter)
+{
+    uint8_t filterSelect = 0;
+    uint8_t i = 0;
+    uint8_t numTapsReg = 0;
+    uint8_t numTapMultiple = 24;
+    uint8_t maxNumTaps = 72;
+    uint8_t filterGain = 0;
+    uint8_t msbRead = 0;
+    uint8_t lsbRead = 0;
+
+    const uint8_t PROGRAM_CLK_EN = 0x80;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readFir()\n");
+#endif
+
+    if (firFilter == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_NULL_PARM, getMykonosErrorMessage(MYKONOS_ERR_READFIR_NULL_PARM));
+        return MYKONOS_ERR_READFIR_NULL_PARM;
+    }
+
+    if (firFilter->coefs == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_COEFS_NULL, getMykonosErrorMessage(MYKONOS_ERR_READFIR_COEFS_NULL));
+        return MYKONOS_ERR_READFIR_COEFS_NULL;
+    }
+
+    switch (filterToRead)
+    {
+        case TX1_FIR:
+            filterSelect = 0x01;
+            numTapMultiple = 16;
+            maxNumTaps = 96;
+            break;
+        case TX2_FIR:
+            filterSelect = 0x02;
+            numTapMultiple = 16;
+            maxNumTaps = 96;
+            break;
+        case TX1TX2_FIR:
+            filterSelect = 0x03;
+            numTapMultiple = 16;
+            maxNumTaps = 96;
+            break;
+        case RX1_FIR:
+            filterSelect = 0x04;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case RX2_FIR:
+            filterSelect = 0x08;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case RX1RX2_FIR:
+            filterSelect = 0x0C;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case OBSRX_A_FIR:
+            filterSelect = 0x10;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        case OBSRX_B_FIR:
+            filterSelect = 0x20;
+            numTapMultiple = 24;
+            maxNumTaps = 72;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_INV_FIRNAME_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_READFIR_INV_FIRNAME_PARM));
+            return MYKONOS_ERR_READFIR_INV_FIRNAME_PARM;
+    }
+
+    /* clear Program clock enable */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, filterSelect);
+
+    /* Read filter gain and #taps */
+    if (filterToRead == RX1_FIR || filterToRead == RX2_FIR || filterToRead == RX1RX2_FIR)
+    {
+        /* Read Rx FIR #taps */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, &numTapsReg, 0x60, 5);
+
+        firFilter->numFirCoefs = (numTapsReg + 1) * numTapMultiple;
+
+        /* Read Rx filter gain */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_GAIN, &filterGain, 0x03, 0);
+
+        switch (filterGain)
+        {
+            case 0x00:
+                firFilter->gain_dB = -12;
+                break;
+            case 0x01:
+                firFilter->gain_dB = -6;
+                break;
+            case 0x02:
+                firFilter->gain_dB = 0;
+                break;
+            case 0x03:
+                firFilter->gain_dB = 6;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_RXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_RXFIR_INV_GAIN_PARM;
+        }
+    }
+    else if (filterToRead == OBSRX_A_FIR)
+    {
+        /* Read Obs Rx FIR A #taps */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, &numTapsReg, 0x60, 1);
+
+        firFilter->numFirCoefs = (numTapsReg + 1) * numTapMultiple;
+
+        /* Read Obs Rx FIR A gain */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, &filterGain, 0x03, 0);
+
+        switch (filterGain)
+        {
+            case 0x00:
+                firFilter->gain_dB = -12;
+                break;
+            case 0x01:
+                firFilter->gain_dB = -6;
+                break;
+            case 0x02:
+                firFilter->gain_dB = 0;
+                break;
+            case 0x03:
+                firFilter->gain_dB = 6;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM;
+        }
+    }
+    else if (filterToRead == OBSRX_B_FIR)
+    {
+        /* Read Obs Rx FIR B #taps */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_RX_FILTER_CONFIGURATION, &numTapsReg, 0x18, 3);
+
+        firFilter->numFirCoefs = (numTapsReg + 1) * numTapMultiple;
+
+        /* Read Obs Rx FIR B gain */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN, &filterGain, 0x60, 5);
+
+        switch (filterGain)
+        {
+            case 0x00:
+                firFilter->gain_dB = -12;
+                break;
+            case 0x01:
+                firFilter->gain_dB = -6;
+                break;
+            case 0x02:
+                firFilter->gain_dB = 0;
+                break;
+            case 0x03:
+                firFilter->gain_dB = 6;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SRXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_SRXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_SRXFIR_INV_GAIN_PARM;
+        }
+    }
+    else if (filterToRead == TX1_FIR || filterToRead == TX2_FIR || filterToRead == TX1TX2_FIR)
+    {
+        /* Read number of Taps */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, &numTapsReg, 0xE0, 5);
+
+        firFilter->numFirCoefs = (numTapsReg + 1) * numTapMultiple;
+
+        /* Read Tx Filter gain */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX_FILTER_CONFIGURATION, &filterGain, 0x01, 0);
+
+        switch (filterGain)
+        {
+            case 0:
+                firFilter->gain_dB = 0;
+                break;
+            case 1:
+                firFilter->gain_dB = 6;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TXFIR_INV_GAIN_PARM,
+                        getMykonosErrorMessage(MYKONOS_ERR_TXFIR_INV_GAIN_PARM));
+                return MYKONOS_ERR_TXFIR_INV_GAIN_PARM;
+        }
+    }
+
+    /* Select which FIR filter to read the coeffs for */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect)); //select filter and enable the programming clock
+
+    if (firFilter->numFirCoefs > maxNumTaps)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM));
+        return MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM;
+    }
+
+    /* write filter coefficients */
+    for (i = 0; i < firFilter->numFirCoefs; i++)
+    {
+        /* Write Low byte of 16bit coefficient */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, (i * 2));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect)); /* write enable (self clearing) */
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, &lsbRead);
+
+        /* Write High Byte of 16bit coefficient */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_ADDR, ((i * 2) + 1));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_CTL, (PROGRAM_CLK_EN | filterSelect));/* write enable (self clearing) */
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PFIR_COEFF_DATA, &msbRead);
+
+        firFilter->coefs[i] = (int16_t)((lsbRead & 0xFF) | ((msbRead << 8) & 0xFF00));
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/*
+ *****************************************************************************
+ * Rx Data path functions
+ *****************************************************************************
+ */
+/*!
+ * \brief Programs the gain table settings for either Rx1, Rx2, Rx1 + Rx2, ORx, or SnRx receiver types
+ *
+ * The gain table for a receiver type is set with the parameters passed by uint8_t gainTablePtr array.
+ * gainTablePtr is a 4 x n array, where there are four (4) elements per index, and the array
+ * length (n) is dependent upon receiver type. The (n) value is conveyed by numGainIndexesInTable.
+ * All gain tables have a maximum index of 255 when used with this function. The minimum gain index is
+ * application dependent.
+ *
+ * Where for Rx1, Rx2, and ObsRx:
+ * [A, B, C, D]: A = Front End Gain, B = External Control, C = Digital Attenuation/Gain, D = Attenuation/Gain select
+ *
+ * Where for SnRx:
+ * [A, B, C, D]: A = Front End Gain, B = LNA Bypass, C = Digital Attenuation/Gain, D = Attenuation/Gain select
+ *
+ * The gain table starting address changes with each receiver type. This function accounts for this change as well as the
+ * difference between byte [B] for {Rx1, Rx2, ObsRx} and SnRx receiver array values and programs the correct registers.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param gainTablePtr Pointer to 4 x n array containing gain table program values
+ * \param numGainIndexesInTable The number of 'n' indices in 4 x n array.  A range check is performed to ensure the maximum is not exceeded.
+ * \param rxChannel mykonosGainTable_t enum type to select either Rx1, Rx2, Rx1 + Rx2, ORx, or SnRx gain table for programming.  A
+ * channel check is performed to ensure a valid selection.
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK if successful, MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL if invalid channel is selected, MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE
+ * if numGainIndexesInTable exceeds range for selected receiver gain table
+ */
+mykonosErr_t MYKONOS_programRxGainTable(mykonosDevice_t *device, uint8_t *gainTablePtr, uint8_t numGainIndexesInTable, mykonosGainTable_t rxChannel)
+{
+    uint8_t ctlReg = 0;
+    uint8_t ch3CtlReg = 0;
+    uint16_t rxFEGainAddr = 0;
+    uint16_t rxExtCtlLnaAddr = 0;
+    uint16_t rxDigGainAttenAddr = 0;
+    uint16_t rx2FEGainAddr = 0;
+    uint16_t rx2ExtCtlAddr = 0;
+    uint16_t rx2DigGainAttenAddr = 0;
+    uint8_t minGainIndex = 0;
+    uint8_t startIndex = 0;
+    int16_t i = 0;
+    uint16_t tableRowIndex = 0;
+    uint8_t retFlag = 0;
+
+#if MYK_ENABLE_SPIWRITEARRAY
+    uint32_t addrIndex = 0;
+    uint32_t dataIndex = 0;
+    uint32_t spiBufferSize = (((MYK_SPIWRITEARRAY_BUFFERSIZE / 9) - 1) * 9);
+    uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0};
+    uint8_t dataArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0};
+#endif
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_programRxGainTable()\n");
+#endif
+
+    if (gainTablePtr == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM));
+        return MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM;
+    }
+
+    /* checking range of numGainIndexesInTable against maximums and for valid rxChannel selection */
+    switch (rxChannel)
+    {
+        case RX1_GT:
+            /* Rx1 max gain index = 255, check is out of range of uint8_t */
+            break;
+        case RX2_GT:
+            /* Rx1 max gain index = 255, check is out of range of uint8_t */
+            break;
+        case RX1_RX2_GT:
+            /* Rx1 max gain index = 255, check is out of range of uint8_t */
+            break;
+        case ORX_GT:
+            if (numGainIndexesInTable > MAX_ORX_GAIN_TABLE_NUMINDEXES)
+            {
+                retFlag = 1;
+            }
+            break;
+        case SNRX_GT:
+            if (numGainIndexesInTable > MAX_SNRX_GAIN_TABLE_NUMINDEXES)
+            {
+                retFlag = 1;
+            }
+            break;
+        case LOOPBACK_GT:
+            if (numGainIndexesInTable > MAX_LOOPBACK_GAIN_TABLE_NUMINDEXES)
+            {
+                retFlag = 1;
+            }
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL));
+            return MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL;
+    }
+
+    if (retFlag)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE,
+                getMykonosErrorMessage(MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE));
+        return MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE;
+    }
+    else
+    {
+        /* calculating minimum gain index value */
+        minGainIndex = MAX_GAIN_TABLE_INDEX - numGainIndexesInTable + 1;
+    }
+
+    /* forming control register words based on channel select, assigning starting index, and register addressing, also updating max and min gain table indices in structure */
+    switch (rxChannel)
+    {
+        case RX1_GT:
+            ctlReg = (rxChannel << 3) | 0x05;
+            startIndex = START_RX_GAIN_INDEX;
+            rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN;
+            rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL;
+            rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN;
+            device->rx->rxGainCtrl->rx1MaxGainIndex = MAX_GAIN_TABLE_INDEX;
+            device->rx->rxGainCtrl->rx1MinGainIndex = minGainIndex;
+            break;
+        case RX2_GT:
+            ctlReg = (rxChannel << 3) | 0x05;
+            startIndex = START_RX_GAIN_INDEX;
+            rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN;
+            rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL;
+            rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN;
+            device->rx->rxGainCtrl->rx2MaxGainIndex = MAX_GAIN_TABLE_INDEX;
+            device->rx->rxGainCtrl->rx2MinGainIndex = minGainIndex;
+            break;
+        case RX1_RX2_GT:
+            ctlReg = (rxChannel << 3) | 0x05;
+            startIndex = START_RX_GAIN_INDEX;
+            rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN;
+            rx2FEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN;
+            rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL;
+            rx2ExtCtlAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL;
+            rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN;
+            rx2DigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN;
+            device->rx->rxGainCtrl->rx1MaxGainIndex = MAX_GAIN_TABLE_INDEX;
+            device->rx->rxGainCtrl->rx1MinGainIndex = minGainIndex;
+            device->rx->rxGainCtrl->rx2MaxGainIndex = MAX_GAIN_TABLE_INDEX;
+            device->rx->rxGainCtrl->rx2MinGainIndex = minGainIndex;
+            break;
+        case ORX_GT:
+            ctlReg = 0x05;
+            ch3CtlReg = 0x08;
+            startIndex = START_ORX_GAIN_INDEX;
+            rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN;
+            rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB;
+            rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN;
+            device->obsRx->orxGainCtrl->maxGainIndex = MAX_GAIN_TABLE_INDEX;
+            device->obsRx->orxGainCtrl->minGainIndex = minGainIndex;
+            break;
+        case SNRX_GT:
+            ctlReg = 0x05;
+            ch3CtlReg = 0x00;
+            startIndex = START_SNRX_GAIN_INDEX;
+            rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN;
+            rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB;
+            rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN;
+            device->obsRx->snifferGainCtrl->maxGainIndex = MAX_GAIN_TABLE_INDEX;
+            device->obsRx->snifferGainCtrl->minGainIndex = minGainIndex;
+            break;
+        case LOOPBACK_GT: /* Loopback is only for ARM calibrations */
+            ctlReg = 0x05;
+            ch3CtlReg = 0x10;
+            startIndex = START_LOOPBACK_GAIN_INDEX;
+            rxFEGainAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN;
+            rxExtCtlLnaAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB;
+            rxDigGainAttenAddr = MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN;
+            break;
+    }
+
+    /* starting the gain table clock and read from gain table address bits */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg);
+
+    /* if ORx or Sniffer are selected also writing channel 3 readback bits for ObsRx or Sniffer selection */
+    if (rxChannel > RX1_RX2_GT)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg);
+    }
+
+    /* programming a table selected by rxChannel enum type */
+
+#if MYK_ENABLE_SPIWRITEARRAY == 0
+
+    for(i = startIndex; i >= ((startIndex + 1) - numGainIndexesInTable); i--)
+    {
+        tableRowIndex = (uint16_t)(startIndex - i) << 2;
+
+        /* set current gain table index (address) */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_ADDR, i);
+
+        /* Set Rx Front End gain[5:0] */
+        CMB_SPIWriteByte(device->spiSettings, rxFEGainAddr, gainTablePtr[tableRowIndex]);
+
+        /* Set external control [5:0] OR LNA bypass if rxChannel == SNRX_GT */
+        if (rxChannel == SNRX_GT)
+        {
+            CMB_SPIWriteByte(device->spiSettings, rxExtCtlLnaAddr, gainTablePtr[tableRowIndex + 1] << 4);
+        }
+        else
+        {
+            CMB_SPIWriteByte(device->spiSettings, rxExtCtlLnaAddr, gainTablePtr[tableRowIndex + 1]);
+        }
+
+        /* Set digital attenuation/gain[6:0] and set/clear attenuation bit */
+        CMB_SPIWriteByte(device->spiSettings, rxDigGainAttenAddr, (gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]);
+
+        /* repeating gain table settings if Rx1 and Rx2 are selected for Rx2 configuration */
+        if (rxChannel == RX1_RX2_GT)
+        {
+            /* Set Rx Front End gain[5:0] */
+            CMB_SPIWriteByte(device->spiSettings, rx2FEGainAddr, gainTablePtr[tableRowIndex]);
+
+            /* Set external control [5:0] */
+            CMB_SPIWriteByte(device->spiSettings, rx2ExtCtlAddr, gainTablePtr[tableRowIndex + 1]);
+
+            /* Set digital attenuation/gain[6:0] */
+            CMB_SPIWriteByte(device->spiSettings, rx2DigGainAttenAddr, (gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]);
+        }
+
+        /* setting the write enable depending on rxChannel choice */
+        if (rxChannel == ORX_GT)
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg | 0x02);
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02);
+        }
+        else if (rxChannel == SNRX_GT)
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg | 0x01);
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02);
+        }
+        else if (rxChannel == LOOPBACK_GT)
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, ch3CtlReg | 0x04);
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02);
+        }
+        else
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, ctlReg | 0x02);
+        }
+    }
+
+#elif MYK_ENABLE_SPIWRITEARRAY == 1
+//#elif 0
+
+    addrIndex = 0;
+    dataIndex = 0;
+    for (i = startIndex; i >= ((startIndex + 1) - numGainIndexesInTable); i--)
+    {
+        tableRowIndex = (uint16_t)(startIndex - (uint8_t)i) << 2;
+
+        /* set current gain table index (address) */
+        addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_ADDR;
+        dataArray[dataIndex++] = (uint8_t)i;
+
+        /* Set Rx Front End gain[5:0] */
+        addrArray[addrIndex++] = rxFEGainAddr;
+        dataArray[dataIndex++] = gainTablePtr[tableRowIndex];
+
+        /* Set external control [5:0] OR LNA bypass if rxChannel == SNRX_GT */
+        addrArray[addrIndex++] = rxExtCtlLnaAddr;
+        dataArray[dataIndex++] = (rxChannel == SNRX_GT) ? (gainTablePtr[tableRowIndex + 1] << 4) : (gainTablePtr[tableRowIndex + 1]);
+
+        /* Set digital attenuation/gain[6:0] and set/clear attenuation bit */
+        addrArray[addrIndex++] = rxDigGainAttenAddr;
+        dataArray[dataIndex++] = ((gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]);
+
+        /* repeating gain table settings if Rx1 and Rx2 are selected for Rx2 configuration */
+        if (rxChannel == RX1_RX2_GT)
+        {
+            /* Set Rx Front End gain[5:0] */
+            addrArray[addrIndex++] = rx2FEGainAddr;
+            dataArray[dataIndex++] = gainTablePtr[tableRowIndex];
+
+            /* Set external control [5:0] */
+            addrArray[addrIndex++] = rx2ExtCtlAddr;
+            dataArray[dataIndex++] = gainTablePtr[tableRowIndex + 1];
+
+            /* Set digital attenuation/gain[6:0] */
+            addrArray[addrIndex++] = rx2DigGainAttenAddr;
+            dataArray[dataIndex++] = ((gainTablePtr[tableRowIndex + 3] << 7) | gainTablePtr[tableRowIndex + 2]);
+        }
+
+        /* setting the write enable depending on rxChannel choice */
+        if (rxChannel == ORX_GT)
+        {
+            addrArray[addrIndex++] = MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ch3CtlReg | 0x02);
+            addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ctlReg | 0x02);
+        }
+        else if (rxChannel == SNRX_GT)
+        {
+            addrArray[addrIndex++] = MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ch3CtlReg | 0x01);
+            addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ctlReg | 0x02);
+        }
+        else if (rxChannel == LOOPBACK_GT)
+        {
+            addrArray[addrIndex++] = MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ch3CtlReg | 0x04);
+            addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ctlReg | 0x02);
+        }
+        else
+        {
+            addrArray[addrIndex++] = MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION;
+            dataArray[dataIndex++] = (ctlReg | 0x02);
+        }
+
+        if (addrIndex >= spiBufferSize)
+        {
+            CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex);
+            dataIndex = 0;
+            addrIndex = 0;
+        }
+    }
+
+    if (addrIndex > 0)
+    {
+        CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &dataArray[0], addrIndex);
+    }
+
+#endif
+
+    /* clearing the channel 3 gain table configuration register if selected and stopping the gain table clock */
+    if (rxChannel > RX1_RX2_GT)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION, 0x00);
+    }
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION, 0x08);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets the Rx1 Manual Gain Index
+ *
+ * If the value passed in the gainIndex parameter is within range of the gain table minimum and
+ * maximum indexes, the Rx1 gain index will be updated in the device data structure
+ * and written to the transceiver. Else, an error will be returned. The maximum index is 255
+ * and the minimum index is application specific.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->rxSettings->rxGainControl->rx1GainIndex
+ * - device->rxSettings->rxGainControl->rx1MaxGainIndex
+ * - device->rxSettings->rxGainControl->rx1MinGainIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param gainIndex Desired Rx1 gain index
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_setRx1ManualGain(mykonosDevice_t *device, uint8_t gainIndex)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx1ManualGain()\n");
+#endif
+
+    if ((gainIndex < device->rx->rxGainCtrl->rx1MinGainIndex) || (gainIndex > device->rx->rxGainCtrl->rx1MaxGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM));
+        return MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM;
+
+    }
+    else
+    {
+        /* If the desired gain index is in range of the gain table, update the
+         * value in the device data structure, and write to device.
+         */
+        device->rx->rxGainCtrl->rx1GainIndex = gainIndex;
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_1, gainIndex);
+
+        return MYKONOS_ERR_OK;
+    }
+}
+
+/**
+ * \brief Sets the Rx2 Manual Gain index
+ *
+ * If the value passed in the gainIndex parameter is within range of the gain table minimum and
+ * maximum indexes, the Rx2 gain index will be updated in the device data structure
+ * and written to the transceiver. Else, an error will be returned. The maximum index is 255
+ * and the minimum index is application specific.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->rxTxSettings->rxGainControl->rx2GainIndex
+ * - device->rxTxSettings->rxGainControl->rx2MaxGainIndex
+ * - device->rxTxSettings->rxGainControl->rx2MinGainIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param gainIndex Desired Rx2 gain index
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_setRx2ManualGain(mykonosDevice_t *device, uint8_t gainIndex)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx2ManualGain()\n");
+#endif
+
+    if ((gainIndex < device->rx->rxGainCtrl->rx2MinGainIndex) || (gainIndex > device->rx->rxGainCtrl->rx2MaxGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM));
+        return MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM;
+
+    }
+    else
+    {
+        /* If the desired gain index is in range of the gain table, update the
+         * value in the device data structure, and write to device.
+         */
+        device->rx->rxGainCtrl->rx2GainIndex = gainIndex;
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_2, gainIndex);
+
+        return MYKONOS_ERR_OK;
+    }
+}
+
+/**
+ * \brief Reads the Rx1 Gain Index for Manual or AGC gain control mode
+ *
+ * This function reads the Rx1 gain index for manual or AGC modes. If the
+ * *rx1GainIndex pointer is nonzero, the read back gain index will
+ * be returned in the parameter.  If the *rx1GainIndex pointer
+ * is NULL, the device data structure will be updated with the new read back value
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->rxTxSettings->rxGainControl->rx1GainIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param rx1GainIndex uint8_t Pointer to the Rx1 gain index value
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_getRx1Gain(mykonosDevice_t *device, uint8_t *rx1GainIndex)
+{
+    uint8_t readData;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx1Gain()\n");
+#endif
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GAIN_CTL_CHANNEL_1, &readData);
+
+    /*
+     * If rx1GainIndex address is not NULL, return the Rx1 gain index in the
+     * rx1GainIndex function parameter
+     */
+    if (rx1GainIndex != NULL)
+    {
+        *rx1GainIndex = readData;
+    }
+
+    /*
+     * set the current Rx1 gain in the device data structure
+     */
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        device->rx->rxGainCtrl->rx1GainIndex = readData;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the Rx2 Gain Index for Manual or AGC gain control mode
+ *
+ * This function reads the Rx2 gain index for manual or AGC modes. If the
+ * *rx1GainIndex pointer is nonzero, the read back gain index will
+ * be returned in the parameter.  If the *rx1GainIndex pointer
+ * is NULL, the device data structure will be updated with the new read back value
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->rxTxSettings->rxGainControl->rx2GainIndex
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param rx2GainIndex Desired Rx2 gain index
+ *
+ * \return Returns enum MYKONOS_ERR, MYKONOS_ERR_OK=pass, !MYKONOS_ERR_OK=fail
+ */
+mykonosErr_t MYKONOS_getRx2Gain(mykonosDevice_t *device, uint8_t *rx2GainIndex)
+{
+    uint8_t readData;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx2Gain()\n");
+#endif
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GAIN_CTL_CHANNEL_2, &readData);
+
+    /*
+     * If rx1GainIndex address is not NULL, return the Rx1 gain index in the
+     * rx1GainIndex function parameter
+     */
+    if (rx2GainIndex != NULL)
+    {
+        *rx2GainIndex = readData;
+    }
+
+    /*
+     * set the current Rx2 gain in the device data structure
+     */
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        device->rx->rxGainCtrl->rx2GainIndex = readData;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the device Rx Automatic Gain Control (AGC) registers.
+ *
+ * Three data structures (mykonosAgcCfg_t, mykonosPeakDetAgcCfg_t, mykonosPowerMeasAgcCfg_t)
+ * must be instantiated prior to calling this function. Valid ranges for data structure members
+ * must also be provided.
+ *
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->rx->rxAgcCtrl->agcRx1MaxGainIndex
+ * - device->rx->rxAgcCtrl->agcRx1MinGainIndex
+ * - device->rx->rxAgcCtrl->agcRx2MaxGainIndex
+ * - device->rx->rxAgcCtrl->agcRx2MinGainIndex
+ * - device->rx->rxAgcCtrl->agcObsRxMaxGainIndex
+ * - device->rx->rxAgcCtrl->agcObsRxMinGainIndex
+ * - device->rx->rxAgcCtrl->agcObsRxSelect
+ * - device->rx->rxAgcCtrl->agcPeakThresholdMode
+ * - device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease
+ * - device->rx->rxAgcCtrl->agcGainUpdateCounter
+ * - device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay
+ * - device->rx->rxAgcCtrl->agcPeakWaitTime
+ * - device->rx->rxAgcCtrl->agcResetOnRxEnable
+ * - device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter
+ * - device->rx->rxAgcCtrl->peakAgc->apdHighThresh
+ * - device->rx->rxAgcCtrl->peakAgc->apdLowThresh
+ * - device->rx->rxAgcCtrl->peakAgc->hb2HighThresh
+ * - device->rx->rxAgcCtrl->peakAgc->hb2LowThresh
+ * - device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh
+ * - device->rx->rxAgcCtrl->peakAgc->apdHighThreshExceededCnt
+ * - device->rx->rxAgcCtrl->peakAgc->apdLowThreshExceededCnt
+ * - device->rx->rxAgcCtrl->peakAgc->hb2HighThreshExceededCnt
+ * - device->rx->rxAgcCtrl->peakAgc->hb2LowThreshExceededCnt
+ * - device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt
+ * - device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack
+ * - device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery
+ * - device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack
+ * - device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery
+ * - device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery
+ * - device->rx->rxAgcCtrl->peakAgc->apdFastAttack
+ * - device->rx->rxAgcCtrl->peakAgc->hb2FastAttack
+ * - device->rx->rxAgcCtrl->peakAgc->hb2OverloadDetectEnable
+ * - device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt
+ * - device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt
+ * - device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh
+ * - device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh
+ * - device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh
+ * - device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh
+ * - device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack
+ * - device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack
+ * - device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery
+ * - device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery
+ * - device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration
+ * - device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * The pointer to the Mykonos AGC data structure containing settings is checked for a null pointer
+ * to ensure it has been initialized. If not an error is thrown.
+ *
+ * \retval Returns MYKONOS_ERR=pass, !MYKONOS_ERR=fail
+ * \retval MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT
+ * \retval MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT
+ * \retval MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT
+ * \retval MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX
+ * \retval MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX
+ * \retval MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX
+ * \retval MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX
+ * \retval MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY
+ * \retval MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION
+ * \retval MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG
+ * \retval MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC
+ * \retval MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE
+ * \retval MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE
+ * \retval MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE
+ * \retval MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT
+ * \retval MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT
+ */
+mykonosErr_t MYKONOS_setupRxAgc(mykonosDevice_t *device)
+{
+    uint8_t decPowerConfig = 0;
+    uint8_t lower1ThreshGainStepRegValue = 0;
+    uint8_t powerThresholdsRegValue = 0;
+    uint8_t hb2OvldCfgRegValue = 0;
+    uint8_t agcGainUpdateCtr[3] = {0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxAgc()\n");
+#endif
+
+    /* Check mykonosAgcCfg_t device->rx->rxAgcCtrl pointer for initialization */
+    if (&device->rx->rxAgcCtrl == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT));
+        return MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT;
+    }
+
+    /* Check mykonosPeakDetAgcCfg_t device->rx->rxAgcCtrl->peakAgc pointer for initialization */
+    if (&device->rx->rxAgcCtrl->peakAgc == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT));
+        return MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT;
+    }
+
+    /* Check mykonosPowerMeasAgcCfg_t device->rx->rxAgcCtrl->powerAgc pointer for initialization */
+    if (&device->rx->rxAgcCtrl->powerAgc == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT));
+        return MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT;
+    }
+
+    /* Range check agcRx1MaxGainIndex versus gain table limits */
+    if ((device->rx->rxAgcCtrl->agcRx1MaxGainIndex > device->rx->rxGainCtrl->rx1MaxGainIndex)
+            || (device->rx->rxAgcCtrl->agcRx1MaxGainIndex < device->rx->rxAgcCtrl->agcRx1MinGainIndex))
+
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX));
+        return MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx1MaxGainIndex);
+    }
+
+    /* Range check agcRx1MinGainIndex versus gain table limits */
+    if ((device->rx->rxAgcCtrl->agcRx1MinGainIndex < device->rx->rxGainCtrl->rx1MinGainIndex)
+            || (device->rx->rxAgcCtrl->agcRx1MaxGainIndex < device->rx->rxAgcCtrl->agcRx1MinGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX));
+        return MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx1MinGainIndex);
+    }
+
+    /* Range check agcRx2MaxGainIndex versus gain table limits */
+    if ((device->rx->rxAgcCtrl->agcRx2MaxGainIndex > device->rx->rxGainCtrl->rx2MaxGainIndex)
+            || (device->rx->rxAgcCtrl->agcRx2MaxGainIndex < device->rx->rxAgcCtrl->agcRx2MinGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX));
+        return MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx2MaxGainIndex);
+    }
+
+    /* Range check agcRx2MinGainIndex versus gain table limits */
+    if ((device->rx->rxAgcCtrl->agcRx2MinGainIndex < device->rx->rxGainCtrl->rx2MinGainIndex)
+            || (device->rx->rxAgcCtrl->agcRx2MaxGainIndex < device->rx->rxAgcCtrl->agcRx2MinGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX));
+        return MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX, device->rx->rxAgcCtrl->agcRx2MinGainIndex);
+    }
+
+    /* Range check for agcGainUpdateCounter (22-bit) */
+    if ((device->rx->rxAgcCtrl->agcGainUpdateCounter > 0x3FFFFF) || (device->rx->rxAgcCtrl->agcGainUpdateCounter < 1))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM;
+    }
+    else
+    {
+        /* Split agcGainUpdateCounter into three values */
+        agcGainUpdateCtr[0] = (uint8_t)(device->rx->rxAgcCtrl->agcGainUpdateCounter);
+        agcGainUpdateCtr[1] = (uint8_t)(device->rx->rxAgcCtrl->agcGainUpdateCounter >> 8);
+        agcGainUpdateCtr[2] = (uint8_t)(device->rx->rxAgcCtrl->agcGainUpdateCounter >> 16);
+
+        /* Write two bytes directly due. Third word has its upper two bits masked off.  */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_1, agcGainUpdateCtr[0]);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_2, agcGainUpdateCtr[1]);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3, agcGainUpdateCtr[2], 0x3F, 0);
+    }
+
+    /* Range check on agcPeakWaitTime (5-bit) */
+    if (device->rx->rxAgcCtrl->agcPeakWaitTime > 0x1F || device->rx->rxAgcCtrl->agcPeakWaitTime < 0x02)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM;
+    }
+    else
+    {
+        /* Write agcPeakWaitTime */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, device->rx->rxAgcCtrl->agcPeakWaitTime, 0x1F, 0);
+    }
+
+    /* Set MYKONOS_ADDR_AGC_CFG_2 bits [6:5] = b11 to enable AGC counters for MGC mode - needed for ARM cals to work correctly */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, 3, 0x60, 5);
+
+    /* Range check for agcSlowLoopSettlingDelay (7-bit) */
+    if (device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay > 0x7F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY));
+        return MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY;
+    }
+    else
+    {
+        /* Write agcSlowLoopSettlingDelay */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOOP_CFG, device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay, 0x7F, 0);
+    }
+
+    /* Range check for pmdMeasDuration */
+    if ((1 << (3 + device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration)) >= (device->rx->rxAgcCtrl->agcGainUpdateCounter))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION));
+        return MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION;
+    }
+    else
+    {
+        /* Write pmdMeasDuration */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_DEC_POWER_CONFIG_2, device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration, 0x0F, 0);
+    }
+
+    /* Range check for pmdMeasConfig */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig > 0x3)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG));
+        return MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG;
+    }
+    else
+    {
+        if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 0)
+        {
+            decPowerConfig = 0x0; /* Dec Pwr measurement disable */
+        }
+        else if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 1)
+        {
+            decPowerConfig = 0x3; /* Dec Pwr measurement enable,  HB2 for decPwr measurement */
+        }
+        else if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 2)
+        {
+            decPowerConfig = 0x5; /* Dec Pwr measurement enable, RFIR for decPwr measurement */
+        }
+        else if (device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig == 3)
+        {
+            decPowerConfig = 0x11; /* Dec Pwr measurement enable, BBDC2 for decPwr measurement */
+        }
+        /* Write pmdMeasConfig */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_DEC_POWER_CONFIG_1, decPowerConfig);
+    }
+
+    /* Range check agcLowThsPreventGainIncrease (1-bit) */
+    if (device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC));
+        return MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC;
+    }
+    else
+    {
+        /* Write agcLowThsPreventGainIncrease */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH, device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease, 0x80, 7);
+    }
+
+    /* Range check agcPeakThresholdMode (1-bit),  */
+    if (device->rx->rxAgcCtrl->agcPeakThresholdMode > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE));
+        return MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE;
+    }
+    else
+    {
+        /* Save to lower1ThreshGainStepRegValue register variable */
+        lower1ThreshGainStepRegValue |= (device->rx->rxAgcCtrl->agcPeakThresholdMode << 5);
+    }
+
+    /* Range check agcResetOnRxEnable (1-bit) */
+    if (device->rx->rxAgcCtrl->agcResetOnRxEnable > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC));
+        return MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE;
+    }
+    else
+    {
+        /* Write agcResetOnRxEnable */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3, (device->rx->rxAgcCtrl->agcResetOnRxEnable << 7), 0x80, 0);
+    }
+
+    /* Range check agcEnableSyncPulseForGainCounter (1-bit) */
+    if (device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER));
+        return MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER;
+    }
+    else
+    {
+        /* Write agcEnableSyncPulseForGainCounter */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOOP_CFG, (device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter << 7), 0x80, 0);
+    }
+
+    /* WRITE REGISTERS FOR THE AGC POWER MEASUREMENT DETECTOR (PMD) STRUCTURE */
+
+    /* Range check pmdLowerHighThresh (7-bit) vs 0x7F and pmdUpperLowThresh */
+    if ((device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh <= device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh)
+            || device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh > 0x7F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH;
+    }
+    else
+    {
+        /* Write pmdLowerHighThresh */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH, device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh, 0x7F, 0);
+    }
+
+    /* Range check pmdUpperLowThresh (7-bit): Comparison to pmdLowerHigh done earlier */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh > 0x7F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH;
+    }
+    else
+    {
+        /* Write pmdUpperLowThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_LOCK_LEVEL, device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh);
+    }
+
+    /* Range check pmdLowerLowThresh (4-bit)  */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh > 0xF)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH;
+    }
+    else
+    {
+        /* Write pmdUpperLowThresh to temp variable */
+        powerThresholdsRegValue |= device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh;
+    }
+
+    /* Range check pmdUpperHighThresh (4-bit)  */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh > 0xF)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH;
+    }
+    else
+    {
+        /* Write pmdUpperHighThresh to temp var, then to register */
+        powerThresholdsRegValue |= (device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh << 4);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_POWER_THRSH, powerThresholdsRegValue);
+    }
+
+    /* Range check pmdUpperHighGainStepAttack (5-bit)  */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdUpperHighGainStepAttack */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_UPPER1_THRSH_GAIN_STEP, device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack, 0x1F, 0);
+    }
+
+    /* Range check pmdLowerLowGainStepRecovery (5-bit)  */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        lower1ThreshGainStepRegValue |= (device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery);
+    }
+
+    /* Range check pmdUpperLowGainStepRecovery (5-bit)  */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_UPPER0_THRSH_GAIN_STEP, device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack);
+    }
+
+    /* Range check pmdLowerHighGainStepRecovery (5-bit)  */
+    if (device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOWER0_THRSH_GAIN_STEP, device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery);
+    }
+
+    /* WRITE REGISTERS FOR THE AGC PEAK DETECTOR (APD/HB2) STRUCTURE */
+
+    /* Range check apdFastAttack and hb2FastAttack (1-bit)  */
+    if (device->rx->rxAgcCtrl->peakAgc->apdFastAttack > 0x1 || device->rx->rxAgcCtrl->peakAgc->hb2FastAttack > 0x1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE));
+        return MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        lower1ThreshGainStepRegValue |= (device->rx->rxAgcCtrl->peakAgc->apdFastAttack << 7);
+        lower1ThreshGainStepRegValue |= (device->rx->rxAgcCtrl->peakAgc->hb2FastAttack << 6);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOWER1_THRSH_GAIN_STEP, lower1ThreshGainStepRegValue);
+    }
+
+    /* Range check apdHighThresh */
+    if ((device->rx->rxAgcCtrl->peakAgc->apdHighThresh > 0x3F) || (device->rx->rxAgcCtrl->peakAgc->apdHighThresh <= device->rx->rxAgcCtrl->peakAgc->apdLowThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM;
+    }
+    else
+    {
+        /* Write apdHighThresh */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ULB_THRSH, device->rx->rxAgcCtrl->peakAgc->apdHighThresh, 0X3F, 0);
+    }
+
+    /* Range check apdLowThresh */
+    if ((device->rx->rxAgcCtrl->peakAgc->apdLowThresh > 0x3F) || (device->rx->rxAgcCtrl->peakAgc->apdHighThresh < device->rx->rxAgcCtrl->peakAgc->apdLowThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM;
+    }
+    else
+    {
+        /* write apdLowThresh */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_LLB_THRSH, device->rx->rxAgcCtrl->peakAgc->apdLowThresh, 0x3F, 0);
+    }
+
+    /* Range check hb2HighThresh */
+    if ((device->rx->rxAgcCtrl->peakAgc->hb2HighThresh > 0xFF) || (device->rx->rxAgcCtrl->peakAgc->hb2HighThresh < device->rx->rxAgcCtrl->peakAgc->hb2LowThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM;
+    }
+    else
+    {
+        /* write hb2HighThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_UPPER_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2HighThresh);
+    }
+
+    /* Range check hb2LowThresh */
+    if ((device->rx->rxAgcCtrl->peakAgc->hb2LowThresh > 0xFF) || (device->rx->rxAgcCtrl->peakAgc->hb2LowThresh > device->rx->rxAgcCtrl->peakAgc->hb2HighThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM;
+    }
+    else
+    {
+        /* write hb2LowThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_LOWER_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2LowThresh);
+    }
+
+    /* Range check hb2VeryLowThresh */
+    if ((device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh > 0xFF) || (device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh > device->rx->rxAgcCtrl->peakAgc->hb2LowThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM;
+    }
+    else
+    {
+        /* write hb2VeryLowThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_VERYLOW_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh);
+    }
+
+    /* Write threshold counter values for apdHigh/apdLow/hb2High/hb2Low/hb2VeryLow */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ULB_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->apdHighThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LLB_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->apdLowThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_HIGH_OVRG_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2HighThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOW_OVRG_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2LowThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_VERYLOW_OVRG_CNT_THRSH, device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt);
+
+    /* Range check on apdHighGainStepAttack (5-bit) */
+    if (device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write apdHighGainStepAttack */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_1, device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack);
+    }
+
+    /* Range check on apdLowGainStepRecovery (5-bit) */
+    if (device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write apdLowGainStepRecovery */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_4, device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery);
+    }
+
+    /* Range check on hb2HighGainStepAttack (5-bit) */
+    if (device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write hb2HighGainStepAttack */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_2, device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack);
+    }
+
+    /* Range check on hb2LowGainStepRecovery (5-bit) */
+    if (device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write hb2LowGainStepRecovery */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_5, device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery);
+    }
+
+    /* Range check on hb2VeryLowGainStepRecovery (5-bit) */
+    if (device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write hb2VeryLowGainStepRecovery */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_6, device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery);
+    }
+
+    /* Range Check on hb2OverloadDetectEnable */
+    if (device->rx->rxAgcCtrl->peakAgc->hb2OverloadDetectEnable > 0x1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE;
+    }
+
+    /* Range Check on hb2OverloadDetectEnable */
+    if (device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt > 0x7)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT;
+    }
+
+    /* Range Check on hb2OverloadDetectEnable */
+    if (device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt > 0xF)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT));
+        return MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT;
+    }
+    else
+    {
+        /* Write the hb2OvldCfgRegValue, the combination of hb2OverloadThreshCnt, hb2OverloadDurationCnt, and hb2OverloadDetectEnable */
+        hb2OvldCfgRegValue = (device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt) | (device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt << 4)
+                | (device->rx->rxAgcCtrl->peakAgc->hb2OverloadDetectEnable << 7);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_CFG, hb2OvldCfgRegValue);
+    }
+
+    /* Hard-coded value for the ADC overload configuration. Sets the HB2 offset to -6dB.*/
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OVRLD_ADC_OVRLD_CFG, 0x18);
+    /* Hard-coded value for APD decay setting. Setting allows for the quickest settling time of peak detector */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX_BLOCK_DET_DECAY, 0x0);
+
+    /* performing a soft reset */
+    MYKONOS_resetRxAgc(device);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function resets the AGC state machine
+ *
+ * Calling this function resets all state machines within the gain control and maximum gain.
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_resetRxAgc(mykonosDevice_t *device)
+{
+    const uint8_t AGC_RESET = 0x80;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetRxAgc()\n");
+#endif
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, 1, AGC_RESET, 7);
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_CFG_2, 0, AGC_RESET, 7);
+
+    return MYKONOS_ERR_OK;
+
+}
+
+/**
+ * \brief This function sets the min/max gain indexes for AGC in the main RX channel
+ *
+ * Allows to change min/max gain index on runtime.
+ * If RX1_RX2 selected, then the maxGainIndex/minGainIndex value will be applied to both channels.
+ * If only Rx1 selected, then only Rx1 min/max gain indices will be updated, along with their device data structure values.
+ * If only Rx2 selected, then only Rx2 min/max gain indices will be updated, along with their device data structure values.
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ * - device->rx->rxAgcCtrl
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param rxChannelSelect RX channel for setting the max and min gain index settings
+ * \param maxGainIndex Max gain index setting
+ * \param minGainIndex Min gain index setting
+ *
+ * \retval MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX Max gain index bigger than max gain index loaded table.
+ * \retval MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX Min gain index lower than min gain index loaded table.
+ * \retval MYKONOS_ERR_AGC_MIN_MAX_CHANNEL Wrong RX channel selected
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosRxChannels_t rxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex)
+{
+    const uint8_t MIN_GAIN_INDEX = 1 + MAX_GAIN_TABLE_INDEX - (sizeof(RxGainTable) / sizeof(RxGainTable[0]));
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxAgcMinMaxGainIndex()\n");
+#endif
+
+    /* Check for maxGainIndex */
+    if (maxGainIndex > MAX_GAIN_TABLE_INDEX)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX));
+        return MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX;
+    }
+
+    /* Check for minGainIndex */
+    if (minGainIndex < MIN_GAIN_INDEX)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX));
+        return MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX;
+    }
+
+    if (rxChannelSelect & RX1)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX, maxGainIndex);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX, minGainIndex);
+        device->rx->rxAgcCtrl->agcRx1MaxGainIndex = maxGainIndex;
+        device->rx->rxAgcCtrl->agcRx1MinGainIndex = minGainIndex;
+    }
+
+    if (rxChannelSelect & RX2)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX, maxGainIndex);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX, minGainIndex);
+        device->rx->rxAgcCtrl->agcRx2MaxGainIndex = maxGainIndex;
+        device->rx->rxAgcCtrl->agcRx2MinGainIndex = minGainIndex;
+    }
+
+    /* Check for invalid Rx channel */
+    if (!(rxChannelSelect & RX1_RX2))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL,
+                getMykonosErrorMessage(MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL));
+        return MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function sets the min/max gain indexes for AGC in the observation channel
+ *
+ * Allows to change min/max gain index on runtime.
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ * - device->rx->rxAgcCtrl
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param obsRxChannelSelect Observation channel for setting the max and min gain index settings
+ * \param maxGainIndex Max gain index setting
+ * \param minGainIndex Min gain index setting
+ *
+ * \retval MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL Wrong read back channel.
+ * \retval MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX Max gain index bigger than max gain index loaded table.
+ * \retval MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX Min gain index lower than min gain index loaded table.
+ * \retval MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL Wrong observation channel selected
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setObsRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex)
+{
+    uint8_t rdObsActive = 0x00;
+    uint8_t obsActive = 0x00;
+    uint8_t obsCheck = 0x00;
+    uint8_t minGainIndexCheck = 0x00;
+    uint8_t maxGainIndexCheck = 0x00;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxAgcMinMaxGainIndex()\n");
+#endif
+
+    /* Read active channel */
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE, &rdObsActive, 0x03, 0);
+
+    /* Check active channel and set min/max checks */
+    switch (rdObsActive)
+    {
+        case 0x00:
+        case 0x01:
+            /*sniffer*/
+            maxGainIndexCheck = MAX_GAIN_TABLE_INDEX;
+            minGainIndexCheck = MAX_GAIN_TABLE_INDEX - (sizeof(SnRxGainTable) / sizeof(SnRxGainTable[0]));
+            obsActive = OBS_SNIFFER | OBS_SNIFFER_A | OBS_SNIFFER_B | OBS_SNIFFER_C;
+            break;
+        case 0x02:
+        case 0x03:
+            /*observation 1*/
+            maxGainIndexCheck = MAX_GAIN_TABLE_INDEX;
+            minGainIndexCheck = MAX_GAIN_TABLE_INDEX - (sizeof(ORxGainTable) / sizeof(ORxGainTable[0]));
+            obsActive = OBS_RX1_TXLO | OBS_RX1_SNIFFERLO | OBS_RX2_TXLO | OBS_RX2_SNIFFERLO;
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL));
+            return MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL;
+    }
+
+    /* Check for maxGainIndex */
+    if ((maxGainIndex > maxGainIndexCheck) || (maxGainIndex < minGainIndexCheck))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX));
+        return MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX;
+    }
+
+    /* Check for minGainIndex */
+    if ((minGainIndex < minGainIndexCheck) || (minGainIndex > maxGainIndexCheck))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX));
+        return MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX;
+    }
+
+    device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex = maxGainIndex;
+    device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex = minGainIndex;
+
+    switch (obsRxChannelSelect)
+    {
+        case OBS_SNIFFER:
+        case OBS_SNIFFER_A:
+        case OBS_SNIFFER_B:
+        case OBS_SNIFFER_C:
+            obsCheck = OBS_SNIFFER | OBS_SNIFFER_A | OBS_SNIFFER_B | OBS_SNIFFER_C;
+            maxGainIndex = maxGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES;
+            minGainIndex = minGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES;
+            break;
+
+        case OBS_RX1_TXLO:
+        case OBS_RX2_TXLO:
+        case OBS_RX1_SNIFFERLO:
+        case OBS_RX2_SNIFFERLO:
+            obsCheck = OBS_RX1_TXLO | OBS_RX1_SNIFFERLO | OBS_RX2_TXLO | OBS_RX2_SNIFFERLO;
+            maxGainIndex = maxGainIndex - MAX_ORX_GAIN_TABLE_NUMINDEXES;
+            minGainIndex = minGainIndex - MAX_ORX_GAIN_TABLE_NUMINDEXES;
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL));
+            return MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL;
+    }
+
+    if (obsCheck & obsActive)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX, maxGainIndex);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX, minGainIndex);
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL,
+                getMykonosErrorMessage(MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL));
+        return MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function sets the Temperature gain compensation for Rx1 channel
+ *
+ * The temperature gain compensation control allow for a +3000mdB to -3000mdB digital gain
+ * in the data path.
+ * The resolution of the temperature compensation gain is 250mdB.
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param rx1TempCompGain_mdB gain compensation for Rx1, the range is from -3000mdB to +3000mdB in steps of 250mdB
+ *
+ * \retval MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE The temp gain compensation is outside range (-3000mdB to 3000mdB)
+ * \retval MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP Not valid temp gain compensation, step size is 250mdB
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setRx1TempGainComp(mykonosDevice_t *device, int16_t rx1TempCompGain_mdB)
+{
+    int8_t tempGainComp = 0x00;
+
+    const int16_t LOW_LIMIT_GAIN_COMP = -3000;
+    const int16_t HIGH_LIMIT_GAIN_COMP = 3000;
+    const int16_t GAIN_COMP_STEP = 250;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx1TempGainComp()\n");
+#endif
+
+    /* Check for Gain compensation range */
+    if ((rx1TempCompGain_mdB > HIGH_LIMIT_GAIN_COMP) || (rx1TempCompGain_mdB < LOW_LIMIT_GAIN_COMP))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE,
+                getMykonosErrorMessage(MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE));
+        return MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE;
+    }
+
+    /* Check for Gain compensation steps */
+    if (rx1TempCompGain_mdB % GAIN_COMP_STEP)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP));
+        return MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP;
+    }
+
+    /* Prepare register write */
+    tempGainComp = (rx1TempCompGain_mdB / GAIN_COMP_STEP) & 0x1F;
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_TEMP_GAIN_COMP, (uint8_t)tempGainComp);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function gets the Temperature gain compensation for Rx1
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param rx1TempCompGain_mdB Which will be populated with the Temperature Gain Compensation in mdB value for Rx1 channel.
+ *
+ * \retval MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL rx1TempCompGain_mdB pointer is null.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getRx1TempGainComp(mykonosDevice_t *device, int16_t *rx1TempCompGain_mdB)
+{
+    uint8_t tempGainComp = 0x00;
+    int8_t tempGainCompDB = 0x00;
+
+    const int16_t GAIN_COMP_STEP = 250;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx1TempGainComp()\n");
+#endif
+
+    /* Check for null passed parameter */
+    if (rx1TempCompGain_mdB == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL,
+                getMykonosErrorMessage(MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL));
+        return MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL;
+    }
+
+    /* Read Temperature Gain Compensation */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX1_TEMP_GAIN_COMP, &tempGainComp);
+
+    /* Convert to dB and prepare the signed return */
+    tempGainCompDB = tempGainComp & 0x1F;
+    if (tempGainCompDB & 0x10)
+    {
+        tempGainCompDB = (((~tempGainCompDB) & 0x0F) + 1) * -1;
+    }
+
+    /* Assign value to the passed pointer */
+    *rx1TempCompGain_mdB = tempGainCompDB * GAIN_COMP_STEP;
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function sets the Temperature gain compensation for Rx2 channel
+ *
+ * The temperature gain compensation control allow for a +3000mdB to -3000mdB digital gain
+ * in the data path.
+ * The resolution of the temperature compensation gain is 250mdB.
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param rx2TempCompGain_mdB gain compensation for Rx1,
+ * the range is from -3000mdB to +3000mdB in steps of 250mdB
+ *
+ * \retval MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE The temp gain compensation is outside range (-3000mdB to 3000mdB)
+ * \retval MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP Not valid temp gain compensation, step size is 250mdB
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setRx2TempGainComp(mykonosDevice_t *device, int16_t rx2TempCompGain_mdB)
+{
+    int8_t tempGainComp = 0x00;
+
+    const int16_t LOW_LIMIT_GAIN_COMP = -3000;
+    const int16_t HIGH_LIMIT_GAIN_COMP = 3000;
+    const int16_t GAIN_COMP_STEP = 250;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRx2TempGainComp()\n");
+#endif
+
+    /* Check for Gain compensation range */
+    if ((rx2TempCompGain_mdB > HIGH_LIMIT_GAIN_COMP) || (rx2TempCompGain_mdB < LOW_LIMIT_GAIN_COMP))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE,
+                getMykonosErrorMessage(MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE));
+        return MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE;
+    }
+
+    /* Check for Gain compensation range */
+    if (rx2TempCompGain_mdB % GAIN_COMP_STEP)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP));
+        return MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP;
+    }
+
+    /* Prepare register write */
+    tempGainComp = (rx2TempCompGain_mdB / GAIN_COMP_STEP) & 0x1F;
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_TEMP_GAIN_COMP, (uint8_t)tempGainComp);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function gets the Temperature gain compensation for Rx2
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param rx2TempCompGain_mdB Which will be populated with the Temperature Gain Compensation in mdB value for Rx2 channel.
+ *
+ * \retval MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL rx2TempCompGain_mdB pointer is null.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getRx2TempGainComp(mykonosDevice_t *device, int16_t *rx2TempCompGain_mdB)
+{
+    uint8_t tempGainComp = 0x00;
+    int8_t tempGainCompDB = 0x00;
+
+    const int16_t GAIN_COMP_STEP = 250;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx2TempGainComp()\n");
+#endif
+
+    /* Check for null passed parameter */
+    if (rx2TempCompGain_mdB == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL,
+                getMykonosErrorMessage(MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL));
+        return MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL;
+    }
+
+    /* Read programmed Temperature Gain Compensation */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX2_TEMP_GAIN_COMP, &tempGainComp);
+
+    /* Convert to dB and prepare the signed return */
+    tempGainCompDB = tempGainComp & 0x1F;
+    if (tempGainCompDB & 0x10)
+    {
+        tempGainCompDB = (((~tempGainCompDB) & 0x0F) + 1) * -1;
+    }
+
+    /* Assign value to the passed pointer */
+    *rx2TempCompGain_mdB = tempGainCompDB * GAIN_COMP_STEP;
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function sets the Temperature gain compensation for the observation channel
+ *
+ * The temperature gain compensation control allow for a +3000mdB to -3000mdB digital gain
+ * in the data path.
+ * The resolution of the temperature compensation gain is 250mdB.
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param obsRxTempCompGain_mdB gain compensation for observation channel,
+ * the range is from -3000mdB to +3000mdB in steps of 250mdB
+ *
+ * \retval MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE The temp gain compensation is outside range (-3000mdB to 3000mdB)
+ * \retval MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP Not valid temp gain compensation, step size is 250mdB
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setObsRxTempGainComp(mykonosDevice_t *device, int16_t obsRxTempCompGain_mdB)
+{
+    int8_t tempGainComp = 0x00;
+
+    const int16_t LOW_LIMIT_GAIN_COMP = -3000;
+    const int16_t HIGH_LIMIT_GAIN_COMP = 3000;
+    const int16_t GAIN_COMP_STEP = 250;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxTempGainComp()\n");
+#endif
+
+    /* Check for Gain compensation range */
+    if ((obsRxTempCompGain_mdB > HIGH_LIMIT_GAIN_COMP) || (obsRxTempCompGain_mdB < LOW_LIMIT_GAIN_COMP))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE,
+                getMykonosErrorMessage(MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE));
+        return MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE;
+    }
+
+    /* Check for Gain compensation range */
+    if (obsRxTempCompGain_mdB % GAIN_COMP_STEP)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP));
+        return MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP;
+    }
+
+    /* Prepare register write */
+    tempGainComp = (obsRxTempCompGain_mdB / GAIN_COMP_STEP) & 0x1F;
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_TEMP_GAIN_COMP, (uint8_t)tempGainComp);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function gets the Temperature gain compensation for the observation channel
+ *
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param obsRxTempCompGain_mdB Which will be populated with the Temperature Gain Compensation in mdB value for the observation channel.
+ *
+ * \retval MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL obsRxTempCompGain_mdB pointer is null.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getObsRxTempGainComp(mykonosDevice_t *device, int16_t *obsRxTempCompGain_mdB)
+{
+    uint8_t tempGainComp = 0x00;
+    int8_t tempGainCompDB = 0x00;
+
+    const int16_t GAIN_COMP_STEP = 250;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxTempGainComp()\n");
+#endif
+
+    /* Check for null passed parameter */
+    if (obsRxTempCompGain_mdB == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL,
+                getMykonosErrorMessage(MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL));
+        return MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_OBS_TEMP_GAIN_COMP, &tempGainComp);
+
+    /* Convert to dB and prepare the signed return */
+    tempGainCompDB = tempGainComp & 0x1F;
+    if (tempGainCompDB & 0x10)
+    {
+        tempGainCompDB = (((~tempGainCompDB) & 0x0F) + 1) * -1;
+    }
+
+    /* Assign value to the passed pointer */
+    *obsRxTempCompGain_mdB = tempGainCompDB * GAIN_COMP_STEP;
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables or disables the Rx slow loop gain counter to use the sync pulse
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param enable is a uint8_t data type where '0' = disable Rx gain counter from using sync pulse, '1' = enable Rx gain. All other values will throw an error.
+ * counter to use the sync pulse. This value is written back to the device data structure for storage.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enableRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable)
+{
+    const uint8_t syncPulseBitMask = 0x80;
+    uint8_t enableBit = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxGainCtrSyncPulse()\n");
+#endif
+
+    /* read, modify, write Rx gain counter sync pulse enable bit */
+    enableBit = (enable > 0) ? 1 : 0;
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_LOOP_CFG, enableBit, syncPulseBitMask, 7);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Configures the Rx gain control mode
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->rx->rxGainCtrl->gainMode
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param mode is a mykonosGainMode_t enumerated gain control mode type where:
+ * Manual Gain = MGC, Automatic Gain Control = AGC, and hybrid mode = HYBRID
+ *
+ * When the mode enumerated type is passed, the Rx1 and Rx2 gain mode is set to this value and the
+ * Rx gainMode structure member is updated with the new value
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_INV_RX_GAIN_MODE_PARM Invalid AGC mode pass in function mode paramter
+ */
+mykonosErr_t MYKONOS_setRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode)
+{
+    uint8_t rxGainCfgReg = 0;
+
+    const uint8_t RX_GAIN_TYPE_MASK = 0x1F;
+    const uint8_t RX_GAIN_HYBRID_MASK = 0x10;
+    const uint8_t RX_GAIN_TYPE_SHIFT = 0x02;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxGainControlMode()\n");
+#endif
+
+    /* read AGC type for Rx1 and Rx2 for modify, write */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_CFG_1, &rxGainCfgReg);
+    rxGainCfgReg &= ~RX_GAIN_TYPE_MASK;
+
+    /* performing AGC type check */
+    switch (mode)
+    {
+        case MGC:
+            rxGainCfgReg &= ~RX_GAIN_HYBRID_MASK;
+            break;
+        case AGC:
+            rxGainCfgReg &= ~RX_GAIN_HYBRID_MASK;
+            break;
+        case HYBRID:
+            rxGainCfgReg |= RX_GAIN_HYBRID_MASK;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RX_GAIN_MODE_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_INV_RX_GAIN_MODE_PARM));
+            return MYKONOS_ERR_INV_RX_GAIN_MODE_PARM;
+    }
+
+    /* modify, write AGC type for Rx1 and Rx2 */
+    rxGainCfgReg |= mode;
+    rxGainCfgReg |= mode << RX_GAIN_TYPE_SHIFT;
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_CFG_1, rxGainCfgReg);
+
+    /* writing mode setting to data structure */
+    if ((device->profilesValid & RX_PROFILE_VALID) > 0)
+    {
+        device->rx->rxGainCtrl->gainMode = mode;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs a power measurement in the Rx1 digital data path.
+ *
+ * Due to interdependencies between the AGC and power measurement the power measurement duration and
+ * where the measurement is taken is variable.
+ * The location of the power measurement is given by device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasConfig
+ * The number of samples the power measurement uses is given by 8*2^(device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasDuration) at the IQ rate,
+ * if measured at RFIR output. This number of samples must be less than the agcGainUpdateCounter.
+ * If the receiver is disabled during the power measurement, this function returns a 0 value for rx1DecPower_mdBFS
+ *
+ * The resolution of this function is 0.25dB.
+ * The dynamic range of this function is 40dB. Signals lower than 40dBFS may not be measured accurately.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasConfig
+ * - device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasDuration
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param rx1DecPower_mdBFS Pointer to store the Rx1 decimated power return.  Value returned in mdBFS
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getRx1DecPower(mykonosDevice_t *device, uint16_t *rx1DecPower_mdBFS)
+{
+    uint8_t rx1DecPower_dBFS = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx1DecPower()\n");
+#endif
+
+    /* read Rx1 Dec Power Measurement */
+    if (rx1DecPower_mdBFS != NULL)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_CH1_DECIMATED_PWR, &rx1DecPower_dBFS);
+        *rx1DecPower_mdBFS = (uint16_t)(rx1DecPower_dBFS * 250); /* 250 = 1000 * 0.25dB */
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM));
+        return MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs a power measurement in the Rx2 digital data path.
+ *
+ * Due to interdependencies between the AGC and power measurement the power measurement duration and
+ * where the measurement is taken is variable.
+ * The location of the power measurement is given by device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasConfig
+ * The number of samples the power measurement uses is given by 8*2^(device->rx->rxAgcCtrl->rxPwrAgc->pmdMeasDuration) at the IQ rate,
+ * if measured at RFIR output. This number of samples must be less than the agcGainUpdateCounter.
+ * If the receiver is disabled during the power measurement, this function returns a 0 value for rx2DecPower_mdBFS
+ *
+ * The resolution of this function is 0.25dB.
+ * The dynamic range of this function is 40dB. Signals lower than 40dBFS may not be measured accurately.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param rx2DecPower_mdBFS Pointer to store the Rx1 decimated power return.  Value returned in mdBFS
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getRx2DecPower(mykonosDevice_t *device, uint16_t *rx2DecPower_mdBFS)
+{
+    uint8_t rx2DecPower_dBFS = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRx2DecPower()\n");
+#endif
+
+    /* read Rx2 Dec Power Measurement */
+    if (rx2DecPower_mdBFS != NULL)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_CH2_DECIMATED_PWR, &rx2DecPower_dBFS);
+        *rx2DecPower_mdBFS = (uint16_t)(rx2DecPower_dBFS * 250); /* 250 = 1000 * 0.25dB */
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM));
+        return MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/*
+ *****************************************************************************
+ * Observation Rx Data path functions
+ *****************************************************************************
+ */
+
+/**
+ * \brief Sets the default Obs Rx channel to enter when device moves from
+ *        radioOff to radioOn
+ *
+ * By default, the observation receiver remains powered down when the device
+ * moves into the radioOn state.  If the BBIC prefers a particular ObsRx
+ * channel to be enabled, this function can be called in radioOff to set
+ * the default channel to power up when the device moves to radioOn.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->obsRx->defaultObsRxChannel
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param defaultObsRxCh is mykonosObsRxChannels_t enum type which selects the desired observation receive path to power up
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETDEFOBSRXPATH_NULL_OBSRX_STRUCT Observation profile not valid, device->obsRx structure is NULL
+ * \retval MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT Invalid defaultObsRxCh function parameter
+ */
+mykonosErr_t MYKONOS_setDefaultObsRxPath(mykonosDevice_t *device, mykonosObsRxChannels_t defaultObsRxCh)
+{
+    uint8_t orxEntryMode[1] = {0};
+    uint16_t byteOffset = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDefaultObsRxPath()\n");
+#endif
+
+    if (device->obsRx == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT));
+        return MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT;
+    }
+
+    if (((defaultObsRxCh > OBS_RX2_SNIFFERLO) && (defaultObsRxCh != OBS_SNIFFER_A) && (defaultObsRxCh != OBS_SNIFFER_B) && (defaultObsRxCh != OBS_SNIFFER_C)))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM));
+        return MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM;
+    }
+
+    device->obsRx->defaultObsRxChannel = defaultObsRxCh;
+    orxEntryMode[0] = (device->obsRx->defaultObsRxChannel & 0xFF);
+
+    byteOffset = 6;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_RADIO_CONTROL, byteOffset, &orxEntryMode[0], 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Powers up or down the Observation Rx signal chain in the radioOn state
+ *
+ * When the ARM radio control is in ARM command mode, this
+ * function allows the user to selectively power up or down the desired ObsRx
+ * data path. If this function is called when the ARM is expecting GPIO pin
+ * control of the ObsRx path source, an error will be returned.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param obsRxCh is mykonosObsRxChannels_t enum type which selects the desired observation receive path to power up
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM Invalid obsRxCh function parameter
+ * \retval MYKONOS_ERR_PU_OBSRXPATH_ARMERROR ARM returned an error while trying to set the ObsRx Path source
+ */
+mykonosErr_t MYKONOS_setObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh)
+{
+    uint8_t cmdStatByte = 0;
+    uint32_t timeoutMs = 0;
+    uint8_t payload[2] = {0, 0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxPathSource()\n");
+#endif
+
+    if (((obsRxCh > OBS_RX2_SNIFFERLO) && (obsRxCh != OBS_SNIFFER_A) && (obsRxCh != OBS_SNIFFER_B) && (obsRxCh != OBS_SNIFFER_C)))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM));
+        return MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM;
+    }
+
+    payload[0] = MYKONOS_ARM_OBJECTID_ORX_MODE;
+    payload[1] = (uint8_t)(obsRxCh);
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &payload[0], sizeof(payload));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000; /* wait max of 1sec for command to complete */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_ARMERROR));
+            return MYKONOS_ERR_PU_OBSRXPATH_ARMERROR;
+        }
+
+        return retVal;
+    }
+
+    /* Verify ARM command did not return an error */
+    if (cmdStatByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_OBSRXPATH_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_PU_OBSRXPATH_ARMERROR));
+        return MYKONOS_ERR_PU_OBSRXPATH_ARMERROR;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads back the currently enabled Observation Rx channel in the
+ *        radioOn state
+ *
+ * In pin mode, the pin could change asynchronous to reading back the
+ * current enable ObsRx path.  Calling this function while in radioOff will
+ * return OBS_RXOFF since all radio channels are powered down.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param obsRxCh Parameter to return enum of the current observation receive
+ *                path powered up
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR ARM returned an error while trying to get the ObsRx Path source
+ */
+mykonosErr_t MYKONOS_getObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t *obsRxCh)
+{
+    uint8_t extData[1] = {MYKONOS_ARM_OBJECTID_ORX_MODE};
+    uint8_t cmdStatusByte = 0;
+    uint8_t armData[1] = {0};
+    uint32_t timeoutMs = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxPathSource()\n");
+#endif
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR));
+            return MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR;
+        }
+
+        return retVal;
+    }
+
+    /* read 64-bit frequency from ARM memory */
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 1, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR));
+        return MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR;
+    }
+
+    *obsRxCh = (mykonosObsRxChannels_t)(armData[0]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets the Rx gain of the ObsRx channel
+ *
+ * The ObsRx channel can have different RF inputs (ORx1/ORx2/SnRx A,B,C)
+ * This function sets the ObsRx gain index independently for ORx1/ORx2, or SnRx.
+ * SnRx A, B, and C share the same gain index.  Please note that ORx1/ORx2 share a gain
+ * table, as does SnRx A, B, and C. The maximum index is 255
+ * and the minimum index is application specific.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->obsRx->orxGainCtrl->maxGainIndex
+ * - device->obsRx->orxGainCtrl->minGainIndex
+ * - device->obsRx->orxGainCtrl->orx1GainIndex
+ * - device->obsRx->orxGainCtrl->orx2GainIndex
+ * - device->obsRx->snifferGainCtrl->maxGainIndex
+ * - device->obsRx->snifferGainCtrl->minGainIndex
+ * - device->obsRx->snifferGainCtrl->gainIndex
+ *
+ * \param device Pointer to the Mykonos device data structure
+ * \param obsRxCh is an enum type mykonosObsRxChannels_t to identify the desired RF input for gain change
+ * \param gainIndex Desired manual gain table index to set
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN Invalid gain requested for ORx1: outside gain table min/max index
+ * \retval MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN Invalid gain requested for ORx2: outside gain table min/max index
+ * \retval MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN Invalid gain requested for Sniffer: outside gain table min/max index
+ * \retval MYKONOS_ERR_SETORXGAIN_INV_CHANNEL Function parameter obsRxCh has an invalid enum value
+ */
+mykonosErr_t MYKONOS_setObsRxManualGain(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh, uint8_t gainIndex)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxManualGain()\n");
+#endif
+
+    if ((obsRxCh == OBS_RX1_TXLO) || (obsRxCh == OBS_RX1_SNIFFERLO))
+    {
+        if (gainIndex <= device->obsRx->orxGainCtrl->maxGainIndex && gainIndex >= device->obsRx->orxGainCtrl->minGainIndex)
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX1_MANUAL_GAIN_INDEX, (gainIndex - MIN_ORX_GAIN_TABLE_INDEX));
+            device->obsRx->orxGainCtrl->orx1GainIndex = gainIndex;
+        }
+        else
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN));
+            return MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN;
+        }
+    }
+    else if ((obsRxCh == OBS_RX2_TXLO) || (obsRxCh == OBS_RX2_SNIFFERLO))
+    {
+        if (gainIndex <= device->obsRx->orxGainCtrl->maxGainIndex && gainIndex >= device->obsRx->orxGainCtrl->minGainIndex)
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX2_MANUAL_GAIN_INDEX, (gainIndex - MIN_ORX_GAIN_TABLE_INDEX));
+            device->obsRx->orxGainCtrl->orx2GainIndex = gainIndex;
+        }
+        else
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN));
+            return MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN;
+        }
+
+    }
+    else if (obsRxCh == OBS_SNIFFER_A || obsRxCh == OBS_SNIFFER_B || obsRxCh == OBS_SNIFFER_C || obsRxCh == OBS_SNIFFER)
+    {
+        if (gainIndex <= device->obsRx->snifferGainCtrl->maxGainIndex && gainIndex >= device->obsRx->snifferGainCtrl->minGainIndex)
+        {
+            CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SNRX_MANUAL_GAIN_INDEX, (gainIndex - MIN_SNRX_GAIN_TABLE_INDEX));
+            device->obsRx->snifferGainCtrl->gainIndex = gainIndex;
+        }
+        else
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN));
+            return MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN;
+        }
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETORXGAIN_INV_CHANNEL,
+                getMykonosErrorMessage(MYKONOS_ERR_SETORXGAIN_INV_CHANNEL));
+        return MYKONOS_ERR_SETORXGAIN_INV_CHANNEL;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Gets the gain index of the currently enabled ObsRx channel
+ *
+ * The ObsRx data path can have multiple RF sources.  This function will
+ * read back the gain index of the currently enabled RF source. If the ObsRx
+ * data path is disabled, an error is returned.  If the functions uint8_t *gainIndex
+ * parameter is a valid pointer, the gain index is returned at the pointers
+ * address.  Else, if the uint8_t *gainIndex pointer is NULL, the gainIndex read back
+ * is stored in the device data structure.
+ *
+ * NOTE: if the observation source is chosen by ORX_MODE pins, it is possible that
+ * the readback value will be incorrect if the obsRx channel changes while this function
+ * reads the gain.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->profilesValid
+ * - device->obsRx->orxGainCtrl->orx1GainIndex
+ * - device->obsRx->orxGainCtrl->orx2GainIndex
+ * - device->obsRx->snifferGainCtrl->gainIndex
+ *
+ * \param device Pointer to the Mykonos device data structure
+ * \param gainIndex Return value of the current gain index for the currently enabled ObsRx channel.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETORX1GAIN_INV_POINTER The ObsRx profile is not valid in the device data structure
+ * \retval MYKONOS_ERR_GETORX2GAIN_INV_POINTER The ObsRx profile is not valid in the device data structure
+ * \retval MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER The sniffer profile is not valid in the device data structure
+ * \retval MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED The observation receiver is currently disabled, can not read back gain index.
+ */
+mykonosErr_t MYKONOS_getObsRxGain(mykonosDevice_t *device, uint8_t *gainIndex)
+{
+    /* Potential issue, if ARM is using loopback path when this function is called, it will likely readback loopback gain */
+    uint8_t readObsRxPathEnabled = 0;
+    uint8_t readObsRxGain = 0;
+
+    const uint8_t ORX1_EN = 0x01;
+    const uint8_t ORX2_EN = 0x02;
+    const uint8_t SNRX_EN = 0x04;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxGain()\n");
+#endif
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_1, &readObsRxPathEnabled);
+
+    /* If obsRx channel enabled, then read gain index */
+    if (readObsRxPathEnabled > 0)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_GAIN, &readObsRxGain);
+
+        switch (readObsRxPathEnabled)
+        {
+            case 0x01:
+                readObsRxGain += MIN_ORX_GAIN_TABLE_INDEX;
+                break;
+            case 0x02:
+                readObsRxGain += MIN_ORX_GAIN_TABLE_INDEX;
+                break;
+            case 0x04:
+                readObsRxGain += MIN_SNRX_GAIN_TABLE_INDEX;
+                break;
+            default:
+                break;
+        }
+
+        if (gainIndex != NULL)
+        {
+            *gainIndex = readObsRxGain;
+        }
+
+        /* Store the gain index in the device's gain control data structure. */
+
+        if (readObsRxPathEnabled == ORX1_EN)
+        {
+            /* verify valid data structure pointers */
+            if (device->profilesValid & ORX_PROFILE_VALID)
+            {
+                device->obsRx->orxGainCtrl->orx1GainIndex = readObsRxGain;
+            }
+            else
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORX1GAIN_INV_POINTER,
+                        getMykonosErrorMessage(MYKONOS_ERR_GETORX1GAIN_INV_POINTER));
+                return MYKONOS_ERR_GETORX1GAIN_INV_POINTER;
+            }
+
+        }
+        else if (readObsRxPathEnabled == ORX2_EN)
+        {
+            /* verify valid pointers */
+            if (device->profilesValid & ORX_PROFILE_VALID)
+            {
+                device->obsRx->orxGainCtrl->orx2GainIndex = readObsRxGain;
+            }
+            else
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORX2GAIN_INV_POINTER,
+                        getMykonosErrorMessage(MYKONOS_ERR_GETORX2GAIN_INV_POINTER));
+                return MYKONOS_ERR_GETORX2GAIN_INV_POINTER;
+            }
+
+        }
+        else if (readObsRxPathEnabled == SNRX_EN)
+        {
+            /* verify valid pointers */
+            if (device->profilesValid & SNIFF_PROFILE_VALID)
+            {
+                device->obsRx->snifferGainCtrl->gainIndex = readObsRxGain;
+            }
+            else
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER,
+                        getMykonosErrorMessage(MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER));
+                return MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER;
+            }
+        }
+        else
+        {
+            /* ignore gain index for Tx loopback input into obsRx channel */
+        }
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED,
+                getMykonosErrorMessage(MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED));
+        return MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the device ObsRx Automatic Gain Control (AGC) registers.
+ *
+ * Three data structures (of types mykonosAgcCfg_t, mykonosPeakDetAgcCfg_t, mykonosPowerMeasAgcCfg_t)
+ * must be instantiated prior to calling this function. Valid ranges for data structure members
+ * must also be provided.
+ *
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->obsRx->orxAgcCtrl->agcRx1MaxGainIndex
+ * - device->obsRx->orxAgcCtrl->agcRx1MinGainIndex
+ * - device->obsRx->orxAgcCtrl->agcRx2MaxGainIndex
+ * - device->obsRx->orxAgcCtrl->agcRx2MinGainIndex
+ * - device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex
+ * - device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex
+ * - device->obsRx->orxAgcCtrl->agcObsRxSelect
+ * - device->obsRx->orxAgcCtrl->agcPeakThresholdMode
+ * - device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease
+ * - device->obsRx->orxAgcCtrl->agcGainUpdateCounter
+ * - device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay
+ * - device->obsRx->orxAgcCtrl->agcPeakWaitTime
+ * - device->obsRx->orxAgcCtrl->agcResetOnRxEnable
+ * - device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdHighThreshExceededCnt
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdLowThreshExceededCnt
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2HighThreshExceededCnt
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2LowThreshExceededCnt
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery
+ * - device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2FastAttack
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDetectEnable
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt
+ * - device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThreshCnt
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration
+ * - device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * The pointer to the Mykonos AGC data structure containing settings is checked for a null pointer
+ * to ensure it has been initialized. If not an error is thrown.
+ *
+ * \retval Returns MYKONOS_ERR=pass, !MYKONOS_ERR=fail
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_SELECT
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT
+ * \retval MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT
+ */
+mykonosErr_t MYKONOS_setupObsRxAgc(mykonosDevice_t *device)
+{
+    /* Current configuration does not support AGC on ORx channel */
+    uint8_t decPowerConfig = 0;
+    uint8_t lower1ThreshGainStepRegValue = 0;
+    uint8_t powerThresholdsRegValue = 0;
+    uint8_t hb2OvldCfgRegValue = 0;
+    uint8_t agcGainUpdateCtr[3] = {0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupObsRxAgc()\n");
+#endif
+
+    /* Check mykonosAgcCfg_t device->obsRx->orxAgcCtrl pointer for initialization */
+    if (&device->obsRx->orxAgcCtrl == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT));
+        return MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT;
+    }
+
+    /* Check mykonosPeakDetAgcCfg_t device->orx->orxAgcCtrl->peakAgc pointer for initialization */
+    if (&device->obsRx->orxAgcCtrl->peakAgc == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT;
+    }
+
+    /* Check mykonosPowerMeasAgcCfg_t device->obsRx->orxAgcCtrl->powerAgc pointer for initialization */
+    if (&device->obsRx->orxAgcCtrl->powerAgc == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT;
+    }
+
+    /* Range check agcObsRxMaxGainIndex versus gain table limits and agcObsRxMinGainIndex */
+    if ((device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex > device->obsRx->snifferGainCtrl->maxGainIndex) ||
+        (device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex < device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX));
+        return MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX,
+                (device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES));
+    }
+
+    /* Range check agcObsRxMinGainIndex versus gain table limits and agcObsRxMaxGainIndex */
+    if ((device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex < device->obsRx->snifferGainCtrl->minGainIndex) ||
+        (device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex < device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX));
+        return MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX,
+                (device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex - MAX_SNRX_GAIN_TABLE_NUMINDEXES));
+    }
+
+    /* Range check agcObsRxSelect. Sniffer only support. Sniffer is selected if value is 0 or 1. 2 or 3 select ORx1/ORx2 respectively */
+    if (device->obsRx->orxAgcCtrl->agcObsRxSelect > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_SELECT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_SELECT));
+        return MYKONOS_ERR_INV_AGC_OBSRX_SELECT;
+    }
+    else
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE, device->obsRx->orxAgcCtrl->agcObsRxSelect);
+    }
+
+    /* Range check for agcGainUpdateCounter (22-bit) */
+    if ((device->obsRx->orxAgcCtrl->agcGainUpdateCounter > 0x3FFFFF) ||
+        (device->obsRx->orxAgcCtrl->agcGainUpdateCounter < 1))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM;
+    }
+    else
+    {
+        /* Split agcGainUpdateCounter into three values */
+        agcGainUpdateCtr[0] = (uint8_t)(device->obsRx->orxAgcCtrl->agcGainUpdateCounter);
+        agcGainUpdateCtr[1] = (uint8_t)(device->obsRx->orxAgcCtrl->agcGainUpdateCounter >> 8);
+        agcGainUpdateCtr[2] = (uint8_t)(device->obsRx->orxAgcCtrl->agcGainUpdateCounter >> 16);
+
+        /* Write two bytes directly due. Third word has its upper two bits masked off.  */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_1, agcGainUpdateCtr[0]);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_2, agcGainUpdateCtr[1]);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3, agcGainUpdateCtr[2], 0x3F, 0);
+    }
+
+    /* Range check on agcPeakWaitTime (5-bit) */
+    if ((device->obsRx->orxAgcCtrl->agcPeakWaitTime > 0x1F) ||
+        (device->obsRx->orxAgcCtrl->agcPeakWaitTime < 0x02))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM;
+    }
+    else
+    {
+        /* Write agcPeakWaitTime */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2, device->obsRx->orxAgcCtrl->agcPeakWaitTime, 0x1F, 0);
+    }
+
+    /* Range check for agcSlowLoopSettlingDelay (7-bit) */
+    if (device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay > 0x7F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY));
+        return MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY;
+    }
+    else
+    {
+        /* Write agcSlowLoopSettlingDelay */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG, device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay, 0x7F, 0);
+    }
+
+    /* Range check for pmdMeasDuration */
+    if ((1 << (3 + device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration)) >= (device->obsRx->orxAgcCtrl->agcGainUpdateCounter))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION;
+    }
+    else
+    {
+        /* Write pmdMeasDuration */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_SNIFFER_DEC_POWER_CONFIG_2, device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration, 0x0F, 0);
+    }
+
+    /* Range check for pmdMeasConfig */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig > 0x3)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG;
+    }
+    else
+    {
+        if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 0)
+        {
+            decPowerConfig = 0x0; /* Dec Pwr measurement disable */
+        }
+        else if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 1)
+        {
+            decPowerConfig = 0x3; /* Dec Pwr measurement enable,  HB2 for decPwr measurement */
+        }
+        else if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 2)
+        {
+            decPowerConfig = 0x5; /* Dec Pwr measurement enable, RFIR for decPwr measurement */
+        }
+        else if (device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig == 3)
+        {
+            decPowerConfig = 0x11; /* Dec Pwr measurement enable, BBDC2 for decPwr measurement */
+        }
+        /* Write pmdMeasConfig */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_SNIFFER_DEC_POWER_CONFIG_1, decPowerConfig);
+    }
+
+    /* Range check agcLowThsPreventGainIncrease (1-bit) */
+    if (device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC));
+        return MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC;
+    }
+    else
+    {
+        /* Write agcLowThsPreventGainIncrease */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH, device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease, 0x80, 7);
+    }
+
+    /* Range check agcPeakThresholdMode (1-bit),  */
+    if (device->obsRx->orxAgcCtrl->agcPeakThresholdMode > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE;
+    }
+    else
+    {
+        /* Save to lower1ThreshGainStepRegValue register variable */
+        lower1ThreshGainStepRegValue |= (device->obsRx->orxAgcCtrl->agcPeakThresholdMode << 5);
+    }
+
+    /* Range check agcResetOnRxEnable (1-bit) */
+    if (device->obsRx->orxAgcCtrl->agcResetOnRxEnable > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE));
+        return MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE;
+    }
+    else
+    {
+        /* Write agcResetOnRxEnable */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3, (device->obsRx->orxAgcCtrl->agcResetOnRxEnable << 7), 0x80, 0);
+    }
+
+    /* Range check agcEnableSyncPulseForGainCounter (1-bit) */
+    if (device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER));
+        return MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER;
+    }
+    else
+    {
+        /* Write agcEnableSyncPulseForGainCounter */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG, (device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter << 7), 0x80, 0);
+    }
+
+    /* WRITE REGISTERS FOR THE AGC POWER MEASUREMENT DETECTOR (PMD) STRUCTURE */
+
+    /* Range check pmdLowerHighThresh (7-bit) vs 0x7F and pmdUpperLowThresh */
+    if ((device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh <= device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh) ||
+        (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh > 0x7F))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH;
+    }
+    else
+    {
+        /* Write pmdLowerHighThresh */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH, device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh, 0x7F, 0);
+    }
+
+    /* Range check pmdUpperLowThresh (7-bit): Comparison to pmdLowerHigh done earlier */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh > 0x7F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH;
+    }
+    else
+    {
+        /* Write pmdUpperLowThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_LOCK_LEVEL, device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh);
+    }
+
+    /* Range check pmdLowerLowThresh (4-bit)  */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh > 0xF)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH;
+    }
+    else
+    {
+        /* Write pmdUpperLowThresh to temp variable */
+        powerThresholdsRegValue |= device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh;
+    }
+
+    /* Range check pmdUpperHighThresh (4-bit)  */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh > 0xF)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH;
+    }
+    else
+    {
+        /* Write pmdUpperHighThresh to temp var, then to register */
+        powerThresholdsRegValue |= (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh << 4);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_POWER_THRSH, powerThresholdsRegValue);
+    }
+
+    /* Range check pmdUpperHighGainStepAttack (5-bit)  */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdUpperHighGainStepAttack */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER1_THRSH_GAIN_STEP, device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack,
+                0x1F, 0);
+    }
+
+    /* Range check pmdLowerLowGainStepRecovery (5-bit)  */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        lower1ThreshGainStepRegValue |= (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery);
+    }
+
+    /* Range check pmdUpperLowGainStepRecovery (5-bit)  */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdUpperLowGainStepRecovery to register */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER0_THRSH_GAIN_STEP, device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack);
+    }
+
+    /* Range check pmdLowerHighGainStepRecovery (5-bit)  */
+    if (device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER0_THRSH_GAIN_STEP, device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery);
+    }
+
+    /* WRITE REGISTERS FOR THE AGC PEAK DETECTOR (APD/HB2) STRUCTURE */
+
+    /* Range check apdFastAttack and hb2FastAttack (1-bit)  */
+    if ((device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack > 0x1) ||
+        (device->obsRx->orxAgcCtrl->peakAgc->hb2FastAttack > 0x1))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE));
+        return MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE;
+    }
+    else
+    {
+        /* Write pmdLowerLowGainStepRecovery to temp var, then to register */
+        lower1ThreshGainStepRegValue |= (device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack << 7);
+        lower1ThreshGainStepRegValue |= (device->obsRx->orxAgcCtrl->peakAgc->hb2FastAttack << 6);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER1_THRSH_GAIN_STEP, lower1ThreshGainStepRegValue);
+    }
+
+    /* Range check apdHighThresh */
+    if ((device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh > 0x3F) ||
+        (device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh <= device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM;
+    }
+    else
+    {
+        /* Write apdHighThresh */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_ULB_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh, 0X3F, 0);
+    }
+
+    /* Range check apdLowThresh */
+    if ((device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh > 0x3F) ||
+        (device->obsRx->orxAgcCtrl->peakAgc->apdHighThresh < device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM;
+    }
+    else
+    {
+        /* write apdLowThresh */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_LLB_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdLowThresh, 0x3F, 0);
+    }
+
+    /* Range check hb2HighThresh */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh < device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM;
+    }
+    else
+    {
+        /* write hb2HighThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_UPPER_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh);
+    }
+
+    /* Range check hb2LowThresh */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh > device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM;
+    }
+    else
+    {
+        /* write hb2LowThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_LOWER_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh);
+    }
+
+    /* Range check hb2VeryLowThresh */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh > device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM;
+    }
+    else
+    {
+        /* write hb2VeryLowThresh */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_VERYLOW_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh);
+    }
+
+    /* Write threshold counter values for apdHigh/apdLow/hb2High/hb2Low/hb2VeryLow */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ULB_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdHighThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LLB_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->apdLowThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_HIGH_OVRG_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2HighThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_LOW_OVRG_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2LowThreshExceededCnt);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_VERYLOW_OVRG_CNT_THRSH, device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThreshExceededCnt);
+
+    /* Range check on apdHighGainStepAttack (5-bit) */
+    if (device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write apdHighGainStepAttack */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_1, device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack);
+    }
+
+    /* Range check on apdLowGainStepRecovery (5-bit) */
+    if (device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write apdLowGainStepRecovery */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_4, device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery);
+    }
+
+    /* Range check on hb2HighGainStepAttack (5-bit) */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write hb2HighGainStepAttack */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_2, device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack);
+    }
+
+    /* Range check on hb2LowGainStepRecovery (5-bit) */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write hb2LowGainStepRecovery */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_5, device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery);
+    }
+
+    /* Range check on hb2VeryLowGainStepRecovery (5-bit) */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery > 0x1F)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM;
+    }
+    else
+    {
+        /* Write hb2VeryLowGainStepRecovery */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_6, device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery);
+    }
+
+    /* Range Check on hb2OverloadDetectEnable */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDetectEnable > 0x1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE;
+    }
+
+    /* Range Check on hb2OverloadDetectEnable */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt > 0x7)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT;
+    }
+
+    /* Range Check on hb2OverloadDetectEnable */
+    if (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThreshCnt > 0xF)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT));
+        return MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT;
+    }
+    else
+    {
+        /* Write the hb2OvldCfgRegValue, the combination of hb2OverloadThreshCnt, hb2OverloadDurationCnt, and hb2OverloadDetectEnable */
+        hb2OvldCfgRegValue = (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThreshCnt) |
+                             (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt << 4) |
+                             (device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDetectEnable << 7);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_CFG, hb2OvldCfgRegValue);
+    }
+
+    /* Hard-coded value for the ADC overload configuration. Sets the HB2 offset to -6dB.*/
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ORX_SNRX_OVRLD_ADC_OVRLD_CFG, 0x18);
+    /* Hard-coded value for APD decay setting. Setting allows for the quickest settling time of peak detector */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_BLOCK_DET_DECAY, 0x0);
+
+    /* performing a soft reset */
+    MYKONOS_resetRxAgc(device);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables or disables the ObsRx slow loop gain counter to use the sync pulse
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing the device SPI settings
+ * \param enable is a uint8_t data type where '0' = disable ObsRx gain counter from using sync pulse, '1' = enable ObsRx gain. All other values will throw an error.
+ *               counter to use the sync pulse. This value is written back to the device data structure for storage.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enableObsRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable)
+{
+    const uint8_t syncPulseBitMask = 0x80;
+    uint8_t enableBit = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableObsRxGainCtrSyncPulse()\n");
+#endif
+
+    enableBit = (enable > 0) ? 1 : 0;
+
+    /* read, modify, write ObsRx gain counter sync pulse enable bit */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG, enableBit, syncPulseBitMask, 7);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Configures the ObsRx gain control mode
+ *
+ * <B>Dependencies:</B>
+ * - device->spiSettings
+ * - device->obsRx->orxGainCtrl->gainMode
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param mode is a mykonosGainMode_t enumerated gain control mode type
+ *
+ * When the mode enumerated type is passed, the ObsRx gain mode is set to this value and the
+ * ObsRX agcType mykonosAgcCfg_t structure member is updated with the new value
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM Invalid Observation Rx Gain control mode selected (use mykonosGainMode_t ENUM values)
+ */
+mykonosErr_t MYKONOS_setObsRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode)
+{
+    const uint8_t ORX_GAIN_TYPE_MASK = 0x3;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxGainControlMode()\n");
+#endif
+
+    /* performing gain type check */
+    switch (mode)
+    {
+        case MGC:
+            break;
+        case AGC:
+            break;
+        case HYBRID:
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM));
+            return MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM;
+    }
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_CFG_1, mode, ORX_GAIN_TYPE_MASK, 0);
+
+    /* writing mode setting to data structure */
+    if ((device->profilesValid & ORX_PROFILE_VALID) > 0)
+    {
+        device->obsRx->orxGainCtrl->gainMode = mode;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs a power measurement in the ObsRx digital data path.
+ *
+ * Due to interdependencies between the AGC and power measurement the power measurement duration and
+ * where the measurement is taken is variable.
+ * The location of the power measurement is given by device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig
+ * The number of samples the power measurement uses is given by 8*2^(device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig) at the IQ rate,
+ * if measured at RFIR output. This number of samples must be less than the agcGainUpdateCounter.
+ * If the receiver is disabled during the power measurement, this function returns a 0 value for rx2DecPower_mdBFS
+ *
+ * The resolution of this function is 0.25dB.
+ * The dynamic range of this function is 40dB. Signals lower than 40dBFS may not be measured accurately.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig
+ * - device->obsRx->obsRxAgcCtrl->obsRxPwrAgc->pmdMeasConfig
+ *
+ * \param device Pointer to the Mykonos data structure
+ * \param obsRxDecPower_mdBFS Pointer to store the Rx1 decimated power return.  Value returned in mdBFS
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getObsRxDecPower(mykonosDevice_t *device, uint16_t *obsRxDecPower_mdBFS)
+{
+    uint8_t obsRxDecPower_dBFS = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getObsRxDecPower()\n");
+#endif
+
+    /* read ObsRx Dec Power Measurement */
+    if (obsRxDecPower_mdBFS != NULL)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_SNIFFER_DECIMATED_PWR, &obsRxDecPower_dBFS);
+        *obsRxDecPower_mdBFS = (uint16_t)(obsRxDecPower_dBFS * 250); /* 250 = 1000 * 0.25dB */
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM));
+        return MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/*
+ *****************************************************************************
+ * Tx Data path functions
+ *****************************************************************************
+ */
+
+/**
+ * \brief Sets the Tx1 RF output Attenuation
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->tx->txAttenStepSize
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param tx1Attenuation_mdB The desired TxAttenuation in milli-dB (Range: 0 to 41950 mdB)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETTX1ATTEN_INV_PARM tx1Attenuation_mdB parameter is out of range (0 - 41950)
+ * \retval MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM device->tx->txAttenStepSize is not a valid enum value
+ */
+mykonosErr_t MYKONOS_setTx1Attenuation(mykonosDevice_t *device, uint16_t tx1Attenuation_mdB)
+{
+    uint16_t data = 0;
+    uint16_t attenStepSizeDiv = 50;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setTx1Attenuation()\n");
+#endif
+
+    /* check input parameter is in valid range */
+    if (tx1Attenuation_mdB > 41950)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX1ATTEN_INV_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_SETTX1ATTEN_INV_PARM));
+        return MYKONOS_ERR_SETTX1ATTEN_INV_PARM;
+    }
+
+    switch (device->tx->txAttenStepSize)
+    {
+        case TXATTEN_0P05_DB:
+            attenStepSizeDiv = 50;
+            break;
+        case TXATTEN_0P1_DB:
+            attenStepSizeDiv = 100;
+            break;
+        case TXATTEN_0P2_DB:
+            attenStepSizeDiv = 200;
+            break;
+        case TXATTEN_0P4_DB:
+            attenStepSizeDiv = 400;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM));
+            return MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM;
+
+    }
+
+    data = (tx1Attenuation_mdB / attenStepSizeDiv);
+
+    /* Write MSB bits followed by LSB bits, TxAtten updates when [7:0] written */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_1, ((data >> 8) & 0x03));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_0, (data & 0xFF));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets the Tx2 RF output Attenuation (Step size is 0.05dB.)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->tx->txAttenStepSize
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param tx2Attenuation_mdB The desired TxAttenuation in milli-dB
+ *                           (Range: 0 to 41950 mdB)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETTX2ATTEN_INV_PARM tx2Attenuation_mdB parameter is out of range (0 - 41950)
+ * \retval MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM device->tx->txAttenStepSize is not a valid enum value
+ */
+mykonosErr_t MYKONOS_setTx2Attenuation(mykonosDevice_t *device, uint16_t tx2Attenuation_mdB)
+{
+    uint16_t attenStepSizeDiv = 50;
+    uint16_t data = 0;
+    //const uint8_t SPI_TXATTEN_MODE = 0x01;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setTx2Attenuation()\n");
+#endif
+
+    /* check input parameter is in valid range */
+    if (tx2Attenuation_mdB > 41950)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX2ATTEN_INV_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_SETTX2ATTEN_INV_PARM));
+        return MYKONOS_ERR_SETTX2ATTEN_INV_PARM;
+    }
+
+    switch (device->tx->txAttenStepSize)
+    {
+        case TXATTEN_0P05_DB:
+            attenStepSizeDiv = 50;
+            break;
+        case TXATTEN_0P1_DB:
+            attenStepSizeDiv = 100;
+            break;
+        case TXATTEN_0P2_DB:
+            attenStepSizeDiv = 200;
+            break;
+        case TXATTEN_0P4_DB:
+            attenStepSizeDiv = 400;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM));
+            return MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM;
+    }
+
+    data = (tx2Attenuation_mdB / attenStepSizeDiv);
+
+    /* Write MSB bits followed by LSB bits, TxAtten updates when [7:0] written */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_1, ((data >> 8) & 0x03));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_0, (data & 0xFF));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads back the Tx1 RF output Attenuation
+ *
+ *  This function reads back the TxAttenuation setting currently applied to the transmit chain.
+ *  The function will work with SPI mode or pin controlled TxAtten mode using the increment/decrement GPIO
+ *  pins.  For the readback value to be valid the Tx data path must be powered up.  If the Tx data path
+ *  is powered down or radioOff state, the last TxAtten setting while the Tx was powered up will be
+ *  read back.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param tx1Attenuation_mdB The readback value of the Tx1 Attenuation in milli-dB (Range: 0 to 41950 mdB)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETTX1ATTEN_NULL_PARM tx1Attenuation_mdB return parameter has NULL pointer
+ */
+mykonosErr_t MYKONOS_getTx1Attenuation(mykonosDevice_t *device, uint16_t *tx1Attenuation_mdB)
+{
+    uint8_t txAttenLsb = 0;
+    uint8_t txAttenMsb = 0;
+    uint16_t attenStepSizeDiv = 50;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTx1Attenuation()\n");
+#endif
+
+    /* check return parameter pointer is not NULL pointer */
+    if (tx1Attenuation_mdB == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1ATTEN_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETTX1ATTEN_NULL_PARM));
+        return MYKONOS_ERR_GETTX1ATTEN_NULL_PARM;
+    }
+
+    /* Write TxAtten read back reg to update readback values, then read Tx1Atten */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK, 0x00);
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_0_READBACK, &txAttenLsb, 0xFF, 0);
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK, &txAttenMsb, 0x03, 0);
+
+    /* Readback word always reads back with 0.05dB resolution */
+    *tx1Attenuation_mdB = (((uint16_t)(txAttenLsb) | ((uint16_t)(txAttenMsb) << 8)) * attenStepSizeDiv);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads back the Tx2 RF output Attenuation
+ *
+ *  This function reads back the TxAttenuation setting currently applied to the transmit chain.
+ *  The function will work with SPI mode or pin controlled TxAtten mode using the increment/decrement GPIO
+ *  pins.  For the readback value to be valid the Tx data path must be powered up.  If the Tx data path
+ *  is powered down or radioOff state, the last TxAtten setting while the Tx was powered up will be
+ *  read back.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param tx2Attenuation_mdB The readback value of the Tx2 Attenuation in milli-dB (Range: 0 to 41950 mdB)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETTX2ATTEN_NULL_PARM tx2Attenuation_mdB return parameter pointer is NULL
+ */
+mykonosErr_t MYKONOS_getTx2Attenuation(mykonosDevice_t *device, uint16_t *tx2Attenuation_mdB)
+{
+    uint8_t txAttenLsb = 0;
+    uint8_t txAttenMsb = 0;
+    uint16_t attenStepSizeDiv = 50;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTx2Attenuation()\n");
+#endif
+
+    /* check return parameter pointer is not NULL pointer */
+    if (tx2Attenuation_mdB == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2ATTEN_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETTX2ATTEN_NULL_PARM));
+        return MYKONOS_ERR_GETTX2ATTEN_NULL_PARM;
+    }
+
+    /* Write TxAtten read back reg to update readback values, then read Tx1Atten */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK, 0x00);
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_0_READBACK, &txAttenLsb, 0xFF, 0);
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK, &txAttenMsb, 0x03, 0);
+
+    /* Readback word always reads back with 0.05dB resolution */
+    *tx2Attenuation_mdB = (((uint16_t)(txAttenLsb) | ((uint16_t)(txAttenMsb) << 8)) * attenStepSizeDiv);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Checks the Tx Filter over-range bit assignments for digital clipping in the Tx data path
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * txFilterStatus bit-field assignments are:
+ * txFilterStatus[0] = TFIR Ch1 Overflow
+ * txFilterStatus[1] = HB1 Ch1 Overflow
+ * txFilterStatus[2] = HB2 Ch1 Overflow
+ * txFilterStatus[3] = QEC Ch1 Overflow
+ * txFilterStatus[4] = TFIR Ch2 Overflow
+ * txFilterStatus[5] = HB1 Ch2 Overflow
+ * txFilterStatus[6] = HB2 Ch2 Overflow
+ * txFilterStatus[7] = QEC Ch2 Overflow
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param txFilterStatus is an 8-bit Tx filter over-range status bit-field
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM Function txFilterStatus parameter pointer is NULL
+ */
+mykonosErr_t MYKONOS_getTxFilterOverRangeStatus(mykonosDevice_t *device, uint8_t *txFilterStatus)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTxFilterOverRangeStatus()\n");
+#endif
+
+    if (txFilterStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM));
+        return MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_FILTER_OVERFLOW, txFilterStatus);
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables/Disables the Tx NCO test tone
+ *
+ *  This function enables/disables a digital numerically controlled oscillator
+ *  in the Mykonos Digital to create a test CW tone on Tx1 and Tx2 RF outputs.
+ *
+ *  The TxAttenuation is forced in this function to max analog output power, but
+ *  the digital attenuation is backed off 6dB to make sure the digital filter
+ *  does not clip and cause spurs in the tx spectrum.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->profilesValid
+ * - device->tx->txProfile->iqRate_kHz
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param enable 0 = Disable Tx NCO, 1 = Enable Tx NCO on both transmitters
+ * \param tx1ToneFreq_kHz Signed frequency in kHz of the desired Tx1 tone
+ * \param tx2ToneFreq_kHz Signed frequency in kHz of the desired Tx2 tone
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID Can not enable Tx NCO when Tx Profile is not enabled/valid
+ * \retval MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID Tx1 NCO Tone frequency out of range (-IQrate/2 to IQrate/2)
+ * \retval MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID Tx2 NCO Tone frequency out of range (-IQrate/2 to IQrate/2)
+ */
+mykonosErr_t MYKONOS_enableTxNco(mykonosDevice_t *device, uint8_t enable, int32_t tx1ToneFreq_kHz, int32_t tx2ToneFreq_kHz)
+{
+    int16_t tx1NcoTuneWord = 0;
+    int16_t tx2NcoTuneWord = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableTxNco()\n");
+#endif
+
+    if (enable > 0)
+    {
+        if ((device->profilesValid & TX_PROFILE_VALID) == 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID));
+            return MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID;
+        }
+
+        if ((tx1ToneFreq_kHz > ((int32_t)(device->tx->txProfile->iqRate_kHz) / 2)) || (tx1ToneFreq_kHz < ((int32_t)(device->tx->txProfile->iqRate_kHz) * -1 / 2)))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID));
+            return MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID;
+        }
+
+        if ((tx2ToneFreq_kHz > ((int32_t)(device->tx->txProfile->iqRate_kHz) / 2)) || (tx2ToneFreq_kHz < ((int32_t)(device->tx->txProfile->iqRate_kHz) * -1 / 2)))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID));
+            return MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID;
+        }
+
+        /* Force Tx output power to max analog output power, but 6dB digital */
+        /* backoff to prevent the NCO from clipping the Tx PFIR filter */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_GAIN_0, 0x78);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX1_GAIN_1, 0x00, 0x3F, 0);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX1_GAIN_2, 0x0);
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_GAIN_0, 0x78);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX2_GAIN_1, 0x00, 0x3F, 0);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX2_GAIN_2, 0x0);
+
+        /* Enable manual Tx output power mode */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x0A, 0x0F, 0);
+
+        /* Set Tx NCO tuning words */
+        tx1NcoTuneWord = (int16_t)(((int64_t)(tx1ToneFreq_kHz) << 16) / device->tx->txProfile->iqRate_kHz * -1);
+        tx2NcoTuneWord = (int16_t)(((int64_t)(tx2ToneFreq_kHz) << 16) / device->tx->txProfile->iqRate_kHz * -1);
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_MSB, ((tx1NcoTuneWord >> 8) & 0xFF));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_LSB, (tx1NcoTuneWord & 0xFF));
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_MSB, ((tx2NcoTuneWord >> 8) & 0xFF));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_LSB, (tx2NcoTuneWord & 0xFF));
+
+        /* Enable Tx NCO - set [7] = 1 */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DIGITAL_TEST_BYTE_0, 1, 0x80, 7);
+    }
+    else
+    {
+        /* Disable Tx NCO - set [7] = 0 */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DIGITAL_TEST_BYTE_0, 0, 0x80, 7);
+
+        /* Enable normal Tx Atten table mode */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, 0x05, 0x0F, 0);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Writes Mykonos device registers with settings for the PA Protection block.
+ *
+ * This function writes register settings for the Mykonos PA Protection Block.
+ * This function does not enable the PA Protection functionality.
+ * Note that independent control of PA protection for both Tx channels is not possible.
+ * The PA Protection block allows for error flags to go high if the accumulated TX power in the data path
+ * exceeds a programmable threshold level based on samples taken in a programmable duration.
+ *
+ * \post After calling this function the user will need to call MYKONOS_enablePaProtection(...)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param powerThreshold PA Protection Threshold sets the power level that, if detected in the TX data path, raises the PA error flags. The range is 0 to 4096.
+ * To calculate the required setting for the power threshold:
+ * powerThreshold = MAX_DAC_CODE * (10^((txPowerThresh_dBFS/10)))
+ * For example: If the required dBFS for the threshold is -10 dBFS, then the powerThreshold passed should be 409.
+ *
+ * \param attenStepSize Attenuation Step Size sets the size of the attenuation step when Tx Atten Control is Enabled. The range is 0 to 128 with a resolution is 0.2dB/LSB.
+ * \param avgDuration Averaging Duration for the TX data path power measurement. The range is 0 to 14 specified in number of cycles of the TX IQ Rate.
+ * \param stickyFlagEnable "1" Enables the PA Error Flags to stay high after being triggered, even if the power decreases below threshold. "0" disables this functionality.
+ * \param txAttenControlEnable "1" Enables autonomous attenuation changes in response to PA error flags. "0" disables this functionality.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION avgDuration parameter invalid (valid 0-15)
+ * \retval MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP attenStepSize function parameter invalid (valid 0-127)
+ */
+mykonosErr_t MYKONOS_setupPaProtection(mykonosDevice_t *device, uint16_t powerThreshold, uint8_t attenStepSize, uint8_t avgDuration, uint8_t stickyFlagEnable, uint8_t txAttenControlEnable)
+{
+    uint8_t paProtectConfig = 0;
+    uint8_t paProtectAttenCntl = 0;
+
+    const uint8_t PROTECT_AVG_DUR_MASK = 0x1E;
+    const uint8_t STICKY_FLAG_EN_MASK = 0x40;
+    const uint8_t ATT_STEP_MASK = 0xFE;
+    const uint8_t PROTECT_ATT_EN_MASK = 0x01;
+    const uint8_t AVG_DUR_MASK = 0x0F;
+    const uint8_t ATT_STEP_SIZE = 0x7F;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupPaProtection()\n");
+#endif
+
+    /* Overwrite PA Protection Config register data with averaging duration and sticky flag. Also performing range check on stickyFlagEnable and avgDuration */
+    if (avgDuration > AVG_DUR_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION,
+                getMykonosErrorMessage(MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION));
+        return MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION;
+    }
+
+    if (attenStepSize > ATT_STEP_SIZE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP,
+                getMykonosErrorMessage(MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP));
+        return MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP;
+    }
+
+    paProtectConfig = (PROTECT_AVG_DUR_MASK & (avgDuration << 1));
+
+    if (stickyFlagEnable > 0)
+    {
+        paProtectConfig |= (STICKY_FLAG_EN_MASK);
+    }
+
+    paProtectAttenCntl = ATT_STEP_MASK & (attenStepSize << 1);
+
+    if (txAttenControlEnable > 0)
+    {
+        paProtectAttenCntl |= (PROTECT_ATT_EN_MASK);
+    }
+
+    /* Clear and write all PA Protection setup registers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL, 0x00);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, 0x00);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB, 0x00);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB, 0x00);
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL, paProtectAttenCntl);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, paProtectConfig);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB, (powerThreshold & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB, ((powerThreshold >> 8) & 0x0F));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables the Mykonos PA Protection block according to the parameters passed in MYKONOS_setupPaProtection(...).
+ *
+ * This function enables the PA Protection block according to the parameters passed in MYKONOS_setupPaProtection(...)
+ * The paProtectEnable signal enables the PA Protection block, allowing usage of the PA protection functions.
+ *
+ * \pre Before calling this function the user needs to setup the PA protection by calling MYKONOS_setupPaProtection(...)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ * \param paProtectEnable "1" Enables the PA Protection block. "0" Disables the PA Protection block
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enablePaProtection(mykonosDevice_t *device, uint8_t paProtectEnable)
+{
+    uint8_t paProtectEnableReg = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enablePaProtection()\n");
+#endif
+
+    paProtectEnableReg = (paProtectEnable > 0) ? 1 : 0;
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, paProtectEnableReg, 0x01, 0);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Obtains an estimate of a TX channel's accumulated power over the sample duration provided in MYKONOS_setupPaProtection(...)
+ *
+ * This function uses the 'avgDuration' parameter provided in MYKONOS_setupPaProtection to set the number of samples to accumulate
+ * to obtain an estimate for a TX channel specified by the 'channel' parameter.
+ * A 12-bit field estimating the channel power is returned in the '*channelPower' pointer.
+ * To obtain the dBFS value of the reading:
+ * dBFS value = 10*log10(channelPower/MAX_DAC_CODE)
+ * where MAX_DAC_CODE = 2^12 =  4096
+ * For example: If channelPower is reading 409 then the channel power in dBFS is -10dBFS.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Point to the Mykonos device's data structure
+ * \param channel Select the channel of interest. Only use TX1 (1) or TX2 (2) of mykonosTxChannels_t
+ * \param *channelPower A pointer that stores the selected channels power. Read back is provided as a 12 bit value.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GET_DAC_PWR_INV_POINTER Function channelPower parameter is a NULL pointer
+ * \retval MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL Invalid Tx Channel passed in function channel parameter (TX1 or TX2)
+ */
+mykonosErr_t MYKONOS_getDacPower(mykonosDevice_t *device, mykonosTxChannels_t channel, uint16_t *channelPower)
+{
+    uint8_t channelPowerLsb = 0;
+    uint8_t channelPowerMsb = 0;
+
+    const uint8_t CHAN_POWER_MSB_MASK = 0xF;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDacPower()\n");
+#endif
+
+    if (channelPower == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_DAC_PWR_INV_POINTER,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_DAC_PWR_INV_POINTER));
+        return MYKONOS_ERR_GET_DAC_PWR_INV_POINTER;
+    }
+
+    /* Set bit D5 to read the appropriate channel power */
+    switch (channel)
+    {
+        case TX1:
+            CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, 0, 0x20, 5);
+            break;
+        case TX2:
+            CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, 1, 0x20, 5);
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL));
+            return MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL;
+    }
+
+    /* SPI Write to register PA Protection power readback registers (write strobe) */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB, 0x00);
+
+    /* SPI Read of the PA Protection power readback registers */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB, &channelPowerLsb);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB, &channelPowerMsb);
+
+    *channelPower = (channelPowerLsb | (((uint16_t)(channelPowerMsb & CHAN_POWER_MSB_MASK)) << 8));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Returns PA Protection Error Flag Status
+ *
+ * This function provides a readback of the PA protection Error Flag Status through the '*errorFlagStatus' pointer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Point to the Mykonos device's data structure
+ * \param errorFlagStatus Pointer to store the error flag status.
+ * errorFlagStatus  |  error
+ * -----------------|------------
+ *         0        |   indicates no PA Error Flags are high
+ *         1        |   indicates TX1 Error Flag
+ *         2        |   indicates TX2 Error Flag
+ *         3        |   indicates TX1 and TX2 Error Flags are high
+ *
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER Function errorFlagStatus parameter has NULL pointer
+ */
+mykonosErr_t MYKONOS_getPaProtectErrorFlagStatus(mykonosDevice_t *device, uint8_t *errorFlagStatus)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getPaProtectErrorFlagStatus()\n");
+#endif
+
+    if (errorFlagStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER,
+                getMykonosErrorMessage(MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER));
+        return MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER;
+    }
+
+    /* SPI Write to register PA Protection power readback registers (write strobe) */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB, 0x00);
+
+    /* SPI Read of the PA Protection power readback registers */
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB, errorFlagStatus, 0x60, 5);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Manually clears the PA Protection Error Flags.
+ *
+ * This function manually clears the PA Error Flags. The user must setup the PA Protection block to enable
+ * sticky error flags. Sticky error flags require the user to clear the bit manually even if the accumulated power is
+ * below the power threshold for the PA protection block.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device's data structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_clearPaErrorFlag(mykonosDevice_t *device)
+{
+    uint8_t paProtectConfig;
+
+    const uint8_t PA_ERROR_CLEAR_MASK = 0x80;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_clearPaErrorFlag()\n");
+#endif
+
+    /* SPI Read of the PA Protection power readback registers */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, &paProtectConfig);
+
+    /* SPI Write to self clear the PA Error Flags */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION, (paProtectConfig | PA_ERROR_CLEAR_MASK));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Helper function for return of character string based on 32-bit mykonosErr_t enum value
+ *
+ * To save codespace, these error strings are ifdef'd out unless the user
+ * adds a define MYKONOS_VERBOSE to their workspace.  This function can be
+ * useful for debug.  Each function also returns unique error codes to
+ * make it easier to determine where the code broke.
+ *
+ * \param errorCode is enumerated error code value
+ *
+ * \return Returns character string based on enumerated value
+ */
+const char* getMykonosErrorMessage(mykonosErr_t errorCode)
+{
+#ifndef MYKONOS_VERBOSE
+    return "";
+
+#else
+
+    switch (errorCode)
+    {
+        case MYKONOS_ERR_OK:
+            return "";
+        case MYKONOS_ERR_INV_PARM:
+            return "Mykonos: Invalid parameter\n";
+        case MYKONOS_ERR_FAILED:
+            return "Mykonos: General Failure\n";
+        case MYKONOS_ERR_WAITFOREVENT_INV_PARM:
+            return "waitForEvent had invalid parameter.\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT:
+            return "waitForEvent timed out.\n";
+        case MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_WAIT:
+            return "Requested new ENSM state is invalid from the WAIT state.\n";
+        case MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_ALERT:
+            return "Requested new ENSM state is invalid from the ALERT state.\n";
+        case MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_TXRX:
+            return "Requested new ENSM state is invalid from the TXRX state.\n";
+        case MYKONOS_ERR_SETENSM_INVALIDSTATE:
+            return "Current ENSM state is an invalid state or calibration state.\n";
+        case MYKONOS_ERR_PU_RXPATH_INV_PARAM:
+            return "Invalid Rx channel was requested to be powered up.\n";
+        case MYKONOS_ERR_PU_TXPATH_INV_PARAM:
+            return "Invalid Tx channel was requested to be powered up.\n";
+        case MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM:
+            return "Invalid ObsRx channel was requested to be powered up.\n";
+        case MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT:
+            return "Invalid default ObsRx channel was requested to be powered up.\n";
+        case MYKONOS_ERR_INIT_INV_ORXCHAN:
+            return "Invalid ObsRx channel requested during initialize().\n";
+        case MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE:
+            return "Invalid combination for rxsyncb and orxsyncb, if shared syncb they should have the CMOS/LVDS mode\n";
+        case MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION:
+            return "Invalid TxFIR interpolation value.(Valid: 1,2,4)\n";
+        case MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION:
+            return "Invalid TXHB2 interpolation value.(Valid: 1 or 2)\n";
+        case MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION:
+            return "Invalid TXHB1 interpolation value.(Valid: 1 or 2)\n";
+        case MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION:
+            return "Invalid RxFIR decimation value.(Valid: 1,2,4)\n";
+        case MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION:
+            return "Invalid Rx DEC5 decimation value.(Valid: 4 or 5)\n";
+        case MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION:
+            return "Invalid RxHB1 decimation value.(Valid: 1 or 2)\n";
+        case MYKONOS_ERR_INIT_INV_SNIFFER_RHB1:
+            return "Invalid Sniffer HB1 decimation value (Valid 1 or 2)\n";
+        case MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC:
+            return "Invalid Sniffer RFIR decimation value (Valid 1,2,4)\n";
+        case MYKONOS_ERR_INIT_INV_ORX_RHB1:
+            return "Invalid ORx HB1 decimation value (Valid 1 or 2)\n";
+        case MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC:
+            return "Invalid ORx RFIR decimation value. (Valid 1,2,4)\n";
+        case MYKONOS_ERR_INIT_INV_ADCDIV:
+            return "Invalid Rx ADC divider. (Valid 1 or 2)\n";
+        case MYKONOS_ERR_INIT_INV_DACDIV:
+            return "Invalid Tx DAC divider. Use enum DACDIV_2, DACDIV_2p5 or DACDIV_4.\n";
+        case MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV:
+            return "Invalid ObsRx ADC div. (Valid 1 or 2)\n";
+        case MYKONOS_ERR_CLKPLL_INV_HSDIV:
+            return "Invalid CLKPLL HSDIV. (Valid 4 or 5)\n";
+        case MYKONOS_ERR_CLKPLL_INV_VCODIV:
+            return "Invalid CLKPLL VCODIV. Use enum VCODIV_1, VCODIV_1p5, VCODIV_2, VCODIV_3\n";
+        case MYKONOS_ERR_CLKPLL_INV_RXTXPROFILES:
+            return "No Rx or Tx profile is specified.\n";
+        case MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX:
+            return "CLKPLL VCO frequency out of range.\n";
+        case MYKONOS_ERR_SETCLKPLL_INV_FRACWORD:
+            return "CLKPLL fractional word is non zero.\n";
+        case MYKONOS_ERR_SETRFPLL_INV_PLLNAME:
+            return "Invalid pllName requested in setRfPllFreuquency()\n";
+        case MYKONOS_ERR_SETRFPLL_INV_LO_PARM:
+            return "RF PLL frequency out of range\n";
+        case MYKONOS_ERR_GETRFPLL_INV_PLLNAME:
+            return "Invalid pllName requested in getRfPllFrequency()\n";
+        case MYKONOS_ERR_GETRFPLL_ARMERROR:
+            return "ARM Command Error in MYKONOS_getRfPllFrequency()\n";
+        case MYKONOS_ERR_GETRFPLL_NULLPARAM:
+            return "NULL pointer in function parameter for MYKONOS_setRfPllFrequency()\n";
+        case MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM:
+            return "Could not scale device clock into range 40MHz to 80Mhz.\n";
+        case MYKONOS_ERR_SETRFPLL_INV_VCOINDEX:
+            return "RFPLL VCO frequency out of range.\n";
+        case MYKONOS_ERR_SETRFPLL_INV_REFCLK:
+            return "Unsupported PLL reference clock or refclk out of range.\n";
+        case MYKONOS_ERR_SETORXGAIN_INV_CHANNEL:
+            return "Invalid ObsRx channel in setObsRxManualGain().\n";
+        case MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN:
+            return "Invalid gain requested in setObsRxManualGain() for ORX1\n";
+        case MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN:
+            return "Invalid gain requested in setObsRxManualGain() for ORX2\n";
+        case MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN:
+            return "Invalid gain requested in setObsRxManualGain() for Sniffer\n";
+        case MYKONOS_ERR_GETORX1GAIN_INV_POINTER:
+            return "Cannot return ORx1 gain to gain control data structure (invalid pointer).\n";
+        case MYKONOS_ERR_GETORX2GAIN_INV_POINTER:
+            return "Cannot return ORx2 gain to gain control data structure (invalid pointer).\n";
+        case MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER:
+            return "Cannot return Sniffer gain to gain control data structure (invalid pointer).\n";
+        case MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED:
+            return "Cannot read ObsRx gain index. ObsRx Channel is disabled.\n";
+        case MYKONOS_ERR_SETTX1ATTEN_INV_PARM:
+            return "Tx1 attenuation is out of range (0 - 41950 mdB).\n";
+        case MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM:
+            return "Invalid Tx1Atten stepsize. Use enum mykonosTxAttenStepSize_t\n";
+        case MYKONOS_ERR_SETTX2ATTEN_INV_PARM:
+            return "Tx2 attenuation is out of range (0 - 41950 mdB).\n";
+        case MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM:
+            return "Invalid Tx2Atten stepsize. Use enum mykonosTxAttenStepSize_t\n";
+        case MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM:
+            return "Invalid number of FIR taps\n";
+        case MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM:
+            return "Invalid number of FIR taps read for the selected Filter\n";
+        case MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM:
+            return "Invalid FIR filter name requested. use enum mykonosfirName_t\n";
+        case MYKONOS_ERR_RXFIR_INV_GAIN_PARM:
+            return "Rx FIR filter has invalid gain setting\n";
+        case MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM:
+            return "ObsRx FIR filter A (ORx) has invalid gain setting\n";
+        case MYKONOS_ERR_SRXFIR_INV_GAIN_PARM:
+            return "ObsRx FIR filter B (Sniffer) has invalid gain setting\n";
+        case MYKONOS_ERR_TXFIR_INV_GAIN_PARM:
+            return "Tx FIR filter has invalid gain setting\n";
+        case MYKONOS_ERR_READFIR_NULL_PARM:
+            return "MYKONOS_readFir() has a null *firFilter parameter\n";
+        case MYKONOS_ERR_READFIR_COEFS_NULL:
+            return "MYKONOS_readFir() has a null coef array in *firFilter structure\n";
+        case MYKONOS_ERR_READFIR_INV_FIRNAME_PARM:
+            return "Invalid FIR filter name requested. use enum mykonosfirName_t\n";
+        case MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM:
+            return "Rx1 manual gain index out of range of gain table\n";
+        case MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM:
+            return "Rx2 manual gain index out of range of gain table\n";
+        case MYKONOS_ERR_INITSER_INV_VCODIV_PARM:
+            return "Found invalid VCO divider value during setupSerializers()\n";
+        case MYKONOS_ERR_INITDES_INV_VCODIV_PARM:
+            return "Found invalid VCO divider value during setupDeserializers()\n";
+        case MYKONOS_ERR_SER_INV_M_PARM:
+            return "Invalid JESD Framer M parameter during setupSerializers()\n";
+        case MYKONOS_ERR_SER_INV_L_PARM:
+            return "Invalid JESD Framer L parameter during setupSerializers()\n";
+        case MYKONOS_ERR_SER_INV_HSCLK_PARM:
+            return "Invalid HSCLK frequency in setupSerializers()\n";
+        case MYKONOS_ERR_SER_INV_LANERATE_PARM:
+            return "Invalid Lanerate frequency in setupSerializer()\n";
+        case MYKONOS_ERR_SER_INV_LANEEN_PARM:
+            return "Invalid number of JESD204 lanes enabled.\n";
+        case MYKONOS_ERR_SER_INV_AMP_PARM:
+            return "Invalid JESD204 serializer amplitude\n";
+        case MYKONOS_ERR_SER_INV_PREEMP_PARM:
+            return "Invalid JESD204 serializer preemphasis setting\n";
+        case MYKONOS_ERR_SER_INV_LANEPN_PARM:
+            return "Invald JESD204 serializer PN invert setting\n";
+        case MYKONOS_ERR_SER_LANE_CONFLICT_PARM:
+            return "Rx framer and ObsRx framer are attempting to use the same physical lanes\n";
+        case MYKONOS_ERR_SER_INV_TXSER_DIV_PARM:
+            return "Invalid serializer lane clock divider\n";
+        case MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM:
+            return "Rx lane and ObsRx lane rate must match\n";
+        case MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM:
+            return "Framer M can only =1 if Real IF data option is enabled\n";
+        case MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT:
+            return "Serializer HSCLK and lane clock are not integer multiples\n";
+        case MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT:
+            return "Deserializer HSCLK and lane clock are not integer multiples\n";
+        case MYKONOS_ERR_DESER_INV_M_PARM:
+            return "Invalid deserializer M value. (Valid 2 or 4)\n";
+        case MYKONOS_ERR_DESER_INV_L_PARM:
+            return "Invalid deserializer L value. (Valid 1,2,4)\n";
+        case MYKONOS_ERR_DESER_INV_HSCLK_PARM:
+            return "Invalid HSCLK in setupDeserializer()\n";
+        case MYKONOS_ERR_DESER_INV_LANERATE_PARM:
+            return "Invalid deserializer lane rate\n";
+        case MYKONOS_ERR_DESER_INV_LANEEN_PARM:
+            return "Invalid number of deserializer lanes enabled\n";
+        case MYKONOS_ERR_DESER_INV_EQ_PARM:
+            return "Invalid deserializer EQ setting";
+        case MYKONOS_ERR_DESER_INV_LANEPN_PARM:
+            return "Invalid deserializer invert Lane PN setting\n";
+        case MYKONOS_ERR_FRAMER_INV_M_PARM:
+            return "Invalid Rx framer M setting\n";
+        case MYKONOS_ERR_FRAMER_INV_BANKID_PARM:
+            return "Invalid Rx framer Bank ID\n";
+        case MYKONOS_ERR_FRAMER_INV_LANEID_PARM:
+            return "Invalid Rx framer Lane ID\n";
+        case MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM:
+            return "Invalid Rx framer LMFC offset\n";
+        case MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM:
+            return "Invalid Rx framer Real IF setting\n";
+        case MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM:
+            return "Invalid ObsRx Framer M value\n";
+        case MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM:
+            return "Invalid ObsRx Framer Bank ID\n";
+        case MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM:
+            return "Invalid ObsRx framer Lane ID\n";
+        case MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM:
+            return "Invalid ObsRx framer LMFC offset\n";
+        case MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM:
+            return "Invalid ObsRx framer Real IF setting, M must =1\n";
+        case MYKONOS_ERR_DEFRAMER_INV_M_PARM:
+            return "Invalid Deframer M setting\n";
+        case MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM:
+            return "Invalid Deframer Bank ID\n";
+        case MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM:
+            return "Invalid Deframer Lane ID\n";
+        case MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM:
+            return "Invalid Deframer LMFC offset";
+        case MYKONOS_ERR_DEFRAMER_INV_K_PARAM:
+            return "Invalid Deframer K setting\n";
+        case MYKONOS_ERR_DEFRAMER_INV_FK_PARAM:
+            return "Invalid Deframer F*K value\n";
+        case MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM:
+            return "Invalid polyOrder parameter in enableRxFramerPrbs()\n";
+        case MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM:
+            return "Invalid polyOrder parameter in enableObsRxFramerPrbs()\n";
+        case MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM:
+            return "Invalid enable parameter value in enableDeframerPrbsChecker()\n";
+        case MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM:
+            return "Invalid polyOrder parameter in enableDeframerPrbsChecker()\n";
+        case MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM:
+            return "Invalid lane counter select in readDeframerPrbsCounters()\n";
+        case MYKONOS_ERR_INITARM_INV_DATARATE_PARM:
+            return 0;
+        case MYKONOS_ERR_INITARM_INV_VCODIV:
+            return "Invalid ARM VCO divider\n";
+        case MYKONOS_ERR_INITARM_INV_REGCLK:
+            return "Invalid ARM SPI register clock rate\n";
+        case MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM:
+            return "Invalid ARM clock rate\n";
+        case MYKONOS_ERR_LOADHEX_INV_CHARCOUNT:
+            return "LoadHex() char count = 0\n";
+        case MYKONOS_ERR_LOADHEX_INVALID_FIRSTCHAR:
+            return "LoadHex() First char is not :\n";
+        case MYKONOS_ERR_LOADHEX_INVALID_CHKSUM:
+            return "LoadHex() line checksum is invalid\n";
+        case MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT:
+            return 0;
+        case MYKONOS_ERR_ARM_INVALID_BUILDCHKSUM:
+            return "Verify ARM checksum failed\n";
+        case MYKONOS_ERR_READARMMEM_INV_ADDR_PARM:
+            return "ReadArmMem() was given an invalid memory address\n";
+        case MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM:
+            return "WriteArmMem() was given an invalid memory address\n";
+        case MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM:
+            return "Invalid ARM opcode given to sendArmCommand()\n";
+        case MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM:
+            return "Invalid number of extended data in sendArmCommand()\n";
+        case MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM:
+            return "Invalid opcode given to waitArmCmdStatus()\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER:
+            return "Pointer to Mykonos device data structure is NULL\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_SPI:
+            return "Invalid spiSettings pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_RX:
+            return "Invalid device->rx pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB:
+            return "Invalid pointer within device->rx data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR:
+            return "Invalid RXFIR pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_TX:
+            return "Invalid device->tx pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB:
+            return "Invalid pointer within device->tx data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR:
+            return "Invalid TXFIR pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX:
+            return "Invalid device->obsRx pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXSUB:
+            return "Invalid pointer within device->obsRx data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR:
+            return "Invalid Sniffer FIR pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR:
+            return "Invalid ORX FIR pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL:
+            return "Invalid Orx gain control pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL:
+            return "Invalid Sniffer gain control pointer in device data structure\n";
+        case MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER:
+            return "Invalid obsRx framer pointer in device data structure\n";
+        case MYKONOS_ERR_INITSER_INV_PROFILE:
+            return "Invalid RX profile within device data structure detected in MYKONOS_setupSerializers()\n";
+        case MYKONOS_ERR_INITDES_INV_TXPROFILE:
+            return "Invalid TX profile within device data structure detected in MYKONOS_setupDeserializers()\n";
+        case MYKONOS_ERR_JESD204B_ILAS_MISMATCH:
+            return "Mismatch detected in MYKONOS_jesd204bIlasCheck()\n";
+        case MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL:
+            return "Invalid channel specified in MYKONOS_programRxGainTable()\n";
+        case MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE:
+            return "Invalid numGainIndicesinTable greater than possible number of gain indices for channel. \n";
+        case MYKONOS_ERR_WRITE_CFG_MEMORY_FAILED:
+            return "Failed write to ARM memory in MYKONOS_writeArmProfile()\n";
+        case MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM:
+            return "Invalid PCLKDIV parameter detected in MYKONOS_setupSerializers()\n";
+        case MYKONOS_ERR_RXFRAMER_INV_FK_PARAM:
+            return "Invalid FK parameter detected in MYKONOS_setupJesd204bFramer()\n";
+        case MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM:
+            return "Invalid FK paramter detected in MYKONOS_setupJesd204bObsRxFramer()\n";
+        case MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM:
+            return "Invalid PCLKDIV paramter detected in MYKONOS_setupSerializers()\n";
+        case MYKONOS_ERR_PU_OBSRXPATH_INV_LOSOURCE_PARAM:
+            return "Invalid LO Source for OBSRX data path \n";
+        case MYKONOS_ERR_ARM_RADIOON_FAILED:
+            return "ARM command to move to radioOn state failed. \n";
+        case MYKONOS_ERR_ARM_RADIOOFF_FAILED:
+            return "ARM command to move to radioOff state failed. \n";
+        case MYKONOS_ERR_INV_RX_GAIN_MODE_PARM:
+            return "Invalid gain control mode detected in MYKONOS_setRxGainControlMode()\n";
+        case MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM:
+            return "Invalid gain control mode detected in MYKONOS_setObsRxGainControlMode()\n";
+        case MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT:
+            return "Invalid RX AGC structure detected at &device->rx->rxAgcCtrl in MYKONOS_setupRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM:
+            return "device->rx->rxAgcCtrl->agcPeakWaitTime out of range in MYKONOS_setupRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM:
+            return "device->rx->rxAgcCtrl->agcGainUpdateTime_us out of range in MYKONOS_setupRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM:
+            return "device->rx->rxAgcCtrl->apdHighThresh out of range in MYKONOS_setupRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM:
+            return "device->rx->rxAgcCtrl->apdLowThresh out of range in MYKONOS_setupRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_RX_BLOCK_DET_DECAY_PARM:
+            return "device->rx->rxAgcCtrl->apdDecay out of range in MYKONOS_setupRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT:
+            return "Data structure for peakAgc not initialized when used in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT:
+            return "Data structure for powerAgc not initialized when used in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX:
+            return "device->rx->rxAgcCtrl->agcRx1MaxGainIndex out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX:
+            return "device->rx->rxAgcCtrl->agcRx1MinGainIndex out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX:
+            return "device->rx->rxAgcCtrl->agcRx2MaxGainIndex out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX:
+            return "device->rx->rxAgcCtrl->agcRx2MinGainIndex out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY:
+            return "device->rx->rxAgcCtrl->agcSlowLoopSettlingDelay out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdMeasDuration out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdMeasConfig out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC:
+            return "device->rx->rxAgcCtrl->agcLowThsPreventGainIncrease out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE:
+            return "device->rx->rxAgcCtrl->agcPeakThresholdMode out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE:
+            return "device->rx->rxAgcCtrl->agcResetOnRxEnable out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER:
+            return "device->rx->rxAgcCtrl->agcEnableSyncPulseForGainCounter out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdLowerHighThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdUpperLowThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdLowerLowThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdUpperHighThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP:
+            return "device->rx->rxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE:
+            return "device->rx->rxAgcCtrl->peakAgc->apdFastAttack or hb2FastAttack out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2HighThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2LowThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2VeryLowThresh out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->apdHighGainStepAttack out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->apdLowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2HighGainStepAttack out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2LowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2OverloadEnable out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2OverloadThreshCnt out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT:
+            return "device->rx->rxAgcCtrl->peakAgc->hb2OverloadDurationCnt out of range in MYKONOS_setupRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT:
+            return "Invalid OBSRX AGC structure detected at &device->obsRx->orxAgcCtrl in MYKONOS_setupObsRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT:
+            return "Data structure for obsRx->orxAgcCtrl->peakAgc not initialized when used in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT:
+            return "Data structure for obsRx->orxAgcCtrl->powerAgc not initialized when used in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX:
+            return "device->obsRx->orxAgcCtrl->agcObsRxMaxGainIndex out of range in  MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX:
+            return "device->obsRx->orxAgcCtrl->agcObsRxMinGainIndex out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_SELECT:
+            return "device->obsRx->orxAgcCtrl->agcObsRxSelect out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM:
+            return "device->obsRx->orxAgcCtrl->agcGainUpdateTime_us out of range in MYKONOS_setupObsRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM:
+            return "device->obsRx->orxAgcCtrl->agcPeakWaitTime out of range in MYKONOS_setupObsRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY:
+            return "device->obsRx->orxAgcCtrl->agcSlowLoopSettlingDelay out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdMeasDuration out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdMeasConfig out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC:
+            return "device->obsRx->orxAgcCtrl->agcLowThsPreventGainIncrease out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE:
+            return "device->obsRx->orxAgcCtrl->agcPeakThresholdMode out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE:
+            return "device->obsRx->orxAgcCtrl->agcResetOnRxEnable out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER:
+            return "device->obsRx->orxAgcCtrl->agcEnableSyncPulseForGainCounter out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperHighGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerLowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdUpperLowGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE:
+            return "device->obsRx->orxAgcCtrl->peakAgc->apdFastAttack or hb2FastAttack out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM:
+            return "device->obsRx->orxAgcCtrl->apdHighThresh out of range in MYKONOS_setupObsRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM:
+            return "device->obsRx->orxAgcCtrl->apdLowThresh out of range in MYKONOS_setupObsRxAgc()\n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2HighThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2LowThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowThresh out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->apdHighGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->apdLowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2HighGainStepAttack out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2LowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2VeryLowGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadEnable out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadDurationCnt out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT:
+            return "device->obsRx->orxAgcCtrl->peakAgc->hb2OverloadThresholdCnt out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP:
+            return "device->obsRx->orxAgcCtrl->powerAgc->pmdLowerHighGainStepRecovery out of range in MYKONOS_setupObsRxAgc() \n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CALPLL_LOCK:
+            return "CAL PLL Lock event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLLCP:
+            return "Clock PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLL_LOCK:
+            return "Clock PLL Lock event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLLCP:
+            return "RX PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLL_LOCK:
+            return "RX PLL Lock event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLLCP:
+            return "TX PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLL_LOCK:
+            return "TX PLL Lock event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLLCP:
+            return "Sniffer PLL Charge Pump Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLL_LOCK:
+            return "Sniffer PLL Lock event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXBBFCALDONE:
+            return "RX Baseband Filter Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXBBFCALDONE:
+            return "TX Baseband Filter Cal timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RFDCCALDONE:
+            return "RF DC Offset Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ADCTUNECALDONE:
+            return "ADC Tuner Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX1ADCPROFILE:
+            return "Rx1 ADC Profile Loading event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX2ADCPROFILE:
+            return "Rx2 ADC Profile Loading event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ORXADCPROFILE:
+            return "ObsRx ADC Profile Loading event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RCALDONE:
+            return "Resistor Cal event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ARMBUSY:
+            return "ARM Busy event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_INITARMDONE:
+            return "Initialize ARM event timed out in MYKONOS_waitForEvent()\n";
+        case MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY:
+            return "ARM Mailbox Busy. Command not executed in MYKONOS_sendArmCommand()\n";
+        case MYKONOS_ERR_PU_OBSRXPATH_ARMERROR:
+            return "ARM Command Error in MYKONOS_setObsRxPathSource()\n";
+        case MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR:
+            return "Device not in radioOff/IDLE state. Error in MYKONOS_enableTrackingCals()\n";
+        case MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR:
+            return "ARM Command Error in MYKONOS_enableTrackingCals()\n";
+        case MYKONOS_ERR_SETRFPLL_ARMERROR:
+            return "ARM Command Error in MYKONOS_setRfPllFrequency()\n";
+        case MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM:
+            return "device->tx->txProfile->txInputHbInterpolation out of range in MYKONOS_initialize(): valid = 1,2 or 4\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV:
+            return "device->clocks->clkPllVcoDiv value not supported in MYKONOS_loadAdcProfiles\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED:
+            return "Custom RX ADC Profile required\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED:
+            return "Custom ORX ADC Profile required\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED:
+            return "Custom SNRX ADC Profile required\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED:
+            return "Custom Loopback ADC profile required\n";
+        case MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED:
+            return "WriteArmMemory call failed while writing the Loopback ADC profile into ARM memory\n";
+        case MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED:
+            return "WriteArmMemory call failed while writing the Sniffer ADC profile into ARM memory\n";
+        case MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED:
+            return "WriteArmMemory call failed while writing the ObsRx ADC profile into ARM memory\n";
+        case MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED:
+            return "WriteArmMemory call failed while writing the RX ADC profile into ARM memory\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO:
+            return "SnRx profile has invalid ADC divider of 0, causing a divide by zero\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO:
+            return "ORx profile has invalid ADC divider of 0, causing a divide by zero\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO:
+            return "Rx profile has invalid ADC divider of 0, causing a divide by zero\n";
+        case MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE:
+            return "If Tx Profile is valid, a matching ORx profile must be provided to set ADC divider and digital filtering for loopback calibrations\n";
+        case MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION:
+            return "Invalid setting for avgDuration in MYKONOS_setupPaProtection(...)\n";
+        case MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP:
+            return "Invalid setting for attenStepSize in MYKONOS_setupPaProtection(...)\n";
+        case MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_ENABLE:
+            return "Invalid setting for txAttenControlEnable in MYKONOS_setupPaProtection(...)\n";
+        case MYKONOS_ERR_SETUP_PA_PROT_INV_POWER_THRESH:
+            return "Invalid setting for powerThreshold in MYKONOS_setupPaProtection(...)\n";
+        case MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL:
+            return "Invalid TX channel selected for MYKONOS_getDacPower(...)\n";
+        case MYKONOS_ERR_GET_DAC_PWR_INV_POINTER:
+            return "Cannot return DAC Power information (invalid pointer)\n";
+        case MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER:
+            return "Cannot return PA Protection Flag Status information (invalid pointer)\n";
+        case MYKONOS_ERR_GET_OBSRX_OVERLOADS_NULL_PARM:
+            return "MYKONOS_getObsRxPathOverloads() has null *obsRxOverloads parameter\n";
+        case MYKONOS_ERR_GET_RX1_OVERLOADS_NULL_PARM:
+            return "MYKONOS_getRxPathOverloads() has null *rx1Overloads parameter\n";
+        case MYKONOS_ERR_GET_RX2_OVERLOADS_NULL_PARM:
+            return "MYKONOS_getRxPathOverloads() has null *rx2Overloads parameter\n";
+        case MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM:
+            return "MYKONOS_getRadioState() has null *radioStatus parameter\n";
+        case MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM:
+            return "MYKONOS_abortInitCals() has null *calsCompleted parameter\n";
+        case MYKONOS_ERR_WAIT_INITCALS_ARMERROR:
+            return "MYKONOS_waitInitCals() returned an ARM error\n";
+        case MYKONOS_ERR_WAIT_INITCALS_NULL_PARAM:
+            return "MYKONOS_waitInitCals() has one or more null parameters\n";
+        case MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM:
+            return "MYKONOS_checkPllsLockStatus() has a null *pllLockStatus parameter\n";
+        case MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM:
+            return "MYKONOS_getTxFilterOverRangeStatus() has a null *txFilterStatus parameter\n";
+        case MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM:
+            return "MYKONOS_programRxGainTable() has a null *gainTablePtr parameter\n";
+        case MYKONOS_ERR_PROGRAMFIR_NULL_PARM:
+            return "MYKONOS_programFir() has a null *firFilter parameter\n";
+        case MYKONOS_ERR_PROGRAMFIR_COEFS_NULL:
+            return "MYKONOS_programFir() has a null coef array in *firFilter structure\n";
+        case MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM:
+            return "MYKONOS_readDeframerStatus() has a null *deframerStatus parameter\n";
+        case MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM:
+            return "MYKONOS_readDeframerPrbscounters() has a null *prbsErrorCount parameter\n";
+        case MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM:
+            return "MYKONOS_readOrxFramerStatus() has a null *obsFramerStatus parameter\n";
+        case MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM:
+            return "MYKONOS_readRxFramerStatus() has a null *framerStatus parameter\n";
+        case MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM:
+            return "MYKONOS_waitArmCmdStatus() has a null *cmdStatByte parameter\n";
+        case MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM:
+            return "MYKONOS_readArmCmdStatus() has one or more null pointer parameters\n";
+        case MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM:
+            return "MYKONOS_readArmCmdStatusByte() has an invalid opcode parameter\n";
+        case MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM:
+            return "MYKONOS_readArmCmdStatusByte() has a null *cmdStatByte parameter\n";
+        case MYKONOS_ERR_ARMCMD_NULL_PARM:
+            return "MYKONOS_sendArmCommand() has a null *extendedData parameter\n";
+        case MYKONOS_ERR_WRITEARMMEM_NULL_PARM:
+            return "MYKONOS_writeArmMem() has a null *data parameter\n";
+        case MYKONOS_ERR_LOADBIN_NULL_PARAM:
+            return "MYKONOS_loadArmFromBinary() has a null *binary parameter\n";
+        case MYKONOS_ERR_GETTX1ATTEN_NULL_PARM:
+            return "MYKONOS_getTx1Attenuation() has NULL tx1Attenuation_mdB parameter\n";
+        case MYKONOS_ERR_GETTX2ATTEN_NULL_PARM:
+            return "MYKONOS_getTx2Attenuation() has NULL tx2Attenuation_mdB parameter\n";
+        case MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM:
+            return "Invalid serializer Lanes Enable parameter in Rx framer structure\n";
+        case MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM:
+            return "Invalid serializer Lanes Enable parameter in ObsRx framer structure\n";
+        case MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID:
+            return "Can not enable Tx NCO when Tx Profile is invalid\n";
+        case MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID:
+            return "Invalid Tx1 NCO frequency\n";
+        case MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID:
+            return "Invalid Tx2 NCO frequency\n";
+        case MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM:
+            return "Function parameter has NULL pointer in MYKONOS_jesd204bIlasCheck()\n";
+        case MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV:
+            return "CLKPLL refclk divider was read back as an invalid setting in MYKONOS_getRfPllFrequency()\n";
+        case MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV:
+            return "CLKPLL HSDIV divider was read back as an invalid setting in MYKONOS_getRfPllFrequency()\n";
+        case MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM:
+            return "MYKONOS_getRx1DecPower() has a null *rx1DecPower_mdBFS parameter\n";
+        case MYKONOS_ERR_GET_RX1_DEC_POWER_NUM_SAMPLES:
+            return "MYKONOS_getRx1DecPower() numSamples greater than agcGainUpdateCounter\n";
+        case MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM:
+            return "MYKONOS_getRx2DecPower() has a null *rx2DecPower_mdBFS parameter\n";
+        case MYKONOS_ERR_GET_RX2_DEC_POWER_NUM_SAMPLES:
+            return "MYKONOS_getRx2DecPower() numSamples greater than agcGainUpdateCounter\n";
+        case MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM:
+            return "MYKONOS_getObsRxDecPower() has a null *obsRxDecPower_mdBFS parameter\n";
+        case MYKONOS_ERR_GET_OBSRX_DEC_POWER_NUM_SAMPLES:
+            return "MYKONOS_getObsRxDecPower() numSamples greater than agcGainUpdateCounter\n";
+        case MYKONOS_ERR_GETARMVER_NULL_PARM:
+            return "MYKONOS_getArmVersion() has a NULL pointer in one of the function parameters\n";
+        case MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR:
+            return "ARM is not in the RadioOff state before MYKONOS_enableDpdTracking(), call MYKONOS_radioOff()\n";
+        case MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE:
+            return "MYKONOS_restoreDpdModel() supplied DPD Model Data Buffer is incorrect size\n";
+        case MYKONOS_ERR_RESTDPDMOD_ARMSTATE:
+            return "ARM is not in the RadioOff state before MYKONOS_restoreDpdModel(), call MYKONOS_radioOff()\n";
+        case MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL:
+            return "MYKONOS_restoreDpdModel() invalid txChannel specified\n";
+        case MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE:
+            return "MYKONOS_saveDpdModelL() supplied DPD Model Data Buffer is incorrect size\n";
+        case MYKONOS_ERR_SAVDPDMOD_ARMSTATE:
+            return "ARM is not in the RadioOff state before MYKONOS_saveDpdModelL(), call MYKONOS_radioOff()\n";
+        case MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL:
+            return "MYKONOS_saveDpdModelL() invalid txChannel specified\n";
+        case MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR:
+            return "ARM is not in the RadioOff state before MYKONOS_enableClgcTracking(), call MYKONOS_radioOff()\n";
+        case MYKONOS_ERR_CFGDPD_ARMSTATE_ERROR:
+            return "MYKONOS_configDpd() was called while ARM was not in radioOff state\n";
+        case MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV:
+            return "Tx or ORx profile is not valid, both are necessary for DPD features in MYKONOS_configDpd()\n";
+        case MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT:
+            return "device->tx->dpdConfig structure has NULL pointer in MYKONOS_configDpd()\n";
+        case MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG:
+            return "The ARM reported a error while writing to an ARM config structure in MYKONOS_writeArmCfgStruct()\n";
+        case MYKONOS_ERR_CFGDPD_INV_DPDDAMPING:
+            return "ERROR: device->tx->dpdConfig->damping parameter is out of range (0-15)\n";
+        case MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES:
+            return "ERROR: device->tx->dpdConfig->samples parameter is out of range (64 - 32768)\n";
+        case MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS:
+            return "ERROR: device->tx->dpdConfig->numWeights parameter is out of range (0-3)\n";
+        case MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH:
+            return "ERROR: device->tx->dpdConfig->outlierThreshold parameter is out of range\n";
+        case MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT:
+            return "ERROR: device->tx->dpdConfig->modelPriorWeight parameter is out of range (Valid 0-32)\n";
+        case MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN:
+            return "ERROR: device->tx->clgcConfig->tx1DesiredGain or tx2DesiredGain parameter is out of range\n";
+        case MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT:
+            return "ERROR: device->tx->clgcConfig->tx1AttenLimit or tx2AttenLimit parameter is out of range\n";
+        case MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO:
+            return "ERROR: device->tx->clgcConfig->tx1ControlRatio or tx2ControlRatio parameter is out of range\n";
+        case MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY:
+            return "ERROR: device->tx->dpdConfig->additionalDelayOffset parameter is out of range\n";
+        case MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL:
+            return "ERROR: device->tx->dpdConfig->pathDelayPnSeqLevel parameter is out of range\n";
+        case MYKONOS_ERR_CFGDPD_INV_MODELVERSION:
+            return "ERROR: device->tx->dpdConfig->modelVersion parameter is out of range\n";
+        case MYKONOS_ERR_READARMCFG_ARMERRFLAG:
+            return "ERROR: MYKONOS_readArmConfig failed due to an ARM error\n";
+        case MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM:
+            return "MYKONOS_getPendingTrackingCals() has NULL function parameter\n";
+        case MYKONOS_ERR_ARMCMDSTATUS_ARMERROR:
+            return "MYKONOS_waitArmCmdStatus() exited due to ARM error for the desired ARM opcode\n";
+        case MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT:
+            return "MYKONOS_waitArmCmdStatus() timed out waiting for the ARM to complete the requested command\n";
+        case MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR:
+            return "ARM returned an error while trying to get the ObsRx Path source in MYKONOS_getObsRxPathSource()\n";
+        case MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT:
+            return "MYKONOS_getDpdConfig() could not complete due to a NULL pointer to device->tx->dpdConfig structure\n";
+        case MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV:
+            return "The Tx and ORx profiles must be valid for DPD related functions\n";
+        case MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG:
+            return "MYKONOS_getDpdStatus() reported an ARM error with the ARM Get command\n";
+        case MYKONOS_ERR_GETDPDSTATUS_NULLPARAM:
+            return "MYKONOS_getDpdStatus() has NULL pointer in the function parameter\n";
+        case MYKONOS_ERR_SETDEFOBSRXPATH_NULL_OBSRX_STRUCT:
+            return "Observation profile not valid, device->obsRx structure is NULL in MYKONOS_setDefaultObsRxPath()\n";
+        case MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM:
+            return "MYKONOS_getClgcStatus() has NULL clgcStatus parameter\n";
+        case MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG:
+            return "ARM reported an error with the ARM GET command during MYKONOS_getClgcStatus()\n";
+        case MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM:
+            return "MYKONOS_getDeframerFifoDepth() function parameter fifoDepth is a NULL pointer\n";
+        case MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM:
+            return "MYKONOS_getDeframerFifoDepth() function parameter readEnLmfcCount is a NULL pointer\n";
+        case MYKONOS_ERR_GETDPDSTATUS_INV_CH:
+            return "MYKONOS_getDpdStatus() txChannel parameter is not valid (TX1 and TX2 are the only valid options)\n";
+        case MYKONOS_ERR_GETCLGCSTATUS_INV_CH:
+            return "MYKONOS_getClgcStatus() txChannel parameter is not valid (TX1 and TX2 are the only valid options)\n";
+        case MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE:
+            return "Invalid Tx profile: When using Tx Input halfband, IQ rate must not exceed 160MSPS\n";
+        case MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE:
+            return "Invalid Tx profile: When using Tx Input halfband 0, IQ rate must not exceed 80MSPS\n";
+        case MYKONOS_ERR_RXFIR_TAPSEXCEEDED:
+            return "Rx PFIR can not be clocked fast enough to handle the number of FIR coefficents provided\n";
+        case MYKONOS_ERR_ORXFIR_TAPSEXCEEDED:
+            return "ORx PFIR can not be clocked fast enough to handle the number of FIR coefficents provided\n";
+        case MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED:
+            return "Sniffer Rx PFIR can not be clocked fast enough to handle the number of FIR coefficents provided\n";
+        case MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM:
+            return "Invalid number of Tx FIR coefficients\n";
+        case MYKONOS_ERR_TXFIR_INV_NUMROWS:
+            return "Invalid number of PFIR coefficient rows\n";
+        case MYKONOS_ERR_TXFIR_TAPSEXCEEDED:
+            return "Too many Tx PFIR taps for the IQ sample rate.  FIR processing clock can not run fast enough to handle the number of taps\n";
+        case MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM:
+            return "MYKONOS_getInitCalStatus() has a null pointer in parameter list\n";
+        case MYKONOS_ERR_GETINITCALSTATUS_ARMERROR:
+            return "MYKONOS_getInitCalStatus() returned an ARM error while getting the init cal status information";
+        case MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV:
+            return "Tx and ObsRx profiles must be valid to use the CLGC feature in MYKONOS_configClgc()\n";
+        case MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT:
+            return "CLGC config structure is NULL in device->tx->clgcConfig in MYKONOS_configClgc()\n";
+        case MYKONOS_ERR_CFGCLGC_ARMSTATE_ERROR:
+            return "CLGC config could not be set because ARM is not in radioOff or ready state in MYKONOS_configClgc()\n";
+        case MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV:
+            return "Could not read back CLGC status because Tx and ORx profiles are not valid\n";
+        case MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT:
+            return "Could not read back CLGC status because return structure device->tx->clgcConfig pointer is NULL\n";
+        case MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM:
+            return "device structure pointer is NULL in MYKONOS_calculateDigitalClocks()\n";
+        case MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT:
+            return "device->clocks structure pointer is NULL in MYKONOS_calculateDigitalClocks()\n";
+        case MYKONOS_ERR_NULL_DEVICE_PARAM:
+            return "The device pointer in the calling function's parameter list is a NULL pointer\n";
+        case MYKONOS_ERR_CALCDEVCLK_NULLPARAM:
+            return "MYKONOS_calculateScaledDeviceClk_kHz() has a NULL pointer in one of the function parameters\n";
+        case MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY:
+            return "CLGC Additional Delay parameter is out of range in MYKONOS_configClgc\n";
+        case MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL:
+            return "CLGC PN Sequence level parameter is out of range in MYKONOS_configClgc\n";
+        case MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV:
+            return "The Tx and ORx profiles must be valid to use the VSWR feature in MYKONOS_configVswr()\n";
+        case MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR:
+            return "ARM must be in radioOff state to configure the VSWR config parameters in MYKONOS_configVswr()\n";
+        case MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN:
+            return "VSWR 3.3v GPIO pin selection is out of range (0-11) in MYKONOS_configVswr()\n";
+        case MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL:
+            return "VSWR init PN sequence level is out of range in MYKONOS_configVswr()\n";
+        case MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY:
+            return "VSWR additionalDelay member is out of range in MYKONOS_configVswr()\n";
+        case MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT:
+            return "device->tx->vswrConfig pointer is null in MYKONOS_confgiVswr()\n";
+        case MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT:
+            return "device->tx->vswrConfig pointer is null in MYKONOS_getVswrConfig()\n";
+        case MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV:
+            return "Tx and ORx profiles must be valid in MYKONOS_getVswrConfig()\n";
+        case MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG:
+            return "ARM returned an error while attempting to read the VSWR status structure\n";
+        case MYKONOS_ERR_GETVSWRSTATUS_INV_CH:
+            return "Invalid Tx channel parameter passed to MYKONOS_getVswrStatus()\n";
+        case MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM:
+            return "vswrStatus function parameter is null in MYKONOS_getVswrStatus\n";
+        case MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX:
+            return "Max gain index bigger than max gain index loaded table in MYKONOS_setRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX:
+            return "Min gain index lower than min gain index loaded table in MYKONOS_setRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL:
+            return "Wrong RX channel selected in MYKONOS_setRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL:
+            return "Wrong read back channel in MYKONOS_setObsRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX:
+            return "Max gain index bigger than max gain index loaded table in MYKONOS_setObsRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX:
+            return "Min gain index lower than min gain index loaded table in MYKONOS_setObsRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL:
+            return "Wrong observation channel selected in MYKONOS_setObsRxAgcMinMaxGainIndex().\n";
+        case MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE:
+            return "The temp gain compensation is outside range (-3000mdB to 3000mdB) in MYKONOS_setRx1TempGainComp().\n";
+        case MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP:
+            return "Not valid temp gain compensation, step size is 250mdB in MYKONOS_setRx1TempGainComp().\n";
+        case MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE:
+            return "The temp gain compensation is outside range (-3000mdB to 3000mdB) in MYKONOS_setRx2TempGainComp().\n";
+        case MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP:
+            return "Not valid temp gain compensation, step size is 250mdB in MYKONOS_setRx2TempGainComp().\n";
+        case MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE:
+            return "The temp gain compensation is outside range (-3000mdB to 3000mdB) in MYKONOS_setObsRxTempGainComp().\n";
+        case MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP:
+            return "Not valid temp gain compensation, step size is 250mdB in MYKONOS_setObsRxTempGainComp().\n";
+        case MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL:
+            return "rx1TempCompGain_mdB pointer is null MYKONOS_getRx1TempGainComp().\n";
+        case MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL:
+            return "rx2TempCompGain_mdB pointer is null MYKONOS_getRx2TempGainComp().\n";
+        case MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL:
+            return "obsRxTempCompGain_mdB pointer is null MYKONOS_getObsRxTempGainComp().\n";
+        case MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM:
+            return "Function parameter mykonosOrxQecStatus_t is a NULL pointer in MYKONOS_getOrxQecStatus().\n";
+        case MYKONOS_ERR_GETORXQECSTATUS_INV_CH:
+            return "Channel selection not valid in MYKONOS_getOrxQecStatus().\n";
+        case MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG:
+            return "ARM command error in MYKONOS_getOrxQecStatus().\n";
+        case MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM:
+            return "Function parameter mykonosRxQecStatus_t is a NULL pointer in MYKONOS_getRxQecStatus().\n";
+        case MYKONOS_ERR_GETRXQECSTATUS_INV_CH:
+            return "Channel selection not valid in MYKONOS_getRxQecStatus().\n";
+        case MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG:
+            return "ARM command error in MYKONOS_getRxQecStatus().\n";
+        case MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM:
+            return "Function parameter mykonosTxQecStatus_t is a NULL pointer in MYKONOS_getRxQecStatus().\n";
+        case MYKONOS_ERR_GETTXQECSTATUS_INV_CH:
+            return "Channel selection not valid in MYKONOS_getTxQecStatus().\n";
+        case MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG:
+            return "ARM command error in MYKONOS_getTxQecStatus().\n";
+        case MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM:
+            return "Function parameter mykonosTxLolStatus_t is a NULL pointer in MYKONOS_getTLolStatus().\n";
+        case MYKONOS_ERR_GETTXLOLSTATUS_INV_CH:
+            return "Channel selection not valid in MYKONOS_getTLolStatus().\n";
+        case MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG:
+            return "ARM command error in MYKONOS_getTLolStatus().\n";
+        case MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV:
+            return "Not valid calibration passed to MYKONOS_rescheduleTrackingCal().\n";
+        case MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG:
+            return "ARM error in MYKONOS_rescheduleTrackingCal().\n";
+        case MYKONOS_ERR_ARMSTATE_EXCEPTION:
+            return "ARM system problem has been detected.\n";
+        case MYKONOS_ERR_ARMSTATE_CAL_ERROR:
+            return "ARM has detected an error in the tracking calibrations.\n";
+        case MYKONOS_ERR_ARMSTATE_PROFILE_ERROR:
+            return "ARM has detected an illegal profile.\n";
+        case MYKONOS_ERR_WAITARMCSTATE_TIMEOUT:
+            return "Timeout occurred in MYKONOS_checkArmState().\n";
+        case MYKONOS_ERR_GET_API_VERSION_NULL_PARAM:
+            return "Null parameter passed to the function MYKONOS_getApiVersion().\n";
+        case MYKONOS_ERR_GETPRODUCTID_NULL_PARAM:
+            return "Null parameter passed to the function MYKONOS_getProductId().\n";
+        case MYKONOS_ERR_TXPROFILE_IQRATE:
+            return "Tx Profile IQ rate out of range.\n";
+        case MYKONOS_ERR_TXPROFILE_RFBW:
+            return "Tx Profile RF bandwidth out of range.\n";
+        case MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION:
+            return "Tx Filter interpolation not valid.\n";
+        case MYKONOS_ERR_TXPROFILE_FIR_COEFS:
+            return "Tx FIR filter not valid.\n";
+        case MYKONOS_ERR_RXPROFILE_RXCHANNEL:
+            return " Rx channel is not valid.\n";
+        case MYKONOS_ERR_RXPROFILE_IQRATE:
+            return "Receiver profile out of range IQ rate.\n";
+        case MYKONOS_ERR_RXPROFILE_RFBW:
+            return "Receiver profile out of range RF bandwidth.\n";
+        case MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION:
+            return "Receiver profile not valid filter decimation setting.\n";
+        case MYKONOS_ERR_RXPROFILE_FIR_COEFS:
+            return "Receiver profile FIR filter not valid.\n";
+        case MYKONOS_ERR_RXPROFILE_ADCDIV:
+            return "Receiver profile not valid ADC divider.\n";
+        case MYKONOS_ERR_PROFILES_HSDIGCLK:
+            return "Profile combinations loaded are not valid.\n";
+        case MYKONOS_ERR_RESET_TXLOL_INV_PARAM:
+            return "Selected channel is not valid.\n";
+        case MYKONOS_ERR_RESET_TXLOL_ARMERROR:
+            return "ARM command error in MYKONOS_resetExtTxLolChannel().\n";
+        case MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV:
+            return "Not valid calibration mask passed for trackCals.\n";
+        case MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG:
+            return "ARM error flag set.\n";
+        case MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG:
+            return "ARM error flag set.\n";
+        case MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR:
+            return "ARM command error.\n";
+        case MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM:
+            return "Null parameter passed for trackCals.\n";
+        case MYKONOS_ERR_SETSTATE_TRACK_CAL_INV:
+            return "Not valid calibration passed.\n";
+        case MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG:
+            return "ARM command error.\n";
+        case MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM:
+            return "Null parameter passed to trackCalState.\n";
+        case MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG:
+            return "ARM command error flag set.\n";
+        case MYKONOS_ERR_GETSTATE_TRACK_ARMERROR:
+            return "ARM command error.\n";
+        case MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL:
+            return "Tx channel is not valid (Valid ENUM values: TX1 or TX2 only).\n";
+        case MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG:
+            return "ARM command flag error set.\n";
+        case MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN:
+            return "CLGC gain parameter is out of range, valid range is from -10000 to 10000.\n";
+        case MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL:
+            return "Tx channel is not valid (Valid ENUM values: TX1, TX2 or TX1_TX2).\n";
+        case MYKONOS_ERR_SETDPDACT_INV_STATE:
+            return "Invalid Actuator state, valid states are 0-disable and 1-enable.\n";
+        case MYKONOS_ERR_SETDPDACT_ARMERRFLAG:
+            return "ARM command flag error set.\n";
+        default:
+            return "";
+    }
+
+#endif
+}
+
+/**
+ * \brief Calculates the scaled device clock frequency at the input of the
+ *        CLKPLL or RFPLL
+ *
+ * Use this helper function any time the scaled device clock frequency is needed.
+ *
+ * <B>Dependencies</B>
+ * - device->clocks->deviceClock_kHz
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param scaledRefClk_kHz Output: The returned scaled reference clock for the device's PLLs
+ * \param deviceClkDiv Output: The device clock divider setting that gets set in the devices SPI register.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_NULL_DEVICE_PARAM Function parameter device pointer is NULL
+ * \retval MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM The scaled PLL refclk frequency is out of range (40MHz to 80MHz)
+ * \retval MYKONOS_ERR_CALCDEVCLK_NULLPARAM Function parameter scaledRefClk_kHz or deviceClkDiv has a NULL pointer
+ */
+static mykonosErr_t MYKONOS_calculateScaledDeviceClk_kHz(mykonosDevice_t *device, uint32_t *scaledRefClk_kHz, uint8_t *deviceClkDiv)
+{
+    uint32_t deviceClock_kHz = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_calculateScaledDeviceClk_kHz()\n");
+#endif
+
+    if ((device == NULL) || (device->clocks == NULL))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_NULL_DEVICE_PARAM, getMykonosErrorMessage(MYKONOS_ERR_NULL_DEVICE_PARAM));
+        return MYKONOS_ERR_NULL_DEVICE_PARAM;
+    }
+
+    deviceClock_kHz = device->clocks->deviceClock_kHz;
+
+    if ((scaledRefClk_kHz == NULL) || (deviceClkDiv == NULL))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CALCDEVCLK_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_CALCDEVCLK_NULLPARAM));
+        return MYKONOS_ERR_CALCDEVCLK_NULLPARAM;
+    }
+
+    /* scaled Ref Clock at input to CLKPLL must be in range 40-80MHz. */
+    if (deviceClock_kHz > 20000 && deviceClock_kHz <= 40000)
+    {
+        *scaledRefClk_kHz = deviceClock_kHz << 1;
+        *deviceClkDiv = 3;
+    } /* x2 */
+    else if (deviceClock_kHz > 40000 && deviceClock_kHz <= 80000)
+    {
+        *scaledRefClk_kHz = deviceClock_kHz;
+        *deviceClkDiv = 0;
+    } /* x1 */
+    else if (deviceClock_kHz > 80000 && deviceClock_kHz <= 160000)
+    {
+        *scaledRefClk_kHz = deviceClock_kHz >> 1;
+        *deviceClkDiv = 1;
+    } /* div2 */
+    else if (deviceClock_kHz > 160000 && deviceClock_kHz <= 320000)
+    {
+        *scaledRefClk_kHz = deviceClock_kHz >> 2;
+        *deviceClkDiv = 2;
+    } /* div4 */
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM));
+        return MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM;
+    }
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Resets the JESD204B Deframer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_resetDeframer(mykonosDevice_t *device)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetDeframer()\n");
+#endif
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_RESET, 0x03);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_RESET, 0x00);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the JESD204B Serializers
+ *
+ * This function uses the Rx framer and ObsRx framer structures to setup the 4
+ * serializer lanes that are shared between the two framers.  If the Rx profile is valid
+ * the serializer amplitude and preEmphasis are used from the Rx framer.  If only the ObsRx
+ * profile is valid, the obsRx framer settings are used.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->rx->framer->M
+ * - device->rx->framer->serializerAmplitude
+ * - device->rx->framer->preEmphasis
+ * - device->rx->framer->serializerLanesEnabled
+ * - device->rx->framer->invertLanePolarity
+ * - device->obsRx->framer->serializerLanesEnabled
+ * - device->obsRx->framer->invertLanePolarity
+ * - device->obsRx->framer->M
+ * - device->obsRx->framer->serializerLanesEnabled
+ * - device->obsRx->framer->serializerAmplitude
+ * - device->obsRx->framer->preEmphasis
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_INITSER_INV_VCODIV_PARM Mykonos CLKPLL has invalid VCO divider, verify CLKPLL config
+ * \retval MYKONOS_ERR_SER_LANE_CONFLICT_PARM When both Rx and ObsRx framers are enabled, framers can not share the same physical lane.
+ * \retval MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM Rx Framer M can only = 1 when Real IF mode is enabled
+ * \retval MYKONOS_ERR_SER_INV_M_PARM Invalid Rx Framer M (valid 1,2,4)
+ * \retval MYKONOS_ERR_SER_INV_LANEEN_PARM Invalid Rx framer serializerLanesEnabled (valid 0-15)
+ * \retval MYKONOS_ERR_SER_INV_AMP_PARM Invalid Rx serializer amplitude (valid 0-31)
+ * \retval MYKONOS_ERR_SER_INV_PREEMP_PARM Invalid Rx serializer pre-emphesis (valid 0-7)
+ * \retval MYKONOS_ERR_SER_INV_LANEPN_PARM Invalid Rx serializer PN invert setting (valid 0-15)
+ * \retval MYKONOS_ERR_SER_INV_L_PARM Invalid Rx serializer lanes enabled (must use 1, 2 or 4 lanes)
+ * \retval MYKONOS_ERR_SER_INV_LANERATE_PARM Invalid Rx serializer lane rate (valid 614.4Mbps - 6144Mbps)
+ *
+ * \retval MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM
+ * \retval MYKONOS_ERR_SER_INV_LANEEN_PARM
+ * \retval MYKONOS_ERR_SER_INV_AMP_PARM
+ * \retval MYKONOS_ERR_SER_INV_PREEMP_PARM
+ * \retval MYKONOS_ERR_SER_INV_LANEPN_PARM
+ * \retval MYKONOS_ERR_SER_INV_L_PARM
+ * \retval MYKONOS_ERR_SER_INV_LANERATE_PARM
+ *
+ * \retval MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM Necessary lane rates for Rx and ObsRx framer can not be obtained with possible divider settings
+ * \retval MYKONOS_ERR_SER_INV_HSCLK_PARM Invalid HSCLK frequency (check CLKPLL config, HSCLK must be <= 6144GHz)
+ * \retval MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT HSCLK is not an integer multiple of the lane clock rate
+ * \retval MYKONOS_ERR_SER_INV_TXSER_DIV_PARM No valid Tx serializer divider to obtain desired lane rates
+ * \retval MYKONOS_ERR_INITSER_INV_PROFILE Rx/ObsRx and sniffer profiles are not valid - can not config serializers
+ * \retval MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM Invalid Rx framer PCLK divider
+ * \retval MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM Invalid ORx/Sniffer framer PCLK divider
+ *
+ */
+mykonosErr_t MYKONOS_setupSerializers(mykonosDevice_t *device)
+{
+    uint8_t div2 = 0;
+    uint8_t txser_div = 0;
+    uint8_t txser_div_reg = 0;
+    uint32_t clkPllVcoFrequency_kHz = 0;
+    uint32_t hsclkRate_kHz = 0;
+    uint32_t rxLaneRate_kHz = 0;
+    uint32_t obsRxLaneRate_kHz = 0;
+    uint32_t fasterLaneRate_kHz = 0;
+    uint32_t slowerLaneRate_kHz = 0;
+    uint8_t modHsLaneRate = 0;
+    uint8_t rxL = 0;
+    uint8_t obsRxL = 0;
+    uint8_t i = 0;
+    uint8_t amplitudeEmphasis = 0;
+    uint8_t lanePowerDown = 0x00;
+    mykonosVcoDiv_t vcoDiv = VCODIV_1;
+    uint8_t rxLanePn = 0;
+    uint8_t obsRxLanePn = 0;
+
+    uint32_t hsDigClkdiv4_5_kHz = 0;
+    uint32_t rxPclkDiv = 0;
+    uint32_t obsRxPclkDiv = 0;
+    uint32_t tempPclkDiv = 0;
+    uint32_t rxFramerPclk_kHz = 0;
+    uint32_t obsRxFramerPclk_kHz = 0;
+    uint8_t rxSyncbSelect = 0;
+    uint8_t obsRxSyncbSelect = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupSerializers()\n");
+#endif
+
+    vcoDiv = device->clocks->clkPllVcoDiv;
+    clkPllVcoFrequency_kHz = device->clocks->clkPllVcoFreq_kHz;
+
+    switch (vcoDiv)
+    {
+        case VCODIV_1:
+            hsclkRate_kHz = clkPllVcoFrequency_kHz;
+            break;
+        case VCODIV_1p5:
+            hsclkRate_kHz = (clkPllVcoFrequency_kHz / 15) * 10;
+            break;
+        case VCODIV_2:
+            hsclkRate_kHz = clkPllVcoFrequency_kHz >> 1;
+            break;
+        case VCODIV_3:
+            hsclkRate_kHz = (clkPllVcoFrequency_kHz / 30) * 10;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITSER_INV_VCODIV_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_INITSER_INV_VCODIV_PARM));
+            return MYKONOS_ERR_INITSER_INV_VCODIV_PARM;
+        }
+    }
+
+    if ((device->profilesValid & RX_PROFILE_VALID) && (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)))
+    {
+        if (device->rx->framer->serializerLanesEnabled & device->obsRx->framer->serializerLanesEnabled)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_LANE_CONFLICT_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_LANE_CONFLICT_PARM));
+            return MYKONOS_ERR_SER_LANE_CONFLICT_PARM;
+        }
+    }
+
+    lanePowerDown = 0x9F;
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        if (device->rx->framer->M == 1 && !(device->rx->realIfData))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM));
+            return MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM;
+        }
+
+        if (device->rx->framer->M != 1 && device->rx->framer->M != 2 && device->rx->framer->M != 4)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_M_PARM));
+            return MYKONOS_ERR_SER_INV_M_PARM;
+        }
+
+        for (i = 0; i < 4; i++)
+        {
+            rxL += ((device->rx->framer->serializerLanesEnabled >> i) & 0x01);
+        }
+
+        if (device->rx->framer->serializerLanesEnabled > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEEN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEEN_PARM));
+            return MYKONOS_ERR_SER_INV_LANEEN_PARM;
+        }
+
+        if (device->rx->framer->serializerAmplitude > 31)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_AMP_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_AMP_PARM));
+            return MYKONOS_ERR_SER_INV_AMP_PARM;
+        }
+
+        if (device->rx->framer->preEmphasis > 7)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_PREEMP_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_PREEMP_PARM));
+            return MYKONOS_ERR_SER_INV_PREEMP_PARM;
+        }
+
+        if (device->rx->framer->invertLanePolarity > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEPN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEPN_PARM));
+            return MYKONOS_ERR_SER_INV_LANEPN_PARM;
+        }
+        if ((rxL != 1) && (rxL != 2) && (rxL != 4))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_L_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_L_PARM));
+            return MYKONOS_ERR_SER_INV_L_PARM;
+        }
+
+        rxLaneRate_kHz = device->rx->rxProfile->iqRate_kHz * 20 * device->rx->framer->M / rxL;
+        lanePowerDown &= (~(device->rx->framer->serializerLanesEnabled));
+
+        if ((rxLaneRate_kHz < 614400) || (rxLaneRate_kHz > 6144000))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANERATE_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANERATE_PARM));
+            return MYKONOS_ERR_SER_INV_LANERATE_PARM;
+        }
+    }
+
+    if (device->obsRx->framer > 0 && (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID)))
+    {
+        if (device->obsRx->framer->M == 1 && !(device->obsRx->realIfData))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM));
+            return MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM;
+        }
+
+        for (i = 0; i < 4; i++)
+        {
+            obsRxL += ((device->obsRx->framer->serializerLanesEnabled >> i) & 0x01);
+        }
+
+        if (device->obsRx->framer->serializerLanesEnabled > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEEN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEEN_PARM));
+            return MYKONOS_ERR_SER_INV_LANEEN_PARM;
+        }
+
+        if (device->obsRx->framer->serializerAmplitude > 31)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_AMP_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_AMP_PARM));
+            return MYKONOS_ERR_SER_INV_AMP_PARM;
+        }
+
+        if (device->obsRx->framer->preEmphasis > 7)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_PREEMP_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_PREEMP_PARM));
+            return MYKONOS_ERR_SER_INV_PREEMP_PARM;
+        }
+
+        if (device->obsRx->framer->invertLanePolarity > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANEPN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANEPN_PARM));
+            return MYKONOS_ERR_SER_INV_LANEPN_PARM;
+        }
+
+        if ((obsRxL != 0) && (obsRxL != 1) && (obsRxL != 2) && (obsRxL != 4))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_L_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_L_PARM));
+            return MYKONOS_ERR_SER_INV_L_PARM;
+        }
+
+        /* check for valid pointer */
+        if (obsRxL == 0)
+        {
+            /* Allow ORx receiver to work but disable Obs Rx framer link - valid on 9373 */
+            obsRxLaneRate_kHz = 0;
+        }
+        else if (device->profilesValid & ORX_PROFILE_VALID)
+        {
+            obsRxLaneRate_kHz = device->obsRx->orxProfile->iqRate_kHz * 20 * device->obsRx->framer->M / obsRxL;
+        }
+        else if (device->profilesValid & SNIFF_PROFILE_VALID)
+        {
+            obsRxLaneRate_kHz = device->obsRx->snifferProfile->iqRate_kHz * 20 * device->obsRx->framer->M / obsRxL;
+        }
+
+        lanePowerDown &= (~(device->obsRx->framer->serializerLanesEnabled));
+
+        if ((obsRxLaneRate_kHz != 0) && ((obsRxLaneRate_kHz < 614400) || (obsRxLaneRate_kHz > 6144000)))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_LANERATE_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_LANERATE_PARM));
+            return MYKONOS_ERR_SER_INV_LANERATE_PARM;
+        }
+    }
+
+    /* checking for RX and OBSRX effective lane rates match */
+    /* Need to account for oversampling, verify that the 2 lane rate are integer related */
+
+    if ((rxLaneRate_kHz > 0) && (obsRxLaneRate_kHz > 0))
+    {
+        fasterLaneRate_kHz = (rxLaneRate_kHz >= obsRxLaneRate_kHz) ? (rxLaneRate_kHz) : (obsRxLaneRate_kHz);
+        slowerLaneRate_kHz = (rxLaneRate_kHz >= obsRxLaneRate_kHz) ? (obsRxLaneRate_kHz) : (rxLaneRate_kHz);
+
+        /* Verify that lane rates are integer multiples of each other */
+        if ((fasterLaneRate_kHz % slowerLaneRate_kHz) != 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM));
+            return MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM;
+        }
+    }
+    else
+    {
+        fasterLaneRate_kHz = (rxLaneRate_kHz >= obsRxLaneRate_kHz) ? (rxLaneRate_kHz) : (obsRxLaneRate_kHz);
+    }
+
+    if (hsclkRate_kHz > 6144000)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_HSCLK_PARM, getMykonosErrorMessage(MYKONOS_ERR_SER_INV_HSCLK_PARM));
+        return MYKONOS_ERR_SER_INV_HSCLK_PARM;
+    }
+
+    /* performing integer multiple check on HS clock and lane rate clock */
+    if (fasterLaneRate_kHz == 0)
+    {
+        /* All serializer lanes are disabled */
+        txser_div = 1;
+        div2 = 0;
+    }
+    else
+    {
+        modHsLaneRate = hsclkRate_kHz % fasterLaneRate_kHz;
+        if (modHsLaneRate)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT,
+                    getMykonosErrorMessage(MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT));
+            return MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT;
+        }
+
+        /* if lane rate = HSCLK /1, /2 or /4, the division is set in reg x11A */
+        /* if lane rate = HSCLK /8, x11A is set for /4 and 0xB3 is set for /2 */
+
+        txser_div = (uint8_t)(hsclkRate_kHz / fasterLaneRate_kHz);
+        if (txser_div == 8)
+        {
+            div2 = 1;
+        }
+        else
+        {
+            div2 = 0;
+        }
+    }
+
+    switch (txser_div)
+    {
+        case 1:
+            txser_div_reg = 0;
+            break;
+        case 2:
+            txser_div_reg = 1;
+            break;
+        case 4:
+            txser_div_reg = 2;
+            break;
+        case 8:
+            txser_div_reg = 2;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SER_INV_TXSER_DIV_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_SER_INV_TXSER_DIV_PARM));
+            return MYKONOS_ERR_SER_INV_TXSER_DIV_PARM;
+            break;
+    }
+
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        amplitudeEmphasis = ((device->rx->framer->serializerAmplitude & 0x1f) << 3) | (device->rx->framer->preEmphasis & 0x07);
+    }
+    else if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))
+    {
+        amplitudeEmphasis = ((device->obsRx->framer->serializerAmplitude & 0x1f) << 3) | (device->obsRx->framer->preEmphasis & 0x07);
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITSER_INV_PROFILE, getMykonosErrorMessage(MYKONOS_ERR_INITSER_INV_PROFILE));
+        return MYKONOS_ERR_INITSER_INV_PROFILE;
+    }
+
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        rxSyncbSelect = (device->rx->framer->obsRxSyncbSelect > 0) ? 1 : 0;
+        rxLanePn = (rxSyncbSelect << 7) | (device->rx->framer->invertLanePolarity & 0xF);
+    }
+
+    if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))
+    {
+        obsRxSyncbSelect = (device->obsRx->framer->obsRxSyncbSelect > 0) ? 1 : 0;
+        obsRxLanePn = (obsRxSyncbSelect << 7) | (device->obsRx->framer->invertLanePolarity & 0xF);
+    }
+
+    /* Serializer lane clock frequency */
+    /* serLaneClock_kHz = fasterLaneRate_kHz / txser_div / 20; */
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        /* calculate manual PCLK frequency for Rx framer  = Rx IQrate * F, where F = (2*M/L)  or PCLK = lanerate /10 */
+        if (device->rx->framer->overSample)
+        {
+            rxFramerPclk_kHz = fasterLaneRate_kHz / 10;
+        }
+        else
+        {
+            rxFramerPclk_kHz = rxLaneRate_kHz / 10;
+        }
+
+        hsDigClkdiv4_5_kHz = hsclkRate_kHz / device->clocks->clkPllHsDiv / device->rx->rxProfile->rxDec5Decimation;
+
+        /* PCLKDiv: 0=4x, 1=2x, 2=1x, 3=/2, 4=/4, 5=/8, 6=/16 */
+        if (hsDigClkdiv4_5_kHz == rxFramerPclk_kHz)
+        {
+            rxPclkDiv = 2;
+        }
+        else if (hsDigClkdiv4_5_kHz > rxFramerPclk_kHz)
+        {
+            tempPclkDiv = hsDigClkdiv4_5_kHz / rxFramerPclk_kHz;
+            switch (tempPclkDiv)
+            {
+                case 2:
+                    rxPclkDiv = 3;
+                    break;
+                case 4:
+                    rxPclkDiv = 4;
+                    break;
+                case 8:
+                    rxPclkDiv = 5;
+                    break;
+                case 16:
+                    rxPclkDiv = 6;
+                    break;
+                default:
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM,
+                            getMykonosErrorMessage(MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM));
+                    return MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM;
+                }
+            }
+        }
+        else if (hsDigClkdiv4_5_kHz < rxFramerPclk_kHz)
+        {
+            tempPclkDiv = rxFramerPclk_kHz / hsDigClkdiv4_5_kHz;
+            switch (tempPclkDiv)
+            {
+                case 2:
+                    rxPclkDiv = 1;
+                    break;
+                case 4:
+                    rxPclkDiv = 0;
+                    break;
+                default:
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM,
+                            getMykonosErrorMessage(MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM));
+                    return MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM;
+                }
+            }
+        }
+    }
+
+    if (obsRxL == 0)
+    {
+        /* Make sure PCLK is set as low as possible because it interacts with Rx Framer logic, */
+        /* even though ObsRx Framer disabled */
+        obsRxPclkDiv = 6;
+    }
+    else if (device->profilesValid & (ORX_PROFILE_VALID | SNIFF_PROFILE_VALID))
+    {
+        /* calculate manual PCLK frequency for obsRx framer  = obsRx IQrate * F, where F = (2*M/L) */
+        if (device->profilesValid & ORX_PROFILE_VALID)
+        {
+            if (device->obsRx->framer->overSample)
+            {
+                obsRxFramerPclk_kHz = fasterLaneRate_kHz / 10;
+            }
+            else
+            {
+                obsRxFramerPclk_kHz = obsRxLaneRate_kHz / 10;
+            }
+
+            hsDigClkdiv4_5_kHz = hsclkRate_kHz / device->clocks->clkPllHsDiv / device->obsRx->orxProfile->rxDec5Decimation;
+        }
+        else if (device->profilesValid & SNIFF_PROFILE_VALID)
+        {
+            if (device->obsRx->framer->overSample)
+            {
+                obsRxFramerPclk_kHz = fasterLaneRate_kHz / 10;
+            }
+            else
+            {
+                obsRxFramerPclk_kHz = obsRxLaneRate_kHz / 10;
+            }
+
+            hsDigClkdiv4_5_kHz = hsclkRate_kHz / device->clocks->clkPllHsDiv / device->obsRx->snifferProfile->rxDec5Decimation;
+        }
+
+        /* PCLKDiv: 0=4x, 1=2x, 2=1x, 3=/2, 4=/4, 5=/8, 6=/16 */
+        if (hsDigClkdiv4_5_kHz == obsRxFramerPclk_kHz)
+        {
+            obsRxPclkDiv = 2;
+        }
+        else if ((hsDigClkdiv4_5_kHz > obsRxFramerPclk_kHz) && (obsRxFramerPclk_kHz != 0))
+        {
+            tempPclkDiv = hsDigClkdiv4_5_kHz / obsRxFramerPclk_kHz;
+            switch (tempPclkDiv)
+            {
+                case 2:
+                    obsRxPclkDiv = 3;
+                    break;
+                case 4:
+                    obsRxPclkDiv = 4;
+                    break;
+                case 8:
+                    obsRxPclkDiv = 5;
+                    break;
+                case 16:
+                    obsRxPclkDiv = 6;
+                    break;
+                default:
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM,
+                            getMykonosErrorMessage(MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM));
+                    return MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM;
+                }
+            }
+        }
+        else if (hsDigClkdiv4_5_kHz < obsRxFramerPclk_kHz)
+        {
+            tempPclkDiv = obsRxFramerPclk_kHz / hsDigClkdiv4_5_kHz;
+            switch (tempPclkDiv)
+            {
+                case 2:
+                    obsRxPclkDiv = 1;
+                    break;
+                case 4:
+                    obsRxPclkDiv = 0;
+                    break;
+                default:
+                {
+                    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM,
+                            getMykonosErrorMessage(MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM));
+                    return MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM;
+                }
+            }
+        }
+    }
+
+    /* set lane rate divide setting */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_3, txser_div_reg, 0x03, 0);
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_2, amplitudeEmphasis);
+
+    /* Serializer: Release Reset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_SPECIAL, 0x03);
+
+    /* Serializer: txser clk enable */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_HS_DIV_TXSER_CLK_EN, 0x01);
+
+    /* Serializer: Enable 2 to 1 serializer */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_3, 0x20 | div2);
+
+    /* power up desired serializer lanes */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, lanePowerDown);
+
+    /* apply desired lane PN inversions to the TX and OBSRX framers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LANE_DATA_CTL, rxLanePn);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_DATA_CTL, obsRxLanePn);
+
+    /* set Rx framer manual PCLK frequency based on lane rate of the serializers */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, rxPclkDiv, 0x70, 4);
+
+    /* enable bit repeat mode in Rx framer - since manual PCLK, oversample will still work */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 0, 0x80, 7);
+
+    /* enable manual PCLK mode in Rx framer */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 1, 0x04, 2);
+
+    /* set obsRx framer manual PCLK frequency based on lane rate of the serializers */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, obsRxPclkDiv, 0x70, 4);
+
+    /* enable bit repeat mode in ObsRx framer - since manual PCLK, oversample will still work */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0, 0x80, 7);
+
+    /* enable manual PCLK mode in ObsRx framer */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 1, 0x04, 2);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the JESD204B Deserializers
+ *
+ * This function enables the necessary deserializer lanes, sets the deserializer clocks
+ * PN inversion settings, and EQ settings based on the info found in the device data structure.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->tx->txProfile->clkPllVcoDiv
+ * - device->tx->txProfile->vcoFreq_kHz
+ * - device->tx->txProfile->txIqRate_kHz
+ * - device->tx->deframer->M
+ * - device->tx->deframer->deserializerLanesEnabled
+ * - device->tx->deframer->invertLanePolarity
+ * - device->tx->deframer->EQSetting
+ *
+ * \param device Pointer to the device settings structure
+
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_INITDES_INV_TXPROFILE Tx Profile is not valid in data structure - can not setup deserializer
+ * \retval MYKONOS_ERR_INITDES_INV_VCODIV_PARM Mykonos CLKPLL VCO divider is invalid
+ * \retval MYKONOS_ERR_DESER_INV_M_PARM Invalid M (valid 2 or 4)
+ * \retval MYKONOS_ERR_DESER_INV_L_PARM Invalid L (valid 1,2,4)
+ * \retval MYKONOS_ERR_DESER_INV_HSCLK_PARM Invalid HSCLK, must be 6.144G or less after CLKPLL VCO divider - verify CLKPLL config
+ * \retval MYKONOS_ERR_DESER_INV_LANERATE_PARM Invalid lanerate, must be between 614.4 Mbps to 6144 Mbps
+ * \retval MYKONOS_ERR_DESER_INV_LANEEN_PARM Invalid deserializerLanesEnabled (valid 0-15 in 1,2,4 lane combinations)
+ * \retval MYKONOS_ERR_DESER_INV_EQ_PARM Invalid EQ parameter (valid 0-4)
+ * \retval MYKONOS_ERR_DESER_INV_LANEPN_PARM Invalid PN invert setting, (valid 0-15, invert bit per lane)
+ * \retval MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT Invalid clock settings, HSCLK is not an integer multiple of lane rate
+ *
+ */
+mykonosErr_t MYKONOS_setupDeserializers(mykonosDevice_t *device)
+{
+    uint8_t lanePowerDown = 0xF;
+    uint8_t des_div = 0;
+    uint8_t des_div_bitfield = 0;
+    uint8_t rxcdr_div = 0;
+    uint8_t rxcdr_div_bitfield = 0;
+    uint32_t hsclkRate_kHz = 0;
+    uint8_t i = 0;
+    uint8_t L = 0;
+    uint32_t laneRate_kHz = 0;
+    uint8_t invertLanePolarity = 0;
+    uint8_t modHsLaneRate = 0;
+
+    const uint32_t MAX_HSCLKRATE_KHZ = 12288000;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupDeserializers()\n");
+#endif
+
+    if ((device->profilesValid & TX_PROFILE_VALID) == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITDES_INV_TXPROFILE,
+                getMykonosErrorMessage(MYKONOS_ERR_INITDES_INV_TXPROFILE));
+        return MYKONOS_ERR_INITDES_INV_TXPROFILE;
+    }
+
+    if (device->tx->deframer->M != 2 && device->tx->deframer->M != 4)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_M_PARM));
+        return MYKONOS_ERR_DESER_INV_M_PARM;
+    }
+
+    for (i = 0; i < 4; i++)
+    {
+        L += ((device->tx->deframer->deserializerLanesEnabled >> i) & 0x01);
+    }
+
+    if ((L == 0) || (L == 3) || (L > 4))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_L_PARM, getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_L_PARM));
+        return MYKONOS_ERR_DESER_INV_L_PARM;
+    }
+
+    //laneRate_kHz calculation and checks
+    laneRate_kHz = device->tx->txProfile->iqRate_kHz * 20 * device->tx->deframer->M / L;
+
+    if ((laneRate_kHz < 614400) || (laneRate_kHz > 6144000))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANERATE_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANERATE_PARM));
+        return MYKONOS_ERR_DESER_INV_LANERATE_PARM;
+    }
+
+    if (device->tx->deframer->deserializerLanesEnabled > 15)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANEEN_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANEEN_PARM));
+        return MYKONOS_ERR_DESER_INV_LANEEN_PARM;
+    }
+
+    if ((device->tx->deframer->deserializerLanesEnabled == 0x7) || (device->tx->deframer->deserializerLanesEnabled == 0xB)
+            || (device->tx->deframer->deserializerLanesEnabled == 0xD) || (device->tx->deframer->deserializerLanesEnabled == 0xE))
+    {
+        /* 3 lanes not valid, only 1,2, or 4 lanes */
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANEEN_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANEEN_PARM));
+        return MYKONOS_ERR_DESER_INV_LANEEN_PARM;
+    }
+
+    if (device->tx->deframer->EQSetting > 4)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_EQ_PARM, getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_EQ_PARM));
+        return MYKONOS_ERR_DESER_INV_EQ_PARM;
+    }
+
+    if (device->tx->deframer->invertLanePolarity > 15)
+    {
+        /* only lower 4 bits of parameter are valid */
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_LANEPN_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_LANEPN_PARM));
+        return MYKONOS_ERR_DESER_INV_LANEPN_PARM;
+    }
+
+    //hsclkRate_kHz calculations
+    switch (device->clocks->clkPllVcoDiv)
+    {
+        case VCODIV_1:
+            hsclkRate_kHz = device->clocks->clkPllVcoFreq_kHz;
+            break;
+        case VCODIV_1p5:
+            hsclkRate_kHz = (device->clocks->clkPllVcoFreq_kHz / 15) * 10;
+            break;
+        case VCODIV_2:
+            hsclkRate_kHz = device->clocks->clkPllVcoFreq_kHz >> 1;
+            break;
+        case VCODIV_3:
+            hsclkRate_kHz = (device->clocks->clkPllVcoFreq_kHz / 30) * 10;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITDES_INV_VCODIV_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_INITDES_INV_VCODIV_PARM));
+            return MYKONOS_ERR_INITDES_INV_VCODIV_PARM;
+    }
+
+    if (hsclkRate_kHz > MAX_HSCLKRATE_KHZ)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DESER_INV_HSCLK_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_DESER_INV_HSCLK_PARM));
+        return MYKONOS_ERR_DESER_INV_HSCLK_PARM;
+    }
+
+    /* The deserializer clock needs to be in the range 3.8GHz to 6.144 GHz in reg x107.  The rest of the division is in xDD */
+    if (hsclkRate_kHz <= 6144000)
+    {
+        rxcdr_div = 1;
+    }
+    else if (hsclkRate_kHz > 6144000 && hsclkRate_kHz <= MAX_HSCLKRATE_KHZ)
+    {
+        rxcdr_div = 2;
+    }
+    else if (hsclkRate_kHz > MAX_HSCLKRATE_KHZ)
+    {
+        rxcdr_div = 4;
+    }
+
+    switch (rxcdr_div)
+    {
+        case 1:
+            rxcdr_div_bitfield = 0;
+            break;
+        case 2:
+            rxcdr_div_bitfield = 1;
+            break;
+        case 4:
+            rxcdr_div_bitfield = 2;
+            break;
+        default:
+            rxcdr_div_bitfield = 0;
+            break;
+    }
+
+    /* performing integer multiple check on HS clock and lane rate clock */
+    modHsLaneRate = hsclkRate_kHz % laneRate_kHz;
+    if (modHsLaneRate)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT,
+                getMykonosErrorMessage(MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT));
+        return MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT;
+    }
+
+    des_div = (uint8_t)(hsclkRate_kHz / laneRate_kHz / rxcdr_div);
+
+    switch (des_div)
+    {
+        case 1:
+            des_div_bitfield = 0;
+            break;
+        case 2:
+            des_div_bitfield = 1;
+            break;
+        case 4:
+            des_div_bitfield = 2;
+            break;
+        case 8:
+            des_div_bitfield = 3;
+            break;
+        default:
+            des_div_bitfield = 0;
+            break;
+    }
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_3, rxcdr_div_bitfield, 0x0C, 0x02);
+
+    invertLanePolarity = (device->tx->deframer->invertLanePolarity & 0xF);
+
+    lanePowerDown = (~(device->tx->deframer->deserializerLanesEnabled)) & 0xF;
+
+    /* Deserializer: PLL clock enable */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_HS_DIV_RXCDR_CLK_EN, 0x01);
+
+    /* Deserializer: Set Pdet control */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_PDET_CTL, 0x09);
+
+    /* Deserializer: Set Power down control */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_CTL_0, (0x80U | lanePowerDown | (des_div_bitfield << 4)));
+
+    /* Deserializer: Set Sine Shape */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_0, 0x00);
+
+    /* Deserializer: Set ss gain and vga */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_1, 0x00);
+
+    /* Deserializer: Enable EQ, AC coupled JESD204B lanes */
+    /* TODO: add ability to set this for AC coupling or DC coupling */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1, 0x07);
+
+    /* Deserializer: Clear Data present at negedge, disable peak adjust */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_MISC_CTL, 0x04);
+
+    /* Deserializer: Set Equalizer for lanes 1 and 0 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1_TO_0, ((device->tx->deframer->EQSetting << 3) | device->tx->deframer->EQSetting));
+
+    /* Deserializer: Set Equalizer for lanes 2 and 3 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_EQ_CTL_3_TO_2, ((device->tx->deframer->EQSetting << 3) | device->tx->deframer->EQSetting));
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LANE_DATA_CTL, invertLanePolarity);
+
+    /* Reset Deserializers - toggle resetb bit in [0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SPECIAL, 0x00);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_SPECIAL, 0x01);
+
+    /* Start ALC cal */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DESERIALIZER_CDR_CAL_CTL, 0x02);
+
+    /* Deframer: Enable clocks and lane clocks */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_CLK_EN, 0x03);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the JESD204B Framer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->rx->framer->M
+ * - device->rx->realIfData
+ * - device->rx->framer->bankId
+ * - device->rx->framer->lane0Id
+ * - device->rx->framer->serializerLanesEnabled
+ * - device->rx->framer->obsRxSyncbSelect
+ * - device->rx->framer->K
+ * - device->rx->framer->externalSysref
+ * - device->rx->rxChannels
+ * - device->rx->framer->newSysrefOnRelink
+ * - device->rx->framer->enableAutoChanXbar
+ * - device->rx->framer->lmfcOffset
+ * - device->rx->framer->scramble
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM Invalid framer M, M can only = 1 in real IF mode
+ * \retval MYKONOS_ERR_FRAMER_INV_M_PARM Invalid framer M (valid 1,2,4)
+ * \retval MYKONOS_ERR_FRAMER_INV_BANKID_PARM Invalid BankId (valid 0-15)
+ * \retval MYKONOS_ERR_FRAMER_INV_LANEID_PARM Invalid Lane0Id (valid 0-31)
+ * \retval MYKONOS_ERR_RXFRAMER_INV_FK_PARAM
+ * \retval MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM
+ */
+mykonosErr_t MYKONOS_setupJesd204bFramer(mykonosDevice_t *device)
+{
+    uint8_t i = 0;
+    uint8_t fifoLaneEnable = 0;
+    uint8_t L = 0;
+    uint8_t ML = 0;
+    uint8_t framerConfigF = 0;
+
+    uint8_t subaddr[29] = {0}; /* holds address to framer sub register map */
+    uint8_t subdata[29] = {0}; /* holds data for framer sub register map */
+
+    /* Setup submap registers */
+    uint8_t SUBCLASSV = 1; /* JESD subclass 1 */
+    uint8_t JESDV = 1; /* Version: JESD204B */
+    uint8_t DID = 0;
+    uint8_t BID = 0;
+    uint8_t LID0 = 0;
+    uint8_t LID1 = 1;
+    uint8_t LID2 = 2;
+    uint8_t LID3 = 3;
+    uint8_t CS = 0;
+    uint8_t N = 0x0F;
+    uint8_t Np = 0x0F;
+    uint8_t S = 0;
+    uint8_t CF = 0;
+    uint8_t K = 31;
+    uint8_t HD = 0;
+    uint8_t FramerL = 1;
+    uint8_t FramerM = 2;
+    uint8_t FramerF = 1;
+    uint8_t framerADC_XBar = 0xE4;
+    uint16_t FK = 0;
+
+    uint8_t regE0 = 0;
+    uint8_t regE2 = 0;
+    uint8_t framerLaneXbar = 0xE4;
+    uint16_t CheckSum = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupJesd204bFramer()\n");
+#endif
+
+    if (device->rx->framer->M == 1 && !(device->rx->realIfData))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM));
+        return MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM;
+    }
+
+    if (device->rx->framer->M != 1 && device->rx->framer->M != 2 && device->rx->framer->M != 4)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_M_PARM));
+        return MYKONOS_ERR_FRAMER_INV_M_PARM;
+    }
+
+    if (device->rx->framer->bankId > 15)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_BANKID_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_BANKID_PARM));
+        return MYKONOS_ERR_FRAMER_INV_BANKID_PARM;
+    }
+
+    /* no need to check deviceId, its range is full uint8_t range */
+    if (device->rx->framer->lane0Id > 31)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_LANEID_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_LANEID_PARM));
+        return MYKONOS_ERR_FRAMER_INV_LANEID_PARM;
+    }
+
+    //count number of lanes
+    L = 0;
+    ML = 0;
+
+    for (i = 0; i < 4; i++)
+    {
+        L += ((device->rx->framer->serializerLanesEnabled >> i) & 0x01);
+    }
+    ML = device->rx->framer->M * 10 + L;
+
+    FK = (uint16_t)device->rx->framer->K * 2 * device->rx->framer->M / L;
+
+    if (FK < 20 || FK > 256 || FK % 4 != 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RXFRAMER_INV_FK_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_RXFRAMER_INV_FK_PARAM));
+        return MYKONOS_ERR_RXFRAMER_INV_FK_PARAM;
+    }
+
+    if (device->rx->framer->externalSysref == 0)
+    {
+        /* Framer: Generate SYSREF internally */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_TEST_CNTR_CTL, 0x20);
+    }
+
+    framerADC_XBar = 0xB1;
+    if (ML == 24)
+    {
+        if (device->rx->rxChannels == RX1)
+        {
+            /* adc 0 and 2 used */
+            framerADC_XBar = ((framerADC_XBar & 0x0C) << 2) | (framerADC_XBar & 0x03);
+        }
+        else if (device->rx->rxChannels == RX2)
+        {
+            /* swap ADC xbar for Rx1 and Rx2 */
+            framerADC_XBar = ((framerADC_XBar & 0xF) << 4) | ((framerADC_XBar & 0xF0) >> 4);
+            /* adc 0 and 2 used */
+            framerADC_XBar = ((framerADC_XBar & 0x0C) << 2) | (framerADC_XBar & 0x03);
+        }
+
+        /* Framer: Set ADC Crossbar */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL, framerADC_XBar);
+    }
+    else
+    {
+        /* Framer: Set ADC Crossbar */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL, framerADC_XBar);
+    }
+
+    if (ML == 42)
+    {
+        /* uses framer outputs 0 and 2 instead of 0 and 1...fix framer lane XBar */
+        /* only 2 lane cases here */
+        switch ((device->rx->framer->serializerLanesEnabled & 0x0F))
+        {
+            case 3:
+                framerLaneXbar = 0x08;
+                break;
+            case 5:
+                framerLaneXbar = 0x20;
+                break;
+            case 6:
+                framerLaneXbar = 0x20;
+                break;
+            case 9:
+                framerLaneXbar = 0x80;
+                break;
+            case 10:
+                framerLaneXbar = 0x80;
+                break;
+            case 12:
+                framerLaneXbar = 0x80;
+                break;
+            default:
+                /* default to valid setting for Lane 0 */
+                framerLaneXbar = 0x08;
+                break;
+        }
+    }
+    else
+    {
+        switch ((device->rx->framer->serializerLanesEnabled & 0x0F))
+        {
+            /* all 4 lanes get framer 0 output */
+            case 1:
+                framerLaneXbar = 0x00;
+                break;
+            case 2:
+                framerLaneXbar = 0x00;
+                break;
+            case 3:
+                framerLaneXbar = 0x04;
+                break;
+            case 4:
+                framerLaneXbar = 0x00;
+                break;
+            case 5:
+                framerLaneXbar = 0x10;
+                break;
+            case 6:
+                framerLaneXbar = 0x10;
+                break;
+            case 8:
+                framerLaneXbar = 0x00;
+                break;
+            case 9:
+                framerLaneXbar = 0x40;
+                break;
+            case 10:
+                framerLaneXbar = 0x40;
+                break;
+            case 12:
+                framerLaneXbar = 0x40;
+                break;
+            case 15:
+                framerLaneXbar = 0xE4;
+                break;
+            default:
+                /* default to valid setting for all Lanes */
+                framerLaneXbar = 0xE4;
+                break;
+        }
+    }
+    /* Framer: Set Lane Crossbar */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LANE_XBAR_SEL, framerLaneXbar);
+
+    if (ML == 24)
+    {
+        /* Framer: Clear ADC Xbar channel auto switch */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x00);
+    }
+    else
+    {
+        /* Framer: Set ADC Xbar channel auto switch */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x04);
+    }
+
+    /* enabling the SYSREF for relink if newSysrefOnRelink is set */
+    if (device->rx->framer->newSysrefOnRelink)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x01, 0x40, 6);
+    }
+
+    /* enabling auto channel if the enableAutoChanXbar structure member is set */
+    if (device->rx->framer->enableAutoChanXbar)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x01, 0x04, 2);
+    }
+
+    /* determining F octets per frame based on 2*M/L */
+    framerConfigF = 2 * (device->rx->framer->M / L);
+
+    /* Framer: Soft Reset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x03);
+
+    /* Framer: Clear Soft Reset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x00);
+
+    /* Framer: Set F (Octets in Frame) */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_F, framerConfigF);
+
+    /* Framer: Enable framer clock and lane clocks */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 0x03, 0x03, 0);
+
+    /* Set Framer lane FIFO enable for each lane enabled */
+    fifoLaneEnable = (((device->rx->framer->serializerLanesEnabled & 0x0F) << 4) | 0x01);
+
+    /* Framer: Enable Lane FIFOs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LANE_CTL, fifoLaneEnable);
+
+    /* Setup submap registers */
+    SUBCLASSV = 1; /* JESD subclass 1 */
+    JESDV = 1; /* Version: JESD204B */
+    DID = device->rx->framer->deviceId;
+    BID = device->rx->framer->bankId;
+    LID0 = device->rx->framer->lane0Id;
+    LID1 = device->rx->framer->lane0Id + 1;
+    LID2 = device->rx->framer->lane0Id + 2;
+    LID3 = device->rx->framer->lane0Id + 3;
+
+    CS = 0;
+    N = 0x0F;
+    Np = 0x0F;
+    S = 0;
+    CF = 0;
+    HD = 0;
+    K = device->rx->framer->K - 1;
+    FramerL = L - 1;
+    FramerM = device->rx->framer->M - 1;
+    FramerF = (2 * device->rx->framer->M / L) - 1;
+
+    if (ML == 11)
+    {
+        regE0 = 0x01;
+        regE2 = 0x01;
+    }
+    else if (ML == 12)
+    {
+        regE0 = 0x01;
+        regE2 = 0x03;
+        HD = 0x01;
+    }
+    else if (ML == 21)
+    {
+        regE0 = 0x03;
+        regE2 = 0x01;
+    }
+    else if (ML == 22)
+    {
+        regE0 = 0x03;
+        regE2 = 0x03;
+    }
+    else if (ML == 24)
+    {
+        regE0 = 0x05;
+        regE2 = 0x0F;
+        HD = 0x01;
+    }
+    else if (ML == 41)
+    {
+        regE0 = 0x0F;
+        regE2 = 0x01;
+    }
+    else if (ML == 42)
+    {
+        regE0 = 0x0F;
+        regE2 = 0x05;
+    }
+    else if (ML == 44)
+    {
+        regE0 = 0x0F;
+        regE2 = 0x0F;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_M_PARM));
+        return MYKONOS_ERR_FRAMER_INV_M_PARM;
+    }
+
+    /* setting K offset for framer */
+    if (device->rx->framer->lmfcOffset < device->rx->framer->K)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_LMFC_K_OFFSET, device->rx->framer->lmfcOffset);
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM));
+        return MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM;
+    }
+
+    subaddr[0] = 0x00;
+    subdata[0] = (DID & 0xFF); /* Device ID */
+    subaddr[1] = 0x01;
+    subdata[1] = (BID & 0x0F); /* Bank ID */
+    subaddr[2] = 0x02;
+    subdata[2] = (LID0 & 0x1F); /* Lane 0 ID */
+    subaddr[3] = 0x03;
+    subdata[3] = (device->rx->framer->scramble << 7) | (FramerL & 0x1F); /* [7] Scramble, #Lanes[4:0]-1 */
+    subaddr[4] = 0x04;
+    subdata[4] = (FramerF & 0xFF); /* F[7:0]-1 */
+    subaddr[5] = 0x05;
+    subdata[5] = (K & 0x1F); /* K[4:0]-1 */
+    subaddr[6] = 0x06;
+    subdata[6] = (FramerM & 0xFF); /* M[7:0]-1 */
+    subaddr[7] = 0x07;
+    subdata[7] = ((CS & 0x3) << 6) | (N & 0x1F); /* [7:6] = CS[1:0], N[4:0]-1 */
+    subaddr[8] = 0x08;
+    subdata[8] = ((SUBCLASSV & 7) << 5) | (Np & 0x1F); /* NP[4:0] -1 */
+    subaddr[9] = 0x09;
+    subdata[9] = ((JESDV & 7) << 5) | (S & 0x1F); /* S[4:0]-1 */
+    subaddr[10] = 0x0A;
+    subdata[10] = ((HD & 1) << 7) | (CF & 0x1F); /* [7] = HD, CF[4:0] */
+    subaddr[11] = 0x0B;
+    subdata[11] = 0x00; /* reserved */
+    subaddr[12] = 0x0C;
+    subdata[12] = 0x00; /* reserved */
+
+    CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID0 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+            + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+    /* Checksum Lane 0 */
+    subaddr[13] = 0x0D;
+    subdata[13] = CheckSum & 0xFF;
+
+    /* in JESD204B ML=42 case, framer ip lanes 0 and 2 are used, write lane 1 id and checksum to ip lane 2 regs */
+    if (ML == 42)
+    {
+        /* Lane 1 ID */
+        subaddr[14] = 0x1A;
+        subdata[14] = LID1;
+
+        CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID1 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+                + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+        /* Checksum Lane 1 */
+        subaddr[15] = 0x1D;
+        subdata[15] = CheckSum & 0xFF;
+    }
+    else
+    {
+        /* Lane 1 ID */
+        subaddr[14] = 0x12;
+        subdata[14] = LID1;
+
+        CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID1 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+                + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+        /* Checksum Lane 1 */
+        subaddr[15] = 0x15;
+        subdata[15] = CheckSum & 0xFF;
+
+        /* Lane 2 ID */
+        subaddr[16] = 0x1A;
+        subdata[16] = LID2;
+
+        CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID2 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+                + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+        /* Checksum Lane 2 */
+        subaddr[17] = 0x1D;
+        subdata[17] = CheckSum & 0xFF;
+
+        /* Lane 3 ID */
+        subaddr[18] = 0x22;
+        subdata[18] = LID3;
+
+        CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID3 & 0x1F) + (device->rx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+                + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+        subaddr[19] = 0x25;
+        subdata[19] = CheckSum & 0xFF;
+    }
+
+    subaddr[20] = 0xE0;
+    subdata[20] = regE0; /* Enable converter n logic */
+    subaddr[21] = 0xE2;
+    subdata[21] = regE2; /* Enable Lane n logic */
+    subaddr[22] = 0xE4;
+    subdata[22] = 0x00;
+    subaddr[23] = 0xE6;
+    subdata[23] = 0x00;
+    subaddr[24] = 0xF0;
+    subdata[24] = 0x00; /* #multiframes in ILAS */
+    subaddr[25] = 0xF2;
+    subdata[25] = 0x00;
+    subaddr[26] = 0xF3;
+    subdata[26] = 0x00;
+    subaddr[27] = 0xF4;
+    subdata[27] = 0x00;
+    subaddr[28] = 0xC0;
+    subdata[28] = 0x03; /* Framer enable, both sides perform lane sync */
+
+    for (i = 0; i <= 28; i++)
+    {
+        /* Set framer sub register map address */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_ADDR, subaddr[i]);
+
+        /* Set framer sub register map data word */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_DATA, subdata[i]);
+
+        /* Write enable */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_WRITE_EN, 0x01);
+    }
+
+    if (device->rx->framer->externalSysref > 0)
+    {
+        /* Framer: Enable lane FIFO sync (Enable CGS) */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x30);
+    }
+    else
+    {
+        /* Framer: Enable lane FIFO sync (Enable CGS) */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x10);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the JESD204B OBSRX Framer
+ *
+ * <B>Dependencies</B>
+ * - device->rxChannels
+ * - device->spiSettings->chipSelectIndex
+ * - device->obsRx->framer->bankId
+ * - device->obsRx->framer->M
+ * - device->obsRx->framer->serializerLanesEnabled
+ * - device->obsRx->framer->externalSysref
+ * - device->spiSettings
+ * - device->obsRx->framer->deviceId
+ * - device->obsRx->framer->lane0Id
+ * - device->obsRx->framer->K
+ * - device->obsRx->framer->lmfcOffset
+ * - device->obsRx->framer->scramble
+ * - device->obsRx->framer->obsRxSyncbSelect
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM M parameter can only be 1 when real IF data mode is enabled
+ * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM ObsRx Framer M parameter can only be 1 or 2
+ * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM Invalid BankId (0-15)
+ * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM Invalid lane0Id (0-31)
+ * \retval MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM Invalid F*K value (F * K must be > 20 and divisible by 4)
+ * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM Invalid K offset, must be less than K
+ */
+mykonosErr_t MYKONOS_setupJesd204bObsRxFramer(mykonosDevice_t *device)
+{
+    uint8_t i = 0;
+    uint8_t laneFifoEnable = 0;
+    uint8_t L = 1;
+    uint8_t ML = 2;
+    uint8_t framerConfigF = 0;
+
+    uint8_t subaddr[29] = {0}; /* holds address to framer sub register map */
+    uint8_t subdata[29] = {0}; /* holds data for framer sub register map */
+
+    /* Setup submap registers */
+    uint8_t SUBCLASSV = 1; /* JESD subclass 1 */
+    uint8_t JESDV = 1; /* Version: JESD204B */
+    uint8_t DID = 0;
+    uint8_t BID = 0;
+    uint8_t LID0 = 0;
+    uint8_t LID1 = 1;
+    uint8_t LID2 = 2;
+    uint8_t LID3 = 3;
+    uint8_t CS = 0;
+    uint8_t N = 0x0F;
+    uint8_t Np = 0x0F;
+    uint8_t S = 0;
+    uint8_t CF = 0;
+    uint8_t K = 31;
+    uint8_t HD = 0;
+    uint8_t FramerL = 1;
+    uint8_t FramerM = 2;
+    uint8_t FramerF = 1;
+    uint8_t framerADC_XBar = 0xE4;
+    uint8_t regE0 = 0;
+    uint8_t regE2 = 0;
+    uint8_t framerLaneXbar = 0xE4;
+    uint16_t CheckSum = 0;
+    uint16_t FK = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupJesd204bObsRxFramer()\n");
+#endif
+
+    if (device->obsRx->framer->M == 1 && !(device->obsRx->realIfData))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM;
+    }
+
+    if (device->obsRx->framer->M != 1 && device->obsRx->framer->M != 2)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM;
+    }
+
+    if (device->obsRx->framer->bankId > 15)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM;
+    }
+
+    /* no need to check deviceId, its range is full uint8_t range */
+    if (device->obsRx->framer->lane0Id > 31)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM;
+    }
+
+    //count number of lanes
+    L = 0;
+    ML = 0;
+
+    for (i = 0; i < 4; i++)
+    {
+        L += ((device->obsRx->framer->serializerLanesEnabled >> i) & 0x01);
+    }
+
+    ML = device->obsRx->framer->M * 10 + L;
+
+    if (L == 0)
+    {
+        /* Disable framer and return successfully */
+        /* Disable framer clock and lane clocks */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0, 0x03, 0);
+
+        /* Disable lane FIFO enables */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_CTL, 0, 0xF0, 4);
+        return MYKONOS_ERR_OK;
+    }
+
+    FK = (uint16_t)device->obsRx->framer->K * 2 * device->obsRx->framer->M / L;
+    if (FK < 20 || FK > 256 || FK % 4 != 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM));
+        return MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM;
+    }
+
+    if (device->obsRx->framer->externalSysref == 0)
+    {
+        /* Framer: Generate SYSREF internally */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_TEST_CNTR_CTL, 0x20);
+    }
+
+    /* Framer: Set ADC Crossbar */
+    framerADC_XBar = 0xB1;
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_ADC_XBAR_SEL, framerADC_XBar);
+
+    if (ML == 42)
+    {
+        /* uses framer outputs 0 and 2 instead of 0 and 1...fix framer lane XBar */
+        /* only 2 lane cases here */
+        switch ((device->obsRx->framer->serializerLanesEnabled & 0x0F))
+        {
+            case 3:
+                framerLaneXbar = 0x08;
+                break;
+            case 5:
+                framerLaneXbar = 0x20;
+                break;
+            case 6:
+                framerLaneXbar = 0x20;
+                break;
+            case 9:
+                framerLaneXbar = 0x80;
+                break;
+            case 10:
+                framerLaneXbar = 0x80;
+                break;
+            case 12:
+                framerLaneXbar = 0x80;
+                break;
+            default:
+                /* default to valid setting for Lane 0 */
+                framerLaneXbar = 0x08;
+                break;
+        }
+    }
+    else
+    {
+        switch ((device->obsRx->framer->serializerLanesEnabled & 0x0F))
+        {
+            /* all 4 lanes get framer 0 output */
+            case 1:
+                framerLaneXbar = 0x00;
+                break;
+            case 2:
+                framerLaneXbar = 0x00;
+                break;
+            case 3:
+                framerLaneXbar = 0x04;
+                break;
+            case 4:
+                framerLaneXbar = 0x00;
+                break;
+            case 5:
+                framerLaneXbar = 0x10;
+                break;
+            case 6:
+                framerLaneXbar = 0x10;
+                break;
+            case 8:
+                framerLaneXbar = 0x00;
+                break;
+            case 9:
+                framerLaneXbar = 0x40;
+                break;
+            case 10:
+                framerLaneXbar = 0x40;
+                break;
+            case 12:
+                framerLaneXbar = 0x40;
+                break;
+            case 15:
+                framerLaneXbar = 0xE4;
+                break;
+            default:
+                /* default to valid setting for all Lanes */
+                framerLaneXbar = 0xE4;
+                break;
+        }
+    }
+
+    /* Framer: set Lane Crossbar */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_XBAR_SEL, framerLaneXbar);
+
+    /* Framer: determine the framerConfigF value (2*M/L) */
+    framerConfigF = 2 * (device->obsRx->framer->M / L);
+
+    /* Framer: Soft Reset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x03);
+
+    /* Framer: Clear Soft Reset */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x00);
+
+    /* Framer: Set F (Octets in Frame) */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CONFIG_F, framerConfigF);
+
+    /* Framer: Enable framer clock and lane clocks */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0x03, 0x03, 0);
+
+    /* Set Framer lane FIFO enable for each lane enabled */
+    laneFifoEnable = (((device->obsRx->framer->serializerLanesEnabled & 0x0F) << 4) | 0x01);
+
+    /* Framer: Enable Lane FIFOs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LANE_CTL, laneFifoEnable);
+
+    /* enabling the SYSREF for relink if newSysrefOnRelink is set */
+    if (device->obsRx->framer->newSysrefOnRelink)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x01, 0x40, 6);
+    }
+
+    /* enabling auto channel if the enableAutoChanXbar structure member is set */
+    if (device->obsRx->framer->enableAutoChanXbar)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV, 0x01, 0x04, 2);
+    }
+
+    /* Setup submap registers */
+    SUBCLASSV = 1; /* JESD subclass 1 */
+    JESDV = 1; /* Version: JESD204B */
+    DID = device->obsRx->framer->deviceId;
+    BID = device->obsRx->framer->bankId;
+    LID0 = device->obsRx->framer->lane0Id;
+    LID1 = device->obsRx->framer->lane0Id + 1;
+    LID2 = device->obsRx->framer->lane0Id + 2;
+    LID3 = device->obsRx->framer->lane0Id + 3;
+
+    CS = 0;
+    N = 0x0F;
+    Np = 0x0F;
+    S = 0;
+    CF = 0;
+    K = device->obsRx->framer->K - 1;
+    HD = 0;
+    FramerL = L - 1;
+    FramerM = device->obsRx->framer->M - 1;
+    FramerF = (2 * device->obsRx->framer->M / L) - 1;
+
+    if (ML == 11)
+    {
+        regE0 = 0x1;
+        regE2 = 0x1;
+    }
+    else if (ML == 12)
+    {
+        regE0 = 0x1;
+        regE2 = 0x3;
+        HD = 1;
+    }
+    else if (ML == 21)
+    {
+        regE0 = 0x3;
+        regE2 = 0x1;
+    }
+    else if (ML == 22)
+    {
+        regE0 = 0x3;
+        regE2 = 0x3;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM;
+    }
+
+    /* setting K offset for framer */
+    if (device->obsRx->framer->lmfcOffset < device->rx->framer->K)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_LMFC_K_OFFSET, device->obsRx->framer->lmfcOffset);
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM;
+    }
+
+    subaddr[0] = 0x00;
+    subdata[0] = (DID & 0xFF); /* Device ID */
+    subaddr[1] = 0x01;
+    subdata[1] = (BID & 0x0F); /* Bank ID */
+    subaddr[2] = 0x02;
+    subdata[2] = (LID0 & 0x1F); /* Lane 0 ID */
+    subaddr[3] = 0x03;
+    subdata[3] = (device->obsRx->framer->scramble << 7) | (FramerL & 0x1F); /* [7] Scramble, #Lanes[4:0]-1 */
+    subaddr[4] = 0x04;
+    subdata[4] = (FramerF & 0xFF); /* F[7:0]-1 */
+    subaddr[5] = 0x05;
+    subdata[5] = (K & 0x1F); /* K[4:0]-1 */
+    subaddr[6] = 0x06;
+    subdata[6] = (FramerM & 0xFF); /* M[7:0]-1 */
+    subaddr[7] = 0x07;
+    subdata[7] = ((CS & 0x3) << 6) | (N & 0x1F); /* [7:6] = CS[1:0], N[4:0]-1 */
+    subaddr[8] = 0x08;
+    subdata[8] = ((SUBCLASSV & 7) << 5) | (Np & 0x1F); /* NP[4:0] -1 */
+    subaddr[9] = 0x09;
+    subdata[9] = ((JESDV & 7) << 5) | (S & 0x1F); /* S[4:0]-1 */
+    subaddr[10] = 0x0a;
+    subdata[10] = ((HD & 1) << 7) | (CF & 0x1F); /* [7] = HD, CF[4:0] */
+    subaddr[11] = 0x0b;
+    subdata[11] = 0x00; /* reserved */
+    subaddr[12] = 0x0c;
+    subdata[12] = 0x00; /* reserved */
+
+    CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID0 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+            + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+    /* Checksum Lane 0 */
+    subaddr[13] = 0x0d;
+    subdata[13] = CheckSum & 0xFF;
+
+    /* Lane 1 ID */
+    subaddr[14] = 0x12;
+    subdata[14] = LID1;
+
+    CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID1 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+            + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+    /* Checksum Lane 1 */
+    subaddr[15] = 0x15;
+    subdata[15] = CheckSum & 0xFF;
+
+    /* Lane 2 ID */
+    subaddr[16] = 0x1a;
+    subdata[16] = LID2;
+
+    CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID2 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+            + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+    /* Checksum Lane 2 */
+    subaddr[17] = 0x1d;
+    subdata[17] = CheckSum & 0xFF;
+
+    /* Lane 3 ID */
+    subaddr[18] = 0x22;
+    subdata[18] = LID3;
+
+    CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID3 & 0x1F) + (device->obsRx->framer->scramble) + (FramerL & 0x1F) + (FramerF & 0xFF) + (K & 0x1F) + (FramerM & 0xFF)
+            + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+
+    subaddr[19] = 0x25;
+    subdata[19] = CheckSum & 0xFF;
+
+    subaddr[20] = 0xe0;
+    subdata[20] = regE0; /* Enable converter n logic */
+    subaddr[21] = 0xe2;
+    subdata[21] = regE2; /* Enable Lane n logic */
+    subaddr[22] = 0xe4;
+    subdata[22] = 0x00;
+    subaddr[23] = 0xe6;
+    subdata[23] = 0x00;
+    subaddr[24] = 0xf0;
+    subdata[24] = 0x00; /* #multiframes in ILAS */
+    subaddr[25] = 0xf2;
+    subdata[25] = 0x00;
+    subaddr[26] = 0xf3;
+    subdata[26] = 0x00;
+    subaddr[27] = 0xf4;
+    subdata[27] = 0x00;
+    subaddr[28] = 0xc0;
+    subdata[28] = 0x03; /* Framer enable, both sides perform lane sync */
+
+    for (i = 0; i <= 28; i++)
+    {
+        /* Set framer sub register map address */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_ADDR, subaddr[i]);
+
+        /* Set framer sub register map data word */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_DATA, subdata[i]);
+
+        /* Write enable */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_WRITE_EN, 0x01);
+    }
+
+    if (device->obsRx->framer->externalSysref > 0)
+    {
+        /* Framer: Enable lane FIFO sync (Enable CGS) */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x30);
+    }
+    else
+    {
+        /* Framer: Enable lane FIFO sync (Enable CGS) */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x10);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables/Disables the JESD204B Rx Framer
+ *
+ * This function is normally not necessary.  In the event that the link needs to be reset, this
+ * function allows the Rx framer to be disabled and re-enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->rx->framer->serializerLanesEnabled
+ *
+ * \param device is a pointer to the device settings structure
+ * \param enable 0 = Disable the selected framer, 1 = enable the selected framer link
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM Invalid serializerLanesEnabled parameter in device data structure
+ */
+mykonosErr_t MYKONOS_enableRxFramerLink(mykonosDevice_t *device, uint8_t enable)
+{
+    uint8_t enableLink = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableFramerLink()\n");
+#endif
+
+    enableLink = (enable > 0) ? 1 : 0;
+
+    if (enableLink)
+    {
+        /* Power Up serializer lanes */
+        if (device->rx->framer->serializerLanesEnabled > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM));
+            return MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM;
+        }
+
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, ((~device->rx->framer->serializerLanesEnabled) & 0x0F),
+                device->rx->framer->serializerLanesEnabled, 0);
+
+        /* Enable Clocks to Framer */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 3, 0x03, 0);
+
+        /* Release reset to framer and lane FIFOs */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x00);
+    }
+    else
+    {
+        /* Disable Link */
+        /* Hold Rx framer in reset */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_RESET, 0x03);
+
+        /* Disable Clocks to Framer */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CLK_EN, 0, 0x03, 0);
+
+        /* Power down serializer lanes */
+        if (device->rx->framer->serializerLanesEnabled > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM));
+            return MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM;
+        }
+
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, device->rx->framer->serializerLanesEnabled, device->rx->framer->serializerLanesEnabled, 0);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables/Disables the JESD204B ObsRx Framer
+ *
+ * This function is normally not necessary.  In the event that the link needs to be reset, this
+ * function allows the ObsRx framer to be disabled and re-enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->obsRx->framer->serializerLanesEnabled
+ *
+ * \param device is a pointer to the device settings structure
+ * \param enable 0 = Disable the selected framer, 1 = enable the selected framer link
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM Invalid serializerLanesEnabled parameter in device data structure (Valid 0-15)
+ */
+mykonosErr_t MYKONOS_enableObsRxFramerLink(mykonosDevice_t *device, uint8_t enable)
+{
+    uint8_t enableLink = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableObsRxFramerLink()\n");
+#endif
+
+    enableLink = (enable > 0) ? 1 : 0;
+
+    if (enableLink)
+    {
+        /* Power Up serializer lanes */
+        if (device->rx->framer->serializerLanesEnabled > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM));
+            return MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM;
+        }
+
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, ((~device->obsRx->framer->serializerLanesEnabled) & 0x0F),
+                device->obsRx->framer->serializerLanesEnabled, 0);
+
+        /* Enable Clocks to Framer */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 3, 0x03, 0);
+
+        /* Release reset to framer and lane FIFOs */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x00);
+    }
+    else
+    {
+        /* Disable Link */
+        /* Hold Rx framer in reset */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_RESET, 0x03);
+
+        /* Disable Clocks to Framer */
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CLK_EN, 0, 0x03, 0);
+
+        /* Power down serializer lanes */
+        if (device->obsRx->framer->serializerLanesEnabled > 15)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM,
+                    getMykonosErrorMessage(MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM));
+            return MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM;
+        }
+
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SERIALIZER_CTL_1, device->obsRx->framer->serializerLanesEnabled,
+                device->obsRx->framer->serializerLanesEnabled, 0);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the JESD204B Deframer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->tx->deframer->M
+ * - device->tx->deframer->bankId
+ * - device->tx->deframer->lane0Id
+ * - device->tx->deframer->K
+ * - device->tx->deframer->deserializerLanesEnabled
+ * - device->tx->deframer->externalSysref
+ * - device->tx->deframer->newSysrefOnRelink
+ * - device->tx->deframer->enableAutoChanXbar
+ * - device->tx->deframer->lmfcOffset
+ * - device->tx->deframer->scramble
+ *
+ * \param device Pointer to device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_DEFRAMER_INV_M_PARM Invalid M parameter in deframer structure
+ * \retval MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM Invalid BankId parameter in deframer structure (Valid 0-15)
+ * \retval MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM Invalid Lane0Id parameter in deframer structure (Valid 0-31)
+ * \retval MYKONOS_ERR_DEFRAMER_INV_K_PARAM Invalid K parameter in deframer structure (valid 1-32 with other constraints)
+ * \retval MYKONOS_ERR_DEFRAMER_INV_FK_PARAM Invalid F*K parameter (Valid F*K > 20, F*K must be divisible by 4), K must be <= 32
+ * \retval MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM Invalid K offset parameter in deframer structure (must be less than K)
+ */
+mykonosErr_t MYKONOS_setupJesd204bDeframer(mykonosDevice_t *device)
+{
+    uint8_t i = 0;
+    uint8_t temp = 0;
+    uint8_t reg080 = 0;
+    uint8_t laneXbar = 0;
+    uint8_t L = 0;
+    uint8_t ML = 0;
+
+    /* Setup submap registers */
+    uint8_t SUBCLASSV = 1;
+    uint8_t JESDV = 1;
+    uint8_t DID = 0;
+    uint8_t BID = 0;
+    uint8_t LID0 = 0;
+    uint8_t CS = 2; /* 2 control bits */
+    uint8_t N = 0x0D; /* 14 bits */
+    uint8_t Np = 0x0F; /* 16 bits */
+    uint8_t S = 0;
+    uint8_t CF = 0;
+    uint8_t K = 0x1F;
+    uint16_t FK = 0;
+    uint8_t HD = 0; /* only one case has HD == 1 */
+    uint8_t CTRLREG0 = 0;
+    uint8_t DeframerL = 1;
+    uint8_t DeframerM = 2;
+    uint8_t DeframerF = 0;
+    uint8_t CTRLREG1 = 0;
+    uint8_t CTRLREG2 = 0;
+    uint8_t DeframerLaneEnable = 0x00;
+    uint16_t CheckSum = 0;
+    uint8_t subaddr[25] = {0};
+    uint8_t subdata[25] = {0};
+
+    uint8_t deframerInput = 0;
+    uint8_t lane = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setupJesd204bDeframer()\n");
+#endif
+
+    if (device->tx->deframer->M != 0 && device->tx->deframer->M != 2 && device->tx->deframer->M != 4)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_M_PARM));
+        return MYKONOS_ERR_DEFRAMER_INV_M_PARM;
+    }
+
+    if (device->tx->deframer->bankId > 15)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM));
+        return MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM;
+    }
+
+    if (device->tx->deframer->lane0Id > 31)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM));
+        return MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM;
+    }
+
+    //count number of lanes
+    L = 0;
+    ML = 0;
+
+    for (i = 0; i < 4; i++)
+    {
+        L += ((device->tx->deframer->deserializerLanesEnabled >> i) & 0x01);
+    }
+
+    ML = device->tx->deframer->M * 10 + L;
+
+    if (device->tx->deframer->K > 32)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_K_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_K_PARAM));
+        return MYKONOS_ERR_DEFRAMER_INV_K_PARAM;
+    }
+
+    FK = (uint16_t)device->tx->deframer->K * 2 * device->tx->deframer->M / L;
+
+    if (FK < 20 || FK > 256 || FK % 4 != 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_FK_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_FK_PARAM));
+        return MYKONOS_ERR_DEFRAMER_INV_FK_PARAM;
+    }
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYNC_REQ_RETIME, (device->tx->deframer->K - 1), 0x1F, 0x00);
+
+    if (!device->tx->deframer->externalSysref)
+    {
+        /* Deframer: Generate SYSREF internally */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_TEST, 0x02);
+    }
+
+    /* enabling the SYSREF for relink if newSysrefOnRelink is set */
+    if (device->tx->deframer->newSysrefOnRelink)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x01, 0x40, 6);
+    }
+
+    /* enabling auto channel if the enableAutoChanXbar structure member is set */
+    if (device->tx->deframer->enableAutoChanXbar)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV, 0x01, 0x04, 2);
+    }
+
+    /* Fix bad default bit to allow deterministic latency on deframer (Clear bit 4)*/
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV, 0x00, 0x10, 4);
+
+    /* Deframer: Set DAC Crossbar */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DAC_XBAR_SEL, 0xB1);
+
+    /* Lane crossbar  - Allow user to reorder lanes in deframer->deserializerLaneCrossbar, but this code still */
+    /* maps used lanes to deframer inputs */
+    deframerInput = 0;
+    for (lane = 0; lane < 4; lane++)
+    {
+        if ((device->tx->deframer->deserializerLanesEnabled >> lane) & 1)
+        {
+            laneXbar |= (((device->tx->deframer->deserializerLaneCrossbar >> (lane << 1)) & 3) << (deframerInput << 1));
+            deframerInput += 1;
+        }
+    }
+
+    if (ML == 42)
+    {
+        /* M4L2 uses internal deframer ports 0 and 2 */
+        /* swap bits 3:2 and 5:4, keep 1:0 and 7:6 in place */
+        laneXbar = (laneXbar & 0xC3U) | ((laneXbar & 0x30) >> 2) | ((laneXbar & 0x0C) << 2);
+    }
+
+    /* Deframer: Set Lane Crossbar */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LANE_XBAR_SEL, laneXbar);
+
+    //Find value for Framer F depending on M and L
+    switch (ML)
+    {
+        case 21:
+            reg080 = 0x04;
+            break;
+        case 22:
+            reg080 = 0x22;
+            break;
+        case 24:
+            reg080 = 0x41;
+            break;
+        case 41:
+            reg080 = 0x18;
+            break;
+        case 42:
+            reg080 = 0x34;
+            break;
+        case 44:
+            reg080 = 0x52;
+            break;
+        default:
+            reg080 = 0x04;
+            break;
+    }
+
+    /* Deframer: Set F (Octets in Frame) */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_CONFIG_F, reg080);
+
+    /* Deframer: Enable clocks and lane clocks */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_CLK_EN, 0x03);
+
+    /* Set deframer lane FIFO enable for each lane enabled */
+    temp = (device->tx->deframer->deserializerLanesEnabled & 0x0F);
+
+    /* Deframer: Enable Lane FIFOs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LANE_FIFO_CTL, temp);
+
+    /* Setup submap registers */
+    SUBCLASSV = 1; /* JESD subclass 1 */
+    JESDV = 1; /* Version: JESD204B */
+    DID = device->tx->deframer->deviceId;
+    BID = device->tx->deframer->bankId;
+    LID0 = device->tx->deframer->lane0Id;
+    CS = 2; /* 2 control bits */
+    N = 0x0D; /* 14 bits */
+    Np = 0x0F;
+    S = 0;
+    CF = 0;
+    K = device->tx->deframer->K - 1;
+    HD = 0; /* only one case has HD = 1 */
+    CTRLREG0 = 1;
+    DeframerL = L - 1;
+    DeframerM = device->tx->deframer->M - 1;
+    DeframerF = (2 * device->tx->deframer->M / L) - 1;
+    CheckSum = 0;
+
+    if (ML == 21)
+    {
+        CTRLREG1 = 4;
+        CTRLREG2 = 0x14;
+        DeframerLaneEnable = 1;
+    }
+    else if (ML == 22)
+    {
+        CTRLREG1 = 2;
+        CTRLREG2 = 4;
+        DeframerLaneEnable = 3;
+    }
+    else if (ML == 24)
+    {
+        HD = 1;
+        CTRLREG1 = 1;
+        CTRLREG2 = 0;
+        DeframerLaneEnable = 0x0F;
+    }
+    else if (ML == 41)
+    {
+        CTRLREG1 = 8;
+        CTRLREG2 = 0;
+        DeframerLaneEnable = 1;
+    }
+    else if (ML == 42)
+    {
+        CTRLREG1 = 4;
+        CTRLREG2 = 0;
+        DeframerLaneEnable = 5;
+    }
+    else if (ML == 44)
+    {
+        CTRLREG1 = 2;
+        CTRLREG2 = 0;
+        DeframerLaneEnable = 0x0F;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_M_PARM, getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_M_PARM));
+        return MYKONOS_ERR_DEFRAMER_INV_M_PARM;
+    }
+
+    /* LMFC offset limit check */
+    if (device->tx->deframer->lmfcOffset < device->tx->deframer->K)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_LMFC_K_OFFSET, device->tx->deframer->lmfcOffset);
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM));
+        return MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM;
+    }
+
+    subaddr[0] = 0x50;
+    subdata[0] = DID & 0xFFU; /* Device ID */
+    subaddr[1] = 0x51;
+    subdata[1] = BID & 0x0F; /* Bank ID */
+    subaddr[2] = 0x52;
+    subdata[2] = LID0 & 0x1F; /* Lane 0 ID */
+    subaddr[3] = 0x53;
+    subdata[3] = (device->tx->deframer->scramble << 7) | (DeframerL & 0x1F); /* [7] = Scramble Enable, #Lanes[4:0] */
+    subaddr[4] = 0x54;
+    subdata[4] = DeframerF & 0xFFU; /* F[7:0] */
+    subaddr[5] = 0x55;
+    subdata[5] = K & 0x1F; /* K[4:0] */
+    subaddr[6] = 0x56;
+    subdata[6] = DeframerM & 0xFFU; /* M[7:0] */
+    subaddr[7] = 0x57;
+    subdata[7] = ((CS & 0x3) << 6) | (N & 0x1F); /* [7:6] = CS[1:0], N[4:0] */
+    subaddr[8] = 0x58;
+    subdata[8] = ((SUBCLASSV & 7) << 5) | (Np & 0x1F); /* Np[4:0] */
+    subaddr[9] = 0x59;
+    subdata[9] = ((JESDV & 7) << 5) | (S & 0x1F); /* S[4:0] */
+    subaddr[10] = 0x5A;
+    subdata[10] = ((HD & 1) << 7) | (CF & 0x1F); /* [7]=HD, CF[4:0] */
+    subaddr[11] = 0x5B;
+    subdata[11] = 0x00; /* reserved */
+    subaddr[12] = 0x5C;
+    subdata[12] = 0x00; /* reserved */
+    CheckSum = (DID & 0xFF) + (BID & 0xF) + (LID0 & 0x1F) + (device->tx->deframer->scramble) + (DeframerL & 0x1F) + (DeframerF & 0xFF) + (K & 0x1F) + (DeframerM & 0xFF)
+            + (CS & 0x3) + (N & 0x1F) + (Np & 0x1F) + (S & 0x1F) + (HD & 1) + (CF & 0x1F) + (SUBCLASSV & 7) + (JESDV & 7);
+    subaddr[13] = 0x5D;
+    subdata[13] = CheckSum & 0xFFU; /* Checksum Lane 0 */
+    subaddr[14] = 0x6D;
+    subdata[14] = 0xA0U; /* Bad Disparity setup */
+    subaddr[15] = 0x6E;
+    subdata[15] = 0xA0U; /* Not in Table setup */
+    subaddr[16] = 0x6F;
+    subdata[16] = 0xA0U; /* UnExpected K character setup */
+    subaddr[17] = 0x75;
+    subdata[17] = CTRLREG0; /* CTRLREG 0 */
+    subaddr[18] = 0x76;
+    subdata[18] = CTRLREG1; /* CTRLREG 1 (Bytes per frame) */
+    subaddr[19] = 0x77;
+    subdata[19] = CTRLREG2; /* CTRLREG 2 */
+    subaddr[20] = 0x78;
+    subdata[20] = 0x01; /* # 4*K multiframes during ILAS */
+    subaddr[21] = 0x7A;
+    subdata[21] = 0xE0U; /* Setup JESD interrupt sources */
+    subaddr[22] = 0x7B;
+    subdata[22] = 0x08U; /* Sync assertion setup */
+    subaddr[23] = 0x7C;
+    subdata[23] = 0xFFU; /* Error count threshold */
+    subaddr[24] = 0x7D;
+    subdata[24] = DeframerLaneEnable & 0xFFU; /* Lane enable */
+
+    for (i = 0; i <= 24; i++)
+    {
+        /* Set deframer sub-register map address */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_ADDR, subaddr[i]);
+
+        /* Set deframer sub-register map data word */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DATA, subdata[i]);
+
+        /* Set write enable to latch data into deframer sub register map */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_WR_EN, 0x01);
+    }
+
+    /* Deframer: Enable lane FIFO sync */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x10);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets up the chip for multichip sync, and cleans up after MCS.
+ *
+ *  When working with multiple transceivers or even only one transceiver that requires deterministic
+ *  latency between the Tx and observation and or main Rx JESD204B data path, Multichip sync is
+ *  necessary.  This function should be run after all transceivers are initialized.
+ *
+ *  After the SYSREF pulses have been sent, call the MYKONOS_enableMultichipSync() function again with the
+ *  enableMcs parameter set to 0.  When enableMcs = 0, the MCS status will be returned in the mcsStatus
+ *  parameter.
+ *
+ *  Typical sequence:
+ *  1) Initialize all Mykonos devices in system using MYKONOS_initialize()
+ *  2) Run MYKONOS_enableMultichipSync with enableMcs = 1
+ *  3) Send at least 3 SYSREF pulses
+ *  4) Run MYKONOS_enableMultichipSync with enableMcs = 0
+ *  5) Load ARM, run ARM cals and continue to active Transmit/Receive
+ *
+ *  mcsStatus | bit Description
+ * -----------|--------------------------------------------------------
+ *       [0]  | MCS JESD SYSREF Status (1 = sync occurred)
+ *       [1]  | MCS Digital Clocks Sync Status (1 = sync occurred)
+ *       [2]  | MCS CLKPLL SDM Sync Status (1 = sync occurred)
+ *       [3]  | MCS Device Clock divider Sync Status (1 = sync occurred)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param enableMcs =1 will enable the MCS state machine, =0 will allow reading back MCS status
+ * \param mcsStatus optional parameter, if pointer is not null the function Which will be populated with the mcsStatus word described in the table above.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enableMultichipSync(mykonosDevice_t *device, uint8_t enableMcs, uint8_t *mcsStatus)
+{
+    uint8_t clkPllSdmBypass = 0;
+    uint8_t mcsEnable = 0x9B; /* [7] Keeps RF LO divider enabled, Enable MCS[4] and reset Device Clock divider[3], Digital clocks[1], and JESD204 SYSREF[0] */
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableMultichipSync()\n");
+#endif
+
+    if (enableMcs)
+    {
+        /* If CLKPLL SDM not bypassed, reset CLKPLL SDM as well. */
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1, &clkPllSdmBypass, 0x40, 6);
+
+        if (clkPllSdmBypass == 0)
+        {
+            mcsEnable |= 0x04; /* enable MCS for CLKPLL SDM */
+        }
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_MCS_CONTROL, mcsEnable);
+    }
+
+    /* if mcsStatus is a valid pointer, return the MCS status */
+    if (mcsStatus != NULL)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_MCS_STATUS, mcsStatus);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables or disables SYSREF to the transceiver's RX framer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param enable = '1' enables SYSREF to RX framer, '0' disables SYSREF to framer
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enableSysrefToRxFramer(mykonosDevice_t *device, uint8_t enable)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableSysrefToRxFramer()\n");
+#endif
+
+    if (enable)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x01, 0x01, 0);
+    }
+    else
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN, 0x00, 0x01, 0);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables or disables SYSREF to the transceiver's Observation RX framer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param enable = '1' enables SYSREF to OBSRX framer, '0' disables SYSREF to framer
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enableSysrefToObsRxFramer(mykonosDevice_t *device, uint8_t enable)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableSysrefToObsRxFramer()\n");
+#endif
+
+    if (enable)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x01, 0x01, 0);
+    }
+    else
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN, 0x00, 0x01, 0);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Enables or disables SYSREF to the transceiver's deframer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param enable = '1' enables SYSREF to deframer, '0' disables SYSREF to deframer
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_enableSysrefToDeframer(mykonosDevice_t *device, uint8_t enable)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableSysrefToDeframer()\n");
+#endif
+
+    if (enable)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x01, 0x01, 0);
+    }
+    else
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN, 0x00, 0x01, 0);
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the transceiver's RX framer status
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * framerStatus |  Description
+ * -------------|-----------------------------------------------------------------------------
+ *         [7]  | SYSREF phase error � a new SYSREF had different timing than the first that set the LMFC timing.
+ *         [6]  | Framer lane FIFO read/write pointer delta has changed.  Can help debug issues with deterministic latency.
+ *         [5]  | Framer has received the SYSREF and has retimed its LMFC
+ *       [4:2]  | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete
+ *       [1:0]  | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data
+ *
+ * \param device is a pointer to the device settings structure
+ * \param framerStatus is the RX framer status byte read
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM Function parameter framerStatus has NULL pointer
+ */
+mykonosErr_t MYKONOS_readRxFramerStatus(mykonosDevice_t *device, uint8_t *framerStatus)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readRxFramerStatus()\n");
+#endif
+
+    if (framerStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM));
+        return MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_STATUS_STRB, 0x01);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_STATUS_STRB, 0x00);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FRAMER_STATUS, framerStatus);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the transceiver's Observation RX framer status
+ *
+ * <B>Dependencies</B>
+ * * - device->spiSettings
+ *
+ * obsFramerStatus |  Description
+ * ----------------|-----------------------------------------------------------------------------
+ *            [7]  | SYSREF phase error � a new SYSREF had different timing than the first that set the LMFC timing.
+ *            [6]  | Framer lane FIFO read/write pointer delta has changed.  Can help debug issues with deterministic latency.
+ *            [5]  | Framer has received the SYSREF and has retimed its LMFC
+ *          [4:2]  | Framer ILAS state: 0=CGS, 1= 1st Multframe, 2= 2nd Multiframe, 3= 3rd Multiframe, 4= 4th multiframe, 5= Last multiframe, 6=invalid, 7= ILAS complete
+ *          [1:0]  | Framer Tx state: 0=CGS, 1= ILAS, 2 = ADC Data
+ *
+ * \param device is a pointer to the device settings structure
+ * \param obsFramerStatus is the OBSRX framer status byte read
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM Function parameter obsFramerStatus has NULL pointer
+ */
+mykonosErr_t MYKONOS_readOrxFramerStatus(mykonosDevice_t *device, uint8_t *obsFramerStatus)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readOrxFramerStatus()\n");
+#endif
+
+    if (obsFramerStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM));
+        return MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB, 0x01);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB, 0x00);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_STATUS, obsFramerStatus);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the transceiver's deframer status
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ *   deframerStatus  |  Bit Name                |  Description
+ *   ----------------|--------------------------|---------------------------------------------
+ *              [7]  | Unused                   | Unused
+ *              [6]  | Deframer IRQ             | This bit indicates that the IRQ interrupt was asserted.
+ *              [5]  | Deframer SYSREF Received | When this bit is set, it indicates that the SYSREF pulse was received by the deframer IP
+ *              [4]  | Deframer Receiver Error  | This bit is set when PRBS has received an error.
+ *              [3]  | Valid Checksum           | This bit is set when the received ILAS checksum is valid.
+ *              [2]  | EOF Event                | This bit captures the internal status of the framer End of Frame event. Value =1 if framing error during ILAS
+ *              [1]  | EOMF Event               | This bit captures the internal status of the framer End of Multi-Frame event. Value =1 if framing error during ILAS
+ *              [0]  | FS Lost                  | This bit captures the internal status of the framer Frame Symbol event. Value =1 if framing error during ILAS or user data (invalid replacement characters)
+ *
+ *
+ * \param device is a pointer to the device settings structure
+ * \param deframerStatus is the deframer status byte read
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM Function parameter deframerStatus has NULL pointer
+ */
+mykonosErr_t MYKONOS_readDeframerStatus(mykonosDevice_t *device, uint8_t *deframerStatus)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readDeframerStatus()\n");
+#endif
+
+    if (deframerStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM));
+        return MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x01);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x00);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT, deframerStatus);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the Mykonos JESD204b Deframer determinstic FIFO depth
+ *
+ * To verify that the deterministic latency FIFO is not close to a underflow or
+ * overflow condition, it is recommended to check the FIFO depth. If the FIFO
+ * is close to an overflow or underflow condition, it is possible that from
+ * power up to powerup, deterministic latency may not be met.  If a underflow
+ * or overflow occurred, the data would still be correct, but would possibly
+ * slip by 1 multiframe (losing deterministic latency).  To correct for an
+ * overflow/underflow, the BBIC would need to add delay from SYSREF until
+ * the first symbol in a multiframe
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param fifoDepth Return value that describes the depth of the Mykonos
+ *                  deterministic latency deframer FIFO.
+ * \param readEnLmfcCount Returns the LMFC count value when the deterministic FIFO read enable was asserted.
+ *                        Counts at the Mykonos internal deframer PCLK frequency.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM Error: function parameter fifoDepth is a NULL pointer
+ * \retval MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM Error: function parameter readEnLmfcCount is a NULL pointer
+ *
+ */
+mykonosErr_t MYKONOS_getDeframerFifoDepth(mykonosDevice_t *device, uint8_t *fifoDepth, uint8_t *readEnLmfcCount)
+{
+    uint8_t fifoReadPtr = 0;
+    uint8_t fifoWritePtr = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDeframerFifoDepth()\n");
+#endif
+
+    if (fifoDepth == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM));
+        return MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM;
+    }
+
+    if (readEnLmfcCount == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM));
+        return MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x01);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x00);
+
+    /* read/write pointers are 7 bits, (0 - 127) */
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_RD_ADDR, &fifoReadPtr, 0x7F, 0);
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_ADDR, &fifoWritePtr, 0x7F, 0);
+
+    /* Adding 128 and modulus 128 handle the wrap cases where the read pointer
+     * is less than write pointer
+     */
+    *fifoDepth = (((fifoReadPtr + 128) - fifoWritePtr) % 128);
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DET_FIFO_PHASE, readEnLmfcCount);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Selects the PRBS type and enables or disables RX Framer PRBS20 generation
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param polyOrder selects the PRBS type based on a two-bit value range from 0-3
+ * \param enable '1' = enables PRBS RX framer PRBS generator, '0' = disables PRBS generator
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM Invalid polyOrder parameter, use ENUM
+ *
+ */
+mykonosErr_t MYKONOS_enableRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable)
+{
+    uint8_t wrmask = 0;
+    uint8_t enableBit = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableRxFramerPrbs()\n");
+#endif
+
+    enableBit = (enable > 0) ? 1 : 0;
+
+    if ((polyOrder == MYK_PRBS7) || (polyOrder == MYK_PRBS15) || (polyOrder == MYK_PRBS31))
+    {
+        wrmask = (polyOrder << 1) | enableBit;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM));
+        return MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, wrmask);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Selects the PRBS type and enables or disables OBSRX Framer PRBS20 generation
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param polyOrder selects the PRBS type based on a two-bit value range from 0-3
+ * \param enable '1' = enables PRBS OBSRX framer PRBS generator, '0' = disables PRBS generator
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM polyOrder parameter is not a valid value - use ENUM
+ */
+mykonosErr_t MYKONOS_enableObsRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable)
+{
+    uint8_t wrmask = 0;
+    uint8_t enableBit = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableObsRxFramerPrbs()\n");
+#endif
+
+    enableBit = (enable > 0) ? 1 : 0;
+
+    if ((polyOrder == MYK_PRBS7) || (polyOrder == MYK_PRBS15) || (polyOrder == MYK_PRBS31))
+    {
+        wrmask = (polyOrder << 1) | enableBit;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM));
+        return MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, wrmask);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Injects a PRBS error into the RX data path
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_rxInjectPrbsError(mykonosDevice_t *device)
+{
+    uint8_t prbsControl = 0x00;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_rxInjectPrbsError()\n");
+#endif
+
+    /* reading current PRBS20 control register contents */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, &prbsControl);
+
+    /* setting bit 4 in framer PRBS20 control register and then clearing it for error injection */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, prbsControl |= 0x10);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FRAMER_PRBS20_CTL, prbsControl &= ~0x10);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Initiates a PRBS error injection into the Observation RX data path
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_obsRxInjectPrbsError(mykonosDevice_t *device)
+{
+    uint8_t prbsControl = 0x00;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_obsRxInjectPrbsError()\n");
+#endif
+
+    /* reading current PRBS20 control register contents */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, &prbsControl);
+
+    /* setting bit 4 in framer PRBS20 control register and then clearing it for error injection */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, prbsControl |= 0x10);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL, prbsControl &= ~0x10);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Configures and enables or disables the transceiver's deframer PRBS checker
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param lanes selects the lane for PRBS checking based on a 4-bit mask, where each weighted bit
+ * corresponds with a different lane selection as such: '1' = lane 0, '2' = lane 1, '4' = lane 2, '8' = lane 3
+ * \param polyOrder selects the PRBS type based on enum values (MYK_PRBS7, MYK_PRBS15, MYK_PRBS31)
+ * \param enable '1' = enables checking, '0' = disables checking
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM Invalid polyOrder parameter - use ENUM
+ * \retval MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM Invalid enable (valid 0-1) or lanes (valid 0-15) parameter
+ */
+mykonosErr_t MYKONOS_enableDeframerPrbsChecker(mykonosDevice_t *device, uint8_t lanes, mykonosPrbsOrder_t polyOrder, uint8_t enable)
+{
+    uint8_t wrmask = 0x00;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableDeframerPrbsChecker()\n");
+#endif
+
+    if ((enable <= 0x01) && (lanes <= 0x0F))
+    {
+        if ((polyOrder == MYK_PRBS7) || (polyOrder == MYK_PRBS15) || (polyOrder == MYK_PRBS31))
+        {
+            wrmask = (lanes << 4) | (polyOrder << 1) | enable;
+        }
+        else
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM,
+                    getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM));
+            return MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM;
+        }
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM));
+        return MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, wrmask);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the deframer PRBS counters
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ * \param counterSelect selects the PRBS error counter to be read based on values between 0-3
+ *                      If counterSelect exceeds this value an error is thrown.
+ *
+ * \param prbsErrorCount is return value after reading the PRBS error count
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM Function parameter prbsErrorCount has NULL pointer
+ * \retval MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM if counterSelect is out of bounds
+ */
+mykonosErr_t MYKONOS_readDeframerPrbsCounters(mykonosDevice_t *device, uint8_t counterSelect, uint32_t *prbsErrorCount)
+{
+    uint8_t wrmask = 0x00;
+    uint8_t errorCnt[3];
+    const uint8_t COUNTER_SATURATE = 0x40;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readDeframerPrbsCounters()\n");
+#endif
+
+    if (prbsErrorCount == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM));
+        return MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM;
+    }
+
+    if (counterSelect & ~0x03)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM));
+        return MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM;
+    }
+    else
+    {
+        wrmask = COUNTER_SATURATE | (counterSelect << 4);
+        *prbsErrorCount = 0x00000000;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE, wrmask);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE, wrmask |= 0x01);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE, wrmask &= ~0x01);
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_7_TO_0, &errorCnt[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_15_TO_8, &errorCnt[1]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_23_TO_16, &errorCnt[2]);
+
+    *prbsErrorCount = (uint32_t)(errorCnt[2] << 16) | (uint32_t)(errorCnt[1] << 8) | (uint32_t)(errorCnt[0]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Clears the deframer/deserializer PRBS counters
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_clearDeframerPrbsCounters(mykonosDevice_t *device)
+{
+    uint8_t spiReg = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_clearDeframerPrbsCounters()\n");
+#endif
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, &spiReg);
+    spiReg &= ~0x08; //make sure PRBS clear bit is 0
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, (spiReg | 0xF8)); //clear counters for all lanes
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_PRBS20_CTL, spiReg); //set reg back to previous value
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the lane 0 JESD204B deframer configuration and compares it against the ILAS received values
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param mismatch [15-0] is a bit-encoded word which for mismatch[15] = '0' = no mismatch, '1' = mismatch for one or more parameters
+ * mismatch bits [14-0] are aligned with the mykonosJesd204bLane0Config_t structure members starting at '0' = DID.  The aligned bit is set to
+ * '1' if the configuration parameter does not agree with its corresponding received ILAS value, otherwise '0' if they agree.
+ *
+ * The bit assignments for the 16-bit word are:
+ *   mismatch | bit description
+ * -----------|--------------------------------------------------------
+ *      [0]   | JESD204B DID: device ID
+ *      [1]   | JESD204B BID: bank ID
+ *      [2]   | JESD204B LID0: lane ID
+ *      [3]   | JESD204B L: lanes per data converter
+ *      [4]   | JESD204B SCR: scramble setting
+ *      [5]   | JESD204B F: octets per frame
+ *      [6]   | JESD204B K: frames per multiframe
+ *      [7]   | JESD204B M: number of data converters
+ *      [8]   | JESD204B N: data converter sample resolution
+ *      [9]   | JESD204B CS: number of control bits transferred per sample per frame
+ *      [10]  | JESD204B NP: JESD204B word size based on the highest data converter resolution
+ *      [11]  | JESD204B S: number of samples per converter per frame
+ *      [12]  | JESD204B CF: '0' = control bits appended to each sample, '1' = control bits appended to end of frame
+ *      [13]  | JESD204B HD: high density bit, where '0' = samples are contained with single lane, '1' = samples are divided over more than one lane
+ *      [14]  | JESD204B FCHK0: configuration checksum OK bit. where '1' = fail, '0' = pass
+ *      [15]  | MISMATCH DETECTED BIT: bits 0-14 are ored together to set this bit
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM Function parameter mismatch has NULL pointer
+ */
+mykonosErr_t MYKONOS_jesd204bIlasCheck(mykonosDevice_t *device, uint16_t *mismatch)
+{
+    uint8_t i = 0;
+    uint8_t ilasdata[15] = {0};
+    uint8_t cfgdata[15] = {0};
+    mykonosJesd204bLane0Config_t lane0ILAS;
+    mykonosJesd204bLane0Config_t lane0Cfg;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_jesd204bIlasCheck()\n");
+#endif
+
+    if (mismatch == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM));
+        return MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM;
+    }
+
+    *mismatch = 0;
+
+    /* setting deframer read received ILAS data */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_WR_EN, 0x00);
+
+    /* reading deframer received ILAS register contents into array */
+    for (i = 0; i < 15; i++)
+    {
+        /* setting the deframer sub-address for received ilas data */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_ADDR, MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_RECVD + i);
+
+        /* reading the received ILAS data into byte array */
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DATA, &ilasdata[i]);
+    }
+
+    /* reading deframer config register contents into array */
+    for (i = 0; i < 15; i++)
+    {
+        /* setting the deframer sub-address for received ilas data */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_ADDR, MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_CFG + i);
+
+        /* reading the received ILAS data into byte array */
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_DATA, &cfgdata[i]);
+    }
+
+    /* loading the structures with the read values for easier reading when doing compares */
+    lane0ILAS.DID = ilasdata[0];
+    lane0ILAS.BID = ilasdata[1] & 0x0F;
+    lane0ILAS.LID0 = ilasdata[2] & 0x1F;
+    lane0ILAS.L = ilasdata[3] & 0x1F;
+    lane0ILAS.SCR = ilasdata[3] >> 7;
+    lane0ILAS.F = ilasdata[4];
+    lane0ILAS.K = ilasdata[5] & 0x1F;
+    lane0ILAS.M = ilasdata[6];
+    lane0ILAS.N = ilasdata[7] & 0x1F;
+    lane0ILAS.CS = ilasdata[7] >> 6;
+    lane0ILAS.NP = ilasdata[8] & 0x1F;
+    lane0ILAS.S = ilasdata[9] & 0x1F;
+    lane0ILAS.CF = ilasdata[10] & 0x1F;
+    lane0ILAS.HD = ilasdata[10] >> 7;
+    lane0ILAS.FCHK0 = ilasdata[13];
+
+    lane0Cfg.DID = cfgdata[0];
+    lane0Cfg.BID = cfgdata[1] & 0x0F;
+    lane0Cfg.LID0 = cfgdata[2] & 0x0F;
+    lane0Cfg.L = cfgdata[3] & 0x1F;
+    lane0Cfg.SCR = cfgdata[3] >> 7;
+    lane0Cfg.F = cfgdata[4];
+    lane0Cfg.K = cfgdata[5] & 0x1F;
+    lane0Cfg.M = cfgdata[6];
+    lane0Cfg.N = cfgdata[7] & 0x1F;
+    lane0Cfg.CS = cfgdata[7] >> 6;
+    lane0Cfg.NP = cfgdata[8] & 0x1F;
+    lane0Cfg.S = cfgdata[9] & 0x1F;
+    lane0Cfg.CF = cfgdata[10] & 0x1F;
+    lane0Cfg.HD = cfgdata[10] >> 7;
+    lane0Cfg.FCHK0 = cfgdata[13];
+
+    /* performing ILAS mismatch check */
+    if (lane0ILAS.DID != lane0Cfg.DID)
+    {
+        *mismatch |= 0x0001;
+    }
+
+    if (lane0ILAS.BID != lane0Cfg.BID)
+    {
+        *mismatch |= 0x0002;
+    }
+
+    if (lane0ILAS.LID0 != lane0Cfg.LID0)
+    {
+        *mismatch |= 0x0004;
+    }
+
+    if (lane0ILAS.L != lane0Cfg.L)
+    {
+        *mismatch |= 0x0008;
+    }
+
+    if (lane0ILAS.SCR != lane0Cfg.SCR)
+    {
+        *mismatch |= 0x0010;
+    }
+
+    if (lane0ILAS.F != lane0Cfg.F)
+    {
+        *mismatch |= 0x0020;
+    }
+
+    if (lane0ILAS.K != lane0Cfg.K)
+    {
+        *mismatch |= 0x0040;
+    }
+
+    if (lane0ILAS.M != lane0Cfg.M)
+    {
+        *mismatch |= 0x0080;
+    }
+
+    if (lane0ILAS.N != lane0Cfg.N)
+    {
+        *mismatch |= 0x0100;
+    }
+
+    if (lane0ILAS.CS != lane0Cfg.CS)
+    {
+        *mismatch |= 0x0200;
+    }
+
+    if (lane0ILAS.NP != lane0Cfg.NP)
+    {
+        *mismatch |= 0x0400;
+    }
+
+    if (lane0ILAS.S != lane0Cfg.S)
+    {
+        *mismatch |= 0x0800;
+    }
+
+    if (lane0ILAS.CF != lane0Cfg.CF)
+    {
+        *mismatch |= 0x1000;
+    }
+
+    if (lane0ILAS.HD != lane0Cfg.HD)
+    {
+        *mismatch |= 0x2000;
+    }
+
+    if (lane0ILAS.FCHK0 != lane0Cfg.FCHK0)
+    {
+        *mismatch |= 0x4000;
+    }
+
+    if (*mismatch)
+    {
+        *mismatch |= 0x8000;
+        CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, MYKONOS_ERR_JESD204B_ILAS_MISMATCH,
+                getMykonosErrorMessage(MYKONOS_ERR_JESD204B_ILAS_MISMATCH));
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Select data to inject into the Rx framer input (ADC data or Loopback data from deframer output)
+ *
+ * This function allows inputting deframed data (IQ samples) from the Tx data path into the Rx framer.
+ * For this to work correctly, the IQ data rate of the Tx data path must match the Rx IQ data rate.
+ * Framer/Deframer JESD204 config parameters can vary as long as the Rx and Tx IQ rates match.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device A pointer to the device settings structure
+ * \param dataSource 0 = ADC data at Rx Framer input, 1 = Deframed Tx JESD204 IQ samples input into Rx framer
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource)
+{
+    uint8_t enableLoopBack = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setRxFramerDataSource()\n");
+#endif
+
+    enableLoopBack = (dataSource > 0) ? 1 : 0;
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV, enableLoopBack, 0x10, 4);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Select data to inject into the ObsRx framer input (ADC data or Loopback data from deframer output)
+ *
+ * This function allows inputting deframed data (IQ samples) from the Tx data path into the Obs Rx framer.
+ * For this to work correctly, the IQ data rate of the Tx data path must match the ORx IQ data rate.
+ * Framer/Deframer JESD204 config parameters can vary as long as the Obs Rx and Tx IQ rates match.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device A pointer to the device settings structure
+ * \param dataSource 0 = ADC data at ObsRx Framer input, 1 = Deframed Tx JESD204 IQ samples input into Obs Rx framer
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setObsRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource)
+{
+    uint8_t enableLoopBack = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setObsRxFramerDataSource()\n");
+#endif
+
+    enableLoopBack = (dataSource > 0) ? 1 : 0;
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV, enableLoopBack, 0x10, 4);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Runs the Mykonos initialization calibrations
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * ENUM mykonosInitCalibrations_t can be used to OR together to generate the calMask parameter.
+ *
+ *  calMask Bit | Calibration
+ *  ------------|----------------------
+ *       0      | Tx BB Filter
+ *       1      | ADC Tuner
+ *       2      | TIA 3dB Corner
+ *       3      | DC Offset
+ *       4      | Tx Attenuation Delay
+ *       5      | Rx Gain Delay
+ *       6      | Flash Cal
+ *       7      | Path Delay
+ *       8      | Tx LO Leakage Internal
+ *       9      | Tx LO Leakage External
+ *       10     | Tx QEC Init
+ *       11     | LoopBack Rx LO Delay
+ *       12     | LoopBack Rx Rx QEC Init
+ *       13     | Rx LO Delay
+ *       14     | Rx QEC Init
+ *       15     | DPD Init
+ *       16     | Tx CLGC (Closed Loop Gain Control)
+ *       17     | Tx VSWR Init
+ *    [31-18]   | Ignored - Future space for new calibrations
+ *
+ * \param device A pointer to the device settings structure
+ * \param calMask A bitmask that informs the Mykonos ARM processor which calibrations to run
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_runInitCals(mykonosDevice_t *device, uint32_t calMask)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    const uint8_t RUNINITCALS_OPCODE = 0x02;
+    uint8_t payload[4] = {0, 0, 0, 0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_runInitCals()\n");
+#endif
+
+    payload[0] = (uint8_t)(calMask & 0xFF);
+    payload[1] = (uint8_t)((calMask >> 8) & 0xFF);
+    payload[2] = (uint8_t)((calMask >> 16) & 0xFF);
+    payload[3] = (uint8_t)((calMask >> 24) & 0xFF);
+
+    retVal = MYKONOS_sendArmCommand(device, RUNINITCALS_OPCODE, &payload[0], sizeof(payload));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Blocking waits for the Mykonos initialization calibrations to complete
+ *
+ * The *errorFlag and *errorCode parameters are optional.  If the pointers are
+ * set to null, no values will be returned.  If the function returns an error
+ * that the init calibration failed, use the MYKONOS_getInitCalStatus() function
+ * to get more detailed information about why the init cal failed.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device A pointer to the device settings structure
+ * \param timeoutMs A timeout value in Ms to wait for the calibrations to complete
+ * \param errorFlag A 3bit error flag that helps identify what went wrong in the ARM.  0=No Error
+ * \param errorCode The value represents the init calibration object ID that caused a failure.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_WAIT_INITCALS_ARMERROR ARM returned error unrelated to init cals
+ */
+mykonosErr_t MYKONOS_waitInitCals(mykonosDevice_t *device, uint32_t timeoutMs, uint8_t *errorFlag, uint8_t *errorCode)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    mykonosErr_t retValCalStatus = MYKONOS_ERR_OK;
+    uint8_t cmdStatusByte = 0;
+    uint8_t _errorFlag = 0; /* Local version of parameter */
+    mykonosInitCalStatus_t initCalStatus = {0};
+
+    const uint8_t INITCALS_CAL_ERROR = 0x07;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_waitInitCals()\n");
+#endif
+
+    /* Clear before making any calls that can throw errors */
+    if (errorFlag != NULL)
+    {
+        *errorFlag = 0;
+    }
+
+    /* Clear before making any calls that can throw errors */
+    if (errorCode != NULL)
+    {
+        *errorCode = 0;
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_RUNINIT_OPCODE, timeoutMs, &cmdStatusByte);
+    _errorFlag = cmdStatusByte >> 1; /* remove pending bit in [0], error flag is in bits [3:1] */
+
+    if (errorFlag != NULL)
+    {
+        *errorFlag = _errorFlag;
+    }
+
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (_errorFlag == INITCALS_CAL_ERROR)
+        {
+            /* return Error code if a calibration had an error */
+            retValCalStatus = MYKONOS_getInitCalStatus(device, &initCalStatus);
+            if (retValCalStatus == MYKONOS_ERR_OK)
+            {
+                if (errorCode != NULL)
+                {
+                    *errorCode = initCalStatus.initErrCal;
+                }
+            }
+
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_CALFAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_CALFAILED));
+            return MYKONOS_ERR_WAIT_INITCALS_CALFAILED;
+        }
+        else if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_ARMERROR));
+            return MYKONOS_ERR_WAIT_INITCALS_ARMERROR;
+        }
+    }
+
+    /* Same logic if MYKONOS_waitArmCmdStatus() did not return an error, but cmdStatusByte shows an ARM error */
+    if (_errorFlag == INITCALS_CAL_ERROR)
+    {
+        /* return Error code if a calibration had an error */
+        retValCalStatus = MYKONOS_getInitCalStatus(device, &initCalStatus);
+        if (retValCalStatus == MYKONOS_ERR_OK)
+        {
+            if (errorCode != NULL)
+            {
+                *errorCode = initCalStatus.initErrCal;
+            }
+        }
+
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_CALFAILED,
+                getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_CALFAILED));
+        return MYKONOS_ERR_WAIT_INITCALS_CALFAILED;
+    }
+    else if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAIT_INITCALS_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_WAIT_INITCALS_ARMERROR));
+        return MYKONOS_ERR_WAIT_INITCALS_ARMERROR;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Aborts from an on going ARM init calibration operation.
+ *
+ *  The ARM init calibrations can take several seconds.  If for any reason the Baseband processor
+ *  needs to stop the running ARM calibration sequence, call this function.  The *calsCompleted
+ *  parameter is an option parameter that will return which cals completed before the abort
+ *  command was received.  If *calsCompleted is a null pointer, no value will be returned.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device A pointer to the device settings structure
+ * \param calsCompleted A bitmask is returned which describes which cals completed during the previous
+ *                      MYKONOS_runInitCals() call.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM Function parameter calsCompleted has NULL pointer
+ */
+mykonosErr_t MYKONOS_abortInitCals(mykonosDevice_t *device, uint32_t *calsCompleted)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t timeoutMs = 1000; //1 second timeout
+    uint8_t cmdStatusByte = 0;
+    uint8_t payload = 0x43; /* object ID to get INIT_CAL_DONE status */
+    uint8_t calCompleteBitField[4] = {0, 0, 0, 0};
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_ABORT_OPCODE, 0, 0);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_ABORT_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if timeout occurred */
+    }
+
+    /* Read back Calibration Completion status */
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &payload, sizeof(payload));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if timeout occurred */
+    }
+
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + 4), &calCompleteBitField[0], 4, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if (calsCompleted != NULL)
+    {
+        *calsCompleted = ((uint32_t)(calCompleteBitField[3]) << 24) | ((uint32_t)(calCompleteBitField[2]) << 16) | ((uint32_t)(calCompleteBitField[1]) << 8)
+                | ((uint32_t)(calCompleteBitField[0]));
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM));
+        return MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Gets the device initialization calibration status
+ *
+ * This function requests the init cal status information from the Mykonos ARM
+ * processor.  The ARM returns information including a bitmask that describes
+ * which calibrations have completed during the last cal of runInitCals, as
+ * well as the init cals that have run successfully since loading the ARM.  If
+ * an ARM error does occur during one of the init calibrations, the initErrCal
+ * member returns the object ID of the failing calibration.  The initErrCode
+ * returns the specific ARM error code that caused that calibration to fail.
+ * The calsMinimum structure member describes the minimum set of init calibrations
+ * required to complete by the ARM before it will allow the device to move to
+ * the radioOn state.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device A pointer to the device settings structure
+ * \param initCalStatus Pointer to a structure that returns cal status information such as cals completed since last run, and init error codes
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM if initCalStatus parameter is a NULL pointer
+ * \retval MYKONOS_ERR_GETINITCALSTATUS_ARMERROR if ARM returned an error while requesting the init cal status information
+ */
+mykonosErr_t MYKONOS_getInitCalStatus(mykonosDevice_t *device, mykonosInitCalStatus_t *initCalStatus)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t cmdStatusByte = 0;
+    uint8_t calStatusArray[14] = {0};
+    uint8_t payload[1] = {MYKONOS_ARM_OBJECTID_INIT_CAL_DONE};
+
+    uint32_t timeoutMs = 1000;
+
+    /* Verify function parameter pointer is not NULL */
+    if (initCalStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM));
+        return MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM;
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &payload[0], sizeof(payload));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETINITCALSTATUS_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETINITCALSTATUS_ARMERROR));
+            return MYKONOS_ERR_GETINITCALSTATUS_ARMERROR;
+        }
+
+        return retVal; /* Will return if timeout occurred */
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETINITCALSTATUS_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_GETINITCALSTATUS_ARMERROR));
+        return MYKONOS_ERR_GETINITCALSTATUS_ARMERROR;
+    }
+
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &calStatusArray[0], sizeof(calStatusArray), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    initCalStatus->calsDoneLifetime = ((uint32_t)(calStatusArray[3]) << 24) | ((uint32_t)(calStatusArray[2]) << 16) | ((uint32_t)(calStatusArray[1]) << 8)
+            | ((uint32_t)(calStatusArray[0]));
+    initCalStatus->calsDoneLastRun = ((uint32_t)(calStatusArray[7]) << 24) | ((uint32_t)(calStatusArray[6]) << 16) | ((uint32_t)(calStatusArray[5]) << 8)
+            | ((uint32_t)(calStatusArray[4]));
+    initCalStatus->calsMinimum = ((uint32_t)(calStatusArray[11]) << 24) | ((uint32_t)(calStatusArray[10]) << 16) | ((uint32_t)(calStatusArray[9]) << 8)
+            | ((uint32_t)(calStatusArray[8]));
+    initCalStatus->initErrCal = calStatusArray[12];
+    initCalStatus->initErrCode = calStatusArray[13];
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Instructs the ARM processor to move the radio state to the Radio ON state
+ *
+ * When the ARM to the Radio On state, the enabled Rx and Tx signal chains will power up,
+ * and the ARM tracking calibrations will begin.  To exit this state back to a low power,
+ * offline state, call the MYKONOS_radioOff() function.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ARM_RADIOON_FAILED ARM returned error running this command
+ */
+mykonosErr_t MYKONOS_radioOn(mykonosDevice_t *device)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t timeoutMs = 1000; //1 second timeout
+    uint8_t cmdStatusByte = 0;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_RADIOON_OPCODE, 0, 0);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_RADIOON_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOON_FAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOON_FAILED));
+            return MYKONOS_ERR_ARM_RADIOON_FAILED;
+        }
+
+        return retVal; /* Will return if timeout occurred */
+    }
+
+    /* If ARM command error flag is 2, the command was not accepted, RUN_INIT must complete first */
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOON_FAILED, getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOON_FAILED));
+        return MYKONOS_ERR_ARM_RADIOON_FAILED;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Instructs the ARM processor to move the radio state to the off state
+ *
+ * When the ARM moves from the Radio On state to Radio Off (Idle) the ARM tracking calibrations
+ * are stopped and the TxEnable/RxEnable, etc GPIO control pins will be ignored.  This will also
+ * keep the receive and transmit chains powered down until the MYKONOS_radioOn() function
+ * is called again.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ARM_RADIOOFF_FAILED ARM returned error running this command
+ */
+mykonosErr_t MYKONOS_radioOff(mykonosDevice_t *device)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    const uint8_t ABORTCAL_OPCODE = 0x00;
+    uint32_t timeoutMs = 1000; //1 second timeout
+    uint8_t cmdStatusByte = 0;
+
+    retVal = MYKONOS_sendArmCommand(device, ABORTCAL_OPCODE, 0, 0);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal; /* Will return if mailbox busy bit is busy for more than 2 seconds */
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, ABORTCAL_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOOFF_FAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOOFF_FAILED));
+            return MYKONOS_ERR_ARM_RADIOOFF_FAILED;
+        }
+
+        return retVal; /* Will return if timeout occurred */
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARM_RADIOOFF_FAILED, getMykonosErrorMessage(MYKONOS_ERR_ARM_RADIOOFF_FAILED));
+        return MYKONOS_ERR_ARM_RADIOOFF_FAILED;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the current ARM radio state
+ *
+ * Currently, *radioStatus only returns data in the lower 8 bits, but
+ * is defined as a 32bit status to allow for more information to be returned
+ * in the future.
+ *
+ * radioStatus  |  Bitfield
+ * -------------|------------------
+ *        [1:0] | State[1:0], 0=POWERUP, 1=READY, 2=INIT, 3=RADIO ON
+ *        [3:2] | unused
+ *        [4]   | TDD_nFDD , 1= TDD, 0=FDD
+ *        [7:5] | unused
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param radioStatus The current ARM radio state is returned in this parameter
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM Function parameter radioStatus has a NULL pointer
+ */
+mykonosErr_t MYKONOS_getRadioState(mykonosDevice_t *device, uint32_t *radioStatus)
+{
+    uint8_t status = 0;
+
+    /* if radioStatus is not null */
+    if (radioStatus != NULL)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_0, &status);
+        *radioStatus = (uint32_t)status;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM));
+        return MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sets which ARM tracking cals are enabled during the radioOn state.
+ *
+ * This command must be called during radioOff state.  If called during radioOn,
+ * an error will be returned.  The enum mykonosTrackingCalibrations_t can be used to
+ * OR together to form the enableMask parameter.
+ *
+ * enableMask  |  Bit description
+ * ------------|------------
+ *        [0]  | TRACK_RX1_QEC
+ *        [1]  | TRACK_RX2_QEC
+ *        [2]  | TRACK_ORX1_QEC
+ *        [3]  | TRACK_ORX2_QEC
+ *        [4]  | TRACK_TX1_LOL
+ *        [5]  | TRACK_TX2_LOL
+ *        [6]  | TRACK_TX1_QEC
+ *        [7]  | TRACK_TX2_QEC
+ *        [8]  | TRACK_TX1_DPD
+ *        [9]  | TRACK_TX2_DPD
+ *       [10]  | TRACK_TX1_CLGC
+ *       [11]  | TRACK_TX2_CLGC
+ *       [12]  | TRACK_TX1_VSWR
+ *       [13]  | TRACK_TX2_VSWR
+ *       [16]  | TRACK_ORX1_QEC_SNLO
+ *       [17]  | TRACK_ORX2_QEC_SNLO
+ *       [18]  | TRACK_SRX_QEC
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param enableMask A bitmask that selects which cals to run during radioOn state.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR Error: Tracking cals can only be enabled in the radioOff state.
+ * \retval MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR ARM returned error when executing this command
+ */
+mykonosErr_t MYKONOS_enableTrackingCals(mykonosDevice_t *device, uint32_t enableMask)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armData[4] = {0, 0, 0, 0};
+    uint8_t extData[4] = {MYKONOS_ARM_OBJECTID_CALSCHEDULER, 0x00, 0x00, 0x04}; //Target ARM Object ID, Offset LSB, Offset MSB, Length
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    uint32_t radioStatus = 0;
+    uint8_t allowTx1AttenUpdates = 0;
+    uint8_t allowTx2AttenUpdates = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableTrackingCals()\n");
+#endif
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR));
+        return MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR;
+    }
+
+    /* In the ARM, DPD tracking and CLGC tracking share the same cal.  Must
+     * set extra enable bits in ARM Memory to tell which cal to run. */
+    retVal = enableDpdTracking(device, ((enableMask & TRACK_TX1_DPD) ? 1 : 0), ((enableMask & TRACK_TX2_DPD) ? 1 : 0));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if (((device->profilesValid & TX_PROFILE_VALID) > 0) && (device->tx->clgcConfig != NULL))
+    {
+        allowTx1AttenUpdates = device->tx->clgcConfig->allowTx1AttenUpdates;
+        allowTx2AttenUpdates = device->tx->clgcConfig->allowTx2AttenUpdates;
+    }
+    else
+    {
+        allowTx1AttenUpdates = 0;
+        allowTx2AttenUpdates = 0;
+    }
+
+    retVal = enableClgcTracking(device, ((allowTx1AttenUpdates > 0) ? 1 : 0), ((allowTx2AttenUpdates > 0) ? 1 : 0));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    armData[0] = (uint8_t)(enableMask & 0xFF);
+    armData[1] = (uint8_t)((enableMask >> 8) & 0xFF);
+    armData[2] = (uint8_t)((enableMask >> 16) & 0xFF);
+    armData[3] = (uint8_t)((enableMask >> 24) & 0xFF);
+    retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_WRITECFG_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_WRITECFG_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR));
+            return MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR));
+        return MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reschedules a tracking calibration to run. Can be used to
+ * override the tracking calibration timer and force a tracking calibration to run.
+ * Can be used to reschedule a tracking calibration after a tracking calibration
+ * error has been detected.  Only one tracking calibration object can be scheduled
+ * per channel per function call.
+ *
+ * \pre Command can be called in either Radio On or Radio Off state.  ARM must be
+ * initialized.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param trackingCal Selects the tracking calibration to schedule.
+ *
+ * \retval MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV Not valid calibration passed
+ * \retval MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG ARM error
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_rescheduleTrackingCal(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal)
+{
+    uint32_t retVal = MYKONOS_ERR_OK;
+    uint8_t extData[3] = {0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t timeoutMs = 1000;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_rescheduleTrackingCal()\n");
+#endif
+
+    switch (trackingCal)
+    {
+        case TRACK_RX1_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING;
+            extData[2] = 0;
+            break;
+
+        case TRACK_RX2_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING;
+            extData[2] = 1;
+            break;
+
+        case TRACK_ORX1_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING;
+            extData[2] = 0;
+            break;
+
+        case TRACK_ORX2_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING;
+            extData[2] = 1;
+            break;
+
+        case TRACK_TX1_LOL:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING;
+            extData[2] = 0;
+            break;
+
+        case TRACK_TX2_LOL:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING;
+            extData[2] = 1;
+            break;
+
+        case TRACK_TX1_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING;
+            extData[2] = 0;
+            break;
+
+        case TRACK_TX2_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING;
+            extData[2] = 1;
+            break;
+
+        case TRACK_TX1_DPD:
+            extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG;
+            extData[2] = 0;
+            break;
+
+        case TRACK_TX2_DPD:
+            extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG;
+            extData[2] = 1;
+            break;
+
+        case TRACK_TX1_CLGC:
+            extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG;
+            extData[2] = 0;
+            break;
+
+        case TRACK_TX2_CLGC:
+            extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG;
+            extData[2] = 1;
+            break;
+
+        case TRACK_TX1_VSWR:
+            extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG;
+            extData[2] = 0;
+            break;
+
+        case TRACK_TX2_VSWR:
+            extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG;
+            extData[2] = 1;
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV));
+            return MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV;
+    }
+
+    extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_PENDING;
+
+    /* sending ARM command */
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG));
+            return MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG));
+        return MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG;
+    }
+
+    return retVal;
+}
+
+/**
+ * \brief Suspend or resume tracking calibrations in RADIO_ON.
+ *
+ * This function is used to suspend or resume active tracking calibrations based on the passed mask trackingCals.
+ *
+ * \pre Command can be called in Radio On.
+ *
+ * trackCals[bit]  |  Bit description
+ * ----------------|------------
+ *       [0]       | TRACK_RX1_QEC
+ *       [1]       | TRACK_RX2_QEC
+ *       [2]       | TRACK_ORX1_QEC
+ *       [3]       | TRACK_ORX2_QEC
+ *       [4]       | TRACK_TX1_LOL
+ *       [5]       | TRACK_TX2_LOL
+ *       [6]       | TRACK_TX1_QEC
+ *       [7]       | TRACK_TX2_QEC
+ *       [8]       | TRACK_TX1_DPD
+ *       [9]       | TRACK_TX2_DPD
+ *      [10]       | TRACK_TX1_CLGC
+ *      [11]       | TRACK_TX2_CLGC
+ *      [12]       | TRACK_TX1_VSWR
+ *      [13]       | TRACK_TX2_VSWR
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param trackCals Selects the tracking calibrations to suspend or resume during the radio ON state.
+ * mykonosTrackingCalibrations_t enumerated types are or'd together to form the tracking calibration
+ * mask word. If the bit is high the calibration will resume, if the bit is low the calibration will be suspended.
+ *
+ * \retval MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV Not valid calibration mask passed for trackCals
+ * \retval MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG ARM error
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setAllTrackCalState(mykonosDevice_t *device, uint32_t trackCals)
+{
+    uint32_t retVal = MYKONOS_ERR_OK;
+    uint8_t cfgData[4] = {0};
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME, 0x0F, 0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t enTrackCal = 0x00;
+    uint32_t timeoutMs = 1000;
+
+    const uint32_t TRACKING_MASK = 0x3FFF;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setAllTrackCalState()\n");
+#endif
+
+    /* reading enabled tracking calibrations */
+    retVal = MYKONOS_getEnabledTrackingCals(device, &enTrackCal);
+
+    /* trackingCalMask check */
+    if (((trackCals | enTrackCal) > enTrackCal) || (trackCals > TRACKING_MASK))
+    {
+        /* invalid cal mask error return, tracking cal not enable so we can not resume it */
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV));
+        return MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV;
+    }
+
+    /* convert tracking mask to array of uint8_t type */
+    cfgData[0] = (uint8_t)(trackCals & 0xFF);
+    cfgData[1] = (uint8_t)((trackCals >> 8) & 0xFF);
+    cfgData[2] = (uint8_t)((trackCals >> 16) & 0x0FF);
+    cfgData[3] = (uint8_t)((trackCals >> 24) & 0xFF);
+
+    retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &cfgData[0], sizeof(cfgData));
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData));
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG));
+            return MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG));
+        return MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG;
+    }
+
+    return retVal;
+}
+
+/**
+ * \brief Get the Suspended or Resumed state for tracking calibrations
+ *
+ * This function is used to get the suspend or resume state of all active tracking calibrations and the state is stored in trackCals.
+ *
+ * \pre Command can be called in Radio On.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param trackCals pointer to store the tracking calibration state.
+ * If the bit is set then the tracking calibration is resumed and if not set then the tracking cal is suspended, the bit field follows:
+ *
+ * trackCals[bit] |  Bit description
+ * ---------------|------------
+ *       [0]      | TRACK_RX1_QEC
+ *       [1]      | TRACK_RX2_QEC
+ *       [2]      | TRACK_ORX1_QEC
+ *       [3]      | TRACK_ORX2_QEC
+ *       [4]      | TRACK_TX1_LOL
+ *       [5]      | TRACK_TX2_LOL
+ *       [6]      | TRACK_TX1_QEC
+ *       [7]      | TRACK_TX2_QEC
+ *       [8]      | TRACK_TX1_DPD
+ *       [9]      | TRACK_TX2_DPD
+ *      [10]      | TRACK_TX1_CLGC
+ *      [11]      | TRACK_TX2_CLGC
+ *      [12]      | TRACK_TX1_VSWR
+ *      [13]      | TRACK_TX2_VSWR
+ *
+ * \retval MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM Null parameter passed for trackCals
+ * \retval MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG ARM error flag set.
+ * \retval MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR ARM command error.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getAllTrackCalState(mykonosDevice_t *device, uint32_t *trackCals)
+{
+    uint32_t retVal = MYKONOS_ERR_OK;
+    uint8_t extData = MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME;
+    uint8_t armData[4] = {0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t timeoutMs = 1000;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getAllTrackCalState()\n");
+#endif
+
+    /* Check for passed parameter */
+    if (trackCals == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM));
+        return MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM;
+    }
+
+    /* sending ARM command */
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData, sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG));
+            return MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG));
+        return MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG;
+    }
+
+    /* read 32-bit tracking state from ARM memory */
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR));
+        return MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR;
+    }
+
+    *trackCals = (uint32_t)armData[0] | ((uint32_t)armData[1] << 8) | ((uint32_t)armData[2] << 16) | ((uint32_t)armData[3] << 24);
+
+    return retVal;
+}
+
+/**
+ * \brief Suspend or resume individual tracking calibration
+ *
+ * \pre The tracking calibration must have been enabled with MYKONOS_enableTrackingCals(), this command can be called in Radio On.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param trackingCal Selects the tracking calibration to resume or suspend.
+ * \param trackCalState if set then the selected tracking calibration will be resumed and if not set then the tracking cal will be suspended
+ *
+ * \retval MYKONOS_ERR_SETSTATE_TRACK_CAL_INV Not valid calibration passed
+ * \retval MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG ARM error
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t trackCalState)
+{
+    uint32_t retVal = MYKONOS_ERR_OK;
+    uint8_t extData[2] = {0};
+    uint8_t cmdStatusByte = 0;
+    uint8_t suspendTrack = 0x0F;
+    uint32_t timeoutMs = 1000;
+    uint32_t enTrackCal = 0x00;
+
+    const uint8_t CHANNEL_1 = 0x00;
+    const uint8_t CHANNEL_2 = 0x10;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setTrackingCalState()\n");
+#endif
+
+    if (trackCalState > 0)
+    {
+        suspendTrack = 0x2F;
+    }
+
+    /* reading enabled tracking calibrations */
+    retVal = MYKONOS_getEnabledTrackingCals(device, &enTrackCal);
+
+    /* trackingCalMask check */
+    if ((trackingCal & enTrackCal) != trackingCal)
+    {
+        /* invalid cal mask error return, tracking cal not enable so we can not resume or suspend it */
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_CAL_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_CAL_INV));
+        return MYKONOS_ERR_SETSTATE_TRACK_CAL_INV;
+    }
+
+    switch (trackingCal)
+    {
+        case TRACK_RX1_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_RX2_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_RXQEC_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        case TRACK_ORX1_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_ORX2_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        case TRACK_TX1_LOL:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_TX2_LOL:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXLOL_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        case TRACK_TX1_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_TX2_QEC:
+            extData[1] = MYKONOS_ARM_OBJECTID_TXQEC_TRACKING & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        case TRACK_TX1_DPD:
+            extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_TX2_DPD:
+            extData[1] = MYKONOS_ARM_OBJECTID_DPDCONFIG & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        case TRACK_TX1_CLGC:
+            extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_TX2_CLGC:
+            extData[1] = MYKONOS_ARM_OBJECTID_CLGCCONFIG & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        case TRACK_TX1_VSWR:
+            extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG & suspendTrack;
+            extData[1] |= CHANNEL_1;
+            break;
+
+        case TRACK_TX2_VSWR:
+            extData[1] = MYKONOS_ARM_OBJECTID_VSWRCONFIG & suspendTrack;
+            extData[1] |= CHANNEL_2;
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_CAL_INV,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_CAL_INV));
+            return MYKONOS_ERR_SETSTATE_TRACK_CAL_INV;
+    }
+
+    extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME;
+
+    /* sending ARM command */
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG));
+            return MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG));
+        return MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG;
+    }
+
+    return retVal;
+}
+
+/**
+ * \brief Get the Suspended or Resumed state for individual tracking calibration
+ *
+ * \pre Command can be called in Radio On.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param trackingCal Selects the tracking calibration to get the resumed or suspended state.
+ * \param trackCalState pointer to store the tracking calibration state,
+ * if set then the selected tracking calibration is resumed and if not set then the tracking cal is suspended
+ *
+ * \retval MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM Null parameter passed to trackCalState
+ * \retval MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG ARM command error flag set.
+ * \retval MYKONOS_ERR_GETSTATE_TRACK_ARMERROR ARM command error.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t *trackCalState)
+{
+    uint32_t retVal = MYKONOS_ERR_OK;
+    uint8_t extData = MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME;
+    uint8_t armData[4] = {0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t timeoutMs = 1000;
+    uint32_t trackMask = 0x00;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTrackingCalState()\n");
+#endif
+
+    /* Check for passed parameter */
+    if (trackCalState == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM));
+        return MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM;
+    }
+
+    /* sending ARM command */
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData, sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG));
+            return MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG));
+        return MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG;
+    }
+
+    /* read 32-bit tracking state from ARM memory */
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], sizeof(armData), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETSTATE_TRACK_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_GETSTATE_TRACK_ARMERROR));
+        return MYKONOS_ERR_GETSTATE_TRACK_ARMERROR;
+    }
+
+    trackMask = (uint32_t)armData[0] | ((uint32_t)armData[1] << 8) | ((uint32_t)armData[2] << 16) | ((uint32_t)armData[3] << 24);
+
+    if (trackMask & trackingCal)
+    {
+        *trackCalState = 1;
+    }
+    else
+    {
+        *trackCalState = 0;
+    }
+
+    return retVal;
+}
+
+/**
+ * \brief Reads back which ARM tracking cals are enabled
+ *
+ * enableMask  |  Bit description
+ * ------------|----------------------
+ *        [0]  | TRACK_RX1_QEC
+ *        [1]  | TRACK_RX2_QEC
+ *        [2]  | TRACK_ORX1_QEC
+ *        [3]  | TRACK_ORX2_QEC
+ *        [4]  | TRACK_TX1_LOL
+ *        [5]  | TRACK_TX2_LOL
+ *        [6]  | TRACK_TX1_QEC
+ *        [7]  | TRACK_TX2_QEC
+ *        [8]  | TRACK_TX1_DPD
+ *        [9]  | TRACK_TX2_DPD
+ *       [10]  | TRACK_TX1_CLGC
+ *       [11]  | TRACK_TX2_CLGC
+ *       [12]  | TRACK_TX1_VSWR
+ *       [13]  | TRACK_TX2_VSWR
+ *       [16]  | TRACK_ORX1_QEC_SNLO
+ *       [17]  | TRACK_ORX1_QEC_SNLO
+ *       [18]  | TRACK_SRX_QEC
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param enableMask Returned bitmask that shows which tracking cals are enabled
+ *                   to run during radioOn state. See mykonosTrackingCalibrations_t enum of tracking cals.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_getEnabledTrackingCals(mykonosDevice_t *device, uint32_t *enableMask)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armData[4] = {0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getEnabledTrackingCals()\n");
+#endif
+
+    /* Ask ARM to read tracking cal enable bits and place in mailbox buffer memory */
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CALSCHEDULER, 0, &armData[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    *enableMask = ((uint32_t)(armData[0]) | ((uint32_t)(armData[1]) << 8) | ((uint32_t)(armData[2]) << 16) | ((uint32_t)(armData[3]) << 24));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Returns the tracking calibration pending and error status.
+ *
+ * When in radioOn state, the enabled tracking calibrations will set the pending
+ * flag when the particular calibration is ready to be run, but has not completed
+ * yet. For Tx tracking cals to complete, the BBIC must set the ObsRx path to
+ * the INTERNAL CALS mode.  If a tracking calibration had an error, the corresponding
+ * error flag will be asserted.
+ *
+ *  pendingCalMask | bit Description
+ * ----------------|--------------------------------------------------------
+ *            [0]  | Rx1 QEC tracking pending
+ *            [1]  | Rx1 QEC tracking error
+ *            [2]  | Rx2 QEC tracking pending
+ *            [3]  | Rx2 QEC tracking error
+ *            [4]  | ORx1 QEC tracking pending
+ *            [5]  | ORx1 QEC tracking error
+ *            [6]  | ORx2 QEC tracking pending
+ *            [7]  | ORx2 QEC tracking error
+ *            [8]  | Tx1 LOL tracking pending
+ *            [9]  | Tx1 LOL tracking error
+ *           [10]  | Tx2 LOL tracking pending
+ *           [11]  | Tx2 LOL tracking error
+ *           [12]  | Tx1 QEC tracking pending
+ *           [13]  | Tx1 QEC tracking error
+ *           [14]  | Tx2 QEC tracking pending
+ *           [15]  | Tx2 QEC tracking error
+ *           [16]  | Tx1 DPD tracking pending
+ *           [17]  | Tx1 DPD tracking error
+ *           [18]  | Tx2 DPD tracking pending
+ *           [19]  | Tx2 DPD tracking error
+ *           [20]  | Tx1 CLGC tracking pending
+ *           [21]  | Tx1 CLGC tracking error
+ *           [22]  | Tx2 CLGC tracking pending
+ *           [23]  | Tx2 CLGC tracking error
+ *           [24]  | Tx1 VSWR tracking pending
+ *           [25]  | Tx1 VSWR tracking error
+ *           [26]  | Tx2 VSWR tracking pending
+ *           [27]  | Tx2 VSWR tracking error
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param pendingCalMask Bit mask that describes which tracking cals are pending
+ *                       or had errors
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM Function parameter pendingCalMask is a NULL pointer
+ */
+mykonosErr_t MYKONOS_getPendingTrackingCals(mykonosDevice_t *device, uint32_t *pendingCalMask)
+{
+    uint8_t readData[4] = {0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getPendingTrackingCals()\n");
+#endif
+
+    if (pendingCalMask == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM));
+        return MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_3, &readData[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_4, &readData[1]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_5, &readData[2]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_OPCODE_STATE_6, &readData[3]);
+    *pendingCalMask = ((uint32_t)readData[3] << 24) | ((uint32_t)readData[2] << 16) | ((uint32_t)readData[1] << 8) | ((uint32_t)readData[0]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Returns the status of the TxLOL external tracking calibration
+ *
+ * The Tx LOL external tracking calibration is run during the radioOn state.
+ * The function can be called to read back the status of the TxLOL external
+ * calibration including metrics like error codes, percentage of data
+ * collected for current cal, the performance of the cal and the number of
+ * times the cal has run and updated the hardware.
+ *
+ * \pre Before the function is called, the device must be initialized, the ARM
+ * loaded, and init cals run.  These functions can be called in radioOff or
+ * radioOn state.
+ *
+ * \param device Pointer to the device settings structure
+ * \param txChannel The channel (Tx1/Tx2) whose status is to be read back
+ * \param txLolStatus Status of the TxLOL external calibration, as a structure
+ * of type mykonosTxLolStatus_t is returned to this pointer address
+ *
+ * \retval MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM Function parameter mykonosTxLolStatus_t is a NULL pointer
+ * \retval MYKONOS_ERR_GETTXLOLSTATUS_INV_CH Channel selection not valid
+ * \retval MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG ARM command error
+ * \retval MYKONOS_ERR_OK  Function completed successfully
+ */
+mykonosErr_t MYKONOS_getTxLolStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxLolStatus_t *txLolStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_TXLOL_TRACKING, 0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t offset = 0;
+    uint32_t timeoutMs = 0;
+    uint8_t armReadBack[20] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTxLolStatus()\n");
+#endif
+
+    if (txLolStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM;
+    }
+
+    switch (txChannel)
+    {
+        case TX1:
+            extData[2] = 0;
+            break;
+        case TX2:
+            extData[2] = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_INV_CH));
+            return MYKONOS_ERR_GETTXLOLSTATUS_INV_CH;
+        }
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    offset = 0;
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Assign to data structure */
+    txLolStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]);
+    txLolStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8)
+            | ((uint32_t)armReadBack[4]);
+    txLolStatus->performanceMetric = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8)
+            | ((uint32_t)armReadBack[8]);
+    txLolStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) | ((uint32_t)armReadBack[12]);
+    txLolStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8)
+            | ((uint32_t)armReadBack[16]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Returns the status of the TxQEC tracking calibration
+ *
+ * The Tx QEC tracking calibration is run during the radioOn state.
+ * The function can be called to read back the status of the TxQEC
+ * calibration including metrics like error codes, percentage of data
+ * collected for current cal, the performance of the cal and the number of
+ * times the cal has run and updated the hardware.
+ *
+ * \pre Before the function is called, the device must be initialized, the ARM
+ * loaded, and init cals run.  These functions can be called in radioOff or
+ * radioOn state.
+ *
+ * \param device Pointer to the device settings structure
+ * \param txChannel The channel (Tx1/Tx2) whose status is to be read back
+ * \param txQecStatus Status of the TxQEC external calibration, as a structure
+ * of type mykonosTxQecStatus_t is returned to this pointer address
+ *
+ * \retval MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM Function parameter txQecStatus is a NULL pointer
+ * \retval MYKONOS_ERR_GETTXQECSTATUS_INV_CH Channel selection not valid
+ * \retval MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG ARM command error
+ * \retval MYKONOS_ERR_OK  Function completed successfully
+ */
+mykonosErr_t MYKONOS_getTxQecStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxQecStatus_t *txQecStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_TXQEC_TRACKING, 0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t offset = 0;
+    uint32_t timeoutMs = 0;
+    uint8_t armReadBack[20] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getTxQecStatus()\n");
+#endif
+
+    if (txQecStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM;
+    }
+
+    switch (txChannel)
+    {
+        case TX1:
+            extData[2] = 0;
+            break;
+        case TX2:
+            extData[2] = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_INV_CH));
+            return MYKONOS_ERR_GETTXQECSTATUS_INV_CH;
+        }
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    offset = 0;
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Assign to data structure */
+    txQecStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]);
+    txQecStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8)
+            | ((uint32_t)armReadBack[4]);
+    txQecStatus->performanceMetric = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8)
+            | ((uint32_t)armReadBack[8]);
+    txQecStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) | ((uint32_t)armReadBack[12]);
+    txQecStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8)
+            | ((uint32_t)armReadBack[16]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Returns the status of the RxQEC tracking calibration
+ *
+ * The Rx QEC tracking calibration is run during the radioOn state.
+ * The function can be called to read back the status of the RxQEC external
+ * calibration including metrics like error codes, percentage of data
+ * collected for current cal, the performance of the cal and the number of
+ * times the cal has run and updated the hardware.
+ *
+ * \pre Before the function is called, the device must be initialized, the ARM
+ * loaded, and init cals run.  These functions can be called in radioOff or
+ * radioOn state.
+ *
+ * \param device Pointer to the device settings structure
+ * \param rxChannel The channel (Rx1/Rx2) whose status is to be read back
+ * \param rxQecStatus Status of the RxQEC calibration, as a structure
+ * of type mykonosRxQecStatus_t is returned to this pointer address
+ *
+ * \retval MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM Function parameter rxQecStatus is a NULL pointer
+ * \retval MYKONOS_ERR_GETRXQECSTATUS_INV_CH Channel selection not valid
+ * \retval MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG ARM command error
+ * \retval MYKONOS_ERR_OK  Function completed successfully
+ */
+mykonosErr_t MYKONOS_getRxQecStatus(mykonosDevice_t *device, mykonosRxChannels_t rxChannel, mykonosRxQecStatus_t *rxQecStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_RXQEC_TRACKING, 0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t offset = 0;
+    uint32_t timeoutMs = 0;
+    uint8_t armReadBack[20] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getRxQecStatus()\n");
+#endif
+
+    if (rxQecStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM;
+    }
+
+    switch (rxChannel)
+    {
+        case RX1:
+            extData[2] = 0;
+            break;
+        case RX2:
+            extData[2] = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_INV_CH));
+            return MYKONOS_ERR_GETRXQECSTATUS_INV_CH;
+        }
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    offset = 0;
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Assign to data structure */
+    rxQecStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]);
+    rxQecStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8)
+            | ((uint32_t)armReadBack[4]);
+    rxQecStatus->selfcheckIrrDb = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8)
+            | ((uint32_t)armReadBack[8]);
+    rxQecStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8) | ((uint32_t)armReadBack[12]);
+    rxQecStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8)
+            | ((uint32_t)armReadBack[16]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Returns the status of the ORxQEC tracking calibration
+ *
+ * The ORx QEC tracking calibration is run during the radioOn state.
+ * The function can be called to read back the status of the ORxQEC external
+ * calibration including metrics like error codes, percentage of data
+ * collected for current cal, the performance of the cal and the number of
+ * times the cal has run and updated the hardware.
+ *
+ * \pre Before the function is called, the device must be initialized, the ARM
+ * loaded, and init cals run.  These functions can be called in radioOff or
+ * radioOn state.
+ *
+ * \param device Pointer to the device settings structure
+ * \param orxChannel The channel whose status is to be read back
+ * \param orxQecStatus Status of the ORxQEC external calibration, as a structure
+ * of type mykonosOrxQecStatus_t is returned to this pointer address
+ *
+ * \retval MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM Function parameter orxQecStatus is a NULL pointer
+ * \retval MYKONOS_ERR_GETORXQECSTATUS_INV_CH Channel selection not valid
+ * \retval MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG ARM command error
+ * \retval MYKONOS_ERR_OK  Function completed successfully
+ */
+mykonosErr_t MYKONOS_getOrxQecStatus(mykonosDevice_t *device, mykonosObsRxChannels_t orxChannel, mykonosOrxQecStatus_t *orxQecStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING, 0};
+    uint8_t cmdStatusByte = 0;
+    uint32_t offset = 0;
+    uint32_t timeoutMs = 0;
+    uint8_t armReadBack[20] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getOrxQecStatus()\n");
+#endif
+
+    if (orxQecStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM;
+    }
+
+    switch (orxChannel)
+    {
+        case OBS_RX1_TXLO:
+        case OBS_RX1_SNIFFERLO:
+            extData[2] = 0;
+            break;
+        case OBS_RX2_TXLO:
+        case OBS_RX2_SNIFFERLO:
+            extData[2] = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_INV_CH));
+            return MYKONOS_ERR_GETORXQECSTATUS_INV_CH;
+        }
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    offset = 0;
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armReadBack[0], sizeof(armReadBack), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Assign to data structure */
+    orxQecStatus->errorCode = (((uint32_t)armReadBack[3]) << 24) | (((uint32_t)armReadBack[2]) << 16) | (((uint32_t)armReadBack[1]) << 8) | ((uint32_t)armReadBack[0]);
+    orxQecStatus->percentComplete = (((uint32_t)armReadBack[7]) << 24) | (((uint32_t)armReadBack[6]) << 16) | (((uint32_t)armReadBack[5]) << 8)
+            | ((uint32_t)armReadBack[4]);
+    orxQecStatus->selfcheckIrrDb = (((uint32_t)armReadBack[11]) << 24) | (((uint32_t)armReadBack[10]) << 16) | (((uint32_t)armReadBack[9]) << 8)
+            | ((uint32_t)armReadBack[8]);
+    orxQecStatus->iterCount = (((uint32_t)armReadBack[15]) << 24) | (((uint32_t)armReadBack[14]) << 16) | (((uint32_t)armReadBack[13]) << 8)
+            | ((uint32_t)armReadBack[12]);
+    orxQecStatus->updateCount = (((uint32_t)armReadBack[19]) << 24) | (((uint32_t)armReadBack[18]) << 16) | (((uint32_t)armReadBack[17]) << 8)
+            | ((uint32_t)armReadBack[16]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Selects the Sniffer RF input to use for the observation receiver when in ObsRx pin mode and ORX_MODE = SNIFFER(4)
+ *
+ * This function is only valid when using the ObsRx Pin mode.  In pin mode, 3 GPIO pins select an Observation Rx source.
+ * See mykonosObsRxChannels_t enum values less than 7.  When the ORX_MODE GPIO pins are set to 4 for Sniffer, Sniffer inputs
+ * A, B, and C can be chosen by calling this function.  This function can be called any time after the ARM is loaded and running.
+ * It can be called in radioOn or radioOff state.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param snifferChannel Desired channel to set.  This channel will be enabled when ORX_MODE = SNIFFER.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR ARM returned an error
+ */
+mykonosErr_t MYKONOS_setSnifferChannel(mykonosDevice_t *device, mykonosSnifferChannel_t snifferChannel)
+{
+    uint8_t armData[2] = {0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+    armData[0] = 0x6A; /* SET SRX_SOURCE ARM object ID */
+    armData[1] = (uint8_t)snifferChannel;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &armData[0], sizeof(armData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR));
+            return MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR));
+        return MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Resets the ARM processor and performs initialization
+ *
+ * Sets ARM Run = 0, Disables parity checks, sets ARM and SPI reg clock selects,
+ * resets ARM, and enables ARM SPI register access
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->rx->rxProfile->iqRate_kHz
+ * - device->deviceClock_kHz
+ * - device->rx->rxProfile->rfBandwidth_Hz
+ * - device->tx->txProfile->rfBandwidth_Hz
+ * - device->rx->rxProfile->rxFirDecimation
+ * - device->rx->rxProfile->rhb1Decimation
+ * - device->spiSettings
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_INITARM_INV_VCODIV
+ * \retval MYKONOS_ERR_INITARM_INV_REGCLK Could not calculate a valid ARM Register clock divider
+ * \retval MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM Could not calculate a valid ARM clock divider
+ */
+mykonosErr_t MYKONOS_initArm(mykonosDevice_t *device)
+{
+    uint8_t regClkSel = 0;
+    uint8_t armClkSel = 0;
+    uint32_t hsClkRateDiv4or5_Khz = 0;
+    uint32_t hb1Clk = 0;
+    uint32_t vcoDivTimes10 = 1;
+    uint8_t adcDiv = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_initArm()\n");
+#endif
+
+    /* Finish init - this is part of init that must run after Multi Chip Sync */
+    retVal = MYKONOS_initSubRegisterTables(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    switch (device->clocks->clkPllVcoDiv)
+    {
+        case VCODIV_1:
+            vcoDivTimes10 = 10;
+            break;
+        case VCODIV_1p5:
+            vcoDivTimes10 = 15;
+            break;
+        case VCODIV_2:
+            vcoDivTimes10 = 20;
+            break;
+        case VCODIV_3:
+            vcoDivTimes10 = 30;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITARM_INV_VCODIV,
+                    getMykonosErrorMessage(MYKONOS_ERR_INITARM_INV_VCODIV));
+            return MYKONOS_ERR_INITARM_INV_VCODIV;
+        }
+    }
+
+    hsClkRateDiv4or5_Khz = device->clocks->clkPllVcoFreq_kHz * 10 / vcoDivTimes10 / 20;
+
+    /* If ADC divider is set, divide hsClkRateDiv4or5_kHz by 2 (ADC divider) */
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_CLOCK_CONTROL_1, &adcDiv, 0x01, 0);
+    hb1Clk = (adcDiv == 1) ? (hsClkRateDiv4or5_Khz >> 1) : (hsClkRateDiv4or5_Khz);
+
+    /* the ARM clock should not exceed 250 Mhz */
+    if (hb1Clk <= 250000)
+    {
+        armClkSel = 0x00;
+    }
+    else if (hb1Clk > 250000 && hb1Clk <= 500000)
+    {
+        armClkSel = 0x02;
+    }
+    else if (hb1Clk > 500000 && hb1Clk <= 1000000)
+    {
+        armClkSel = 0x04;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM));
+        return MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM;
+    }
+
+    /* the SPI read reg clock must be equal or less than 100MHz and the SPI write reg clock must be less equal or less than 200 Mhz*/
+    if (hb1Clk <= 100000)
+    {
+        regClkSel = 0x00;
+    }
+    else if (hb1Clk > 100000 && hb1Clk <= 200000)
+    {
+        regClkSel = 0x04;
+    }
+    else if (hb1Clk > 200000 && hb1Clk <= 400000)
+    {
+        regClkSel = 0x09;
+    }
+    else if (hb1Clk > 400000 && hb1Clk <= 800000)
+    {
+        regClkSel = 0x0E;
+    }
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INITARM_INV_REGCLK, getMykonosErrorMessage(MYKONOS_ERR_INITARM_INV_REGCLK));
+        return MYKONOS_ERR_INITARM_INV_REGCLK;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x8C); /* arm_debug_enable[7]=1, mem_hresp_mask[3]=1, auto_incr[2]=1, arm_m3_run[0]=0 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CLK_CTL, armClkSel |= 0x41); /* setting the ARM clock rate, resetting the PC, and enabling the ARM clock */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CLK_CTL, armClkSel &= ~0x40); /* maintaining the ARM clock rate, disabling the PC reset, and maintaining ARM clock enable */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BRIDGE_CLK_CTL, regClkSel); /* setting the SPI read and write clock rates */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AHB_SPI_BRIDGE, 0x13); /* blockout_window_size[4:1] = 9, ahb_spi_bridge_enable[0] = 1 */
+
+    retVal = MYKONOS_writeArmProfile(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    retVal = MYKONOS_loadAdcProfiles(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Loads binary byte array into ARM program memory
+ *
+ * This function assumes the ARM auto increment bit is set in 0x0D00[2]. Valid memory
+ * addresses are: Program Memory (0x01000000 - 0x01017FFF)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param binary is a byte array containing ARM program memory data bytes (directly from .bin file)
+ * \param count is the number of bytes in the byte array
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_LOADBIN_NULL_PARAM Function parameter binary has a NULL pointer
+ * \retval MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT Count parameter must be 98304 bytes
+ */
+mykonosErr_t MYKONOS_loadArmFromBinary(mykonosDevice_t *device, uint8_t *binary, uint32_t count)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t stackPtr[4] = {0};
+    uint8_t bootAddr[4] = {0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_loadArmFromBinary()\n");
+#endif
+
+    if (binary == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOADBIN_NULL_PARAM, getMykonosErrorMessage(MYKONOS_ERR_LOADBIN_NULL_PARAM));
+        return MYKONOS_ERR_LOADBIN_NULL_PARAM;
+    }
+
+    if (count != 98304)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT,
+                getMykonosErrorMessage(MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT));
+        return MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT;
+    }
+    else
+    {
+        /* extraction of stack pointer and boot address from top of array */
+        stackPtr[0] = binary[0];
+        stackPtr[1] = binary[1];
+        stackPtr[2] = binary[2];
+        stackPtr[3] = binary[3];
+
+        bootAddr[0] = binary[4];
+        bootAddr[1] = binary[5];
+        bootAddr[2] = binary[6];
+        bootAddr[3] = binary[7];
+
+        /* writing binary data to ARM memory */
+        retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR, &binary[0], count);
+    }
+
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+    else
+    {
+        /* writing the stack pointer address */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_0, stackPtr[0]); /* stack pointer [7:0]     */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_1, stackPtr[1]); /* stack pointer [15:8]  */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_2, stackPtr[2]); /* stack pointer [23:16] */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_STACK_PTR_BYTE_3, stackPtr[3]); /* stack pointer [31:24] */
+
+        /* writing the boot address */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_0, bootAddr[0]); /* boot address [7:0]     */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_1, bootAddr[1]); /* boot address [15:8]     */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_2, bootAddr[2]); /* boot address [23:16]     */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_3, bootAddr[3]); /* boot address [31:24]     */
+
+        /* setting the ARM run bit */
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x8D); /* arm_debug_enable[7]=1, mem_hresp_mask[3]=1, auto_incr[2]=1, arm_m3_run[0]=1 */
+    }
+
+    /* verifying ARM checksum */
+    retVal = MYKONOS_verifyArmChecksum(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    /* verifying ARM state is in MYKONOS_ARM_READY state, otherwise return error */
+    retVal = MYKONOS_checkArmState(device, MYK_ARM_READY);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    /* Setup ARM GPIO pins and program ARMs radio control structure */
+    retVal = MYKONOS_setArmGpioPins(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    retVal = MYKONOS_setRadioControlPinMode(device);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    /* Set the default ObsRx Path source for when the device moves to RadioOn */
+    retVal = MYKONOS_setDefaultObsRxPath(device, device->obsRx->defaultObsRxChannel);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, retVal, getMykonosErrorMessage(retVal));
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Verifies the ARM checksum value
+ *
+ * The checksum which is written into the .hex file is verified with the calculated checksum
+ * in the Mykonos ARM after the hex file has been loaded
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device)
+{
+    uint32_t buildTimeChecksum = 0x00000000;
+    uint32_t calculatedChecksum = 0x00000000;
+    uint8_t buildData[4];
+    uint8_t calcData[4];
+    const uint8_t CHECKSUM_BYTES = 0x4;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_verifyArmChecksum()\n");
+#endif
+
+    /* disabling auto increment and reading four (4) bytes at ARM checksum memory location */
+    MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_BUILD_CHKSUM_ADDR, buildData, CHECKSUM_BYTES, 0);
+
+    /* determining build time checksum */
+    buildTimeChecksum = (((uint32_t)buildData[3] << 24) | ((uint32_t)buildData[2] << 16) | ((uint32_t)buildData[1] << 8) | (uint32_t)buildData[0]);
+
+    /* using 200 msec timeout for exit out of while loop [maximum checksum calculation time = 5 ms] */
+    CMB_setTimeout_ms(200);
+
+    /* determining calculated checksum */
+    do
+    {
+        MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_CALC_CHKSUM_ADDR, calcData, CHECKSUM_BYTES, 0);
+        calculatedChecksum = (((uint32_t)calcData[3] << 24) | ((uint32_t)calcData[2] << 16) | ((uint32_t)calcData[1] << 8) | (uint32_t)calcData[0]);
+    } while ((!calculatedChecksum) && (!CMB_hasTimeoutExpired()));
+
+    /* performing consistency check */
+    if (buildTimeChecksum == calculatedChecksum)
+    {
+        return MYKONOS_ERR_OK;
+    }
+    else
+    {
+        return MYKONOS_ERR_ARM_INVALID_BUILDCHKSUM;
+    }
+}
+
+/**
+ * \brief Verifies the ARM status once it is start running
+ *
+ * Wait for ARM to go into radio state, if takes longer there is and ARM error
+ * get error in Application layer calling MYKONOS_getRadioState()
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param armStateCheck if the ARM is not in this state it will return an error,
+ *
+ * \retval MYKONOS_ERR_ARMSTATE_EXCEPTION ARM system problem has been detected.
+ * \retval MYKONOS_ERR_ARMSTATE_CAL_ERROR ARM has detected an error in the tracking calibrations.
+ * \retval MYKONOS_ERR_ARMSTATE_EXCEPTION ARM has detected an illegal profile.
+ * \retval MYKONOS_ERR_WAITARMCSTATE_TIMEOUT Timeout occurred in check ARM state.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t armStateCheck)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t armStatus = 0x00;
+    uint32_t timeoutMs = 500; /* 500ms timeOut */
+    uint8_t endCheck = 0x00;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_checkArmState()\n");
+#endif
+
+    CMB_setTimeout_ms(timeoutMs);
+
+    do
+    {
+        retVal = MYKONOS_getRadioState(device, &armStatus);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+
+        if (armStateCheck == armStatus)
+        {
+            retVal = MYKONOS_ERR_OK;
+            break;
+        }
+
+        if (CMB_hasTimeoutExpired())
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITARMCSTATE_TIMEOUT,
+                    getMykonosErrorMessage(MYKONOS_ERR_WAITARMCSTATE_TIMEOUT));
+            retVal = MYKONOS_ERR_WAITARMCSTATE_TIMEOUT;
+            break;
+        }
+
+        switch (armStatus)
+        {
+            /* this cases are not ARM errors */
+            case MYK_ARM_POWERUP:
+            case MYK_ARM_READY:
+            case MYK_ARM_IDLE:
+            case MYK_ARM_RADIO_ON:
+                break;
+
+            case MYK_ARM_PROFILE_ERROR:
+                /* return error directly */
+                retVal = MYKONOS_ERR_ARMSTATE_PROFILE_ERROR;
+                endCheck = 1;
+                break;
+
+            case MYK_ARM_CAL_ERROR:
+                /* return error directly */
+                retVal = MYKONOS_ERR_ARMSTATE_CAL_ERROR;
+                endCheck = 1;
+                break;
+
+            case MYK_ARM_EXCEPTION:
+                /* return error directly */
+                retVal = MYKONOS_ERR_ARMSTATE_EXCEPTION;
+                endCheck = 1;
+                break;
+
+            case MYK_ARM_EXCEPTION | MYK_ARM_PROFILE_ERROR:
+                /* return error directly */
+                retVal = MYKONOS_ERR_ARMSTATE_EXCEPTION;
+                endCheck = 1;
+                break;
+
+            default:
+                endCheck = 0;
+                break;
+        }
+
+    } while (!endCheck);
+
+    return retVal;
+}
+
+/**
+ * \brief Reads back the version of the ARM binary loaded into the Mykonos ARM memory
+ *
+ * This function reads the ARM memory to read back the major.minor.releaseCandidate
+ * version for the ARM binary loaded into ARM memory.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param majorVer The Major version is returned in this parameter
+ * \param minorVer The Minor version is returned in this parameter
+ * \param rcVer The release candidate version (build number) is returned in this parameter
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETARMVER_NULL_PARM One of the function parameters has a NULL pointer
+ */
+mykonosErr_t MYKONOS_getArmVersion(mykonosDevice_t *device, uint8_t *majorVer, uint8_t *minorVer, uint8_t *rcVer)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t ver[4] = {0};
+    uint32_t fullVersion = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getArmVersion()\n");
+#endif
+
+    if ((majorVer == NULL) || (minorVer == NULL) || (rcVer == NULL))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETARMVER_NULL_PARM, getMykonosErrorMessage(MYKONOS_ERR_GETARMVER_NULL_PARM));
+        return MYKONOS_ERR_GETARMVER_NULL_PARM;
+    }
+
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_VERSION, &ver[0], sizeof(ver), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    fullVersion = ((uint32_t)(ver[0]) | ((uint32_t)(ver[1]) << 8) | ((uint32_t)(ver[2]) << 16) | ((uint32_t)(ver[3]) << 24));
+    *rcVer = (fullVersion % 100);
+    *minorVer = ((fullVersion / 100) % 100);
+    *majorVer = (fullVersion / 10000);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function, when called during RadioOff, will configure DPD settings
+ *
+ *  A AD9373 device is required for DPD to be enabled.  The DPD has several user
+ *  adjustable settings that can be configured before running the runInitCals
+ *  with the calMask set for the DPD init cal. Call this function with desired
+ *  settings set before running the DPD init cal or enabling DPD tracking.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->dpdConfig (All members)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV ERROR: to use these features, a valid Tx and ORx profile must exist in the device data structure
+ * \retval MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT ERROR: device->tx->dpdConfig is a NULL pointer
+ * \retval MYKONOS_ERR_CFGDPD_ARMSTATE_ERROR ERROR: To set these settings, the ARM must be in the radioOff (IDLE) state.
+ * \retval MYKONOS_ERR_CFGDPD_INV_DPDDAMPING ERROR: damping parameter is out of range
+ * \retval MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES ERROR: samples parameter is out of range
+ * \retval MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS ERROR: numWeights parameter is out of range (0-3)
+ * \retval MYKONOS_ERR_CFGDPD_INV_MODELVERSION ERROR: modelVersion parameter is out of range (0-3)
+ * \retval MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH ERROR: outlierThreshold parameter is out of range
+ * \retval MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY ERROR: additionalDelayOffset parameter is out of range
+ * \retval MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL ERROR: pathDelayPnSeqLevel parameter is out of range
+ *
+ */
+mykonosErr_t MYKONOS_configDpd(mykonosDevice_t *device)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armFieldValue[6] = {0};
+    uint8_t byteOffset = 0;
+    uint16_t negPnLevel = 0;
+    uint8_t highPowerModelUpdate = 0;
+    uint8_t robustModeling = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_configDpd()\n");
+#endif
+
+    /* DPD requires Tx and ORx enabled, throw error if both are not enabled */
+    if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV));
+        return MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV;
+    }
+
+    if (device->tx->dpdConfig == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT));
+        return MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT;
+    }
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_ARMSTATE_ERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_ARMSTATE_ERROR));
+        return MYKONOS_ERR_CFGDPD_ARMSTATE_ERROR;
+    }
+
+    /* check DPD damping and samples parameters */
+    if (device->tx->dpdConfig->damping > 15)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDDAMPING,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDDAMPING));
+        return MYKONOS_ERR_CFGDPD_INV_DPDDAMPING;
+    }
+
+    if ((device->tx->dpdConfig->samples < 64) || (device->tx->dpdConfig->samples > 32768))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES));
+        return MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES;
+    }
+
+    if (device->tx->dpdConfig->numWeights > 3)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS));
+        return MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS;
+    }
+
+    if (device->tx->dpdConfig->modelVersion > 3)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_MODELVERSION,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_MODELVERSION));
+        return MYKONOS_ERR_CFGDPD_INV_MODELVERSION;
+    }
+
+    highPowerModelUpdate = (device->tx->dpdConfig->highPowerModelUpdate > 0) ? 1 : 0;
+    robustModeling = (device->tx->dpdConfig->robustModeling > 0) ? 1 : 0;
+
+    armFieldValue[0] = (((device->tx->dpdConfig->numWeights & 3) << 4) | (device->tx->dpdConfig->damping & 0xF));
+    armFieldValue[1] = ((robustModeling << 3) | (highPowerModelUpdate << 2) | (device->tx->dpdConfig->modelVersion & 3));
+    armFieldValue[2] = (device->tx->dpdConfig->samples & 0xFF);
+    armFieldValue[3] = ((device->tx->dpdConfig->samples >> 8) & 0xFF);
+    byteOffset = 0;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set DPD outlier threshold parameter */
+    if ((device->tx->dpdConfig->outlierThreshold < 1) || (device->tx->dpdConfig->outlierThreshold > 8192))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH));
+        return MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH;
+    }
+
+    armFieldValue[0] = (device->tx->dpdConfig->outlierThreshold & 0xFF);
+    armFieldValue[1] = ((device->tx->dpdConfig->outlierThreshold >> 8) & 0xFF);
+    byteOffset = 10;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set DPD Model Prior Weight parameter */
+    if (device->tx->dpdConfig->modelPriorWeight > 32)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT));
+        return MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT;
+    }
+    armFieldValue[0] = (device->tx->dpdConfig->modelPriorWeight & 0xFF);
+    armFieldValue[1] = 0;
+    byteOffset = 12;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* no need to verify weights min/max as all int8 values are valid */
+    armFieldValue[0] = (device->tx->dpdConfig->weights[0].real);
+    armFieldValue[1] = (device->tx->dpdConfig->weights[0].imag);
+    armFieldValue[2] = (device->tx->dpdConfig->weights[1].real);
+    armFieldValue[3] = (device->tx->dpdConfig->weights[1].imag);
+    armFieldValue[4] = (device->tx->dpdConfig->weights[2].real);
+    armFieldValue[5] = (device->tx->dpdConfig->weights[2].imag);
+
+    byteOffset = 14;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armFieldValue[0], 6);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set DPD additional delay offset parameter */
+    if ((device->tx->dpdConfig->additionalDelayOffset < -64) || (device->tx->dpdConfig->additionalDelayOffset > 64))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY));
+        return MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY;
+    }
+
+    armFieldValue[0] = (device->tx->dpdConfig->additionalDelayOffset & 0xFF);
+    armFieldValue[1] = ((device->tx->dpdConfig->additionalDelayOffset >> 8) & 0xFF);
+    byteOffset = 2;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armFieldValue[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if ((device->tx->dpdConfig->pathDelayPnSeqLevel < 1) || (device->tx->dpdConfig->pathDelayPnSeqLevel > 8191))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL));
+        return MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL;
+    }
+
+    /* Set Path Delay PN sequence amplitude - positive and negative */
+    armFieldValue[0] = (device->tx->dpdConfig->pathDelayPnSeqLevel & 0xFF);
+    armFieldValue[1] = ((device->tx->dpdConfig->pathDelayPnSeqLevel >> 8) & 0xFF);
+
+    negPnLevel = ((~device->tx->dpdConfig->pathDelayPnSeqLevel) + 1); /* times -1 */
+    armFieldValue[2] = (negPnLevel & 0xFF);
+    armFieldValue[3] = (((negPnLevel) >> 8) & 0xFF);
+    byteOffset = 10;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/* \brief Reads the DPD config structure from ARM memory
+ *
+ *  This function reads the DPD structure
+ *  from ARM memory and returns in the device->tx->dpdConfig structure.
+ *
+ *  A AD9373 device is required for DPD to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->dpdConfig (All members)
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV Error: Tx and ORx profiles must be valid for DPD functions
+ * \retval MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT Error: NULL pointer to device->tx->dpdConfig structure
+ */
+mykonosErr_t MYKONOS_getDpdConfig(mykonosDevice_t *device)
+{
+    uint16_t byteOffset = 0;
+    uint8_t armMem[20] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdConfig()\n");
+#endif
+
+    /* DPD requires Tx and ORx enabled, throw error if both are not enabled */
+    if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV));
+        return MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV;
+    }
+
+    if (device->tx->dpdConfig == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT));
+        return MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT;
+    }
+
+    byteOffset = 0;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &armMem[0], 20);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->dpdConfig->damping = (armMem[0] & 0x0F);
+    device->tx->dpdConfig->numWeights = ((armMem[0] >> 4) & 0x03);
+
+    device->tx->dpdConfig->modelVersion = (armMem[1] & 0x03);
+    device->tx->dpdConfig->highPowerModelUpdate = ((armMem[1] >> 2) & 0x01);
+    device->tx->dpdConfig->robustModeling = ((armMem[1] >> 3) & 0x01);
+    device->tx->dpdConfig->samples = ((uint16_t)(armMem[3]) << 8) | (uint16_t)(armMem[2]);
+
+    device->tx->dpdConfig->outlierThreshold = ((uint16_t)(armMem[11]) << 8) | (uint16_t)(armMem[10]);
+    device->tx->dpdConfig->modelPriorWeight = armMem[12];
+    device->tx->dpdConfig->weights[0].real = (int8_t)(armMem[14]);
+    device->tx->dpdConfig->weights[0].imag = (int8_t)(armMem[15]);
+    device->tx->dpdConfig->weights[1].real = (int8_t)(armMem[16]);
+    device->tx->dpdConfig->weights[1].imag = (int8_t)(armMem[17]);
+    device->tx->dpdConfig->weights[2].real = (int8_t)(armMem[18]);
+    device->tx->dpdConfig->weights[2].imag = (int8_t)(armMem[19]);
+
+    byteOffset = 2;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armMem[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->dpdConfig->additionalDelayOffset = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+
+    byteOffset = 10;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG, byteOffset, &armMem[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->dpdConfig->pathDelayPnSeqLevel = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function reads the DPD calibration status from the Mykonos ARM processor.
+ *
+ * The dpdStatus is read back from the ARM processor and returned in the function
+ * parameter dpdStatus.
+ *
+ * A AD9373 device is required for this feature to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param txChannel Desired Transmit channel to read back DPD status for (Valid ENUM values: TX1 or TX2 only)
+ * \param dpdStatus Pointer to a structure to return the status information to
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETDPDSTATUS_NULLPARAM dpdStatus function parameter is a NULL pointer
+ * \retval MYKONOS_ERR_GETDPDSTATUS_INV_CH txChannel parameter is a non-supported value.
+ * \retval MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG ARM reported an error while processing the GET ARM command
+ */
+mykonosErr_t MYKONOS_getDpdStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdStatus_t *dpdStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_DPDCONFIG, 0};
+    uint8_t armData[28] = {0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    uint8_t channelSelect = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getDpdStatus()\n");
+#endif
+
+    if (dpdStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETDPDSTATUS_NULLPARAM;
+    }
+
+    switch (txChannel)
+    {
+        case TX1:
+            channelSelect = 0;
+            break;
+        case TX2:
+            channelSelect = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_INV_CH));
+            return MYKONOS_ERR_GETDPDSTATUS_INV_CH;
+        }
+    }
+
+    extData[2] = channelSelect;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armData[0], 28, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    dpdStatus->dpdErrorStatus = ((uint32_t)(armData[1]) << 8) | (uint32_t)(armData[0]); /* Only lower 16 bits */
+    dpdStatus->dpdTrackCount = ((uint32_t)(armData[11]) << 24) | ((uint32_t)(armData[10]) << 16) | ((uint32_t)(armData[9]) << 8) | (uint32_t)(armData[8]);
+    dpdStatus->dpdModelErrorPercent = ((uint32_t)(armData[15]) << 24) | ((uint32_t)(armData[14]) << 16) | ((uint32_t)(armData[13]) << 8) | (uint32_t)(armData[12]);
+    dpdStatus->dpdExtPathDelay = ((uint32_t)(armData[26]) * 16) + (uint32_t)(armData[24]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This private helper function called during RadioOff, will allow DPD tracking to be scheduled
+ *        by the ARM when back in the RadioOn state.
+ *
+ *  This function sets a flag in the ARM memory that if the enableDpd tracking cal mask
+ *  and this setting are both set, then the ARM will schedule DPD tracking to occur
+ *  in the radioOn ARM state.
+ *
+ *  A AD9373 device is required for DPD to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->tx->dpdConfig
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param tx1Enable 0=disable DPD Tx1 tracking, 1= enable DPD Tx1 tracking
+ * \param tx2Enable 0=disable DPD Tx2 tracking, 1= enable DPD Tx2 tracking
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR ARM is not in the RadioOff state, call MYKONOS_radioOff()
+ */
+static mykonosErr_t enableDpdTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t enableBit[4] = {0};
+    uint8_t byteOffset = 20;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableDpdTracking()\n");
+#endif
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR));
+        return MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR;
+    }
+
+    enableBit[0] = (tx1Enable > 0) ? 1 : 0;
+    enableBit[1] = 0;
+    enableBit[2] = (tx2Enable > 0) ? 1 : 0;
+    enableBit[3] = 0;
+
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_DPDCONFIG, byteOffset, &enableBit[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function called during RadioOff, will allow loading of the DPD model file.
+ *
+ *  This function writes a copy of the user's DPD model to ARM memory and instructs the ARM to install that DPD model
+ *  into hardware.  Note that initializing the device will over write DPD model data.  Note that the DPD model being
+ *  restored must match the PA for which it is configured.  Restoring a DPD model to a different PA than for which it
+ *  is configured will not yield the desired performance.  The user is responsible to insure the DPD model matches the
+ *  PA configuration.
+ *
+ * \param device Structure pointer to the Mykonos data structure containing settings
+ * \param txChannel Desired transmit channel to which to write the DPD model file (Valid ENUM type mykonosTxChannels_t: TX1 or TX2 or TX1_TX2)
+ * \param modelDataBuffer Pointer to the user buffer containing the history/model data to be loaded to a txChannel
+ *        Valid sizes: 172 bytes for a single model/rms load to either TX1 or TX2.
+ *                     344 bytes for a dual model/rms load to both TX1_TX2, where the TX1 model/rms data will occupy the first 172 bytes
+ *                     and TX2 model/rms data will occupy the second 172 bytes.
+ * \param modelNumberBytes Total buffer size of the user history/model data buffer. Allowed sizes are 172 bytes for TX1 or TX2 and
+ *        344 bytes for TX1_TX2.
+ *
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_RESTDPDMOD_ARMSTATE ARM is not in the RadioOff state, call MYKONOS_radioOff()
+ * \retval MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE User suppled modelNumberBytes size is incorrect. TX1 or TX2 = 172,  TX1_TX2 = 344
+ * \retval MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL User supplied txChannel does not match TX1 or TX2 or TX1_TX2
+ * \retval MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG ARM returned error for Set ARM Command
+ */
+mykonosErr_t MYKONOS_restoreDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint16_t modelSize = 0;
+    uint16_t rmsSize = 0;
+    uint8_t armData[4] = {0};
+    uint32_t armBufferAddr = 0;
+    uint8_t *bufferPtr = 0;
+    uint8_t extendedData[4] = {0};
+    uint8_t cmdStatusByte = 0;
+
+    const uint32_t timeoutMs = 1000;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_restoreDpdModel()\n");
+#endif
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_ARMSTATE, getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_ARMSTATE)); /* radio not off or initialized */
+        return MYKONOS_ERR_RESTDPDMOD_ARMSTATE;
+    }
+
+    /* retrieve the model buffer byte count */
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_DPD_MODEL_BUF_SIZE), &armData[0], 2, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+    modelSize = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8));
+
+    /* retrieve the rms buffer byte count */
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_DPD_RMS_BUF_SIZE), &armData[0], 2, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+    rmsSize = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8));
+
+    if (txChannel == TX1)
+    {
+        /* check for single valid provided buffer size */
+        if (modelNumberBytes != (modelSize + rmsSize))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE));
+            return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE;
+        }
+
+        /* retrieve the arm TX1 model buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX1 model data */
+        bufferPtr = modelDataBuffer;
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, modelSize); /* write TX1 model */
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        bufferPtr += modelSize;
+
+        /* retrieve the arm TX1 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_RMS_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX1 rms */
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, rmsSize);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }/*end TX1 */
+
+    else if (txChannel == TX2)
+    {
+        /* check for single valid provided buffer size */
+        if (modelNumberBytes != (modelSize + rmsSize))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE));
+            return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE;
+        }
+
+        /* retrieve the arm TX2 model buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX2 model data */
+        bufferPtr = modelDataBuffer;
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, modelSize); /* write TX2 model */
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        bufferPtr += modelSize;
+
+        /* retrieve the arm TX2 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_RMS_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX2 rms */
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, rmsSize);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }/* end TX2 */
+
+    /* check for dual txChannel type */
+    else if (txChannel == TX1_TX2)
+    {
+        /* check for single valid provided buffer size */
+        if (modelNumberBytes != (2 * (modelSize + rmsSize)))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE));
+            return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE;
+        }
+
+        /* retrieve the arm TX1 model buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX1 model data */
+        bufferPtr = modelDataBuffer;
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, modelSize); /* write TX1 model */
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        bufferPtr += modelSize;
+
+        /* retrieve the arm TX1 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_RMS_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX1 rms */
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, rmsSize);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        bufferPtr += rmsSize;
+
+        /* retrieve the arm TX2 model buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX2 model data */
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, modelSize); /* write TX2 model */
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        bufferPtr += modelSize;
+
+        /* retrieve the arm TX2 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_RMS_INDIRECT_PTR), &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* write the TX2 rms */
+        retVal = MYKONOS_writeArmMem(device, armBufferAddr, bufferPtr, rmsSize);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }/*end two txChannel model data load */
+
+    /* invalid txChannel for this api command */
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL,
+                getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL));
+        return MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL;
+    }/* end invalid txChannel check */
+
+    /* instruct ARM to load DPD Model */
+    extendedData[0] = MYKONOS_ARM_OBJECTID_GS_TRACKCALS;
+    extendedData[1] = MYKONOS_ARM_DPD_INIT_MODEL;
+    extendedData[2] = txChannel;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extendedData[0], sizeof(extendedData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* wait max of 1sec for command to complete */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG));
+            return MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG;
+        }
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function called during RadioOff, will allow retrevial of the DPD model file.
+ *
+ *  This function reads a copy of the DPD model from ARM memory to user memory specified by the modelDataBuffer pointer.
+ *  The user must provide the correct buffer size with the modelNumberBytes argument.
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param txChannel Desired Transmit channel to read back DPD status for (Valid ENUM type mykonosTxChannels_t: TX1 or TX2 or TX1_TX2)
+ * \param modelDataBuffer a pointer to the user buffer where the model/rms data is to be written.
+ *        Valid sizes: 172 bytes for a single model load to either TX1 or TX2.
+ *                     344 bytes for a dual model load to both TX1_TX2, where the TX1 model/rms data will occupy the first 172 bytes
+ *                          and TX2 model/rms data will occupy the second 172 bytes.
+ * \param modelNumberBytes is the total buffer size of the user rms/model data buffer. Allowed sizes are 172 bytes for TX1 or TX2 and
+ *        344 bytes for TX1_TX2.
+ *
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_SAVEDPDMODEL_ARMSTATE_ERROR ARM is not in the RadioOff state, call MYKONOS_radioOff()
+ * \retval MYKONOS_ERR_SAVEDPDMODEL_BUFFERSIZE_ERROR suppled modelNumberBytes size is incorrect. TX1 or TX2 = 172,  TX1_TX2 = 344
+ * \retval MYKONOS_ERR_SAVEDPDMODEL_INVALID_TXCHANNEL_ERROR supplied txChannel does not match TX1 or TX2 or TX1_TX2
+ */
+mykonosErr_t MYKONOS_saveDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint16_t modelSize = 0;
+    uint16_t rmsSize = 0;
+    uint8_t armData[4] = {0};
+    uint32_t armBufferAddr = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_saveDpdModel()\n");
+#endif
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_ARMSTATE, getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_ARMSTATE)); /* radio not off or initialized */
+        return MYKONOS_ERR_SAVDPDMOD_ARMSTATE;
+    }
+
+    /* retrieve the model buffer byte count */
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_DPD_MODEL_BUF_SIZE), &armData[0], 2, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+    modelSize = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8));
+
+    /* retrieve the rms buffer byte count */
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_DPD_RMS_BUF_SIZE), &armData[0], 2, 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+    rmsSize = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8));
+
+    if (txChannel == TX1)
+    {
+        /* check for single valid provided buffer size */
+        if (modelNumberBytes != (modelSize + rmsSize))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE));
+            return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE; /* wrong buffer size */
+        }
+
+        /* retrieve the arm TX1 model buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX1 model */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, modelSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        modelDataBuffer += modelSize;
+
+        /* retrieve the arm TX1 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_RMS_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX1 rms */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, rmsSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }/*end TX1 */
+
+    else if (txChannel == TX2)
+    {
+        /* check for single valid provided buffer size */
+        if (modelNumberBytes != (modelSize + rmsSize))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE));
+            return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE; /* wrong buffer size */
+        }
+
+        /* retrieve the arm TX2 model buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX2 model */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, modelSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        modelDataBuffer += modelSize;
+
+        /* retrieve the arm TX2 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_RMS_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX2 rms */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, rmsSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }/*end TX2 */
+
+    /* check for dual txChannel type */
+    else if (txChannel == TX1_TX2)
+    {
+        /* check for single valid provided buffer size */
+        if (modelNumberBytes != (2 * (modelSize + rmsSize)))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE));
+            return MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE; /* wrong buffer size */
+        }
+
+        /* retrieve the arm TX1 model buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX1 model */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, modelSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        modelDataBuffer += modelSize;
+
+        /* retrieve the arm TX1 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX1_DPD_RMS_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX1 rms */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, rmsSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        modelDataBuffer += rmsSize;
+
+        /* retrieve the arm TX2 model buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX2 model */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, modelSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        modelDataBuffer += modelSize;
+
+        /* retrieve the arm TX2 rms buffer address */
+        retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_PROG_ADDR + MYKONOS_ADDR_TX2_DPD_RMS_INDIRECT_PTR, &armData[0], 4, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+        armBufferAddr = (((uint32_t)armData[0]) | (((uint32_t)armData[1]) << 8) | (((uint32_t)armData[2]) << 16) | (((uint32_t)armData[3]) << 24));
+
+        /* read the TX2 rms */
+        retVal = MYKONOS_readArmMem(device, armBufferAddr, modelDataBuffer, rmsSize, 1);
+        if (retVal != MYKONOS_ERR_OK)
+        {
+            return retVal;
+        }
+    }/* end two txChannel */
+
+    /* invalid txChannel for this api command */
+    else
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL,
+                getMykonosErrorMessage(MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL));
+        return MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL; /* invalid txChannel */
+    }/* end invalid txChannel check */
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function sets the state of the DPD actuator.
+ *
+ *  This function can be called in either Radio On or Off state.
+ *
+ * \pre A AD9373 device is required for DPD to be enabled. DPD init cal has been run and DPD tracking enable.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param txChannel Desired Transmit channel to set the Actuator State (Valid ENUM values: TX1, TX2 or TX1_TX2)
+ * \param actState Desired actuator state for the DPD, valid states are 0-disable and 1-enable
+ *
+ * \retval MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL ERROR: Tx channel is not valid (Valid ENUM values: TX1, TX2 or TX1_TX2)
+ * \retval MYKONOS_ERR_SETDPDACT_INV_STATE ERROR: Invalid Actuator state, valid states are 0-disable and 1-enable.
+ * \retval MYKONOS_ERR_SETDPDACT_ARMERRFLAG ERROR: ARM command flag error set
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setDpdActState(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t actState)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t timeoutMs = 1000;
+    uint8_t extData[3] = {0};
+    uint8_t actuatorSet = 0x00;
+    uint8_t cmdStatusByte = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setDpdActuator()\n");
+#endif
+
+    switch (txChannel)
+    {
+        case TX1:
+            break;
+        case TX2:
+            break;
+        case TX1_TX2:
+            break;
+
+        default:
+            /* this function allow single channel gain only */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL));
+            return MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL;
+    }
+    switch (actState)
+    {
+        case 0:
+            actuatorSet = DISABLE_DPD_ACTUATOR;
+            break;
+        case 1:
+            actuatorSet = ENABLE_DPD_ACTUATOR;
+            break;
+
+        default:
+            /* this function allow single channel gain only */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_INV_STATE,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_INV_STATE));
+            return MYKONOS_ERR_SETDPDACT_INV_STATE;
+    }
+
+    extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL;
+    extData[1] = actuatorSet;
+    extData[2] = (uint8_t)txChannel;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_ARMERRFLAG));
+            return MYKONOS_ERR_SETDPDACT_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETDPDACT_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_SETDPDACT_ARMERRFLAG));
+        return MYKONOS_ERR_SETDPDACT_ARMERRFLAG;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function, when called during RadioOff, will configure CLGC settings
+ *
+ *  A AD9373 device is required for CLGC to be enabled.  The CLGC has several user
+ *  adjustable settings that can be configured before running the runInitCals
+ *  with the calMask set for the CLGC init cal. Call this function with desired
+ *  settings set before running the CLGC init cal or enabling CLGC tracking.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->clgcConfig (All members)
+ *
+ * \retval MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV ERROR: Tx and ObsRx profiles must be valid to use the CLGC feature
+ * \retval MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT ERROR: CLGC config structure pointer is null in device->tx->clgcConfig
+ * \retval MYKONOS_ERR_CFGCLGC_ARMSTATE_ERROR ERROR: ARM is not in the IDLE(radioOff) or Ready state.
+ * \retval MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN ERROR: CLGC tx1DesiredGain or tx2DesiredGain parameter is out of range
+ * \retval MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT ERROR: CLGC tx1AttenLimit or tx2AttenLimit parameter is out of range
+ * \retval MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO ERROR: clgcControlRatio parameter is out of range
+ */
+mykonosErr_t MYKONOS_configClgc(mykonosDevice_t *device)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armFieldValue[4] = {0};
+    uint8_t byteOffset = 0;
+    uint16_t negPnLevel = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_configClgc()\n");
+#endif
+
+    /* CLGC requires Tx and ORx enabled, throw error if both are not enabled */
+    if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV));
+        return MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV;
+    }
+
+    if (device->tx->clgcConfig == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT));
+        return MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT;
+    }
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_ARMSTATE_ERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_ARMSTATE_ERROR));
+        return MYKONOS_ERR_CFGCLGC_ARMSTATE_ERROR;
+    }
+
+    /* set CLGC desired gain parameter */
+    if ((device->tx->clgcConfig->tx1DesiredGain < -10000) || (device->tx->clgcConfig->tx1DesiredGain > 10000) || (device->tx->clgcConfig->tx2DesiredGain < -10000)
+            || (device->tx->clgcConfig->tx2DesiredGain > 10000))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN));
+        return MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN;
+    }
+
+    armFieldValue[0] = (device->tx->clgcConfig->tx1DesiredGain & 0xFF);
+    armFieldValue[1] = ((device->tx->clgcConfig->tx1DesiredGain >> 8) & 0xFF);
+    armFieldValue[2] = (device->tx->clgcConfig->tx2DesiredGain & 0xFF);
+    armFieldValue[3] = ((device->tx->clgcConfig->tx2DesiredGain >> 8) & 0xFF);
+
+    byteOffset = 0;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set CLGC Tx Atten limit parameter */
+    if ((device->tx->clgcConfig->tx1AttenLimit > 40) || (device->tx->clgcConfig->tx2AttenLimit > 40))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT));
+        return MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT;
+    }
+
+    armFieldValue[0] = (device->tx->clgcConfig->tx1AttenLimit & 0xFF);
+    armFieldValue[1] = ((device->tx->clgcConfig->tx1AttenLimit >> 8) & 0xFF);
+    armFieldValue[2] = (device->tx->clgcConfig->tx2AttenLimit & 0xFF);
+    armFieldValue[3] = ((device->tx->clgcConfig->tx2AttenLimit >> 8) & 0xFF);
+
+    byteOffset = 8;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set CLGC Control Ratio parameter */
+    if ((device->tx->clgcConfig->tx1ControlRatio < 1) || (device->tx->clgcConfig->tx1ControlRatio > 100) || (device->tx->clgcConfig->tx2ControlRatio < 1)
+            || (device->tx->clgcConfig->tx2ControlRatio > 100))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO));
+        return MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO;
+    }
+
+    armFieldValue[0] = (device->tx->clgcConfig->tx1ControlRatio & 0xFF);
+    armFieldValue[1] = ((device->tx->clgcConfig->tx1ControlRatio >> 8) & 0xFF);
+    armFieldValue[2] = (device->tx->clgcConfig->tx2ControlRatio & 0xFF);
+    armFieldValue[3] = ((device->tx->clgcConfig->tx2ControlRatio >> 8) & 0xFF);
+
+    byteOffset = 12;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set CLGC additional delay offset parameter (init cal)*/
+    if ((device->tx->clgcConfig->additionalDelayOffset < -64) || (device->tx->clgcConfig->additionalDelayOffset > 64))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY));
+        return MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY;
+    }
+
+    armFieldValue[0] = (device->tx->clgcConfig->additionalDelayOffset & 0xFF);
+    armFieldValue[1] = ((device->tx->clgcConfig->additionalDelayOffset >> 8) & 0xFF);
+    byteOffset = 2;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armFieldValue[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if ((device->tx->clgcConfig->pathDelayPnSeqLevel < 1) || (device->tx->clgcConfig->pathDelayPnSeqLevel > 8191))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL));
+        return MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL;
+    }
+
+    /* Set Path Delay PN sequence amplitude - positive and negative (init cal)*/
+    armFieldValue[0] = (device->tx->clgcConfig->pathDelayPnSeqLevel & 0xFF);
+    armFieldValue[1] = ((device->tx->clgcConfig->pathDelayPnSeqLevel >> 8) & 0xFF);
+
+    negPnLevel = ((~device->tx->clgcConfig->pathDelayPnSeqLevel) + 1); /* times -1 */
+    armFieldValue[2] = (negPnLevel & 0xFF);
+    armFieldValue[3] = (((negPnLevel) >> 8) & 0xFF);
+    byteOffset = 10;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    retVal = enableClgcTracking(device, ((device->tx->clgcConfig->allowTx1AttenUpdates > 0) ? 1 : 0), ((device->tx->clgcConfig->allowTx2AttenUpdates > 0) ? 1 : 0));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/* \brief Reads the CLGC config structure from ARM memory
+ *
+ *  This function reads the Closed Loop Gain Control structure
+ *  from ARM memory and returns in the device->tx->clgcConfig structure.
+ *
+ *  A AD9373 device is required for CLGC to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->clgcConfig (All members)
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV Error: Tx and ORx profiles must be valid for CLGC functions
+ * \retval MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT Error: NULL pointer to device->tx->clgcConfig structure
+ */
+mykonosErr_t MYKONOS_getClgcConfig(mykonosDevice_t *device)
+{
+    uint16_t byteOffset = 0;
+    uint8_t armMem[16] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getClgcConfig()\n");
+#endif
+
+    /* CLGC requires Tx and ORx enabled, throw error if both are not enabled */
+    if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV));
+        return MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV;
+    }
+
+    if (device->tx->clgcConfig == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT));
+        return MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT;
+    }
+
+    byteOffset = 0;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &armMem[0], sizeof(armMem));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->clgcConfig->tx1DesiredGain = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+    device->tx->clgcConfig->tx2DesiredGain = (int16_t)(((uint16_t)(armMem[3]) << 8) | (uint16_t)(armMem[2]));
+    device->tx->clgcConfig->tx1AttenLimit = (((uint16_t)(armMem[9]) << 8) | (uint16_t)(armMem[8]));
+    device->tx->clgcConfig->tx2AttenLimit = (((uint16_t)(armMem[11]) << 8) | (uint16_t)(armMem[10]));
+    device->tx->clgcConfig->tx1ControlRatio = (((uint16_t)(armMem[13]) << 8) | (uint16_t)(armMem[12]));
+    device->tx->clgcConfig->tx2ControlRatio = (((uint16_t)(armMem[15]) << 8) | (uint16_t)(armMem[14]));
+
+    byteOffset = 2;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armMem[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->clgcConfig->additionalDelayOffset = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+
+    byteOffset = 10;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG, byteOffset, &armMem[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->clgcConfig->pathDelayPnSeqLevel = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function reads the CLGC calibration status from the Mykonos ARM processor.
+ *
+ * The Closed Loop Gain Control Status is read back from the ARM processor and
+ * returned in the function parameter clgcStatus.
+ *
+ * A AD9373 device is required for this feature to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param txChannel Desired Transmit channel to read back CLGC status for (Valid ENUM values: TX1 or TX2 only)
+ * \param clgcStatus Pointer to a structure to return the status information to
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM clgcStatus function parameter is a NULL pointer
+ * \retval MYKONOS_ERR_GETCLGCSTATUS_INV_CH txChannel parameter is a non supported value.
+ * \retval MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG ARM reported an error while processing the GET ARM command
+ */
+mykonosErr_t MYKONOS_getClgcStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosClgcStatus_t *clgcStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_CLGCCONFIG, 0};
+    uint8_t armData[52] = {0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    uint32_t offset = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t channelSelect = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getClgcStatus()\n");
+#endif
+
+    if (clgcStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM;
+    }
+
+    switch (txChannel)
+    {
+        case TX1:
+            channelSelect = 0;
+            break;
+        case TX2:
+            channelSelect = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_INV_CH));
+            return MYKONOS_ERR_GETCLGCSTATUS_INV_CH;
+        }
+    }
+
+    extData[2] = channelSelect;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    offset = 0;
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armData[0], sizeof(armData), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    clgcStatus->errorStatus = ((uint32_t)(armData[3]) << 24) | ((uint32_t)(armData[2]) << 16) | ((uint32_t)(armData[1]) << 8) | (uint32_t)(armData[0]);
+    clgcStatus->desiredGain = (int32_t)(((uint32_t)(armData[23]) << 24) | ((uint32_t)(armData[22]) << 16) | ((uint32_t)(armData[21]) << 8) | (uint32_t)(armData[20]));
+    clgcStatus->currentGain = (int32_t)(((uint32_t)(armData[27]) << 24) | ((uint32_t)(armData[26]) << 16) | ((uint32_t)(armData[25]) << 8) | (uint32_t)(armData[24]));
+    clgcStatus->txGain = ((uint32_t)(armData[39]) << 24) | ((uint32_t)(armData[38]) << 16) | ((uint32_t)(armData[37]) << 8) | (uint32_t)(armData[36]);
+    clgcStatus->txRms = (int32_t)(((uint32_t)(armData[43]) << 24) | ((uint32_t)(armData[42]) << 16) | ((uint32_t)(armData[41]) << 8) | (uint32_t)(armData[40]));
+    clgcStatus->orxRms = (int32_t)(((uint32_t)(armData[47]) << 24) | ((uint32_t)(armData[46]) << 16) | ((uint32_t)(armData[45]) << 8) | (uint32_t)(armData[44]));
+    clgcStatus->trackCount = ((uint32_t)(armData[51]) << 24) | ((uint32_t)(armData[50]) << 16) | ((uint32_t)(armData[49]) << 8) | (uint32_t)(armData[48]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This private helper function called during RadioOff, will allow CLGC tracking to be scheduled
+ *        by the ARM when back in the RadioOn state.
+ *
+ *  This function sets a flag in the ARM memory that if the enableDpd tracking cal mask
+ *  and this setting are both set, then the ARM will schedule closed loop gain control
+ *  tracking to occur in the radioOn ARM state.
+ *
+ *  A AD9373 device is required for this feature to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->tx->dpdConfig
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param tx1Enable 0=disable CLGC Tx1 tracking, 1= enable CLGC Tx1 tracking
+ * \param tx2Enable 0=disable CLGC Tx2 tracking, 1= enable CLGC Tx2 tracking
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR ARM is not in the RadioOff state, call MYKONOS_radioOff()
+ */
+static mykonosErr_t enableClgcTracking(mykonosDevice_t *device, uint8_t tx1Enable, uint8_t tx2Enable)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t enableBit[4] = {0};
+    uint8_t byteOffset = 4;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_enableClgcTracking()\n");
+#endif
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR));
+        return MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR;
+    }
+
+    enableBit[0] = (tx1Enable > 0) ? 1 : 0;
+    enableBit[1] = 0;
+    enableBit[2] = (tx2Enable > 0) ? 1 : 0;
+    enableBit[3] = 0;
+
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_CLGCCONFIG, byteOffset, &enableBit[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function updates the CLGC desired gain parameter.
+ *
+ *  This function can be called in either Radio On or Off state.
+ *
+ * \pre A AD9373 device is required for CLGC to be enabled. CLGC init cal has been run and CLGC tracking enable.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *  \param txChannel Desired Transmit channel to set the (Valid ENUM values: TX1 or TX2 only)
+ * \param gain Total gain and attenuation (dB * 100) for the selected channel txChannel
+ *
+ * \retval MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL ERROR: Tx channel is not valid (Valid ENUM values: TX1 or TX2 only)
+ * \retval MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG ERROR: ARM command flag error set
+ * \retval MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN ERROR: CLGC gain parameter is out of range, valid range is from -10000 to 10000.
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_setClgcGain(mykonosDevice_t *device, mykonosTxChannels_t txChannel, int16_t gain)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t timeoutMs = 1000;
+    uint8_t extData[4] = {0};
+    uint8_t clcgChannel = 0x00;
+    uint8_t cmdStatusByte = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_setClgcGain()\n");
+#endif
+
+    /* Range check for desired gain parameter */
+    if ((gain < -10000) || (gain > 10000))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN,
+                getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN));
+        return MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN;
+    }
+
+    switch (txChannel)
+    {
+        case TX1:
+            clcgChannel = SET_CLGC_DESIRED_GAIN_1;
+            break;
+        case TX2:
+            clcgChannel = SET_CLGC_DESIRED_GAIN_2;
+            break;
+
+        default:
+            /* this function allow single channel gain only */
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL));
+            return MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL;
+    }
+
+    extData[0] = MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL;
+    extData[1] = clcgChannel;
+    extData[2] = (gain & 0xFF);
+    extData[3] = ((gain >> 8) & 0xFF);
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* check for completion */
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG));
+            return MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG));
+        return MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function, when called during RadioOff, will configure VSWR settings
+ *
+ *  A AD9373 device is required for VSWR to be enabled.  The VSWR has several user
+ *  adjustable settings that can be configured before running the runInitCals
+ *  with the calMask set for the VSWR init cal. Call this function with desired
+ *  settings set before running the VSWR init cal or enabling VSWR tracking.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->vswrConfig (All members)
+ *
+ * \retval MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV ERROR: Tx and ObsRx profiles must be valid to use the VSWR feature
+ * \retval MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT ERROR: CLGC config structure pointer is null in device->tx->clgcConfig
+ * \retval MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR ERROR: ARM is not in the IDLE(radioOff) or Ready state.
+ */
+mykonosErr_t MYKONOS_configVswr(mykonosDevice_t *device)
+{
+    uint32_t radioStatus = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t armFieldValue[16] = {0};
+    uint8_t byteOffset = 0;
+    uint16_t negPnLevel = 0;
+    const uint8_t ENABLE_VSWR = 1;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_configVswr()\n");
+#endif
+
+    /* VSWR requires Tx and ORx enabled, throw error if both are not enabled */
+    if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV));
+        return MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV;
+    }
+
+    if (device->tx->vswrConfig == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT));
+        return MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT;
+    }
+
+    /* read radio state to make sure ARM is in radioOff /IDLE */
+    retVal = MYKONOS_getRadioState(device, &radioStatus);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    if (((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_IDLE) && ((radioStatus & 0x03) != MYKONOS_ARM_SYSTEMSTATE_READY))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR));
+        return MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR;
+    }
+
+    /* range check valid 3p3 GPIO pin */
+    if ((device->tx->vswrConfig->tx1VswrSwitchGpio3p3Pin > 11) || (device->tx->vswrConfig->tx2VswrSwitchGpio3p3Pin > 11))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN));
+        return MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN;
+    }
+
+    armFieldValue[0] = ENABLE_VSWR;
+    armFieldValue[1] = 0;
+    armFieldValue[2] = ENABLE_VSWR;
+    armFieldValue[3] = 0;
+    armFieldValue[4] = (device->tx->vswrConfig->tx1VswrSwitchGpio3p3Pin & 0xFF);
+    armFieldValue[5] = 0;
+    armFieldValue[6] = (device->tx->vswrConfig->tx2VswrSwitchGpio3p3Pin & 0xFF);
+    armFieldValue[7] = 0;
+    armFieldValue[8] = (device->tx->vswrConfig->tx1VswrSwitchPolarity > 0) ? 1 : 0;
+    armFieldValue[9] = 0;
+    armFieldValue[10] = (device->tx->vswrConfig->tx2VswrSwitchPolarity > 0) ? 1 : 0;
+    armFieldValue[11] = 0;
+    armFieldValue[12] = device->tx->vswrConfig->tx1VswrSwitchDelay_ms; /* support full 0 to 255 ms range */
+    armFieldValue[13] = 0;
+    armFieldValue[14] = device->tx->vswrConfig->tx2VswrSwitchDelay_ms; /* support full 0 to 255 ms range */
+    armFieldValue[15] = 0;
+    byteOffset = 0;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRCONFIG, byteOffset, &armFieldValue[0], 16);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* set VSWR additional delay offset parameter (init cal)*/
+    if ((device->tx->vswrConfig->additionalDelayOffset < -64) || (device->tx->vswrConfig->additionalDelayOffset > 64))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY));
+        return MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY;
+    }
+
+    armFieldValue[0] = (device->tx->vswrConfig->additionalDelayOffset & 0xFF);
+    armFieldValue[1] = ((device->tx->vswrConfig->additionalDelayOffset >> 8) & 0xFF);
+    byteOffset = 2;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armFieldValue[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    if ((device->tx->vswrConfig->pathDelayPnSeqLevel < 1) || (device->tx->vswrConfig->pathDelayPnSeqLevel > 8191))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL,
+                getMykonosErrorMessage(MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL));
+        return MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL;
+    }
+
+    /* Set Path Delay PN sequence amplitude - positive and negative (init cal)*/
+    armFieldValue[0] = (device->tx->vswrConfig->pathDelayPnSeqLevel & 0xFF);
+    armFieldValue[1] = ((device->tx->vswrConfig->pathDelayPnSeqLevel >> 8) & 0xFF);
+
+    negPnLevel = ((~device->tx->vswrConfig->pathDelayPnSeqLevel) + 1); /* times -1 */
+    armFieldValue[2] = (negPnLevel & 0xFF);
+    armFieldValue[3] = (((negPnLevel) >> 8) & 0xFF);
+    byteOffset = 10;
+    /* Set for Tx1 channel */
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    /* Set for Tx2 channel */
+    byteOffset = 30;
+    retVal = MYKONOS_writeArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armFieldValue[0], 4);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/* \brief Reads the VSWR config structure from ARM memory
+ *
+ *  This function reads the VSWR structure
+ *  from ARM memory and returns in the device->tx->vswrConfig structure.
+ *
+ *  A AD9373 device is required for VSWR to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->profilesValid
+ * - device->tx->vswrConfig (All members)
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV Error: Tx and ORx profiles must be valid for VSWR functions
+ * \retval MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT Error: NULL pointer to device->tx->vswrConfig structure
+ */
+mykonosErr_t MYKONOS_getVswrConfig(mykonosDevice_t *device)
+{
+    uint16_t byteOffset = 0;
+    uint8_t armMem[12] = {0};
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getVswrConfig()\n");
+#endif
+
+    /* VSWR requires Tx and ORx enabled, throw error if both are not enabled */
+    if ((device->profilesValid & (TX_PROFILE_VALID | ORX_PROFILE_VALID)) != (TX_PROFILE_VALID | ORX_PROFILE_VALID))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV,
+                getMykonosErrorMessage(MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV));
+        return MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV;
+    }
+
+    if (device->tx->vswrConfig == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT));
+        return MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT;
+    }
+
+    byteOffset = 4;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRCONFIG, byteOffset, &armMem[0], sizeof(armMem));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->vswrConfig->tx1VswrSwitchGpio3p3Pin = armMem[0];
+    device->tx->vswrConfig->tx2VswrSwitchGpio3p3Pin = armMem[2];
+    device->tx->vswrConfig->tx1VswrSwitchPolarity = armMem[4];
+    device->tx->vswrConfig->tx2VswrSwitchPolarity = armMem[6];
+    device->tx->vswrConfig->tx1VswrSwitchDelay_ms = armMem[8];
+    device->tx->vswrConfig->tx2VswrSwitchDelay_ms = armMem[10];
+
+    byteOffset = 2;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armMem[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->vswrConfig->additionalDelayOffset = (int16_t)(((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+
+    byteOffset = 10;
+    retVal = MYKONOS_readArmConfig(device, MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG, byteOffset, &armMem[0], 2);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    device->tx->vswrConfig->pathDelayPnSeqLevel = (((uint16_t)(armMem[1]) << 8) | (uint16_t)(armMem[0]));
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief This function reads the VSWR calibration status from the Mykonos ARM processor.
+ *
+ * The VSWR Status is read back from the ARM processor and
+ * returned in the function parameter vswrStatus.
+ *
+ * A AD9373 device is required for this feature to be enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param txChannel Desired Transmit channel to read back VSWR status for (Valid ENUM values: TX1 or TX2 only)
+ * \param vswrStatus Pointer to a structure to return the status information to
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM vswrStatus function parameter is a NULL pointer
+ * \retval MYKONOS_ERR_GETVSWRSTATUS_INV_CH txChannel parameter is a non supported value.
+ * \retval MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG ARM reported an error while processing the GET ARM command
+ */
+mykonosErr_t MYKONOS_getVswrStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosVswrStatus_t *vswrStatus)
+{
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_CAL_STATUS, MYKONOS_ARM_OBJECTID_VSWRCONFIG, 0};
+    uint8_t armData[64] = {0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    uint32_t offset = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t channelSelect = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_getVswrStatus()\n");
+#endif
+
+    if (vswrStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM,
+                getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM));
+        return MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM;
+    }
+
+    switch (txChannel)
+    {
+        case TX1:
+            channelSelect = 0;
+            break;
+        case TX2:
+            channelSelect = 1;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_INV_CH,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_INV_CH));
+            return MYKONOS_ERR_GETVSWRSTATUS_INV_CH;
+        }
+    }
+
+    extData[2] = channelSelect;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_GET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    timeoutMs = 1000;
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_GET_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        /* throw more specific error message instead of returning error code from waitArmCmdStatus */
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG));
+            return MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG));
+        return MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG;
+    }
+
+    /* read status from ARM memory */
+    offset = 0;
+    retVal = MYKONOS_readArmMem(device, (MYKONOS_ADDR_ARM_START_DATA_ADDR + offset), &armData[0], sizeof(armData), 1);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    vswrStatus->errorStatus = ((uint32_t)(armData[3]) << 24) | ((uint32_t)(armData[2]) << 16) | ((uint32_t)(armData[1]) << 8) | (uint32_t)(armData[0]);
+    vswrStatus->forwardGainRms_dB =
+            (int32_t)(((uint32_t)(armData[23]) << 24) | ((uint32_t)(armData[22]) << 16) | ((uint32_t)(armData[21]) << 8) | (uint32_t)(armData[20]));
+    vswrStatus->forwardGainReal = (int32_t)(((uint32_t)(armData[27]) << 24) | ((uint32_t)(armData[26]) << 16) | ((uint32_t)(armData[25]) << 8) | (uint32_t)(armData[24]));
+    vswrStatus->forwardGainImag = (int32_t)(((uint32_t)(armData[31]) << 24) | ((uint32_t)(armData[30]) << 16) | ((uint32_t)(armData[29]) << 8) | (uint32_t)(armData[28]));
+    vswrStatus->reflectedGainRms_dB = (int32_t)(((uint32_t)(armData[35]) << 24) | ((uint32_t)(armData[34]) << 16) | ((uint32_t)(armData[33]) << 8)
+            | (uint32_t)(armData[32]));
+    vswrStatus->reflectedGainReal =
+            (int32_t)(((uint32_t)(armData[39]) << 24) | ((uint32_t)(armData[38]) << 16) | ((uint32_t)(armData[37]) << 8) | (uint32_t)(armData[36]));
+    vswrStatus->reflectedGainImag =
+            (int32_t)(((uint32_t)(armData[43]) << 24) | ((uint32_t)(armData[42]) << 16) | ((uint32_t)(armData[41]) << 8) | (uint32_t)(armData[40]));
+    vswrStatus->trackCount = ((uint32_t)(armData[63]) << 24) | ((uint32_t)(armData[62]) << 16) | ((uint32_t)(armData[61]) << 8) | (uint32_t)(armData[60]);
+    vswrStatus->vswr_forward_tx_rms = ((uint32_t)(armData[47]) << 24) | ((uint32_t)(armData[46]) << 16) | ((uint32_t)(armData[45]) << 8) | (uint32_t)(armData[44]);
+    vswrStatus->vswr_forward_orx_rms = ((uint32_t)(armData[51]) << 24) | ((uint32_t)(armData[50]) << 16) | ((uint32_t)(armData[49]) << 8) | (uint32_t)(armData[48]);
+    vswrStatus->vswr_reflection_tx_rms = ((uint32_t)(armData[55]) << 24) | ((uint32_t)(armData[54]) << 16) | ((uint32_t)(armData[53]) << 8) | (uint32_t)(armData[52]);
+    vswrStatus->vswr_reflection_orx_rms = ((uint32_t)(armData[59]) << 24) | ((uint32_t)(armData[58]) << 16) | ((uint32_t)(armData[57]) << 8) | (uint32_t)(armData[56]);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Read from the Mykonos ARM program or data memory
+ *
+ * Valid memory addresses are: Program Memory (0x01000000 - 0x01017FFF),
+ * Data Memory (0x20000000 - 0x2000FFFF)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param address The 32bit ARM address to read from.
+ * \param returnData Byte(uint8_t) array containing the data read from the ARM memory.
+ * \param bytesToRead Number of bytes in the returnData array.
+ * \param autoIncrement is boolean flag to enable or disable autoincrement of ARM register address
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READARMMEM_INV_ADDR_PARM ARM memory address is out of range
+ *
+ */
+mykonosErr_t MYKONOS_readArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *returnData, uint32_t bytesToRead, uint8_t autoIncrement)
+{
+    uint8_t dataMem;
+    uint32_t i;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readArmMem()\n");
+#endif
+
+    /* check that start and stop address are in valid range */
+    if ((!(address >= MYKONOS_ADDR_ARM_START_PROG_ADDR && address <= MYKONOS_ADDR_ARM_END_PROG_ADDR))
+            && !(address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMMEM_INV_ADDR_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_READARMMEM_INV_ADDR_PARM));
+        return MYKONOS_ERR_READARMMEM_INV_ADDR_PARM;
+    }
+
+    if ((!(((address + bytesToRead - 1) >= MYKONOS_ADDR_ARM_START_PROG_ADDR) && (address + bytesToRead - 1) <= MYKONOS_ADDR_ARM_END_PROG_ADDR))
+            && (!(((address + bytesToRead - 1) >= MYKONOS_ADDR_ARM_START_DATA_ADDR) && (address + bytesToRead - 1) <= MYKONOS_ADDR_ARM_END_DATA_ADDR)))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMMEM_INV_ADDR_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_READARMMEM_INV_ADDR_PARM));
+        return MYKONOS_ERR_READARMMEM_INV_ADDR_PARM;
+    }
+
+    if (address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR)
+    {
+        dataMem = 1;
+    }
+    else
+    {
+        dataMem = 0;
+    }
+
+    /* NOT assuming auto increment bit is already set from MYKONOS_initARM function call */
+    /* setting auto increment address bit if autoIncrement evaluates true */
+    if (autoIncrement)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x01, 0x04, 2);
+    }
+    else
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x00, 0x04, 2);
+    }
+
+    /* setting up for ARM read */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x01, 0x20, 5);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)((address) >> 2)); /* write address[9:2] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, (uint8_t)(address >> 10) | (dataMem << 7)); /* write address[15:10] */
+
+    /* start read-back at correct byte offset */
+    /* read data is located at SPI address 0xD04=data[7:0], 0xD05=data[15:8], 0xD06=data[23:16], 0xD07=data[31:24]. */
+    /* with address auto increment set, after xD07 is read, the address will automatically increment */
+    /* without address auto increment set, 0x4 must be added to the address for correct indexing */
+    if (autoIncrement)
+    {
+        for (i = 0; i < bytesToRead; i++)
+        {
+            CMB_SPIReadByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), &returnData[i]);
+        }
+    }
+    else
+    {
+        for (i = 0; i < bytesToRead; i++)
+        {
+            CMB_SPIReadByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), &returnData[i]);
+
+            if ((MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)) == MYKONOS_ADDR_ARM_DATA_BYTE_3)
+            {
+                CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)(((address + 0x4) & 0x3FF) >> 2));
+                CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, ((address + 0x4) & 0x1FC00U) >> 10 | (dataMem << 7));
+            }
+        }
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Write to the Mykonos ARM program or data memory
+ *
+ * Valid memory addresses are: Program Memory (0x01000000 - 0x01017FFF),
+ * Data Memory (0x20000000 - 0x2000FFFF)
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param address The 32bit ARM address to write to.
+ * \param data Byte(uint8_t) array containing the data to write to the ARM memory.
+ * \param byteCount Number of bytes in the data array.
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_WRITEARMMEM_NULL_PARM Function parameter data has NULL pointer when byteCount is >0
+ * \retval MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM ARM memory address is out of range of valid ARM memory
+ */
+mykonosErr_t MYKONOS_writeArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *data, uint32_t byteCount)
+{
+    /* write address, then data with auto increment enabled. */
+    uint8_t dataMem;
+    uint32_t i;
+
+#if MYK_ENABLE_SPIWRITEARRAY == 1
+    uint32_t addrIndex = 0;
+    uint32_t dataIndex = 0;
+    uint32_t spiBufferSize = MYK_SPIWRITEARRAY_BUFFERSIZE;
+    uint16_t addrArray[MYK_SPIWRITEARRAY_BUFFERSIZE] = {0};
+#endif
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_writeArmMem()\n");
+#endif
+
+    if ((data == NULL) && (byteCount > 0))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMMEM_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_WRITEARMMEM_NULL_PARM));
+        return MYKONOS_ERR_WRITEARMMEM_NULL_PARM;
+    }
+
+    if ((!(address >= MYKONOS_ADDR_ARM_START_PROG_ADDR && address <= MYKONOS_ADDR_ARM_END_PROG_ADDR))
+            && !(address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM));
+        return MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM;
+    }
+
+    if ((!(((address + byteCount - 1) >= MYKONOS_ADDR_ARM_START_PROG_ADDR) && ((address + byteCount - 1) <= MYKONOS_ADDR_ARM_END_PROG_ADDR)))
+            && (!(((address + byteCount - 1) >= MYKONOS_ADDR_ARM_START_DATA_ADDR) && ((address + byteCount - 1) <= MYKONOS_ADDR_ARM_END_DATA_ADDR))))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM));
+        return MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM;
+    }
+
+    if (address >= MYKONOS_ADDR_ARM_START_DATA_ADDR && address <= MYKONOS_ADDR_ARM_END_DATA_ADDR)
+    {
+        dataMem = 1;
+    }
+    else
+    {
+        dataMem = 0;
+    }
+
+    /* set auto increment address bit */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x01, 0x04, 2);
+
+    /* writing the address */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_ARM_CTL_1, 0x00, 0x20, 5);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_0, (uint8_t)((address) >> 2));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_ADDR_BYTE_1, (uint8_t)(address >> 10) | (dataMem << 7));
+
+    /* start write at correct byte offset */
+    /* write data is located at SPI address 0xD04=data[7:0], 0xD05=data[15:8], 0xD06=data[23:16], 0xD07=data[31:24] */
+    /* with address auto increment set, after x407 is written, the address will automatically increment */
+
+#if (MYK_ENABLE_SPIWRITEARRAY == 0)
+
+    for (i = 0; i < byteCount; i++)
+    {
+        CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4)), data[i]);
+    }
+
+#elif (MYK_ENABLE_SPIWRITEARRAY == 1)
+
+    addrIndex = 0;
+    dataIndex = 0;
+    for (i = 0; i < byteCount; i++)
+    {
+        addrArray[addrIndex++] = (MYKONOS_ADDR_ARM_DATA_BYTE_0 | (((address & 0x3) + i) % 4));
+
+        if (addrIndex == spiBufferSize)
+        {
+            CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &data[dataIndex], addrIndex);
+            dataIndex = dataIndex + addrIndex;
+            addrIndex = 0;
+        }
+    }
+
+    if (addrIndex > 0)
+    {
+        CMB_SPIWriteBytes(device->spiSettings, &addrArray[0], &data[dataIndex], addrIndex);
+    }
+
+#endif
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Low level helper function used by Mykonos API to write the ARM memory config structures
+ *
+ * Normally this function should not be required to be used directly by the BBIC.  This is a helper
+ * function used by other Mykonos API commands to write settings into the ARM memory.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param objectId ARM id of a particular structure or setting in ARM memory
+ * \param offset Byte offset from the start of the objectId's memory location in ARM memory
+ * \param data A byte array containing data to write to the ARM memory buffer.
+ * \param byteCount Number of bytes in the data array (Valid size = 1-255 bytes)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG ARM write config command failed with a nonzero error code
+ */
+mykonosErr_t MYKONOS_writeArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t extendedData[4] = {0}; /* ARM Object id, byte offset LSB, offset MSB = 0, copy 2 bytes */
+    uint32_t timeoutMs = 1000;
+    uint8_t cmdStatusByte = 0;
+
+    retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &data[0], byteCount);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    extendedData[0] = objectId;
+    extendedData[1] = (offset & 0xFF);
+    extendedData[2] = ((offset >> 8) & 0xFF);
+    extendedData[3] = byteCount;
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_WRITECFG_OPCODE, &extendedData[0], sizeof(extendedData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_WRITECFG_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG));
+            return MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG));
+        return MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Low level helper function used by Mykonos API to read the ARM memory config structures
+ *
+ * Normally this function should not be required to be used directly by the BBIC.  This is a helper
+ * function used by other Mykonos API commands to read settings from the ARM memory.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param objectId ARM id of a particular structure or setting in ARM memory
+ * \param offset Byte offset from the start of the objectId's memory location in ARM memory
+ * \param data A byte array containing data to write to the ARM memory buffer.
+ * \param byteCount Number of bytes in the data array (Valid size = 1-255 bytes)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READARMCFG_ARMERRFLAG ARM read config command failed with a nonzero error code
+ */
+mykonosErr_t MYKONOS_readArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount)
+{
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t extendedData[4] = {0}; /* ARM Object id, byte offset LSB, offset MSB = 0, copy 2 bytes */
+    uint32_t timeoutMs = 1000;
+    uint8_t cmdStatusByte = 0;
+    const uint8_t AUTO_INCREMENT = 1;
+    extendedData[0] = objectId;
+    extendedData[1] = (offset & 0xFF);
+    extendedData[2] = ((offset >> 8) & 0xFF);
+    extendedData[3] = byteCount;
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_READCFG_OPCODE, &extendedData[0], sizeof(extendedData));
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_READCFG_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCFG_ARMERRFLAG,
+                    getMykonosErrorMessage(MYKONOS_ERR_READARMCFG_ARMERRFLAG));
+            return MYKONOS_ERR_READARMCFG_ARMERRFLAG;
+        }
+
+        return retVal;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCFG_ARMERRFLAG,
+                getMykonosErrorMessage(MYKONOS_ERR_READARMCFG_ARMERRFLAG));
+        return MYKONOS_ERR_READARMCFG_ARMERRFLAG;
+    }
+
+    retVal = MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &data[0], byteCount, AUTO_INCREMENT);
+    if (retVal != MYKONOS_ERR_OK)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Sends a command to the Mykonos ARM processor
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->spiSettings
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param opCode Value (0-30, even only) indicating the desired function to run in the ARM.
+ * \param extendedData A byte array containing extended data to write to the ARM command interface.
+ * \param extendedDataNumBytes Number of bytes in the extendedData array (Valid size = 0-4 bytes)
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ARMCMD_NULL_PARM Function parameter extendedData is NULL and extendedDataNumBytes is positive
+ * \retval MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM ARM opcode is out of range (valid 0-30, even only)
+ * \retval MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM Number of extended bytes parameter is out of range (valid 0-4)
+ * \retval MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY ARM control interface is busy, command could not be executed by ARM
+ */
+mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode, uint8_t *extendedData, uint8_t extendedDataNumBytes)
+{
+    uint8_t armCommandBusy = 0;
+    uint8_t i = 0;
+    uint16_t extCmdByteStartAddr = MYKONOS_ADDR_ARM_EXT_CMD_BYTE_1;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_sendArmCommand()\n");
+#endif
+
+    if ((extendedData == NULL) && (extendedDataNumBytes > 0))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMD_NULL_PARM, getMykonosErrorMessage(MYKONOS_ERR_ARMCMD_NULL_PARM));
+        return MYKONOS_ERR_ARMCMD_NULL_PARM;
+    }
+
+    /* check for even-numbered opCodes only including opcode 0, but not must be greater than opCode 30 */
+    if ((opCode != 0) && ((opCode % 2) || (opCode > 30)))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM));
+        return MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM;
+    }
+
+    /* the number of valid extended data bytes is from 0-4 */
+    if (extendedDataNumBytes > 4)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM));
+        return MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM;
+    }
+
+    /* setting a 2 sec timeout for mailbox busy bit to be clear (can't send an arm mailbox command until mailbox is ready) */
+    CMB_setTimeout_ms(2000);
+
+    do
+    {
+        CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_ARM_CMD, &armCommandBusy, 0x80, 7);
+
+        if (CMB_hasTimeoutExpired())
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY,
+                    getMykonosErrorMessage(MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY));
+            return MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY;
+        }
+    } while (armCommandBusy);
+
+    if (extendedDataNumBytes)
+    {
+        for (i = 0; i < extendedDataNumBytes; i++)
+        {
+            CMB_SPIWriteByte(device->spiSettings, extCmdByteStartAddr + i, extendedData[i]);
+        }
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_ARM_CMD, opCode);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Reads the Mykonos ARM 64-bit command status register
+ *
+ * A 64-bit status register consisting of a pending bit and three-bit error type is read one byte at
+ * a time for opcodes 0-30. The function parses the pending bits and error bits into
+ * two (2) separate 16-bit words containing pending bits, and error bits if the error type > 0
+ * The words are weighted according to each even-numbered opcode from 0-30,
+ * where, 0x0001 = opcode '0', 0x0002 = opcode '2', 0x0004 = opcode '4', 0x0008 = opcode '6' and so on.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param errorWord 16-bit error word comprised of weighted bits according to each opcode number
+ * The weighted bit = '1' if error type > 0, '0' if OK
+ * \param statusWord 16-bit pending bits word comprised of weighted bits according to each opcode number
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM Function parameters errorWord or statusWord have a NULL pointer
+ */
+mykonosErr_t MYKONOS_readArmCmdStatus(mykonosDevice_t *device, uint16_t *errorWord, uint16_t *statusWord)
+{
+    uint8_t i = 0;
+    uint8_t bytes[8] = {0};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readArmCmdStatus()\n");
+#endif
+
+    if (errorWord == NULL || statusWord == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM));
+        return MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM;
+    }
+
+    /* making sure the errorWord and statusWord are clear */
+    *errorWord = 0;
+    *statusWord = 0;
+
+    /* read in the entire 64-bit status register into a byte array for parsing */
+    for (i = 0; i < 8; i++)
+    {
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_CMD_STATUS_0 + i, &bytes[i]);
+    }
+
+    /* parse the byte array for pending bits and error types and generate statusWord and errorWord bits */
+    for (i = 0; i < 8; i++)
+    {
+        *statusWord |= (uint16_t)(((bytes[i] & 0x10) >> 3) | (bytes[i] & 0x01)) << (i * 2);
+
+        if (bytes[i] & 0x0E)
+        {
+            *errorWord |= (0x0001 << (i * 2));
+        }
+        else if (bytes[i] & 0xE0)
+        {
+            *errorWord |= (0x0002 << (i * 2));
+        }
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Isolated byte read of the Mykonos ARM 64-bit command status register based on the opcode
+ *
+ * A single byte read is performed on the 64-bit command status register according to
+ * the opcode of interest. The pending bit and the error type are extracted from the status
+ * register and returned as a single byte in the lower nibble.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param opCode Valid values are even increments from 0-30. The ARM opCode is used to determine which status register byte to read
+ * \param cmdStatByte returns cmdStatByte[3:1] = error type, cmdStatByte[0] = pending flag for selected opCode
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM Function parameter cmdStatByte has NULL pointer
+ * \retval MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM ARM opcode is out of range (valid 0-30, even only)
+ */
+mykonosErr_t MYKONOS_readArmCmdStatusByte(mykonosDevice_t *device, uint8_t opCode, uint8_t *cmdStatByte)
+{
+    uint8_t cmdByteIndex = 0;
+    uint8_t cmdByte = 0;
+
+#if 0
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_readArmCmdStatByte()\n");
+#endif
+#endif
+
+    if (cmdStatByte == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM));
+        return MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM;
+    }
+
+    /* check for even-numbered opCodes only including opcode 0, but not must be greater than opCode 30 */
+    if ((opCode != 0) && ((opCode % 2) || (opCode > 30)))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM));
+        return MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM;
+    }
+    else
+    {
+        cmdByteIndex = (opCode / 4);
+
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_ARM_CMD_STATUS_0 + cmdByteIndex, &cmdByte);
+
+        if ((opCode / 2) % 2)
+        {
+            *cmdStatByte = ((cmdByte >> 4) & 0x0F);
+        }
+        else
+        {
+            *cmdStatByte = (cmdByte & 0x0F);
+        }
+
+        return MYKONOS_ERR_OK;
+    }
+}
+
+/**
+ * \brief Mykonos ARM command status wait function polls command status until opcode completes
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param opCode Valid values are even increments from 0-30. The ARM opCode is used to determine which pending bit to wait for
+ * \param timeoutMs conveys the time-out period in milliseconds
+ * \param cmdStatByte returns cmdStatByte[3:1] = error type, cmdStatByte[0] = pending flag for selected opCode
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM Function parameter cmdStatByte has NULL pointer
+ * \retval MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM Invalid ARM opcode (valid 0-30, even numbers only)
+ * \retval MYKONOS_ERR_ARMCMDSTATUS_ARMERROR ARM Mailbox error flag for requested opcode returned a nonzero error flag
+ * \retval MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT Timeout occurred before ARM command completed
+ */
+mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, uint32_t timeoutMs, uint8_t *cmdStatByte)
+{
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_waitArmCmdStatus()\n");
+#endif
+
+    if (cmdStatByte == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM));
+        return MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM;
+    }
+
+    /* check for even-numbered opCodes only including opcode 0, but not must be greater than opCode 30 */
+    if ((opCode != 0) && ((opCode % 2) || (opCode > 30)))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM,
+                getMykonosErrorMessage(MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM));
+        return MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM;
+    }
+
+    /* start wait */
+    CMB_setTimeout_ms(timeoutMs);
+
+    do
+    {
+        MYKONOS_readArmCmdStatusByte(device, opCode, cmdStatByte);
+
+        /* If error flag is non zero in [3:1], - return error */
+        if ((*cmdStatByte & 0x0E) > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_ARMCMDSTATUS_ARMERROR,
+                    getMykonosErrorMessage(MYKONOS_ERR_ARMCMDSTATUS_ARMERROR));
+            return MYKONOS_ERR_ARMCMDSTATUS_ARMERROR;
+        }
+
+        if (CMB_hasTimeoutExpired())
+        {
+            return MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT;
+        }
+    } while (*cmdStatByte & 0x01);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Mykonos ARM configuration write
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_writeArmProfile(mykonosDevice_t *device)
+{
+    const uint8_t length = 100;
+
+    int32_t i = 0;
+    uint8_t vcoDiv = 0;
+    uint8_t hsDiv = 0;
+    uint16_t channelsEnabled = 0;
+    uint8_t cfgData[100] = {0};
+
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_writeArmConfig()\n");
+#endif
+
+    /* reading in required mykonosDevice_t structure data into array - not pretty but it works */
+    for (i = 0; i < 4; i++)
+    {
+        cfgData[i] = (uint8_t)(((device->clocks->deviceClock_kHz * 1000) >> (i * 8)) & 0x000000FF);
+    }
+
+    for (i = 4; i < 8; i++)
+    {
+        cfgData[i] = (uint8_t)(((device->clocks->clkPllVcoFreq_kHz) >> ((i - 4) * 8)) & 0x000000FF);
+    }
+
+    vcoDiv = (uint8_t)(device->clocks->clkPllVcoDiv);
+    hsDiv = device->clocks->clkPllHsDiv;
+
+    cfgData[8] = vcoDiv; /* uint8_t vco_div */
+    cfgData[9] = hsDiv; /* uint8_t hs_div */
+
+    channelsEnabled |= device->tx->txChannels & 0x03;
+    channelsEnabled |= ((device->rx->rxChannels & 0x03) << 2);
+    if (device->profilesValid & ORX_PROFILE_VALID)
+    {
+        channelsEnabled |= ((device->obsRx->obsRxChannelsEnable & 3) << 4);
+    }
+
+    if (device->profilesValid & SNIFF_PROFILE_VALID)
+    {
+        channelsEnabled |= (((device->obsRx->obsRxChannelsEnable >> 2) & 7) << 6);
+    }
+
+    for (i = 10; i < 12; i++)
+    {
+        cfgData[i] = (uint8_t)((channelsEnabled >> ((i - 10) * 8)) & 0xFF);
+    }
+
+    cfgData[12] = ((device->rx->rxPllUseExternalLo & 0x01) << 1) | (device->tx->txPllUseExternalLo & 0x01);
+    cfgData[13] = 0x00; /* Not used...padding */
+    cfgData[14] = 0x00; /* Not used...padding */
+    cfgData[15] = 0x00; /* Not used...padding */
+
+    if (device->profilesValid & TX_PROFILE_VALID)
+    {
+        /* start of Tx profile data */
+        cfgData[16] = device->tx->txProfile->dacDiv;
+        cfgData[17] = device->tx->txProfile->txFirInterpolation;
+        cfgData[18] = device->tx->txProfile->thb1Interpolation;
+        cfgData[19] = device->tx->txProfile->thb2Interpolation;
+
+        for (i = 20; i < 24; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->tx->txProfile->iqRate_kHz * 1000) >> ((i - 20) * 8)) & 0x000000FF);
+        }
+
+        for (i = 24; i < 28; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->tx->txProfile->primarySigBandwidth_Hz) >> ((i - 24) * 8)) & 0x000000FF);
+        }
+
+        for (i = 28; i < 32; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->tx->txProfile->rfBandwidth_Hz) >> ((i - 28) * 8)) & 0x000000FF);
+        }
+
+        for (i = 32; i < 36; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->tx->txProfile->txDac3dBCorner_kHz) >> ((i - 32) * 8)) & 0x000000FF);
+        }
+
+        for (i = 36; i < 40; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->tx->txProfile->txBbf3dBCorner_kHz * 1000) >> ((i - 36) * 8)) & 0x000000FF);
+        }
+    }
+    else
+    {
+        cfgData[16] = 0;
+        cfgData[17] = 0;
+        cfgData[18] = 0;
+        cfgData[19] = 0;
+        cfgData[20] = 0;
+        cfgData[21] = 0;
+        cfgData[22] = 0;
+        cfgData[23] = 0;
+        cfgData[24] = 0;
+        cfgData[25] = 0;
+        cfgData[26] = 0;
+        cfgData[27] = 0;
+        cfgData[28] = 0;
+        cfgData[29] = 0;
+        cfgData[30] = 0;
+        cfgData[31] = 0;
+        cfgData[32] = 0;
+        cfgData[33] = 0;
+        cfgData[34] = 0;
+        cfgData[35] = 0;
+        cfgData[36] = 0;
+        cfgData[37] = 0;
+        cfgData[38] = 0;
+        cfgData[39] = 0;
+    }
+
+    if (device->profilesValid & RX_PROFILE_VALID)
+    {
+        /* start of Rx profile data */
+        cfgData[40] = device->rx->rxProfile->adcDiv;
+        cfgData[41] = device->rx->rxProfile->rxFirDecimation;
+        cfgData[42] = device->rx->rxProfile->rxDec5Decimation;
+        cfgData[43] = device->rx->rxProfile->rhb1Decimation;
+
+        for (i = 44; i < 48; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->rx->rxProfile->iqRate_kHz * 1000) >> ((i - 44) * 8)) & 0x000000FF);
+        }
+
+        for (i = 48; i < 52; i++)
+        {
+            /* sig bw placeholder */
+            cfgData[i] = (uint8_t)(((device->rx->rxProfile->rfBandwidth_Hz) >> ((i - 48) * 8)) & 0x000000FF);
+        }
+
+        for (i = 52; i < 56; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->rx->rxProfile->rfBandwidth_Hz) >> ((i - 52) * 8)) & 0x000000FF);
+        }
+
+        for (i = 56; i < 60; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->rx->rxProfile->rxBbf3dBCorner_kHz * 1000) >> ((i - 56) * 8)) & 0x000000FF);
+        }
+    }
+    else
+    {
+        cfgData[40] = 0;
+        cfgData[41] = 0;
+        cfgData[42] = 0;
+        cfgData[43] = 0;
+        cfgData[44] = 0;
+        cfgData[45] = 0;
+        cfgData[46] = 0;
+        cfgData[47] = 0;
+        cfgData[48] = 0;
+        cfgData[49] = 0;
+        cfgData[50] = 0;
+        cfgData[51] = 0;
+        cfgData[52] = 0;
+        cfgData[53] = 0;
+        cfgData[54] = 0;
+        cfgData[55] = 0;
+        cfgData[56] = 0;
+        cfgData[57] = 0;
+        cfgData[58] = 0;
+        cfgData[59] = 0;
+    }
+
+    if (device->profilesValid & ORX_PROFILE_VALID)
+    {
+        /* start of ObsRx profile data */
+        cfgData[60] = device->obsRx->orxProfile->adcDiv;
+        cfgData[61] = device->obsRx->orxProfile->rxFirDecimation;
+        cfgData[62] = device->obsRx->orxProfile->rxDec5Decimation;
+        cfgData[63] = device->obsRx->orxProfile->rhb1Decimation;
+
+        for (i = 64; i < 68; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->iqRate_kHz * 1000) >> ((i - 64) * 8)) & 0x000000FF);
+        }
+
+        for (i = 68; i < 72; i++)
+        {
+            /* sig bw placeholder */
+            cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->rfBandwidth_Hz) >> ((i - 68) * 8)) & 0x000000FF);
+        }
+
+        for (i = 72; i < 76; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->rfBandwidth_Hz) >> ((i - 72) * 8)) & 0x000000FF);
+        }
+
+        for (i = 76; i < 80; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->obsRx->orxProfile->rxBbf3dBCorner_kHz * 1000) >> ((i - 76) * 8)) & 0x000000FF);
+        }
+    }
+    else
+    {
+        cfgData[60] = 0;
+        cfgData[61] = 0;
+        cfgData[62] = 0;
+        cfgData[63] = 0;
+        cfgData[64] = 0;
+        cfgData[65] = 0;
+        cfgData[66] = 0;
+        cfgData[67] = 0;
+        cfgData[68] = 0;
+        cfgData[69] = 0;
+        cfgData[70] = 0;
+        cfgData[71] = 0;
+        cfgData[72] = 0;
+        cfgData[73] = 0;
+        cfgData[74] = 0;
+        cfgData[75] = 0;
+        cfgData[76] = 0;
+        cfgData[77] = 0;
+        cfgData[78] = 0;
+        cfgData[79] = 0;
+    }
+
+    if (device->profilesValid & SNIFF_PROFILE_VALID)
+    {
+        /* start of SnRx profile data */
+        cfgData[80] = device->obsRx->snifferProfile->adcDiv;
+        cfgData[81] = device->obsRx->snifferProfile->rxFirDecimation;
+        cfgData[82] = device->obsRx->snifferProfile->rxDec5Decimation;
+        cfgData[83] = device->obsRx->snifferProfile->rhb1Decimation;
+
+        for (i = 84; i < 88; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->iqRate_kHz * 1000) >> ((i - 84) * 8)) & 0x000000FF);
+        }
+
+        for (i = 88; i < 92; i++)
+        {
+            /* sig bw placeholder */
+            cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->rfBandwidth_Hz) >> ((i - 88) * 8)) & 0x000000FF);
+        }
+
+        for (i = 92; i < 96; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->rfBandwidth_Hz) >> ((i - 92) * 8)) & 0x000000FF);
+        }
+
+        for (i = 96; i < 100; i++)
+        {
+            cfgData[i] = (uint8_t)(((device->obsRx->snifferProfile->rxBbf3dBCorner_kHz * 1000) >> ((i - 96) * 8)) & 0x000000FF);
+        }
+    }
+    else
+    {
+        cfgData[80] = 0;
+        cfgData[81] = 0;
+        cfgData[82] = 0;
+        cfgData[83] = 0;
+        cfgData[84] = 0;
+        cfgData[85] = 0;
+        cfgData[86] = 0;
+        cfgData[87] = 0;
+        cfgData[88] = 0;
+        cfgData[89] = 0;
+        cfgData[90] = 0;
+        cfgData[91] = 0;
+        cfgData[92] = 0;
+        cfgData[93] = 0;
+        cfgData[94] = 0;
+        cfgData[95] = 0;
+        cfgData[96] = 0;
+        cfgData[97] = 0;
+        cfgData[98] = 0;
+        cfgData[99] = 0;
+    }
+
+    /* writing to the ARM memory with the array data */
+    retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &cfgData[0], length);
+    if (retVal)
+    {
+        return retVal;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Function called automatically that loads the ADC profiles into the ARM
+ *
+ * User should not need to call this function normally.  It is called automatically
+ * during MYKONOS_initArm() to load the ADC profiles (tunes the ADC performance).
+ *
+ * Rx ADC profile is only loaded if the Rx Profile is valid, ORx ADC profile is
+ * only loaded if the ORx Profile is valid. Sniffer ADC profile is only loaded
+ * if the Sniffer profile is valid.  The Loopback ADC profile is always
+ * loaded.  If Tx profile is valid, the loopback ADC profile is chosen based
+ * on the Tx Primary Signal bandwidth.  If no valid Tx Profile, the Rx profile
+ * is used to set the Loopback ADC profile.  Else, ORx, then sniffer profiles
+ * are used to set the loopback ADC profile.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV Mykonos CLKPLL has invalid VCO divider in the clocks structure
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE When Tx Profile used, a matching ORx Profile must be provided with a valid ADC divider.
+ *                                                         The ORx digital filters and clock dividers are used with the Loopback Rx path for Tx calibrations.
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED ADC Profile Lookup table does not have a match
+ *                                                       for current Rx Profile settings.  Custom ADC profile required
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED ADC Profile Lookup table does not have a match
+ *                                                        for current ORx Profile settings.  Custom ADC profile required
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED ADC Profile Lookup table does not have a match
+ *                                                         for current Sniffer Rx Profile settings.  Custom ADC profile required
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED ADC Profile Lookup table does not have a match
+ *                                                       for Loopback passband BW and ADC Clock frequency settings.  Custom ADC profile required
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO Rx Profile has invalid ADC divider = 0, causing a divide by zero error
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO ORx profile has invalid ADC divider = 0, causing a divide by zero error
+ * \retval MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO Sniffer profile has invalid ADC divider = 0, causing a divide by zero error
+ * \retval MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED Error returned while trying to write Rx ADC profile to ARM memory
+ * \retval MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED Error returned while trying to write ORx ADC profile to ARM memory
+ * \retval MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED Error returned while trying to write Sniffer ADC profile into ARM memory
+ * \retval MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED Error returned while trying to write Loopback ADC profile into ARM memory
+ */
+mykonosErr_t MYKONOS_loadAdcProfiles(mykonosDevice_t *device)
+{
+    uint8_t adcProfile[32] = {0};
+    uint8_t i = 0;
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint32_t hsDigClk_MHz = 0;
+    uint32_t adcClk_MHz = 0;
+    uint32_t vcoDiv = 0;
+    uint32_t vcoDivTimes10 = 10;
+    uint8_t profileIndex = 0;
+    const uint8_t ARM_CONFIG_OFFSET = 100; /* number of bytes written in MYKONOS_writeArmProfile() to ARM memory */
+
+    const uint8_t NUM_ADCPROFILE_COEFS = 16;
+    const uint8_t NUM_ADC_PROFILES = 20;
+    static const uint16_t adcProfileLut[20][18] = {
+        /* Max RFBW, ADCCLK_MHz, adcProfile[16] */
+        { 20,  491, 1494, 564, 201,  98, 1280, 134,  945,  40,  529,  10,  326, 39, 30, 16,  9, 201},
+        { 60,  983,  712, 462, 201,  98, 1280, 291, 1541, 149, 1054,  46,  645, 34, 48, 32, 18, 193},
+        { 75,  983,  680, 477, 201,  98, 1280, 438, 1577, 242, 1046,  73,  636, 30, 48, 31, 18, 192},
+        {100,  983,  655, 446, 201,  98, 1280, 336, 1631, 334, 1152, 207,  733, 33, 48, 32, 21, 212},
+        { 75, 1228,  569, 369, 201,  98, 1280, 291, 1541, 149, 1320,  58,  807, 34, 48, 40, 23, 189},
+        {100, 1228,  534, 386, 201,  98, 1280, 491, 1591, 279, 1306, 104,  792, 28, 48, 39, 23, 187},
+        {160, 1228,  491, 375, 201,  98, 1280, 514, 1728, 570, 1455, 443,  882, 27, 48, 39, 25, 205},
+        {200, 1228,  450, 349, 201,  98, 1280, 730, 1626, 818, 1476, 732,  834, 20, 41, 36, 24, 200},
+        { 80, 1250,  555, 365, 201,  98, 1280, 317, 1547, 165, 1341,  65,  819, 33, 48, 40, 24, 188},
+        {102, 1250,  524, 379, 201,  98, 1280, 494, 1592, 281, 1328, 107,  805, 28, 48, 40, 23, 187},
+        { 80, 1333,  526, 339, 201,  98, 1280, 281, 1539, 143, 1433,  60,  877, 35, 48, 43, 25, 188},
+        {217, 1333,  414, 321, 201,  98, 1280, 730, 1626, 818, 1603, 794,  905, 20, 41, 40, 26, 199},
+        { 75, 1474,  486, 302, 199,  98, 1280, 206, 1523, 101, 1578,  47,  977, 37, 48, 48, 28, 186},
+        {100, 1474,  465, 311, 201,  98, 1280, 353, 1556, 187, 1581,  86,  964, 32, 48, 47, 28, 185},
+        {150, 1474,  436, 296, 190,  98, 1280, 336, 1631, 334, 1638, 293, 1102, 33, 48, 46, 31, 205},
+        { 40, 1536,  479, 285, 190,  98, 1280, 112, 1505,  53, 1574,  25, 1026, 40, 48, 48, 29, 186},
+        {100, 1536,  450, 297, 193,  98, 1280, 328, 1550, 171, 1586,  79, 1006, 33, 48, 48, 29, 184},
+        {150, 1536,  421, 283, 182,  98, 1280, 313, 1620, 306, 1638, 269, 1153, 34, 48, 46, 33, 204},
+        {200, 1536,  392, 299, 180,  98, 1280, 514, 1728, 570, 1638, 498, 1104, 27, 48, 44, 32, 200},
+        {240, 1536,  366, 301, 178,  98, 1280, 686, 1755, 818, 1638, 742, 1056, 22, 45, 41, 31, 196}};
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_loadAdcProfiles\n");
+#endif
+
+    vcoDiv = device->clocks->clkPllVcoDiv;
+    switch (vcoDiv)
+    {
+        case VCODIV_1:
+            vcoDivTimes10 = 10;
+            break;
+        case VCODIV_1p5:
+            vcoDivTimes10 = 15;
+            break;
+        case VCODIV_2:
+            vcoDivTimes10 = 20;
+            break;
+        case VCODIV_3:
+            vcoDivTimes10 = 30;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV,
+                    getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV));
+            return MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV;
+        }
+    }
+
+    hsDigClk_MHz = device->clocks->clkPllVcoFreq_kHz / vcoDivTimes10 / 100 / device->clocks->clkPllHsDiv;
+
+    /* If Tx Profile is valid, set loopback ADC profile based on Tx primary signal BW */
+    if ((device->profilesValid & TX_PROFILE_VALID) > 0)
+    {
+        /* If custom profile, load it */
+        if (device->obsRx->customLoopbackAdcProfile != NULL)
+        {
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = device->obsRx->customLoopbackAdcProfile[i] & 0xFF;
+                adcProfile[i * 2 + 1] = (device->obsRx->customLoopbackAdcProfile[i] >> 8) & 0xFF;
+            }
+        }
+        else
+        {
+            /* Tx requires ORx profile is configured */
+            if (((device->profilesValid & TX_PROFILE_VALID) > 0) && ((device->profilesValid & ORX_PROFILE_VALID) == 0))
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE;
+            }
+
+            if (device->obsRx->orxProfile->adcDiv == 0)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO;
+            }
+
+            adcClk_MHz = hsDigClk_MHz / device->obsRx->orxProfile->adcDiv;
+
+            /* find correct ADC profile in the LUT */
+            profileIndex = NUM_ADC_PROFILES;
+            for (i = 0; i < NUM_ADC_PROFILES; i++)
+            {
+                /* Find a row in the LUT that matches the ADC clock frequency */
+                if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->tx->txProfile->primarySigBandwidth_Hz / 1000000)))
+                {
+                    profileIndex = i;
+                    break;
+                }
+            }
+
+            /* Verify that a profile was found in the LUT, if not return error */
+            /* In this case a custom profile would need to be passed in */
+            if (profileIndex >= NUM_ADC_PROFILES)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED;
+            }
+
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF;
+                adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF;
+            }
+        }
+
+        /* writing to the ARM memory: Set Loopback ADC Profile based on Tx Primary signal Bandwidth */
+        retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile));
+        if (retVal)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED));
+            return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED;
+        }
+    }
+
+    if ((device->profilesValid & RX_PROFILE_VALID) > 0)
+    {
+        /* If custom profile, load it */
+        if (device->rx->rxProfile->customAdcProfile != NULL)
+        {
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = device->rx->rxProfile->customAdcProfile[i] & 0xFF;
+                adcProfile[i * 2 + 1] = (device->rx->rxProfile->customAdcProfile[i] >> 8) & 0xFF;
+            }
+        }
+        else
+        {
+            if (device->rx->rxProfile->adcDiv == 0)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO;
+            }
+
+            adcClk_MHz = hsDigClk_MHz / device->rx->rxProfile->adcDiv;
+
+            /* find correct ADC profile in the LUT */
+            profileIndex = NUM_ADC_PROFILES;
+            for (i = 0; i < NUM_ADC_PROFILES; i++)
+            {
+                /* Find a row in the LUT that matches the ADC clock frequency */
+                if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->rx->rxProfile->rfBandwidth_Hz / 1000000)))
+                {
+                    profileIndex = i;
+                    break;
+                }
+            }
+
+            /* Verify that a profile was found in the LUT, if not return error */
+            /* In this case a custom profile would need to be passed in */
+            if (profileIndex >= NUM_ADC_PROFILES)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED;
+            }
+
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF;
+                adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF;
+            }
+        }
+
+        /* writing to the ARM memory with ADC Profile for Rx path */
+        retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET, &adcProfile[0], sizeof(adcProfile));
+        if (retVal)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED));
+            return MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED;
+        }
+
+        /* writing to the ARM memory: Set Loopback ADC Profile = Rx ADC Profile ONLY if Tx profile is not valid */
+        if ((device->profilesValid & TX_PROFILE_VALID) == 0)
+        {
+            retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile));
+            if (retVal)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED));
+                return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED;
+            }
+        }
+    }
+
+    if ((device->profilesValid & ORX_PROFILE_VALID) > 0)
+    {
+        /* If custom profile, load it */
+        if (device->obsRx->orxProfile->customAdcProfile != NULL)
+        {
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = device->obsRx->orxProfile->customAdcProfile[i] & 0xFF;
+                adcProfile[i * 2 + 1] = (device->obsRx->orxProfile->customAdcProfile[i] >> 8) & 0xFF;
+            }
+        }
+        else
+        {
+            if (device->obsRx->orxProfile->adcDiv == 0)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO;
+            }
+
+            adcClk_MHz = hsDigClk_MHz / device->obsRx->orxProfile->adcDiv;
+
+            /* find correct ADC profile in the LUT */
+            profileIndex = NUM_ADC_PROFILES;
+            for (i = 0; i < NUM_ADC_PROFILES; i++)
+            {
+                /* Find a row in the LUT that matches the ADC clock frequency */
+                if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->obsRx->orxProfile->rfBandwidth_Hz / 1000000)))
+                {
+                    profileIndex = i;
+                    break;
+                }
+            }
+
+            /* Verify that a profile was found in the LUT, if not return error */
+            /* In this case a custom profile would need to be passed in */
+            if (profileIndex >= NUM_ADC_PROFILES)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED;
+            }
+
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF;
+                adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF;
+            }
+        }
+
+        /* writing to the ARM memory with ADC Profile for ORx path */
+        retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 32, &adcProfile[0], sizeof(adcProfile));
+        if (retVal)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED));
+            return MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED;
+        }
+
+        /* If Rx and Tx Profiles are not valid, set Loopback ADC profile to ORx ADC Profile */
+        if (((device->profilesValid & TX_PROFILE_VALID) == 0) && ((device->profilesValid & RX_PROFILE_VALID) == 0))
+        {
+            retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile));
+            if (retVal)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED));
+                return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED;
+            }
+        }
+    }
+
+    if ((device->profilesValid & SNIFF_PROFILE_VALID) > 0)
+    {
+        /* If custom profile, load it */
+        if (device->obsRx->snifferProfile->customAdcProfile != NULL)
+        {
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = device->obsRx->orxProfile->customAdcProfile[i] & 0xFF;
+                adcProfile[i * 2 + 1] = (device->obsRx->orxProfile->customAdcProfile[i] >> 8) & 0xFF;
+            }
+        }
+        else
+        {
+
+            if (device->obsRx->snifferProfile->adcDiv == 0)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO;
+            }
+
+            adcClk_MHz = hsDigClk_MHz / device->obsRx->snifferProfile->adcDiv;
+
+            /* find correct ADC profile in the LUT */
+            profileIndex = NUM_ADC_PROFILES;
+            for (i = 0; i < NUM_ADC_PROFILES; i++)
+            {
+                /* Find a row in the LUT that matches the ADC clock frequency */
+                if ((adcProfileLut[i][1] == adcClk_MHz) && (adcProfileLut[i][0] >= (device->obsRx->snifferProfile->rfBandwidth_Hz / 1000000)))
+                {
+                    profileIndex = i;
+                    break;
+                }
+            }
+
+            /* Verify that a profile was found in the LUT, if not return error */
+            /* In this case a custom profile would need to be passed in */
+            if (profileIndex >= NUM_ADC_PROFILES)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED));
+                return MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED;
+            }
+
+            for (i = 0; i < NUM_ADCPROFILE_COEFS; i++)
+            {
+                adcProfile[i * 2] = adcProfileLut[profileIndex][i + 2] & 0xFF;
+                adcProfile[i * 2 + 1] = (adcProfileLut[profileIndex][i + 2] >> 8) & 0xFF;
+            }
+        }
+
+        /* writing to the ARM memory with ADC Profile for sniffer Rx path */
+        retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 64, &adcProfile[0], sizeof(adcProfile));
+        if (retVal)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED,
+                    getMykonosErrorMessage(MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED));
+            return MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED;
+        }
+
+        /* If Tx, Rx, and ORx Profiles are not valid, set Loopback ADC profile to Sniffer Rx ADC Profile */
+        if (((device->profilesValid & TX_PROFILE_VALID) == 0) && ((device->profilesValid & RX_PROFILE_VALID) == 0) && ((device->profilesValid & ORX_PROFILE_VALID) == 0))
+        {
+            retVal = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR + ARM_CONFIG_OFFSET + 96, &adcProfile[0], sizeof(adcProfile));
+            if (retVal)
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED,
+                        getMykonosErrorMessage(MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED));
+                return MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED;
+            }
+        }
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Helper function to calculate commonly used digital clock frequencies in the device
+ *
+ * User should not need to call this function normally.  It is called automatically
+ * within other API functions to calculate the main digital clock.  If the pointers
+ * to the return parameters are NULL, that calculation will be skipped and not
+ * returned.
+ *
+ *
+ * <B>Dependencies</B>
+ * -device->clocks->clkPllVcoFreq_kHz;
+ * -device->clocks->clkPllVcoDiv;
+ * -device->clocks->clkPllHsDiv;
+ *
+ * \param device Pointer to the device settings structure
+ * \param hsDigClk_kHz Return value for the calculated Mykonos high speed Digital clock at the output of the CLKPLL in kHz
+ * \param hsDigClkDiv4or5_kHz Return value for the Mykonos high speed digital clock divided by 4 or 5 in kHz
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM device parameter is a NULL pointer
+ * \retval MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT device->clocks structure is a NULL pointer
+ * \retval MYKONOS_ERR_CLKPLL_INV_VCODIV Invalid CLKPLL VCO divider in device->clocks->clkPllVcoDiv
+ * \retval MYKONOS_ERR_CLKPLL_INV_HSDIV Invalid CLKPLL High speed divider in device->clocks->clkPllHsDiv
+ */
+static mykonosErr_t MYKONOS_calculateDigitalClocks(mykonosDevice_t *device, uint32_t *hsDigClk_kHz, uint32_t *hsDigClkDiv4or5_kHz)
+{
+    uint32_t hsclkRate_kHz = 0;
+    uint32_t clkPllVcoFrequency_kHz = 0;
+    mykonosVcoDiv_t vcoDiv = VCODIV_1;
+    uint8_t hsDiv = 4;
+
+    if (device == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, 0, MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM, getMykonosErrorMessage(MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM));
+        return MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM;
+    }
+
+    if ((device->clocks == NULL))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT,
+                getMykonosErrorMessage(MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT));
+        return MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT;
+    }
+
+    clkPllVcoFrequency_kHz = device->clocks->clkPllVcoFreq_kHz;
+    vcoDiv = device->clocks->clkPllVcoDiv;
+    hsDiv = device->clocks->clkPllHsDiv;
+
+    switch (vcoDiv)
+    {
+        case VCODIV_1:
+            hsclkRate_kHz = clkPllVcoFrequency_kHz;
+            break;
+        case VCODIV_1p5:
+            hsclkRate_kHz = (clkPllVcoFrequency_kHz / 15) * 10;
+            break;
+        case VCODIV_2:
+            hsclkRate_kHz = clkPllVcoFrequency_kHz >> 1;
+            break;
+        case VCODIV_3:
+            hsclkRate_kHz = (clkPllVcoFrequency_kHz / 30) * 10;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_VCODIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_VCODIV));
+            return MYKONOS_ERR_CLKPLL_INV_VCODIV;
+        }
+    }
+
+    switch (hsDiv)
+    {
+        case 4:
+            hsDiv = 4;
+            break;
+        case 5:
+            hsDiv = 5;
+            break;
+        default:
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CLKPLL_INV_HSDIV, getMykonosErrorMessage(MYKONOS_ERR_CLKPLL_INV_HSDIV));
+            return MYKONOS_ERR_CLKPLL_INV_HSDIV;
+        }
+    }
+
+    if (hsDigClk_kHz != NULL)
+    {
+        *hsDigClk_kHz = hsclkRate_kHz / hsDiv;
+    }
+
+    if (hsDigClkDiv4or5_kHz != NULL)
+    {
+        /* This digital div 4 or 5 is always mutually exclusive with the HS Divider (4 or 5) to always
+         * create a /20 from the hsclk.
+         */
+        *hsDigClkDiv4or5_kHz = hsclkRate_kHz / 20;
+    }
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs reset to the External Tx LO Leakage tracking calibration channel estimate
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the Mykonos device data structure containing settings
+ * \param channelSel Enum selects the channel to reset
+ *
+ * \retval MYKONOS_ERR_RESET_TXLOL_INV_PARAM Selected channel is not valid
+ * \retval MYKONOS_ERR_RESET_TXLOL_ARMERROR ARM error
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ */
+mykonosErr_t MYKONOS_resetExtTxLolChannel(mykonosDevice_t *device, mykonosTxChannels_t channelSel)
+{
+    const uint8_t TXLOL_RESET_CHANNEL_ESTIMATE = 0x01;
+    const uint32_t GETTXLOLSTATUS_TIMEOUT_MS = 1000;
+
+    mykonosErr_t retVal = MYKONOS_ERR_OK;
+    uint8_t extData[3] = {MYKONOS_ARM_OBJECTID_GS_TRACKCALS, TXLOL_RESET_CHANNEL_ESTIMATE, 0};
+    uint8_t cmdStatusByte = 0;
+    uint8_t armErrorFlag = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_resetExtTxLolChannel()\n");
+#endif
+
+    /* Check Channel */
+    switch (channelSel)
+    {
+        case TX1:
+            extData[2] = 0x01;
+            break;
+        case TX2:
+            extData[2] = 0x02;
+            break;
+        case TX1_TX2:
+            extData[2] = 0x03;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_RESET_TXLOL_INV_PARAM,
+                    getMykonosErrorMessage(MYKONOS_ERR_RESET_TXLOL_INV_PARAM));
+            return MYKONOS_ERR_RESET_TXLOL_INV_PARAM;
+    }
+
+    /* throw error if not in radioOff/IDLE state */
+    retVal = MYKONOS_checkArmState(device, (MYK_ARM_IDLE | MYK_ARM_RADIO_ON));
+    if (retVal)
+    {
+        return retVal;
+    }
+
+    retVal = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &extData[0], sizeof(extData));
+    if (retVal)
+    {
+        return retVal;
+    }
+    retVal = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, GETTXLOLSTATUS_TIMEOUT_MS, &cmdStatusByte);
+
+    /* Error check WaitArmCmdStatus return */
+    armErrorFlag = (cmdStatusByte >> 1);
+    if (armErrorFlag > 0)
+    {
+        return MYKONOS_ERR_RESET_TXLOL_ARMERROR;
+    }
+
+    return retVal;
+}
+
diff --git a/mpm/lib/mykonos/adi/mykonos.h b/mpm/lib/mykonos/adi/mykonos.h
new file mode 100644
index 000000000..cdda125d8
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos.h
@@ -0,0 +1,242 @@
+/*!
+ * \file mykonos.h
+ * \brief Contains macro definitions and function prototypes for mykonos.c
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef _MYKONOS_LIB_H_
+#define _MYKONOS_LIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "t_mykonos.h"
+#include "mykonos_version.h"
+
+#define TX_PROFILE_VALID    0x01
+#define RX_PROFILE_VALID    0x02
+#define ORX_PROFILE_VALID   0x04
+#define SNIFF_PROFILE_VALID 0x08
+
+/* 
+ ****************************************************************************
+ * General Initialization functions 
+ ****************************************************************************
+ */
+mykonosErr_t MYKONOS_resetDevice(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getDeviceRev(mykonosDevice_t *device, uint8_t *revision);
+mykonosErr_t MYKONOS_getProductId(mykonosDevice_t *device, uint8_t *productId);
+mykonosErr_t MYKONOS_setSpiSettings(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_verifyDeviceDataStructure(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_verifyProfiles(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_initialize(mykonosDevice_t *device); 
+mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent, uint32_t timeout_us);
+mykonosErr_t MYKONOS_readEventStatus(mykonosDevice_t *device, waitEvent_t waitEvent, uint8_t *eventDone);
+mykonosErr_t MYKONOS_getApiVersion (mykonosDevice_t *device, uint32_t *siVer, uint32_t *majorVer, uint32_t *minorVer, uint32_t *buildVer);
+
+/*
+ *****************************************************************************
+ * PLL / Synthesizer functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_initDigitalClocks(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t rfPllLoFrequency_Hz);
+mykonosErr_t MYKONOS_getRfPllFrequency(mykonosDevice_t *device, mykonosRfPllName_t pllName, uint64_t *rfPllLoFrequency_Hz);
+mykonosErr_t MYKONOS_checkPllsLockStatus(mykonosDevice_t *device, uint8_t *pllLockStatus);
+
+/*
+ *****************************************************************************
+ * ARM Processor Control Functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_initArm(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_loadArmFromBinary(mykonosDevice_t *device, uint8_t *binary, uint32_t count);
+mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t armStateCheck);
+mykonosErr_t MYKONOS_getArmVersion(mykonosDevice_t *device, uint8_t *majorVer, uint8_t *minorVer, uint8_t *rcVer);
+
+mykonosErr_t MYKONOS_configDpd(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getDpdConfig(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getDpdStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosDpdStatus_t *dpdStatus);
+mykonosErr_t MYKONOS_restoreDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes);
+mykonosErr_t MYKONOS_saveDpdModel(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t *modelDataBuffer, uint32_t modelNumberBytes);
+mykonosErr_t MYKONOS_setDpdActState(mykonosDevice_t *device, mykonosTxChannels_t txChannel, uint8_t actState);
+
+mykonosErr_t MYKONOS_configClgc(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getClgcConfig(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getClgcStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosClgcStatus_t *clgcStatus);
+mykonosErr_t MYKONOS_setClgcGain(mykonosDevice_t *device, mykonosTxChannels_t txChannel, int16_t gain);
+
+mykonosErr_t MYKONOS_configVswr(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getVswrConfig(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getVswrStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosVswrStatus_t *vswrStatus);
+
+mykonosErr_t MYKONOS_runInitCals(mykonosDevice_t *device, uint32_t calMask);
+mykonosErr_t MYKONOS_waitInitCals(mykonosDevice_t *device, uint32_t timeoutMs, uint8_t *errorFlag, uint8_t *errorCode);
+mykonosErr_t MYKONOS_abortInitCals(mykonosDevice_t *device, uint32_t *calsCompleted);
+mykonosErr_t MYKONOS_getInitCalStatus(mykonosDevice_t *device, mykonosInitCalStatus_t *initCalStatus);
+
+mykonosErr_t MYKONOS_resetExtTxLolChannel(mykonosDevice_t *device, mykonosTxChannels_t channelSel);
+
+mykonosErr_t MYKONOS_radioOn(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_radioOff(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_getRadioState(mykonosDevice_t *device, uint32_t *radioStatus);
+mykonosErr_t MYKONOS_enableTrackingCals(mykonosDevice_t *device, uint32_t enableMask);
+mykonosErr_t MYKONOS_rescheduleTrackingCal(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal);
+mykonosErr_t MYKONOS_setAllTrackCalState(mykonosDevice_t *device, uint32_t trackingCalMask);
+mykonosErr_t MYKONOS_getAllTrackCalState(mykonosDevice_t *device, uint32_t *trackCals);
+mykonosErr_t MYKONOS_setTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t trackCalState);
+mykonosErr_t MYKONOS_getTrackingCalState(mykonosDevice_t *device, mykonosTrackingCalibrations_t trackingCal, uint8_t *trackCalState);
+mykonosErr_t MYKONOS_getEnabledTrackingCals(mykonosDevice_t *device, uint32_t *enableMask);
+mykonosErr_t MYKONOS_getPendingTrackingCals(mykonosDevice_t *device, uint32_t *pendingCalMask);
+mykonosErr_t MYKONOS_getTxLolStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxLolStatus_t *txLolStatus);
+mykonosErr_t MYKONOS_getTxQecStatus(mykonosDevice_t *device, mykonosTxChannels_t txChannel, mykonosTxQecStatus_t *txQecStatus);
+
+mykonosErr_t MYKONOS_getRxQecStatus(mykonosDevice_t *device, mykonosRxChannels_t rxChannel, mykonosRxQecStatus_t *rxQecStatus);
+mykonosErr_t MYKONOS_getOrxQecStatus(mykonosDevice_t *device, mykonosObsRxChannels_t orxChannel, mykonosOrxQecStatus_t *orxQecStatus);
+
+mykonosErr_t MYKONOS_setSnifferChannel(mykonosDevice_t *device, mykonosSnifferChannel_t snifferChannel);
+
+/* Low level ARM functions */
+mykonosErr_t MYKONOS_readArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *returnData, uint32_t bytesToRead, uint8_t autoIncrement);
+mykonosErr_t MYKONOS_writeArmMem(mykonosDevice_t *device, uint32_t address, uint8_t *data, uint32_t byteCount);
+mykonosErr_t MYKONOS_writeArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount);
+mykonosErr_t MYKONOS_readArmConfig(mykonosDevice_t *device, uint8_t objectId, uint16_t offset, uint8_t *data, uint8_t byteCount);
+mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode,  uint8_t *extendedData, uint8_t extendedDataNumBytes);
+mykonosErr_t MYKONOS_readArmCmdStatus(mykonosDevice_t *device, uint16_t *errorWord, uint16_t *statusWord);
+mykonosErr_t MYKONOS_readArmCmdStatusByte(mykonosDevice_t *device, uint8_t opCode, uint8_t *cmdStatByte);
+mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, uint32_t timeoutMs, uint8_t *cmdStatByte);
+mykonosErr_t MYKONOS_writeArmProfile(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_loadAdcProfiles(mykonosDevice_t *device);
+
+
+/*
+ *****************************************************************************
+ * JESD204B Datapath Functions
+ *****************************************************************************
+ */
+/* Functions to setup the JESD204B IP */
+mykonosErr_t MYKONOS_resetDeframer(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setupSerializers(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setupDeserializers(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setupJesd204bFramer(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setupJesd204bObsRxFramer(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setupJesd204bDeframer(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_enableRxFramerLink(mykonosDevice_t *device, uint8_t enable);
+mykonosErr_t MYKONOS_enableObsRxFramerLink(mykonosDevice_t *device, uint8_t enable);
+
+/* Functions to initialize the JESD204B link */
+mykonosErr_t MYKONOS_enableMultichipSync(mykonosDevice_t *device, uint8_t enableMcs, uint8_t *mcsStatus);
+mykonosErr_t MYKONOS_enableSysrefToRxFramer(mykonosDevice_t *device, uint8_t enable);
+mykonosErr_t MYKONOS_enableSysrefToObsRxFramer(mykonosDevice_t *device, uint8_t enable);
+mykonosErr_t MYKONOS_enableSysrefToDeframer(mykonosDevice_t *device, uint8_t enable);
+
+/* Functions to help debug the JESD204B link */
+mykonosErr_t MYKONOS_readRxFramerStatus(mykonosDevice_t *device, uint8_t *framerStatus);
+mykonosErr_t MYKONOS_readOrxFramerStatus(mykonosDevice_t *device, uint8_t *obsFramerStatus);
+mykonosErr_t MYKONOS_readDeframerStatus(mykonosDevice_t *device, uint8_t *deframerStatus);
+mykonosErr_t MYKONOS_getDeframerFifoDepth(mykonosDevice_t *device, uint8_t *fifoDepth, uint8_t *readEnLmfcCount);
+
+/* PRBS debug functions */
+mykonosErr_t MYKONOS_enableRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable);
+mykonosErr_t MYKONOS_enableObsRxFramerPrbs(mykonosDevice_t *device, mykonosPrbsOrder_t polyOrder, uint8_t enable);
+mykonosErr_t MYKONOS_rxInjectPrbsError(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_obsRxInjectPrbsError(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_enableDeframerPrbsChecker(mykonosDevice_t *device, uint8_t lanes, mykonosPrbsOrder_t polyOrder, uint8_t enable);
+mykonosErr_t MYKONOS_clearDeframerPrbsCounters(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_readDeframerPrbsCounters(mykonosDevice_t *device, uint8_t counterSelect, uint32_t *prbsErrorCount);
+
+/* Miscellaneous debug functions */
+mykonosErr_t MYKONOS_jesd204bIlasCheck(mykonosDevice_t *device, uint16_t *mismatch);
+mykonosErr_t MYKONOS_setRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource);
+mykonosErr_t MYKONOS_setObsRxFramerDataSource(mykonosDevice_t *device, uint8_t dataSource);
+
+/*
+ *****************************************************************************
+ * Shared Data path functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_programFir(mykonosDevice_t *device, mykonosfirName_t filterToProgram, mykonosFir_t *firFilter);
+mykonosErr_t MYKONOS_readFir(mykonosDevice_t *device, mykonosfirName_t filterToRead, mykonosFir_t *firFilter);
+
+/*
+ *****************************************************************************
+ * Rx Data path functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_programRxGainTable(mykonosDevice_t *device, uint8_t *gainTablePtr, uint8_t numGainIndexesInTable, mykonosGainTable_t rxChannel);
+mykonosErr_t MYKONOS_setRx1ManualGain(mykonosDevice_t *device, uint8_t gainIndex);
+mykonosErr_t MYKONOS_setRx2ManualGain(mykonosDevice_t *device, uint8_t gainIndex);
+mykonosErr_t MYKONOS_getRx1Gain(mykonosDevice_t *device, uint8_t *rx1GainIndex);
+mykonosErr_t MYKONOS_getRx2Gain(mykonosDevice_t *device, uint8_t *rx2GainIndex);
+mykonosErr_t MYKONOS_setupRxAgc(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_resetRxAgc(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosRxChannels_t rxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex);
+mykonosErr_t MYKONOS_setObsRxAgcMinMaxGainIndex(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxChannelSelect, uint8_t maxGainIndex, uint8_t minGainIndex);
+mykonosErr_t MYKONOS_setRx1TempGainComp(mykonosDevice_t *device, int16_t rx1TempCompGain_mdB);
+mykonosErr_t MYKONOS_getRx1TempGainComp(mykonosDevice_t *device, int16_t *rx1TempCompGain_mdB);
+mykonosErr_t MYKONOS_setRx2TempGainComp(mykonosDevice_t *device, int16_t rx2TempCompGain_mdB);
+mykonosErr_t MYKONOS_getRx2TempGainComp(mykonosDevice_t *device, int16_t *rx2TempCompGain_mdB);
+mykonosErr_t MYKONOS_setObsRxTempGainComp(mykonosDevice_t *device, int16_t obsRxTempCompGain_mdB);
+mykonosErr_t MYKONOS_getObsRxTempGainComp(mykonosDevice_t *device, int16_t *obsRxTempCompGain_mdB);
+mykonosErr_t MYKONOS_enableRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable);
+mykonosErr_t MYKONOS_setRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode);
+mykonosErr_t MYKONOS_getRx1DecPower(mykonosDevice_t *device, uint16_t *rx1DecPower_mdBFS);
+mykonosErr_t MYKONOS_getRx2DecPower(mykonosDevice_t *device, uint16_t *rx2DecPower_mdBFS);
+
+/*
+ *****************************************************************************
+ * Observation Rx Data path functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_setDefaultObsRxPath(mykonosDevice_t *device,  mykonosObsRxChannels_t defaultObsRxCh);
+mykonosErr_t MYKONOS_setObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh);
+mykonosErr_t MYKONOS_getObsRxPathSource(mykonosDevice_t *device, mykonosObsRxChannels_t *obsRxCh);
+mykonosErr_t MYKONOS_setObsRxManualGain(mykonosDevice_t *device, mykonosObsRxChannels_t obsRxCh, uint8_t gainIndex);
+mykonosErr_t MYKONOS_getObsRxGain(mykonosDevice_t *device, uint8_t *gainIndex);
+mykonosErr_t MYKONOS_setupObsRxAgc(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_enableObsRxGainCtrSyncPulse(mykonosDevice_t *device, uint8_t enable);
+mykonosErr_t MYKONOS_setObsRxGainControlMode(mykonosDevice_t *device, mykonosGainMode_t mode);
+mykonosErr_t MYKONOS_getObsRxDecPower(mykonosDevice_t *device, uint16_t *obsRxDecPower_mdBFS);
+
+/*
+ *****************************************************************************
+ * Tx Data path functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_setTx1Attenuation(mykonosDevice_t *device, uint16_t tx1Attenuation_mdB);
+mykonosErr_t MYKONOS_setTx2Attenuation(mykonosDevice_t *device, uint16_t tx2Attenuation_mdB);
+mykonosErr_t MYKONOS_getTx1Attenuation(mykonosDevice_t *device, uint16_t *tx1Attenuation_mdB);
+mykonosErr_t MYKONOS_getTx2Attenuation(mykonosDevice_t *device, uint16_t *tx2Attenuation_mdB);
+mykonosErr_t MYKONOS_getTxFilterOverRangeStatus(mykonosDevice_t *device, uint8_t *txFilterStatus);
+mykonosErr_t MYKONOS_enableTxNco(mykonosDevice_t *device, uint8_t enable, int32_t tx1ToneFreq_kHz, int32_t tx2ToneFreq_kHz);
+
+/*
+ *****************************************************************************
+ * PA Protection Functions
+ *****************************************************************************
+ */
+mykonosErr_t MYKONOS_setupPaProtection(mykonosDevice_t *device, uint16_t powerThreshold, uint8_t attenStepSize, uint8_t avgDuration, uint8_t stickyFlagEnable, uint8_t txAttenControlEnable);
+mykonosErr_t MYKONOS_enablePaProtection(mykonosDevice_t *device, uint8_t enable);
+mykonosErr_t MYKONOS_getDacPower(mykonosDevice_t *device, mykonosTxChannels_t channel, uint16_t *channelPower);
+mykonosErr_t MYKONOS_getPaProtectErrorFlagStatus(mykonosDevice_t *device, uint8_t *errorFlagStatus);
+mykonosErr_t MYKONOS_clearPaErrorFlag(mykonosDevice_t *device);
+
+/*
+ *****************************************************************************
+ * Low level functions and helper functions. BBP should not need to call
+ *****************************************************************************
+ */
+const char* getMykonosErrorMessage(mykonosErr_t errorCode);
+
+mykonosErr_t MYKONOS_initSubRegisterTables(mykonosDevice_t *device);
+mykonosErr_t MYKONOS_setTxPfirSyncClk(mykonosDevice_t *device); /* Helper function */
+mykonosErr_t MYKONOS_setRxPfirSyncClk(mykonosDevice_t *device); /* Helper function */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mpm/lib/mykonos/adi/mykonosMmap.c b/mpm/lib/mykonos/adi/mykonosMmap.c
new file mode 100644
index 000000000..f88cbb3a3
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonosMmap.c
@@ -0,0 +1,129 @@
+/**
+ * \file mykonosMmap.c
+ * \brief Contains the Mykonos memory mapping
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#include <stdint.h>
+uint8_t mykonosMmap [] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x13,0x03,0x03,0x13,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+                                 0x00,0xE4,0xE4,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x01,0x00,0xE4,0xE4,0x00,0x00,0x00,0x1F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0xE0,0x20,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x8F,0x0F,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+/*!< Mykonos memory map */
diff --git a/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.c b/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.c
new file mode 100644
index 000000000..aa70e9cc7
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.c
@@ -0,0 +1,1333 @@
+/**
+ * \file mykonos_dbgjesd.c
+ *
+ * \brief Contains Mykonos APIs for Jesd debug facilities.
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "mykonos_dbgjesd.h"
+#include "mykonos_macros.h"
+
+
+/**
+ * \brief Helper function for return of character string based on 32-bit mykonosDbgErr_t enum value
+ *
+ * To save codespace, these error strings are ifdef'd out unless the user
+ * adds a define MYKONOS_VERBOSE to their workspace.  This function can be
+ * useful for debug.  Each function also returns unique error codes to
+ * make it easier to determine where the code broke.
+ *
+ * \param errorCode is enumerated error code value
+ *
+ * \return Returns character string based on enumerated value
+ */
+const char* getDbgJesdMykonosErrorMessage(mykonosDbgErr_t errorCode)
+{
+
+#if MYKONOS_VERBOSE == 0
+    return "";
+#else
+
+    switch (errorCode)
+    {
+        case MYKONOS_ERR_DBG_OK:
+            return "No error\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER:
+            return "Pointer to passed parameter is NULL\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE:
+            return "Illegal JESD core passed, valid options for the JESD code are in mykonos_jesdcore_t\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_ERROR_TYPE:
+            return "Illegal error type passed, valid error types are given in mykonosErrType_t\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED:
+            return "Illegal errType passed, valid errType are BADDISP, NIT and UEKC\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER:
+            return "Illegal lane number passed, valid lanes are given in mykonosLaneSel_t\n";
+
+        case MYKONOS_ERR_DBG_ERROR_THRESHOLD:
+            return "Illegal error threshold passed, valid error thresholds are in the range 0x00 to 0xFF\n";
+
+        case MYKONOS_ERR_DBG_ERROR_SYNC_MASK:
+            return "Illegal Sync Mask passed, valid Sync Masks are in the range 0x00 to 0x07\n";
+
+        case MYKONOS_ERR_DBG_ERROR_IRQ_MASK:
+            return "Illegal IRQ mask passed, valid IRQ Masks are in the range 0x00 to 0x1FF\n";
+
+        case MYKONOS_ERR_DBG_PATTERN_GEN_NULL_PATTERN:
+            return "Function parameter pattern is a NULL pointer\n";
+
+        case MYKONOS_ERR_DBG_PATTERN_GEN_NULL_ENABLE:
+            return "Function parameter enable is a NULL pointer\n";
+
+        case MYKONOS_ERR_DBG_PATTERN_GEN_NULL_TOGGLE:
+            return "Function parameter toggle is a NULL pointer\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_TOGGLE:
+            return "Toggle is not valid, valid values are 0 and 1.\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_FRAMER_PATTERN:
+            return "Pattern passed is outside the range valid range from 0x00000 to 0xFFFFF\n";
+
+        case MYKONOS_ERR_DBG_ILLEGAL_ENABLE:
+            return "Enable not valid, valid values are 0 and 1.\n";
+
+        case MYKONOS_ERR_DBG_ZERO_DATA_INV_LANE:
+            return "the lane selection is out of range, valid range is 0x00 to 0x0F in MYKONOS_framerSetZeroData().\n";
+
+        case MYKONOS_ERR_DBG_ZERO_DATA_LANE_NULL:
+            return "Function parameter lane is a NULL pointer passed to MYKONOS_framerGetZeroData().\n";
+
+        case MYKONOS_ERR_DBG_FRAMER_SEL_BASE_ADD_NULL:
+            return "base address is null in MYKONOS_framerCoreSel().\n";
+
+        case MYKONOS_ERR_DBG_FRAMER_ILLEGAL_JESD_CORE:
+            return "Only valid JESD cores are FRAMER and OBS_FRAMER in MYKONOS_framerCoreSel().\n";
+
+        default:
+            return "";
+    }
+
+#endif
+}
+
+/**
+ * \brief Performs indirect write access to internal JESD register.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param jesdCore JESD core selection
+ * \param intAddr Internal address to access in JESD core
+ * \param data Data to write into internal address
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE An illegal JESD core passed, valid cores are given in mykonos_jesdcore_t
+ */
+mykonosDbgErr_t MYKONOS_jesdIndWrReg(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint8_t intAddr, uint8_t data)
+{
+    uint16_t baseAddr = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdIndWrReg()\n");
+#endif
+
+    /* Check for jesdCore and address assignment */
+    switch (jesdCore)
+    {
+        case MYK_FRAMER:
+            baseAddr = MYKONOS_ADDR_FRAMER_ADDR;
+        break;
+
+        case MYK_DEFRAMER:
+            baseAddr = MYKONOS_ADDR_DEFRAMER_ADDR;
+        break;
+
+        case MYK_OBS_FRAMER:
+            baseAddr = MYKONOS_ADDR_OBS_FRAMER_ADDR;
+        break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE));
+             return MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE;
+        break;
+    }
+
+    /* Perform indirect write */
+    CMB_SPIWriteByte(device->spiSettings, baseAddr, intAddr);
+    CMB_SPIWriteByte(device->spiSettings, baseAddr + 1, data);
+    CMB_SPIWriteByte(device->spiSettings, baseAddr + 2, 0x01);
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+/**
+ * \brief Performs indirect read access to internal JESD register.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param jesdCore JESD core selection
+ * \param intAddr Internal address to access in JESD core
+ * \param data Pointer to store data
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed is a NULL pointer
+ */
+mykonosDbgErr_t MYKONOS_jesdIndRdReg(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint8_t intAddr, uint8_t *data)
+{
+    uint16_t baseAddr = 0;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdIndRdReg()\n");
+#endif
+
+    /* Check for valid data pointer */
+    if(data == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+         return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Check for jesdCore and address assignment */
+    switch (jesdCore)
+    {
+        case MYK_FRAMER:
+            baseAddr = MYKONOS_ADDR_FRAMER_ADDR;
+        break;
+
+        case MYK_DEFRAMER:
+            baseAddr = MYKONOS_ADDR_DEFRAMER_ADDR;
+        break;
+
+        case MYK_OBS_FRAMER:
+            baseAddr = MYKONOS_ADDR_OBS_FRAMER_ADDR;
+        break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE));
+             return MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE;
+        break;
+    }
+
+    /* Perform indirect read */
+    CMB_SPIWriteByte(device->spiSettings, baseAddr, intAddr);
+    CMB_SPIReadByte(device->spiSettings, baseAddr + 1, data);
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+/**
+ * \brief Performs reads to JESD Deframer secondary status register.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param defStat2 Pointer to store the deframer secondary status
+ *
+ *  Bit mask  |  Description of defStat2
+ * -----------|---------------
+ *      2     | DeframerSYSREF Phase Error, when set, this bit reports that an incoming SYSREF is not aligned to the current LMFC boundary.
+ *      1     | Deframer Det Lat FIFO RD, this bit is the status of rd_enable for deterministic sample FIFO. If set deterministic latency is achieved.
+ *      0     | Deframer Lane FIFO PTR Delta Changed. If set this bit reports that the offset between the read and write FIFO pointers has changed.
+ *
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed defStat2 is NULL
+ */
+mykonosDbgErr_t MYKONOS_deframerRd2Stat(mykonosDevice_t *device, uint8_t *defStat2)
+{
+    uint8_t regRd = 0x00;
+
+    const uint8_t SHIFT_MASK = 0x05;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdRdDefrmSndStat()\n");
+#endif
+
+    /* Check for valid defStat2 pointer */
+    if (defStat2 == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+        return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Read deframer secondary status */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STATUS_2, &regRd);
+
+    *defStat2 = regRd >> SHIFT_MASK;
+
+    /* Refresh status registers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x01);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DEFRAMER_STAT_STRB, 0x00);
+
+    return MYKONOS_ERR_OK;
+}
+
+/**
+ * \brief Performs read back lanes in error for the given errType of the JESD Deframer.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errType which error counter to read back
+ * \param lane Pointer to store which lane has reached the error threshold.
+ * Every bit shows per lane which error count has reached the threshold count.
+ * A value of 0x0F will represent that all the lanes has reached the error threshold.
+ *
+ *    Value      |  Description of Lane
+ * --------------|-----------------------
+ *      8        | Lane 3 has reached the error threshold
+ *      4        | Lane 2 has reached the error threshold
+ *      2        | Lane 1 has reached the error threshold
+ *      1        | Lane 0 has reached the error threshold
+ *      0        | No errors in lanes
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed lane is NULL
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED Illegal errType passed, valid errType are BADDISP, NIT and UEKC
+ */
+mykonosDbgErr_t MYKONOS_deframerGetErrLane(mykonosDevice_t *device, mykonosErrType_t errType, uint8_t *lane)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdIndRdReg()\n");
+#endif
+
+    /* Check for valid Lane pointer */
+    if(lane == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+         return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Check for valid error type */
+    switch (errType)
+    {
+        case MYK_BADDISP:
+        case MYK_NIT:
+        case MYK_UEKC:
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED));
+            return MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED;
+    }
+
+    /* Read error and store it in lane */
+    error = MYKONOS_jesdIndRdReg(device, jesdCore, errType, lane);
+
+    return error;
+}
+
+/**
+ * \brief Performs reset of the selected error type for the selected lane.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errType Which error counter to be reset
+ * \param lane Which lane error counter to be reset
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER Illegal lane passed, valid lanes are given in mykonosLaneSel_t
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED Illegal errType passed, valid errType are BADDISP, NIT and UEKC
+ */
+mykonosDbgErr_t MYKONOS_deframerRstErrCntr(mykonosDevice_t *device, mykonosErrType_t errType, mykonosLaneSel_t lane)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+
+    const uint8_t rstCntBit = 0x20;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdIndRdReg()\n");
+#endif
+
+    /* Check for valid Lane */
+    switch (lane)
+    {
+        case MYK_LANE_0:
+        case MYK_LANE_1:
+        case MYK_LANE_2:
+        case MYK_LANE_3:
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER));
+            return MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER;
+    }
+
+    /* Check for error type */
+    switch (errType)
+    {
+        case MYK_BADDISP:
+        case MYK_NIT:
+        case MYK_UEKC:
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED));
+            return MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED;
+    }
+
+    /* Perform reset counter */
+    error = MYKONOS_jesdIndWrReg(device, jesdCore, errType, (rstCntBit | ((uint8_t)lane)));
+
+    return error;
+}
+
+/**
+ * \brief Performs reset of the selected error type IRQ for the given lane.
+ *
+ *<B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errType Which error counter to be reset, for the full list
+ * \param lane Which lane error counter to be reset
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER Illegal lane passed, valid lanes are given in mykonosLaneSel_t
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_ERROR_TYPE Illegal errType passed, valid errType are given in mykonosErrType_t
+ */
+mykonosDbgErr_t MYKONOS_deframerRstErrIrq(mykonosDevice_t *device, mykonosErrType_t errType, mykonosLaneSel_t lane)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t regRd = 0;
+    uint8_t rstIrqBit = 0x80;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdIndRdReg()\n");
+#endif
+
+    /* Check for valid Lane */
+    switch (lane)
+    {
+        case MYK_LANE_0:
+        case MYK_LANE_1:
+        case MYK_LANE_2:
+        case MYK_LANE_3:
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER));
+            return MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER;
+    }
+
+    /* Check for error type */
+    switch (errType)
+    {
+        case MYK_CMM:
+            /* CMM has no lane selection */
+            error = MYKONOS_jesdIndRdReg(device, jesdCore, errType, &regRd);
+            if (error != MYKONOS_ERR_DBG_OK)
+            {
+                return error;
+            }
+
+            lane = MYK_LANE_0;
+            rstIrqBit = 0x10 | regRd;
+            break;
+
+        case MYK_BADDISP:
+        case MYK_NIT:
+        case MYK_UEKC:
+            break;
+
+        default:
+           CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_ERROR_TYPE,
+                   getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_ERROR_TYPE));
+           return MYKONOS_ERR_DBG_ILLEGAL_ERROR_TYPE;
+    }
+
+    /* Reset selected IRQ */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, errType, &regRd)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, errType, (rstIrqBit | ((uint8_t)lane)))) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, errType, &regRd)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+    }
+
+    return error;
+}
+
+
+/**
+ * \brief Performs read back of the error counters for selected lane of the JESD Deframer.
+ *
+ * This function reads the counters per the given lane for the bad disparity, not in table and unexpected K character errors and stores them in the
+ * structure laneErr.
+ * The structure laneErr must be initialised in the calling function as it will contain the values of the counters per error type for the given lane.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - laneErr structure must be initialised
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param laneSel which JESD lane error counter to be read
+ * \param laneErr Pointer to a mykonosLaneErr_t structure type to store counter values for different errors
+ *
+ * \retval MYKONOS_ERR_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed laneErr is NULL
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER Illegal laneSel parameter passed, valid laneSel are given in mykonosLaneSel_t
+ */
+mykonosDbgErr_t MYKONOS_deframerRdErrCntr(mykonosDevice_t *device, mykonosLaneSel_t laneSel, mykonosLaneErr_t *laneErr)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t counterSel = 0;
+
+    const uint8_t ERR_CNT_ADDR = 0x6B;
+
+#if (MYKONOS_VERBOSE == 1)
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdRdErrCntr()\n");
+#endif
+
+    /* Check for valid laneErr pointer */
+    if(laneErr == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+        return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Check for valid laneSel */
+    switch (laneSel)
+    {
+        case MYK_LANE_0:
+        case MYK_LANE_1:
+        case MYK_LANE_2:
+        case MYK_LANE_3:
+            break;
+
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER));
+             return MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER;
+    }
+
+    /* Reading Bad disparity Counter */
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, ERR_CNT_ADDR, (((uint8_t)(laneSel) << 4) | counterSel++))) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, ERR_CNT_ADDR, &laneErr->badDispCntr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    /* Reading Not in table Counter */
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, ERR_CNT_ADDR, (((uint8_t)(laneSel) << 4) | counterSel++))) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, ERR_CNT_ADDR, &laneErr->nitCntr)))
+    {
+        return error;
+    }
+
+    /* Reading unexpected K character Counter */
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, ERR_CNT_ADDR, (((uint8_t)(laneSel) << 4) | counterSel))) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, ERR_CNT_ADDR, &laneErr->uekcCntr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+    }
+
+    return error;
+}
+
+
+/**
+ * \brief Performs set JESD Deframer error thresholds.
+ *
+ * The value for the error threshold will be applied to all the error counters for all the enabled lanes.
+ * Bad disparity, NIT disparity and Unexpected K char. Errors are counted and compared to the errThrs value.
+ * When the count is equal, then the user has the ability of raising an IRQ, see MYKONOS_deframerSetIrqMask,
+ * or asserted the SYNC signal per the mask register settings, see MYKONOS_deframerSetSyncMask,
+ * or do nothing upon threshold reach.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errThrs is the value that will be written to the error threshold, valid error threshold is in the range 0x00 to 0xFF.
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_deframerSetErrThrs(mykonosDevice_t *device, uint8_t errThrs)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+
+    const uint8_t DFM_ERROR_THRES = 0x7C;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdGetErrThrs()\n");
+#endif
+
+    /* Writing internal registers 0x7C */
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, DFM_ERROR_THRES, errThrs)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+    }
+
+    return error;
+}
+
+/**
+ * \brief Performs read JESD Deframer error thresholds.
+ *
+ * The value for the error threshold is common to all the error counters.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - laneErr structure must be initialised
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errThrs Pointer to store the error threshold value read back
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed errThrs is NULL
+ */
+mykonosDbgErr_t MYKONOS_deframerGetErrThrs(mykonosDevice_t *device, uint8_t *errThrs)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+
+    const uint8_t DFM_ERROR_THRES = 0x7C;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdGetErrThrs()\n");
+#endif
+
+    /* Check for null parameter */
+    if (errThrs == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+        return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Reading internal registers */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, DFM_ERROR_THRES, errThrs)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+    }
+
+    return error;
+}
+
+
+/**
+ * \brief Performs set JESD Deframer Sync mask.
+ *
+ * This function sets the syncMask that will be programmed in to Mykonos.
+ * When the error counter reaches the error threshold value programmed by MYKONOS_deframerSetErrThrs function, if the syncMask is set for the particular
+ * errors type then the SYNC~ is asserted.
+ * The syncMask is applied to all the enabled lanes.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errSyncMask is the mask that will be used in order to assert SYNC~
+ * Setting the syncMask bits causes the deframer to assert the SYNC~ when the count of the corresponding error reaches the
+ * errThrs value.
+ *
+ *   Sync       |   Bit mask   |  Description of sync
+ * -------------|--------------|-----------------------
+ * SYNC_BADDISP |     2        | Bad disparity mask
+ * SYNC_NIT     |     1        | Not in table
+ * SYNC_UEKC    |     0        | Unexpected K character
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully.
+ * \retval MYKONOS_ERR_DBG_ERROR_SYNC_MASK Passed errSyncMask parameter is outside its boundaries, valid sync mask are in the range 0x00 to 0x07.
+ */
+mykonosDbgErr_t MYKONOS_deframerSetSyncMask(mykonosDevice_t *device, uint8_t errSyncMask)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t regRd = 0x00;
+    uint8_t regWr = 0x00;
+
+    const uint8_t SYNC_MASK_CTRL = 0x7B;
+    const uint8_t SYNC_MASK = 0x07;
+    const uint8_t MASK = 0xE0;
+    const uint8_t SYNC_SHIFT = 5;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdSetSyncMask()\n");
+#endif
+
+    /* Check for valid errSyncMask */
+    if (errSyncMask & ~SYNC_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ERROR_SYNC_MASK,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ERROR_SYNC_MASK));
+        return MYKONOS_ERR_DBG_ERROR_SYNC_MASK;
+    }
+
+    /* Writing internal registers do a read modify write */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, SYNC_MASK_CTRL, &regRd)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+    regRd &= ~(MASK);
+
+    regWr = regRd | (errSyncMask << SYNC_SHIFT);
+
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, SYNC_MASK_CTRL, regWr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+    }
+
+    return error;
+}
+
+/**
+ * \brief Performs get JESD Deframer SyncMask.
+ *
+ * This function read the SyncMask that is programmed into Mykonos.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errSyncMask Pointer to store the sync mask currently being used:
+ *
+ *   Sync       |   Bit mask   |  Description of errSyncMask
+ *--------------|--------------|-----------------------
+ * SYNC_BADDISP |     2        | Bad disparity mask
+ * SYNC_NIT     |     1        | Not in table
+ * SYNC_UEKC    |     0        | Unexpected K character
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed errSyncMask is NULL
+ */
+mykonosDbgErr_t MYKONOS_deframerGetSyncMask(mykonosDevice_t *device, uint8_t *errSyncMask)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t regRd = 0x00;
+
+    const uint8_t SYNC_MASK_CTRL = 0x7B;
+    const uint8_t SYNC_MASK = 0x07;
+    const uint8_t SYNC_SHIFT = 5;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdGetSyncMask()\n");
+#endif
+
+    /* Check for valid errSyncMask pointer */
+    if (errSyncMask == NULL)
+    {
+       CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+               getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+       return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /*read sync mask internal reg */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, SYNC_MASK_CTRL, &regRd)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    *errSyncMask = (regRd >> SYNC_SHIFT) & SYNC_MASK;
+
+    return error;
+}
+
+
+/**
+ * \brief Performs read of enabled JESD Deframer lanes.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param lane Pointer to store the current enabled lanes
+ *
+ *  Value        |  Description of Lane
+ * --------------|-----------------------
+ *      8        | Lane 3 is enabled
+ *      4        | Lane 2 is enabled
+ *      2        | Lane 1 is enabled
+ *      1        | Lane 0 is enabled
+ *      0        | No lanes are enabled
+ *
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed lane is NULL
+ */
+mykonosDbgErr_t MYKONOS_deframerGetEnLanes(mykonosDevice_t *device, uint8_t *lane)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t regRd = 0x00;
+
+    const uint8_t DFM_LANE_EN = 0x7D;
+    const uint8_t LANE_MASK = 0x0F;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdGetEnLanes()\n");
+#endif
+
+    /* Check for valid lane pointer */
+    if (lane == NULL)
+    {
+       CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+               getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+       return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Read enable lanes internal reg */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, DFM_LANE_EN, &regRd)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    *lane = regRd & LANE_MASK;
+
+    return error;
+}
+
+
+/**
+ * \brief Performs Deframer Force SYNC requests
+ *
+ * Using this feature, the user can force SYNC request on the Deframer
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param syncReq sync Request parameter
+ * Setting the syncReq causes the deframer to assert the SYNC~.
+ * Clearing syncReq causes the deframer to de-assert the SYNC~.
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_deframerForceSyncReq(mykonosDevice_t *device, uint8_t syncReq)
+{
+    uint8_t syncReqWr = 0x00;
+
+    const uint8_t SYNC_REQ_MASK = 0x01;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_deframerForceSyncReq()\n");
+#endif
+
+    syncReqWr = (syncReq > 0) ? 0x01 : 0x00;
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_DEFRAMER_TEST, syncReqWr, SYNC_REQ_MASK, 0);
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+/**
+ * \brief Performs set JESD Deframer IRQ mask that will be used to generates interrupts
+ *
+ * Bad disparity, NIT disparity and Unexpected K char. Errors are counted and compared to the errThrs value.
+ * When the count is equal, either an IRQ is generated if the mask for the particular error is set.
+ * Configuration mismatch flag does not have a counter.
+ * Function is performed in all lanes.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errIrqMsk the value of the mask applied to the IRQ generation, possible combinations are:
+ *
+ *   IRQ       |   Bit mask   |  Description of errIrq
+ * ------------|--------------|-----------------------
+ *   CMM       |     3        | Configuration mismatch flag 0 if is CMM ok, 1 if CMM is detected
+ *   BADDISP   |     2        | Incorrect disparity flag 0 if is BADDISP ok, 1 if BADDISP is detected
+ *   NIT       |     1        | Not in table flag  0 if is NIT ok, 1 if NIT character is detected
+ *   UEKC      |     0        | Unexpected K character flag 0 if is UEKC ok, 1 if UEKC is detected
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ERROR_IRQ_MASK Illegal parameter passed for errIrqMsk, valid parameter is in the range of 0x00 to 0x1FF
+ */
+mykonosDbgErr_t MYKONOS_deframerSetIrqMask(mykonosDevice_t *device, uint8_t errIrqMsk)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t regRd = 0x0000;
+    uint8_t regWr = 0x0000;
+
+    const uint8_t IRQ_MSK_CTRL_ADDR = 0x7A;
+    const uint8_t IRQ_MSK = 0x0F;
+    const uint8_t CMMIRQ_MSK = 0x08;
+    const uint8_t CMMIRQ_CTRL = 0x7B;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdSetErrMask()\n");
+#endif
+
+    /* Check for valid errIrqMask */
+    if (errIrqMsk & ~IRQ_MSK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ERROR_IRQ_MASK,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ERROR_IRQ_MASK));
+        return MYKONOS_ERR_DBG_ERROR_IRQ_MASK;
+    }
+
+    /* Setting required IRQs */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, CMMIRQ_CTRL, &regRd)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    regWr = (CMMIRQ_MSK & errIrqMsk) | (regRd & ~CMMIRQ_MSK);
+
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, CMMIRQ_CTRL, regWr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    regWr = (errIrqMsk & 0x07) << 5;
+    if ((error = MYKONOS_jesdIndWrReg(device, jesdCore, IRQ_MSK_CTRL_ADDR, regWr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+    }
+
+    return error;
+}
+
+/**
+ * \brief Performs a read of the JESD IRQ vector for the deframer.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param errIrq Pointer to store the deframer IRQ status, the different bits mask are:
+ *
+*    IRQ       |   Bit mask   |  Description of errIrq
+ * ------------|--------------|-----------------------
+ *   CMM       |     3        | Configuration mismatch 0 if is CMM ok, 1 if CMM is detected
+ *   BADDISP   |     2        | Incorrect disparity 0 if is BADDISP ok, 1 if BADDISP character is detected
+ *   NIT       |     1        | Not in table 0 if is NIT ok, 1 if NIT character is detected
+ *   UEKC      |     0        | Unexpected K character 0 if is UEKC ok, 1 if UEKC character is detected
+ *
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER Data pointer passed errIrqMask is NULL
+ */
+mykonosDbgErr_t MYKONOS_deframerGetIrq(mykonosDevice_t *device, uint8_t *errIrq)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_OK;
+    mykonos_jesdcore_t jesdCore = MYK_DEFRAMER;
+    uint8_t regRd = 0x00;
+    uint8_t irqRd = 0x00;
+
+    const uint8_t IRQ_MSK_CTRL_ADDR = 0x7A;
+    const uint8_t CMMIRQ_CTRL = 0x7B;
+    const uint8_t CMMIRQ_MASK_REG = 0x10;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_jesdGetErrMask()\n");
+#endif
+
+    /* Check for valid errIrq pointer */
+    if (errIrq == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER));
+        return MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER;
+    }
+
+    /* Reading main IRQ */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, IRQ_MSK_CTRL_ADDR, &regRd)))
+    {
+        return error;
+    }
+
+    irqRd = (regRd & 0xE0) >> 5;
+
+
+    /* Reading CMMIRQ */
+    if ((error = MYKONOS_jesdIndRdReg(device, jesdCore, CMMIRQ_CTRL, &regRd)))
+    {
+        return error;
+    }
+
+    irqRd |= ((regRd & CMMIRQ_MASK_REG) >> 1);
+
+    /* Computing final value */
+    *errIrq = irqRd;
+
+    return error;
+}
+
+/**
+ * \brief Performs set JESD framer Pattern Generator.
+ *
+ * The Pattern Generator is a function for JESD testing. The JESD framer will be transmitting
+ * the "pattern" once the enabled.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param jesdCore selection for FRAMER and OBS_FRAMER
+ * \param pattern pattern to be transmitted by the Framer, is a 20 bit field having a range from 0x00000 to 0xFFFFF
+ * \param enable Bit used to enable the Pattern Generator facility
+ * \param toggle if 0 the transfer data will be not modified, if 1 the transfered data will be toggling
+ *
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_TOGGLE Toggle is not valid, valid values are 0 and 1.
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_FRAMER_PATTERN Pattern passed is outside the range valid range from 0x00000 to 0xFFFFF
+ * \retval MYKONOS_ERR_DBG_ILLEGAL_ENABLE Enable not valid, valid values are 0 and 1.
+ * \retval MYKONOS_ERR_DBG_PATTERN_GEN_ILLEGAL_JESD_CORE
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_framerSetPatternGen(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint32_t pattern, uint8_t enable, uint8_t toggle)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_FAIL;
+    uint16_t baseAddr = 0x00;
+    uint8_t rgWr = 0x00;
+
+    const uint32_t PATTERN_MSK = 0xFFFFF;
+    const uint8_t ENABLE_MASK = 0x01;
+    const uint8_t TOGGLE_MASK = 0x02;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_framerSetPatternGen()\n");
+#endif
+
+    /* JESD framer core selection */
+    if ((error = MYKONOS_framerCoreSel(jesdCore, MYKONOS_ADDR_FRAMER_PATTERN_GEN_EN, &baseAddr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    /* Check for valid enable */
+    if (enable == 1)
+    {
+        rgWr = ENABLE_MASK;
+        /* check for valid pattern */
+        if (pattern & ~PATTERN_MSK)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_FRAMER_PATTERN,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_FRAMER_PATTERN));
+            return MYKONOS_ERR_DBG_ILLEGAL_FRAMER_PATTERN;
+        }
+
+        /* Check for valid toggle */
+        if (toggle == 1)
+        {
+            rgWr += TOGGLE_MASK;
+
+        }
+        else if (toggle > 1)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_TOGGLE,
+                    getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_TOGGLE));
+            return MYKONOS_ERR_DBG_ILLEGAL_TOGGLE;
+        }
+    }
+    else if (enable ==0)
+    {
+        rgWr = 0x00;
+        pattern = 0x5A5A5;
+    }
+    else if (enable > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ILLEGAL_ENABLE,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ILLEGAL_ENABLE));
+        return MYKONOS_ERR_DBG_ILLEGAL_ENABLE;
+    }
+
+    /* Write pattern and enable */
+    CMB_SPIWriteByte(device->spiSettings, baseAddr, rgWr);
+    CMB_SPIWriteByte(device->spiSettings, (baseAddr + 1), (uint8_t)(pattern & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, (baseAddr + 2), (uint8_t)((pattern >> 8) & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, (baseAddr + 3), (uint8_t)((pattern >> 16) & 0x0F));
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+/**
+ * \brief Gets JESD framer Pattern generator
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param jesdCore selection for FRAMER and OBS_FRAMER
+ * \param pattern Pointer to store the programmed pattern
+ * \param enable Pointer to store the programmed enable
+ * \param toggle Pointer to store the programmed toggle
+ *
+ * \retval MYKONOS_ERR_DBG_PATTERN_GEN_NULL_PATTERN Function parameter pattern is a NULL pointer
+ * \retval MYKONOS_ERR_DBG_PATTERN_GEN_NULL_ENABLE Function parameter enable is a NULL pointer
+ * \retval MYKONOS_ERR_DBG_PATTERN_GEN_NULL_TOGGLE Function parameter toggle is a NULL pointer
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_framerGetPatternGen(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint32_t *pattern, uint8_t *enable, uint8_t *toggle)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_FAIL;
+    uint16_t baseAddr = 0x00;
+    uint8_t regRd = 0x00;
+    uint32_t patRd = 0x00000;
+    uint8_t toggleRd = 0x00;
+    uint8_t enableRd = 0x00;
+
+    const uint8_t ENABLE_MASK = 0x01;
+    const uint8_t TOGGLE_MASK = 0x02;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_framerGetPatternGen()\n");
+#endif
+
+    /* Check null parameter passed */
+    if (pattern == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_PATTERN_GEN_NULL_PATTERN,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_PATTERN_GEN_NULL_PATTERN));
+        return MYKONOS_ERR_DBG_PATTERN_GEN_NULL_PATTERN;
+    }
+
+    /* Check null parameter passed */
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_PATTERN_GEN_NULL_ENABLE,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_PATTERN_GEN_NULL_ENABLE));
+        return MYKONOS_ERR_DBG_PATTERN_GEN_NULL_ENABLE;
+    }
+
+    /* Check null parameter passed */
+    if (toggle == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_PATTERN_GEN_NULL_TOGGLE,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_PATTERN_GEN_NULL_TOGGLE));
+        return MYKONOS_ERR_DBG_PATTERN_GEN_NULL_TOGGLE;
+    }
+
+    /* JESD framer core selection */
+    if ((error = MYKONOS_framerCoreSel(jesdCore, MYKONOS_ADDR_FRAMER_PATTERN_GEN_EN, &baseAddr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    /* Read back pattern generator */
+    CMB_SPIReadByte(device->spiSettings, baseAddr, &regRd);
+    toggleRd = (regRd & TOGGLE_MASK)>>1;
+    enableRd = regRd & ENABLE_MASK;
+
+    CMB_SPIReadByte(device->spiSettings, (baseAddr + 1), &regRd);
+    patRd = regRd;
+
+    CMB_SPIReadByte(device->spiSettings, (baseAddr + 2), &regRd);
+    patRd |= (regRd << 8);
+
+    CMB_SPIReadByte(device->spiSettings, (baseAddr + 3), &regRd);
+    patRd |= ((regRd & 0x0F) << 16);
+
+    /* Write to pointers */
+    *pattern = patRd;
+    *toggle = toggleRd;
+    *enable = enableRd;
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+
+/**
+ * \brief Performs set JESD framer Zero data samples per lane.
+ *
+ * This functions will zero the Framer data samples for the specify lane or lanes.
+ * For the specified Framer or ObsFramer.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param jesdCore selection for FRAMER and OBS_FRAMER
+ * \param lane lanes to zero the Framer data samples
+ *
+ * \retval MYKONOS_ERR_DBG_ZERO_DATA_INV_LANE the lane selection is out of range
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_framerSetZeroData(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, mykonosLaneSel_t lane)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_FAIL;
+    uint16_t baseAddr = 0x00;
+
+    const uint32_t LANE_MSK = 0x0F;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_framerSetZeroData()\n");
+#endif
+
+    /* check for valid pattern */
+    if (lane & ~LANE_MSK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ZERO_DATA_INV_LANE,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ZERO_DATA_INV_LANE));
+        return MYKONOS_ERR_DBG_ZERO_DATA_INV_LANE;
+    }
+
+    /* JESD framer core selection */
+    if ((error = MYKONOS_framerCoreSel(jesdCore, MYKONOS_ADDR_FRAMER_DATA_SAMPLE_CTL, &baseAddr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    /* Write Framer Data Zero samples */
+    CMB_SPIWriteByte(device->spiSettings, baseAddr, lane);
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+
+/**
+ * \brief Performs get JESD framer Zero data samples.
+ *
+ * This functions will get the settings for zero the Framer data samples.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to Mykonos device data structure containing settings
+ * \param jesdCore selection for MYK_FRAMER and MYK_OBS_FRAMER
+ * \param lane Pointer to store the programmed pattern
+ *
+ * \retval MYKONOS_ERR_DBG_ZERO_DATA_LANE_NULL Function parameter lane is a NULL pointer
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_framerGetZeroData(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, mykonosLaneSel_t *lane)
+{
+    mykonosDbgErr_t error = MYKONOS_ERR_DBG_FAIL;
+    uint16_t baseAddr = 0x00;
+    uint8_t regRd = 0x00;
+
+    const uint8_t LANE_MASK = 0x0F;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_OK, "MYKONOS_framerGetZeroData()\n");
+#endif
+
+    /* Check null parameter passed */
+    if (lane == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_DBG_ZERO_DATA_LANE_NULL,
+                getDbgJesdMykonosErrorMessage(MYKONOS_ERR_DBG_ZERO_DATA_LANE_NULL));
+        return MYKONOS_ERR_DBG_ZERO_DATA_LANE_NULL;
+    }
+
+    /* JESD framer core selection */
+    if ((error = MYKONOS_framerCoreSel(jesdCore, MYKONOS_ADDR_FRAMER_DATA_SAMPLE_CTL, &baseAddr)) != MYKONOS_ERR_DBG_OK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, error,
+                getDbgJesdMykonosErrorMessage(error));
+        return error;
+    }
+
+    /* Read back data zeroed register */
+    CMB_SPIReadByte(device->spiSettings, baseAddr, &regRd);
+    regRd = (regRd & LANE_MASK);
+
+    /* Write to pointers */
+    *lane = regRd;
+
+    return MYKONOS_ERR_DBG_OK;
+}
+
+
+/**
+ * \brief Helper function to perform JESD framer core selection.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param jesdCore selection for FRAMER and OBS_FRAMER
+ * \param rxFramerAdd base address for Framer selection
+ * \param baseAddr Pointer to store the selected address base
+ *
+ * \retval MYKONOS_ERR_DBG_FRAMER_SEL_BASE_ADD_NULL base address is null
+ * \retval MYKONOS_ERR_DBG_FRAMER_ILLEGAL_JESD_CORE Only valid JESD cores are FRAMER and OBS_FRAMER
+ * \retval MYKONOS_ERR_DBG_OK Function completed successfully
+ */
+mykonosDbgErr_t MYKONOS_framerCoreSel(mykonos_jesdcore_t jesdCore, uint16_t rxFramerAdd, uint16_t *baseAddr)
+{
+    const uint16_t OFFSET = 0xD67;
+
+    /* Check null parameter passed */
+    if (baseAddr == NULL)
+    {
+        return MYKONOS_ERR_DBG_FRAMER_SEL_BASE_ADD_NULL;
+    }
+
+    /* Check for jesdCore and address assignment */
+    switch (jesdCore)
+    {
+        case MYK_FRAMER:
+            *baseAddr = rxFramerAdd;
+            break;
+
+        case MYK_OBS_FRAMER:
+            *baseAddr = rxFramerAdd + OFFSET;
+            break;
+
+        case MYK_DEFRAMER:
+        default:
+            return MYKONOS_ERR_DBG_FRAMER_ILLEGAL_JESD_CORE;
+            break;
+    }
+
+    return MYKONOS_ERR_DBG_OK;
+}
diff --git a/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h b/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h
new file mode 100644
index 000000000..deb0702bd
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h
@@ -0,0 +1,67 @@
+/**
+ * \file mykonos_dbgjesd.h
+ *
+ * \brief Contains macro definitions and global structure declarations for mykonos_dbgjesd.c
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef MYKONOS_DBGJESD_H_
+#define MYKONOS_DBGJESD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mykonos.h"
+#include "t_mykonos_gpio.h"
+#include "t_mykonos_dbgjesd.h"
+#include "mykonos_user.h"
+
+/*
+ *****************************************************************************
+ * JESD debug functions
+ *****************************************************************************
+ */
+mykonosDbgErr_t MYKONOS_deframerRd2Stat(mykonosDevice_t *device, uint8_t *defStat2);
+
+mykonosDbgErr_t MYKONOS_deframerSetErrThrs(mykonosDevice_t *device, uint8_t errThrs);
+mykonosDbgErr_t MYKONOS_deframerGetErrThrs(mykonosDevice_t *device, uint8_t *errThrs);
+
+mykonosDbgErr_t MYKONOS_deframerSetIrqMask(mykonosDevice_t *device, uint8_t errIrqMsk);
+mykonosDbgErr_t MYKONOS_deframerGetIrq(mykonosDevice_t *device, uint8_t *errIrq);
+
+mykonosDbgErr_t MYKONOS_deframerSetSyncMask(mykonosDevice_t *device, uint8_t errSyncMask);
+mykonosDbgErr_t MYKONOS_deframerGetSyncMask(mykonosDevice_t *device, uint8_t *errSyncMask);
+
+mykonosDbgErr_t MYKONOS_deframerRdErrCntr(mykonosDevice_t *device, mykonosLaneSel_t laneSel, mykonosLaneErr_t *laneErr);
+
+mykonosDbgErr_t MYKONOS_deframerGetErrLane(mykonosDevice_t *device, mykonosErrType_t errType, uint8_t *lane);
+
+mykonosDbgErr_t MYKONOS_deframerRstErrCntr(mykonosDevice_t *device, mykonosErrType_t errType, mykonosLaneSel_t lane);
+mykonosDbgErr_t MYKONOS_deframerRstErrIrq(mykonosDevice_t *device, mykonosErrType_t errType, mykonosLaneSel_t lane);
+
+mykonosDbgErr_t MYKONOS_deframerGetEnLanes(mykonosDevice_t *device, uint8_t *lane);
+
+mykonosDbgErr_t MYKONOS_deframerForceSyncReq(mykonosDevice_t *device, uint8_t syncReq);
+
+mykonosDbgErr_t MYKONOS_framerSetPatternGen(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint32_t pattern, uint8_t enable, uint8_t toggle);
+mykonosDbgErr_t MYKONOS_framerGetPatternGen(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint32_t *pattern, uint8_t *enable, uint8_t *toggle);
+
+mykonosDbgErr_t MYKONOS_framerSetZeroData(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, mykonosLaneSel_t lane);
+mykonosDbgErr_t MYKONOS_framerGetZeroData(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, mykonosLaneSel_t *lane);
+
+/* Helper functions for indirect access to internal register */
+mykonosDbgErr_t MYKONOS_jesdIndWrReg(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint8_t intAddr, uint8_t data);
+mykonosDbgErr_t MYKONOS_jesdIndRdReg(mykonosDevice_t *device, mykonos_jesdcore_t jesdCore, uint8_t intAddr, uint8_t *data);
+
+mykonosDbgErr_t MYKONOS_framerCoreSel(mykonos_jesdcore_t jesdCore, uint16_t rxFramerAdd, uint16_t *baseAddr);
+
+
+const char* getDbgJesdMykonosErrorMessage(mykonosDbgErr_t errorCode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MYKONOS_DBGJESD_H_ */
diff --git a/mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h b/mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h
new file mode 100644
index 000000000..da98c56e1
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h
@@ -0,0 +1,160 @@
+/*!
+ * \file t_mykonos_dbgjesd.h
+ *
+ * \brief Contains definitions and structure declarations for mykonos_dbgjesd.c
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef T_MYKONOS_DBGJESD_H_
+#define T_MYKONOS_DBGJESD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+
+/**
+ *  \brief Enum of unique error codes from the Mykonos DBG API functions.
+ * Each error condition in the library should get its own enum value to allow
+ * easy debug of errors.
+ */
+typedef enum
+{
+    MYKONOS_ERR_DBG_OK = 0,
+    MYKONOS_ERR_DBG_FAIL = 1,
+    MYKONOS_ERR_DBG_ILLEGAL_LANE_NUMBER,
+    MYKONOS_ERR_DBG_ILLEGAL_ERROR_TYPE,
+    MYKONOS_ERR_DBG_ILLEGAL_ERROR_SELECTED,
+    MYKONOS_ERR_DBG_ILLEGAL_JESD_CORE,
+    MYKONOS_ERR_DBG_ILLEGAL_DATA_POINTER,
+    MYKONOS_ERR_DBG_NULL_PARM,
+    MYKONOS_ERR_DBG_ERROR_SYNC_MASK,
+    MYKONOS_ERR_DBG_ERROR_IRQ_MASK,
+    MYKONOS_ERR_DBG_ERROR_THRESHOLD,
+
+    MYKONOS_ERR_DBG_ILLEGAL_FRAMER_PATTERN,
+    MYKONOS_ERR_DBG_ILLEGAL_ENABLE,
+    MYKONOS_ERR_DBG_PATTERN_GEN_NOT_ENABLED,
+    MYKONOS_ERR_DBG_ILLEGAL_TOGGLE,
+    MYKONOS_ERR_DBG_PATTERN_GEN_NULL_PATTERN,
+    MYKONOS_ERR_DBG_PATTERN_GEN_NULL_ENABLE,
+    MYKONOS_ERR_DBG_PATTERN_GEN_NULL_TOGGLE,
+
+    MYKONOS_ERR_DBG_ZERO_DATA_INV_LANE,
+    MYKONOS_ERR_DBG_ZERO_DATA_LANE_NULL,
+
+    MYKONOS_ERR_DBG_FRAMER_SEL_BASE_ADD_NULL,
+    MYKONOS_ERR_DBG_FRAMER_ILLEGAL_JESD_CORE,
+
+    MYKONOS_ERR_DBG_NUMBER_OF_ERRORS
+} mykonosDbgErr_t;
+
+/**
+ *  \brief Enum to select Jesd core
+ */
+typedef enum
+{
+    MYK_FRAMER = 0,     /*!< Framer for the main receive channel */
+    MYK_DEFRAMER = 1,   /*!< Deframer for Tx channel */
+    MYK_OBS_FRAMER = 2  /*!< Framer for the observation channel */
+} mykonos_jesdcore_t;
+
+/**
+ *  \brief Enum to set the Lane
+ */
+typedef enum
+{
+    MYK_LANE_0 = 0, /*!< Lane 0 */
+    MYK_LANE_1 = 1, /*!< Lane 1 */
+    MYK_LANE_2 = 2, /*!< Lane 2 */
+    MYK_LANE_3 = 3, /*!< Lane 3 */
+} mykonosLaneSel_t;
+
+/**
+ *  \brief Enum to set the Lane
+ */
+typedef enum
+{
+    MYK_BAD_DISP_CNTR = 0,  /*!< Bad disparity */
+    MYK_NIT_CNTR = 1,       /*!< Not in table */
+    MYK_UEKC_CNTR = 2,      /*!< Unexpected K character */
+} mykonosCtrSel_t;
+
+/**
+ *  \brief Enum for the IRQ mask
+ */
+typedef enum
+{
+    MYK_SYNC_BADDISP = 0x04,    /*!< Bad disparity mask enable */
+    MYK_SYNC_NIT = 0x02,        /*!< Not in table */
+    MYK_SYNC_UEKC = 0x01,       /*!< Unexpected K character */
+} mykonosSyncMasks_t;
+
+/**
+ *  \brief Enum for the IRQ mask
+ */
+typedef enum
+{
+    MYK_IRQ_CMM = 0x08,     /*!< Configuration mismatch mask enable */
+    MYK_IRQ_BADDISP = 0x04, /*!< Bad disparity mask enable */
+    MYK_IRQ_NIT = 0x02,     /*!< Not in table */
+    MYK_IRQ_UEKC = 0x01,    /*!< Unexpected K character */
+} mykonosIrqMasks_t;
+
+/**
+ *  \brief Enum for the error handling type
+ */
+typedef enum
+{
+    MYK_CLEAR = 1,          /*!< Clear error handling type */
+    MYK_RESET = 2,          /*!< Reset error handling type */
+    MYK_CLEAR_RESET = 3,    /*!< Clear and Reset error handling type */
+} mykonosHandleType_t;
+
+/**
+ *  \brief Enum for the error type
+ */
+typedef enum
+{
+    MYK_CMM = 0x7B,     /*!< configuration mismatch */
+    MYK_BADDISP = 0x6D, /*!< Bad disparity */
+    MYK_NIT = 0x6E,     /*!< Not in table */
+    MYK_UEKC = 0x6F,    /*!< Unexpected K character */
+} mykonosErrType_t;
+
+/**
+ *  \brief Data structure to hold the error counters per a given lane
+ */
+typedef struct
+{
+    uint8_t badDispCntr;    /*!< bad disparity counter can 0-255 */
+    uint8_t nitCntr;        /*!< not in table counter can 0-255 */
+    uint8_t uekcCntr;       /*!< unexpected K character counter can 0-255 */
+} mykonosLaneErr_t;
+
+/**
+ *  \brief Data structure to hold the deframer status
+ */
+typedef struct
+{
+    uint8_t deframerStatus;         /*!< deframer status see deframer status function */
+    uint8_t deframerStatus2;        /*!< deframer status2 see function MYKONOS_deframerRd2Stat(...)*/
+    uint8_t fifoDepth;              /*!< fifo depth */
+    uint8_t phaseOffsetLFMC_sysref; /*!< phase offset might not be needed*/
+    uint8_t fifoFullEMpty;          /*!< fifo full/empty */
+    mykonosLaneErr_t lane0;         /*!< Lane 0 errors */
+    mykonosLaneErr_t lane1;         /*!< Lane 1 errors */
+    mykonosLaneErr_t lane2;         /*!< Lane 2 errors */
+    mykonosLaneErr_t lane3;         /*!< Lane 3 errors */
+    uint8_t irqMask;                /*!< Mask for IRQ generation */
+    uint8_t errCntrMax;             /*!< Max error counters */
+    uint8_t enabledLanes;           /*!< Lanes that are enabled */
+} mykonosDeframerStatus_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* T_MYKONOS_DBGJESD_H_ */
diff --git a/mpm/lib/mykonos/adi/mykonos_gpio.c b/mpm/lib/mykonos/adi/mykonos_gpio.c
new file mode 100644
index 000000000..2da33dcdb
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_gpio.c
@@ -0,0 +1,5420 @@
+/**
+ *\file mykonos_gpio.c
+ *
+ *\brief Contains Mykonos APIs for transceiver GPIO configuration and control.
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+
+/**
+ * \page Disclaimer Legal Disclaimer
+ * WARRANTY DISCLAIMER: THE SOFTWARE AND ANY RELATED INFORMATION AND/OR ADVICE IS PROVIDED ON AN
+ * �AS IS� BASIS, WITHOUT REPRESENTATIONS, GUARANTEES OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
+ * ORAL OR WRITTEN, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include "common.h"
+#include "mykonos.h"
+#include "mykonos_gpio.h"
+#include "mykonos_macros.h"
+#include "mykonos_user.h"
+
+
+/**
+ * \brief Helper function for return of character string based on 32-bit mykonosGpioErr_t enum value
+ *
+ * To save codespace, these error strings are ifdef'd out unless the user
+ * adds a define MYKONOS_VERBOSE to their workspace.  This function can be
+ * useful for debug.  Each function also returns unique error codes to
+ * make it easier to determine where the code broke.
+ *
+ * \param errorCode is enumerated error code value
+ *
+ * \return Returns character string based on enumerated value
+ */
+const char* getGpioMykonosErrorMessage(mykonosGpioErr_t errorCode)
+{
+#if MYKONOS_VERBOSE == 0
+        return "";
+
+ #else
+
+    switch (errorCode)
+    {
+        case MYKONOS_ERR_GPIO_OK:
+            return "";
+
+        case MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED:
+            return "MYKONOS_setGpioMonitorOut() Mykonos monitor output not enable, please run GPIO setup with the correct setup for enabling the monitor output functionality\n";
+
+        case MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE:
+            return "MYKONOS_setGpioMonitorOut()The index specified is incorrect, index available are from 0x01 to 0x42\n";
+
+        case MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM:
+            return "MYKONOS_getGpioMonitorOut() if the monitorIndex is null.\n";
+
+        case MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM:
+            return "MYKONOS_getGpioMonitorOut() if the monitorMask is null.\n";
+
+        case MYKONOS_ERR_MGCRX1_STEP_INV_PARAM:
+            return "MYKONOS_setRx1GainCtrlPin() An invalid step size has been passed, valid step sizes for increment/decrement is 0-7\n";
+
+        case MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM:
+            return "MYKONOS_setRx1GainCtrlPin() An invalid decrement pin has been passed \n";
+
+        case MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM:
+            return "MYKONOS_setRx1GainCtrlPin() An invalid increment pin has been passed, \n";
+
+        case MYKONOS_ERR_MGCRX2_STEP_INV_PARAM:
+            return "MYKONOS_setRx2GainCtrlPin() An invalid step size has been passed, valid step sizes for increment/decrement is 0-7\n";
+
+        case MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM:
+            return "MYKONOS_setRx2GainCtrlPin() An invalid decrement pin has been passed\n";
+
+        case MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM:
+            return "MYKONOS_setRx2GainCtrlPin() An invalid increment pin has been passed\n";
+
+        case MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM:
+            return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to incStep.\n";
+
+        case MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM:
+            return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to decStep.\n";
+
+        case MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM:
+            return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to rx1GainIncPin.\n";
+
+        case MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM:
+            return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to rx1GainDecPin.\n";
+
+        case MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM:
+            return "MYKONOS_getRx1GainCtrlPin() if a null value has been passed to enable.\n";
+
+        case MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM:
+            return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to incStep.\n";
+
+        case MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM:
+            return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to decStep.\n";
+
+        case MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM:
+            return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to rx1GainIncPin.\n";
+
+        case MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM:
+            return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to rx1GainDecPin.\n";
+
+        case MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM:
+            return "MYKONOS_getRx2GainCtrlPin() if a null value has been passed to enable.\n";
+
+        case MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM:
+            return "MYKONOS_setTx1AttenCtrlPin() An invalid step size has been passed, valid step sizes for att are 0x00-0x1F\n";
+
+        case MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM:
+            return "MYKONOS_setTx1AttenCtrlPin() An invalid decrement pin has been passed\n";
+
+        case MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM:
+            return "MYKONOS_setTx1AttenCtrlPin() An invalid decrement pin has been passed\n";
+
+        case MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM:
+            return "MYKONOS_setTx2AttenCtrlPin() An invalid step size has been passed, valid step sizes for att are 0x00-0x1F\n";
+
+        case MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM:
+            return "MYKONOS_setTx2AttenCtrlPin() An invalid decrement pin has been passed\n";
+
+        case MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM:
+            return "MYKONOS_setTx2AttenCtrlPin() An invalid decrement pin has been passed\n";
+
+        case MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM:
+            return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to stepSize.\n";
+
+        case MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM:
+            return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to tx2AttenIncPin.\n";
+
+        case MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM:
+            return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to tx2AttenDecPin.\n";
+
+        case MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM:
+            return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to enable.\n";
+
+        case MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM:
+            return "MYKONOS_getTx2AttenCtrlPin() if a null value has been passed to useTx1ForTx2.\n";
+
+        case MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM:
+            return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to stepSize.\n";
+
+        case MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM:
+            return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to tx1AttenIncPin.\n";
+
+        case MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM:
+            return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to tx1AttenDecPin.\n";
+
+        case MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM:
+            return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to enable.\n";
+
+        case MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM:
+            return "MYKONOS_getTx1AttenCtrlPin() if a null value has been passed to useTx1ForTx2.\n";
+
+        case MYKONOS_ERR_GPIO_SRC_PARAM_INV:
+            return "MYKONOS_setGpioSourceCtrl() An invalid source control parameter has been passed\n";
+
+        case MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM:
+            return "MYKONOS_getGpioSetLevel() gpioPinSetLevel pointer is NULL in function parameter\n";
+
+        case MYKONOS_ERR_READGPIOSPI_NULL_PARM:
+            return "MYKONOS_readGpioPinLevel() has a null *gpioPinLevel parameter\n";
+
+        case MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM:
+            return "MYKONOS_getGpio3v3PinLevel() has a null *gpio3v3PinLevel parameter\n";
+
+        case MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM:
+            return "MYKONOS_setupAuxDac() has a null device->auxIo pointer\n";
+
+        case MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM:
+            return "MYKONOS_getGpio3v3Oe() has NULL pointer for function parameter gpio3v3OutEn\n;";
+
+        case MYKONOS_ERR_INV_GP_INT_MASK_PARM:
+            return "General Purpose Interrupt source mask parameter is invalid\n";
+
+        case MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM:
+            return "MYKONOS_readGpInterruptStatus() has NULL status parameter\n";
+
+        case MYKONOS_ERR_SET_GPIO_3V3_INV_MODE:
+            return "Invalid GPIO3v3 source control mode\n";
+
+        case MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL:
+            return "gpio3v3 members have invalid value for the GPIO3v3 source control mode.\n";
+
+        case MYKONOS_ERR_SET_GPIO_1V8_INV_MODE:
+            return "The GPIO mode enum is not a valid value in MYKONOS_setupGpio\n";
+
+        case MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM:
+            return "MYKONOS_getGpio3v3SetLevel() has NULL pointer for function parameter gpio3v3SetLevel\n";
+
+        case MYKONOS_ERR_GPIO_OE_INV_PARAM:
+            return "MYKONOS_setGpioOe() had invalid parameter gpioOutEn (valid range 0 - 0x07FFFF)\n";
+
+        case MYKONOS_ERR_GETGPIO_OE_NULL_PARM:
+            return "MYKONOS_getGpioOe() has NULL function parameter\n";
+
+        case MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO:
+            return "device->auxIo structure has NULL pointer in MYKONOS_writeAuxDac()\n";
+
+        case MYKONOS_ERR_READAUXADC_NULL_PARAM:
+            return "MYKONOS_readAuxAdc() has NULL function parameter\n";
+
+        case MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER:
+            return "Invalid pointer detected in MYKONOS_setupGpio3v3()\n";
+
+        case MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER:
+            return "Invalid pointer detected in MYKONOS_setupGpio()\n";
+
+        case MYKONOS_ERR_SET_ARMGPIO_INV_POINTER:
+            return "Invalid pointer detected at device->auxIo->armGpio in MYKONOS_setArmGpioPins() \n";
+
+        case MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR:
+            return "ARM Command Error in MYKONOS_setArmGpioPins()\n";
+
+        case MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID:
+            return "Invalid Signal ID detected in device->auxIo->armGpio \n";
+
+        case MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN:
+            return "Out of range GPIO pin detected \n";
+
+        case MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR:
+            return "ARM command Error in MYKONOS_setRadioControlPinMode()\n";
+
+        case MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE:
+            return "device->auxIo->auxDacValue, AUXDAC value out of range in MYKONOS_setupAuxDacs()\n";
+
+        case MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE:
+            return "auxDacCode value out of range in MYKONOS_writeAuxDac()\n";
+
+        case MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX:
+            return "auxDacIndex value out of range in MYKONOS_writeAuxDac()\n";
+
+        case MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM:
+            return "auxAdcChannel value out of range in MYKONOS_setAuxAdcChannel()\n";
+
+        case MYKONOS_ERR_SETUPAUXADC_INV_VCODIV:
+            return "device->clocks->clkPllVcoDiv value not supported in MYKONOS_setupAuxAdcs()\n";
+
+        case MYKONOS_ERR_INV_AUX_ADC_DEC_PARM:
+            return "adcDecimation value out of range in MYKONOS_setupAuxAdcs()\n";
+
+        case MYKONOS_ERR_SLICER_INV_RX1_SEL:
+            return "invalid RX1 GPIO pin selection for Slicer control in MYKONOS_setRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_INV_RX2_SEL:
+            return "invalid RX2 GPIO pin selection for Slicer control in MYKONOS_setRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE:
+            return "slicer step is out of range for the SLicer control in MYKONOS_setRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_EN_INV:
+            return "invalid enable in MYKONOS_setRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM:
+            return "rx1Pins is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM:
+            return "rx1Pins is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_STEP_NULL_PARM:
+            return "slicerStep is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_SLICER_EN_NULL_PARM:
+            return "enable is null pointer for the passed parameter in MYKONOS_getRxSlicerCtrl()\n";
+
+        case MYKONOS_ERR_GAINCOMP_NULL_STRUCT:
+            return "gain compensation structure gainComp is not initialised in MYKONOS_getRxGainCompensation()\n";
+
+        case MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT:
+            return "gain compensation structure gainComp is not initialised in MYKONOS_setRxGainCompensation()\n";
+
+        case MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET:
+            return "gain compensation structure gainComp->rx1Offset is invalid in MYKONOS_setRxGainCompensation()\n";
+
+        case MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET:
+            return "gain compensation structure gainComp->rx2Offset is invalid in MYKONOS_setRxGainCompensation()\n";
+
+        case MYKONOS_ERR_GAINCOMP_INV_STEP:
+            return "gain compensation structure gainComp->compStep is invalid in MYKONOS_setRxGainCompensation()\n";
+
+        case MYKONOS_ERR_GAINCOMP_INV_EN:
+            return "enable is not valid in MYKONOS_setRxGainCompensation()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_NULL_STRUCT:
+            return "floating point formatter structure floatFrmt not initialised in MYKONOS_getFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT:
+            return "floating point formatter structure floatFrmt not initialised in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE:
+            return "floating point formatter structure floatFrmt.roundMode not valid parameter in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT:
+            return "floating point formatter structure floatFrmt.dataFormat not valid parameter in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN:
+            return "floating point formatter structure floatFrmt.encNan not valid parameter in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS:
+            return "floating point formatter structure floatFrmt.expBits not valid parameter in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_LEADING:
+            return "floating point formatter structure floatFrmt.leading not valid parameter in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_RX1ATT:
+            return "not valid rx1 attenuation parameter passed in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_INV_RX2ATT:
+            return "not valid rx2 attenuation parameter passed in MYKONOS_setFloatPointFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT:
+            return "not valid rx2 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT:
+            return "not valid rx1 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_SET_INV_EN:
+            return "not valid enable parameter passed in MYKONOS_setRxEnFloatPntFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT:
+            return "null pointer passed for rx1 attenuation in MYKONOS_setRxEnFloatPntFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT:
+            return "null pointer passed for rx2 attenuation in MYKONOS_setRxEnFloatPntFrmt()\n";
+
+        case MYKONOS_ERR_FLOATFRMT_NULL_ENABLE:
+            return "null pointer passed for enable in MYKONOS_setRxEnFloatPntFrmt()\n";
+
+        case MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM:
+            return "MYKONOS_setupTempSensor() has NULL function parameter\n";
+
+        case MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION:
+            return "tempDecimation value out of range in MYKONOS_setupTempSensor()\n";
+
+        case MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW:
+            return "tempWindow value out of range in MYKONOS_setupTempSensor()\n";
+
+        case MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET:
+            return "offset value out of range in MYKONOS_setupTempSensor()\n";
+
+        case MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM:
+            return "MYKONOS_getTempSensorConfig() has NULL function parameter\n";
+
+        case MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM:
+            return "MYKONOS_readTempSensor() has NULL function parameter\n";
+
+        case MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED:
+            return "MYKONOS_readTempSensor() temperature sensor reading is not locked\n";
+
+        case MYKONOS_ERR_GPIO_HYBRID_RX1_PIN:
+            return "MYKONOS_setRxHybridGainChangePin() not valid pin has been passed for RX1 hybrid gain control.\n";
+
+        case MYKONOS_ERR_GPIO_HYBRID_RX2_PIN:
+            return "MYKONOS_setRxHybridGainChangePin() not valid pin has been passed for RX2 hybrid gain control.\n";
+
+        case MYKONOS_ERR_GPIO_HYBRID_ORX_PIN:
+            return "MYKONOS_setObsRxHybridGainChangePin() if invalid pin has been passed for ORX hybrid gain control.\n";
+
+        case MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID:
+            return "MYKONOS_setObsRxHybridGainChangePin() if the observation gain mode is not set to Hybrid.\n";
+
+        case MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM:
+            return "MYKONOS_getRxHybridGainChangePin() null value has been passed to rx1GainChangePin.\n";
+
+        case MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM:
+            return "MYKONOS_getRxHybridGainChangePin() null value has been passed to rx1GainChangePin.\n";
+
+        case  MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID:
+            return "MYKONOS_setRxHybridGainChangePin() if gain control is not hybrid.\n";
+
+        case MYKONOS_ERR_GAIN_CONTROL_NOT_AGC :
+            return "MYKONOS_setRxAgcEnSyncPin() or MYKONOS_getObsRxAgcEnSyncPin() if the observation gain control mode is not set to AGC.\n";
+
+        case MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC:
+            return "MYKONOS_getObsRxAgcEnSyncPin() if the observation gain control mode is not set to AGC.\n";
+
+        case MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN:
+            return "MYKONOS_setRxAgcEnSyncPin() if invalid pin has been passed for RX1 AGC sync gain control.\n";
+
+        case MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN:
+            return "MYKONOS_setRxAgcEnSyncPin() if invalid pin has been passed for RX2 AGC sync gain control.\n";
+
+        case MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM:
+            return "MYKONOS_getRxAgcEnSyncPin()  if a null value has been passed to rx1AgcSyncPin.\n";
+
+        case MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM:
+            return "MYKONOS_getRxAgcEnSyncPin()  if a null value has been passed to rx2AgcSyncPin.\n";
+
+        case MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN:
+           return "MYKONOS_setObsRxAgcEnSyncPin() if invalid pin has been passed for ORX AGC sync gain control.\n";
+
+        case MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM:
+            return "MYKONOS_getObsRxAgcEnSyncPin() if a null value has been passed to obsRxAgcSyncPin.\n";
+
+        case MYKONOS_ERR_SLICER_INV_OBS_RX_SEL:
+            return "Invalid observation channel GPIO pin selection for Slicer control passed to MYKONOS_setObsRxSlicerCtrl().\n";
+
+        case MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE:
+            return "Slicer step is out of range passed to MYKONOS_setObsRxSlicerCtrl().\n";
+
+        case MYKONOS_ERR_SLICER_OBS_RX_EN_INV:
+            return "Invalid enable passed to MYKONOS_setObsRxSlicerCtrl().\n";
+
+        case MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM:
+            return "ObsRxPins is null pointer for the passed parameter passed to MYKONOS_getObsRxSlicerCtrl().\n";
+
+        case MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM:
+            return "SlicerStep is null pointer for the passed parameter passed to MYKONOS_getObsRxSlicerCtrl().\n";
+
+        case MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM:
+            return "Enable is null pointer for the passed parameter passed to MYKONOS_getObsRxSlicerCtrl().\n";
+
+        case MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT:
+            return "Gain compensation structure gainComp is not initialised in MYKONOS_setObsRxGainCompensation().\n";
+
+        case MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET:
+            return "Gain compensation structure gainComp->obsRxOffset is invalid in MYKONOS_setObsRxGainCompensation().\n";
+
+        case MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP:
+            return "Gain compensation structure gainComp->compStep is invalid in MYKONOS_setObsRxGainCompensation().\n";
+
+        case MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN:
+            return "Enable is not valid in MYKONOS_setObsRxGainCompensation().\n";
+
+        case MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT:
+            return "Observation channel gain compensation structure gainComp is not initialised in MYKONOS_getObsRxGainCompensation().\n";
+
+        case MYKONOS_ERR_GETGPIODRV_NULL_PARAM:
+            return "Null parameter passed to the function MYKONOS_getGpioDrv().\n";
+
+        case MYKONOS_ERR_GPIO_DRV_INV_PARAM:
+            return "GPIO out of range passed to function MYKONOS_setGpioDrv(), valid GPIOs are in the range 0x00000 to 0x7FFFF.\n";
+
+        case MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM:
+            return "GPIO out of range -valid GPIOs are in the range 0x00000 to 0x7FFFF.\n";
+
+        case MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM:
+            return "Null parameter passed to the function MYKONOS_getGpioSlewRate().\n";
+
+        case MYKONOS_ERR_CMOS_DRV_NULL_PARAM:
+            return "Null parameter passed to the function.\n";
+
+        case MYKONOS_ERR_CMOS_DRV_INV_PARAM:
+            return "Incorrect drive strength, valid settings are given by mykonosCmosPadDrvStr_t.\n";
+
+        case MYKONOS_ERR_SPI2_INV_GPIO:
+            return "if an invalid GPIO pin configuration is passed to MYKONOS_spi2GpioSetup().\n";
+
+        default:
+            return "";
+    }
+
+ #endif
+}
+
+/**
+ * \brief This API function configures the monitor output function for the GPIOs
+ *
+ * The monitor outputs are grouped in set of nibbles, the user can set
+ * individual nibbles for having the monitor output function across the available GPIO.
+ * In order to enable the GPIO monitor function the function setupGpio has to be run and the
+ * structure should have the proper setup:
+ * - device->auxIo->gpio->gpioOe = 0xXXXFF the first D7:D0 GPIOs will have the output enable
+ * - device->auxIo->gpio->gpioSrcCtrl3_0 = GPIO_MONITOR_MODE
+ * - device->auxIo->gpio->gpioSrcCtrl4_7 = GPIO_MONITOR_MODE
+
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->gpio->gpioOe
+ * - device->auxIo->gpio->gpioSrcCtrl3_0
+ * - device->auxIo->gpio->gpioSrcCtrl4_7
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \param monitorIndex which will be the index at which the outputs are going to be set. see table in documentation
+ *
+ * \param monitorMask which GPIO outputs are going to active, the available GPIO
+ * bit 0 will represent MYKGPIO0 and bit 7 will represent MYKGPIO7.
+ *
+ * \retval MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE if GPIO Monitor output index is not in table
+ * \retval MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED if GPIO source control not set for Monitor output
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpioMonitorOut(mykonosDevice_t *device, uint8_t monitorIndex, uint8_t monitorMask)
+{
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+    const uint8_t INDEX_MASK = 0x42;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioMonitorOut()\n");
+#endif
+
+    /* Error checking for correct index. */
+    if (monitorIndex > INDEX_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE));
+        return MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE;
+    }
+
+    /* Set the GPIO monitor index and the required pin configuration. */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_INDEX, monitorIndex);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_ENABLE, monitorMask);
+
+    return error;
+}
+
+/**
+ * \brief This API function reads the GPIO monitor index from Mykonos
+ *
+ * The monitor outputs are grouped in two set of nibbles, the user can set
+ * individual nibbles for having the monitor output function, this nibbles
+ * will output the monitor output as per the index set.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ * - GPIO output enable
+ * - GPIO source control
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param monitorIndex which will be the index at which the outputs are set to.
+ * \param monitorMask which will be enable the monitor function.
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM if the monitorIndex is null.
+ * \retval MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM if the monitorMask is null.
+ */
+mykonosGpioErr_t MYKONOS_getGpioMonitorOut(mykonosDevice_t *device, uint8_t *monitorIndex, uint8_t *monitorMask)
+{
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+    uint8_t indexRd = 0;
+    uint8_t monMaskRd = 0;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioMonitorOut()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (monitorIndex == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM));
+        return MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM;
+    }
+
+    if (monitorMask == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM));
+        return MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM;
+    }
+
+    /* Get GPIO monitor out enable. */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_ENABLE, &monMaskRd);
+
+    /* Get the GPIO monitor index and the required pin configuration. */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_MONITOR_INDEX, &indexRd);
+
+    /* assigning return values to the pointers passed */
+    *monitorMask = monMaskRd;
+    *monitorIndex = indexRd;
+
+    return error;
+}
+
+
+
+
+/**
+ * \brief This API function configures the GPIO inputs for controlling RX gain
+ *
+ * This API function configures the GPIO input pin and step size to allow the BBP to control gain changes in Rx1 signal chain.
+ * A high pulse on the 'rx1GainIncPin' in pin control mode will increment the gain by the value set in incStep'.
+ * A high pulse on the 'rx1GainDecPin' in pin control mode will decrement the gain by the value set in 'decStep'.
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \param incStep This sets the change (increase) in gain index that is applied when the
+ * increment gain pin  (in MGC pin control mode) is pulsed.
+ *
+ * \param decStep This configures the decrement in gain index that should be applied
+ * when the decrement gain pin (in MGC pin control mode) is pulsed.
+ *
+ * \param rx1GainIncPin mykonosGpioSelect_t These bits select the GPIO used as the enable for
+ * the Rx1 Manual Increment gain input according to the following:
+ * MYKGPIO0 or MYKGPIO10
+ *
+ * \param rx1GainDecPin mykonosGpioSelect_t These bits select the GPIO used as the enable for
+ * the Rx1 Manual Decrement gain input according to the following:
+ * MYKGPIO1 or MYKGPIO11
+ *
+ * \param enable 0 = Disable the gain pin control for Rx1
+ *               1 = enable the gain pin control for Rx1
+ *
+ * \retval MYKONOS_ERR_MGCRX1_STEP_INV_PARAM if an invalid step size has been passed
+ * \retval MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM if invalid increment pin has been passed
+ * \retval MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM if invalid decrement pin has been passed
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setRx1GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx1GainIncPin, mykonosGpioSelect_t rx1GainDecPin, uint8_t enable)
+{
+    uint8_t wrtPin = 0x00;
+    uint8_t wrtStep = 0x00;
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+    const uint8_t SHIFT_CH1 = 0x00;
+    const uint8_t SHIFT_INC = 0x05;
+    const uint8_t SHIFT_DEC = 0x02;
+    const uint8_t MAX_STEP = 0x07;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRx1GainCtrlPin()\n");
+#endif
+
+    /* If enable then check for the next otherwise go directly to disable */
+    if (enable > 0)
+    {
+        /* Error checking for correct step. */
+        if ((incStep > MAX_STEP) | (decStep > MAX_STEP))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_MGCRX1_STEP_INV_PARAM,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_MGCRX1_STEP_INV_PARAM));
+            return MYKONOS_ERR_MGCRX1_STEP_INV_PARAM;
+        }
+
+        /* Pin configuration assignment*/
+        switch (rx1GainIncPin)
+        {
+            case MYKGPIO0:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO10:
+                wrtPin |= 0x04;
+                break;
+
+            default:
+                return MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM;
+        }
+
+        switch (rx1GainDecPin)
+        {
+            case MYKGPIO1:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO11:
+                wrtPin |= 0x01;
+                break;
+
+            default:
+                return MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM;
+        }
+    }
+
+    /* Setting increment step. */
+    wrtStep = (incStep<<SHIFT_INC) | (decStep<<SHIFT_DEC) | (enable<<SHIFT_CH1);
+
+    /* Set the GPIO input pin configuration and the step size. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, wrtStep, 0xFD, 0);
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, wrtPin, 0x0F, 0);
+
+    return error;
+}
+
+/**
+ * \brief This API function returns the configuration RX1 gain Pin control
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param incStep will contain the step that is used for increment.
+ * \param decStep will contain the step that is used for decrement.
+ * \param rx1GainIncPin this will have the pin used for increment.
+ * \param rx1GainDecPin this will have the pin used for decrement.
+ * \param enable will contain the enable status for this channel if it is set to 1 then this
+ * function is enable for this channel, if it is 0 it is not enable
+ *
+ * \retval MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM if a null value has been passed to incStep
+ * \retval MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM if a null value has been passed to decStep
+ * \retval MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM if a null value has been passed to rx1GainIncPin
+ * \retval MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM if a null value has been passed to rx1GainDecPin
+ * \retval MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM if a null value has been passed to enable
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getRx1GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx1GainIncPin, mykonosGpioSelect_t *rx1GainDecPin, uint8_t *enable)
+{
+    uint8_t readVal = 0x00;
+
+    const uint8_t MASK_GPIO_CH1 = 0x0F;
+    const uint8_t MASK_EN_CH1 = 0x01;
+    const uint8_t MASK_STEP_INC = 0xE0;
+    const uint8_t MASK_STEP_DEC = 0x1C;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRx1GainCtrlPin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (incStep == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM));
+        return MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM;
+    }
+
+    if (decStep == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM));
+        return MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM;
+    }
+
+    if (rx1GainIncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM));
+        return MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM;
+    }
+
+    if (rx1GainDecPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM));
+        return MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM;
+    }
+
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM,
+               getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM));
+        return MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, &readVal);
+    readVal = readVal & MASK_GPIO_CH1;
+
+    if (readVal & 0x04)
+    {
+        *rx1GainIncPin = MYKGPIO10;
+    }
+    else
+    {
+        *rx1GainIncPin = MYKGPIO0;
+    }
+
+    if (readVal & 0x01)
+    {
+        *rx1GainDecPin = MYKGPIO11;
+    }
+    else
+    {
+        *rx1GainDecPin = MYKGPIO1;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, &readVal);
+
+    *enable = readVal & MASK_EN_CH1;
+
+    *incStep = (readVal & MASK_STEP_INC) >> 5;
+
+    *decStep = (readVal & MASK_STEP_DEC) >> 2;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function configures the GPIO inputs for controlling RX gain
+ *
+ * This API function configures the GPIO input pin and step size to allow the BBP to control gain changes in Rx2 signal chain.
+ * A high pulse on the 'rx2GainIncPin' in pin control mode will increment the gain by the value set in incStep'.
+ * A high pulse on the 'rx2GainDecPin' in pin control mode will decrement the gain by the value set in 'decStep'.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \param incStep This sets the change (increase) in gain index that is applied when the
+ * increment gain pin (in MGC pin control mode) is pulsed.
+ *
+ * \param decStep This configures the decrement in gain index that should be applied
+ * when the decrement gain pin (in MGC pin control mode) is pulsed.
+ *
+ * \param rx2GainIncPin mykonosGpioSelect_t These bits select the GPIO used as the enable for
+ * the Rx2 Manual Increment gain input according to the following:
+ * MYKGPIO3 or MYKGPIO13
+ *
+ * \param rx2GainDecPin mykonosGpioSelect_t These bits select the GPIO used as the enable for
+ * the Rx2 Manual Decrement gain input according to the following:
+ * MYKGPIO4 or MYKGPIO14
+ *
+ * \param enable 0 = Disable the gain pin control for Rx2
+ *               1 = enable the gain pin control for Rx2
+ *
+ *
+ * \retval MYKONOS_ERR_MGCRX2_STEP_INV_PARAM if an invalid step size is passed
+ * \retval MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM if invalid increment pin has been passed
+ * \retval MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM if invalid decrement pin has been passed
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setRx2GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx2GainIncPin, mykonosGpioSelect_t rx2GainDecPin, uint8_t enable)
+{
+    uint8_t wrtPin = 0x00;
+    uint8_t wrtStep = 0x00;
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+    const uint8_t SHIFT_CH2 = 0x01;
+    const uint8_t SHIFT_INC = 0x5;
+    const uint8_t SHIFT_DEC = 0x2;
+    const uint8_t MAX_STEP = 0x07;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRx2GainCtrlPin()\n");
+#endif
+
+    /* If enable then check for the next otherwise go directly to disable */
+    if (enable > 0)
+    {
+        /* Error checking for correct step. */
+        if ((incStep > MAX_STEP) | (decStep > MAX_STEP))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_MGCRX2_STEP_INV_PARAM,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_MGCRX2_STEP_INV_PARAM));
+            return MYKONOS_ERR_MGCRX2_STEP_INV_PARAM;
+        }
+
+        /* Pin configuration assignment*/
+        switch (rx2GainIncPin)
+        {
+            case MYKGPIO3:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO13:
+                wrtPin |= 0x40;
+                break;
+
+            default:
+                return MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM;
+        }
+
+        switch (rx2GainDecPin)
+        {
+            case MYKGPIO4:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO14:
+                wrtPin |= 0x10;
+                break;
+
+            default:
+                return MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM;
+        }
+    }
+
+    /* Setting increment step. */
+    wrtStep = (incStep<<SHIFT_INC) | (decStep<<SHIFT_DEC) | (enable<<SHIFT_CH2);
+
+    /* Set the GPIO input pin configuration and the step size. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, wrtStep, 0xFE, 0);
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, wrtPin, 0xF0, 0);
+
+    return error;
+}
+
+/**
+ * \brief This API function returns the configuration RX2 gain Pin control
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param incStep will contain the step that is used for increment.
+ * \param decStep will contain the step that is used for decrement.
+ * \param rx2GainIncPin this will have the pin used for increment.
+ * \param rx2GainDecPin this will have the pin used for decrement.
+ * \param enable will contain the enable status for this channel if it is set to 1 then this
+ * function is enable for this channel, if it is 0 it is not enable
+ *
+ * \retval MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM if a null value has been passed to incStep
+ * \retval MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM if a null value has been passed to decStep
+ * \retval MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM if a null value has been passed to rx1GainIncPin
+ * \retval MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM if a null value has been passed to rx1GainDecPin
+ * \retval MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM if a null value has been passed to enable
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getRx2GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx2GainIncPin, mykonosGpioSelect_t *rx2GainDecPin, uint8_t *enable)
+{
+    uint8_t readVal = 0x00;
+
+    const uint8_t MASK_GPIO_CH2 = 0xF0;
+    const uint8_t MASK_EN_CH2 = 0x02;
+    const uint8_t MASK_STEP_INC = 0xE0;
+    const uint8_t MASK_STEP_DEC = 0x1C;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRx2GainCtrlPin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (incStep == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM));
+        return MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM;
+    }
+
+    if (decStep == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM));
+        return MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM;
+    }
+
+    if (rx2GainIncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM));
+        return MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM;
+    }
+
+    if (rx2GainDecPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM));
+        return MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM;
+    }
+
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM,
+               getGpioMykonosErrorMessage(MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM));
+        return MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL, &readVal);
+    readVal = readVal & MASK_GPIO_CH2;
+
+    if (readVal & 0x40)
+    {
+        *rx2GainIncPin = MYKGPIO13;
+    }
+    else
+    {
+        *rx2GainIncPin = MYKGPIO3;
+    }
+
+    if (readVal & 0x10)
+    {
+        *rx2GainDecPin = MYKGPIO14;
+    }
+    else
+    {
+        *rx2GainDecPin = MYKGPIO4;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG, &readVal);
+
+    *enable = (readVal & MASK_EN_CH2) >> 1;
+
+    *incStep = (readVal & MASK_STEP_INC) >> 5;
+
+    *decStep = (readVal & MASK_STEP_DEC) >> 2;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function set the pins for hybrid gain control
+ *
+ * In order to call this function the gain mode should be set to Hybrid.
+ * The AGC gain change will be controlled with the selected GPIO pin:
+ * A pulse on the 'rx1GainChangePin' in hybrid pin control will enable the AGC gain change for RX1
+ * A pulse on the 'rx2GainChangePin' in hybrid pin control will enable the AGC gain change for RX2
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param rx1GainChangePin GPIO pin that will be used for hybrid gain change control, the available pins for RX1 channel
+ * hybrid control are:
+ * MYKGPIO1
+ * MYKGPIO10
+ * MYKGPIO11
+ * MYKGPIONAN for no GPIO selected
+ *
+ * \param rx2GainChangePin GPIO pin that will be used for hybrid gain change control, the available pins for RX2 channel
+ * hybrid control are:
+ * MYKGPIO4
+ * MYKGPIO10
+ * MYKGPIO13
+ * MYKGPIONAN for no GPIO selected
+ *
+ * \retval MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID if gain control is not hybrid
+ * \retval MYKONOS_ERR_GPIO_HYBRID_RX1_PIN if invalid pin has been passed for RX1 hybrid gain control.
+ * \retval MYKONOS_ERR_GPIO_HYBRID_RX2_PIN if invalid pin has been passed for RX2 hybrid gain control.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t rx1GainChangePin, mykonosGpioSelect_t rx2GainChangePin)
+{
+    uint8_t hybridPinWrite = 0x00;
+    uint8_t pinRx1 = 0x00;
+    uint8_t pinRx2 = 0x00;
+
+    const uint8_t HYBRID_RX_PIN_MASK = 0x0F;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxHybridGainChangePin()\n");
+#endif
+
+    /* Check if in Hybrid Mode */
+    if (device->rx->rxGainCtrl->gainMode != HYBRID)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID));
+        return MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID;
+    }
+
+    /* Pin configuration assignment for RX1 and RX2 */
+    switch (rx1GainChangePin)
+    {
+        case MYKGPIO1:
+            pinRx1 |= 0x00;
+            break;
+        case MYKGPIO10:
+            pinRx1 |= 0x01;
+            break;
+        case MYKGPIO11:
+            pinRx1 |= 0x02;
+            break;
+        case MYKGPIONAN:
+            pinRx1 |= 0x03;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX1_PIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX1_PIN));
+            return MYKONOS_ERR_GPIO_HYBRID_RX1_PIN;
+    }
+
+    switch (rx2GainChangePin)
+    {
+        case MYKGPIO4:
+            pinRx2 |= 0x00;
+            break;
+        case MYKGPIO10:
+            pinRx2 |= 0x04;
+            break;
+        case MYKGPIO13:
+            pinRx2 |= 0x08;
+            break;
+        case MYKGPIONAN:
+            pinRx2 |= 0x0C;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX2_PIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX2_PIN));
+            return MYKONOS_ERR_GPIO_HYBRID_RX2_PIN;
+    }
+
+    /* Setting GPIO control for RX1 and RX2 */
+    hybridPinWrite = (pinRx1 | pinRx2);
+
+    /* Writing GPIO pin configuration for hybrid mode. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, hybridPinWrite, HYBRID_RX_PIN_MASK, 0);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+
+/**
+ * \brief This API function gets the pin configuration for hybrid gain control of RX1 and RX2
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param rx1GainChangePin Will return the GPIO pin used for Rx1 in hybrid gain control.
+ * \param rx2GainChangePin Will return the GPIO pin used for Rx2 in hybrid gain control.
+ *
+ * \retval MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM if a null value has been passed to rx1GainChangePin
+ * \retval MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM if a null value has been passed to rx2GainChangePin
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1GainChangePin, mykonosGpioSelect_t *rx2GainChangePin)
+{
+    uint8_t hybridPinRead = 0x00;
+    uint8_t pinRx1 = 0x00;
+    uint8_t pinRx2 = 0x00;
+    mykonosGpioSelect_t rx1Pin = MYKGPIONAN;
+    mykonosGpioSelect_t rx2Pin = MYKGPIONAN;
+
+    const uint8_t MASK_RX1_PIN = 0x03;
+    const uint8_t MASK_RX2_PIN = 0x0C;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxHybridGainChangePin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (rx1GainChangePin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM));
+        return MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM;
+    }
+
+    if (rx2GainChangePin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM));
+        return MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, &hybridPinRead);
+    pinRx1 = hybridPinRead & MASK_RX1_PIN;
+    pinRx2 = hybridPinRead & MASK_RX2_PIN;
+
+    /* Pin configuration mapping assignment for RX1 and RX2 */
+    switch (pinRx1)
+    {
+        case 0x00:
+            rx1Pin = MYKGPIO1;
+            break;
+        case 0x01:
+            rx1Pin = MYKGPIO10;
+            break;
+        case 0x02:
+            rx1Pin = MYKGPIO11;
+            break;
+        default:
+            rx1Pin = MYKGPIONAN;
+            break;
+    }
+
+    switch (pinRx2)
+    {
+        case 0x00:
+            rx2Pin = MYKGPIO4;
+            break;
+        case 0x04:
+            rx2Pin = MYKGPIO10;
+            break;
+        case 0x08:
+            rx2Pin = MYKGPIO13;
+            break;
+        default:
+            rx2Pin = MYKGPIONAN;
+            break;
+    }
+
+    /* Setting pins to passed pointers */
+    *rx1GainChangePin = rx1Pin;
+    *rx2GainChangePin = rx2Pin;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief This API function set the pins for hybrid gain control
+ *
+ * In order to call this function the gain mode should be set to Hybrid.
+ * The AGC gain change will be controlled with the selected GPIO pin:
+ * A pulse on the 'obsRxGainChangePin' in hybrid pin control will enable the AGC gain change for observation channel
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param obsRxGainChangePin GPIO pin that will be used for hybrid gain change control, the available pins for observation channel
+ * hybrid control are:
+ * MYKGPIO6
+ * MYKGPIO10
+ * MYKGPIO17
+ * MYKGPIONAN for none selected
+ *
+ * \retval MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID if the observation gain mode is not set to Hybrid
+ * \retval MYKONOS_ERR_GPIO_HYBRID_ORX_PIN if invalid pin has been passed for ORX hybrid gain control.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxGainChangePin)
+{
+    uint8_t hybridPinWrite = 0x00;
+    uint8_t pinOrx = 0x00;
+
+    const uint8_t HYBRID_ORX_PIN_MASK = 0x30;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxHybridGainChangePin()\n");
+#endif
+
+    /* Check if in Hybrid Mode */
+    if (device->obsRx->orxGainCtrl->gainMode != HYBRID)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID));
+        return MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID;
+    }
+
+    /* Pin configuration assignment for RX1 and RX2 */
+    switch (obsRxGainChangePin)
+    {
+        case MYKGPIO6:
+            pinOrx |= 0x00;
+            break;
+        case MYKGPIO10:
+            pinOrx |= 0x10;
+            break;
+        case MYKGPIO17:
+            pinOrx |= 0x20;
+            break;
+        case MYKGPIONAN:
+            pinOrx |= 0x30;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_ORX_PIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_ORX_PIN));
+            return MYKONOS_ERR_GPIO_HYBRID_ORX_PIN;
+    }
+
+    /* Setting GPIO control for observation channel */
+    hybridPinWrite = pinOrx;
+
+    /* Writing GPIO pin configuration for hybrid mode. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, hybridPinWrite, HYBRID_ORX_PIN_MASK, 0);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function gets the pin configuration for hybrid gain control of observation channel
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param obsRxGainChangePin Will return the GPIO pin used for observation channel in hybrid gain control.
+ *
+ * \retval MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM if a null value has been passed to obsRxGainChangePin
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxGainChangePin)
+{
+    uint8_t hybridPinRead = 0x00;
+    uint8_t pinOrx = 0x00;
+    mykonosGpioSelect_t orxPin = MYKGPIONAN;
+
+    const uint8_t MASK_ORX_PIN = 0x30;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxHybridGainChangePin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (obsRxGainChangePin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM));
+        return MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, &hybridPinRead);
+    pinOrx = hybridPinRead & MASK_ORX_PIN;
+
+    /* Pin configuration mapping assignment for RX1 and RX2 */
+    switch (pinOrx)
+    {
+        case 0x00:
+            orxPin = MYKGPIO6;
+            break;
+        case 0x10:
+            orxPin = MYKGPIO10;
+            break;
+        case 0x20:
+            orxPin = MYKGPIO17;
+            break;
+        default:
+            orxPin = MYKGPIONAN;
+            break;
+    }
+
+    /* Setting pins to passed pointer */
+    *obsRxGainChangePin = orxPin;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function set the pins for sync AGC gain control
+ *
+ * In order to call this function the RX gain control should be set to AGC mode.
+ * The AGC gain sync will be controlled with the selected GPIO pin:
+ * A pulse on the 'rx1AgcSyncPin' in hybrid pin control will enable the AGC gain sync for RX1
+ * A pulse on the 'rx2AgcSyncPin' in hybrid pin control will enable the AGC gain sync for RX2
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param rx1AgcSyncPin GPIO pin that will be used for AGC sync gain control, the available pins for RX1 channel are:
+ * MYKGPIO1
+ * MYKGPIO10
+ * MYKGPIO11
+ * MYKGPIONAN for no GPIO selected
+ *
+ * \param rx2AgcSyncPin GPIO pin that will be used for AGC sync gain control, the available pins for RX2 channel are:
+ * MYKGPIO4
+ * MYKGPIO10
+ * MYKGPIO13
+ * MYKGPIONAN for no GPIO selected
+ *
+ * \retval MYKONOS_ERR_GAIN_CONTROL_NOT_AGC if the RX gain control mode is not set to AGC.
+ * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN if invalid pin has been passed for RX1 AGC sync gain control.
+ * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN if invalid pin has been passed for RX2 AGC sync gain control.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t rx1AgcSyncPin, mykonosGpioSelect_t rx2AgcSyncPin)
+{
+    uint8_t agcSyncPinWrite = 0x00;
+    uint8_t pinRx1 = 0x00;
+    uint8_t pinRx2 = 0x00;
+
+    const uint8_t SYNC_RX_PIN_MASK = 0x0F;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxAgcEnSyncPin()\n");
+#endif
+
+    /* Check if in Hybrid Mode */
+    if (device->rx->rxGainCtrl->gainMode != AGC)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAIN_CONTROL_NOT_AGC,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GAIN_CONTROL_NOT_AGC));
+        return MYKONOS_ERR_GAIN_CONTROL_NOT_AGC;
+    }
+
+    /* Pin configuration assignment for RX1 and RX2 */
+    switch (rx1AgcSyncPin)
+    {
+        case MYKGPIO1:
+            pinRx1 |= 0x00;
+            break;
+        case MYKGPIO10:
+            pinRx1 |= 0x01;
+            break;
+        case MYKGPIO11:
+            pinRx1 |= 0x02;
+            break;
+        case MYKGPIONAN:
+            pinRx1 |= 0x03;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN));
+            return MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN;
+    }
+
+    switch (rx2AgcSyncPin)
+    {
+        case MYKGPIO4:
+            pinRx2 |= 0x00;
+            break;
+        case MYKGPIO10:
+            pinRx2 |= 0x04;
+            break;
+        case MYKGPIO13:
+            pinRx2 |= 0x08;
+            break;
+        case MYKGPIONAN:
+            pinRx2 |= 0x0C;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN));
+            return MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN;
+    }
+
+    /* Setting GPIO control for RX1 and RX2 */
+    agcSyncPinWrite = (pinRx1 | pinRx2);
+
+    /* Writing GPIO pin configuration for Sync AGC. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, agcSyncPinWrite, SYNC_RX_PIN_MASK, 0);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function gets the GPIO pin configuration for AGC gain sync control of RX1 and RX2
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param rx1AgcSyncPin Will return the GPIO pin used for RX1 channel AGC gain sync control,
+ *
+ * \param rx2AgcSyncPin Will return the GPIO pin used for RX2 channel AGC gain sync control,
+ *
+ * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM if a null value has been passed to rx1AgcSyncPin
+ * \retval MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM if a null value has been passed to rx2AgcSyncPin
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1AgcSyncPin, mykonosGpioSelect_t *rx2AgcSyncPin)
+{
+    uint8_t agcSyncPinRead = 0x00;
+    uint8_t pinRx1 = 0x00;
+    uint8_t pinRx2 = 0x00;
+    mykonosGpioSelect_t rx1Pin = MYKGPIONAN;
+    mykonosGpioSelect_t rx2Pin = MYKGPIONAN;
+
+    const uint8_t MASK_RX1_PIN = 0x03;
+    const uint8_t MASK_RX2_PIN = 0x0C;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxHybridGainChangePin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (rx1AgcSyncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM));
+        return MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM;
+    }
+
+    if (rx2AgcSyncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM));
+        return MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL, &agcSyncPinRead);
+    pinRx1 = agcSyncPinRead & MASK_RX1_PIN;
+    pinRx2 = agcSyncPinRead & MASK_RX2_PIN;
+
+    /* Pin configuration mapping assignment for RX1 and RX2 */
+    switch (pinRx1)
+    {
+        case 0x00:
+            rx1Pin = MYKGPIO1;
+            break;
+        case 0x01:
+            rx1Pin = MYKGPIO10;
+            break;
+        case 0x02:
+            rx1Pin = MYKGPIO11;
+            break;
+        default:
+            rx1Pin = MYKGPIONAN;
+            break;
+    }
+
+    switch (pinRx2)
+    {
+        case 0x00:
+            rx2Pin = MYKGPIO4;
+            break;
+        case 0x04:
+            rx2Pin = MYKGPIO10;
+            break;
+        case 0x08:
+            rx2Pin = MYKGPIO13;
+            break;
+        default:
+            rx2Pin = MYKGPIONAN;
+            break;
+    }
+
+    /* Setting pins to passed pointers */
+    *rx1AgcSyncPin = rx1Pin;
+    *rx2AgcSyncPin = rx2Pin;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief This API function set the pins for AGC gain Sync control
+ *
+ * In order to call this function the gain mode should be set to AGC mode.
+ * The AGC gain sync will be controlled with the selected GPIO pin:
+ * A pulse on the 'obsRxGainChangePin' in hybrid pin control will enable the AGC gain change for observation channel
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param obsRxAgcSyncPin GPIO pin that will be used for AGC sync gain control, the available pins for observation channel are:
+ * MYKGPIO6
+ * MYKGPIO10
+ * MYKGPIO17
+ * MYKGPIONAN for none selected
+ *
+ * \retval MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC if the observation gain control mode is not set to AGC
+ * \retval MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN  if invalid pin has been passed for ORX AGC sync gain control.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxAgcSyncPin)
+{
+    uint8_t agcSyncPinWrite = 0x00;
+    uint8_t pinOrx = 0x00;
+
+    const uint8_t SYNC_ORX_PIN_MASK = 0x30;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxAgcEnSyncPin()\n");
+#endif
+
+    /* Check if in Hybrid Mode */
+    if (device->obsRx->orxGainCtrl->gainMode != AGC)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC));
+        return MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC;
+    }
+
+    /* Pin configuration assignment for observation channel */
+    switch (obsRxAgcSyncPin)
+    {
+        case MYKGPIO6:
+            pinOrx |= 0x00;
+            break;
+        case MYKGPIO10:
+            pinOrx |= 0x10;
+            break;
+        case MYKGPIO17:
+            pinOrx |= 0x20;
+            break;
+        case MYKGPIONAN:
+            pinOrx |= 0x30;
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN));
+            return MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN;
+    }
+
+    /* Setting GPIO control for observation channel */
+    agcSyncPinWrite = pinOrx;
+
+    /* Writing GPIO pin configuration for Sync AGC mode. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, agcSyncPinWrite, SYNC_ORX_PIN_MASK, 0);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function gets the pin configuration for AGC Sync gain control of observation channel
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param obsRxAgcSyncPin Will return the GPIO pin used for observation channel AGC gain sync control,
+ *
+ * \retval MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM if a null value has been passed to obsRxAgcSyncPin
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxAgcSyncPin)
+{
+    uint8_t agcSyncPinRead = 0x00;
+    uint8_t pinOrx = 0x00;
+    mykonosGpioSelect_t orxPin = MYKGPIONAN;
+
+    const uint8_t MASK_ORX_PIN = 0x30;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxAgcEnSyncPin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (obsRxAgcSyncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM));
+        return MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL, &agcSyncPinRead);
+    pinOrx = agcSyncPinRead & MASK_ORX_PIN;
+
+    /* Pin configuration mapping assignment for observation channel */
+    switch (pinOrx)
+    {
+        case 0x00:
+            orxPin = MYKGPIO6;
+            break;
+        case 0x10:
+            orxPin = MYKGPIO10;
+            break;
+        case 0x20:
+            orxPin = MYKGPIO17;
+            break;
+        default:
+            orxPin = MYKGPIONAN;
+            break;
+    }
+
+    /* Setting pins to passed pointer */
+    *obsRxAgcSyncPin = orxPin;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief This API function configures the GPIO inputs for controlling Tx attenuation settings
+ *
+ * This allows to control the TX attenuation using GPIO inputs. When a low to high transition is
+ * applied to the configure GPIO input the attenuation will change by the desire step.
+ * The stepSize parameter will set the attenuation change applied.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \param stepSize the step that will increase or decrease the Tx1 channel attenuation.
+ * This parameter sets the change in Tx attenuation for each increment or decrement signal received in incr/decr mode.
+ * Step of 1 changes attenuation by 0.05dB.
+ *
+ * \param tx1AttenIncPin This parameter is the GPIO pin configuration that will be controlling the increment
+ * of Tx attenuation. Available pins are:
+ * Tx1 increment: MYKGPIO4 or MYKGPIO12
+ *
+ * \param tx1AttenDecPin This parameter is the GPIO pin configuration that will be controlling the decrement
+ * of Tx attenuation. Available pins are:
+ * Tx1 decrement: MYKGPIO5 or MYKGPIO13
+ *
+ * \param enable 0 = Disable the attenuation pin control for Tx1
+ *               1 = enable the attenuation pin control for Tx1
+ *
+ * \param useTx1ForTx2 is used to return if TX1 settings are used for TX2 channel.
+ *
+ * \retval MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM if an invalid step size is passed
+ * \retval MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM if an invalid channel for TX is passed
+ * \retval MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM if an invalid channel for TX is passed
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx1AttenIncPin, mykonosGpioSelect_t tx1AttenDecPin, uint8_t enable, uint8_t useTx1ForTx2)
+{
+    uint8_t wrtPin = 0;
+    uint8_t tpcMode = 0x0;
+    uint8_t tpcMaskTx2 = 0x00;
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+    const uint8_t TX_INCDEC_MASK = 0x1F;
+    const uint8_t TX_PIN_MASK = 0x0F;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setTx1AttenCtrlPin()\n");
+#endif
+
+    /* If enable then check for the next otherwise go directly to disable */
+    if(enable > 0)
+    {
+        /* Error checking for correct step. */
+        if (stepSize >  TX_INCDEC_MASK)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM));
+            return MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM;
+        }
+
+        /* Pin configuration assignment for Tx1 increments */
+        switch (tx1AttenIncPin)
+        {
+            case MYKGPIO4:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO12:
+                wrtPin |= 0x01;
+                break;
+
+            default:
+                return MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM;
+        }
+
+        /* Pin configuration assignment for Tx1 decrements */
+        switch (tx1AttenDecPin)
+        {
+            case MYKGPIO5:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO13:
+                wrtPin |= 0x04;
+                break;
+
+            default:
+                return MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM;
+        }
+
+        /* Setting TPC mode corresponding to the enable */
+        tpcMode = 0x03;
+
+        /* Setting TPC control for Tx2 using Tx1 */
+        if (useTx1ForTx2 > 0)
+        {
+            tpcMode |= 0x1C;
+            tpcMaskTx2 = 0x1F;
+        }
+        else
+        {
+            tpcMaskTx2 = 0x13;
+        }
+    }
+    else
+    {
+        /* Setting TPC mode corresponding for no Pin control */
+        tpcMode = 0x05;
+        tpcMaskTx2 = 0x1F;
+    }
+
+    /* Setting increment step. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, stepSize, TX_INCDEC_MASK, 0);
+
+    /* Set the TPC mode for GPIO control. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, tpcMode, tpcMaskTx2, 0);
+
+    /* Set the GPIO input pin configuration and the step size. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, wrtPin, TX_PIN_MASK, 0);
+
+    return error;
+}
+
+/**
+ * \brief This API function returns the configuration TX1 attenuation Pin control
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param stepSize will contain the step that is used for increment and decrement.
+ * \param tx1AttenIncPin this will have the pin used for increment.
+ * \param tx1AttenDecPin this will have the pin used for decrement.
+ * \param enable will contain the enable status for this channel if it is set to 1 then this
+ * function is enable for this channel, if it is 0 it is not enable
+ * \param useTx1ForTx2 is used to return if TX1 settings are used for TX2 channel.
+ *
+ * \retval MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM if a null value has been passed to stepSize
+ * \retval MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM if a null value has been passed to tx1AttenIncPin
+ * \retval MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM if a null value has been passed to tx1AttenDecPin
+ * \retval MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM if a null value has been passed to enable
+ * \retval MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM if a null value has been passed to useTx1ForTx2
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx1AttenIncPin, mykonosGpioSelect_t *tx1AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2)
+{
+    uint8_t readVal = 0x00;
+    uint8_t en = 0x00;
+
+    const uint8_t MASK_TPC_CH1 = 0x03;
+    const uint8_t MASK_TPC_CH1FCH2 = 0x10;
+    const uint8_t MASK_TPC_STEP = 0x1F;
+    const uint8_t MASK_TPC_GPIO_CH1 = 0x0F;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getTx1AttenCtrlPin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (stepSize == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM));
+        return MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM;
+    }
+
+    if (tx1AttenIncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM));
+        return MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM;
+    }
+
+    if (tx1AttenDecPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM));
+        return MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM;
+    }
+
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM));
+        return MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM;
+    }
+
+    if (useTx1ForTx2 == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM,
+               getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM));
+        return MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, &readVal);
+    readVal = readVal & MASK_TPC_GPIO_CH1;
+
+    if (readVal & 0x01)
+    {
+        *tx1AttenIncPin = MYKGPIO12;
+    }
+    else
+    {
+        *tx1AttenIncPin = MYKGPIO4;
+    }
+
+    if (readVal & 0x04)
+    {
+        *tx1AttenDecPin = MYKGPIO13;
+    }
+    else
+    {
+        *tx1AttenDecPin = MYKGPIO5;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, &readVal);
+
+    en = readVal & MASK_TPC_CH1;
+
+    *enable = (en == MASK_TPC_CH1) ? 1 : 0;
+
+    *useTx1ForTx2 = readVal & MASK_TPC_CH1FCH2;
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, &readVal);
+
+    *stepSize = readVal & MASK_TPC_STEP;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This API function configures the GPIO inputs for controlling Tx attenuation settings
+ *
+ * This allows to control the TX attenuation using GPIO inputs. when a low to high transition is
+ * applied to the configure GPIO input the attenuation will change by the desire step.
+ * The stepSize parameter will set the attenuation change applied.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ *
+ * \param stepSize the step that will increase or decrease the Tx2 channel attenuation.
+ * This parameter sets the change in Tx attenuation for each increment or decrement signal received in incr/decr mode.
+ * Step of 1 changes attenuation by 0.05dB.
+ *
+ * \param tx2AttenIncPin This parameter is the GPIO pin configuration that will be controlling the increment
+ * of Tx attenuation. Available pins are:
+ * Tx2 increment: MYKGPIO6 or MYKGPIO14
+ *
+ * \param tx2AttenDecPin This parameter is the GPIO pin configuration that will be controlling the decrement
+ * of Tx attenuation. Available pins are:
+ * Tx2 decrement: MYKGPIO7 or MYKGPIO15
+ *
+ * \param enable 0 = Disable the attenuation pin control for Tx2
+ *               1 = enable the attenuation pin control for Tx2
+ *
+ * \retval MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM if an invalid step size is passed
+ * \retval MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM if an invalid channel for TX is passed
+ * \retval MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM if an invalid channel for TX is passed
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx2AttenIncPin, mykonosGpioSelect_t tx2AttenDecPin, uint8_t enable)
+{
+    uint8_t wrtPin = 0;
+    uint8_t tpcMode = 0x0;
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+
+    const uint8_t TX_INCDEC_MASK = 0x1F;
+    const uint8_t TX2_TPC_MASK = 0x1C;
+    const uint8_t TX2_WRTPIN = 0xf0;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setTx2AttenCtrlPin()\n");
+#endif
+
+    /* If enable then check for the next otherwise go directly to disable */
+    if(enable > 0)
+    {
+        /* Error checking for correct step. */
+        if (stepSize >  TX_INCDEC_MASK)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM));
+            return MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM;
+        }
+
+        /* Pin configuration assignment for Tx2 increments */
+        switch (tx2AttenIncPin)
+        {
+            case MYKGPIO6:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO14:
+                wrtPin |= 0x10;
+                break;
+
+            default:
+                return MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM;
+        }
+
+        /* Pin configuration assignment for Tx2 decrements */
+        switch (tx2AttenDecPin)
+        {
+            case MYKGPIO7:
+                wrtPin |= 0x00;
+                break;
+            case MYKGPIO15:
+                wrtPin |= 0x40;
+                break;
+
+            default:
+                return MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM;
+        }
+
+        /* Setting TPC mode corresponding to the enable */
+        tpcMode = 0x0C;
+    }
+    else
+    {
+          /* Setting TPC mode corresponding for no Pin control */
+          tpcMode = 0x05;
+    }
+
+    /* Setting increment step. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, stepSize, TX_INCDEC_MASK, 0);
+
+    /* Set the TPC mode for GPIO control. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, tpcMode, TX2_TPC_MASK, 0);
+
+    /* Set the GPIO input pin configuration and the step size. */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, wrtPin, TX2_WRTPIN, 0);
+
+    return error;
+}
+
+/**
+ * \brief This API function returns the configuration TX2 attenuation Pin control
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ * - device->spiSettings->chipSelectIndex
+
+ *
+ * \param device is structure pointer to the Mykonos data structure containing settings
+ * \param stepSize will contain the step that is used for increment and decrement.
+ * \param tx2AttenIncPin this will have the pin used for increment.
+ * \param tx2AttenDecPin this will have the pin used for decrement.
+ * \param enable will contain the enable status for this channel if it is set to 1 then this
+ * function is enable for this channel, if it is 0 it is not enable
+ * \param useTx1ForTx2 is used to return if TX1 settings are used for TX2 channel.
+ *
+ * \retval MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM if a null value has been passed to stepSize
+ * \retval MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM if a null value has been passed to tx1AttenIncPin
+ * \retval MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM if a null value has been passed to tx1AttenDecPin
+ * \retval MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM if a null value has been passed to enable
+ * \retval MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM if a null value has been passed to useTx1ForTx2
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx2AttenIncPin, mykonosGpioSelect_t *tx2AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2)
+{
+    uint8_t readVal = 0x00;
+    uint8_t en = 0x00;
+
+    const uint8_t MASK_TPC_CH2 = 0x0C;
+    const uint8_t MASK_TPC_CH1FCH2 = 0x10;
+    const uint8_t MASK_TPC_STEP = 0x1F;
+    const uint8_t MASK_TPC_GPIO_CH2 = 0xF0;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getTx2AttenCtrlPin()\n");
+#endif
+
+    /* Checking for null passed parameters */
+    if (stepSize == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM));
+        return MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM;
+    }
+
+    if (tx2AttenIncPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM));
+        return MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM;
+    }
+
+    if (tx2AttenDecPin == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM));
+        return MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM;
+    }
+
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM));
+        return MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM;
+    }
+
+    if (useTx1ForTx2 == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM,
+               getGpioMykonosErrorMessage(MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM));
+        return MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_GPIO_CFG, &readVal);
+    readVal = readVal & MASK_TPC_GPIO_CH2;
+
+    if (readVal & 0x10)
+    {
+        *tx2AttenIncPin = MYKGPIO14;
+    }
+    else
+    {
+        *tx2AttenIncPin = MYKGPIO6;
+    }
+
+    if (readVal & 0x40)
+    {
+        *tx2AttenDecPin = MYKGPIO15;
+    }
+    else
+    {
+        *tx2AttenDecPin = MYKGPIO7;
+    }
+
+    /* Getting Pin configuration assignment*/
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_TPC_CONFIG, &readVal);
+
+    en = readVal & MASK_TPC_CH2;
+
+    *enable = (en == MASK_TPC_CH2) ? 1 : 0;
+
+    *useTx1ForTx2 = readVal & MASK_TPC_CH1FCH2;
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TX_INCR_DECR_WORD, &readVal);
+
+    *stepSize = readVal & MASK_TPC_STEP;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Sets the Mykonos low voltage GPIO output pins level
+ *
+ * This function will only affect the GPIO pins that have their OE direction set to output and
+ * that have the correct source control for the nibbles in GPIO_BITBANG_MODE
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioPinLevel bit per GPIO pin, level to output for each GPIO pin. 0 = low output, 1= high output
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpioPinLevel(mykonosDevice_t *device, uint32_t gpioPinLevel)
+{
+
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioPinLevel()\n");
+#endif
+
+    /* writing GPIO configuration registers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_7_0, (gpioPinLevel & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_15_8, ((gpioPinLevel >> 8) & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_18_16, ((gpioPinLevel >> 16) & 0x07));
+
+    /* Return */
+    return error;
+}
+
+/**
+ * \brief Reads the Mykonos low voltage GPIO pin levels and returns their contents in a single 32-bit word
+ *
+ *  The GPIO pins that are set to be inputs in BITBANG mode will read back and be returned
+ *  in the gpioPinLevel parameter. The return value is a bit per pin.  GPIO 0 returns on bit 0 of
+ *  the gpioPinLevel parameter.  A logic low level returns a 0, a logic high level returns a 1.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioPinLevel Input Gpio pin levels read back on the pins assigned as inputs (bit per pin)
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_READGPIOSPI_NULL_PARM The pointer passed for gpioPinLevel parameter is NULL
+ */
+mykonosGpioErr_t MYKONOS_getGpioPinLevel(mykonosDevice_t *device, uint32_t *gpioPinLevel)
+{
+    uint8_t readBytes[3] = {0, 0, 0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioPinLevel()\n");
+#endif
+
+    if (gpioPinLevel == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READGPIOSPI_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_READGPIOSPI_NULL_PARM));
+        return MYKONOS_ERR_READGPIOSPI_NULL_PARM;
+    }
+
+    /* reading the registers into three-byte array */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_READ_7_0, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_READ_15_8, &readBytes[1]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_READ_18_16, &readBytes[2]);
+
+    /* performing concatenation and assigning value to gpio1v8SpiRead */
+    *gpioPinLevel = ((uint32_t)(readBytes[2] & 0x07) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the Mykonos GPIO pin output levels for BITBANG mode
+ *
+ *  This function allows reading the value that the GPIO output pins are
+ *  set to drive out the pins.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioPinSetLevel is a unit32_t pointer which contains the level of each GPIO pin (bit per pin)
+ *
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM gpioPinSetLevel pointer is NULL in function parameter
+ *
+ */
+mykonosGpioErr_t MYKONOS_getGpioSetLevel(mykonosDevice_t *device, uint32_t *gpioPinSetLevel)
+{
+    uint8_t readBytes[3] = {0, 0, 0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioSetLevel()\n");
+#endif
+
+    if (gpioPinSetLevel == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM));
+        return MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM;
+    }
+
+    /* reading the registers into two-byte array */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_7_0, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_15_8, &readBytes[1]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_SPI_SRC_18_16, &readBytes[2]);
+
+    /* performing concatenation and assigning value to gpioPinSetLevel */
+    *gpioPinSetLevel = ((uint32_t)(readBytes[2] & 0x07) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+
+/**
+ * \brief Sets the General Purpose (GP) interrupt register bit mask to enable interrupt sources to assert the GP Interrupt pin
+ *
+ *  Mykonos has a single output pin called General Purpose Interrupt that asserts to a logic high level
+ *  when certain events occur.  The events that cause the GP Interrupt pin to assert are user
+ *  selectable by setting the gpMask parameter in this function.  Device default is mask = x1FF = ignore
+ *  all events.  The ARM Error interrupt can not be ignored and can always assert the GP interrupt pin.
+ *
+ *     gpMask  |  Bit description
+ * ------------|------------
+ *        [0]  | TXPLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore TXPLL LOCK
+ *        [1]  | RXPLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore RXPLL LOCK
+ *        [2]  | SNIFFER PLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore SNIFFER PLL LOCK
+ *        [3]  | CALIBRATION PLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore CALIBRATION PLL LOCK
+ *        [4]  | CLKPLL LOCK - 0 = allow PLL unlocking to assert GP Interrupt pin, 1 = ignore CLKPLL LOCK
+ *        [5]  | 0 = Allow JESD204 deframer interrupt to assert GP Interrupt pin, 1 = ignore JESD204 deframer interrupt
+ *        [6]  | Tx1 PA protection - 0 = allow Tx1 PA protection event to assert GP Interrupt pin, 1 = ignore Tx1 PA protection
+ *        [7]  | Tx2 PA protection - 0 = allow Tx2 PA protection event to assert GP Interrupt pin, 1 = ignore Tx2 PA protection
+ *        [8]  | Mykonos ARM Watchdog - 0 = allow Mykonos ARM Watchdog timeout to assert GP Interrupt pin, 1 = ignore Watchdog timeout event
+ *     [15-9]  | Reserved for future use
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device Pointer to the device settings structure
+ * \param gpMask Value is passed to enable one or more general purpose interrupt sources
+ *               (1=ignore source, 0 = enable source interrupt to GP Interrupt pin)
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_INV_GP_INT_MASK_PARM if invalid interrupt mask is passed
+ */
+mykonosGpioErr_t MYKONOS_configGpInterrupt(mykonosDevice_t *device, uint16_t gpMask)
+{
+    const uint16_t GP_INT_VALID_MASK = 0x1FF;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_configGpInterrupt()\n");
+#endif
+
+    /* checking for valid mask setting */
+    if (gpMask & ~GP_INT_VALID_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_GP_INT_MASK_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_INV_GP_INT_MASK_PARM));
+        return MYKONOS_ERR_INV_GP_INT_MASK_PARM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_MASK_1, (gpMask & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_MASK_0, ((gpMask >> 8) & 0x01));
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the General Purpose (GP) interrupt status to determine what caused the GP Interrupt pin to assert
+ *
+ *  When the BBIC detects a rising edge on the General Purpose Interrupt pin, this function
+ *  allows the BBIC to determine the source of the interrupt.  The value returned in the status parameter
+ *  will show one or more sources for the interrupt based on the following table.
+ *
+ *  The PLL unlock bits are not sticky.  They will follow the current status of the PLLs.  If the PLL relocks, the
+ *  status bit will clear as well.  The GP Interrupt pin is the logical OR of all the sources.  When all the status
+ *  bits are low, the GP Interrupt pin will be low.  The status word readback will show the current value
+ *  for all interrupt sources, even if they are disabled by the masked. However, the GP Interrupt pin will only assert
+ *  for the enabled sources.
+ *
+ *     status  |  Bit description
+ * ------------|------------
+ *        [0]  | 1 = TXPLL UNLOCK
+ *        [1]  | 1 = RXPLL UNLOCK
+ *        [2]  | 1 = SNIFFER PLL UNLOCK
+ *        [3]  | 1 = CALIBRATION PLL UNLOCK
+ *        [4]  | 1 = CLK PLL UNLOCK
+ *        [5]  | 1 = JESD204 deframer interrupt occurred
+ *        [6]  | 1 = Tx1 PA protection event
+ *        [7]  | 1 = Tx2 PA protection event
+ *        [8]  | 1 = Mykonos ARM Watchdog timeout
+ *        [9]  | 1 = ARM interrupt occurred
+ *    [15-10]  | Reserved for future use
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings
+ *
+ * \param device Pointer to the device settings structure
+ * \param status parameter to return the IRQ source(s) that caused the GP Interrpt pin to assert.
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM if null *status pointer is passed
+ */
+mykonosGpioErr_t MYKONOS_readGpInterruptStatus(mykonosDevice_t *device, uint16_t *status)
+{
+    uint8_t readStatus1 = 0;
+    uint8_t readStatus0 = 0;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_readGpInterruptStatus()\n");
+#endif
+    /* checking for null pointer */
+    if (status == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM));
+        return MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_READ_1, &readStatus1);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GP_INTERRUPT_READ_0, &readStatus0);
+
+    /* PLL Lock status bits are high when locked, invert to match up with other bits */
+    *status = ((((uint16_t)(readStatus1) & 0xE0U) | ((~(uint16_t)(readStatus1)) & 0x1F)) | (((uint16_t)(readStatus0) & 0x0003) << 8)) ;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Sets the input and output GPIO pin selections for ARM related signals.
+ *
+ * The BBP should not have to call this as it will automatically be setup during the
+ * MYKONOS_loadArmFromBinary() function call.  If the BBP wishes to change the GPIO
+ * assignments this function can be called again to change the configuration while
+ * the ARM is in the radioOff state.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->armGpio : all members in structure
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SET_ARMGPIO_INV_POINTER device->auxIo->armGpio pointer is null
+ * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID Invalid ARM GPIO pin signal ID
+ * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN Invalid GPIO pin selected for ARM output (valid 0-15 + output enable in bit[4])
+ * \retval MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR ARM returned error setting GPIO pins
+ */
+mykonosGpioErr_t MYKONOS_setArmGpioPins(mykonosDevice_t *device)
+{
+    uint8_t i = 0;
+    uint8_t gpioConfig[3] = {0};
+    uint8_t signalId[12] = {ORX_TRIGGER_SIGNALID, ORX_MODE_0_SIGNALID, ORX_MODE_1_SIGNALID, ORX_MODE_2_SIGNALID, RX1_ENABLE_ACK_SIGNALID,
+            RX2_ENABLE_ACK_SIGNALID, TX1_ENABLE_ACK_SIGNALID, TX2_ENABLE_ACK_SIGNALID, ORX1_ENABLE_ACK_SIGNALID, ORX2_ENABLE_ACK_SIGNALID,
+            SRX_ENABLE_ACK_SIGNALID, TX_OBS_SELECT_SIGNALID};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    uint32_t gpioOe = 0;
+    uint32_t gpioUsedMask = 0;
+    mykonosGpioErr_t retval = MYKONOS_ERR_GPIO_OK;
+
+    const uint8_t GPIO_CTRL_OBJECTID = 0x60;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setArmGpioPins()\n");
+#endif
+
+    if (device->auxIo->armGpio == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_ARMGPIO_INV_POINTER,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_INV_POINTER));
+        return MYKONOS_ERR_SET_ARMGPIO_INV_POINTER;
+    }
+
+    /* Write ARM set command to setup which ARM signals are using which GPIO pins */
+    /* Setup input pins for ORX_MODE[2:0] and ORX_MODE_Trigger if orx is in pin mode */
+    for(i = 0; i < sizeof(signalId); i++)
+    {
+        gpioConfig[0] = GPIO_CTRL_OBJECTID;
+        gpioConfig[1] = signalId[i];
+
+        switch(signalId[i])
+        {
+            case ORX_TRIGGER_SIGNALID:      gpioConfig[2] = device->auxIo->armGpio->orxTriggerPin;   break;
+            case ORX_MODE_0_SIGNALID:       gpioConfig[2] = device->auxIo->armGpio->orxMode0Pin;     break;
+            case ORX_MODE_1_SIGNALID:       gpioConfig[2] = device->auxIo->armGpio->orxMode1Pin;     break;
+            case ORX_MODE_2_SIGNALID:       gpioConfig[2] = device->auxIo->armGpio->orxMode2Pin;     break;
+            case RX1_ENABLE_ACK_SIGNALID:   gpioConfig[2] = device->auxIo->armGpio->rx1EnableAck;    break;
+            case RX2_ENABLE_ACK_SIGNALID:   gpioConfig[2] = device->auxIo->armGpio->rx2EnableAck;    break;
+            case TX1_ENABLE_ACK_SIGNALID:   gpioConfig[2] = device->auxIo->armGpio->tx1EnableAck;    break;
+            case TX2_ENABLE_ACK_SIGNALID:   gpioConfig[2] = device->auxIo->armGpio->tx2EnableAck;    break;
+            case ORX1_ENABLE_ACK_SIGNALID:  gpioConfig[2] = device->auxIo->armGpio->orx1EnableAck;   break;
+            case ORX2_ENABLE_ACK_SIGNALID:  gpioConfig[2] = device->auxIo->armGpio->orx2EnableAck;   break;
+            case SRX_ENABLE_ACK_SIGNALID:   gpioConfig[2] = device->auxIo->armGpio->srxEnableAck;    break;
+            case TX_OBS_SELECT_SIGNALID:    gpioConfig[2] = device->auxIo->armGpio->txObsSelect;     break;
+            default:
+            {
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex,  MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID,
+                        getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID));
+                return MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID;
+            }
+        }
+
+        if (gpioConfig[2] > 0x1F)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex,  MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN));
+            return MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN;
+        }
+
+        /* if output signal */
+        if ((signalId[i] >= RX1_ENABLE_ACK_SIGNALID) && (gpioConfig[2] != 0))
+        {
+            gpioOe |= (((gpioConfig[2] >> 4) & 0x01) << (gpioConfig[2] & 0x0F)); /* 1 = output */
+            gpioUsedMask |= (1 << (gpioConfig[2] & 0x0F));
+        }
+
+        /* if input signal and orx Pin mode enabled - currently only input pins are orx pin mode control */
+        if ((signalId[i] < RX1_ENABLE_ACK_SIGNALID) && (device->auxIo->armGpio->orxPinMode > 0))
+        {
+            gpioUsedMask |= (1 << (gpioConfig[2] & 0x1F));
+        }
+
+        retval = MYKONOS_sendArmCommand(device, MYKONOS_ARM_SET_OPCODE, &gpioConfig[0], sizeof(gpioConfig));
+        if (retval != MYKONOS_ERR_GPIO_OK)
+        {
+            return retval;
+        }
+
+        timeoutMs = 1000;
+        retval = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_SET_OPCODE, timeoutMs, &cmdStatusByte);
+        if (retval != MYKONOS_ERR_GPIO_OK)
+        {
+            return retval;
+        }
+
+        if (cmdStatusByte > 0)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex,  MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR));
+            return MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR;
+        }
+    }
+
+    /* Mykonos SPI regs to set GPIO OE direction only for pins used by ARM */
+    retval = MYKONOS_setGpioOe(device, gpioOe, gpioUsedMask);
+    if (retval != MYKONOS_ERR_GPIO_OK)
+    {
+        return retval;
+    }
+
+    //if any output pins enabled, write GPIO nibble source control.  ARM outputs only allowed on GPIO[15:0]
+    if (gpioOe & 0x000F)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, 0x09, 0x0F, 0);
+    }
+
+    if (gpioOe & 0x00F0)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, 0x09, 0xF0, 4);
+    }
+
+    if (gpioOe & 0x0F00)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, 0x09, 0x0F, 0);
+    }
+
+    if (gpioOe & 0xF000)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, 0x09, 0xF0, 4);
+    }
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Configures the Radio power up/down control for Rx and Tx paths to be controlled by pins
+ *        (TX1/2_ENABLE, RX1/2_ENABLE, and GPIO pins) or an API function call.
+ *
+ * The BBP should not have to call this as it will automatically be setup at the end of the
+ * MYKONOS_loadArmFromBinary() function call.  If the BBP wishes to change the radio power up/down
+ * control method this function can be called again to change the configuration while
+ * the ARM is in the radioOff state.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->armGpio->useRx2EnablePin
+ * - device->auxIo->armGpio->useTx2EnablePin
+ * - device->auxIo->armGpio->txRxPinMode
+ * - device->auxIo->armGpio->orxPinMode
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR ARM returned an error and did not accept the command.
+ */
+mykonosGpioErr_t MYKONOS_setRadioControlPinMode(mykonosDevice_t *device)
+{
+    uint8_t extData[4] = {0x81, 0, 0, 4}; //Object ID 0x81 (radio control structure), offset lsb, offset msb, length
+    uint8_t armRadioControlStruct[4] = {0};
+    uint32_t timeoutMs = 0;
+    uint8_t cmdStatusByte = 0;
+    mykonosGpioErr_t retval = MYKONOS_ERR_GPIO_OK;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRadioControlPinMode()\n");
+#endif
+
+    /* write ARM radio control structure to enable pin mode/command mode */
+    if (device->auxIo->armGpio->useRx2EnablePin > 0)
+    {
+        armRadioControlStruct[0] = 0x01;
+    }
+
+    if (device->auxIo->armGpio->useTx2EnablePin > 0)
+    {
+        armRadioControlStruct[1] = 0x01;
+    }
+
+    if (device->auxIo->armGpio->txRxPinMode > 0)
+    {
+        armRadioControlStruct[2] = 0x01;
+    }
+
+    if (device->auxIo->armGpio->orxPinMode > 0)
+    {
+        armRadioControlStruct[3] = 0x01;
+    }
+
+    retval = MYKONOS_writeArmMem(device, MYKONOS_ADDR_ARM_START_DATA_ADDR, &armRadioControlStruct[0], sizeof(armRadioControlStruct));
+    if (retval != MYKONOS_ERR_GPIO_OK)
+    {
+        return retval;
+    }
+
+    retval = MYKONOS_sendArmCommand(device, MYKONOS_ARM_WRITECFG_OPCODE, &extData[0], sizeof(extData));
+    if (retval != MYKONOS_ERR_GPIO_OK)
+    {
+        return retval;
+    }
+
+    timeoutMs = 1000;
+    retval = MYKONOS_waitArmCmdStatus(device, MYKONOS_ARM_WRITECFG_OPCODE, timeoutMs, &cmdStatusByte);
+    if (retval != MYKONOS_ERR_GPIO_OK)
+    {
+        return retval;
+    }
+
+    if (cmdStatusByte > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex,  MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR));
+        return MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR;
+    }
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Sets up the auxiliary ADC
+ *
+ *  This function configures the AuxADC with the requested decimation.  The AuxADC clock is set as close
+ *  as possible to 40MHz.  The AuxADC conversion time = (1/40Mhz) * decimation, where the decimation ranges
+ *  from 256 AuxADC clock cycles to 32768 AuxADc clock cycles.
+ *
+ *  Note: The AuxADC is intended for relative measurements.  Two back to back measurements can allow a delta
+ *  measurement with 12bit resolution.  If absolute measurements are required, an accurate
+ *  reference should be first measured on AuxADC0 input and used to calibrate the offset/gain error of the AuxADC.
+ *  The reference would need to be measured before each measurement to account for measurement variations caused
+ *  by the transmitter/receiver transients as other circuits in the device are being powered up/down.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device Pointer to the device settings structure
+ * \param adcDecimation ADC decimation factor (0-7). Decimates by 256 * 2^(adcDecimation) ADC clock cycles.
+ * \param enable Stop/run ADC (0/1)
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETUPAUXADC_INV_VCODIV CLKPLL VCO divider is invalid - Check CLKPLL setup
+ * \retval MYKONOS_ERR_INV_AUX_ADC_DEC_PARM AuxADC decimation out of range (valid 0-7)
+ */
+mykonosGpioErr_t MYKONOS_setupAuxAdcs(mykonosDevice_t *device, uint8_t adcDecimation, uint8_t enable)
+{
+    uint32_t hsDigClk_kHz = 0;
+    uint32_t auxAdcDiv = 0;
+    uint32_t auxAdcClk_kHz = 40000;
+    uint32_t vcoDiv = device->clocks->clkPllVcoDiv;
+    uint8_t vcoDivTimes10 = 10;
+
+    const uint8_t AUXADC_POWER_BIT_MASK = 0x80;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupAuxAdcs()\n");
+#endif
+
+    if(enable == 0)
+    {
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0, 0xCF);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, 0x01);
+
+        return MYKONOS_ERR_GPIO_OK;
+    }
+    else
+    {
+        switch(vcoDiv)
+        {
+            case VCODIV_1:
+                vcoDivTimes10 = 10;
+                break;
+            case VCODIV_1p5:
+                vcoDivTimes10 = 15;
+                break;
+            case VCODIV_2:
+                vcoDivTimes10 = 20;
+                break;
+            case VCODIV_3:
+                vcoDivTimes10 = 30;
+                break;
+
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPAUXADC_INV_VCODIV,
+                        getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPAUXADC_INV_VCODIV));
+                return MYKONOS_ERR_SETUPAUXADC_INV_VCODIV;
+        }
+
+        hsDigClk_kHz = (device->clocks->clkPllVcoFreq_kHz / vcoDivTimes10 / device->clocks->clkPllHsDiv) * 10;
+        auxAdcDiv = ((hsDigClk_kHz / 2) / (auxAdcClk_kHz)) - 1;
+
+        if(auxAdcDiv > 63)
+        {
+            auxAdcDiv = 63;
+        }
+
+        if(adcDecimation > 0x07)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AUX_ADC_DEC_PARM,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_INV_AUX_ADC_DEC_PARM));
+            return MYKONOS_ERR_INV_AUX_ADC_DEC_PARM;
+        }
+
+        CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE, (uint8_t)(auxAdcDiv));
+        CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, (uint8_t)((adcDecimation << 1)));
+        CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_AUX_ADC_SEL, 0x00); /* Set AuxADC select to AuxADC0 */
+        CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0, 0, AUXADC_POWER_BIT_MASK, 7);
+
+        /* Set Clock enable bit to latch divider */
+        CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE, (uint8_t)(auxAdcDiv | 0x80));
+    }
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Sets the selected channel of the auxiliary ADC
+ *
+ *  After setting the AuxADC channel, wait at least 1 AuxADC conversion time before
+ *  reading back the AuxADC value.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param auxAdcChannel desired Aux ADC input(0-4 and 16 = temperature sensor)
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM Invalid AuxADC channel (valid 0-4 and 16)
+ */
+mykonosGpioErr_t MYKONOS_setAuxAdcChannel(mykonosDevice_t *device, mykonosAuxAdcChannels_t auxAdcChannel)
+{
+    uint8_t currentAuxAdcChan = 0x00;
+
+    const uint8_t CHANNEL_MASK = 0x17;
+    const uint8_t POWER_UP_AUXADC = 0x00;
+    const uint8_t POWER_DOWN_AUXADC = 0x01;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setAuxAdcChannel()\n");
+#endif
+
+    if ((auxAdcChannel & ~CHANNEL_MASK) > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM));
+        return MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM;
+    }
+
+    /* Read current selected channel, if different power down AUXADC and change AUXADC */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_SEL, &currentAuxAdcChan);
+    if (currentAuxAdcChan != auxAdcChannel)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, POWER_DOWN_AUXADC, 0x01, 0);
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_SEL, auxAdcChannel);
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, POWER_UP_AUXADC, 0x01, 0);
+    }
+
+    /* Invalid AuxADC channel, the only valid channel for external ref is channel 0 */
+    if (auxAdcChannel == MYK_AUXADC_0_DIV2)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1, 0x01, 0x04, 2);
+    }
+    else if (auxAdcChannel == MYK_AUXADC_0)
+    {
+        CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1, 0x00, 0x04, 2);
+    }
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads from the selected channel of the auxiliary ADC
+ *
+ *  Before using this function to read back the AuxADC value of the
+ *  currently selected AuxADC, make sure that at least 1 conversion time
+ *  of the ADC has passed since setting the AuxADC channel.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param adcCode is a pointer for return of the 12bit ADC read value
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_READAUXADC_NULL_PARAM Function parameter adcCode is a NULL pointer
+ */
+mykonosGpioErr_t MYKONOS_readAuxAdc(mykonosDevice_t *device, uint16_t *adcCode)
+{
+    uint8_t adcNibble = 0;
+
+    const uint8_t AUXADC_LOCK_BIT_MASK = 0x80;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_readAuxAdcs()\n");
+#endif
+
+    if (adcCode == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READAUXADC_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_READAUXADC_NULL_PARAM));
+        return MYKONOS_ERR_READAUXADC_NULL_PARAM;
+    }
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_AUX_ADC_CFG, 1, AUXADC_LOCK_BIT_MASK, 7);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_READ_MSB, &adcNibble);
+    *adcCode = adcNibble << 4;
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_AUX_ADC_READ_LSB, &adcNibble);
+    *adcCode |= (adcNibble & 0x0F);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Sets up the 10 AuxDACs on the Mykonos device.
+ *
+ * This function uses the configuration in the Mykonos device data structure AuxIO substructure to
+ * setup which of the ten AuxDACs are enabled, their slope, Vref(mid point) and their initial DAC code.
+ *
+ *  This function can be called any time after MYKONOS_initialize() to reconfigure, enable, disable the
+ *  different AuxDAC outputs. The AuxDACs are used in manual control mode.  After calling this setup
+ *  function, it is possible to change a particular AuxDAC code by calling the writeAuxDac() function.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->auxDacEnable: 1= enabled, 0 = disabled
+ * - device->auxIo->auxDacSlope[i]: 0 = 1.404mv/code, 1= 0.702mV/code
+ * - device->auxIo->auxDacVref: 0 = 1v midpoint, 1 = 1.5v midpoint, 2 = 2v midpoint, 3 = 2.5v midpoint
+ * - device->auxIo->auxDacValue[i]: 10bit DAC code (0-1023)
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM device->auxIo structure has a NULL pointer
+ * \retval MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE auxDAC code is out of range (valid 0-1023)
+ */
+mykonosGpioErr_t MYKONOS_setupAuxDacs(mykonosDevice_t *device)
+{
+    uint8_t i = 0; /* for loop index */
+    uint8_t auxDacConfig = 0 ;
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupAuxDacs()\n");
+#endif
+
+    if (device->auxIo == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM));
+        return MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM;
+    }
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_5_0, 0x3F); /* Enable Manual AuxDAC control for all AuxDACs[5:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_9_6, 0x0F); /* Enable Manual AuxDAC control for all AuxDACs[9:6] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0, 0x3F); /* Power down all AuxDACs[5:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6, 0x0F); /* Power down all AuxDACs[9:6] */
+
+    for (i = 0; i < 10; i++)
+    {
+        /* If auxDac enabled, setup AuxDAC configuration */
+        if ((device->auxIo->auxDacEnable >> i) & 0x01)
+        {
+            if (device->auxIo->auxDacValue[i] > 1023)
+            {
+                device->auxIo->auxDacValue[i] = 1023; /* clip value to max */
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE,
+                        getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE));
+                error = MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE; /* Complete AuxDAC configuration before returning error code */
+            }
+
+            auxDacConfig = 0x00; /* initialize config variable */
+
+            if (device->auxIo->auxDacSlope[i] > 0)
+            {
+                auxDacConfig = 0x40; /* bit [6] sets the slope */
+            }
+
+            auxDacConfig |= ((device->auxIo->auxDacVref[i] & 0x03) << 4);
+
+            /* Write AuxDAC config and DAC code */
+            CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_AUXDAC_0_WORD_MSB + (i * 2)), (auxDacConfig | ((device->auxIo->auxDacValue[i] >> 8) & 0x0F)));
+            CMB_SPIWriteByte(device->spiSettings, (MYKONOS_ADDR_AUXDAC_0_WORD_MSB + (i * 2 ) + 1), (device->auxIo->auxDacValue[i] & 0xFF));
+        }
+    }
+
+    /* Write enable bit to latch DAC codes into DACs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL, 0x01);
+
+    /* Power up selected AuxDacs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0, ((~device->auxIo->auxDacEnable) & 0x3F)); /* Power up enabled AuxDACs[5:0] */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6, (((~device->auxIo->auxDacEnable) >> 6) & 0x0F)); /* Power up enabled AuxDACs[9:6] */
+
+    return error;
+}
+
+/**
+ * \brief Writes the current AuxDAC code for a particular AuxDAC
+ *
+ * This function updates the 10bit code that controls the AuxDAC output voltage.
+ * The auxDacCode is updated for the specified auxDAC.  Also the auxDacCode is written
+ * to the device data structure for future reference.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->auxDacValue[i]
+ *
+ * \param device is a pointer to the device settings structure
+ * \param auxDacIndex AuxDAC to set the DAC code for (0-9)
+ * \param auxDacCode DAC code to update the AuxDAC to.  Sets the output voltage of the DAC (valid 0-1023)
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE AuxDac code invalid (valid 0-1023)
+ * \retval MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX AuxDAC index out of range (valid 0-9)
+ * \retval MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO device->auxIo has NULL pointer
+ */
+mykonosGpioErr_t MYKONOS_writeAuxDac(mykonosDevice_t *device, uint8_t auxDacIndex, uint16_t auxDacCode)
+{
+    uint16_t auxDacAddr = 0;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_writeAuxDac()\n");
+#endif
+
+    if (auxDacCode > 1023)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE));
+        return MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE;
+    }
+
+    if (auxDacIndex > 9)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX));
+        return MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX;
+    }
+
+    if (device->auxIo == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO));
+        return MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO;
+    }
+
+    device->auxIo->auxDacValue[auxDacIndex] = auxDacCode;
+
+    auxDacAddr = MYKONOS_ADDR_AUXDAC_0_WORD_MSB + (auxDacIndex * 2);
+
+    /* Write AuxDAC config and DAC code */
+    CMB_SPIWriteField(device->spiSettings, auxDacAddr, (auxDacCode >> 8), 0x0F, 0);
+    CMB_SPIWriteByte(device->spiSettings, (auxDacAddr + 1), (auxDacCode & 0xFF));
+
+    /* Write enable bit to latch DAC codes into DACs */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL, 0x01);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Sets the Mykonos low voltage GPIO configuration registers
+ *
+ * Sets the low voltage GPIO pin direction for each low voltage GPIO pin and
+ * sets the source control mode (feature) for each group of 4 GPIO pins.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->gpio - all members
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER device->auxIo->gpio pointer is NULL
+ * \retval MYKONOS_ERR_SET_GPIO_1V8_INV_MODE gpio structure members have invalid enum value for the GPIO source control mode.
+ */
+mykonosGpioErr_t MYKONOS_setupGpio(mykonosDevice_t *device)
+{
+    uint32_t srcWrite = 0x000000;
+    uint32_t oEnMask = 0x7FFFF;
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupGpio()\n");
+#endif
+
+    if (device->auxIo->gpio == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER));
+        return MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER;
+    }
+
+    /* write GPIO pin direction registers */
+    error = MYKONOS_setGpioOe(device, device->auxIo->gpio->gpioOe, oEnMask);
+
+    /* Check and return if error */
+    if (error)
+    {
+        return error;
+    }
+
+    /* write GPIO source control mode */
+    if ((device->auxIo->gpio->gpioSrcCtrl3_0 > 15) || (device->auxIo->gpio->gpioSrcCtrl7_4 > 15) ||
+        (device->auxIo->gpio->gpioSrcCtrl11_8 > 15) || (device->auxIo->gpio->gpioSrcCtrl15_12 > 15) ||
+        (device->auxIo->gpio->gpioSrcCtrl18_16 > 15))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_1V8_INV_MODE,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_1V8_INV_MODE));
+        return MYKONOS_ERR_SET_GPIO_1V8_INV_MODE;
+    }
+
+    srcWrite = device->auxIo->gpio->gpioSrcCtrl3_0 + (device->auxIo->gpio->gpioSrcCtrl7_4 << 4) +
+            (device->auxIo->gpio->gpioSrcCtrl11_8 << 8) + (device->auxIo->gpio->gpioSrcCtrl15_12 << 12) +
+            (device->auxIo->gpio->gpioSrcCtrl18_16 << 16);
+
+    error = MYKONOS_setGpioSourceCtrl(device, srcWrite);
+
+    return error;
+}
+
+/**
+ * \brief Sets the Mykonos low voltage GPIO output pins direction
+ *
+ * This function will set the GPIO direction given by the passed parameter,
+ * the direction can be either output or input.  The gpioUsedMask parameter
+ * allows the function to only affect the GPIO pins of interest.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->gpio->gpioOe
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioOutEn (valid range 0 - 0x07FFFF), bit per GPIO pin, the direction is
+ *
+ * gpioOutEn[bit]  |  GPIO[bit] direction
+ * ----------------|-------------------
+ *        0        |        input
+ *        1        |        output
+ *
+ * \param gpioUsedMask Mask used to control which Oe bits are set/cleared.  If
+ *                     mask bit =1, that bit will be modified by gpioOutEn bit
+ *
+ * \retval MYKONOS_ERR_GPIO_OE_INV_PARAM If the Output enable parameter is invalid
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpioOe(mykonosDevice_t *device, uint32_t gpioOutEn, uint32_t gpioUsedMask)
+{
+    uint32_t error = MYKONOS_ERR_GPIO_OK;
+
+    const uint32_t GPIO_OE_MASK = 0x7FFFF;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioOe()\n");
+#endif
+
+    /* Error checking for correct number of GPIOs available. */
+    if (gpioOutEn > GPIO_OE_MASK )
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OE_INV_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_OE_INV_PARAM));
+        return MYKONOS_ERR_GPIO_OE_INV_PARAM;
+    }
+
+    /* Mykonos SPI regs to set GPIO OE direction */
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_7_0, (gpioOutEn & 0xFF), (gpioUsedMask & 0xFF), 0);
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_15_8, ((gpioOutEn >> 8) & 0xFF), ((gpioUsedMask >> 8) & 0xFF), 0);
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_18_16, ((gpioOutEn >> 16) & 0xFF), ((gpioUsedMask >> 16) & 0xFF), 0);
+
+    /* Updating gpioConfig->gpioSetup->gpioOe output enable */
+    error = MYKONOS_getGpioOe(device, &gpioOutEn);
+    if (error)
+    {
+        return error;
+    }
+
+    device->auxIo->gpio->gpioOe = gpioOutEn;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Gets the Mykonos low voltage GPIO output pins direction
+ *
+ * This function will get the GPIO direction currently set in the device,
+ * the direction can be either output or input. The return gpioOutEn function
+ * parameter returns a bit per GPIO pin.  1 = output from the Mykonos Device,
+ * 0 = input into the Mykonos device.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param *gpioOutEn a pointer to the data to be returned with the output enable reading
+ *
+ * gpioOutEn[bit]  |  GPIO[bit] direction
+ * ----------------|-------------------
+ *        0        |        input
+ *        1        |        output
+ *
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETGPIO_OE_NULL_PARM gpioOutEn function parameter is NULL
+ */
+mykonosGpioErr_t MYKONOS_getGpioOe(mykonosDevice_t *device, uint32_t *gpioOutEn)
+{
+    uint8_t readBytes[3] = {0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioOe()\n");
+#endif
+
+    if (gpioOutEn == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIO_OE_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIO_OE_NULL_PARM));
+        return MYKONOS_ERR_GETGPIO_OE_NULL_PARM;
+    }
+
+    /* Reading GPIO output enable registers */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_7_0, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_15_8, &readBytes[1]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_DIR_CTL_18_16, &readBytes[2]);
+
+    /* Updating gpioConfig->gpioSetup->gpioOe output enable */
+    *gpioOutEn = ((uint32_t)(readBytes[2] & 0x07) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+
+/**
+ * \brief Sets the Mykonos GPIO source control for different GPIO functionality
+ *
+ * This function will only affect the GPIO pins that have their OE direction set to output.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioSrcCtrl nibble based source control, this is a 32 bit containing
+ * 5 nibbles that will be set the source control.
+ *
+ * \retval MYKONOS_ERR_GPIO_SRC_PARAM_INV If the source control parameter is invalid
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpioSourceCtrl(mykonosDevice_t *device, uint32_t gpioSrcCtrl)
+{
+    const uint32_t GPIO_SRC_MASK = 0xFFFFF;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioSourceCtrl()\n");
+#endif
+
+    /* writing GPIO configuration registers */
+    if (gpioSrcCtrl > GPIO_SRC_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_SRC_PARAM_INV,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_SRC_PARAM_INV));
+        return MYKONOS_ERR_GPIO_SRC_PARAM_INV;
+    }
+
+    /* writing GPIO configuration registers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, (gpioSrcCtrl & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, ((gpioSrcCtrl >> 8) & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS, ((gpioSrcCtrl >> 16) & 0x0F));
+
+    /* Updating gpioConfig->gpioSetup source control */
+    device->auxIo->gpio->gpioSrcCtrl3_0 = gpioSrcCtrl & 0x0F;
+    device->auxIo->gpio->gpioSrcCtrl7_4 = (gpioSrcCtrl >> 4) & 0x0F;
+    device->auxIo->gpio->gpioSrcCtrl11_8 = (gpioSrcCtrl >> 8) & 0x0F;
+    device->auxIo->gpio->gpioSrcCtrl15_12 = (gpioSrcCtrl >> 12) & 0x0F;
+    device->auxIo->gpio->gpioSrcCtrl18_16 = (gpioSrcCtrl >> 16) & 0x0F;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the Mykonos GPIO source control for different GPIO functionality
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioSrcCtrl nibble based source control, this is a 32 bit containing
+ * 5 nibbles that will be set the source control.
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getGpioSourceCtrl(mykonosDevice_t *device, uint32_t *gpioSrcCtrl)
+{
+    uint8_t readBytes[3] = {0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioSourceCtrl()\n");
+#endif
+
+    /* Reading GPIO output enable registers */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE, &readBytes[1]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS, &readBytes[2]);
+
+    /* Updating gpioConfig->gpioSetup->gpioOe output enable */
+    *gpioSrcCtrl = ((uint32_t)(readBytes[2] & 0x0F) << 16) | ((uint32_t)(readBytes[1]) << 8) | (uint32_t)(readBytes[0]);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+
+/**
+ * \brief Sets the Mykonos 3.3 VDC GPIO configuration registers
+ *
+ *  This function sets the GPIO 3.3v pin direction (1=output, 0=input) and
+ *  sets the mode of each nibble of GPIO 3.3v pins. See the mykonosGpio3v3Mode_t
+ *  enum for possible modes.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->gpio3v3 - all members
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER device->auxIo->gpio3v3 pointer is NULL
+ * \retval MYKONOS_ERR_SET_GPIO_3V3_INV_MODE gpio3v3 members have invalid enum value for the GPIO3v3 source control mode.
+ */
+mykonosGpioErr_t MYKONOS_setupGpio3v3(mykonosDevice_t *device)
+{
+    mykonosGpioErr_t error = MYKONOS_ERR_GPIO_OK;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupGpio3v3()\n");
+#endif
+
+    if (device->auxIo->gpio3v3 == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER));
+        return MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER;
+    }
+    else
+    {
+        /* write GPIO pin direction registers */
+        error = MYKONOS_setGpio3v3Oe(device, device->auxIo->gpio3v3->gpio3v3Oe);
+
+        /* write GPIO3v3 mode */
+        if ((device->auxIo->gpio3v3->gpio3v3SrcCtrl3_0 > 15) ||
+                (device->auxIo->gpio3v3->gpio3v3SrcCtrl7_4 > 15) ||
+                (device->auxIo->gpio3v3->gpio3v3SrcCtrl11_8 > 15))
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_3V3_INV_MODE,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_3V3_INV_MODE));
+            return MYKONOS_ERR_SET_GPIO_3V3_INV_MODE;
+        }
+
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL, ((device->auxIo->gpio3v3->gpio3v3SrcCtrl7_4 << 4) | device->auxIo->gpio3v3->gpio3v3SrcCtrl3_0));
+        CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL, (device->auxIo->gpio3v3->gpio3v3SrcCtrl11_8 & 0x0F));
+
+        return error;
+    }
+}
+
+/**
+ * \brief If the GPIO3v3 pins are setup for BITBANG mode, this function sets
+ *        the output pin levels per pin
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->gpio3v3 - all members
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3PinLevel Bit per pin to set the level of each GPIO3v3 output pin
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpio3v3PinLevel(mykonosDevice_t *device, uint16_t gpio3v3PinLevel)
+{
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpio3v3PinLevel()\n");
+#endif
+
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0, (gpio3v3PinLevel & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8, ((gpio3v3PinLevel >> 8) & 0x0F));
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the Mykonos 3.3 VDC GPIO pin output levels for BITBANG mode
+ *
+ *  This function allows reading the value that the 3.3v GPIO output pins are
+ *  set to drive out the pins.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3SetLevel is a unit16_t pointer which contains the level of each GPIO3V3 pin (bit per pin)
+ *
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM gpio3v3SetLevel pointer is NULL in function parameter
+ */
+mykonosGpioErr_t MYKONOS_getGpio3v3SetLevel(mykonosDevice_t *device, uint16_t *gpio3v3SetLevel)
+{
+    uint8_t readBytes[2] = {0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3SetLevel()\n");
+#endif
+
+    if (gpio3v3SetLevel == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM));
+        return MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM;
+    }
+
+    /* reading the registers into two-byte array */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8, &readBytes[1]);
+
+    /* performing concatenation and assigning value to gpio3v3SpiRead */
+    *gpio3v3SetLevel = ((uint16_t)(readBytes[1] & 0x0F) << 8) | (uint16_t)(readBytes[0]);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the Mykonos 3.3 VDC GPIO pin levels for BITBANG mode
+ *
+ *  Note: this function is only capable of reading back pin levels for the
+ *  3.3v pins set to be inputs.  Any pins set to be a GPIO output will read
+ *  back as zero.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3PinLevel is a unit16_t pointer which contains the level of each GPIO3V3 pin
+ *                        that is defined as an input
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM gpio3v3PinLevel pointer is NULL in function parameter
+ */
+mykonosGpioErr_t MYKONOS_getGpio3v3PinLevel(mykonosDevice_t *device, uint16_t *gpio3v3PinLevel)
+{
+    uint8_t readBytes[2] = {0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3PinLevel()\n");
+#endif
+
+    if (gpio3v3PinLevel == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM));
+        return MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM;
+    }
+
+    /* reading the registers for input pin levels */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_READ_7_0, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_SPI_READ_15_8, &readBytes[1]);
+
+    *gpio3v3PinLevel = ((uint16_t)(readBytes[1] & 0x0F) << 8) | (uint16_t)(readBytes[0]);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This function sets the Pin direction control for the Mykonos 3.3 VDC GPIO.
+ *
+ * The bits in gpio3v3OutEn are used to configure each corresponding pin as an input or an output.
+ * If the bit is set, the pin is configured as an output, and if it is clear the pin is configured as an input.
+ * For example, setting gpio3v3OutEn = 0x02  will configure GPIO_3p3_2 as an output and the rest pins as inputs.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - device->auxIo->gpio3v3 - all members
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3OutEn Bit per pin to set the level of each GPIO3v3 output pin
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpio3v3Oe(mykonosDevice_t *device, uint16_t gpio3v3OutEn)
+{
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3Oe()\n");
+#endif
+
+    /* write GPIO pin direction registers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0, (gpio3v3OutEn & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8, ((gpio3v3OutEn >> 8) & 0x0F));
+
+    /* update device->auxIo->gpio3v3 structure */
+    device->auxIo->gpio3v3->gpio3v3Oe = gpio3v3OutEn;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the Mykonos 3.3 VDC GPIO pin direction
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3OutEn is a unit16_t pointer which will contain the output enable parameter,
+ * this will be a bit field, if a bit is set then the corresponding GPIO pin is an output,
+ * if the bit is not set then the corresponding pin is an input
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM gpio3v3OutEn pointer is NULL in function parameter
+ */
+mykonosGpioErr_t MYKONOS_getGpio3v3Oe(mykonosDevice_t *device, uint16_t *gpio3v3OutEn)
+{
+    uint8_t readBytes[2] = {0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3Oe()\n");
+#endif
+
+    /* checking for null parameter */
+    if (gpio3v3OutEn == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM));
+        return MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM;
+    }
+
+    /* reading the registers for input pin levels */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8, &readBytes[1]);
+
+    *gpio3v3OutEn = ((uint16_t)(readBytes[1] & 0x0F) << 8) | (uint16_t)(readBytes[0]);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Sets the Mykonos GPIO 3.3 VDC source control for different GPIO fucntionality
+ *
+ * This function will only affect the GPIO pins that have their OE direction set to output.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3SrcCtrl nibble based source control, this is a 12 bit containing
+ * 3 nibbles that will be set the source control.
+ *
+ * \retval MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL gpio3v3 members have invalid value for the GPIO3v3 source control mode.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t gpio3v3SrcCtrl)
+{
+    const uint16_t GPIO_SRC_MASK = 0x0FFF;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpio3v3SourceCtrl()\n");
+#endif
+
+    /* writing GPIO configuration registers */
+    if (gpio3v3SrcCtrl > GPIO_SRC_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL));
+        return MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL;
+    }
+
+    /* writing GPIO configuration registers */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL, (gpio3v3SrcCtrl & 0xFF));
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL, ((gpio3v3SrcCtrl >> 8) & 0xFF));
+
+    /* Updating gpioConfig->gpioSetup source control */
+    device->auxIo->gpio3v3->gpio3v3SrcCtrl3_0 = gpio3v3SrcCtrl & 0x0F;
+    device->auxIo->gpio3v3->gpio3v3SrcCtrl7_4 = gpio3v3SrcCtrl & 0xF0;
+    device->auxIo->gpio3v3->gpio3v3SrcCtrl11_8 = (gpio3v3SrcCtrl >> 8) & 0x0F;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads the Mykonos 3v3 GPIO source control for different GPIO functionality
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpio3v3SrcCtrl nibble based source control, this is a 12 bit containing
+ * 3 nibbles that will be set the source control.
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t *gpio3v3SrcCtrl)
+{
+    uint8_t readBytes[2] = {0};
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpio3v3SourceCtrl()\n");
+#endif
+
+    /* checking for null parameter */
+    if (gpio3v3SrcCtrl == NULL)
+    {
+       CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM,
+               getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM));
+       return MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM;
+    }
+
+    /* Reading GPIO output enable registers */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL, &readBytes[0]);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL, &readBytes[1]);
+
+    /* Updating gpioConfig->gpioSetup->gpioOe output enable */
+    *gpio3v3SrcCtrl = ((uint16_t)(readBytes[1] & 0xFF) << 8) | ((uint16_t)(readBytes[0]));
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Gain compensation enable and setup function.
+ *
+ * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the Rx channels.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gainComp which is a mykonosGainComp_t structure.
+ * \param enable this parameter enables or disables the gain compensation block.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT gain compensation structure gainComp is not initialised
+ * \retval MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET gain compensation structure gainComp->rx1Offset is invalid
+ * \retval MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET gain compensation structure gainComp->rx2Offset is invalid
+ * \retval MYKONOS_ERR_GAINCOMP_INV_STEP gain compensation structure gainComp->compStep is invalid
+ * \retval MYKONOS_ERR_GAINCOMP_INV_EN enable is not valid
+ */
+mykonosGpioErr_t MYKONOS_setRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t enable)
+{
+    uint8_t regWr2 = 0x00;
+    uint8_t regWr3 = 0x00;
+    uint8_t regWr4 = 0x00;
+
+    /* Max parameter values for error checking */
+    const uint8_t RXOFFSET_RANGE = 0x1F;
+    const uint8_t STEP_RANGE = 0x07;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxGainCompensation()\n");
+#endif
+
+    /* Check for gainComp initialised */
+    if (gainComp == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT));
+        return MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT;
+    }
+
+    /* Check for enable */
+    if (enable > 1)
+    {
+      CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_EN,
+                         getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_EN));
+      return MYKONOS_ERR_GAINCOMP_INV_EN;
+    }
+    else if (enable == 1)
+    {
+        /* Check for gain compensation Rx1 offset range */
+        if (gainComp->rx1Offset > RXOFFSET_RANGE)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET,
+                               getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET));
+                return MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET;
+        }
+
+        /* Check for gain compensation Rx2 offset range */
+        if (gainComp->rx2Offset > RXOFFSET_RANGE)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET,
+                              getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET));
+            return MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET;
+        }
+
+        /* Check for gain compensation step range */
+        if (gainComp->compStep > STEP_RANGE)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_INV_STEP,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_INV_STEP));
+            return MYKONOS_ERR_GAINCOMP_INV_STEP;
+        }
+
+        /* Enabling gain compensation block */
+        regWr4 = 0x88 | gainComp->compStep;
+        regWr3 = gainComp->rx2Offset;
+        regWr2 = gainComp->rx1Offset;
+    }
+
+    /* Write gain compensation setup to device */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET, regWr2);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET, regWr3);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_GAIN_COMP_CFG, regWr4);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Get gain compensation setup and enabled function.
+ *
+ * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the Rx channels.
+ * This function will get the current setup and the enable state of the block.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gainComp pointer to a mykonosGainComp_t structure, will held the current device gain compensation settings.
+ * \param enabled pointer this parameter will contain the enable state of the gain compensation block.
+ * enabled = 1
+ * disabled = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GAINCOMP_NULL_STRUCT gain compensation structure gainComp is not initialised
+ */
+mykonosGpioErr_t MYKONOS_getRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t *enabled)
+{
+    uint8_t regWr2 = 0x00;
+    uint8_t regWr3 = 0x00;
+    uint8_t regWr4 = 0x00;
+
+    /* Mask parameter values populating mykonosGainComp_t structure */
+    const uint8_t ENABLED_MASK = 0x80;
+    const uint8_t STEP_MASK = 0x07;
+
+    /* Shift values for writing gain values */
+    const uint8_t ENABLED_SHIFT = 0x07;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxGainCompensation()\n");
+#endif
+
+    /* Check for gainComp for Null */
+    if (gainComp == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GAINCOMP_NULL_STRUCT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GAINCOMP_NULL_STRUCT));
+        return MYKONOS_ERR_GAINCOMP_NULL_STRUCT;
+    }
+
+    /* Read gain compensation setup from device */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET, &regWr2);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET, &regWr3);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX_GAIN_COMP_CFG, &regWr4);
+
+
+    /* Parsing read data to passed by reference parameters */
+    *enabled = (regWr4 & ENABLED_MASK) >> ENABLED_SHIFT;
+    gainComp->compStep = (regWr4 & STEP_MASK);
+    gainComp->rx2Offset = regWr3;
+    gainComp->rx1Offset = regWr2;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Gain compensation enable and setup function for the observation channel.
+ *
+ * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the observation channels.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gainComp is a pointer to the mykonosObsRxGainComp_t structure.
+ * \param enable enables or disables the gain compensation block.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT gain compensation structure gainComp is not initialised
+ * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET gain compensation structure gainComp->obsRxOffset is invalid
+ * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP gain compensation structure gainComp->compStep is invalid
+ * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN enable is not valid
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t enable)
+{
+    uint8_t regWr2 = 0x00;
+    uint8_t regWr3 = 0x00;
+
+    /* Max parameter values for error checking */
+    const uint8_t RXOFFSET_RANGE = 0x1F;
+
+    /* Shift values for writing gain values */
+    const uint8_t STEP_RANGE = 0x07;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxGainCompensation()\n");
+#endif
+
+    /* Check for gainComp initialised */
+    if (gainComp == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT));
+        return MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT;
+    }
+
+    /* Check for enable */
+    if (enable > 1)
+    {
+      CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN,
+                         getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN));
+      return MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN;
+    }
+    else if (enable == 1)
+    {
+        /* Check for gain compensation offset range */
+        if (gainComp->obsRxOffset > RXOFFSET_RANGE)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET,
+                               getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET));
+                return MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET;
+        }
+
+        /* Check for gain compensation step range */
+        if (gainComp->compStep > STEP_RANGE)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP));
+            return MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP;
+        }
+
+        /* Enabling gain compensation block */
+        regWr3 = 0x88 | gainComp->compStep;
+        regWr2 = ((gainComp->obsRxOffset & 0x1E) >> 1) | ((gainComp->obsRxOffset & 0x01) << 4);
+    }
+
+    /* Write gain compensation setup to device */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET, regWr2);
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG, regWr3);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Get gain compensation setup and enabled function for the observation channel.
+ *
+ * The gain compensation block is a function that compensates for the attenuation in the internal attenuator for the observation
+ * channels.
+ * This function will get the current setup and the enable state of the block.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gainComp pointer to a mykonosObsRxGainComp_t structure, will held the current device gain compensation settings.
+ * \param enabled pointer this parameter will contain the enable state of the gain compensation block.
+ * enabled = 1
+ * disabled = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT observation channel gain compensation structure gainComp is not initialised
+ */
+mykonosGpioErr_t MYKONOS_getObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t *enabled)
+{
+    uint8_t regRd2 = 0x00;
+    uint8_t regRd3 = 0x00;
+
+    /* Masks values for populating mykonosObsRxGainComp_t structure */
+    const uint8_t ENABLED_MASK = 0x80;
+    const uint8_t STEP_MASK = 0x07;
+
+    /* Shift values for populating mykonosObsRxGainComp_t structure */
+    const uint8_t ENABLED_SHIFT = 0x07;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxGainCompensation()\n");
+#endif
+
+    /* Check for gainComp for Null */
+    if (gainComp == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT));
+        return MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT;
+    }
+
+    /* Read gain compensation setup from device */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET, &regRd2);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG, &regRd3);
+
+
+    /* Parsing read data to passed by reference parameters */
+    *enabled = (regRd3 & ENABLED_MASK) >> ENABLED_SHIFT;
+    gainComp->compStep = (regRd3 & STEP_MASK);
+    gainComp->obsRxOffset = ((regRd2 & 0x0F) << 1) | ((regRd2 & 0x10) >> 4);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Slicer control over GPIO inputs.
+ *
+ * The user can control the slicer position via 3 GPIO inputs per channel.
+ * There are various configurations for the GPIO pins, this configurations are enumerated in the mykonosRxSlicer_t.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - Gain compensation block has to be enabled in order to user the slicer control
+ *
+ * \param device is a pointer to the device settings structure
+ * \param slicerStep configures the step size of the slicer when external pin contol mode is enabled.
+ * Slicer gain in this mode is determined by multiplying the step size by the input bit code from the BBP.
+ * Step sizes are as follows:
+ * sllicerStep  |  step
+ * -------------|------------
+ *       0      |   1
+ *       1      |   2
+ *       2      |   3
+ *       3      |   4
+ *
+ * \param rx1Pins Rx1 slicer inputs can take values from one of the following combinations that are specified in mykonosRxSlicer_t enum:
+ * -GPIO_2, GPIO_1, and GPIO_0
+ * -GPIO_7, GPIO_6, and GPIO_5
+ * -GPIO_10, GPIO_9, and GPIO_8
+ * \param rx2Pins Rx2 slicer inputs can take values from one of the following combinations that are specified in mykonosRxSlicer_t enum:
+ * -GPIO_7, GPIO_6, and GPIO_5
+ * -GPIO_13, GPIO_12, and GPIO_11
+ * \param enable this parameter enables the external pin control mode so the BBP can control the slicer setting.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SLICER_INV_RX1_SEL invalid RX1 GPIO pin selection for Slicer control
+ * \retval MYKONOS_ERR_SLICER_INV_RX2_SEL invalid RX2 GPIO pin selection for Slicer control
+ * \retval MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE slicer step is out of range
+ * \retval MYKONOS_ERR_SLICER_EN_INV invalid enable
+ */
+mykonosGpioErr_t MYKONOS_setRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosRxSlicer_t rx1Pins, mykonosRxSlicer_t rx2Pins, uint8_t enable)
+{
+    uint8_t regWr = 0x00;
+
+    const uint8_t STEP_MASK = 0x03;
+    const uint8_t STEP_SHIFT = 0x05;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxSlicerCtrl()\n");
+#endif
+
+    if (enable > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_EN_INV,
+                             getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_EN_INV));
+        return MYKONOS_ERR_SLICER_EN_INV;
+    }
+    else if (enable == 1)
+    {
+        /* Enabling Slicer input control */
+        regWr = 0x80;
+
+        /* Check for Rx1 Slicer input control */
+        switch (rx1Pins)
+        {
+            case GPIO_0_1_2:
+                regWr |= 0x00;
+                break;
+            case GPIO_5_6_7:
+                regWr |= 0x01;
+                break;
+            case GPIO_8_9_10:
+                regWr |= 0x02;
+                break;
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_INV_RX1_SEL,
+                               getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_INV_RX1_SEL));
+                return MYKONOS_ERR_SLICER_INV_RX1_SEL;
+        }
+
+        /* Check for Rx2 Slicer input control */
+        switch (rx2Pins)
+        {
+            case GPIO_5_6_7:
+               regWr |= 0x00;
+               break;
+           case GPIO_11_12_13:
+               regWr |= 0x04;
+               break;
+           default:
+               CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_INV_RX2_SEL,
+                              getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_INV_RX2_SEL));
+               return MYKONOS_ERR_SLICER_INV_RX2_SEL;
+        }
+
+        /* Check for Slicer input step size control */
+        if (slicerStep > STEP_MASK)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE));
+            return MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE;
+        }
+        else
+        {
+            regWr |= (slicerStep << STEP_SHIFT);
+        }
+    }
+
+    /* Write to device the slicer configuration */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_RX_SLCR_PIN_CFG, regWr);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This function will get the programmed Slicer control for Rx1 and Rx2 channels.
+ *
+ * The user can control the slicer position via 3 GPIO inputs per channel.
+ * There are various configurations for the GPIO pins, this configurations are enumerated in the mykonosRxSlicer_t.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param slicerStep will contain the configured step size
+ * \param rx1Pins will contain the configured GPIO combination for Rx1
+ * \param rx2Pins will contain the configured GPIO combination for Rx2
+ * \param enable will contain the programmed enable setting
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM rx1Pins is null pointer for the passed parameter
+ * \retval MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM rx1Pins is null pointer for the passed parameter
+ * \retval MYKONOS_ERR_SLICER_STEP_NULL_PARM slicerStep is null pointer for the passed parameter
+ * \retval MYKONOS_ERR_SLICER_EN_NULL_PARM enable is null pointer for the passed parameter
+ */
+mykonosGpioErr_t MYKONOS_getRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosRxSlicer_t *rx1Pins, mykonosRxSlicer_t *rx2Pins, uint8_t *enable)
+{
+    uint8_t regRd = 0x00;
+
+    /* Mask parameter values populating parameters */
+    const uint8_t EN_MASK = 0x80;
+    const uint8_t STEP_MASK = 0x60;
+    const uint8_t RX1_MASK = 0x03;
+    const uint8_t RX2_MASK = 0x0C;
+
+    /* Shift values for populating passed parameters */
+    const uint8_t EN_SHIFT = 0x07;
+    const uint8_t STEP_SHIFT = 0x05;
+    const uint8_t RX1_SHIFT = 0x00;
+    const uint8_t RX2_SHIFT = 0x02;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxSlicerCtrl()\n");
+#endif
+
+    /* Check for Rx1 Slicer input control null parameter */
+    if (rx1Pins == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM));
+        return MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM;
+    }
+
+    /* Check for Rx2 Slicer input control null parameter */
+    if (rx2Pins == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM));
+        return MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM;
+    }
+
+    /* Check for Slicer step control null parameter */
+    if (slicerStep == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_STEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_STEP_NULL_PARM));
+        return MYKONOS_ERR_SLICER_STEP_NULL_PARM;
+    }
+
+    /* Check for Slicer step control null parameter */
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_EN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_EN_NULL_PARM));
+        return MYKONOS_ERR_SLICER_EN_NULL_PARM;
+    }
+
+    /* Reading SLicer control register */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_RX_SLCR_PIN_CFG, &regRd);
+
+    /* Parsing values */
+    *enable = (regRd & EN_MASK) >> EN_SHIFT;
+    *slicerStep = (regRd & STEP_MASK) >> STEP_SHIFT;
+
+    /* Map to enum */
+    switch ((regRd & RX2_MASK) >> RX2_SHIFT)
+    {
+        case 0:
+            *rx2Pins = GPIO_5_6_7;
+            break;
+        case 1:
+            *rx2Pins = GPIO_11_12_13;
+            break;
+
+        default:
+            *rx2Pins = GPIO_5_6_7;
+    }
+
+    *rx1Pins = (regRd & RX1_MASK) >> RX1_SHIFT;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Slicer control over GPIO inputs for the observation channel.
+ *
+ * The user can control the slicer position via 3 GPIO inputs for the observation channel.
+ * There are various configurations for the GPIO pins, this configurations are enumerated in the mykonosObsRxSlicer_t.
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - Gain compensation block has to be enabled in order to user the slicer control
+ *
+ * \param device is a pointer to the device settings structure
+ * \param slicerStep configures the step size of the slicer when external pin contol mode is enabled.
+ * Slicer gain in this mode is determined by multiplying the step size by the input bit code from the BBP.
+ * Step sizes are as follows:
+ * sllicerStep  |  step
+ * -------------|------------
+ *       0      |   1
+ *       1      |   2
+ *       2      |   3
+ *       3      |   4
+ *
+ * \param obsRxPins observation slicer inputs can take values from one of the following combinations that are specified in mykonosObsRxSlicer_t enum:
+ * -GPIO_18, GPIO_17 and GPIO_16
+ * -GPIO_16, GPIO_15 and GPIO_14
+ * \param enable enables the external pin control mode so the BBP can control the slicer setting.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_SLICER_INV_OBS_RX_SEL invalid observation channel GPIO pin selection for Slicer control
+ * \retval MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE slicer step is out of range
+ * \retval MYKONOS_ERR_SLICER_OBS_RX_EN_INV invalid enable
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosObsRxSlicer_t obsRxPins, uint8_t enable)
+{
+    uint8_t regWr = 0x00;
+
+    const uint8_t STEP_MASK = 0x03;
+    const uint8_t STEP_SHIFT = 0x05;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setObsRxSlicerCtrl()\n");
+#endif
+
+    if (enable > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_EN_INV,
+                             getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_EN_INV));
+        return MYKONOS_ERR_SLICER_OBS_RX_EN_INV;
+    }
+    else if (enable == 1)
+    {
+        /* Enabling Slicer input control */
+        regWr = 0x80;
+
+        /* Check for Rx1 Slicer input control */
+        switch (obsRxPins)
+        {
+            case GPIO_18_17_16:
+                regWr |= 0x00;
+                break;
+            case GPIO_16_15_14:
+                regWr |= 0x01;
+                break;
+
+            default:
+                CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_INV_OBS_RX_SEL,
+                               getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_INV_OBS_RX_SEL));
+                return MYKONOS_ERR_SLICER_INV_OBS_RX_SEL;
+        }
+
+        /* Check for Slicer input step size control */
+        if (slicerStep & ~STEP_MASK)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE));
+            return MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE;
+        }
+        else
+        {
+            regWr |= (slicerStep << STEP_SHIFT);
+        }
+    }
+
+    /* Write to device the slicer configuration */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG, regWr);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This function will get the programmed Slicer control for observation channel.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param slicerStep will contain the configured step size
+ * \param obsRxPins will contain the configured GPIO combination
+ * \param enable will contain the programmed enable setting
+ *
+ * \retval MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM obsRxPins is null pointer for the passed parameter
+ * \retval MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM slicerStep is null pointer for the passed parameter
+ * \retval MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM, enable is null pointer for the passed parameter
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosObsRxSlicer_t *obsRxPins, uint8_t *enable)
+{
+    uint8_t regRd = 0x00;
+
+    /* Mask parameter values populating slicer parameters */
+    const uint8_t EN_MASK = 0x80;
+    const uint8_t STEP_MASK = 0x60;
+    const uint8_t OBS_RX_MASK = 0x03;
+
+    /* Shift values for writing slicer parameters */
+    const uint8_t EN_SHIFT = 0x07;
+    const uint8_t STEP_SHIFT = 0x05;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getObsRxSlicerCtrl()\n");
+#endif
+
+    /* Check for Rx1 Slicer input control null parameter */
+    if (obsRxPins == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM));
+        return MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM;
+    }
+
+    /* Check for Slicer step control null parameter */
+    if (slicerStep == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM));
+        return MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM;
+    }
+
+    /* Check for Slicer step control null parameter */
+    if (enable == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM));
+        return MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM;
+    }
+
+    /* Reading Slicer control register */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG, &regRd);
+
+    /* Parsing values */
+    *enable = (regRd & EN_MASK) >> EN_SHIFT;
+    *slicerStep = (regRd & STEP_MASK) >> STEP_SHIFT;
+
+    /* Map to enum */
+    switch (regRd & OBS_RX_MASK)
+    {
+        case 0:
+            *obsRxPins = GPIO_18_17_16;
+            break;
+        case 1:
+            *obsRxPins = GPIO_16_15_14;
+            break;
+
+        default:
+            *obsRxPins = 0;
+            break;
+    }
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Floating point formatter enable and setup function.
+ *
+ * The floating point formatter block is a function that works in conjunction with the gain
+ * compensating block, as the gain compensation requires increased dynamic range (total gain range on AD9370 is 42dB)
+ * which increases the bitwidth in the digital datapath.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - Gain compensation block has to be enabled in order to user floating point formatter
+ *
+ * \param device is a pointer to the device settings structure
+ * \param floatFrmt which is a mykonosFloatPntFrmt_t structure.
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT floating point formatter structure floatFrmt not initialized
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE floating point formatter structure floatFrmt.roundMode not valid parameter
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT floating point formatter structure floatFrmt.dataFormat not valid parameter
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN floating point formatter structure floatFrmt.encNan not valid parameter
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS floating point formatter structure floatFrmt.expBits not valid parameter
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_LEADING floating point formatter structure floatFrmt.leading not valid parameter
+ */
+mykonosGpioErr_t MYKONOS_setFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt)
+{
+    uint8_t regWr1 = 0x00;
+
+    /* Max parameter values for error checking */
+    const uint8_t ROUND_RANGE = 0x04;
+    const uint8_t DATA_FRMT_RANGE = 0x01;
+    const uint8_t ENCODE_RANGE = 0x01;
+    const uint8_t EXPBITS_RANGE = 0x03;
+    const uint8_t LEADING_RANGE = 0x01;
+
+    /* Shift values for writing mykonosFloatPntFrmt_t values */
+    const uint8_t ROUND_SHIFT = 0x05;
+    const uint8_t DATA_FRMT_SHIFT = 0x04;
+    const uint8_t ENCODE_SHIFT = 0x03;
+    const uint8_t EXPBITS_SHIFT = 0x01;
+    const uint8_t LEADING_SHIFT = 0x00;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setFloatPointFrmt()\n");
+#endif
+
+    /* Check for gainComp initialised */
+    if (&floatFrmt->dataFormat == 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT));
+        return MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT;
+    }
+
+    /* Check for floating point round mode */
+    if (floatFrmt->roundMode > ROUND_RANGE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE));
+        return MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE;
+    }
+
+    /* Check for floating point data format */
+    if (floatFrmt->dataFormat > DATA_FRMT_RANGE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT,
+                           getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT));
+            return MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT;
+    }
+
+    /* Check for floating point encode NaN */
+    if (floatFrmt->encNan > ENCODE_RANGE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN,
+                          getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN));
+        return MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN;
+    }
+
+    /* Check for floating point exponent bits range */
+    if (floatFrmt->expBits > EXPBITS_RANGE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS));
+        return MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS;
+    }
+
+    /* Check for floating point hide leading ones */
+    if (floatFrmt->leading > LEADING_RANGE)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_LEADING,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_LEADING));
+        return MYKONOS_ERR_FLOATFRMT_INV_LEADING;
+    }
+
+    regWr1 = (floatFrmt->roundMode << ROUND_SHIFT) | (floatFrmt->dataFormat << DATA_FRMT_SHIFT) |
+             (floatFrmt->encNan << ENCODE_SHIFT) | (floatFrmt->expBits << EXPBITS_SHIFT) |
+             (floatFrmt->leading << LEADING_SHIFT);
+
+
+    /* Write gain compensation setup to device */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_CFG, regWr1);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Floating point formatter setup function.
+ *
+ * The floating point formatter block is a function that works in conjunction with the gain
+ * compensating block, as the gain compensation requires increased dynamic range
+ * which increases the bit-width in the digital data-path.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - Gain compensation block has to be enabled in order to user floating point formatter
+ *
+ * \param device is a pointer to the device settings structure
+ * \param floatFrmt which is a mykonosFloatPntFrmt_t structure.
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_FLOATFRMT_NULL_STRUCT floating point formatter structure floatFrmt not initialized
+ *
+ */
+mykonosGpioErr_t MYKONOS_getFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt)
+{
+    uint8_t regRd1 = 0x00;
+
+    /* Mask parameter values populating mykonosGainComp_t structure */
+    const uint8_t ROUND_MASK = 0xE0;
+    const uint8_t DATA_FRMT_MASK = 0x10;
+    const uint8_t ENCODE_MASK = 0x08;
+    const uint8_t EXPBITS_MASK = 0x06;
+    const uint8_t LEADING_MASK = 0x01;
+
+    /* Shift values for writing gain values */
+    const uint8_t ROUND_SHIFT = 0x05;
+    const uint8_t DATA_FRMT_SHIFT = 0x04;
+    const uint8_t ENCODE_SHIFT = 0x03;
+    const uint8_t EXPBITS_SHIFT = 0x01;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getFloatPointFrmt()\n");
+#endif
+
+    /* Check floatFrmt for Null */
+    if (floatFrmt == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_STRUCT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_STRUCT));
+        return MYKONOS_ERR_FLOATFRMT_NULL_STRUCT;
+    }
+
+    /* Read gain compensation setup from device */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_CFG, &regRd1);
+
+    /* Parsing read data to passed by reference parameters */
+    floatFrmt->roundMode = (regRd1 & ROUND_MASK) >> ROUND_SHIFT;
+    floatFrmt->dataFormat = (regRd1 & DATA_FRMT_MASK) >> DATA_FRMT_SHIFT;
+    floatFrmt->encNan = (regRd1 & ENCODE_MASK) >> ENCODE_SHIFT;
+    floatFrmt->expBits = (regRd1 & EXPBITS_MASK) >> EXPBITS_SHIFT;
+    floatFrmt->leading = regRd1 & LEADING_MASK;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Floating point formatter enable/disable Rx1 and Rx2 function.
+ *
+ * The floating point formatter block is a function that works in conjunction with the gain
+ * compensating block, as the gain compensation requires increased dynamic range
+ * which increases the bit-width in the digital data-path.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ * - Gain compensation block has to be enabled in order to user floating point formatter
+ *
+ * \param device is a pointer to the device settings structure
+ * \param rx1Att this parameter sets the integer data attenuation for the Rx1 channel in 6dB steps
+ * to enable the entire data range to be represented in the selected floating point format.
+ * \param rx2Att this parameter sets the integer data attenuation for the Rx2 channel in 6dB steps
+ * to enable the entire data range to be represented in the selected floating point format.
+ * \param enable this parameter enables or disables the gain compensation block.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT not valid rx1 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt()
+ * \retval MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT not valid rx2 attenuation parameter passed in MYKONOS_setRxEnFloatPntFrmt()
+ * \retval MYKONOS_ERR_FLOATFRMT_SET_INV_EN not valid enable parameter passed in MYKONOS_setRxEnFloatPntFrmt()
+ */
+mykonosGpioErr_t MYKONOS_setRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t rx1Att, uint8_t rx2Att, uint8_t enable)
+{
+    uint8_t regWr = 0x00;
+
+    const uint8_t RXATT_RANGE = 0x07;
+    const uint8_t RX1ATT_SHIFT = 0x01;
+    const uint8_t RX2ATT_SHIFT = 0x05;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setRxEnFloatPntFrmt()\n");
+#endif
+
+    if (enable > 1)
+    {
+       CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_INV_EN,
+                          getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_INV_EN));
+       return MYKONOS_ERR_FLOATFRMT_SET_INV_EN;
+    }
+    else if (enable == 1)
+    {
+        /* Check for rx1Att range */
+        if (rx1Att > RXATT_RANGE)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT));
+            return MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT;
+        }
+
+        /* Check for rx2Att range */
+        if (rx2Att > RXATT_RANGE)
+        {
+           CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT,
+                   getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT));
+           return MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT;
+        }
+
+        /* Enabling floating point formatter for Rx1 and Rx2 */
+        regWr = 0x11;
+        regWr |= (rx1Att << RX1ATT_SHIFT) | (rx2Att << RX2ATT_SHIFT);
+    }
+
+    /* Writing floating point formatter enables for Rx1 and Rx2 */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_RX_CTRL, regWr);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Floating point formatter setup function.
+ *
+ * The floating point formatter block is a function that works in conjunction with the gain
+ * compensating block, as the gain compensation requires increased dynamic range (total gain range on AD9370 is 42dB)
+ * which increases the bitwidth in the digital datapath.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param rx1Att this parameter sets the integer data attenuation for the Rx1 channel in 6dB steps
+ * to enable the entire data range to be represented in the selected floating point format.
+ * \param rx2Att this parameter sets the integer data attenuation for the Rx2 channel in 6dB steps
+ * to enable the entire data range to be represented in the selected floating point format.
+ * \param enable this parameter enables or disables the gain compensation block.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT null pointer passed for rx1 attenuation in MYKONOS_setRxEnFloatPntFrmt()
+ * \retval MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT null pointer passed for rx2 attenuation in MYKONOS_setRxEnFloatPntFrmt()
+ * \retval MYKONOS_ERR_FLOATFRMT_NULL_ENABLE null pointer passed for enable in MYKONOS_setRxEnFloatPntFrmt()
+ */
+mykonosGpioErr_t MYKONOS_getRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *rx1Att, uint8_t *rx2Att, uint8_t *enable)
+{
+    uint8_t regRd = 0x00;
+
+    const uint8_t EN_MASK = 0x11;
+    const uint8_t RX1ATT_MASK = 0x0E;
+    const uint8_t RX1ATT_SHIFT = 0x01;
+    const uint8_t RX2ATT_MASK = 0xE0;
+    const uint8_t RX2ATT_SHIFT = 0x05;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getRxEnFloatPntFrmt()\n");
+#endif
+
+    /* Check for rx1Att NULL parameter */
+    if (rx1Att == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT));
+        return MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT;
+    }
+
+    /* Check for rx2Att NULL parameter */
+    if (rx2Att == NULL)
+    {
+       CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT,
+               getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT));
+       return MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT;
+    }
+
+    /* Check for enable NULL parameter */
+    if (enable == NULL)
+    {
+      CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_ENABLE,
+              getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_ENABLE));
+      return MYKONOS_ERR_FLOATFRMT_NULL_ENABLE;
+    }
+
+    /* Read Rx1 and Rx2 floating point enables */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_RX_CTRL, &regRd);
+
+    *rx1Att = (regRd & RX1ATT_MASK) >> RX1ATT_SHIFT;
+    *rx2Att = (regRd & RX2ATT_MASK) >> RX2ATT_SHIFT ;
+    *enable = (regRd & EN_MASK) ? 1 : 0;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+
+/**
+ * \brief Floating point formatter enable function for ORx channel.
+ *
+ * The floating point formatter block is a function that works in conjunction with the gain
+ * compensating block, as the gain compensation requires increased dynamic range
+ * which increases the bit-width in the digital data-path.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param orxAtt this parameter sets the integer data attenuation for the ORx channel in 6dB steps
+ * to enable the entire data range to be represented in the selected floating point format.
+ * * \param enable this parameter enables or disables the gain compensation block.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_ORXATT not valid Orx attenuation parameter passed in MYKONOS_setOrxEnFloatPntFrmt()
+ * \retval MYKONOS_ERR_FLOATFRMT_INV_ORXEN not valid enable parameter passed in MYKONOS_setOrxEnFloatPntFrmt()
+ */
+mykonosGpioErr_t MYKONOS_setOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t orxAtt, uint8_t enable)
+{
+    uint8_t regWr = 0x00;
+
+    const uint8_t ORXATT_RANGE = 0x07;
+    const uint8_t ORXATT_SHIFT = 0x01;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setOrxEnFloatPntFrmt()\n");
+#endif
+
+    /* Check for enable */
+    if (enable > 1)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ORXEN,
+                          getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ORXEN));
+        return MYKONOS_ERR_FLOATFRMT_INV_ORXEN;
+    }
+    else if (enable == 1)
+    {
+        /* Check for rx1Att range */
+        if (orxAtt > ORXATT_RANGE)
+        {
+           CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_INV_ORXATT,
+                   getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_INV_ORXATT));
+           return MYKONOS_ERR_FLOATFRMT_INV_ORXATT;
+        }
+
+        /* Enabling floating point formatter for Rx1 and Rx2 */
+        regWr = 0x01;
+        regWr |= orxAtt << ORXATT_SHIFT;
+    }
+
+    /* Writing floating point formatter enable for ORX channel */
+    CMB_SPIWriteByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL, regWr);
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Floating point formatter enable and setup function.
+ *
+ * The floating point formatter block is a function that works in conjunction with the gain
+ * compensating block, as the gain compensation requires increased dynamic range (total gain range on AD9370 is 42dB)
+ * which increases the bitwidth in the digital datapath.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param orxAtt this parameter sets the integer data attenuation for the ORx channel in 6dB steps
+ * to enable the entire data range to be represented in the selected floating point format.
+ * \param enable this parameter enables or disables the gain compensation block.
+ * enable = 1
+ * disable = 0
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_FLOATFRMT_NULL_ORXATT null pointer passed for orxAtt
+ * \retval MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE null pointer passed for enable
+ */
+mykonosGpioErr_t MYKONOS_getOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *orxAtt, uint8_t *enable)
+{
+    uint8_t regRd = 0x00;
+
+    const uint8_t EN_MASK = 0x01;
+    const uint8_t ORXATT_MASK = 0x0E;
+    const uint8_t ORXATT_SHIFT = 0x01;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getOrxEnFloatPntFrmt()\n");
+#endif
+
+    /* Check for orxAtt NULL parameter */
+    if (orxAtt == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_ORXATT,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_ORXATT));
+        return MYKONOS_ERR_FLOATFRMT_NULL_ORXATT;
+    }
+
+    /* Check for enable NULL parameter */
+    if (enable == NULL)
+    {
+      CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE,
+              getGpioMykonosErrorMessage(MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE));
+      return MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE;
+    }
+
+    /* Read Rx1 and Rx2 floating point enables */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL, &regRd);
+
+    *orxAtt = (regRd  & ORXATT_MASK) >> ORXATT_SHIFT;
+    *enable = (regRd & EN_MASK) ? 1 : 0;
+
+    /* Return */
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief Sets up the Temperature Sensor
+ *
+ *  Before using this function to set up the temp sensor,
+ *  make sure that you call the MYKONOS_setupAuxADC() function
+ *  to ensure that the AuxADC clock is setup and running correctly at 40 MHz,
+ *  and that the structure mykonosTempSensorConfig_t tempSensor is populated.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param tempSensor is a pointer to the mykonosTempSensorConfig_t which holds
+ * the configuration settings for the temperature sensor
+ *
+ * \retval MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM Function parameter tempSensor is a NULL pointer
+ * \retval MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION tempDecimation value out of range (0-7)
+ * \retval MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET offset value out of range (0-255)
+ * \retval MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW tempWindow out of range (0-15)
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setupTempSensor(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor)
+{
+    uint8_t offsetFromDevice = 0;
+
+    const uint8_t OFFSET_API = 0x43;
+    const uint8_t TEMP_OFFSET_MASK = 0xFF;
+    const uint8_t TEMP_WINDOW_MASK = 0xF0;
+    const uint8_t TEMP_WINDOW_CHECK = 0x0F;
+    const uint8_t TEMP_DEC_MASK = 0x07;
+    const uint8_t OFFSET_OVERRIDE_MASK = 0x10;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setupTempSensor()\n");
+#endif
+
+    /* Check for structure initialisation mykonosTempSensorConfig_t */
+    if (tempSensor == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM));
+        return MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM;
+    }
+
+    /* Check Temperature sensor decimation range */
+    if ((tempSensor->tempDecimation & ~TEMP_DEC_MASK) > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION));
+        return MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION;
+    }
+
+    /* Override fused offset */
+    if (tempSensor->overrideFusedOffset > 0)
+    {
+        /* Check Temperature sensor offset range */
+        if (tempSensor->offset & ~TEMP_OFFSET_MASK)
+        {
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET));
+            return MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET;
+        }
+
+        CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, 1, OFFSET_OVERRIDE_MASK, 4);
+        CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, tempSensor->offset);
+    }
+    else
+    {
+        /* If manual override was not requested, read back device offset value.
+         * If factory fused it is non-zero; else API adds a typical offset value */
+        CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, &(offsetFromDevice));
+        if (offsetFromDevice == 0)
+        {
+            CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, OFFSET_API);
+        }
+    }
+
+    /* Check Temperature sensor window range */
+    if ((tempSensor->tempWindow & ~TEMP_WINDOW_CHECK) > 0)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW));
+        return MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW;
+    }
+    else
+    {
+        CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, tempSensor->tempWindow, TEMP_WINDOW_MASK, 4);
+    }
+
+    /* Single shot setup */
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_MSB, 0x00);
+
+    /* Write decimation factor for the Temperature sensor */
+    CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, tempSensor->tempDecimation, TEMP_DEC_MASK, 0);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads from the Temperature Sensor registers and populates device data structure
+ *
+ *  After this function is executed, the tempSensor parameter holds updated values
+ *  from the device registers.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param tempSensor is a pointer to the mykonosTempSensorConfig_t which holds
+ * the configuration settings for the tempSensor
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_GETTEMPSENSORCONFIG_NULL_PARAM Function parameter tempSensor is a NULL pointer
+ */
+mykonosGpioErr_t MYKONOS_getTempSensorConfig(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor)
+{
+    uint8_t tempConfig = 0;
+
+    const uint8_t TEMP_WINDOW_MASK = 0xF0;
+    const uint8_t TEMP_FUSE_MASK = 0x10;
+    const uint8_t TEMP_DECIMATION_MASK = 0x07;
+    const uint8_t TEMP_FUSE_SHIFT = 0x04;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getTempSensorConfig()\n");
+#endif
+
+    /* Check tempSensor null parameter passed */
+    if (tempSensor == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM));
+        return MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM;
+    }
+
+    /* Read back factory offset, if fused; else manual offset value */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_OFFSET, &(tempSensor->offset));
+
+    /* Read back Decimation and override Offset Temperature sensor parameters */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, &tempConfig);
+    tempSensor->overrideFusedOffset = (tempConfig & TEMP_FUSE_MASK) >> TEMP_FUSE_SHIFT;
+    tempSensor->tempDecimation = (tempConfig & TEMP_DECIMATION_MASK);
+
+    /* Read back tempWindow */
+    CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, &tempConfig, TEMP_WINDOW_MASK, 4);
+    tempSensor->tempWindow = tempConfig;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Initiates temperature measurement
+ *
+ * This function will initiate the Temperature sensor measurement.
+ *
+ * \pre
+ * MYKONOS_setupTempSensor() function to set the temperature sensor.
+ * MYKONOS_setAuxAdcChannel() function with the AuxADC setting for Temperature sensor channel MYK_TEMPSENSOR
+ * from the enum type mykonosAuxAdcChannels_t.
+ *
+ * \post
+ * Internal temperature sensor will perform measurement and updated register values,
+ * read back using MYKONOS_readTempSensor() function.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_startTempMeasurement(mykonosDevice_t *device)
+{
+    const uint8_t TEMP_LOCK_MASK = 0x80;
+    const uint8_t TEMP_LOCK_BIT = 0x01;
+    const uint8_t MEASUREMENT_MASK = 0x01;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_startTempMeasurement()\n");
+#endif
+
+    /* Write the lock bit to ensure that a valid measurement is achieved */
+    CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, TEMP_LOCK_BIT, TEMP_LOCK_MASK, 7);
+
+    /* Initiate Temperature measurement */
+    CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, 1, MEASUREMENT_MASK, 0);
+    CMB_SPIWriteField (device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, 0, MEASUREMENT_MASK, 0);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief Reads temperature code and statuses from the Temperature Sensor registers
+ *
+ *  This function reads the temperature sensor's statuses and temperature code.
+ *  Allow at least one computation period to elapse.
+ *  The temperature sensor computation period is as 6 times the AuxADC conversion time.
+ *  AuxADC conversion time = (1/40Mhz) * (256 * 2^(tempDecimation))
+ *
+ *  Before using this function to read back the temperature, make sure that temperature sensor
+ *  is setup using the MYKONOS_setupTempSensor() function.
+ *
+ * \pre Before using this function to read back the sensor value:
+ *  MYKONOS_setupTempSensor() function is needed in order to set up the Temperature sensor.
+ *  MYKONOS_setAuxAdcChannel() function has to be called in order to set the proper AuxADC
+ *  channel. AuxADC channel MYK_TEMPSENSOR is used for the Temperature sensor.
+ *  MYKONOS_startTempMeasurement() this function will start the Temperature sensor, this
+ *  function is needed to be called for every reading that needs to be performed.
+ *
+ * \post "tempStatus" structure will contain the status information and the temperature
+ *  code.
+ *  If a valid measurement is achieved then tempStatus->tempValid will be set and
+ *  tempStatus->tempCode will contain the actual reading.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param tempStatus is a pointer to the mykonosTempSensorStatus_t structure which will be updated
+ * with the temp sensor readings
+ *
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ * \retval MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM Function parameter tempSensor is a NULL pointer
+ * \retval MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED temperature sensor reading is not locked
+ */
+mykonosGpioErr_t MYKONOS_readTempSensor(mykonosDevice_t *device, mykonosTempSensorStatus_t *tempStatus)
+{
+    int16_t temperature = 0;
+    uint8_t statusWord = 0;
+    uint8_t rgRd = 0x00;
+
+    const uint8_t CODE_TO_DEGREE_CELSIUS = 0x67;
+    const uint8_t TEMP_VALID_MASK = 0x02;
+    const uint8_t WINDOW_EXCEED_MASK = 0x08;
+    const uint8_t WINDOW_HI_LO_MASK = 0x04;
+    const uint8_t TEMP_LOCK = 0x80;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_readTempSensor()\n");
+#endif
+
+    if (tempStatus == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM));
+        return MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM;
+    }
+
+    /* Check for temperature sensor value lock */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONFIG, &rgRd);
+    if ((rgRd & TEMP_LOCK) == TEMP_LOCK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED,
+                        getGpioMykonosErrorMessage(MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED));
+        return MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED;
+    }
+
+    /* Perform temperature status reading */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB, &statusWord);
+    tempStatus->windowExceeded = (statusWord & WINDOW_EXCEED_MASK) >> 3;
+    tempStatus->windowHiLo = (statusWord & WINDOW_HI_LO_MASK) >> 2;
+    tempStatus->tempValid = (0x01 & ~((statusWord & TEMP_VALID_MASK) >> 1));
+
+    /* Perform temperature reading */
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_ADDR_TEMP_SENSOR_READ, &rgRd);
+    temperature = rgRd - CODE_TO_DEGREE_CELSIUS;
+    tempStatus->tempCode = temperature;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This function sets the drive strength for the required GPIOs.
+ *
+ * This function will set the required drive strength, the settings for GPIO drive strength are normal drive and double drive.
+ *
+ * GPIO pins that can be assigned independent drive strength are:
+ * -MYKGPIO0 to MYKGPIO7 and MYKGPIO18
+ *
+ * The rest of GPIOs are paired as:
+ * -MYKGPIO17 and MYKGPIO16
+ * -MYKGPIO8 and MYKGPIO15
+ * -MYKGPIO14 and MYKGPIO13
+ * -MYKGPIO10 and MYKGPIO9
+ * -MYKGPIO12 and MYKGPIO11
+ *
+ * This means that if it is required to double the drive strength for MYKGPIO17 then the drive strength will also be doubled for MYKGPIO16.
+ *
+ * If the particular bitfield for gpioDrv is set then the drive strength will be doubled. Note that multiple GPIOs can be set at a time.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioDrv GPIO drive strength setup, valid range is from 0x00000 to 0x7FFFF.
+ *
+ * \retval MYKONOS_ERR_GPIO_DRV_INV_PARAM GPIO out of range- valid GPIOs are in the range 0x00000 to 0x7FFFF.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpioDrv(mykonosDevice_t *device, mykonosGpioSelect_t gpioDrv)
+{
+    uint32_t error = MYKONOS_ERR_GPIO_OK;
+    uint8_t reg0 = 0x00;
+    uint8_t reg1 = 0x00;
+
+    const uint32_t GPIO_MASK = 0x7FFFF;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioDrv()\n");
+#endif
+
+    /* Error checking for correct number of GPIOs. */
+    if (gpioDrv > GPIO_MASK )
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_DRV_INV_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_DRV_INV_PARAM));
+        return MYKONOS_ERR_GPIO_DRV_INV_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_0, &reg0);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_1, &reg1);
+
+    reg1 = reg1 & 0xC0;
+
+    if (gpioDrv & 0xFF)
+    {
+        reg0 = (uint8_t)(gpioDrv & 0xFF);
+    }
+
+    if (gpioDrv & MYKGPIO18)
+    {
+        reg1 |= 0x01;
+    }
+
+    if ((gpioDrv & MYKGPIO17) || (gpioDrv & MYKGPIO16))
+    {
+        reg1 |= 0x02;
+    }
+
+    if ((gpioDrv & MYKGPIO15) || (gpioDrv & MYKGPIO8))
+    {
+        reg1 |= 0x04;
+    }
+
+    if ((gpioDrv & MYKGPIO14) || (gpioDrv & MYKGPIO13))
+    {
+        reg1 |= 0x08;
+    }
+
+    if ((gpioDrv & MYKGPIO10) || (gpioDrv & MYKGPIO9))
+    {
+        reg1 |= 0x10;
+    }
+
+    if ((gpioDrv & MYKGPIO12) || (gpioDrv & MYKGPIO11))
+    {
+        reg1 |= 0x20;
+    }
+
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_DRV_CTL_0, reg0);
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_DRV_CTL_1, reg1);
+
+    return error;
+}
+
+
+/**
+ * \brief This function gets the GPIOs drive strength.
+ *
+ * This function will get the programmed drive strength for all the GPIOs
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure.
+ * \param gpioDrv will contain the current GPIOs drive strength setting.
+ *
+ * \retval MYKONOS_ERR_GETGPIODRV_NULL_PARAM null parameter passed to the function.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getGpioDrv(mykonosDevice_t *device, mykonosGpioSelect_t *gpioDrv)
+{
+    uint32_t error = MYKONOS_ERR_GPIO_OK;
+    uint8_t reg0 = 0x00;
+    uint8_t reg1 = 0x00;
+    uint32_t gpioDrvRd = 0x00;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_getGpioDrv()\n");
+#endif
+
+    /* Error checking for correct number of GPIOs. */
+    if (gpioDrv == NULL )
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GETGPIODRV_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GETGPIODRV_NULL_PARAM));
+        return MYKONOS_ERR_GETGPIODRV_NULL_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_0, &reg0);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_DRV_CTL_1, &reg1);
+
+    gpioDrvRd = (uint32_t)reg0 & 0xFF;
+
+    if (reg1 & 0x01)
+    {
+        gpioDrvRd |= MYKGPIO18;
+    }
+
+    if (reg1 & 0x02)
+    {
+        gpioDrvRd |= MYKGPIO17 | MYKGPIO16;
+    }
+
+    if (reg1 & 0x04)
+    {
+        gpioDrvRd |= MYKGPIO8 | MYKGPIO15;
+    }
+
+    if (reg1 & 0x08)
+    {
+        gpioDrvRd |= MYKGPIO14 | MYKGPIO13;
+    }
+
+    if (reg1 & 0x10)
+    {
+        gpioDrvRd |= MYKGPIO10 | MYKGPIO9;
+    }
+
+    if (reg1 & 0x20)
+    {
+        gpioDrvRd |= MYKGPIO12 | MYKGPIO11;
+    }
+
+    *gpioDrv = gpioDrvRd;
+
+    return error;
+}
+
+/**
+ * \brief This function sets the slew rate for the required GPIOs.
+ *
+ * This function will set the required slew rate, the settings for GPIO slew rate are given by the enumeration type mykonosGpioSlewRate_t.
+ *
+ * GPIO pins that can be assigned independent slew rate are:
+ * -MYKGPIO0 to MYKGPIO7 and MYKGPIO18
+ *
+ * The rest of GPIOs are paired as:
+ * -MYKGPIO17 and MYKGPIO16
+ * -MYKGPIO8 and MYKGPIO15
+ * -MYKGPIO14 and MYKGPIO13
+ * -MYKGPIO10 and MYKGPIO9
+ * -MYKGPIO12 and MYKGPIO11
+ *
+ * This means that if it is required to set the slew rate for MYKGPIO17 then the same slew rate will be applied for MYKGPIO16.
+ *
+ * If the particular bitfield for gpioSelect is set then slewRate will be set for that GPIO. Note that multiple GPIOs can be set at a time.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param gpioSelect GPIO for which the slew rate will be changed, valid range 0x00000 to 0x7FFFF.
+ * \param slewRate slew rate setting, valid slew rate settings are given by the enumeration type mykonosGpioSlewRate_t
+ *
+ * \retval MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM GPIO out of range- valid GPIOs are in the range 0x00000 to 0x7FFFF.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t slewRate)
+{
+    uint32_t error = MYKONOS_ERR_GPIO_OK;
+    uint8_t reg0 = 0x00;
+    uint8_t reg1 = 0x00;
+    uint8_t reg2 = 0x00;
+    uint8_t reg3 = 0x00;
+
+    const uint32_t GPIO_MASK = 0x7FFFF;
+    const uint8_t SLEWRATE_MASK = 0x03;
+    const uint32_t SHIFT4NIBLE = 0x06;
+    const uint32_t SHIFT3NIBLE = 0x04;
+    const uint32_t SHIFT2NIBLE = 0x02;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioSlewRate()\n");
+#endif
+
+    /* Error checking for correct number of GPIOs. */
+    if ((gpioSelect > GPIO_MASK) || (slewRate > SLEWRATE_MASK))
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM));
+        return MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_0, &reg0);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_1, &reg1);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_2, &reg2);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, &reg3);
+
+    if (gpioSelect & MYKGPIO18)
+    {
+        reg0 = (reg0 & ~(SLEWRATE_MASK << SHIFT4NIBLE)) | (slewRate << SHIFT4NIBLE);
+    }
+    if ((gpioSelect & MYKGPIO17) || (gpioSelect & MYKGPIO16))
+    {
+        reg0 = (reg0 & ~(SLEWRATE_MASK << SHIFT3NIBLE)) | (slewRate << SHIFT3NIBLE);
+    }
+    if ((gpioSelect & MYKGPIO15) || (gpioSelect & MYKGPIO8))
+    {
+        reg0 = (reg0 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | (slewRate << SHIFT2NIBLE);
+    }
+    if ((gpioSelect & MYKGPIO14) || (gpioSelect & MYKGPIO13))
+    {
+        reg0 = (reg0 & ~(SLEWRATE_MASK)) | slewRate;
+    }
+    if ((gpioSelect & MYKGPIO11) || (gpioSelect & MYKGPIO12))
+    {
+        reg1 = (reg1 & ~(SLEWRATE_MASK << SHIFT4NIBLE)) | (slewRate << SHIFT4NIBLE);
+    }
+    if ((gpioSelect & MYKGPIO9) || (gpioSelect & MYKGPIO10))
+    {
+        reg1 = (reg1 & ~(SLEWRATE_MASK << SHIFT3NIBLE)) | (slewRate << SHIFT3NIBLE);
+    }
+    if (gpioSelect & MYKGPIO7)
+    {
+        reg1 = (reg1 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | (slewRate << SHIFT2NIBLE);
+    }
+    if (gpioSelect & MYKGPIO6)
+    {
+        reg1 = (reg1 & ~(SLEWRATE_MASK)) | slewRate;
+    }
+    if (gpioSelect & MYKGPIO5)
+    {
+        reg2 = (reg2 & ~(SLEWRATE_MASK << SHIFT4NIBLE)) | (slewRate << SHIFT4NIBLE);
+    }
+    if (gpioSelect & MYKGPIO4)
+    {
+        reg2 = (reg2 & ~(SLEWRATE_MASK << SHIFT3NIBLE)) | (slewRate << SHIFT3NIBLE);
+    }
+    if (gpioSelect & MYKGPIO3)
+    {
+        reg2 = (reg2 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | (slewRate << SHIFT2NIBLE);
+    }
+    if (gpioSelect & MYKGPIO2)
+    {
+        reg2 = (reg2 & ~(SLEWRATE_MASK)) | slewRate;
+    }
+    if (gpioSelect & MYKGPIO1)
+    {
+        reg3 = (reg3 & ~(SLEWRATE_MASK << SHIFT2NIBLE)) | (slewRate << SHIFT2NIBLE);
+    }
+    if (gpioSelect & MYKGPIO0)
+    {
+        reg3 = (reg3 & ~(SLEWRATE_MASK)) | slewRate;
+    }
+
+    /* Prepare registers */
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_0, reg0);
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_1, reg1);
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_2, reg2);
+    CMB_SPIWriteByte (device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, reg3);
+
+    return error;
+}
+
+
+/**
+ * \brief This function gets the GPIO slew rate setting.
+ *
+ * This function will get the programmed slew rate for the GPIO given by slewRateGpio.
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure.
+ * \param gpioSelect GPIO selection for getting the slew rate setting.
+ * \param slewRate will contain the GPIO slew rate setting.
+ *
+ * \retval MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM null parameter passed to the function.
+ * \retval MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM GPIO out of range- valid GPIOs are in the range 0x00000 to 0x7FFFF.
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t *slewRate)
+{
+    uint8_t reg0 = 0x00;
+    uint8_t reg1 = 0x00;
+    uint8_t reg2 = 0x00;
+    uint8_t reg3 = 0x00;
+    mykonosGpioSlewRate_t slewSetting = MYK_SLEWRATE_NONE;
+
+    const uint32_t SLEWRATE_MASK = 0x03;
+    const uint32_t SHIFT4NIBLE = 0x06;
+    const uint32_t SHIFT3NIBLE = 0x04;
+    const uint32_t SHIFT2NIBLE = 0x02;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioSlewRate()\n");
+#endif
+
+    /* Error checking for NULL parameter. */
+    if (slewRate == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM));
+        return MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_0, &reg0);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_1, &reg1);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_2, &reg2);
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, &reg3);
+
+    switch (gpioSelect)
+    {
+        case MYKGPIO18:
+            slewSetting = (reg0 & (SLEWRATE_MASK << SHIFT4NIBLE)) >> SHIFT4NIBLE;
+            break;
+        case MYKGPIO17:
+        case MYKGPIO16:
+            slewSetting = (reg0 & (SLEWRATE_MASK << SHIFT3NIBLE)) >> SHIFT3NIBLE;
+            break;
+        case MYKGPIO15:
+        case MYKGPIO8:
+            slewSetting = (reg0 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE;
+            break;
+        case MYKGPIO14:
+        case MYKGPIO13:
+            slewSetting = (reg0 & (SLEWRATE_MASK));
+            break;
+        case MYKGPIO11:
+        case MYKGPIO12:
+            slewSetting = (reg1 & (SLEWRATE_MASK << SHIFT4NIBLE)) >> SHIFT4NIBLE;
+            break;
+        case MYKGPIO9:
+        case MYKGPIO10:
+            slewSetting = (reg1 & (SLEWRATE_MASK << SHIFT3NIBLE)) >> SHIFT3NIBLE;
+            break;
+        case MYKGPIO7:
+            slewSetting = (reg1 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE;
+            break;
+        case MYKGPIO6:
+            slewSetting = (reg1 & (SLEWRATE_MASK));
+            break;
+        case MYKGPIO5:
+            slewSetting = (reg2 & (SLEWRATE_MASK << SHIFT4NIBLE)) >> SHIFT4NIBLE;
+            break;
+        case MYKGPIO4:
+            slewSetting = (reg2 & (SLEWRATE_MASK << SHIFT3NIBLE)) >> SHIFT3NIBLE;
+            break;
+        case MYKGPIO3:
+            slewSetting = (reg2 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE;
+            break;
+        case MYKGPIO2:
+            slewSetting = (reg2 & (SLEWRATE_MASK));
+            break;
+        case MYKGPIO1:
+            slewSetting = (reg3 & (SLEWRATE_MASK << SHIFT2NIBLE)) >> SHIFT2NIBLE;
+            break;
+        case MYKGPIO0:
+            slewSetting = (reg3 & (SLEWRATE_MASK));
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM,
+                    getGpioMykonosErrorMessage(MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM));
+            return MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM;
+    }
+
+    *slewRate = slewSetting;
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+
+/**
+ * \brief This function sets the CMOS output driver.
+ *
+ * This function sets the CMOS output driver to increase pad drive strength for the SPI_DIO and GP_INTERRUPT pads
+ * according to the following settings of the enumeration type mykonosCmosPadDrvStr_t
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param cmosDrv drive for the CMOS output driver
+ *
+ * \retval MYKONOS_ERR_CMOS_DRV_INV_PARAM invalid drive strength, valid settings are given by mykonosCmosPadDrvStr_t
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_setCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t cmosDrv)
+{
+    const uint8_t CMOS_DRV_MASK = 0x0F;
+    const uint8_t CMOS_DRV_SHIFT = 0x04;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setSpiDrv()\n");
+#endif
+
+    /* Error checking for correct drive */
+    switch (cmosDrv)
+    {   /* fall through since this is only checking */
+        case MYK_CMOSPAD_DRV_1X:
+        case MYK_CMOSPAD_DRV_2X:
+        case MYK_CMOSPAD_DRV_3X:
+        case MYK_CMOSPAD_DRV_4X:
+        case MYK_CMOSPAD_DRV_5X:
+            break;
+        default:
+            CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CMOS_DRV_INV_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_CMOS_DRV_INV_PARAM));
+            return MYKONOS_ERR_CMOS_DRV_INV_PARAM;
+            break;
+    }
+
+    CMB_SPIWriteField(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, cmosDrv, (~CMOS_DRV_MASK), CMOS_DRV_SHIFT);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+ * \brief This function gets the programmed CMOS output driver
+ *
+ *
+ * <B>Dependencies</B>
+ * - device->spiSettings->chipSelectIndex
+ *
+ * \param device is a pointer to the device settings structure
+ * \param cmosDrv will be the programmed drive for the CMOS output driver
+ *
+ * \retval MYKONOS_ERR_CMOS_DRV_NULL_PARAM Null parameter passed to the function
+ * \retval MYKONOS_ERR_GPIO_OK Function completed successfully
+ */
+mykonosGpioErr_t MYKONOS_getCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t *cmosDrv)
+{
+    uint8_t regRd = 0x00;
+
+    const uint8_t CMOS_DRV_MASK = 0xF0;
+    const uint8_t CMOS_DRV_SHIFT = 0x04;
+
+#if MYKONOS_VERBOSE == 1
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_GPIO_OK, "MYKONOS_setGpioSlewRate()\n");
+#endif
+
+    if (cmosDrv == NULL)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_CMOS_DRV_NULL_PARAM,
+                getGpioMykonosErrorMessage(MYKONOS_ERR_CMOS_DRV_NULL_PARAM));
+        return MYKONOS_ERR_CMOS_DRV_NULL_PARAM;
+    }
+
+    CMB_SPIReadByte(device->spiSettings, MYKONOS_GPIO_SLEW_CTL_3, &regRd);
+
+    *cmosDrv = ((regRd & CMOS_DRV_MASK) >> CMOS_DRV_SHIFT);
+
+    return MYKONOS_ERR_GPIO_OK;
+}
+
+/**
+* \brief This API function configures and enables the secondary SPI port.
+*
+* This port allows control compatibility with BBPs that employ dual SPI ports.
+* The GPIO mapping for the SPI2 is fixed:
+*  SPI signal  |   GPIO
+* -------------|-------------------
+*  CSB_2       |   GPIO 3
+*  SCLK_2      |   GPIO 2
+*  SDO_2       |   GPIO 1
+*  SDO_2/SDI2  |   GPIO 0
+*
+* The secondary SPI port only has a small subset of registers that affect the
+* attenuation of the TX channels. It uses a fifth GPIO pin in order to decide
+* which TxAttenuation word is active. The Tx Attenuation words in the 2nd SPI
+* port are different than the first SPI port.  On the 2nd SPI port, each
+* transmitter has two Tx Attenuation words (an active word and an inactive
+* word).  The BBIC should write to the inactive TxAttenuation word. Then the
+* fifth GPIO pin should be asserted to make the inactive TxAttenuation word
+* active.  This allows the BBIC to tightly control in real time when the
+* TxAttenuation updates.
+*
+* <B>Dependencies</B>
+* - device->spiSettings
+* - device->spiSettings->chipSelectIndex
+*
+* \param device is a pointer to the device settings structure
+* \param enable This is parameter will enable the secondary SPI port: 1 = enable, 0 = disable
+* \param updateTxAttenPinSelect This parameter set the GPIO pin to be toggle for using the inactive attenuation words for both channels
+*  tx update  |   GPIO
+* ------------|-------------------
+*     0x00    |   GPIO 4
+*     0x01    |   GPIO 8
+*     0x02    |   GPIO 14
+*     0x03    |   none selected
+*
+* \retval MYKONOS_ERR_SPI2_INV_GPIO if an invalid GPIO pin configuration is passed
+* \retval MYKONOS_ERR_HAL_LAYER if HAL function error is passed
+* \retval MYKONOS_ERR_OK Function completed successfully
+*/
+mykonosGpioErr_t MYKONOS_spi2GpioSetup(mykonosDevice_t *device, uint8_t enable, uint8_t updateTxAttenPinSelect)
+{
+    uint8_t regWrite = 0;
+    uint8_t enableBit = 0;
+    mykonosErr_t error = MYKONOS_ERR_OK;
+    uint32_t halError = COMMONERR_OK;
+
+    const uint32_t SPI2_PIN_MASK = 0x03;
+
+#ifdef MYKONOS_VERBOSE
+    CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_txGpioAttControl()\n");
+#endif
+
+    /* Error checking for correctness of GPIO to control attenuation word. */
+    if (updateTxAttenPinSelect & ~SPI2_PIN_MASK)
+    {
+        CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex,  MYKONOS_ERR_SPI2_INV_GPIO,
+                getMykonosErrorMessage(MYKONOS_ERR_SPI2_INV_GPIO));
+        return MYKONOS_ERR_SPI2_INV_GPIO;
+    }
+
+    /* masking the enable bit and the required pin */
+    enableBit = (enable > 0) ? 1 : 0;
+    regWrite = (updateTxAttenPinSelect << 4) | (enableBit << 3);
+
+    /* Set the SPI2 enable and the GPIO pin associated. */
+    halError = CMB_SPIWriteField(device->spiSettings, MYKONOS_ADDR_CONFIGURATION_CONTROL_1, regWrite, 0x38, 0);
+    if (halError)
+    {
+        return MYKONOS_ERR_HAL_LAYER;
+    }
+
+    return error;
+}
+
diff --git a/mpm/lib/mykonos/adi/mykonos_gpio.h b/mpm/lib/mykonos/adi/mykonos_gpio.h
new file mode 100644
index 000000000..c42c70bb8
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_gpio.h
@@ -0,0 +1,166 @@
+/*!
+ * \file mykonos_gpio.h
+ * \brief Contains macro definitions and function prototypes for mykonos_gpio.c
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef MYKONOSGPIO_H_
+#define MYKONOSGPIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "t_mykonos.h"
+#include "t_mykonos_gpio.h"
+
+/*
+ *****************************************************************************
+ * GPIO functions
+ *****************************************************************************
+ */
+
+/* GPIO CMOS and SPI setting Functions */
+mykonosGpioErr_t MYKONOS_setGpioDrv(mykonosDevice_t *device, mykonosGpioSelect_t gpioDrv);
+mykonosGpioErr_t MYKONOS_getGpioDrv(mykonosDevice_t *device, mykonosGpioSelect_t *gpioDrv);
+
+mykonosGpioErr_t MYKONOS_setGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t slewRate);
+mykonosGpioErr_t MYKONOS_getGpioSlewRate(mykonosDevice_t *device, mykonosGpioSelect_t gpioSelect, mykonosGpioSlewRate_t *slewRate);
+
+mykonosGpioErr_t MYKONOS_setCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t spiDrv);
+mykonosGpioErr_t MYKONOS_getCmosDrv(mykonosDevice_t *device, mykonosCmosPadDrvStr_t *spiDrv);
+
+
+/* Monitor output Functions */
+mykonosGpioErr_t MYKONOS_setGpioMonitorOut(mykonosDevice_t *device, uint8_t monitorIndex, uint8_t monitorMask);
+mykonosGpioErr_t MYKONOS_getGpioMonitorOut(mykonosDevice_t *device, uint8_t *monitorIndex, uint8_t *monitorMask);
+
+/* RX GPIO Functions */
+mykonosGpioErr_t MYKONOS_setRx1GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx1GainIncPin, mykonosGpioSelect_t rx1GainDecPin, uint8_t enable);
+mykonosGpioErr_t MYKONOS_setRx2GainCtrlPin(mykonosDevice_t *device, uint8_t incStep, uint8_t decStep, mykonosGpioSelect_t rx2GainIncPin, mykonosGpioSelect_t rx2GainDecPin, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getRx1GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx1GainIncPin, mykonosGpioSelect_t *rx1GainDecPin, uint8_t *enable);
+mykonosGpioErr_t MYKONOS_getRx2GainCtrlPin(mykonosDevice_t *device, uint8_t *incStep, uint8_t *decStep, mykonosGpioSelect_t *rx2GainIncPin, mykonosGpioSelect_t *rx2GainDecPin, uint8_t *enable);
+
+mykonosGpioErr_t MYKONOS_setRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t rx1GainChangePin, mykonosGpioSelect_t rx2GainChangePin);
+mykonosGpioErr_t MYKONOS_getRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1GainChangePin, mykonosGpioSelect_t *rx2GainChangePin);
+mykonosGpioErr_t MYKONOS_setObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxGainChangePin);
+mykonosGpioErr_t MYKONOS_getObsRxHybridGainChangePin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxGainChangePin);
+
+mykonosGpioErr_t MYKONOS_setRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t rx1AgcSyncPin, mykonosGpioSelect_t rx2AgcSyncPin);
+mykonosGpioErr_t MYKONOS_getRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *rx1AgcSyncPin, mykonosGpioSelect_t *rx2AgcSyncPin);
+mykonosGpioErr_t MYKONOS_setObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t obsRxAgcSyncPin);
+mykonosGpioErr_t MYKONOS_getObsRxAgcEnSyncPin(mykonosDevice_t *device, mykonosGpioSelect_t *obsRxAgcSyncPin);
+
+/* TX GPIO Functions */
+mykonosGpioErr_t MYKONOS_setTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx1AttenIncPin, mykonosGpioSelect_t tx1AttenDecPin, uint8_t enable, uint8_t useTx1ForTx2);
+mykonosGpioErr_t MYKONOS_setTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t stepSize, mykonosGpioSelect_t tx2AttenIncPin, mykonosGpioSelect_t tx2AttenDecPin, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getTx1AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx1AttenIncPin, mykonosGpioSelect_t *tx1AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2);
+mykonosGpioErr_t MYKONOS_getTx2AttenCtrlPin(mykonosDevice_t *device, uint8_t *stepSize, mykonosGpioSelect_t *tx2AttenIncPin, mykonosGpioSelect_t *tx2AttenDecPin, uint8_t *enable, uint8_t *useTx1ForTx2);
+
+mykonosGpioErr_t MYKONOS_spi2GpioSetup(mykonosDevice_t *device, uint8_t enable, uint8_t updateTxAttenPinSelect);
+
+/* GPIO memory source Functions */
+mykonosGpioErr_t MYKONOS_setGpioPinLevel(mykonosDevice_t *device, uint32_t gpioPinLevel);
+mykonosGpioErr_t MYKONOS_getGpioPinLevel(mykonosDevice_t *device, uint32_t *gpioPinLevel);
+mykonosGpioErr_t MYKONOS_getGpioSetLevel(mykonosDevice_t *device, uint32_t *gpioPinSetLevel);
+
+/* Gain Compensation Functions */
+mykonosGpioErr_t MYKONOS_setRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getRxGainCompensation (mykonosDevice_t *device, mykonosGainComp_t *gainComp, uint8_t *enabled);
+
+mykonosGpioErr_t MYKONOS_setObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getObsRxGainCompensation (mykonosDevice_t *device, mykonosObsRxGainComp_t *gainComp, uint8_t *enabled);
+
+/* SLICER Functions */
+mykonosGpioErr_t MYKONOS_setRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosRxSlicer_t rx1Pins, mykonosRxSlicer_t rx2Pins, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosRxSlicer_t *rx1Pins, mykonosRxSlicer_t *rx2Pins, uint8_t *enable);
+
+mykonosGpioErr_t MYKONOS_setObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t slicerStep, mykonosObsRxSlicer_t obsRxPins, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getObsRxSlicerCtrl(mykonosDevice_t *device, uint8_t *slicerStep, mykonosObsRxSlicer_t *obsRxPins, uint8_t *enable);
+
+/* Floating Point Formatter Functions */
+mykonosGpioErr_t MYKONOS_setFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt);
+mykonosGpioErr_t MYKONOS_getFloatPointFrmt (mykonosDevice_t *device, mykonosFloatPntFrmt_t *floatFrmt);
+
+mykonosGpioErr_t MYKONOS_setRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t rx1Att, uint8_t rx2Att, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getRxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *rx1Att, uint8_t *rx2Att, uint8_t *enable);
+
+mykonosGpioErr_t MYKONOS_setOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t orxAtt, uint8_t enable);
+mykonosGpioErr_t MYKONOS_getOrxEnFloatPntFrmt (mykonosDevice_t *device, uint8_t *orxAtt, uint8_t *enable);
+
+/*
+ *****************************************************************************
+ * General Purpose Interrupt functions
+ *****************************************************************************
+ */
+mykonosGpioErr_t MYKONOS_configGpInterrupt(mykonosDevice_t *device, uint16_t gpMask);
+mykonosGpioErr_t MYKONOS_readGpInterruptStatus(mykonosDevice_t *device, uint16_t *status);
+
+/*
+ *****************************************************************************
+ * ARM GPIO usage functions
+ *****************************************************************************
+ */
+mykonosGpioErr_t MYKONOS_setArmGpioPins(mykonosDevice_t *device);
+mykonosGpioErr_t MYKONOS_setRadioControlPinMode(mykonosDevice_t *device);
+
+/*
+ *****************************************************************************
+ * AuxADC/AuxDAC functions
+ *****************************************************************************
+ */
+mykonosGpioErr_t MYKONOS_setupAuxAdcs(mykonosDevice_t *device, uint8_t adcDecimation, uint8_t enable);
+mykonosGpioErr_t MYKONOS_setAuxAdcChannel(mykonosDevice_t *device, mykonosAuxAdcChannels_t auxAdcChannel);
+mykonosGpioErr_t MYKONOS_readAuxAdc(mykonosDevice_t *device, uint16_t *adcCode);
+mykonosGpioErr_t MYKONOS_setupAuxDacs(mykonosDevice_t *device);
+mykonosGpioErr_t MYKONOS_writeAuxDac(mykonosDevice_t *device, uint8_t auxDacIndex, uint16_t auxDacCode);
+
+/*
+ *****************************************************************************
+ * GPIO3v3 functions
+ *****************************************************************************
+ */
+mykonosGpioErr_t MYKONOS_setupGpio3v3(mykonosDevice_t *device);
+
+mykonosGpioErr_t MYKONOS_setGpio3v3PinLevel(mykonosDevice_t *device, uint16_t gpio3v3PinLevel);
+mykonosGpioErr_t MYKONOS_getGpio3v3SetLevel(mykonosDevice_t *device, uint16_t *gpio3v3SetLevel);
+
+mykonosGpioErr_t MYKONOS_getGpio3v3PinLevel(mykonosDevice_t *device, uint16_t *gpio3v3PinLevel);
+
+mykonosGpioErr_t MYKONOS_setGpio3v3Oe(mykonosDevice_t *device, uint16_t gpio3v3OutEn);
+mykonosGpioErr_t MYKONOS_getGpio3v3Oe(mykonosDevice_t *device, uint16_t *gpio3v3OutEn);
+
+mykonosGpioErr_t MYKONOS_setGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t gpio3v3SrcCtrl);
+mykonosGpioErr_t MYKONOS_getGpio3v3SourceCtrl(mykonosDevice_t *device, uint16_t *gpio3v3SrcCtrl);
+
+/*
+ *****************************************************************************
+ * GPIO helper functions
+ *****************************************************************************
+ */
+mykonosGpioErr_t MYKONOS_setupGpio(mykonosDevice_t *device);
+mykonosGpioErr_t MYKONOS_setGpioOe(mykonosDevice_t *device, uint32_t gpioOutEn, uint32_t gpioUsedMask);
+mykonosGpioErr_t MYKONOS_getGpioOe(mykonosDevice_t *device, uint32_t *gpioOutEn);
+
+mykonosGpioErr_t MYKONOS_setGpioSourceCtrl(mykonosDevice_t *device, uint32_t gpioSrcCtrl);
+mykonosGpioErr_t MYKONOS_getGpioSourceCtrl(mykonosDevice_t *device, uint32_t *gpioSrcCtrl);
+
+/*
+ *****************************************************************************
+ * Temperature Sensor functions
+ *****************************************************************************
+ */
+mykonosGpioErr_t MYKONOS_setupTempSensor(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor);
+mykonosGpioErr_t MYKONOS_getTempSensorConfig(mykonosDevice_t *device, mykonosTempSensorConfig_t *tempSensor);
+
+mykonosGpioErr_t MYKONOS_startTempMeasurement(mykonosDevice_t *device);
+mykonosGpioErr_t MYKONOS_readTempSensor(mykonosDevice_t *device, mykonosTempSensorStatus_t *tempStatus);
+
+const char* getGpioMykonosErrorMessage(mykonosGpioErr_t errorCode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MYKONOSGPIO_H_ */
diff --git a/mpm/lib/mykonos/adi/mykonos_macros.h b/mpm/lib/mykonos/adi/mykonos_macros.h
new file mode 100644
index 000000000..cc9abd700
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_macros.h
@@ -0,0 +1,692 @@
+/**
+ * \file mykonos_macros.h
+ * \brief Contains address and miscellaneous macro definitions for Mykonos API
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef CLEMENTE_TDD_MACROS_H
+#define CLEMENTE_TDD_MACROS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MYKONOS_ADDR_CONFIGURATION_CONTROL_0                0x000
+#define MYKONOS_ADDR_SPI_CONFIGURATION_CONTROL_1            0x001
+#define MYKONOS_ADDR_PRODUCT_ID                             0x004
+#define MYKONOS_GPIO_DRV_CTL_0                              0x020
+#define MYKONOS_GPIO_DRV_CTL_1                              0x021
+#define MYKONOS_GPIO_SLEW_CTL_0                             0x022
+#define MYKONOS_GPIO_SLEW_CTL_1                             0x023
+#define MYKONOS_GPIO_SLEW_CTL_2                             0x024
+#define MYKONOS_GPIO_SLEW_CTL_3                             0x025
+
+#define MYKONOS_ADDR_DIGITAL_IO_CONTROL                     0x028
+
+#define MYKONOS_ADDR_SYSREF_PAD_CONFIG                      0x040
+#define MYKONOS_ADDR_TX1_SYNC_PAD_CONFIG                    0x041
+#define MYKONOS_ADDR_TX2_SYNC_PAD_CONFIG                    0x042
+#define MYKONOS_ADDR_RX1_SYNC_CONFIG                        0x043
+#define MYKONOS_ADDR_RX2_SYNC_CONFIG                        0x044
+
+/* Mykonos Framer Registers */
+#define MYKONOS_ADDR_FRAMER_RESET                           0x059
+#define MYKONOS_ADDR_FRAMER_CLK_EN                          0x05A
+#define MYKONOS_ADDR_FRAMER_ADDR                            0x05B
+#define MYKONOS_ADDR_FRAMER_DATA                            0x05C
+#define MYKONOS_ADDR_FRAMER_WRITE_EN                        0x05D
+#define MYKONOS_ADDR_FRAMER_SYSREF_FIFO_EN                  0x05E
+#define MYKONOS_ADDR_FRAMER_CONFIG_F                        0x05F
+#define MYKONOS_ADDR_FRAMER_LANE_CTL                        0x060
+#define MYKONOS_ADDR_FRAMER_ADC_XBAR_SEL                    0x061
+#define MYKONOS_ADDR_FRAMER_LANE_XBAR_SEL                   0x062
+#define MYKONOS_ADDR_FRAMER_CONFIG_LOOPBACK_XBAR_REV        0x063
+#define MYKONOS_ADDR_FRAMER_SYNCN_FILT                      0x064
+#define MYKONOS_ADDR_FRAMER_LMFC_F_OFFSET                   0x065
+#define MYKONOS_ADDR_FRAMER_LMFC_K_OFFSET                   0x066
+#define MYKONOS_ADDR_FRAMER_TEST_CNTR_CTL                   0x067
+#define MYKONOS_ADDR_FRAMER_STATUS_STRB                     0x068
+#define MYKONOS_ADDR_FRAMER_STATUS                          0x069
+#define MYKONOS_ADDR_FRAMER_SYSREF_TO_LMFC_CNTR_STAT        0x06A
+#define MYKONOS_ADDR_FRAMER_SYSREF_TO_LMFC_ERR_MARGIN       0x06B
+#define MYKONOS_ADDR_FRAMER_LANE_FIFO_STRB                  0x06C
+#define MYKONOS_ADDR_FRAMER_LANE0_FIFO_RDWR_ADDR            0x06D
+#define MYKONOS_ADDR_FRAMER_LANE1_FIFO_RDWR_ADDR            0x06E
+#define MYKONOS_ADDR_FRAMER_LANE2_FIFO_RDWR_ADDR            0x06F
+#define MYKONOS_ADDR_FRAMER_LANE3_FIFO_RDWR_ADDR            0x070
+#define MYKONOS_ADDR_FRAMER_PRBS10_CTL                      0x071
+#define MYKONOS_ADDR_FRAMER_PRBS20_CTL                      0x072
+#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_EN                  0x073
+#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_7_TO_0              0x074
+#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_15_TO_8             0x075
+#define MYKONOS_ADDR_FRAMER_PATTERN_GEN_19_TO_16            0x076
+#define MYKONOS_ADDR_FRAMER_CONFIG_JTX_GEN                  0x077
+#define MYKONOS_ADDR_FRAMER_LANE_DATA_CTL                   0x078
+#define MYKONOS_ADDR_FRAMER_DATA_SAMPLE_CTL                 0x079
+
+/* Mykonos Deframer Sub Address Map */
+#define MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_RECVD           0x00
+#define MYKONOS_SUBADDR_DEFRAMER_LANE0_ILAS_CFG             0x50
+
+/* Mykonos Deframer Registers */
+#define MYKONOS_ADDR_DEFRAMER_RESET                         0x07A
+#define MYKONOS_ADDR_DEFRAMER_CLK_EN                        0x07B
+#define MYKONOS_ADDR_DEFRAMER_ADDR                          0x07C
+#define MYKONOS_ADDR_DEFRAMER_DATA                          0x07D
+#define MYKONOS_ADDR_DEFRAMER_WR_EN                         0x07E
+#define MYKONOS_ADDR_DEFRAMER_SYSREF_FIFO_EN                0x07F
+#define MYKONOS_ADDR_DEFRAMER_CONFIG_F                      0x080
+#define MYKONOS_ADDR_DEFRAMER_LANE_FIFO_CTL                 0x081
+#define MYKONOS_ADDR_DEFRAMER_DAC_XBAR_SEL                  0x082
+#define MYKONOS_ADDR_DEFRAMER_LANE_XBAR_SEL                 0x083
+#define MYKONOS_ADDR_DEFRAMER_LMFC_F_OFFSET                 0x084
+#define MYKONOS_ADDR_DEFRAMER_LMFC_K_OFFSET                 0x085
+#define MYKONOS_ADDR_DEFRAMER_CONFIG_SYNC_USER_DATA_CTL     0x086
+#define MYKONOS_ADDR_DEFRAMER_SYNC_REQ_RETIME               0x087
+#define MYKONOS_ADDR_DEFRAMER_TEST                          0x088
+#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_STRT_DAC_XBAR_REV 0x089
+#define MYKONOS_ADDR_DEFRAMER_STAT_STRB                     0x08A
+#define MYKONOS_ADDR_DEFRAMER_STAT                          0x08B
+#define MYKONOS_ADDR_DEFRAMER_TEST_ERR_CNT_STAT             0x08C
+#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_RD_ADDR              0x08D
+#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_WR_ADDR              0x08E
+#define MYKONOS_ADDR_DEFRAMER_QBLMFC_VS_EXTLMFC_CNTR_STAT   0x08F
+#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_STAT                 0x090
+#define MYKONOS_ADDR_DEFRAMER_STRT_RD_DEL_STOP_WR           0x091
+#define MYKONOS_ADDR_DEFRAMER_FIFO_SAMPLE_SPI_ADDR_RD       0x092
+#define MYKONOS_ADDR_DEFRAMER_FIFO_BYTE_SPI_ADDR_RD         0x093
+#define MYKONOS_ADDR_DEFRAMER_FIFO_BYTE_SPI_DATA_RD         0x094
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE0_7_TO_0                0x095
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE0_15_TO_8               0x096
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE1_7_TO_0                0x097
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE1_15_TO_8               0x098
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE2_7_TO_0                0x099
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE2_15_TO_8               0x09A
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE3_7_TO_0                0x09B
+#define MYKONOS_ADDR_DEFRAMER_SAMPLE3_15_TO_8               0x09C
+#define MYKONOS_ADDR_DEFRAMER_LANE_FIFO_STRB                0x09D
+#define MYKONOS_ADDR_DEFRAMER_LANE0_FIFO_RDWR_ADDR          0x09E
+#define MYKONOS_ADDR_DEFRAMER_LANE1_FIFO_RDWR_ADDR          0x09F
+#define MYKONOS_ADDR_DEFRAMER_LANE2_FIFO_RDWR_ADDR          0x0A0
+#define MYKONOS_ADDR_DEFRAMER_LANE3_FIFO_RDWR_ADDR          0x0A1
+#define MYKONOS_ADDR_DEFRAMER_SYSREF_TO_LMFC_CNTR_STAT      0x0A2
+#define MYKONOS_ADDR_DEFRAMER_SYSREF_TO_LMFC_ERR_MARGIN     0x0A3
+#define MYKONOS_ADDR_DEFRAMER_PRBS10_CTL                    0x0A4
+#define MYKONOS_ADDR_DEFRAMER_PRBS20_CTL                    0x0A5
+#define MYKONOS_ADDR_DEFRAMER_PRBS20_STRB_CHKSUM_TYPE       0x0A6
+#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_7_TO_0        0x0A7
+#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_15_TO_8       0x0A8
+#define MYKONOS_ADDR_DEFRAMER_PRBS20_ERR_CNTR_23_TO_16      0x0A9
+#define MYKONOS_ADDR_DEFRAMER_LANE_DATA_CTL                 0x0AA
+#define MYKONOS_ADDR_DEFRAMER_STATUS_2                      0x0AB
+#define MYKONOS_ADDR_DEFRAMER_DET_FIFO_PHASE                0x0AC
+
+/* Mykonos Serializer Registers */
+#define MYKONOS_ADDR_SERIALIZER_CTL_0                       0x0B0
+#define MYKONOS_ADDR_SERIALIZER_CTL_1                       0x0B1
+#define MYKONOS_ADDR_SERIALIZER_CTL_2                       0x0B2
+#define MYKONOS_ADDR_SERIALIZER_CTL_3                       0x0B3
+#define MYKONOS_ADDR_SERIALIZER_HS_DIV_TXSER_CLK_EN         0x0B4
+#define MYKONOS_ADDR_SERIALIZER_SPECIAL                     0x0B5
+
+/* Mykonos Deserializer Registers */
+#define MYKONOS_ADDR_DESERIALIZER_PDET_CTL                  0x0BC
+#define MYKONOS_ADDR_DESERIALIZER_CTL_0                     0x0BD
+#define MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_0               0x0BE
+#define MYKONOS_ADDR_DESERIALIZER_SIN_SHAPE_1               0x0BF
+#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_0                  0x0C1
+#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1                  0x0C2
+#define MYKONOS_ADDR_DESERIALIZER_MISC_CTL                  0x0C3
+#define MYKONOS_ADDR_DESERIALIZER_EQ_HP_EN                  0x0C4
+#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_1_TO_0             0x0C5
+#define MYKONOS_ADDR_DESERIALIZER_EQ_CTL_3_TO_2             0x0C6
+#define MYKONOS_ADDR_DESERIALIZER_HS_DIV_RXCDR_CLK_EN       0x0CD
+#define MYKONOS_ADDR_DESERIALIZER_SPECIAL                   0x0CE
+#define MYKONOS_ADDR_DESERIALIZER_CDR_CAL_CTL               0x0D0
+
+#define MYKONOS_ADDR_CONFIGURATION_CONTROL_1                0x100
+#define MYKONOS_ADDR_CONFIGURATION_CONTROL_2                0x101
+#define MYKONOS_ADDR_CONFIGURATION_CONTROL_4                0x102
+#define MYKONOS_ADDR_CONFIGURATION_CONTROL_5                0x103
+#define MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_1    0x104
+#define MYKONOS_ADDR_DPD_SNIFFER_CONFIGURATION_CONTROL_2    0x105
+#define MYKONOS_ADDR_DPD_SNIFFER_GPIO_SELECT                0x106
+#define MYKONOS_ADDR_SNIFFER_CONFIGURATION_CONTROL          0x107
+#define MYKONOS_ADDR_DPD_CONFIGURATION_CONTROL              0x108
+#define MYKONOS_ADDR_LOOPBACK_CONFIGURATION_CONTROL         0x109
+
+#define MYKONOS_ADDR_CLOCK_CONTROL_0						0x117
+#define MYKONOS_ADDR_CLOCK_CONTROL_1						0x118
+#define MYKONOS_ADDR_CLOCK_CONTROL_2						0x119
+#define MYKONOS_ADDR_CLOCK_CONTROL_3						0x11A
+#define MYKONOS_ADDR_CLOCK_CONTROL_4						0x11B
+#define MYKONOS_ADDR_CLOCK_CONTROL_5                        0x11C
+
+#define MYKONOS_ADDR_MCS_CONTROL                            0x120
+#define MYKONOS_ADDR_MCS_STATUS                             0x121
+
+/* CLK PLL Registers */
+#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE0            0x141
+#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_INT_BYTE1            0x142
+#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE0           0x143
+#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE1           0x144
+#define MYKONOS_ADDR_CLK_SYNTH_DIVIDER_FRAC_BYTE2           0x145
+#define MYKONOS_ADDR_CLK_SYNTH_F_VCOTN_BYTE1                0x148
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE1                        0x149
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE2                        0x14A
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE3                        0x14B
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE5                        0x14D
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE6                        0x14E
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE7                        0x14F
+#define MYKONOS_ADDR_CLK_SYNTH_LF_R3                        0x150
+#define MYKONOS_ADDR_CLK_SYNTH_BYTE9                        0x152
+#define MYKONOS_ADDR_CLK_SYNTH_CAL_STAT                     0x154
+#define MYKONOS_ADDR_CLK_SYNTH_VCO_CAL_REF                  0x155
+#define MYKONOS_ADDR_CLK_SYNTH_VCO_BAND_BYTE1               0x157
+#define MYKONOS_ADDR_CLK_SYNTH_CAL_CONTROL                  0x159
+#define MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL1                 0x15E
+#define MYKONOS_ADDR_CLK_SYNTH_VCO_VAR_CTL2                 0x15F
+
+/* DPD Registers */
+#define MYKONOS_ADDR_TX1_DPD_RMS_INDIRECT_PTR               0x168
+#define MYKONOS_ADDR_TX2_DPD_RMS_INDIRECT_PTR               0x16C
+#define MYKONOS_ADDR_TX1_DPD_MODEL_INDIRECT_PTR             0x178
+#define MYKONOS_ADDR_TX2_DPD_MODEL_INDIRECT_PTR             0x17C
+#define MYKONOS_ADDR_DPD_RMS_BUF_SIZE                       0x180
+#define MYKONOS_ADDR_DPD_MODEL_BUF_SIZE                     0x182
+
+/* Rx NCO Control registers */
+#define MYKONOS_ADDR_CALPLL_SDM_CONTROL                     0x17F
+#define MYKONOS_ADDR_RX_NCO_CONTROL                         0x190
+#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_3                  0x191
+#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_2                  0x192
+#define MYKONOS_ADDR_RX_NCO_CH1_FTW_BYTE_1                  0x193
+#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_3                  0x194
+#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_2                  0x195
+#define MYKONOS_ADDR_RX_NCO_CH2_FTW_BYTE_1                  0x196
+#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_3          0x197
+#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_2          0x198
+#define MYKONOS_ADDR_RX_NCO_DPD_SNIFFER_FTW_BYTE_1          0x199
+
+#define MYKONOS_ADDR_ENSM_CONFIG_7_0                        0x1B0
+#define MYKONOS_ADDR_CALIBRATION_CONTROL                    0x1B2
+#define MYKONOS_ADDR_ENSM_MANUAL_GAIN_LOCK_GPIO_SELECT      0x1B5
+#define MYKONOS_ADDR_REFERENCE_CLOCK_CYCLES                 0x1C0
+#define MYKONOS_ADDR_TX_PD_OVERIDE_7_0                      0x209
+#define MYKONOS_ADDR_RCAL_CONTROL                           0x224
+#define MYKONOS_ADDR_REF_PAD_CONFIG1                        0x230
+#define MYKONOS_ADDR_REF_PAD_CONFIG2                        0x231
+
+#define MYKONOS_ADDR_RXSYNTH_CP_CAL_STAT                    0x254
+#define MYKONOS_ADDR_RXSYNTH_VCO_BAND_BYTE1                 0x257
+#define MYKONOS_ADDR_TXSYNTH_CP_CAL_STAT                    0x2C4
+#define MYKONOS_ADDR_TXSYNTH_VCO_BAND_BYTE1                 0x2C7
+#define MYKONOS_ADDR_SNIFF_RXSYNTH_CP_CAL_STAT              0x354
+#define MYKONOS_ADDR_SNIFF_RXSYNTH_VCO_BAND_BYTE1           0x357
+#define MYKONOS_ADDR_SNIFF_RXLOGEN_BYTE1                    0x380
+
+#define MYKONOS_ADDR_RX_FILTER_CONFIGURATION                0x410
+#define MYKONOS_ADDR_RX_FILTER_GAIN                         0x411
+#define MYKONOS_ADDR_DPD_SNIFFER_RX_FILTER_GAIN             0x412
+
+/* Mykonos Temperature Gain Compensation Registers */
+#define MYKONOS_ADDR_RX1_TEMP_GAIN_COMP                     0x420
+#define MYKONOS_ADDR_RX2_TEMP_GAIN_COMP                     0x421
+#define MYKONOS_ADDR_OBS_TEMP_GAIN_COMP                     0x422
+
+/* Mykonos AGC General Registers */
+#define MYKONOS_ADDR_AGC_CFG_1                              0x42E
+#define MYKONOS_ADDR_AGC_CFG_2                              0x42F
+#define MYKONOS_ADDR_AGC_GAIN_CHANGE_GPIO_SEL               0x430
+#define MYKONOS_ADDR_AGC_RX1_MAX_GAIN_INDEX                 0x431
+#define MYKONOS_ADDR_AGC_RX1_MIN_GAIN_INDEX                 0x432
+#define MYKONOS_ADDR_AGC_MANUAL_GAIN_CFG                    0x433
+#define MYKONOS_ADDR_AGC_MANUAL_GAIN_GPIO_SEL               0x434
+#define MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_1             0x435
+#define MYKONOS_ADDR_AGC_MANUAL_GAIN_INDEX_CH_2             0x436
+#define MYKONOS_ADDR_AGC_LOCK_LEVEL                         0x437
+#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_1                   0x438
+#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_2                   0x439
+#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_3                   0x43A
+#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_4                   0x43B
+#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_5                   0x43C
+#define MYKONOS_ADDR_AGC_OVRG_GAIN_STEP_6                   0x43D
+#define MYKONOS_ADDR_AGC_RX1_GAIN_LOCK_DELAY                0x43E
+#define MYKONOS_ADDR_AGC_RX2_GAIN_LOCK_DELAY                0x43F
+#define MYKONOS_ADDR_AGC_RX1_ATTACK_DELAY                   0x440
+#define MYKONOS_ADDR_AGC_RX2_ATTACK_DELAY                   0x441
+#define MYKONOS_ADDR_AGC_ULB_THRSH                          0x442
+#define MYKONOS_ADDR_AGC_LLB_THRSH                          0x443
+#define MYKONOS_ADDR_AGC_RX_BLOCK_DET_DECAY                 0x444
+#define MYKONOS_ADDR_AGC_RESET_PD_HIGH_CNT                  0x445
+#define MYKONOS_ADDR_AGC_RX2_MAX_GAIN_INDEX                 0x446
+#define MYKONOS_ADDR_AGC_RX2_MIN_GAIN_INDEX                 0x447
+#define MYKONOS_ADDR_AGC_ORX_SNRX_CFG_1                     0x448
+#define MYKONOS_ADDR_AGC_ORX_SNRX_CFG_2                     0x449
+#define MYKONOS_ADDR_AGC_ORX_SNRX_MAX_GAIN_INDEX            0x44A
+#define MYKONOS_ADDR_AGC_ORX_SNRX_MIN_GAIN_INDEX            0x44B
+#define MYKONOS_ADDR_AGC_ORX_SNRX_MANUAL_GAIN_CFG           0x44C
+#define MYKONOS_ADDR_AGC_ORX_SNRX_GPIO_SEL                  0x44D
+#define MYKONOS_ADDR_AGC_ORX_SNRX_LOCK_LEVEL                0x44E
+#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_1          0x44F
+#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_2          0x450
+#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_3          0x451
+#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_4          0x452
+#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_5          0x453
+#define MYKONOS_ADDR_AGC_ORX_SNRX_OVRG_GAIN_STEP_6          0x454
+#define MYKONOS_ADDR_AGC_ORX_SNRX_GAIN_LOCK_DELAY           0x455
+#define MYKONOS_ADDR_AGC_ORX_SNRX_ATTACK_DELAY              0x456
+#define MYKONOS_ADDR_AGC_ORX_SNRX_ULB_THRSH                 0x457
+#define MYKONOS_ADDR_AGC_ORX_SNRX_LLB_THRSH                 0x458
+#define MYKONOS_ADDR_AGC_ORX_SNRX_BLOCK_DET_DECAY           0x459
+#define MYKONOS_ADDR_AGC_ORX_SNRX_RESET_PD_HIGH_CNT         0x45A
+#define MYKONOS_ADDR_AGC_ORX1_MANUAL_GAIN_INDEX             0x45B
+#define MYKONOS_ADDR_AGC_ORX2_MANUAL_GAIN_INDEX             0x45C
+#define MYKONOS_ADDR_AGC_SNRX_MANUAL_GAIN_INDEX             0x45D
+#define MYKONOS_ADDR_AGC_LOOPBACK1_MANUAL_GAIN_INDEX        0x45E
+#define MYKONOS_ADDR_AGC_LOOPBACK2_MANUAL_GAIN_INDEX        0x45F
+#define MYKONOS_ADDR_AGC_ORX_SNRX_ACTIVE                    0x460
+
+/* Mykonos Fast Attack AGC Registers */
+#define MYKONOS_ADDR_AGC_FAST_CFG_1                         0x468
+#define MYKONOS_ADDR_AGC_FAST_CFG_2                         0x469
+#define MYKONOS_ADDR_AGC_FAST_ENRGY_LOST_THRSH              0x46A
+#define MYKONOS_ADDR_AGC_FAST_STRONG_SIG_THRSH              0x46B
+#define MYKONOS_ADDR_AGC_FAST_SETTING_DELAY                 0x46C
+#define MYKONOS_ADDR_AGC_FAST_OPT_MAX_GAIN                  0x46D
+#define MYKONOS_ADDR_AGC_FAST_ENRGY_DET_CNT                 0x46E
+#define MYKONOS_ADDR_AGC_FAST_AGCLL_UPPER_LIMIT             0x46F
+#define MYKONOS_ADDR_AGC_FAST_GAIN_LOCK_EXIT_CNT            0x470
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_CFG_1                0x471
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_CFG_2                0x472
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_ENRGY_LOST_THRSH     0x473
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_STRONG_SIG_THRSH     0x474
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_SET_DELAY            0x475
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_OPT_MAX_GAIN         0x476
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_ENRGY_DET_CNT        0x477
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_AGCLL_UPPER_LIMIT    0x478
+#define MYKONOS_ADDR_AGC_FAST_ORX_SNRX_GAIN_LOCK_EXIT_CNT   0x479
+
+/* Mykonos Slow Loop - Hybrid AGC Registers */
+#define MYKONOS_ADDR_AGC_SLOW_LOCK_LEV_THRSH                    0x480
+#define MYKONOS_ADDR_AGC_SLOW_ULB_CNT_THRSH                     0x481
+#define MYKONOS_ADDR_AGC_SLOW_LLB_CNT_THRSH                     0x482
+#define MYKONOS_ADDR_AGC_SLOW_HIGH_OVRG_CNT_THRSH               0x483
+#define MYKONOS_ADDR_AGC_SLOW_LOW_OVRG_CNT_THRSH                0x484
+#define MYKONOS_ADDR_AGC_SLOW_VERYLOW_OVRG_CNT_THRSH            0x485
+#define MYKONOS_ADDR_AGC_SLOW_DIG_SAT_CNT_THRSH                 0x486
+#define MYKONOS_ADDR_AGC_SLOW_UPPER0_THRSH_GAIN_STEP            0x487
+#define MYKONOS_ADDR_AGC_SLOW_LOWER0_THRSH_GAIN_STEP            0x488
+#define MYKONOS_ADDR_AGC_SLOW_UPPER1_THRSH_GAIN_STEP            0x489
+#define MYKONOS_ADDR_AGC_SLOW_LOWER1_THRSH_GAIN_STEP            0x48A
+#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_1                 0x48B
+#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_2                 0x48C
+#define MYKONOS_ADDR_AGC_SLOW_GAIN_UPDATE_CNT_3                 0x48D
+#define MYKONOS_ADDR_AGC_SLOW_LOOP_CFG                          0x48E
+#define MYKONOS_ADDR_AGC_SLOW_POWER_THRSH                       0x48F
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOCK_LEV_THRSH           0x490
+
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ULB_CNT_THRSH                0x491
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LLB_CNT_THRSH                0x492
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_HIGH_OVRG_CNT_THRSH      0x493
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_LOW_OVRG_CNT_THRSH       0x494
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_ADC_VERYLOW_OVRG_CNT_THRSH   0x495
+
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_DIG_SAT_CNT_THRSH        0x496
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER0_THRSH_GAIN_STEP   0x497
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER0_THRSH_GAIN_STEP   0x498
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UPPER1_THRSH_GAIN_STEP   0x499
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOWER1_THRSH_GAIN_STEP   0x49A
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_1        0x49B
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_2        0x49C
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_GAIN_UPDATE_CTR_3        0x49D
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_LOOP_CFG                 0x49E
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_POWER_THRSH              0x49F
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DEL_1    0x4A0
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DEL_2    0x4A1
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DUR_1    0x4A2
+#define MYKONOS_ADDR_AGC_SLOW_ORX_SNRX_UL_SIG_POW_MEAS_DUR_2    0x4A3
+
+/* Mykonos Gain Control Read Registers */
+#define MYKONOS_ADDR_GAIN_CTL_CHANNEL_1                         0x4B0
+#define MYKONOS_ADDR_GAIN_CTL_FAST_ATTK_STATE                   0x4B1
+#define MYKONOS_ADDR_GAIN_CTL_SLOW_LOOP_STATE                   0x4B2
+#define MYKONOS_ADDR_GAIN_CTL_CHANNEL_2                         0x4B3
+#define MYKONOS_ADDR_GAIN_CTL_OVRG_SIGS_CHANNEL_1               0x4B4
+#define MYKONOS_ADDR_GAIN_CTL_OVRG_SIGS_CHANNEL_2               0x4B5
+#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_GAIN                     0x4B6
+#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_LOOP_STATE               0x4B7
+#define MYKONOS_ADDR_GAIN_CTL_ORX_SNRX_OVRG_SIGS                0x4B8
+
+/* Mykonos Rx Data Path Overrange Registers */
+#define MYKONOS_ADDR_RX_OVRG_DATAPATH_OVRFLW                    0x4B9
+#define MYKONOS_ADDR_RX_OVRG_ORX_SNRX_DATAPATH_OVRFLW           0x4BA
+
+/* Mykonos RSSI Measurement Registers and Dec Power Measurement Registers*/
+#define MYKONOS_ADDR_RSSI_MEAS_DURATION_0_1                     0x4C0
+#define MYKONOS_ADDR_RSSI_MEAS_DURATION_2_3                     0x4C1
+#define MYKONOS_ADDR_RSSI_CFG                                   0x4C6
+#define MYKONOS_DEC_POWER_CONFIG_1                              0x4C7
+#define MYKONOS_DEC_POWER_CONFIG_2								0x4C8
+#define MYKONOS_ADDR_DPD_SNF_RSSI_CFG                           0x4CF
+#define MYKONOS_ADDR_DPD_RSSI_CFG                               0x4D6
+#define MYKONOS_SNIFFER_DEC_POWER_CONFIG_1						0x4D7
+#define MYKONOS_SNIFFER_DEC_POWER_CONFIG_2						0x4D8
+#define MYKONOS_CH1_DECIMATED_PWR								0x4DE
+#define MYKONOS_CH2_DECIMATED_PWR								0x4DF
+#define MYKONOS_SNIFFER_DECIMATED_PWR							0x4E6
+
+#define MYKONOS_ADDR_DIGITAL_GAIN_CONFIG                    0x4F0
+#define MYKONOS_ADDR_DPD_SNIFFER_DIGITAL_GAIN_CONFIG        0x4F1
+#define MYKONOS_ADDR_GAIN_TABLE_ADDR						0x500
+#define MYKONOS_ADDR_GAIN_TABLE_RX1_FE_GAIN					0x501
+#define MYKONOS_ADDR_GAIN_TABLE_RX1_EXT_CTL					0x502
+#define MYKONOS_ADDR_GAIN_TABLE_RX1_DIG_GAIN				0x503
+#define MYKONOS_ADDR_GAIN_TABLE_RX2_FE_GAIN					0x504
+#define MYKONOS_ADDR_GAIN_TABLE_RX2_EXT_CTL					0x505
+#define MYKONOS_ADDR_GAIN_TABLE_RX2_DIG_GAIN				0x506
+#define MYKONOS_ADDR_GAIN_TABLE_RX3_FE_GAIN					0x507
+#define MYKONOS_ADDR_GAIN_TABLE_RX3_LNA_ENAB				0x508
+#define MYKONOS_ADDR_GAIN_TABLE_RX3_DIG_GAIN				0x509
+#define MYKONOS_ADDR_GAIN_TABLE_CONFIGURATION               0x516
+#define MYKONOS_ADDR_CH3_GAIN_TABLE_CONFIGURATION           0x517
+#define MYKONOS_ADDR_RXFE1_LOCM                             0x520
+#define MYKONOS_ADDR_RXFE2_LOCM                             0x521
+#define MYKONOS_ADDR_RXLOOPBACK1_CNTRL_1                    0x540
+#define MYKONOS_ADDR_RXLOOPBACK2_CNTRL_1                    0x541
+#define MYKONOS_ADDR_RX_LOOPBACK1_CNTRL_4                   0x546
+#define MYKONOS_ADDR_RX_LOOPBACK2_CNTRL_4                   0x547
+
+/* Mykonos Overload/Peak Detection Registers */
+#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_CFG                    0x580
+#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_UPPER_THRSH            0x581
+#define MYKONOS_ADDR_OVRLD_ADC_OVRLD_LOWER_THRSH            0x582
+
+#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_CFG                 0x583
+#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_UPPER_THRSH         0x584
+#define MYKONOS_ADDR_OVRLD_PD_DEC_OVRLD_LOWER_THRSH         0x585
+#define MYKONOS_ADDR_OVRLD_PD_DEC_VERYLOW_THRSH             0x586
+#define MYKONOS_ADDR_ORX_SNRX_OVRLD_ADC_OVRLD_CFG           0x587
+#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_CFG        0x58A
+#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_UPPER_THRSH    0x58B
+#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_LOWER_THRSH    0x58C
+#define MYKONOS_ADDR_ORX_SNRX_OVRLD_PD_DEC_OVRLD_VERYLOW_THRSH  0x58D
+
+#define MYKONOS_ADDR_RX_ADC_FLASH_DELAY                     0x5B6
+#define MYKONOS_ADDR_RX_ADC_FLASH_CTRL                      0x5B7
+#define MYKONOS_ADDR_RX_ADC1_PRFL                           0x5DD
+#define MYKONOS_ADDR_RX_ADC2_PRFL                           0x5DE
+#define MYKONOS_ADDR_ORX_ADC_PRFL                           0x5DF
+
+#define MYKONOS_ADDR_RFDC_MEASURE_COUNT_1                   0x631
+#define MYKONOS_ADDR_RFDC_MEASURE_COUNT_2                   0x632
+#define MYKONOS_ADDR_RFDC_PROGRAM_SHIFT                     0x635
+#define MYKONOS_ADDR_RFDC_CONFIG2                           0x636
+#define MYKONOS_ADDR_DIGITAL_DC_MIN_CAL_IDX                 0x63A
+#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_SHIFT                0x674
+#define MYKONOS_ADDR_DIGITAL_DC_OFFSET_CH3_DPD_M_SHIFT      0x67D
+
+#define MYKONOS_ADDR_RX_GAIN_COMP_DELAY                     0x710
+#define MYKONOS_ADDR_RX1_GAIN_COMP_OFFSET                   0x711
+#define MYKONOS_ADDR_RX2_GAIN_COMP_OFFSET                   0x712
+#define MYKONOS_ADDR_RX_GAIN_COMP_CFG                       0x713
+#define MYKONOS_ADDR_RX_SLCR_PIN_CFG                        0x714
+#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_DELAY             0x715
+#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_OFFSET            0x716
+#define MYKONOS_ADDR_DPD_SNF_RX_GAIN_COMP_CFG               0x717
+#define MYKONOS_ADDR_DPD_SNF_RX_SLCR_PIN_CFG                0x718
+
+#define MYKONOS_ADDR_FLOATING_POINT_CFG                     0x750
+#define MYKONOS_ADDR_FLOATING_POINT_RX_CTRL                 0x751
+#define MYKONOS_ADDR_FLOATING_POINT_ORX_CTRL                0x752
+
+
+#define MYKONOS_ADDR_SNRX_LNA_BIAS_C                        0x81B
+
+
+#define MYKONOS_ADDR_ORX_ADC_FLASH_DELAY                     0x846
+#define MYKONOS_ADDR_ORX_ADC_FLASH_CTRL                      0x847
+
+#define MYKONOS_ADDR_TX_FILTER_CONFIGURATION                0x910
+#define MYKONOS_ADDR_TX1_ATTENUATION_0_READBACK             0x940
+#define MYKONOS_ADDR_TX1_ATTENUATION_1_READBACK             0x941
+#define MYKONOS_ADDR_TX2_ATTENUATION_0_READBACK             0x942
+#define MYKONOS_ADDR_TX2_ATTENUATION_1_READBACK             0x943
+#define MYKONOS_ADDR_TX_FILTER_OVERFLOW 					0x950
+
+/* Mykonos PA Protection Block Registers */
+#define MYKONOS_ADDR_PA_PROTECTION_CONFIGURATION            0x955
+#define MYKONOS_ADDR_PA_PROTECTION_ATTEN_CONTROL            0x956
+#define MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_LSB            0x957
+#define MYKONOS_ADDR_PA_PROTECTION_THRESHOLD_MSB            0x958
+#define MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_LSB       0x959
+#define MYKONOS_ADDR_PA_PROTECTION_POWER_READBACK_MSB       0x95A
+#define MYKONOS_ADDR_TX1_ATTENUATION_0                      0x960
+#define MYKONOS_ADDR_TX1_ATTENUATION_1                      0x961
+#define MYKONOS_ADDR_TX2_ATTENUATION_0                      0x962
+#define MYKONOS_ADDR_TX2_ATTENUATION_1                      0x963
+#define MYKONOS_ADDR_TX1_GAIN_0                             0x967
+#define MYKONOS_ADDR_TX1_GAIN_1                             0x968
+#define MYKONOS_ADDR_TX1_GAIN_2                             0x969
+#define MYKONOS_ADDR_TX2_GAIN_0                             0x96A
+#define MYKONOS_ADDR_TX2_GAIN_1                             0x96B
+#define MYKONOS_ADDR_TX2_GAIN_2                             0x96C
+#define MYKONOS_ADDR_TX_INCR_DECR_WORD                      0x96D
+#define MYKONOS_ADDR_TX_TPC_CONFIG                          0x96E
+#define MYKONOS_ADDR_TX_TPC_GPIO_CFG                        0x96F
+
+#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_MSB             0x9CB
+#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_I_LSB             0x9CC
+#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_MSB             0x9CD
+#define MYKONOS_ADDR_TX_ABBF_FREQ_CAL_NCO_Q_LSB             0x9CE
+
+/* Mykonos GPIO Registers */
+#define MYKONOS_ADDR_GPIO_3V3_DIR_CTL_7_0					0xB00
+#define MYKONOS_ADDR_GPIO_3V3_DIR_CTL_15_8					0xB01
+#define MYKONOS_ADDR_GPIO_3V3_SPI_SRC_7_0					0xB02
+#define MYKONOS_ADDR_GPIO_3V3_SPI_SRC_15_8					0xB03
+#define MYKONOS_ADDR_GPIO_3V3_SPI_READ_7_0					0xB04
+#define MYKONOS_ADDR_GPIO_3V3_SPI_READ_15_8					0xB05
+#define MYKONOS_ADDR_GPIO_3V3_LSB_SRC_CTL					0xB06
+#define MYKONOS_ADDR_GPIO_3V3_MSB_SRC_CTL					0xB07
+
+#define MYKONOS_ADDR_GPIO_DIR_CTL_7_0					    0xB20
+#define MYKONOS_ADDR_GPIO_DIR_CTL_15_8					    0xB21
+#define MYKONOS_ADDR_GPIO_DIR_CTL_18_16					    0xB22
+#define MYKONOS_ADDR_GPIO_SPI_SRC_7_0					    0xB23
+#define MYKONOS_ADDR_GPIO_SPI_SRC_15_8					    0xB24
+#define MYKONOS_ADDR_GPIO_SPI_SRC_18_16					    0xB25
+#define MYKONOS_ADDR_GPIO_SPI_READ_7_0					    0xB26
+#define MYKONOS_ADDR_GPIO_SPI_READ_15_8					    0xB27
+#define MYKONOS_ADDR_GPIO_SPI_READ_18_16				    0xB28
+#define MYKONOS_ADDR_SOURCE_CONTROL_LOWER_BYTE              0xB29
+#define MYKONOS_ADDR_SOURCE_CONTROL_UPPER_BYTE              0xB2A
+#define MYKONOS_ADDR_SOURCE_CONTROL_EXTRA_BITS              0xB2B
+
+#define MYKONOS_ADDR_GPIO_MONITOR_INDEX                     0xB40
+#define MYKONOS_ADDR_GPIO_MONITOR_ENABLE                    0xB41
+
+#define MYKONOS_ADDR_GP_INTERRUPT_MASK_1                    0xB42
+#define MYKONOS_ADDR_GP_INTERRUPT_MASK_0                    0xB43
+#define MYKONOS_ADDR_GP_INTERRUPT_READ_1                    0xB44
+#define MYKONOS_ADDR_GP_INTERRUPT_READ_0                    0xB45
+
+#define MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_5_0            0xB73
+#define MYKONOS_ADDR_PDAUXDAC_MANUAL_CONTROL_9_6            0xB74
+#define MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_5_0                 0xB75
+#define MYKONOS_ADDR_PDAUXDAC_MANUAL_IN_9_6                 0xB76
+#define MYKONOS_ADDR_AUX_DAC_LATCH_CONTROL                  0xB9F
+#define MYKONOS_ADDR_AUXDAC_0_WORD_MSB                      0xBA0
+
+#define MYKONOS_ADR_AUX_ADC_CLOCK_DIVIDE                    0xBC0
+#define MYKONOS_ADDR_AUX_ADC_CFG                            0xBC1
+#define MYKONOS_ADDR_AUX_ADC_READ_MSB                       0xBC2
+#define MYKONOS_ADDR_AUX_ADC_READ_LSB                       0xBC3
+#define MYKONOS_ADDR_AUX_ADC_SEL                            0xBC4
+#define MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_0                0xBC5
+#define MYKONOS_ADDR_AUX_ADC_BUFFER_CONFIG_1                0xBC6
+
+#define MYKONOS_ADDR_TEMP_SENSOR_OFFSET                     0xBE0
+#define MYKONOS_ADDR_TEMP_SENSOR_CONTROL_LSB                0xBE1
+#define MYKONOS_ADDR_TEMP_SENSOR_CONTROL_MSB                0xBE2
+#define MYKONOS_ADDR_TEMP_SENSOR_READ                       0xBE3
+#define MYKONOS_ADDR_TEMP_SENSOR_CONFIG                     0xBE4
+
+#define MYKONOS_ADDR_DIGITAL_TEST_BYTE_0                    0xC40
+
+/* ARM subsystem registers */
+#define MYKONOS_ADDR_ARM_CTL_1								0xD00
+#define MYKONOS_ADDR_ARM_CTL_2								0xD01
+#define MYKONOS_ADDR_ARM_ADDR_BYTE_0						0xD02
+#define MYKONOS_ADDR_ARM_ADDR_BYTE_1						0xD03
+#define MYKONOS_ADDR_ARM_DATA_BYTE_0						0xD04
+#define MYKONOS_ADDR_ARM_DATA_BYTE_1						0xD05
+#define MYKONOS_ADDR_ARM_DATA_BYTE_2						0xD06
+#define MYKONOS_ADDR_ARM_DATA_BYTE_3						0xD07
+#define MYKONOS_ADDR_ARM_CLK_CTL							0xD08
+#define MYKONOS_ADDR_AHB_SPI_BRIDGE							0xD09
+#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_0					0xD0A
+#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_1					0xD0B
+#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_2					0xD0C
+#define MYKONOS_ADDR_ARM_BOOT_ADDR_BYTE_3					0xD0D
+#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_0					0xD0E
+#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_1					0xD0F
+#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_2					0xD10
+#define MYKONOS_ADDR_ARM_STACK_PTR_BYTE_3					0xD11
+#define MYKONOS_ADDR_ARM_BRIDGE_CLK_CTL						0xD14
+
+/* ARM mailbox registers */
+#define MYKONOS_ADDR_ARM_CMD								0xD30
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_1						0xD31
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_2						0xD32
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_3						0xD33
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_4						0xD34
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_5						0xD35
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_6						0xD36
+#define MYKONOS_ADDR_ARM_EXT_CMD_BYTE_7						0xD37
+#define MYKONOS_ADDR_ARM_CMD_STATUS_0						0xD38
+#define MYKONOS_ADDR_ARM_CMD_STATUS_1						0xD39
+#define MYKONOS_ADDR_ARM_CMD_STATUS_2						0xD3A
+#define MYKONOS_ADDR_ARM_CMD_STATUS_3						0xD3B
+#define MYKONOS_ADDR_ARM_CMD_STATUS_4						0xD3C
+#define MYKONOS_ADDR_ARM_CMD_STATUS_5						0xD3D
+#define MYKONOS_ADDR_ARM_CMD_STATUS_6						0xD3E
+#define MYKONOS_ADDR_ARM_CMD_STATUS_7						0xD3F
+
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_0						0xD40
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_1						0xD41
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_2						0xD42
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_3						0xD43
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_4						0xD44
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_5						0xD45
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_6						0xD46
+#define MYKONOS_ADDR_ARM_OPCODE_STATE_7						0xD47
+
+/* Mykonos Power-Down Override Control Registers */
+#define MYKONOS_ADDR_TX_PD_OVERRIDE_CONTROL_7_0             0xD89
+
+/* Mykonos Observation Framer Registers */
+#define MYKONOS_ADDR_OBS_FRAMER_RESET						0xDC0
+#define MYKONOS_ADDR_OBS_FRAMER_CLK_EN						0xDC1
+#define MYKONOS_ADDR_OBS_FRAMER_ADDR						0xDC2
+#define MYKONOS_ADDR_OBS_FRAMER_DATA						0xDC3
+#define MYKONOS_ADDR_OBS_FRAMER_WRITE_EN					0xDC4
+#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_FIFO_EN				0xDC5
+#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_F					0xDC6
+#define MYKONOS_ADDR_OBS_FRAMER_LANE_CTL					0xDC7
+#define MYKONOS_ADDR_OBS_FRAMER_ADC_XBAR_SEL				0xDC8
+#define MYKONOS_ADDR_OBS_FRAMER_LANE_XBAR_SEL				0xDC9
+#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_LOOPBACK_XBAR_REV	0xDCA
+#define MYKONOS_ADDR_OBS_FRAMER_SYNCN_FILT					0xDCB
+#define MYKONOS_ADDR_OBS_FRAMER_LMFC_F_OFFSET				0xDCC
+#define MYKONOS_ADDR_OBS_FRAMER_LMFC_K_OFFSET				0xDCD
+#define MYKONOS_ADDR_OBS_FRAMER_TEST_CNTR_CTL				0xDCE
+#define MYKONOS_ADDR_OBS_FRAMER_STATUS_STRB					0xDCF
+#define MYKONOS_ADDR_OBS_FRAMER_STATUS						0xDD0
+#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_TO_LMFC_CNTR_STAT	0xDD1
+#define MYKONOS_ADDR_OBS_FRAMER_SYSREF_TO_LMFC_ERR_MARGIN	0xDD2
+#define MYKONOS_ADDR_OBS_FRAMER_LANE_FIFO_STRB				0xDD3
+#define MYKONOS_ADDR_OBS_FRAMER_LANE0_FIFO_RDWR_ADDR		0xDD4
+#define MYKONOS_ADDR_OBS_FRAMER_LANE1_FIFO_RDWR_ADDR		0xDD5
+#define MYKONOS_ADDR_OBS_FRAMER_LANE2_FIFO_RDWR_ADDR		0xDD6
+#define MYKONOS_ADDR_OBS_FRAMER_LANE3_FIFO_RDWR_ADDR		0xDD7
+#define MYKONOS_ADDR_OBS_FRAMER_PRBS10_CTL					0xDD8
+#define MYKONOS_ADDR_OBS_FRAMER_PRBS20_CTL					0xDD9
+#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_EN				0xDDA
+#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_7_TO_0			0xDDB
+#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_15_TO_8			0xDDC
+#define MYKONOS_ADDR_OBS_FRAMER_PATTERN_GEN_19_TO_16		0xDDD
+#define MYKONOS_ADDR_OBS_FRAMER_CONFIG_JTX_GEN				0xDDE
+#define MYKONOS_ADDR_OBS_FRAMER_LANE_DATA_CTL				0xDDF
+#define MYKONOS_ADDR_OBS_FRAMER_DATA_SAMPLE_CTL				0xDE0
+
+#define MYKONOS_ADDR_PFIR_COEFF_CTL                         0xDFF
+#define MYKONOS_ADDR_PFIR_COEFF_DATA                        0xE00
+#define MYKONOS_ADDR_PFIR_COEFF_ADDR                        0xE01
+
+/* ARM memory */
+#define MYKONOS_ADDR_ARM_START_PROG_ADDR					0x01000000
+#define MYKONOS_ADDR_ARM_END_PROG_ADDR						0x01017FFF
+#define MYKONOS_ADDR_ARM_START_DATA_ADDR					0x20000000
+#define MYKONOS_ADDR_ARM_END_DATA_ADDR						0x2000FFFF
+#define MYKONOS_ADDR_ARM_BUILD_CHKSUM_ADDR					0x01017FE0
+#define MYKONOS_ADDR_ARM_CALC_CHKSUM_ADDR					0x01017FE4
+#define MYKONOS_ADDR_ARM_VERSION                            0x01000128
+#define MYKONOS_ARM_ABORT_OPCODE                            0x00
+#define MYKONOS_ARM_RUNINIT_OPCODE                          0x02
+#define MYKONOS_ARM_RADIOON_OPCODE                          0x04
+#define MYKONOS_ARM_WRITECFG_OPCODE                         0x06
+#define MYKONOS_ARM_READCFG_OPCODE                          0x08
+#define MYKONOS_ARM_SET_OPCODE                              0x0A
+#define MYKONOS_ARM_GET_OPCODE                              0x0C
+
+#define MYKONOS_ARM_OBJECTID_DPDINIT_CONFIG                 0x0F
+#define MYKONOS_ARM_OBJECTID_CLGCINIT_CONFIG                0x10
+#define MYKONOS_ARM_OBJECTID_VSWRINIT_CONFIG                0x11
+#define MYKONOS_ARM_OBJECTID_DPDCONFIG                      0x24
+#define MYKONOS_ARM_DPD_INIT_MODEL                          0x02
+#define MYKONOS_ARM_OBJECTID_GS_TRACKCALS                   0x66
+#define MYKONOS_ARM_OBJECTID_RXQEC_TRACKING                 0x20
+#define MYKONOS_ARM_OBJECTID_ORXQEC_TRACKING                0x21
+#define MYKONOS_ARM_OBJECTID_TXLOL_TRACKING                 0x22
+#define MYKONOS_ARM_OBJECTID_TXQEC_TRACKING                 0x23
+#define MYKONOS_ARM_OBJECTID_CLGCCONFIG                     0x25
+#define MYKONOS_ARM_OBJECTID_VSWRCONFIG                     0x26
+#define MYKONOS_ARM_OBJECTID_CAL_STATUS                     0x42
+#define MYKONOS_ARM_OBJECTID_INIT_CAL_DONE                  0x43
+#define MYKONOS_ARM_OBJECTID_ORX_MODE                       0x61
+#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_SUSPEND_RESUME    0x65
+#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_CONTROL           0x66
+#define MYKONOS_ARM_OBJECTID_TRACKING_CAL_PENDING           0x67
+#define MYKONOS_ARM_OBJECTID_RADIO_CONTROL                  0x81
+#define MYKONOS_ARM_OBJECTID_CALSCHEDULER                   0x83
+
+#define MYKONOS_ARM_SYSTEMSTATE_POWERUP                     0x00
+#define MYKONOS_ARM_SYSTEMSTATE_READY                       0x01
+#define MYKONOS_ARM_SYSTEMSTATE_IDLE                        0x02
+#define MYKONOS_ARM_SYSTEMSTATE_RADIO_ON                    0x03
+
+#define ORX_TRIGGER_SIGNALID      0x00
+#define ORX_MODE_0_SIGNALID       0x01
+#define ORX_MODE_1_SIGNALID       0x02
+#define ORX_MODE_2_SIGNALID       0x03
+#define RX1_ENABLE_ACK_SIGNALID   0x04
+#define RX2_ENABLE_ACK_SIGNALID   0x05
+#define TX1_ENABLE_ACK_SIGNALID   0x06
+#define TX2_ENABLE_ACK_SIGNALID   0x07
+#define ORX1_ENABLE_ACK_SIGNALID  0x08
+#define ORX2_ENABLE_ACK_SIGNALID  0x09
+#define SRX_ENABLE_ACK_SIGNALID   0x0A
+#define TX_OBS_SELECT_SIGNALID    0x0B
+
+#define DISABLE_DPD_ACTUATOR      0x03
+#define ENABLE_DPD_ACTUATOR       0x04
+#define SET_CLGC_DESIRED_GAIN_1   0x05
+#define SET_CLGC_DESIRED_GAIN_2   0x06
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mpm/lib/mykonos/adi/mykonos_user.c b/mpm/lib/mykonos/adi/mykonos_user.c
new file mode 100644
index 000000000..cfcc1ee64
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_user.c
@@ -0,0 +1,170 @@
+/**
+ * \file mykonos_user.c
+ * \brief Contains Mykonos default gain table values for Rx, ObsRx, and SnRx
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#include <stdint.h>
+#include "t_mykonos.h"
+#include "mykonos_user.h"
+
+/**
+ * \brief Default Rx gain table settings
+ */
+
+uint8_t RxGainTable [61][4] =
+{
+	/* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */
+        {0, 0, 0, 0},  /* Gain index 255 */
+        {3, 0, 2, 1},  /* Gain index 254 */
+        {6, 0, 3, 1},  /* Gain index 253 */
+        {10, 0, 0, 0}, /* Gain index 252 */
+        {13, 0, 1, 1}, /* Gain index 251 */
+        {16, 0, 0, 0}, /* Gain index 250 */
+        {18, 0, 3, 1}, /* Gain index 249 */
+        {21, 0, 1, 1}, /* Gain index 248 */
+        {23, 0, 3, 1}, /* Gain index 247 */
+        {25, 0, 4, 1}, /* Gain index 246 */
+        {28, 0, 0, 0}, /* Gain index 245 */
+        {30, 0, 0, 0}, /* Gain index 244 */
+        {31, 0, 5, 1}, /* Gain index 243 */
+        {33, 0, 4, 1}, /* Gain index 242 */
+        {35, 0, 2, 1}, /* Gain index 241 */
+        {37, 0, 0, 0}, /* Gain index 240 */
+        {38, 0, 4, 1}, /* Gain index 239 */
+        {39, 0, 7, 1}, /* Gain index 238 */
+        {41, 0, 2, 1}, /* Gain index 237 */
+        {42, 0, 4, 1}, /* Gain index 236 */
+        {43, 0, 6, 1}, /* Gain index 235 */
+        {44, 0, 8, 1}, /* Gain index 234 */
+        {45, 0, 9, 1},  /* Gain index 233 */
+        {46, 0, 10, 1}, /* Gain index 232 */
+        {47, 0, 10, 1}, /* Gain index 231 */
+        {48, 0, 9, 1}, /* Gain index 230 */
+        {49, 0, 8, 1}, /* Gain index 229 */
+        {50, 0, 6, 1}, /* Gain index 228 */
+        {51, 0, 3, 1}, /* Gain index 227 */
+        {51, 0, 13, 1}, /* Gain index 226 */
+        {52, 0, 9, 1}, /* Gain index 225 */
+        {53, 0, 5, 1}, /* Gain index 224 */
+        {53, 0, 15, 1}, /* Gain index 223 */
+        {54, 0, 9, 1}, /* Gain index 222 */
+        {54, 0, 19, 1}, /* Gain index 221 */
+        {55, 0, 11, 1}, /* Gain index 220 */
+        {55, 0, 21, 1}, /* Gain index 219 */
+        {56, 0, 11, 1}, /* Gain index 218 */
+        {56, 0, 21, 1}, /* Gain index 217 */
+        {57, 0, 9, 1}, /* Gain index 216 */
+        {57, 0, 19, 1}, /* Gain index 215 */
+        {57, 0, 29, 1}, /* Gain index 214 */
+        {58, 0, 12, 1}, /* Gain index 213 */
+        {58, 0, 22, 1}, /* Gain index 212 */
+        {58, 0, 32, 1}, /* Gain index 211 */
+        {59, 0, 11, 1}, /* Gain index 210 */
+        {59, 0, 21, 1}, /* Gain index 209 */
+        {59, 0, 31, 1}, /* Gain index 208 */
+        {59, 0, 41, 1}, /* Gain index 207 */
+        {60, 0, 13, 1}, /* Gain index 206 */
+        {60, 0, 23, 1}, /* Gain index 205 */
+        {60, 0, 33, 1}, /* Gain index 204 */
+        {60, 0, 43, 1}, /* Gain index 203 */
+        {60, 0, 53, 1}, /* Gain index 202 */
+        {61, 0, 14, 1}, /* Gain index 201 */
+        {61, 0, 24, 1}, /* Gain index 200 */
+        {61, 0, 34, 1}, /* Gain index 199 */
+        {61, 0, 44, 1}, /* Gain index 198 */
+        {61, 0, 54, 1}, /* Gain index 197 */
+        {61, 0, 64, 1}, /* Gain index 196 */
+        {61, 0, 74, 1}, /* Gain index 195 */
+};
+
+/**
+ * \brief Default ORx gain table settings
+ */
+uint8_t ORxGainTable [19][4] =
+{
+	/* Order: {FE table, External Ctl, Digital Gain/Atten, Enable Atten} */
+	{0, 0, 0, 0},	/* Gain index 255 */
+	{7, 0, 0, 0},	/* Gain index 254 */
+	{13, 0, 1, 1},	/* Gain index 253 */
+	{18, 0, 3, 1},	/* Gain index 252 */
+	{23, 0, 3, 1},	/* Gain index 251 */
+	{28, 0, 0, 0},	/* Gain index 250 */
+	{32, 0, 0, 0},	/* Gain index 249 */
+	{35, 0, 2, 1},	/* Gain index 248 */
+	{38, 0, 4, 1},	/* Gain index 247 */
+	{41, 0, 2, 1},	/* Gain index 246 */
+	{43, 0, 6, 1},	/* Gain index 245 */
+	{46, 0, 0, 0},	/* Gain index 244 */
+	{47, 0, 10, 1},	/* Gain index 243 */
+	{49, 0, 8, 1},	/* Gain index 242 */
+	{51, 0, 3, 1},	/* Gain index 241 */
+	{52, 0, 9, 1},	/* Gain index 240 */
+	{53, 0, 14, 1},	/* Gain index 239 */
+	{54, 0, 18, 1},	/* Gain index 238 */
+	{56, 0, 0, 0}	/* Gain index 237 */
+
+};
+
+/**
+ * \brief Default SnRx gain table settings
+ */
+uint8_t SnRxGainTable [53][4] =
+{
+	/* Order: {FE table, LNA Bypass, Digital Gain/Atten, Enable Atten} */
+    {0,  0,  0, 0},  /* Gain index 255 */
+    {1,  0,  7, 1},  /* Gain index 254 */
+    {3,  0,  1, 0},  /* Gain index 253 */
+    {3,  0, 15, 1}, /* Gain index 252 */
+    {5,  0,  0, 0},  /* Gain index 251 */
+    {6,  0,  2, 1},  /* Gain index 250 */
+    {7,  0,  2, 1},  /* Gain index 249 */
+    {8,  0, 12, 1}, /* Gain index 248 */
+    {9,  0,  7, 1},  /* Gain index 247 */
+    {11, 0,  1, 0}, /* Gain index 246 */
+    {11, 0, 15, 1},/* Gain index 245 */
+    {13, 0,  1, 0}, /* Gain index 244 */
+    {14, 0,  2, 0}, /* Gain index 243 */
+    {14, 0, 10, 1},/* Gain index 242 */
+    {15, 0,  0, 0}, /* Gain index 241 */
+    {15, 0, 20, 1},/* Gain index 240 */
+    {16, 0,  2, 1}, /* Gain index 239 */
+    {16, 0, 22, 1},/* Gain index 238 */
+    {17, 0,  1, 0}, /* Gain index 237 */
+    {17, 0, 15, 1},/* Gain index 236 */
+    {17, 0, 35, 1},/* Gain index 235 */
+    {17, 0, 55, 1},/* Gain index 234 */
+    {18, 0,  7, 1}, /* Gain index 233 */
+    {18, 0, 27, 1},/* Gain index 232 */
+    { 6, 1,  7, 1},  /* Gain index 231 */
+    { 7, 1,  7, 1},  /* Gain index 230 */
+    { 8, 1, 17, 1}, /* Gain index 229 */
+    { 9, 1, 12, 1}, /* Gain index 228 */
+    {11, 1,  0, 0}, /* Gain index 227 */
+    {12, 1,  3, 1}, /* Gain index 226 */
+    {13, 1,  0, 0}, /* Gain index 225 */
+    {14, 1,  1, 0}, /* Gain index 224 */
+    {14, 1, 15, 1},/* Gain index 223 */
+    {15, 1,  5, 1}, /* Gain index 222 */
+    {15, 1, 25, 1},/* Gain index 221 */
+    {16, 1,  7, 1}, /* Gain index 220 */
+    {16, 1, 27, 1},/* Gain index 219 */
+    {17, 1,  0, 0}, /* Gain index 218 */
+    {17, 1, 20, 1},/* Gain index 217 */
+    {17, 1, 40, 1},/* Gain index 216 */
+    {17, 1, 60, 1},/* Gain index 215 */
+    {18, 1, 12, 1},/* Gain index 214 */
+    {18, 1, 32, 1},/* Gain index 213 */
+    {18, 1, 52, 1},/* Gain index 212 */
+    {18, 1, 72, 1},/* Gain index 211 */
+    {18, 1, 92, 1},/* Gain index 210 */
+    {19, 1,  1, 0}, /* Gain index 209 */
+    {19, 1, 15, 1},/* Gain index 208 */
+    {19, 1, 35, 1},/* Gain index 207 */
+    {19, 1, 55, 1},/* Gain index 206 */
+    {19, 1, 75, 1},/* Gain index 205 */
+    {19, 1, 95, 1},/* Gain index 204 */
+    {19, 1, 115, 1}/* Gain index 203 */
+};
+
diff --git a/mpm/lib/mykonos/adi/mykonos_user.h b/mpm/lib/mykonos/adi/mykonos_user.h
new file mode 100644
index 000000000..4ab9f6614
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_user.h
@@ -0,0 +1,78 @@
+/**
+ * \file mykonos_user.h
+ *
+ * \brief Contains macro definitions and global structure declarations for mykonos_user.c
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef _MYKONOSPROFILES_H_
+#define _MYKONOSPROFILES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* turns verbose messaging on */
+#define MYKONOS_VERBOSE 1
+#define MYK_ENABLE_SPIWRITEARRAY 1
+
+/* 3 Bytes per SPI transaction * 341 transactions = ~1024 byte buffer size */
+/* Minimum MYK_SPIWRITEARRAY_BUFFERSIZE = 27 */
+#define MYK_SPIWRITEARRAY_BUFFERSIZE 341
+/*
+ *****************************************
+ * Rx, ObsRx, and Sniffer gain tables
+ ******************************************
+ */
+#define MAX_GAIN_TABLE_INDEX			255
+
+#define START_RX_GAIN_INDEX 			255
+#define MAX_RX_GAIN_TABLE_NUMINDEXES	(START_RX_GAIN_INDEX + 1)
+#define MIN_RX_GAIN_TABLE_INDEX			0
+
+#define START_ORX_GAIN_INDEX 			47
+#define MAX_ORX_GAIN_TABLE_NUMINDEXES  	(START_ORX_GAIN_INDEX + 1)
+#define MIN_ORX_GAIN_TABLE_INDEX		(MAX_GAIN_TABLE_INDEX - START_ORX_GAIN_INDEX)
+
+#define START_SNRX_GAIN_INDEX 			127
+#define MAX_SNRX_GAIN_TABLE_NUMINDEXES	(START_SNRX_GAIN_INDEX + 1)
+#define MIN_SNRX_GAIN_TABLE_INDEX		(MAX_GAIN_TABLE_INDEX - START_SNRX_GAIN_INDEX)
+
+#define START_LOOPBACK_GAIN_INDEX           47
+#define MAX_LOOPBACK_GAIN_TABLE_NUMINDEXES  (START_LOOPBACK_GAIN_INDEX + 1)
+#define MIN_LOOPBACK_GAIN_TABLE_INDEX       (MAX_GAIN_TABLE_INDEX - START_SNRX_GAIN_INDEX)
+
+extern uint8_t RxGainTable [61][4];
+extern uint8_t ORxGainTable [19][4];
+extern uint8_t SnRxGainTable [53][4];
+
+
+/*
+ ********************************************
+ * Rx, Sniffer, ObsRx and Tx Profiles limits
+ ********************************************
+ */
+#define MIN_RX_IQRATE_KHZ   15000       /*!< Mykonos minimum IQ rate for the Rx channel, expressed in KHz */
+#define MAX_RX_IQRATE_KHZ   320000      /*!< Mykonos maximum IQ rate for the Rx channel, expressed in KHz */
+
+#define MIN_TX_IQRATE_KHZ   15000       /*!< Mykonos minimum IQ rate for the Tx channel, expressed in KHz */
+#define MAX_TX_IQRATE_KHZ   492000      /*!< Mykonos maximum IQ rate for the Tx channel, expressed in KHz */
+
+#define MIN_SNIFFER_RFBW_HZ 5000000     /*!< Mykonos minimum Sniffer channel bandwidth expressed in Hz */
+#define MAX_SNIFFER_RFBW_HZ 20000000    /*!< Mykonos maximum Sniffer channel bandwidth expressed in Hz */
+
+#define MIN_ORX_RFBW_HZ     5000000     /*!< Mykonos minimum Observation channel bandwidth expressed in Hz */
+#define MAX_ORX_RFBW_HZ     250000000   /*!< Mykonos maximum Observation channel bandwidth expressed in Hz */
+
+#define MIN_RX_RFBW_HZ      5000000     /*!< Mykonos minimum Rx channel bandwidth expressed in Hz */
+#define MAX_RX_RFBW_HZ      100000000   /*!< Mykonos maximum Rx channel bandwidth expressed in Hz */
+
+#define MIN_TX_RFBW_HZ      20000000    /*!< Mykonos minimum Tx channel bandwidth expressed in Hz */
+#define MAX_TX_RFBW_HZ      250000000   /*!< Mykonos maximum Tx channel bandwidth expressed in Hz */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mpm/lib/mykonos/adi/mykonos_version.h b/mpm/lib/mykonos/adi/mykonos_version.h
new file mode 100644
index 000000000..1de7a6ebb
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_version.h
@@ -0,0 +1,24 @@
+/**
+ * \file mykonos_version.h
+ * \brief Contains the version number for the Mykonos API
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef MYKONOS_VERSION_H_
+#define MYKONOS_VERSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MYKONOS_CURRENT_SI_VERSION 1    		/*!< Mykonos current silicon version */
+#define MYKONOS_CURRENT_MAJOR_VERSION 3			/*!< Mykonos current ARM major version */
+#define MYKONOS_CURRENT_MINOR_VERSION 1			/*!< Mykonos current ARM minor version */
+#define MYKONOS_CURRENT_BUILD_VERSION 3534		/*!< Mykonos current API build version */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MYKONOS_VERSION_H_ */
diff --git a/mpm/lib/mykonos/adi/t_mykonos.h b/mpm/lib/mykonos/adi/t_mykonos.h
new file mode 100644
index 000000000..2dea92481
--- /dev/null
+++ b/mpm/lib/mykonos/adi/t_mykonos.h
@@ -0,0 +1,1471 @@
+/*!
+ * \file t_mykonos.h
+ * \brief Contains type definitions for Mykonos API
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef _T_MYKONOS_LIB_H_
+#define _T_MYKONOS_LIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+
+
+/**
+ *  \brief Enum of unique error codes from the Mykonos API functions.
+ * Each error condition in the library should get its own enum value to allow
+ * easy debug of errors.
+ */
+typedef enum
+{
+    MYKONOS_ERR_OK=0,
+    MYKONOS_ERR_HAL_LAYER,
+    MYKONOS_ERR_INV_PARM,
+    MYKONOS_ERR_FAILED,
+    MYKONOS_ERR_WAITFOREVENT_INV_PARM,
+    MYKONOS_ERR_WAITFOREVENT_TIMEDOUT,
+    MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_WAIT,
+    MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_ALERT,
+    MYKONOS_ERR_SETENSM_INVALID_NEWSTATE_TXRX,
+    MYKONOS_ERR_SETENSM_INVALIDSTATE,
+    MYKONOS_ERR_PU_RXPATH_INV_PARAM,
+    MYKONOS_ERR_PU_TXPATH_INV_PARAM,
+    MYKONOS_ERR_PU_OBSRXPATH_INV_PARAM,
+    MYKONOS_ERR_INIT_INV_ORXCHAN,
+    MYKONOS_ERR_INIT_INV_RXSYNCB_ORXSYNCB_MODE,
+    MYKONOS_ERR_INIT_INV_TXFIR_INTERPOLATION,
+    MYKONOS_ERR_INIT_INV_TXHB2_INTERPOLATION,
+    MYKONOS_ERR_INIT_INV_TXHB1_INTERPOLATION,
+    MYKONOS_ERR_INIT_INV_RXFIR_DECIMATION,
+    MYKONOS_ERR_INIT_INV_RXDEC5_DECIMATION,
+    MYKONOS_ERR_INIT_INV_RXHB1_DECIMATION,
+    MYKONOS_ERR_INIT_INV_SNIFFER_RHB1,
+    MYKONOS_ERR_INIT_INV_SNIFFER_RFIR_DEC,
+    MYKONOS_ERR_INIT_INV_ORX_RHB1,
+    MYKONOS_ERR_INIT_INV_ORX_RFIR_DEC,
+    MYKONOS_ERR_INIT_INV_ADCDIV,
+    MYKONOS_ERR_INIT_INV_DACDIV,
+    MYKONOS_ERR_INIT_INV_OBSRX_ADCDIV,
+    MYKONOS_ERR_CLKPLL_INV_HSDIV,
+    MYKONOS_ERR_CLKPLL_INV_VCODIV,
+    MYKONOS_ERR_CLKPLL_INV_RXTXPROFILES,
+    MYKONOS_ERR_SETCLKPLL_INV_VCOINDEX,
+    MYKONOS_ERR_SETCLKPLL_INV_FRACWORD,
+    MYKONOS_ERR_SETRFPLL_INV_PLLNAME,
+    MYKONOS_ERR_SETRFPLL_INV_LO_PARM,
+    MYKONOS_ERR_INV_SCALEDDEVCLK_PARAM,
+    MYKONOS_ERR_NULL_DEVICE_PARAM,
+    MYKONOS_ERR_CALCDEVCLK_NULLPARAM,
+    MYKONOS_ERR_SETRFPLL_INV_VCOINDEX,
+    MYKONOS_ERR_SETRFPLL_INV_REFCLK,
+    MYKONOS_ERR_SETORXGAIN_INV_CHANNEL,
+    MYKONOS_ERR_SETORXGAIN_INV_GAIN,
+    MYKONOS_ERR_GETORX1GAIN_INV_POINTER,
+    MYKONOS_ERR_GETORX2GAIN_INV_POINTER,
+    MYKONOS_ERR_GETSNIFFGAIN_INV_POINTER,
+    MYKONOS_ERR_GETOBSRXGAIN_CH_DISABLED,
+    MYKONOS_ERR_SETTX1ATTEN_INV_PARM,
+    MYKONOS_ERR_SETTX1ATTEN_INV_STEPSIZE_PARM,
+    MYKONOS_ERR_SETTX2ATTEN_INV_PARM,
+    MYKONOS_ERR_SETTX2ATTEN_INV_STEPSIZE_PARM,
+    MYKONOS_ERR_PROGRAMFIR_INV_NUMTAPS_PARM,
+    MYKONOS_ERR_PROGRAMFIR_INV_FIRNAME_PARM,
+    MYKONOS_ERR_RXFIR_INV_GAIN_PARM,
+    MYKONOS_ERR_OBSRXFIR_INV_GAIN_PARM,
+    MYKONOS_ERR_SRXFIR_INV_GAIN_PARM,
+    MYKONOS_ERR_TXFIR_INV_GAIN_PARM,
+    MYKONOS_ERR_READFIR_NULL_PARM,
+    MYKONOS_ERR_READFIR_COEFS_NULL,
+    MYKONOS_ERR_READFIR_INV_FIRNAME_PARM,
+    MYKONOS_ERR_READFIR_INV_NUMTAPS_PARM,
+    MYKONOS_ERR_SETRX1GAIN_INV_GAIN_PARM,
+    MYKONOS_ERR_SETRX2GAIN_INV_GAIN_PARM,
+    MYKONOS_ERR_INITSER_INV_VCODIV_PARM,
+    MYKONOS_ERR_INITDES_INV_VCODIV_PARM,
+    MYKONOS_ERR_SER_INV_M_PARM,
+    MYKONOS_ERR_SER_INV_L_PARM,
+    MYKONOS_ERR_SER_INV_HSCLK_PARM,
+    MYKONOS_ERR_SER_INV_LANERATE_PARM,
+    MYKONOS_ERR_SER_INV_LANEEN_PARM,
+    MYKONOS_ERR_SER_INV_AMP_PARM,
+    MYKONOS_ERR_SER_INV_PREEMP_PARM,
+    MYKONOS_ERR_SER_INV_LANEPN_PARM,
+    MYKONOS_ERR_SER_LANE_CONFLICT_PARM,
+    MYKONOS_ERR_SER_INV_TXSER_DIV_PARM,
+    MYKONOS_ERR_SER_LANE_RATE_CONFLICT_PARM,
+    MYKONOS_ERR_SER_INV_REAL_IF_DATA_PARM,
+    MYKONOS_ERR_HS_AND_LANE_RATE_NOT_INTEGER_MULT,
+    MYKONOS_ERR_DES_HS_AND_LANE_RATE_NOT_INTEGER_MULT,
+    MYKONOS_ERR_DESER_INV_M_PARM,
+    MYKONOS_ERR_DESER_INV_L_PARM,
+    MYKONOS_ERR_DESER_INV_HSCLK_PARM,
+    MYKONOS_ERR_DESER_INV_LANERATE_PARM,
+    MYKONOS_ERR_DESER_INV_LANEEN_PARM,
+    MYKONOS_ERR_DESER_INV_EQ_PARM,
+    MYKONOS_ERR_DESER_INV_LANEPN_PARM,
+    MYKONOS_ERR_FRAMER_INV_M_PARM,
+    MYKONOS_ERR_FRAMER_INV_BANKID_PARM,
+    MYKONOS_ERR_FRAMER_INV_LANEID_PARM,
+    MYKONOS_ERR_FRAMER_INV_K_OFFSET_PARAM,
+    MYKONOS_ERR_FRAMER_INV_REAL_IF_DATA_PARM,
+    MYKONOS_ERR_OBSRX_FRAMER_INV_M_PARM,
+    MYKONOS_ERR_OBSRX_FRAMER_INV_BANKID_PARM,
+    MYKONOS_ERR_OBSRX_FRAMER_INV_LANEID_PARM,
+    MYKONOS_ERR_OBSRX_FRAMER_INV_K_OFFSET_PARAM,
+    MYKONOS_ERR_OBSRX_FRAMER_INV_REAL_IF_DATA_PARM,
+    MYKONOS_ERR_DEFRAMER_INV_M_PARM,
+    MYKONOS_ERR_DEFRAMER_INV_BANKID_PARM,
+    MYKONOS_ERR_ERR_DEFRAMER_INV_LANEID_PARM,
+    MYKONOS_ERR_DEFRAMER_INV_K_OFFSET_PARAM,
+    MYKONOS_ERR_DEFRAMER_INV_K_PARAM,
+    MYKONOS_ERR_DEFRAMER_INV_FK_PARAM,
+    MYKONOS_ERR_RX_FRAMER_INV_PRBS_POLYORDER_PARAM,
+    MYKONOS_ERR_OBSRX_FRAMER_INV_PRBS_POLYORDER_PARAM,
+    MYKONOS_ERR_DEFRAMER_INV_PRBS_ENABLE_PARAM,
+    MYKONOS_ERR_DEFRAMER_INV_PRBS_POLYORDER_PARAM,
+    MYKONOS_ERR_DEFRAMER_INV_PRBS_CNTR_SEL_PARAM,
+    MYKONOS_ERR_INITARM_INV_DATARATE_PARM,
+    MYKONOS_ERR_INITARM_INV_REGCLK,
+    MYKONOS_ERR_INITARM_INV_ARMCLK_PARAM,
+    MYKONOS_ERR_LOADHEX_INV_CHARCOUNT,
+    MYKONOS_ERR_LOADHEX_INVALID_FIRSTCHAR,
+    MYKONOS_ERR_LOADHEX_INVALID_CHKSUM,
+    MYKONOS_ERR_LOADBIN_INVALID_BYTECOUNT,
+    MYKONOS_ERR_ARM_INVALID_BUILDCHKSUM,
+    MYKONOS_ERR_READARMMEM_INV_ADDR_PARM,
+    MYKONOS_ERR_WRITEARMMEM_INV_ADDR_PARM,
+    MYKONOS_ERR_ARMCMD_INV_OPCODE_PARM,
+    MYKONOS_ERR_ARMCMD_INV_NUMBYTES_PARM,
+    MYKONOS_ERR_ARMCMDSTATUS_INV_OPCODE_PARM,
+    MYKONOS_ERR_CHECKDEVSTRUCT_SPI,
+    MYKONOS_ERR_CHECKDEVSTRUCT_RX,
+    MYKONOS_ERR_CHECKDEVSTRUCT_RXSUB,
+    MYKONOS_ERR_CHECKDEVSTRUCT_RXFIR,
+    MYKONOS_ERR_CHECKDEVSTRUCT_TX,
+    MYKONOS_ERR_CHECKDEVSTRUCT_TXSUB,
+    MYKONOS_ERR_CHECKDEVSTRUCT_TXFIR,
+    MYKONOS_ERR_CHECKDEVSTRUCT_OBSRX,
+    MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXSUB,
+    MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERFIR,
+    MYKONOS_ERR_CHECKDEVSTRUCT_ORXFIR,
+    MYKONOS_ERR_CHECKDEVSTRUCT_ORXGAINCTRL,
+    MYKONOS_ERR_CHECKDEVSTRUCT_SNIFFERGAINCTRL,
+    MYKONOS_ERR_CHECKDEVSTRUCT_OBSRXFRAMER,
+    MYKONOS_ERR_INITSER_INV_PROFILE,
+    MYKONOS_ERR_INITDES_INV_TXPROFILE,
+    MYKONOS_ERR_JESD204B_ILAS_MISMATCH,
+    MYKONOS_ERR_RXGAINTABLE_INV_CHANNEL,
+    MYKONOS_ERR_RXGAINTABLE_INV_GAIN_INDEX_RANGE,
+    MYKONOS_ERR_WRITE_CFG_MEMORY_FAILED,
+	MYKONOS_ERR_INV_RXFRAMER_PCLKDIV_PARM,
+	MYKONOS_ERR_RXFRAMER_INV_FK_PARAM,
+	MYKONOS_ERR_OBSRXFRAMER_INV_FK_PARAM,
+    MYKONOS_ERR_INV_OBSRXFRAMER_PCLKDIV_PARM,
+    MYKONOS_ERR_PU_OBSRXPATH_INV_LOSOURCE_PARAM,
+    MYKONOS_ERR_ARM_RADIOON_FAILED,
+    MYKONOS_ERR_INV_RX_GAIN_MODE_PARM,
+    MYKONOS_ERR_INV_ORX_GAIN_MODE_PARM,
+    MYKONOS_ERR_INV_AGC_RX_STRUCT_INIT,
+    MYKONOS_ERR_INV_AGC_RX_APD_THRESH_DIFF_VS_ATTACK_GAIN_STEP,
+    MYKONOS_ERR_INV_AGC_RX_PEAK_WAIT_TIME_PARM,
+    MYKONOS_ERR_INV_AGC_RX_GAIN_UPDATE_TIME_PARM,
+    MYKONOS_ERR_INV_AGC_RX_APD_HIGH_THRESH_PARM,
+    MYKONOS_ERR_INV_AGC_RX_APD_LOW_THRESH_PARM,
+    MYKONOS_ERR_INV_AGC_RX_BLOCK_DET_DECAY_PARM,
+    MYKONOS_ERR_INV_AGC_RX_APD_GAIN_STEP_PARM,
+    MYKONOS_ERR_INV_AGC_RX_HB2_GAIN_STEP_PARM,
+    MYKONOS_ERR_INV_AGC_RX_RECOVERY_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_PMD_MEAS_CONFIG,
+	MYKONOS_ERR_INV_AGC_PMD_MEAS_DURATION,
+	MYKONOS_ERR_INV_AGC_RX_ENABLE_SYNC_PULSE_GAIN_COUNTER,
+	MYKONOS_ERR_INV_AGC_RX_LOW_THS_PREV_GAIN_INC,
+	MYKONOS_ERR_INV_AGC_RX_PEAK_STRUCT_INIT,
+	MYKONOS_ERR_INV_AGC_RX_PEAK_THRESH_MODE,
+	MYKONOS_ERR_INV_AGC_RX_PWR_STRUCT_INIT,
+	MYKONOS_ERR_INV_AGC_RX_RESET_ON_RX_ENABLE,
+	MYKONOS_ERR_INV_AGC_RX_SLOW_LOOP_SETTLING_DELAY,
+	MYKONOS_ERR_INV_AGC_RX1_MAX_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_RX1_MIN_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_RX2_MAX_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_RX2_MIN_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_THRESH,
+	MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_THRESH,
+	MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_THRESH,
+	MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_THRESH,
+	MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_LOW_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_RX_PMD_LOWER_HIGH_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_LOW_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_RX_PMD_UPPER_HIGH_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_RX_APD_HIGH_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_RX_APD_LOW_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_RX_HB2_HIGH_THRESH_PARM,
+	MYKONOS_ERR_INV_AGC_RX_HB2_LOW_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_RX_HB2_LOW_THRESH_PARM,
+	MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_RX_HB2_VERY_LOW_THRESH_PARM,
+	MYKONOS_ERR_INV_AGC_RX_PKDET_FAST_ATTACK_VALUE,
+	MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_ENABLE,
+	MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_DUR_CNT,
+	MYKONOS_ERR_INV_AGC_RX_HB2_OVLD_THRESH_CNT,
+    MYKONOS_ERR_INV_AGC_OBSRX_STRUCT_INIT,
+    MYKONOS_ERR_INV_AGC_OBSRX_APD_THRESH_DIFF_VS_ATTACK_GAIN_STEP,
+    MYKONOS_ERR_INV_AGC_OBSRX_PEAK_WAIT_TIME_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_GAIN_UPDATE_TIME_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_THRESH_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_THRESH_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_BLOCK_DET_DECAY_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_APD_GAIN_STEP_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_HB2_GAIN_STEP_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_RECOVERY_GAIN_STEP_PARM,
+    MYKONOS_ERR_INV_AGC_OBSRX_MAX_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_OBSRX_MIN_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_OBSRX_SELECT,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_CONFIG,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_MEAS_DURATION,
+	MYKONOS_ERR_INV_AGC_OBSRX_ENABLE_SYNC_PULSE_GAIN_COUNTER,
+	MYKONOS_ERR_INV_AGC_OBSRX_LOW_THS_PREV_GAIN_INC,
+	MYKONOS_ERR_INV_AGC_OBSRX_PEAK_STRUCT_INIT,
+	MYKONOS_ERR_INV_AGC_OBSRX_PEAK_THRESH_MODE,
+	MYKONOS_ERR_INV_AGC_OBSRX_PWR_STRUCT_INIT,
+	MYKONOS_ERR_INV_AGC_OBSRX_RESET_ON_RX_ENABLE,
+	MYKONOS_ERR_INV_AGC_OBSRX_SLOW_LOOP_SETTLING_DELAY,
+	MYKONOS_ERR_INV_AGC_OBSRX1_MAX_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_OBSRX1_MIN_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_OBSRX2_MAX_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_OBSRX2_MIN_GAIN_INDEX,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_THRESH,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_THRESH,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_THRESH,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_THRESH,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_LOW_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_LOWER_HIGH_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_LOW_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_OBSRX_PMD_UPPER_HIGH_GAIN_STEP,
+	MYKONOS_ERR_INV_AGC_OBSRX_APD_HIGH_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_APD_LOW_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_HIGH_THRESH_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_LOW_THRESH_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_GAIN_STEP_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_VERY_LOW_THRESH_PARM,
+	MYKONOS_ERR_INV_AGC_OBSRX_PKDET_FAST_ATTACK_VALUE,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_ENABLE,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_DUR_CNT,
+	MYKONOS_ERR_INV_AGC_OBSRX_HB2_OVLD_THRESH_CNT,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CALPLL_LOCK,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLLCP,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_CLKPLL_LOCK,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLLCP,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXPLL_LOCK,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLLCP,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXPLL_LOCK,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLLCP,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_SNIFFPLL_LOCK,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RXBBFCALDONE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_TXBBFCALDONE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RFDCCALDONE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ADCTUNECALDONE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX1ADCPROFILE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RX2ADCPROFILE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ORXADCPROFILE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_RCALDONE,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_ARMBUSY,
+	MYKONOS_ERR_WAITFOREVENT_TIMEDOUT_INITARMDONE,
+	MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY,
+	MYKONOS_ERR_PU_OBSRXPATH_ARMERROR,
+	MYKONOS_ERR_EN_TRACKING_CALS_ARMSTATE_ERROR,
+	MYKONOS_ERR_EN_TRACKING_CALS_ARMERROR,
+	MYKONOS_ERR_SETRFPLL_ARMERROR,
+	MYKONOS_ERR_INIT_INV_TXINPUTHB_PARM,
+	MYKONOS_ERR_LOAD_ADCPROFILE_INV_VCODIV,
+	MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_RXREQUIRED,
+	MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_ORXREQUIRED,
+	MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_SNRXREQUIRED,
+	MYKONOS_ERR_SETUP_PA_PROT_INV_AVG_DURATION,
+	MYKONOS_ERR_SETUP_PA_PROT_INV_STICKY_ENABLE,
+	MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_STEP,
+	MYKONOS_ERR_SETUP_PA_PROT_INV_ATTEN_ENABLE,
+	MYKONOS_ERR_SETUP_PA_PROT_INV_POWER_THRESH,
+	MYKONOS_ERR_SETUP_PA_PROT_INV_TX_CHANNEL,
+	MYKONOS_ERR_GET_DAC_PWR_INV_POINTER,
+	MYKONOS_ERR_GET_PA_FLAG_STATUS_INV_POINTER,
+	MYKONOS_ERR_GET_OBSRX_OVERLOADS_NULL_PARM,
+	MYKONOS_ERR_GET_RX1_OVERLOADS_NULL_PARM,
+	MYKONOS_ERR_GET_RX2_OVERLOADS_NULL_PARM,
+	MYKONOS_ERR_GETRADIOSTATE_NULL_PARAM,
+	MYKONOS_ERR_ABORT_INITCALS_NULL_PARAM,
+	MYKONOS_ERR_ARM_RADIOOFF_FAILED,
+	MYKONOS_ERR_WAIT_INITCALS_NULL_PARAM,
+	MYKONOS_ERR_WAIT_INITCALS_CALFAILED,
+	MYKONOS_ERR_WAIT_INITCALS_ARMERROR,
+	MYKONOS_ERR_CHECK_PLL_LOCK_NULL_PARM,
+	MYKONOS_ERR_GET_TXFILTEROVRG_NULL_PARM,
+	MYKONOS_ERR_PROGRAM_RXGAIN_TABLE_NULL_PARM,
+	MYKONOS_ERR_PROGRAMFIR_NULL_PARM,
+	MYKONOS_ERR_PROGRAMFIR_COEFS_NULL,
+	MYKONOS_ERR_READ_DEFRAMERSTATUS_NULL_PARAM,
+	MYKONOS_ERR_READ_DEFRAMERPRBS_NULL_PARAM,
+	MYKONOS_ERR_READ_ORXFRAMERSTATUS_NULL_PARAM,
+	MYKONOS_ERR_READ_RXFRAMERSTATUS_NULL_PARAM,
+	MYKONOS_ERR_ARMCMDSTATUS_NULL_PARM,
+	MYKONOS_ERR_READARMCMDSTATUS_INV_OPCODE_PARM,
+	MYKONOS_ERR_READARMCMDSTATUS_NULL_PARM,
+	MYKONOS_ERR_READARMCMDSTATUSBYTE_NULL_PARM,
+	MYKONOS_ERR_ARMCMD_NULL_PARM,
+	MYKONOS_ERR_WRITEARMMEM_NULL_PARM,
+	MYKONOS_ERR_LOADBIN_NULL_PARAM,
+	MYKONOS_ERR_GETTX1ATTEN_NULL_PARM,
+	MYKONOS_ERR_GETTX2ATTEN_NULL_PARM,
+	MYKONOS_ERR_ENFRAMERLINK_INV_LANESEN_PARM,
+	MYKONOS_ERR_ENOBSFRAMERLINK_INV_LANESEN_PARM,
+	MYKONOS_ERR_ENTXNCO_TXPROFILE_INVALID,
+	MYKONOS_ERR_ENTXNCO_TX1_FREQ_INVALID,
+	MYKONOS_ERR_ENTXNCO_TX2_FREQ_INVALID,
+	MYKONOS_ERR_JESD204B_ILAS_MISMATCH_NULLPARAM,
+	MYKONOS_ERR_LOAD_LBADCPROFILE_ARMMEM_FAILED,
+	MYKONOS_ERR_LOAD_SNRXADCPROFILE_ARMMEM_FAILED,
+	MYKONOS_ERR_LOAD_ADCPROFILE_SNRX_ADCDIV_ZERO,
+	MYKONOS_ERR_LOAD_ORXADCPROFILE_ARMMEM_FAILED,
+	MYKONOS_ERR_LOAD_ADCPROFILE_ORXADCDIV_ZERO,
+	MYKONOS_ERR_LOAD_RXADCPROFILE_ARMMEM_FAILED,
+	MYKONOS_ERR_LOAD_ADCPROFILE_RXADCDIV_ZERO,
+	MYKONOS_ERR_LOAD_ADCPROFILE_CUSTOM_LBREQUIRED,
+	MYKONOS_ERR_LOAD_ADCPROFILE_MISSING_ORX_PROFILE,
+	MYKONOS_ERR_GETRFPLL_INV_PLLNAME,
+	MYKONOS_ERR_GETRFPLL_ARMERROR,
+	MYKONOS_ERR_GETRFPLL_NULLPARAM,
+	MYKONOS_ERR_INITARM_INV_VCODIV,
+	MYKONOS_ERR_GET_PLLFREQ_INV_HSDIV,
+	MYKONOS_ERR_GET_PLLFREQ_INV_REFCLKDIV,
+	MYKONOS_ERR_SETORXGAIN_INV_ORX1GAIN,
+	MYKONOS_ERR_SETORXGAIN_INV_ORX2GAIN,
+	MYKONOS_ERR_SETORXGAIN_INV_SNRXGAIN,
+	MYKONOS_ERR_GET_RX1_DEC_POWER_NUM_SAMPLES,
+	MYKONOS_ERR_GET_RX1_DEC_POWER_NULL_PARM,
+	MYKONOS_ERR_GET_RX2_DEC_POWER_NUM_SAMPLES,
+	MYKONOS_ERR_GET_RX2_DEC_POWER_NULL_PARM,
+	MYKONOS_ERR_GET_OBSRX_DEC_POWER_NUM_SAMPLES,
+	MYKONOS_ERR_GET_OBSRX_DEC_POWER_NULL_PARM,
+	MYKONOS_ERR_GETARMVER_NULL_PARM,
+	MYKONOS_ERR_EN_CLGCTRACKING_ARMSTATE_ERROR,
+	MYKONOS_ERR_EN_DPDTRACKING_ARMSTATE_ERROR,
+	MYKONOS_ERR_RESTDPDMOD_WRONGBUFFERSIZE,
+	MYKONOS_ERR_RESTDPDMOD_ARMSTATE,
+	MYKONOS_ERR_RESTDPDMOD_INVALID_TXCHANNEL,
+	MYKONOS_ERR_RESTDPDMOD_ARMERRFLAG,
+	MYKONOS_ERR_SAVDPDMOD_WRONGBUFFERSIZE,
+	MYKONOS_ERR_SAVDPDMOD_ARMSTATE,
+	MYKONOS_ERR_SAVDPDMOD_INVALID_TXCHANNEL,
+	MYKONOS_ERR_SAVDPDMOD_ARMERRFLAG,
+ 	MYKONOS_ERR_WRITEARMCFG_ARMERRFLAG,
+	MYKONOS_ERR_CFGDPD_TXORX_PROFILE_INV,
+	MYKONOS_ERR_CFGDPD_NULL_DPDCFGSTRUCT,
+	MYKONOS_ERR_CFGDPD_ARMSTATE_ERROR,
+	MYKONOS_ERR_CFGDPD_INV_DPDDAMPING,
+	MYKONOS_ERR_CFGDPD_INV_DPDSAMPLES,
+	MYKONOS_ERR_CFGDPD_INV_DPDOUTLIERTHRESH,
+	MYKONOS_ERR_CFGDPD_INV_DPDPRIORWEIGHT,
+	MYKONOS_ERR_CFGCLGC_INV_DESIREDGAIN,
+	MYKONOS_ERR_CFGCLGC_INV_TXATTENLIMIT,
+	MYKONOS_ERR_CFGCLGC_INV_CLGC_CTRLRATIO,
+	MYKONOS_ERR_SETCLGCGAIN_INV_DESIREDGAIN,
+	MYKONOS_ERR_SETCLGCGAIN_INV_TXCHANNEL,
+	MYKONOS_ERR_SETCLGCGAIN_TRACK_ARMERRFLAG,
+	MYKONOS_ERR_CFGDPD_INV_DPD_ADDDELAY,
+	MYKONOS_ERR_CFGDPD_INV_PNSEQLEVEL,
+	MYKONOS_ERR_READARMCFG_ARMERRFLAG,
+	MYKONOS_ERR_GETPENDTRKCALS_NULL_PARAM,
+	MYKONOS_ERR_ARMCMDSTATUS_ARMERROR,
+	MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT,
+	MYKONOS_ERR_PU_GETOBSRXPATH_ARMERROR,
+	MYKONOS_ERR_GETDPDCFG_NULL_DPDCFGSTRUCT,
+	MYKONOS_ERR_GETDPDCFG_TXORX_PROFILE_INV,
+	MYKONOS_ERR_GETDPDSTATUS_ARMERRFLAG,
+	MYKONOS_ERR_GETDPDSTATUS_NULLPARAM,
+	MYKONOS_ERR_SETDEFOBSRXPATH_NULL_OBSRX_STRUCT,
+	MYKONOS_ERR_SETDEFOBSRXPATH_NULL_DEF_OBSRX_STRUCT,
+	MYKONOS_ERR_GETCLGCSTATUS_NULLPARAM,
+	MYKONOS_ERR_GETCLGCSTATUS_ARMERRFLAG,
+	MYKONOS_ERR_CHECKDEVSTRUCT_NULLDEVPOINTER,
+	MYKONOS_ERR_READ_DEFFIFODEPTH_NULL_PARAM,
+	MYKONOS_ERR_READ_DEFFIFODEPTH_LMFCCOUNT_NULL_PARAM,
+	MYKONOS_ERR_GETDPDSTATUS_INV_CH,
+	MYKONOS_ERR_GETCLGCSTATUS_INV_CH,
+	MYKONOS_ERR_INIT_INV_TXINPUTHB_INV_RATE,
+	MYKONOS_ERR_INIT_INV_TXINPUTHB0_INV_RATE,
+	MYKONOS_ERR_TXFIR_TAPSEXCEEDED,
+	MYKONOS_ERR_TXFIR_INV_NUMROWS,
+    MYKONOS_ERR_TXFIR_INV_NUMTAPS_PARM,
+	MYKONOS_ERR_RXFIR_TAPSEXCEEDED,
+	MYKONOS_ERR_ORXFIR_TAPSEXCEEDED,
+	MYKONOS_ERR_SNRXFIR_TAPSEXCEEDED,
+	MYKONOS_ERR_GETINITCALSTATUS_NULL_PARAM,
+	MYKONOS_ERR_GETINITCALSTATUS_ARMERROR,
+	MYKONOS_ERR_CFGDPD_INV_NUMWEIGHTS,
+	MYKONOS_ERR_CFGDPD_INV_MODELVERSION,
+	MYKONOS_ERR_SETDPDACT_INV_TXCHANNEL,
+	MYKONOS_ERR_SETDPDACT_INV_STATE,
+	MYKONOS_ERR_SETDPDACT_ARMERRFLAG,
+	MYKONOS_ERR_CFGCLGC_TXORX_PROFILE_INV,
+	MYKONOS_ERR_CFGCLGC_NULL_CLGCCFGSTRUCT,
+	MYKONOS_ERR_CFGCLGC_ARMSTATE_ERROR,
+	MYKONOS_ERR_GETCLGCCFG_TXORX_PROFILE_INV,
+	MYKONOS_ERR_GETCLGCCFG_NULL_CFGSTRUCT,
+	MYKONOS_ERR_CALCDIGCLK_NULLDEV_PARAM,
+	MYKONOS_ERR_CALCDIGCLK_NULL_CLKSTRUCT,
+	MYKONOS_ERR_CFGCLGC_INV_CLGC_ADDDELAY,
+	MYKONOS_ERR_CFGCLGC_INV_PNSEQLEVEL,
+	MYKONOS_ERR_CFGVSWR_TXORX_PROFILE_INV,
+	MYKONOS_ERR_CFGVSWR_ARMSTATE_ERROR,
+	MYKONOS_ERR_CFGVSWR_INV_3P3GPIOPIN,
+	MYKONOS_ERR_CFGVSWR_INV_PNSEQLEVEL,
+	MYKONOS_ERR_CFGVSWR_INV_VSWR_ADDDELAY,
+	MYKONOS_ERR_CFGVSWR_NULL_VSWRCFGSTRUCT,
+	MYKONOS_ERR_GETVSWRCFG_NULL_CFGSTRUCT,
+	MYKONOS_ERR_GETVSWRCFG_TXORX_PROFILE_INV,
+	MYKONOS_ERR_GETVSWRSTATUS_ARMERRFLAG,
+	MYKONOS_ERR_GETVSWRSTATUS_INV_CH,
+	MYKONOS_ERR_GETVSWRSTATUS_NULLPARAM,
+	MYKONOS_ERR_SET_RX_MAX_GAIN_INDEX,
+	MYKONOS_ERR_SET_RX_MIN_GAIN_INDEX,
+	MYKONOS_ERR_AGC_MIN_MAX_RX_CHANNEL,
+	MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX_CHANNEL,
+	MYKONOS_ERR_SET_ORX_MAX_GAIN_INDEX,
+	MYKONOS_ERR_SET_ORX_MIN_GAIN_INDEX,
+	MYKONOS_ERR_AGC_MIN_MAX_ORX_CHANNEL,
+	MYKONOS_ERR_RX1_TEMP_GAIN_COMP_RANGE,
+	MYKONOS_ERR_RX2_TEMP_GAIN_COMP_RANGE,
+	MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_RANGE,
+	MYKONOS_ERR_RX1_TEMP_GAIN_COMP_STEP,
+	MYKONOS_ERR_RX2_TEMP_GAIN_COMP_STEP,
+	MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_STEP,
+	MYKONOS_ERR_RX1_TEMP_GAIN_COMP_NULL,
+	MYKONOS_ERR_RX2_TEMP_GAIN_COMP_NULL,
+	MYKONOS_ERR_OBS_RX_TEMP_GAIN_COMP_NULL,
+	MYKONOS_ERR_GETTXLOLSTATUS_NULLPARAM,
+	MYKONOS_ERR_GETTXLOLSTATUS_INV_CH,
+	MYKONOS_ERR_GETTXLOLSTATUS_ARMERRFLAG,
+	MYKONOS_ERR_GETTXQECSTATUS_NULLPARAM,
+	MYKONOS_ERR_GETTXQECSTATUS_INV_CH,
+	MYKONOS_ERR_GETTXQECSTATUS_ARMERRFLAG,
+    MYKONOS_ERR_GETRXQECSTATUS_NULLPARAM,
+    MYKONOS_ERR_GETRXQECSTATUS_INV_CH,
+    MYKONOS_ERR_GETRXQECSTATUS_ARMERRFLAG,
+    MYKONOS_ERR_GETORXQECSTATUS_NULLPARAM,
+    MYKONOS_ERR_GETORXQECSTATUS_INV_CH,
+    MYKONOS_ERR_GETORXQECSTATUS_ARMERRFLAG,
+    MYKONOS_ERR_RESCHEDULE_TRACK_CAL_INV,
+    MYKONOS_ERR_RESCHEDULE_TRACK_ARMERRFLAG,
+
+    MYKONOS_ERR_SETSTATEALL_TRACK_CAL_INV,
+    MYKONOS_ERR_SETSTATEALL_TRACK_ARMERRFLAG,
+
+    MYKONOS_ERR_GETSTATEALL_TRACK_NULL_PARAM,
+    MYKONOS_ERR_GETSTATEALL_TRACK_ARMERRFLAG,
+    MYKONOS_ERR_GETSTATEALL_TRACK_ARMERROR,
+
+    MYKONOS_ERR_SETSTATE_TRACK_CAL_INV,
+    MYKONOS_ERR_SETSTATE_TRACK_ARMERRFLAG,
+
+    MYKONOS_ERR_GETSTATE_TRACK_NULL_PARAM,
+    MYKONOS_ERR_GETSTATE_TRACK_ARMERRFLAG,
+    MYKONOS_ERR_GETSTATE_TRACK_ARMERROR,
+
+    MYKONOS_ERR_ARMSTATE_PROFILE_ERROR,
+    MYKONOS_ERR_ARMSTATE_CAL_ERROR,
+    MYKONOS_ERR_ARMSTATE_EXCEPTION,
+    MYKONOS_ERR_WAITARMCSTATE_TIMEOUT,
+
+    MYKONOS_ERR_GETPRODUCTID_NULL_PARAM,
+    MYKONOS_ERR_GET_API_VERSION_NULL_PARAM,
+
+    MYKONOS_ERR_PROFILES_HSDIGCLK,
+    MYKONOS_ERR_RXPROFILE_RXCHANNEL,
+    MYKONOS_ERR_RXPROFILE_IQRATE,
+    MYKONOS_ERR_RXPROFILE_RFBW,
+    MYKONOS_ERR_RXPROFILE_FILTER_DECIMATION,
+    MYKONOS_ERR_RXPROFILE_FIR_COEFS,
+    MYKONOS_ERR_RXPROFILE_ADCDIV,
+    MYKONOS_ERR_TXPROFILE_IQRATE,
+    MYKONOS_ERR_TXPROFILE_RFBW,
+    MYKONOS_ERR_TXPROFILE_FILTER_INTERPOLATION,
+    MYKONOS_ERR_TXPROFILE_FIR_COEFS,
+    MYKONOS_ERR_TXPROFILE_DACDIV,
+    MYKONOS_ERR_RESET_TXLOL_INV_PARAM,
+    MYKONOS_ERR_RESET_TXLOL_ARMERROR
+} mykonosErr_t;
+
+/**
+ *  \brief Enum for Mykonos low voltage GPIO available pins
+ */
+typedef enum
+{
+    MYKGPIONAN  = 0x00,
+    MYKGPIO0    = 0x1,
+    MYKGPIO1    = 0x2,
+    MYKGPIO2    = 0x4,
+    MYKGPIO3    = 0x8,
+    MYKGPIO4    = 0x10,
+    MYKGPIO5    = 0x20,
+    MYKGPIO6    = 0x40,
+    MYKGPIO7    = 0x80,
+    MYKGPIO8    = 0x100,
+    MYKGPIO9    = 0x200,
+    MYKGPIO10   = 0x400,
+    MYKGPIO11   = 0x800,
+    MYKGPIO12   = 0x1000,
+    MYKGPIO13   = 0x2000,
+    MYKGPIO14   = 0x4000,
+    MYKGPIO15   = 0x8000,
+    MYKGPIO16   = 0x10000,
+    MYKGPIO17   = 0x20000,
+    MYKGPIO18   = 0x40000
+} mykonosGpioSelect_t;
+
+
+/**
+ *  \brief Enum of valid Mykonos Enable State Machine (ENSM) states
+ */
+typedef enum
+{
+    WAIT        = 0,    /*!< Mykonos ENSM state upon which a power up in the WAIT/SLEEP state occurs */
+    INIT        = 1,    /*!< Mykonos ENSM state upon which a power up delay state ocurrs to allow clocks to stabilize */
+    WAITCALS    = 2,    /*!< Mykonos ENSM state upon which calibrations are initializing */
+    ALERTCALS   = 3,    /*!< Mykonos ENSM state upon which calibrations are occurring */
+    ALERTLDS    = 4,    /*!< Mykonos ENSM state upon which a delay state is occurring when moving from WAIT to ALERT to allow internal circuits to power up */
+    ALERT       = 5,    /*!< Mykonos ENSM state upon which the internal RF synth is powered up, and TX and RX data paths are still powered down */
+    TX_RX       = 6,    /*!< Mykonos ENSM state upon which the ability to power up data paths depending on the TxEnable/RxEnable pins or SPI bits */
+    FLUSH       = 7     /*!< Mykonos ENSM state upon which the data paths are cleared when exiting the TX_RX state */
+} mykonosEnsmState_t;
+
+
+/**
+ *  \brief Enum of possible Tx channels
+ */
+typedef enum
+{
+    TXOFF   = 0,
+    TX1     = 1,
+    TX2     = 2,
+    TX1_TX2 = 3
+} mykonosTxChannels_t;
+
+/**
+ *  \brief Enum of possible Rx channels
+ */
+typedef enum
+{
+    RXOFF   = 0,
+    RX1     = 1,
+    RX2     = 2,
+    RX1_RX2 = 3
+} mykonosRxChannels_t;
+
+/**
+ *  \brief Enum of possible Observation Rx channels
+ */
+typedef enum
+{
+    OBS_RXOFF           = 0,
+    OBS_RX1_TXLO        = 1,
+    OBS_RX2_TXLO        = 2,
+    OBS_INTERNALCALS    = 3,
+    OBS_SNIFFER         = 4,
+    OBS_RX1_SNIFFERLO   = 5,
+    OBS_RX2_SNIFFERLO   = 6,
+    OBS_SNIFFER_A       = 0x14,
+    OBS_SNIFFER_B       = 0x24,
+    OBS_SNIFFER_C       = 0x34
+} mykonosObsRxChannels_t;
+
+/**
+ *  \brief Enum of possible Sniffer Rx channels
+ */
+typedef enum
+{
+    SNIFFER_A   = 1,
+    SNIFFER_B   = 2,
+    SNIFFER_C   = 3
+} mykonosSnifferChannel_t;
+
+/**
+ *  \brief Enum of possible Observation Rx channels to enable and run calibrations for during init.
+ *  Choose ENUM value that enables all channels that will be used in the system.  During system use,
+ *  only one channel can be used at a time.  This is also used to alert the ARM processor
+ *  which observation channels are valid for the current desired system setup.
+ */
+typedef enum
+{
+    MYK_OBS_RXOFF   = 0x00,
+    MYK_ORX1        = 0x01,
+    MYK_ORX2        = 0x02,
+    MYK_ORX1_ORX2   = 0x03,
+    MYK_SNRXA       = 0x04,
+    MYK_SNRXB       = 0x08,
+    MYK_SNRXC       = 0x10,
+    MYK_SNRXA_B_C   = 0x1C
+} mykonosObsRxChannelsEn_t;
+
+/**
+ *  \brief Enum of possible DAC divider settings (2x, 2.5x, 4x)
+ */
+typedef enum
+{
+    DACDIV_2,
+    DACDIV_2p5,
+    DACDIV_4
+} mykonosDacDiv_t;
+
+/**
+ *  \brief Enum of possible VCO divider settings (1x, 1.5x, 2x, 3x)
+ */
+typedef enum
+{
+    VCODIV_1    = 0,
+    VCODIV_1p5  = 1,
+    VCODIV_2    = 2,
+    VCODIV_3    = 3
+} mykonosVcoDiv_t;
+
+/**
+ * \brief Enum of possible PRBS pattern settings
+ */
+typedef enum
+{
+    MYK_PRBS7   = 0,
+    MYK_PRBS15  = 1,
+    MYK_PRBS31  = 2
+} mykonosPrbsOrder_t;
+
+/**
+ *  \brief Enum of RF PLL names
+ */
+typedef enum
+{
+    CLK_PLL,
+    RX_PLL,
+    TX_PLL,
+    SNIFFER_PLL
+} mykonosRfPllName_t;
+
+/**
+ *  \brief Enum of Rx profile types
+ */
+typedef enum
+{
+    MYK_RX_PROFILE,
+    MYK_OBS_PROFILE,
+    MYK_SNIFFER_PROFILE
+} mykonosRxProfType_t;
+
+/**
+ * \brief Enum of ORx PLL names
+ */
+typedef enum
+{
+    OBSLO_TX_PLL,
+    OBSLO_SNIFFER_PLL
+} mykonosObsRxLoSource_t;
+
+/**
+ *  \brief Enum of possible wait events to use with MYKONOS_waitForEvent()
+ */
+typedef enum
+{
+    CALPLL_LOCK,
+    CLKPLLCP,
+    CLKPLL_LOCK,
+    RF_RXPLLCP,
+    RF_RXPLL_LOCK,
+    RF_TXPLLCP,
+    RF_TXPLL_LOCK,
+    RF_SNIFFERPLLCP,
+    RF_SNIFFERPLL_LOCK,
+    RXBBF_CALDONE,
+    TXBBF_CALDONE,
+    RX_RFDC_CALDONE,
+    RX_ADCTUNER_CALDONE,
+    RX1_ADCPROFILE,
+    RX2_ADCPROFILE,
+    ORX_ADCPROFILE,
+    RCAL_CALDONE,
+    ARMBUSY,
+    INITARM_DONE
+} waitEvent_t;
+
+/**
+ *  \brief Enum to set the desired FIR filter type for related functions
+ */
+typedef enum
+{
+    TX1_FIR     = 1,
+    TX2_FIR     = 2,
+    TX1TX2_FIR  = 3,
+    RX1_FIR     = 4,
+    RX2_FIR     = 8,
+    RX1RX2_FIR  = 12,
+    OBSRX_A_FIR = 16,
+    OBSRX_B_FIR = 32
+} mykonosfirName_t;
+
+/**
+ *  \brief Enum to set the desired Rx gain table channel
+ */
+typedef enum
+{
+	RX1_GT  = 1,
+	RX2_GT,
+	RX1_RX2_GT,
+	ORX_GT,
+	SNRX_GT,
+	LOOPBACK_GT
+}mykonosGainTable_t;
+
+/**
+ *  \brief Enum to set the Rx Gain control mode
+ */
+typedef enum
+{
+    MGC     = 0,    /*!< Manual Gain Control */
+    AGC     = 2,   	/*!< Automatic Gain Control (AGC) */
+    HYBRID  = 3     /*!< Hybrid AGC Gain Control */
+
+} mykonosGainMode_t;
+
+/**
+ *  \brief Enum to set the Tx Atenuation step size
+ */
+typedef enum
+{
+    TXATTEN_0P05_DB = 0,    /*!< Tx attenuation 0.05dB step size */
+    TXATTEN_0P1_DB  = 1,    /*!< Tx attenuation 0.1dB step size */
+    TXATTEN_0P2_DB  = 2,    /*!< Tx attenuation 0.2dB step size */
+    TXATTEN_0P4_DB  = 3     /*!< Tx attenuation 0.4dB step size */
+} mykonosTxAttenStepSize_t;
+
+/**
+ *  \brief Enum to help set the init calibration mask
+ */
+typedef enum
+{
+    TX_BB_FILTER            = 0x0001,
+    ADC_TUNER               = 0x0002,
+    TIA_3DB_CORNER          = 0x0004,
+    DC_OFFSET               = 0x0008,
+    TX_ATTENUATION_DELAY    = 0x0010,
+    RX_GAIN_DELAY           = 0x0020,
+    FLASH_CAL               = 0x0040,
+    PATH_DELAY              = 0x0080,
+    TX_LO_LEAKAGE_INTERNAL  = 0x0100,
+    TX_LO_LEAKAGE_EXTERNAL  = 0x0200,
+    TX_QEC_INIT             = 0x0400,
+    LOOPBACK_RX_LO_DELAY    = 0x0800,
+    LOOPBACK_RX_RX_QEC_INIT = 0x1000,
+    RX_LO_DELAY             = 0x2000,
+    RX_QEC_INIT             = 0x4000,
+    DPD_INIT                = 0x8000,
+    CLGC_INIT               = 0x10000,
+    VSWR_INIT               = 0x20000
+} mykonosInitCalibrations_t;
+
+/**
+ *  \brief Enum to help set the tracking calibration mask
+ */
+typedef enum
+{
+    TRACK_RX1_QEC       = 0x00001,
+    TRACK_RX2_QEC       = 0x00002,
+    TRACK_ORX1_QEC      = 0x00004,
+    TRACK_ORX2_QEC      = 0x00008,
+    TRACK_TX1_LOL       = 0x00010,
+    TRACK_TX2_LOL       = 0x00020,
+    TRACK_TX1_QEC       = 0x00040,
+    TRACK_TX2_QEC       = 0x00080,
+    TRACK_TX1_DPD       = 0x00100,
+    TRACK_TX2_DPD       = 0x00200,
+    TRACK_TX1_CLGC      = 0x00400,
+    TRACK_TX2_CLGC      = 0x00800,
+    TRACK_TX1_VSWR      = 0x01000,
+    TRACK_TX2_VSWR      = 0x02000,
+    TRACK_ORX1_QEC_SNLO = 0x10000,
+    TRACK_ORX2_QEC_SNLO = 0x20000,
+    TRACK_SRX_QEC       = 0x40000
+} mykonosTrackingCalibrations_t;
+
+/**
+ *  \brief Enum to set the GPIO3v3 mode
+ */
+typedef enum
+{
+    GPIO3V3_LEVELTRANSLATE_MODE     = 1,    /*!< Level translate mode, signal level on low voltage GPIO output on GPIO3v3 pins */
+    GPIO3V3_INVLEVELTRANSLATE_MODE  = 2,    /*!< Inverted Level translate mode, inverse of signal level on low voltage GPIO output on GPIO3v3 pins */
+    GPIO3V3_BITBANG_MODE            = 3,    /*!< Manual mode, API function sets output pin levels and reads input pin levels */
+    GPIO3V3_EXTATTEN_LUT_MODE       = 4,    /*!< GPIO3v3 output level follows Rx1/Rx2 gain table external control 6bit field. */
+} mykonosGpio3v3Mode_t;
+
+/**
+ *  \brief Enum to set the low voltage GPIO mode
+ */
+typedef enum
+{
+    GPIO_MONITOR_MODE       = 0,    /*!< Allows a choice of debug signals to output from Mykonos to monitor the state of the device */
+    GPIO_BITBANG_MODE       = 3,    /*!< Manual mode, API function sets output pin levels and reads input pin levels */
+    GPIO_ARM_OUT_MODE       = 9,    /*!< Allows internal ARM processor to output on GPIO pins */
+    GPIO_SLICER_OUT_MODE    = 10    /*!< Allows Slicer active configuration to the GPIO output  pins */
+} mykonosGpioMode_t;
+
+/**
+ *  \brief Enum for ARM states
+ */
+typedef enum
+{
+    MYK_ARM_POWERUP         = 0x00,    /*!< ARM is powered up and ready to be programmed */
+    MYK_ARM_READY           = 0x01,    /*!< ARM enter this state once the boot up sequence is completed */
+    MYK_ARM_IDLE            = 0x02,    /*!< ARM enter this state after initial calibrations are completed */
+    MYK_ARM_RADIO_ON        = 0x03,    /*!< ARM has moved from MYKONOS_ARM_IDLE state into MYKONOS_ARM_RADIO_ON after the proper command, an abort command will move back to MYKONOS_ARM_IDLE state */
+    MYK_ARM_PROFILE_ERROR   = 0x04,    /*!< ARM has detected an illegal profile */
+    MYK_ARM_CAL_ERROR       = 0x40,    /*!< ARM has detected an error in the tracking calibrations */
+    MYK_ARM_EXCEPTION       = 0x80     /*!< ARM system problem has been detected */
+} mykonosArmState_t;
+
+/**
+ *  \brief Data structure to hold 3.3 VDC GPIO settings
+ */
+typedef struct
+{
+    uint16_t gpio3v3Oe;                         /*!< Pin direction: bit per 3.3v GPIO, 0=Input, 1=Output from Mykonos device */
+    mykonosGpio3v3Mode_t gpio3v3SrcCtrl3_0;     /*!< Mode for GPIO3v3[3:0] pins */
+    mykonosGpio3v3Mode_t gpio3v3SrcCtrl7_4;     /*!< Mode for GPIO3v3[7:4] pins */
+    mykonosGpio3v3Mode_t gpio3v3SrcCtrl11_8;    /*!< Mode for GPIO3v3[11:8] pins */
+} mykonosGpio3v3_t;
+
+/**
+ *  \brief Data structure to hold low voltage GPIO settings
+ */
+typedef struct
+{
+    uint32_t  gpioOe;                     /*!< Output Enable per low voltage GPIO pin (1=output, 0=input) */
+    mykonosGpioMode_t  gpioSrcCtrl3_0;    /*!< Mode for low voltage GPIO[3:0] pins */
+    mykonosGpioMode_t  gpioSrcCtrl7_4;    /*!< Mode for low voltage GPIO[7:4] pins */
+    mykonosGpioMode_t  gpioSrcCtrl11_8;   /*!< Mode for low voltage GPIO[11:8] pins */
+    mykonosGpioMode_t  gpioSrcCtrl15_12;  /*!< Mode for low voltage GPIO[15:12] pins */
+    mykonosGpioMode_t  gpioSrcCtrl18_16;  /*!< Mode for low voltage GPIO[18:16] pins */
+} mykonosGpioLowVoltage_t;
+
+/**
+ *  \brief Structure used within the DPD config structure to hold a int8_t complex number
+ */
+typedef struct{
+  int8_t real; /*!< real part of the complex number */
+  int8_t imag; /*!< imaginary part of the complex number */
+} int8_cpx;
+
+/**
+ *  \brief Structure to configure DPD (Only valid for AD9373 device)
+ *
+ *  This information is loaded into the ARM memory using the
+ *  MYKONOS_configDpd() function before running the DPD init or tracking
+ *  calibrations.  These values can only be changed when the ARM is in the
+ *  radioOff state.
+ */
+typedef struct
+{
+    uint8_t damping;                /*!< 1/2^(damping + 8) fraction of previous model 'forgotten' per adaptation (default: 5 = '1/8192' , valid 0 to 15), 0 = infinite damping */
+    uint8_t numWeights;             /*!< number of weights to use for int8_cpx weights weights member of this structure (default = 1) */
+    uint8_t modelVersion;           /*!< DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2) */
+    uint8_t highPowerModelUpdate;   /*!< 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS */
+    uint8_t modelPriorWeight;       /*!< Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20) */
+    uint8_t robustModeling;         /*!< Default off = 0, 1=enables automatic outlier removal during DPD modeling */
+    uint16_t samples;               /*!< number of samples to capture (default: 512, valid 64 - 32768) */
+    uint16_t outlierThreshold;      /*!< threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1) */
+    int16_t  additionalDelayOffset; /*!< 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64) */
+    uint16_t pathDelayPnSeqLevel;   /*!< Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191) */
+    int8_cpx weights[3];            /*!< DPD model error weighting (real/imag valid from -128 to 127) */
+} mykonosDpdConfig_t;
+
+/**
+ *  \brief Structure to configure CLGC (Closed Loop Gain Control) (Only valid for AD9373 device)
+ *
+ *  This information is loaded into the ARM memory using the
+ *  MYKONOS_configClgc() function before running the CLGC init or tracking
+ *  calibrations.  These values can only be changed when the ARM is in the
+ *  radioOff state.
+ */
+typedef struct
+{
+    int16_t tx1DesiredGain;         /*!< (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100) */
+    int16_t tx2DesiredGain;         /*!< (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100) */
+    uint16_t tx1AttenLimit;         /*!< (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit */
+    uint16_t tx2AttenLimit;         /*!< (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit */
+    uint16_t tx1ControlRatio;       /*!< valid range 1-100, default 45 */
+    uint16_t tx2ControlRatio;       /*!< valid range 1-100, default 45 */
+    uint8_t allowTx1AttenUpdates;   /*!< 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx1Atten automatically updated */
+    uint8_t allowTx2AttenUpdates;   /*!< 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx2Atten automatically updated */
+
+    int16_t  additionalDelayOffset; /*!< 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64) */
+    uint16_t pathDelayPnSeqLevel;   /*!< Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191) */
+} mykonosClgcConfig_t;
+
+typedef struct
+{
+    /* VSWR init cal parameters */
+    int16_t  additionalDelayOffset;     /*!< 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64) */
+    uint16_t pathDelayPnSeqLevel;       /*!< Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191) */
+
+    /* VSWR tracking cal parameters */
+    uint8_t tx1VswrSwitchGpio3p3Pin;    /*!< 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos) */
+    uint8_t tx2VswrSwitchGpio3p3Pin;    /*!< 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos) */
+    uint8_t tx1VswrSwitchPolarity;      /*!< 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level) */
+    uint8_t tx2VswrSwitchPolarity;      /*!< 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level) */
+    uint8_t tx1VswrSwitchDelay_ms;      /*!< Delay for Tx1 after flipping the VSWR switch until measurement is made. In ms resolution */
+    uint8_t tx2VswrSwitchDelay_ms;      /*!< Delay for Tx2 after flipping the VSWR switch until measurement is made. In ms resolution */
+} mykonosVswrConfig_t;
+
+typedef struct
+{
+    /**
+     * errorStatus(decimal) | Description
+     * ---------------------|-----------------------
+     *                  0   | NO ERROR (Tracking success)
+     *                  1   | Tx data path not enabled
+     *                  2   | ORX data path is not enabled
+     *                  3   | Loopback switch closed
+     *                  4   | VSWR init cal was not run
+     *                  5   | Path delay not setup
+     *                  6   | Data measurement was aborted
+     *                  7   | VSWR disabled
+     *                  8   | If set, entered cal but not finished
+     *                  9   | No GPIO configured in single ORx configuration
+     *                 10   | Tx is not observable with any of the ORx Channels
+     *                 11   | ORX_TRACKING_DISABLED  ORx tracking must be enabled
+     *
+     */
+    uint32_t errorStatus;
+    uint32_t trackCount;                /*!< Number of times VSWR tracking has run since last reset */
+    int32_t forwardGainRms_dB;          /*!< Forward RMS gain measured from Tx to ORx path (1 = 0.01 dB Gain) */
+    int32_t forwardGainReal;            /*!< Real part of the forward path complex gain (1 = 0.01 linear Gain) */
+    int32_t forwardGainImag;            /*!< Imaginary part of the forward path complex gain (1 = 0.01 linear Gain) */
+    int32_t reflectedGainRms_dB;        /*!< Measured reflection path gain in RMS (1 = 0.01 dB Gain) */
+    int32_t reflectedGainReal;          /*!< Real part of the reflection path complex gain (1 = 0.01 linear Gain) */
+    int32_t reflectedGainImag;          /*!< Imaginary part of the reflection path complex gain (1 = 0.01 linear Gain) */
+    int32_t vswr_forward_tx_rms;        /*!< Forward RMS measured from Tx path (1 = 0.01 dBFS) */
+    int32_t vswr_forward_orx_rms;       /*!< Forward RMS measured from ORx path (1 = 0.01 dBFS) */
+    int32_t vswr_reflection_tx_rms;     /*!< Reflected RMS measured from Tx path (1 = 0.01 dBFS) */
+    int32_t vswr_reflection_orx_rms;    /*!< Reflected RMS measured from ORx path (1 = 0.01 dBFS) */
+} mykonosVswrStatus_t;
+
+/**
+ *  \brief Data structure to hold Mykonos FIR filter settings
+ */
+typedef struct
+{
+    int8_t gain_dB;         /*!< Filter gain in dB*/
+    uint8_t numFirCoefs;    /*!< Number of coefficients in the FIR filter */
+    int16_t *coefs;         /*!< A pointer to an array of filter coefficients */
+} mykonosFir_t;
+
+/**
+ *  \brief Data structure to hold Mykonos JESD204b Framer configuration settings
+ */
+typedef struct
+{
+    uint8_t bankId; 					/*!< JESD204B Configuration Bank ID extension to Device ID. Range is 0..15 */
+    uint8_t deviceId; 					/*!< JESD204B Configuration Device ID link identification number. Range is 0..255 */
+    uint8_t lane0Id; 					/*!< JESD204B Configuration starting Lane ID. If more than one lane is used, each lane will increment from the Lane0 ID. Range is 0..31 */
+    uint8_t M; 							/*!< Number of ADCs (0, 2, or 4) where 2 ADCs are required per receive chain (I and Q) */
+    uint8_t K; 							/*!< Number of frames in a multiframe. Default = 32, F*K must be modulo 4. Where, F=2*M/numberOfLanes */
+    uint8_t scramble; 					/*!< Scrambling off if framerScramble = 0, if framerScramble > 0 scrambling is enabled */
+    uint8_t externalSysref; 			/*!< External SYSREF select. 0 = use internal SYSREF, 1 = use external SYSREF */
+    uint8_t serializerLanesEnabled; 	/*!< Serializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */
+    uint8_t serializerLaneCrossbar; 	/*!< Lane crossbar to map framer lane outputs to physical lanes */
+    uint8_t serializerAmplitude;  		/*!< Serializer amplitude setting. Default = 22. Range is 0..31 */
+    uint8_t preEmphasis; 				/*!< Serializer pre-emphasis setting. Default = 4 Range is 0..7 */
+    uint8_t invertLanePolarity;			/*!< Lane inversion select. Default = 0. Where, bit[0] = 0 will invert lane [0], bit[1] = 0 will invert lane 1, etc. */
+    uint8_t lmfcOffset;					/*!< LMFC offset value for deterministic latency setting.  Range is 0..31 */
+    uint8_t newSysrefOnRelink; 			/*!< Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set */
+    uint8_t enableAutoChanXbar; 		/*!< Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set */
+    uint8_t obsRxSyncbSelect; 			/*!< Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer */
+    uint8_t rxSyncbMode;                /*!< Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS */
+    uint8_t overSample;                 /*!< Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples) */
+} mykonosJesd204bFramerConfig_t;
+
+/* NO Doxygen content required for this data structure as this is used internally */
+/// @cond
+typedef struct
+{
+  uint8_t DID;                          /*!< JESD204B Configuration Device ID for ILAS check */
+  uint8_t BID;                          /*!< JESD204B Configuration Bank ID for ILAS check */
+  uint8_t LID0;                         /*!< JESD204B Configuration starting Lane ID for ILAS check */
+  uint8_t L;                            /*!< JESD204B Configuration L = lanes per data converter for ILAS check */
+  uint8_t SCR;                          /*!< JESD204B Configuration scramble setting for ILAS check */
+  uint8_t F;                            /*!< JESD204B Configuration F = octets per frame for ILAS check */
+  uint8_t K;                            /*!< JESD204B Configuration K = frames per multiframe for ILAS check */
+  uint8_t M;                            /*!< JESD204B Configuration M = number of data converters for ILAS check */
+  uint8_t N;                            /*!< JESD204B Configuration N = data converter sample resolution for ILAS check */
+  uint8_t CS;                           /*!< JESD204B Configuration CS = number of control bits transferred per sample per frame for ILAS check */
+  uint8_t NP;                           /*!< JESD204B Configuration NP = JESD204B word size based on the highest resolution of the data converter for ILAS check */
+  uint8_t S;                            /*!< JESD204B Configuration S = number of samples/data converter/frame for ILAS check */
+  uint8_t CF;                           /*!< JESD204B Configuration CF = '0' = control bits appended to each sample, '1' = appended to end of frame for ILAS check */
+  uint8_t HD;                           /*!< JESD204B Configuration HD = high density bit - samples are contained within lane (0) or divided over more than one lane (1) for ILAS check */
+  uint8_t FCHK0;                        /*!< JESD204B Configuration checksum for ILAS check */
+} mykonosJesd204bLane0Config_t;
+/// @endcond
+
+/**
+* \brief Data structure to hold the settings for the deserializer and deframer configuration
+*
+* EQ Settings | 3GHz Loss (dB) |6GHz Loss (dB) | max FR408HR Length (in) | max FR4 Length (in)
+*-------------|----------------|---------------|-------------------------|---------------------
+*           0 |      6.5       |      14       |            20           |       12
+*           1 |     11.5       |      21       |            30           |       20
+*           2 |     18         |      31       |            46           |       32
+*           3 |     21.5       |      38       |            56           |       40
+*           4 |     22         |      39       |            60           |       43
+*/
+typedef struct
+{
+    uint8_t bankId; 					/*!< Extension to Device ID. Range is 0..15 */
+    uint8_t deviceId; 					/*!< Link identification number. Range is 0..255 */
+    uint8_t lane0Id; 					/*!< Lane0 ID. Range is 0..31 */
+    uint8_t M; 							/*!< Number of DACs (0, 2, or 4) - 2 DACs per transmit chain (I and Q) */
+    uint8_t K; 							/*!< Number of frames in a multiframe. Default = 32, F*K = modulo 4. Where, F=2*M/numberOfLanes */
+    uint8_t scramble; 					/*!< Scrambling off if scramble = 0, if framerScramble > 0 scrambling is enabled */
+    uint8_t externalSysref; 			/*!< External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF */
+    uint8_t deserializerLanesEnabled; 	/*!< Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */
+    uint8_t deserializerLaneCrossbar;	/*!< Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc  */
+    uint8_t EQSetting; 					/*!< Equalizer setting. Applied to all deserializer lanes. Range is 0..4 */
+    uint8_t invertLanePolarity;			/*!< PN inversion per each lane.  bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc */
+    uint8_t lmfcOffset;					/*!< LMFC offset value to adjust deterministic latency. Range is 0..31 */
+    uint8_t newSysrefOnRelink;			/*!< Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set */
+    uint8_t enableAutoChanXbar;			/*!< Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set */
+    uint8_t txSyncbMode;                /*!< Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS */
+} mykonosJesd204bDeframerConfig_t;
+
+/**
+ *  \brief Data structure to hold settings for the current Rx specific use case profile
+ */
+typedef struct
+{
+    uint8_t  adcDiv;                /*!< The divider used to generate the ADC clock (Valid: 1,2) */
+    mykonosFir_t *rxFir;			/*!< Pointer to Rx FIR filter structure */
+    uint8_t rxFirDecimation;        /*!< Rx FIR decimation (1,2,4) */
+    uint8_t rxDec5Decimation;       /*!< Decimation of Dec5 or Dec4 filter (5,4) */
+    uint8_t enHighRejDec5;          /*!< If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter. Where, 1 = enabled, 0 = disabled */
+    uint8_t rhb1Decimation;         /*!< RX Halfband1 (HB1) decimation. Can be either 1 or 2 */
+    uint32_t iqRate_kHz;		    /*!< Rx IQ data rate in kHz */
+    uint32_t rfBandwidth_Hz;        /*!< Rx RF passband bandwidth for the profile */
+    uint32_t rxBbf3dBCorner_kHz;	/*!< Rx BBF (TIA) 3dB corner in kHz */
+    uint16_t *customAdcProfile;     /*!< Custom ADC profile to set the bandwidth of the ADC response */
+} mykonosRxProfile_t;
+
+/**
+ *  \brief Data structure to hold settings for the current Tx specific use case profile
+ */
+typedef struct
+{
+    mykonosDacDiv_t dacDiv;             /*!< The divider used to generate the DAC clock (ENUM Values)*/
+    mykonosFir_t *txFir;                /*!< Pointer to Tx FIR filter structure */
+    uint8_t  txFirInterpolation;        /*!< The TX digital FIR filter interpolation (1,2,4) */
+    uint8_t  thb1Interpolation;         /*!< Tx Halfband1 (HB1) filter interpolation (1,2) */
+    uint8_t  thb2Interpolation;         /*!< Tx Halfband2 (HB2) filter interpolation (1,2) */
+    uint8_t txInputHbInterpolation;     /*!< Interpolation of half band filter before the programmable FIR (valid 1,2,4) */
+    uint32_t iqRate_kHz;                /*!< Tx IQ data rate in kHz */
+    uint32_t primarySigBandwidth_Hz;    /*!< Tx primary signal BW */
+    uint32_t rfBandwidth_Hz;            /*!< Tx RF passband bandwidth for the profile */
+    uint32_t txDac3dBCorner_kHz;        /*!< DAC filter 3dB corner in kHz */
+    uint32_t txBbf3dBCorner_kHz;        /*!< Tx BBF 3dB corner in kHz */
+    uint8_t enableDpdDataPath;          /*!< Enable Tx Dynamic pre distortion - only valid for AD9373 device */
+} mykonosTxProfile_t;
+
+/**
+ *  \brief Data structure to hold SnRx gain control settings for initialization and during use
+ */
+typedef struct
+{
+	mykonosGainMode_t gainMode; /*!< Current Sniffer gain control mode setting */
+    uint8_t gainIndex;          /*!< Current Sniffer gain index. Can be used differently for Manual Gain control/AGC */
+    uint8_t maxGainIndex;       /*!< Max gain index for the currently loaded Sniffer Gain table */
+    uint8_t minGainIndex;       /*!< Min gain index for the currently loaded Sniffer Gain table */
+} mykonosSnifferGainControl_t;
+
+/**
+ *  \brief Data structure to hold ORx gain control settings for initialization and during use
+ */
+typedef struct
+{
+	mykonosGainMode_t gainMode; /*!< Current ORx gain control mode setting */
+    uint8_t orx1GainIndex;      /*!< ORx1 Gain Index, can be used in different ways for manual and AGC gain control */
+    uint8_t orx2GainIndex;      /*!< ORx2 Gain Index, can be used in different ways for manual and AGC gain control */
+    uint8_t maxGainIndex;       /*!< Max gain index for the currently loaded ORx Gain table */
+    uint8_t minGainIndex;       /*!< Min gain index for the currently loaded ORx Gain table */
+} mykonosORxGainControl_t;
+
+/**
+ *  \brief Data structure to hold Rx gain control settings for initialization and during use
+ */
+typedef struct
+{
+	mykonosGainMode_t gainMode; /*!< Current Rx gain control mode setting */
+    uint8_t rx1GainIndex;       /*!< Rx1 Gain Index, can be used in different ways for manual and AGC gain control */
+    uint8_t rx2GainIndex;       /*!< Rx2 Gain Index, can be used in different ways for manual and AGC gain control */
+    uint8_t rx1MaxGainIndex;    /*!< Max gain index for the currently loaded Rx1 Gain table */
+    uint8_t rx1MinGainIndex;    /*!< Min gain index for the currently loaded Rx1 Gain table */
+    uint8_t rx2MaxGainIndex;    /*!< Max gain index for the currently loaded Rx2 Gain table */
+    uint8_t rx2MinGainIndex;    /*!< Min gain index for the currently loaded Rx2 Gain table */
+    uint8_t rx1Rssi;            /*!< Stores Rx1 RSSI value read back from the Mykonos */
+    uint8_t rx2Rssi;            /*!< Stores Rx2 RSSI value read back from the Mykonos */
+} mykonosRxGainControl_t;
+
+/**
+ *  \brief Data structure to hold peak detector settings for the AGC
+ */
+typedef struct
+{
+	/* Threshold Settings */
+	uint8_t apdHighThresh; 		/*!< APD high threshold. Must be greater than apdLowThresh. Min = apdLowThresh, Max = 0x3F. 6-bit field. */
+	uint8_t apdLowThresh; 		/*!< APD low threshold. Must be less than apdHighThresh. Min = 0, Max = apdHighThresh. 6-bit field. */
+	uint8_t hb2HighThresh; 		/*!< HB2 high threshold. Must be greater than hb2LowThresh. Min = hb2LowThresh, Max = 0xFF. 8-bit field.  */
+	uint8_t hb2LowThresh; 		/*!< HB2 low threshold. Must be less than hb2HighThresh. Min = 0, Max = hb2HighThresh. 8-bit field.  */
+	uint8_t hb2VeryLowThresh; 	/*!< HB2 very low threshold. Must be less than hb2LowThresh. Min = 0, Max = hb2LowThresh. 8-bit field.  */
+
+	/* Threshold Counter Settings */
+	uint8_t apdHighThreshExceededCnt; 		/*!< APD high threshold exceeded counter. Sets number of peaks to detect above apdHighThresh to cause gain decrement according to apdHighGainStepAttack. 8-bit field. */
+	uint8_t apdLowThreshExceededCnt; 		/*!< APD low threshold exceeded counter. Sets number of peaks to detect below apdLowThresh to cause gain increment according to apdLowGainStepRecovery. 8-bit field. */
+	uint8_t hb2HighThreshExceededCnt; 		/*!< HB2 high threshold exceeded counter. Sets number of overloads to detect above hb2HighThresh to cause gain decrement according to hb2HighGainStepAttack. 8-bit field. */
+	uint8_t hb2LowThreshExceededCnt; 		/*!< HB2 low threshold exceeded counter. Sets number of peaks to detect below hb2LowThresh to cause gain increment according to hb2LowGainStepRecovery. 8-bit field. */
+	uint8_t hb2VeryLowThreshExceededCnt; 	/*!< HB2 very low threshold exceeded counter. Sets number of peaks to detect below hb2VeryLowThresh to cause gain increment according to hb2VeryLowGainStepRecovery. 8-bit field. */
+
+	/* Gain Step Settings */
+	uint8_t apdHighGainStepAttack; 		/*!< Number of gain indices to decrement gain when apdHighThreshExceededCnt is exceeded. 5-bit field. */
+	uint8_t apdLowGainStepRecovery; 	/*!< Number of gain indices to increment gain when apdLowThreshExceededCnt is exceeded. 5-bit field */
+	uint8_t hb2HighGainStepAttack; 		/*!< Number of gain indices to decrement gain when hb2HighThreshExceededCnt is exceeded. 5-bit field */
+	uint8_t hb2LowGainStepRecovery; 	/*!< Number of gain indices to increment gain when hb2LowThreshExceededCnt is exceeded. 5-bit field*/
+	uint8_t hb2VeryLowGainStepRecovery; /*!< Number of gain indices to increment gain when hb2VeryLowThreshExceededCnt is exceeded. 5-bit field */
+
+	/* Fast Attack Settings */
+	uint8_t apdFastAttack; 		/*!< [1] Enables APD fast attack mode - gain decrements immediately when apdHighThreshExceededCnt is exceeded. [0] disables APD fast attack mode - gain decrements at the expiry of agcGainUpdateCounter. 1-bit field. */
+	uint8_t hb2FastAttack; 		/*!< [1] Enables HB2 fast attack mode - gain decrements immediately when hb2HighThreshExceededCnt is exceeded. [0] disables HB2 fast attack mode - gain decrements at the expiry of agcGainUpdateCounter. 1-bit field. */
+
+	/* HB2 Configuration Settings */
+	uint8_t hb2OverloadDetectEnable; 	/*!< [1] Enables the HB2 overload detector. [0] Disables the HB2 overload detector. 1-bit field. */
+	uint8_t hb2OverloadDurationCnt; 	/*!< Sets the samples size window of the HB2 overload detector. If hb2OverloadThreshCnt number of overloads are detected, the hb2xxxThreshExceededCnt increments. 3-bit field. [001]=1, [001]=4, [010]=8, [011]=12, [100]=16, [101]=24, [110]=32, [111]=INVALID */
+	uint8_t hb2OverloadThreshCnt; 		/*!< Sets the number of individual overloads necessary within hb2OverloadDurationCnt samples to increment the hb2xxxThreshExceededCnt */
+} mykonosPeakDetAgcCfg_t;
+
+/**
+ *  \brief Data structure to hold power measurement settings for the AGC
+ */
+typedef struct
+{
+	/* Threshold Settings */
+	uint8_t pmdUpperHighThresh; 	/*!< Power measurement upper band, high threshold . This value is a positive offset to the pmdUpperLowThresh threshold. 4-bit field */
+	uint8_t pmdUpperLowThresh; 		/*!< Power measurement upper band, low threshold. This value sets the threshold in (negative) -dBFS. Byte value must be less than pmdLowerHighThresh. 7-bit field */
+	uint8_t pmdLowerHighThresh; 	/*!< Power measurement lower band, high threshold. This value sets the threshold in (negative) -dBFS. Byte value must be greater than pmdUpperLowThresh. 7-bit field */
+	uint8_t pmdLowerLowThresh; 		/*!< Power measurement lower band, low threshold. This value is a negative offset to the pmdLowerHighThresh threshold. 4-bit field */
+
+	/* Gain Step Settings */
+	uint8_t pmdUpperHighGainStepAttack; 	/*!< Number of gain indices to decrement gain if pmdUpperHighThresh is exceeded by the end of the agcGainUpdateCounter. 5-bit field */
+	uint8_t pmdUpperLowGainStepAttack; 		/*!< Number of gain indices to decrement gain if pmdUpperLowThresh is exceeded by the end of the agcGainUpdateCounter. 5-bit field */
+	uint8_t pmdLowerHighGainStepRecovery; 	/*!< Number of gain indices to increment gain if pmdLowerHighThresh is not exceeded by the end of the agcGainUpdateCounter. 5-bit field */
+	uint8_t pmdLowerLowGainStepRecovery; 	/*!< Number of gain indices to increment gain if pmdLowerLowThresh is not exceeded by the end of the agcGainUpdateCounter. 5-bit field */
+
+	/* PMD Configuration Settings */
+	uint8_t pmdMeasDuration; 	/*!< Number of samples to measure power on. The number of samples corresponding to the 4-bit word is 8*2^(pmdMeasDuration[3:0]). This value must be less than agcGainUpdateCounter */
+	uint8_t pmdMeasConfig; 		/*!< Power measurement configuration. 2-bit field. [00]=PMD disabled, [01]=PMD Enabled at HB2 output, [10]=Enabled at RFIR output (recommended), [11]=PMD Enabled at BBDC2 */
+} mykonosPowerMeasAgcCfg_t;
+
+/**
+ *  \brief Data structure to hold general AGC settings for initialization and during use
+ */
+typedef struct
+{
+	/* Gain Table Settings */
+	uint8_t agcRx1MaxGainIndex;			/*!< Maximum Rx1 gain index allowed in AGC mode. Must be greater than agcRx1MinGainIndex and valid gain index. 8-bit field */
+	uint8_t agcRx1MinGainIndex;			/*!< Minimum Rx1 gain index allowed in AGC mode. Must be less than agcRx1MinGainIndex and valid gain index. 8-bit field */
+	uint8_t agcRx2MaxGainIndex;			/*!< Maximum Rx2 gain index allowed in AGC mode. Must be greater than agcRx2MinGainIndex and valid gain index. 8-bit field */
+	uint8_t agcRx2MinGainIndex;			/*!< Minimum Rx2 gain index allowed in AGC mode. Must be less than agcRx2MinGainIndex and valid gain index. 8-bit field */
+	uint8_t agcObsRxMaxGainIndex;		/*!< Maximum ObsRx gain index allowed in AGC mode. Must be greater than agcObsRxMinGainIndex and valid gain index. 8-bit field */
+	uint8_t agcObsRxMinGainIndex;		/*!< Minimum ObsRx gain index allowed in AGC mode. Must be less than agcObsRxMaxGainIndex and valid gain index. 8-bit field */
+	uint8_t agcObsRxSelect; 			/*!< Sniffer or ObsRx AGC channel select. [1] = SnRx */
+
+	/* AGC Mode Selection */
+	uint8_t agcPeakThresholdMode; /*!< [1] = Peak Threshold Mode, power based gain changes are disabled. [0] = Peak and overload detectors are ignored for gain changes */
+	uint8_t agcLowThsPreventGainIncrease; /*!< [1] PMD based gain increments are ignored if apd/hb2LowThreshExceedCnt is high [0] apdLowThreshExceededCnt and hb2LowThreshExceededCnt are "Don't cares" to the AGC gain recovery */
+
+	/* AGC General Settings */
+	uint32_t agcGainUpdateCounter;		/*!< Number of samples for the AGC gain update counter. Counter operates on the IQ data rate. 22-bit field. Min = 0x000001, Max = 0x3FFFFF  */
+	uint8_t agcSlowLoopSettlingDelay;	/*!< Number of IQ data rate clock cycles to wait after a gain change before peak/power measurements resume. 7-bit field */
+	uint8_t agcPeakWaitTime;			/*!< Number of IQ data rate clock cycles to wait to enable peak/overload detectors after AGC is enabled. 5-bit field. Min = 0x02. Max = 0x1F */
+	uint8_t agcResetOnRxEnable;			/*!< [1] = Performs a reset of the AGC slow loop state machine when Rx is disabled. [0] = AGC slow loop state machine maintains its state when Rx is disabled. */
+	uint8_t	agcEnableSyncPulseForGainCounter; /*!< [1] = Allows sync of agcGainUpdateCounter to the time-slot boundary. GPIO setup required. [0] = agcGainUpdateCounter functions as normal */
+
+	mykonosPeakDetAgcCfg_t *peakAgc;    /*!< pointer to structure for Peak AGC */
+	mykonosPowerMeasAgcCfg_t *powerAgc; /*!< pointer to structure for Power AGC */
+} mykonosAgcCfg_t;
+
+/**
+ *  \brief Data structure to hold Tx data path settings
+ */
+typedef struct
+{
+    mykonosTxProfile_t *txProfile;              /*!< Tx datapath profile, 3dB corner frequencies, and digital filter enables */
+    mykonosJesd204bDeframerConfig_t *deframer;  /*!< Mykonos JESD204b deframer config for the Tx data path */
+    mykonosTxChannels_t txChannels;             /*!< The desired Tx channels to enable during initialization */
+    uint8_t txPllUseExternalLo;                 /*!< Internal LO=0, external LO*2 if =1 */
+    uint64_t txPllLoFrequency_Hz;               /*!< Tx PLL LO frequency (internal or external LO) */
+    mykonosTxAttenStepSize_t txAttenStepSize;   /*!< Tx Attenuation step size */
+    uint16_t tx1Atten_mdB;                      /*!< Initial and current Tx1 Attenuation */
+    uint16_t tx2Atten_mdB;                      /*!< Initial and current Tx2 Attenuation */
+    mykonosDpdConfig_t *dpdConfig;              /*!< DPD settings. Only valid for AD9373 device, set pointer to NULL otherwise */
+    mykonosClgcConfig_t *clgcConfig;            /*!< CLGC settings. Only valid for AD9373 device, set pointer to NULL otherwise */
+    mykonosVswrConfig_t *vswrConfig;            /*!< VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise */
+} mykonosTxSettings_t;
+
+/**
+ *  \brief Data structure to hold Rx data path settings
+ */
+typedef struct
+{
+    mykonosRxProfile_t *rxProfile;          /*!< Rx datapath profile, 3dB corner frequencies, and digital filter enables */
+    mykonosJesd204bFramerConfig_t *framer;  /*!< Rx JESD204b framer configuration structure */
+    mykonosRxGainControl_t *rxGainCtrl;     /*!< Rx Gain control settings structure */
+    mykonosAgcCfg_t *rxAgcCtrl;				/*!< Rx AGC control settings structure */
+    mykonosRxChannels_t rxChannels;         /*!< The desired Rx Channels to enable during initialization */
+    uint8_t rxPllUseExternalLo;             /*!< Internal LO = 0, external LO*2 = 1 */
+    uint64_t rxPllLoFrequency_Hz;           /*!< Rx PLL LO Frequency (internal or external LO) */
+    uint8_t realIfData; 			        /*!< Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/
+} mykonosRxSettings_t;
+
+/**
+ *  \brief Data structure to hold ORx data path settings
+ */
+typedef struct
+{
+    mykonosRxProfile_t *orxProfile;         	    /*!< ORx datapath profile, 3dB corner frequencies, and digital filter enables. */
+    mykonosORxGainControl_t *orxGainCtrl;		    /*!< ObsRx gain control settings structure */
+    mykonosAgcCfg_t *orxAgcCtrl;				    /*!< ORx AGC control settings structure */
+    mykonosRxProfile_t *snifferProfile;     	    /*!< Sniffer datapath profile, 3dB corner frequencies, and digital filter enables. */
+    mykonosSnifferGainControl_t *snifferGainCtrl;	/*!< SnRx gain control settings structure */
+    mykonosJesd204bFramerConfig_t *framer;  	    /*!< ObsRx JESD204b framer configuration structure */
+    mykonosObsRxChannelsEn_t obsRxChannelsEnable;   /*!< The desired ObsRx channels to configure/calibrate during initialization */
+    mykonosObsRxLoSource_t obsRxLoSource;   	    /*!< The sniffer/ORx mixers can use the TX_PLL or SNIFFER_PLL */
+    uint64_t snifferPllLoFrequency_Hz;              /*!< SnRx PLL LO frequency in Hz */
+    uint8_t realIfData; 						    /*!< Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data */
+    uint16_t *customLoopbackAdcProfile;             /*!< Custom Loopback ADC profile to set the bandwidth of the ADC response */
+    mykonosObsRxChannels_t defaultObsRxChannel;     /*!< Default ObsRx channel to enter when radioOn called */
+} mykonosObsRxSettings_t;
+
+
+/**
+ * \brief Data structure to hold ARM GPIO pin assignments for each ARM input/output pin.
+ */
+typedef struct
+{
+    uint8_t useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */
+    uint8_t useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */
+    uint8_t txRxPinMode;     /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */
+    uint8_t orxPinMode;      /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/
+
+    /* Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */
+    uint8_t orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */
+    uint8_t orxMode2Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+    uint8_t orxMode1Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+    uint8_t orxMode0Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+
+    /* Mykonos ARM output GPIO pins  --  always available, even when pin mode not enabled*/
+    uint8_t rx1EnableAck;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t rx2EnableAck;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t tx1EnableAck;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t tx2EnableAck;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t orx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t orx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t srxEnableAck;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    uint8_t txObsSelect;    /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+                            /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is   */
+                            /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input */
+} mykonosArmGpioConfig_t;
+
+/**
+ * \brief Data structure to hold auxiliary IO settings (AuxDAC, ARM GPIO, GPIO3.3v, low voltage GPIO, HSCP, etc)
+ */
+typedef struct
+{
+    uint16_t auxDacEnable;           /*!< Aux DAC enable. One bit per Aux DAC. Where bit[0] = Aux DAC 0, bit[1] = Aux DAC 1, etc */
+    uint16_t auxDacValue[10];        /*!< Aux DAC value */
+    uint8_t  auxDacSlope[10];        /*!< Aux DAC slope */
+    uint8_t  auxDacVref[10];         /*!< Aux DAC voltage reference value */
+
+    mykonosGpio3v3_t *gpio3v3;       /*!< GPIO 3.3 VDC settings data structure pointer */
+    mykonosGpioLowVoltage_t *gpio;   /*!< Low voltage GPIO settings data structure pointer */
+    mykonosArmGpioConfig_t *armGpio; /*!< Mykonos ARM GPIO settings*/
+} mykonosAuxIo_t;
+
+/**
+ *  \brief Data structure to hold digital clock settings
+ */
+typedef struct
+{
+    uint32_t deviceClock_kHz;       /*!< CLKPLL and device reference clock frequency in kHz */
+    uint32_t clkPllVcoFreq_kHz;     /*!< CLKPLL VCO frequency in kHz */
+    mykonosVcoDiv_t  clkPllVcoDiv;  /*!< CLKPLL VCO divider */
+    uint8_t  clkPllHsDiv;           /*!< CLKPLL high speed clock divider */
+} mykonosDigClocks_t;
+
+
+/**
+ *  \brief Data structure used to read back the Init Calibration Status
+ */
+typedef struct
+{
+    uint32_t calsDoneLastRun;   /*!< Init cals that completed in the last call to MYKONOS_runInitCals() */
+    uint32_t calsDoneLifetime;  /*!< Init cals that have completed successfully since loading of the ARM processor */
+    uint32_t calsMinimum;       /*!< Minimum set of init cals that must complete before device can move to radioOn state */
+    uint8_t initErrCal;         /*!< If an init cal had an error, this represents the opcode of the init cal that reported an error */
+    uint8_t initErrCode;        /*!< If an init cal had an error, this represents the ARM error code describing the failure */
+} mykonosInitCalStatus_t;
+
+/**
+ *  \brief Data structure used to read back DPD calibration status
+ */
+typedef struct
+{
+    /**
+     *  dpdErrorStatus (decimal) | Description
+     * --------------------------|-----------------------
+     *                       0   | No Error
+     *                       1   | ORX_DISABLED
+     *                       2   | TX_DISABLED
+     *                       3   | PATHDELAY_NOT_SETUP
+     *                       4   | DPD_INIT_NOT_RUN
+     *                       5   | ORX_SIG_TOO_LOW
+     *                       6   | ORX_SIG_SATURATED
+     *                       7   | TX_SIG_TOO_LOW
+     *                       8   | TX_SIG_SATURATED
+     *                       9   | MODEL_ERROR_HIGH
+     *                      10   | AM_AM_OUTLIERS
+     *                      11   | INVALID_TX_PROFILE
+     *                      12   | ORX_TRACKING_DISABLED ORx tracking must be enabled
+     *                      13   | Cal suspended
+     *                      14   | Reserved
+     *                      15   | Reserved
+     *                      16   | Reserved
+     *                      17   | Reserved
+     *                      18   | Reserved
+     */
+    uint32_t dpdErrorStatus;
+    uint32_t dpdTrackCount;         /*!< Number of times DPD tracking has run since last reset */
+    uint32_t dpdModelErrorPercent;  /*!< Percent Error of PA model * 10 to include 1 decimal place */
+    uint32_t dpdExtPathDelay;       /*!< External path delay from Tx output to ORx input, at 1/16 sample resolution of ORx sample rate */
+} mykonosDpdStatus_t;
+
+/**
+ *  \brief Data structure used to read back CLGC calibration status
+ */
+typedef struct
+{
+    /**
+     * clgcErrorStatus(decimal) | Description
+     * -------------------------|-----------------------
+     *                      0   | NO ERROR
+     *                      1   | TX Disabled
+     *                      2   | ORx is disabled
+     *                      3   | Loopback switch is clo
+     *                      4   | Data measurement aborted during capture
+     *                      5   | No initial calibration was done
+     *                      6   | Path delay not setup
+     *                      7   | No apply control is possible
+     *                      8   | Control value is out of range
+     *                      9   | CLGC feature is disabled
+     *                     10   | TX attenuation is capped
+     *                     11   | Gain measurement
+     *                     12   | No GPIO configured in single ORx configuration
+     *                     13   | Tx is not observable with any of the ORx Channels
+     *                     14   | ORX_TRACKING_DISABLED  ORx tracking must be enabled
+     *                     15   | Cal suspended
+     *                     16   | RESERVED
+     *                     17   | RESERVED
+     *                     18   | RESERVED
+     *                     19   | RESERVED
+     */
+    uint32_t errorStatus;
+    uint32_t trackCount;      /*!< Number of times CLGC tracking has run since last reset */
+    int32_t desiredGain;      /*!< Desired gain/attenuation from Tx output to ORx input of Mykonos device. 0.01 dB resolution */
+    int32_t currentGain;      /*!< Current measured gain in 0.01 dB resolution. */
+    uint32_t txGain;          /*!< Current TxAttenuation setting, same as MYKONOS_getTx1/2Attenuation(), in 0.05dB resolution */
+    int32_t txRms;            /*!< Tx digital sample power measured at DPD block input (0.01 dB resolution) */
+    int32_t orxRms;           /*!< ORx digital sample power measured at ORx port (0.01 dB resolution) */
+} mykonosClgcStatus_t;
+
+/**
+ * \brief Data structure to hold Tx LOL Status
+ */
+typedef struct
+{
+    uint32_t errorCode;         /*!< error code from Tx LOL */
+    uint32_t percentComplete;   /*!< percent of required data collected for the current cal. Range 0 to 100 */
+    uint32_t performanceMetric; /*!< Variance of the corrections, and gives an indication in dB on how much LO leakage is corrected on an average tracking pass.  */
+    uint32_t iterCount;         /*!< running counter that increments each time the cal runs to completion */
+    uint32_t updateCount;       /*!< running counter that increments each time the cal updates the correction/actuator hardware */
+} mykonosTxLolStatus_t;
+
+/**
+ * \brief Data structure to hold Tx QEC Status
+ */
+typedef struct
+{
+    uint32_t errorCode;         /*!< error code from Tx QEC */
+    uint32_t percentComplete;   /*!< percent of required data collected for the current cal. Range 0 to 100 */
+    uint32_t performanceMetric; /*!< Number of codes adjusted which is the number of codes of correction made last time which can be converted to an IRR power metric as with Rx QEC, if desired. */
+    uint32_t iterCount;         /*!< running counter that increments each time the cal runs to completion */
+    uint32_t updateCount;       /*!< running counter that increments each time the cal updates the correction/actuator hardware */
+} mykonosTxQecStatus_t;
+
+/**
+ * \brief Data structure to hold Rx QEC Status
+ */
+typedef struct
+{
+    uint32_t errorCode;         /*!< error code from Rx QEC */
+    uint32_t percentComplete;   /*!< percent of required data collected for the current cal. Range 0 to 100 */
+    uint32_t selfcheckIrrDb;    /*!< selfCheckIrrdDb - Power-weighted average Image Rejection Ratio (IRR) in dBc. */
+    uint32_t iterCount;         /*!< running counter that increments each time the cal runs to completion */
+    uint32_t updateCount;       /*!< running counter that increments each time the cal updates the correction/actuator hardware */
+} mykonosRxQecStatus_t;
+
+/**
+ * \brief Data structure to hold Orx QEC Status
+ */
+typedef struct
+{
+    uint32_t errorCode;         /*!< error code from Orx QEC */
+    uint32_t percentComplete;   /*!< percent of required data collected for the current cal. Range 0 to 100 */
+    uint32_t selfcheckIrrDb;    /*!< selfCheckIrrdDb - Power-weighted average Image Rejection Ratio (IRR) in dBc. */
+    uint32_t iterCount;         /*!< running counter that increments each time the cal runs to completion */
+    uint32_t updateCount;       /*!< running counter that increments each time the cal updates the correction/actuator hardware */
+} mykonosOrxQecStatus_t;
+
+/**
+ * \brief Data structure to hold Mykonos device settings
+ */
+typedef struct
+{
+    spiSettings_t          *spiSettings;    /*!< SPI settings data structure pointer */
+    mykonosRxSettings_t    *rx;             /*!< Rx settings data structure pointer */
+    mykonosTxSettings_t    *tx;             /*!< Tx settings data structure pointer */
+    mykonosObsRxSettings_t *obsRx;          /*!< ObsRx settings data structure pointer */
+    mykonosAuxIo_t         *auxIo;          /*!< Auxiliary IO settings data structure pointer */
+    mykonosDigClocks_t     *clocks;         /*!< Holds settings for CLKPLL and reference clock */
+    uint8_t                 profilesValid;  /*!< Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */
+} mykonosDevice_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mpm/lib/mykonos/adi/t_mykonos_gpio.h b/mpm/lib/mykonos/adi/t_mykonos_gpio.h
new file mode 100644
index 000000000..e7ad26e34
--- /dev/null
+++ b/mpm/lib/mykonos/adi/t_mykonos_gpio.h
@@ -0,0 +1,366 @@
+/*!
+ * \file t_mykonos_gpio.h
+ * \brief Mykonos GPIO error handling and type defines
+ *
+ * Mykonos API version: 1.3.1.3534
+ */
+
+#ifndef T_MYKONOSGPIO_H_
+#define T_MYKONOSGPIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "common.h"
+
+/**
+ *  \brief Enum of unique error codes from the Mykonos GPIO API functions.
+ * Each error condition in the library should get its own enum value to allow
+ * easy debug of errors.
+ */
+typedef enum
+{
+	MYKONOS_ERR_GPIO_OK = 0,
+	MYKONOS_ERR_EN_MONITOR_OUT_NOT_ENABLED,
+    MYKONOS_ERR_EN_MONITOR_OUT_SRC_CTRL,
+    MYKONOS_ERR_MONITOR_OUT_INDEX_RANGE,
+    MYKONOS_ERR_GETGPIOMON_INDEX_NULL_PARM,
+    MYKONOS_ERR_GETGPIOMON_MONITORMASK_NULL_PARM,
+
+    MYKONOS_ERR_MGCRX2_GPIO_DECPIN_INV_PARAM,
+    MYKONOS_ERR_MGCRX2_GPIO_INCPIN_INV_PARAM,
+    MYKONOS_ERR_MGCRX2_SOURCE_CONFIG,
+    MYKONOS_ERR_MGCRX2_STEP_INV_PARAM,
+    MYKONOS_ERR_MGCRX1_GPIO_DECPIN_INV_PARAM,
+    MYKONOS_ERR_MGCRX1_GPIO_INCPIN_INV_PARAM,
+    MYKONOS_ERR_MGCRX1_STEP_INV_PARAM,
+    MYKONOS_ERR_GETRX2PIN_INCSTEP_NULL_PARM,
+    MYKONOS_ERR_GETRX2PIN_DECSTEP_NULL_PARM,
+    MYKONOS_ERR_GETRX2PIN_INCPIN_NULL_PARM,
+    MYKONOS_ERR_GETRX2PIN_DECPIN_NULL_PARM,
+    MYKONOS_ERR_GETRX2PIN_EN_NULL_PARM,
+    MYKONOS_ERR_GETRX1PIN_INCSTEP_NULL_PARM,
+    MYKONOS_ERR_GETRX1PIN_DECSTEP_NULL_PARM,
+    MYKONOS_ERR_GETRX1PIN_INCPIN_NULL_PARM,
+    MYKONOS_ERR_GETRX1PIN_DECPIN_NULL_PARM,
+    MYKONOS_ERR_GETRX1PIN_EN_NULL_PARM,
+
+    MYKONOS_ERR_TPCTX2_GPIO_DECPIN_INV_PARAM,
+    MYKONOS_ERR_TPCTX2_GPIO_INCPIN_INV_PARAM,
+    MYKONOS_ERR_TPCTX2_GPIO_STEP_INV_PARAM,
+    MYKONOS_ERR_TPCTX1_GPIO_DECPIN_INV_PARAM,
+    MYKONOS_ERR_TPCTX1_GPIO_INCPIN_INV_PARAM,
+    MYKONOS_ERR_TPCTX1_GPIO_STEP_INV_PARAM,
+    MYKONOS_ERR_GETTX2PIN_STEP_NULL_PARM,
+    MYKONOS_ERR_GETTX2PIN_INC_NULL_PARM,
+    MYKONOS_ERR_GETTX2PIN_DEC_NULL_PARM,
+    MYKONOS_ERR_GETTX2PIN_EN_NULL_PARM,
+    MYKONOS_ERR_GETTX2PIN_TX1TX2_NULL_PARM,
+    MYKONOS_ERR_GETTX1PIN_STEP_NULL_PARM,
+    MYKONOS_ERR_GETTX1PIN_INC_NULL_PARM,
+    MYKONOS_ERR_GETTX1PIN_DEC_NULL_PARM,
+    MYKONOS_ERR_GETTX1PIN_EN_NULL_PARM,
+    MYKONOS_ERR_GETTX1PIN_TX1TX2_NULL_PARM,
+
+	MYKONOS_ERR_SPI2_INV_GPIO,
+	MYKONOS_ERR_SPI2_INV_SETUP,
+
+	MYKONOS_ERR_SET_GPIO_1V8_INV_POINTER,
+
+	MYKONOS_ERR_GETGPIOSETLEVEL_NULL_PARM,
+	MYKONOS_ERR_READGPIOSPI_NULL_PARM,
+    MYKONOS_ERR_SET_GPIO_1V8_INV_MODE,
+    MYKONOS_ERR_GETGPIO_OE_NULL_PARM,
+    MYKONOS_ERR_GPIO_OE_INV_PARAM,
+    MYKONOS_ERR_GPIO_SRC_PARAM_INV,
+
+    MYKONOS_ERR_INV_GP_INT_MASK_PARM,
+    MYKONOS_ERR_GP_INT_STATUS_NULL_PARAM,
+
+    MYKONOS_ERR_GETGPIO3V3OUT_NULL_PARM,
+    MYKONOS_ERR_SET_GPIO_3V3_INV_POINTER,
+    MYKONOS_ERR_GETGPIO3V3SPI_NULL_PARM,
+    MYKONOS_ERR_GPIO3V3OUTEN_NULL_PARM,
+    MYKONOS_ERR_SET_GPIO_3V3_INV_MODE,
+    MYKONOS_ERR_SET_GPIO_3V3_INV_SRC_CTRL,
+
+    MYKONOS_ERR_SET_ARMGPIO_INV_POINTER,
+    MYKONOS_ERR_SET_ARMGPIO_PINS_ARMERROR,
+    MYKONOS_ERR_SET_ARMGPIO_PINS_INV_SIGNALID,
+    MYKONOS_ERR_SET_ARMGPIO_PINS_INV_GPIOPIN,
+    MYKONOS_ERR_SET_RADIOCTRL_PINS_ARMERROR,
+
+    MYKONOS_ERR_SETUPAUXDAC_NULL_PARAM,
+    MYKONOS_ERR_WRITEAUXDAC_NULL_AUXIO,
+    MYKONOS_ERR_READAUXADC_NULL_PARAM,
+    MYKONOS_ERR_SETUPAUXDAC_INV_AUXDACCODE,
+    MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACCODE,
+    MYKONOS_ERR_WRITEAUXDAC_INV_AUXDACINDEX,
+    MYKONOS_ERR_INV_AUX_ADC_CHAN_PARM,
+    MYKONOS_ERR_SETUPAUXADC_INV_VCODIV,
+    MYKONOS_ERR_INV_AUX_ADC_DEC_PARM,
+
+    MYKONOS_ERR_GAINCOMP_NULL_STRUCT,
+    MYKONOS_ERR_GAINCOMP_SET_NULL_STRUCT,
+    MYKONOS_ERR_GAINCOMP_INV_RX1_OFFSET,
+    MYKONOS_ERR_GAINCOMP_INV_RX2_OFFSET,
+    MYKONOS_ERR_GAINCOMP_INV_STEP,
+    MYKONOS_ERR_GAINCOMP_INV_EN,
+
+    MYKONOS_ERR_OBS_RX_GAINCOMP_SET_NULL_STRUCT,
+    MYKONOS_ERR_OBS_RX_GAINCOMP_INV_EN,
+    MYKONOS_ERR_OBS_RX_GAINCOMP_INV_OFFSET,
+    MYKONOS_ERR_OBS_RX_GAINCOMP_INV_STEP,
+    MYKONOS_ERR_OBS_RX_GAINCOMP_NULL_STRUCT,
+
+    MYKONOS_ERR_SLICER_STEP_OUT_OF_RANGE,
+    MYKONOS_ERR_SLICER_INV_RX1_SEL,
+    MYKONOS_ERR_SLICER_INV_RX2_SEL,
+    MYKONOS_ERR_SLICER_EN_INV,
+
+    MYKONOS_ERR_SLICER_RX1PIN_NULL_PARM,
+    MYKONOS_ERR_SLICER_RX2PIN_NULL_PARM,
+    MYKONOS_ERR_SLICER_STEP_NULL_PARM,
+    MYKONOS_ERR_SLICER_EN_NULL_PARM,
+
+    MYKONOS_ERR_SLICER_INV_OBS_RX_SEL,
+    MYKONOS_ERR_SLICER_OBS_RX_STEP_OUT_OF_RANGE,
+    MYKONOS_ERR_SLICER_OBS_RX_EN_INV,
+    MYKONOS_ERR_SLICER_OBS_RX_EN_NULL_PARM,
+    MYKONOS_ERR_SLICER_OBS_RX_STEP_NULL_PARM,
+    MYKONOS_ERR_SLICER_OBS_RXPIN_NULL_PARM,
+
+    MYKONOS_ERR_FLOATFRMT_NULL_STRUCT,
+    MYKONOS_ERR_FLOATFRMT_SET_NULL_STRUCT,
+    MYKONOS_ERR_FLOATFRMT_INV_ROUND_MODE,
+    MYKONOS_ERR_FLOATFRMT_INV_DATA_FORMAT,
+    MYKONOS_ERR_FLOATFRMT_INV_ENC_NAN,
+    MYKONOS_ERR_FLOATFRMT_INV_EXP_BITS,
+    MYKONOS_ERR_FLOATFRMT_INV_LEADING,
+    MYKONOS_ERR_FLOATFRMT_INV_RX1ATT,
+    MYKONOS_ERR_FLOATFRMT_INV_RX2ATT,
+    MYKONOS_ERR_FLOATFRMT_INV_EN,
+    MYKONOS_ERR_FLOATFRMT_NULL_RX1ATT,
+    MYKONOS_ERR_FLOATFRMT_NULL_RX2ATT,
+    MYKONOS_ERR_FLOATFRMT_NULL_ENABLE,
+    MYKONOS_ERR_FLOATFRMT_SET_INV_EN,
+    MYKONOS_ERR_FLOATFRMT_SET_INV_RX1ATT,
+    MYKONOS_ERR_FLOATFRMT_SET_INV_RX2ATT,
+
+    MYKONOS_ERR_FLOATFRMT_INV_ORXATT,
+    MYKONOS_ERR_FLOATFRMT_INV_ORXEN,
+    MYKONOS_ERR_FLOATFRMT_NULL_ORXATT,
+    MYKONOS_ERR_FLOATFRMT_NULL_ORXENABLE,
+
+    MYKONOS_ERR_SETUPTEMPSENSOR_NULL_PARAM,
+    MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPDECIMATION,
+    MYKONOS_ERR_SETUPTEMPSENSOR_INV_OFFSET,
+    MYKONOS_ERR_SETUPTEMPSENSOR_INV_TEMPWINDOW,
+    MYKONOS_ERR_GETTEMPSENSORCFG_NULL_PARAM,
+    MYKONOS_ERR_READTEMPSENSOR_NULL_PARAM,
+    MYKONOS_ERR_READTEMPSENSOR_NOT_LOCKED,
+
+    MYKONOS_ERR_GAIN_CONTROL_NOT_HYBRID,
+    MYKONOS_ERR_GPIO_HYBRID_RX1_PIN,
+    MYKONOS_ERR_GPIO_HYBRID_RX2_PIN,
+    MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_NULL_PARM,
+    MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_NULL_PARM,
+    MYKONOS_ERR_GPIO_HYBRID_RX1_PIN_READ,
+    MYKONOS_ERR_GPIO_HYBRID_RX2_PIN_READ,
+    MYKONOS_ERR_AGC_OBS_NOT_IN_HYBRID,
+    MYKONOS_ERR_GPIO_HYBRID_ORX_PIN,
+    MYKONOS_ERR_GPIO_HYBRID_ORX_PIN_NULL_PARM,
+
+    MYKONOS_ERR_GAIN_CONTROL_NOT_AGC,
+    MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN,
+    MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN,
+    MYKONOS_ERR_GPIO_AGC_SYNC_RX1_PIN_NULL_PARM,
+    MYKONOS_ERR_GPIO_AGC_SYNC_RX2_PIN_NULL_PARM,
+    MYKONOS_ERR_OBS_GAIN_CONTROL_NOT_AGC,
+    MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN,
+    MYKONOS_ERR_GPIO_AGC_SYNC_ORX_PIN_NULL_PARM,
+
+    MYKONOS_ERR_GETGPIODRV_NULL_PARAM,
+    MYKONOS_ERR_GPIO_DRV_INV_PARAM,
+
+    MYKONOS_ERR_GPIO_SLEW_RATE_INV_PARAM,
+    MYKONOS_ERR_GPIO_GETSLEW_NULL_PARAM,
+
+    MYKONOS_ERR_CMOS_DRV_INV_PARAM,
+    MYKONOS_ERR_CMOS_DRV_NULL_PARAM
+} mykonosGpioErr_t;
+
+/**
+ *  \brief Enum of possible Rx Slicer pin combinations
+ */
+typedef enum
+{
+    GPIO_0_1_2      = 0,    /*!< GPIO combination for RX1        */
+    GPIO_5_6_7      = 1,    /*!< GPIO combination for RX1 or RX2 */
+    GPIO_8_9_10     = 2,    /*!< GPIO combination for RX1        */
+    GPIO_11_12_13   = 3     /*!< GPIO combination for RX2        */
+} mykonosRxSlicer_t;
+
+/**
+ *  \brief Enum of possible observation channel Slicer pin combinations
+ */
+typedef enum
+{
+    GPIO_18_17_16      = 0,    /*!< GPIO combination for observation channel */
+    GPIO_16_15_14      = 1,    /*!< GPIO combination for observation channel */
+} mykonosObsRxSlicer_t;
+
+/**
+ *  \brief Enum of possible GPIO slew rate settings
+ */
+typedef enum
+{
+    MYK_SLEWRATE_NONE    = 0,    /*!< Lower slew rate for the GPIO  */
+    MYK_SLEWRATE_LOW     = 1,    /*!< Low slew rate for the GPIO    */
+    MYK_SLEWRATE_MEDIUM  = 2,    /*!< Medium slew rate for the GPIO */
+    MYK_SLEWRATE_HIGH    = 3     /*!< High slew rate for the GPIO   */
+} mykonosGpioSlewRate_t;
+
+/**
+ * \brief Enumerated list of CMOS pads drive strength options
+ */
+typedef enum
+{
+    MYK_CMOSPAD_DRV_1X  = 0x00,       /*!<  2.5pF  load @ 65MHz */
+    MYK_CMOSPAD_DRV_2X  = 0x01,       /*!<    5pF  load @ 65MHz */
+    MYK_CMOSPAD_DRV_3X  = 0x03,       /*!<  7.5pF  load @ 65MHz */
+    MYK_CMOSPAD_DRV_4X  = 0x07,       /*!<   10pF  load @ 65MHz */
+    MYK_CMOSPAD_DRV_5X  = 0x0F        /*!< 12.5pF  load @ 65MHz */
+} mykonosCmosPadDrvStr_t;
+
+
+/**
+ * \brief Enumerated list for Aux ADCs
+ */
+typedef enum
+{
+    MYK_AUXADC_0        = 0x00,       /*!< Aux ADC channel 0 */
+    MYK_AUXADC_1        = 0x01,       /*!< Aux ADC channel 1 */
+    MYK_AUXADC_2        = 0x02,       /*!< Aux ADC channel 2 */
+    MYK_AUXADC_3        = 0x03,       /*!< Aux ADC channel 3 */
+    MYK_AUXADC_0_DIV2   = 0x04,       /*!< Aux ADC channel 0 with the divider by 2 set */
+    MYK_TEMPSENSOR      = 0x10        /*!< Temperature sensor channel */
+} mykonosAuxAdcChannels_t;
+
+
+/**
+ *  \brief Data structure to hold Gain compensation settings for the main receive channels
+ **/
+typedef struct
+{
+    uint8_t rx1Offset;  /*!< These parameter contains the Rx1 offset word used for the gain compensation
+                        when the gain index is at its maximum setting.
+                         It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */
+    uint8_t rx2Offset;  /*!< These parameter contains the Rx2 offset word used for the gain compensation
+                        when the gain index is at its maximum setting.
+                        It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */
+    uint8_t compStep;   /*!< These bits contains the value in dB that the total Rx gain changes
+                         when there is an LSB change in the gain index according to the following settings:
+                         compStep |  dB ramp
+                         ---------|------------
+                            0     |   0.25dB
+                            1     |   0.5dB
+                            2     |   1.0dB
+                            3     |   2.0dB
+                            4     |   3.0dB
+                            5     |   4.0dB
+                            6     |   6.0dB
+                            7     |   Not valid defaulted to 0.25dB */
+} mykonosGainComp_t;
+
+/**
+ *  \brief Data structure to hold Gain compensation settings for the observation channel
+ **/
+typedef struct
+{
+    uint8_t obsRxOffset;    /*!< These parameter contains the Rx1 offset word used for the gain compensation
+                            when the gain index is at its maximum setting.
+                            It has a range of 0 to 0x1F with a resolution is 0.5dB per LSB. */
+    uint8_t compStep;       /*!< These bits contains the value in dB that the total Rx gain changes
+                            when there is an LSB change in the gain index according to the following settings:
+                            compStep |  dB ramp
+                            ---------|------------
+                               0     |   0.25dB
+                               1     |   0.5dB
+                               2     |   1.0dB
+                               3     |   2.0dB
+                               4     |   3.0dB
+                               5     |   4.0dB
+                               6     |   6.0dB
+                               7     |   Not valid defaulted to 0.25dB */
+} mykonosObsRxGainComp_t;
+
+/**
+ * \brief Data structure to hold floating point formatter settings for the floating point
+ *  number generation
+ **/
+typedef struct
+{
+   uint8_t roundMode;   /*!<These parameter set the round modes for the significand.
+                        The following settings are defined in the IEEE754 specification:
+                        roundMode |  Round type
+                        ----------|-----------------
+                             0    |  RoundTiesToEven
+                             1    |  RoundTowardsPositive
+                             2    |  RoundTowardsNegative
+                             3    |  RoundTowardsZero
+                             4    |  RoundTiesToAway*/
+   uint8_t dataFormat;  /*!< These parameter sets the format of the 16-bit output on the JESD interface:
+                        Setting this to 1 then the format is from MSB to LSB to {sign, significand, exponent}.
+                        Clearing this bit sets the format to {sign, exponent, significand}.*/
+   uint8_t encNan;      /*!< if this parameter is set to 1 then the floating point formatter reserves the highest value
+                        of exponent for NaN to be compatible to the IEEE754 specification.
+                        Clearing this parameter increases the range of the exponent by one.*/
+   uint8_t expBits;     /*!<These parameter is used to indicate the number of exponent bits in the floating point number
+                        according to the following settings:
+                          expBits|  Round type
+                         --------|------------------------------------------------
+                            0    |  2 bit exponent, 13 bit significand, 1 bit sign
+                            1    |  3 bit exponent, 12 bit significand, 1 bit sign
+                            2    |  4 bit exponent, 11 bit significand, 1 bit sign
+                            3    |  5 bit exponent, 10 bit significand, 1 bit sign */
+   uint8_t leading;     /*!< Setting this parameter hides the leading one in the the significand to be compatible to the IEEE754 specification.
+                        Clearing this parameter causes the leading one to be at the MSB of the significand.*/
+}mykonosFloatPntFrmt_t;
+
+/**
+ *  \brief Data structure used to configure the on-die Temperature Sensor
+ */
+typedef struct
+{
+    uint8_t tempDecimation;      /*!<3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations;
+                                 AuxADC_decimation = 256 * 2^tempDecimation */
+    uint8_t offset;              /*!< 8-bit offset that gets added to temp sensor code internally */
+    uint8_t overrideFusedOffset; /*!< This bit overrides the factory-calibrated fuse offset
+                                 and uses the value stored in the offset member */
+    uint8_t tempWindow;          /*!<  4-bit code with a resolution of 1?C/LSB, each time a temperature measurement is performed,
+                                 the device compares the current temperature against the previous value.*/
+}mykonosTempSensorConfig_t;
+
+
+/**
+ *  \brief Data structure used to store Temperature Sensor related values
+ */
+typedef struct
+{
+    int16_t tempCode;       /*!< 16-bit signed temperature value (in deg C) that is read back */
+    uint8_t windowExceeded; /*!< If the absolute value of the difference is greater than the value in temperature configuration
+                            tempWindow, the windowExceeded flag is set.*/
+    uint8_t windowHiLo;     /*!<when windowExceeded member gets set,
+                            this bit is set to 1 if current value is greater than previous value, else reset */
+    uint8_t tempValid;      /*!< When the reading is complete and a valid temperature value stored in tempCode*/
+}mykonosTempSensorStatus_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* T_MYKONOSGPIO_H_ */
diff --git a/mpm/lib/mykonos/adi_ctrl.cpp b/mpm/lib/mykonos/adi_ctrl.cpp
new file mode 100644
index 000000000..d25c2b188
--- /dev/null
+++ b/mpm/lib/mykonos/adi_ctrl.cpp
@@ -0,0 +1,215 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "adi/common.h"
+#include <mpm/spi/adi_ctrl.hpp>
+#include <mpm/spi_iface.hpp>
+#include <iostream>
+//#include <boost/format.hpp>
+
+#define CMB_TRACE_FUNCTIONS 0
+
+#if CMB_TRACE_FUNCTIONS == 1
+#define CMB_TRACE_FUNCTION std::cout << __FUNCTION__ << std::endl;
+#else
+#define CMB_TRACE_FUNCTION
+#endif
+
+
+/* close hardware pointers */
+commonErr_t CMB_closeHardware(void)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+/* GPIO function */
+commonErr_t CMB_setGPIO(uint32_t GPIO)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+/* hardware reset function */
+commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex)
+{
+    CMB_TRACE_FUNCTION;
+    //std::cout << "Hard reset chip select " << spiChipSelectIndex << std::endl;
+    return COMMONERR_OK;
+}
+
+/* SPI read/write functions */
+
+/* allows the platform HAL to work with devices with various SPI settings */
+commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+/* value of 0 deasserts all chip selects */
+commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+/* single SPI byte write function */
+commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data)
+{
+    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings);
+    try {
+        mpm_spi->spi_iface->write_byte(addr, data);
+        return COMMONERR_OK;
+    } catch (const std::exception &e) {
+        /* ... error handling ... */
+    }
+    return COMMONERR_FAILED;
+}
+
+commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count)
+{
+    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings);
+    try {
+        mpm_spi->spi_iface->write_bytes(addr, data, count);
+        return COMMONERR_OK;
+    } catch (const std::exception &e) {
+        /* ... error handling ... */
+    }
+    return COMMONERR_FAILED;
+}
+
+/* single SPI byte read function */
+commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t *readdata)
+{
+    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings);
+    try {
+        *readdata = mpm_spi->spi_iface->read_byte(addr);
+        return COMMONERR_OK;
+    } catch (const std::exception &e) {
+        /* ... error handling ... */
+    }
+    return COMMONERR_FAILED;
+}
+
+/* write a field in a single register */
+commonErr_t CMB_SPIWriteField(
+        spiSettings_t *spiSettings,
+        uint16_t addr, uint8_t  field_val,
+        uint8_t mask, uint8_t start_bit
+) {
+    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings);
+    try {
+        mpm_spi->spi_iface->write_field(addr, field_val, mask, start_bit);
+        return COMMONERR_OK;
+    } catch (const std::exception &e) {
+        /* ... error handling ... */
+    }
+    return COMMONERR_FAILED;
+}
+
+
+/* read a field in a single register */
+commonErr_t CMB_SPIReadField(
+        spiSettings_t *spiSettings,
+        uint16_t addr, uint8_t *field_val,
+        uint8_t mask, uint8_t start_bit
+) {
+    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings);
+    try {
+        *field_val = mpm_spi->spi_iface->read_field(addr, mask, start_bit);
+        return COMMONERR_OK;
+    } catch (const std::exception &e) {
+        /* ... error handling ... */
+    }
+    return COMMONERR_FAILED;
+}
+
+/* platform timer functions */
+commonErr_t CMB_wait_ms(uint32_t time_ms)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_wait_us(uint32_t time_us)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_setTimeout_us(uint32_t timeOut_us)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_hasTimeoutExpired()
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_FAILED;
+}
+
+/* platform logging functions */
+commonErr_t CMB_openLog(const char *filename)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_closeLog(void)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, uint32_t errorCode, const char *comment)
+{
+    CMB_TRACE_FUNCTION;
+    std::cout << level << " " << errorCode << " " << comment << std::endl;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_flushLog(void)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+/* platform FPGA AXI register read/write functions */
+commonErr_t CMB_regRead(uint32_t offset, uint32_t *data)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_regWrite(uint32_t offset, uint32_t data)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+
+/* platform DDR3 memory read/write functions */
+commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
+commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len)
+{
+    CMB_TRACE_FUNCTION;
+    return COMMONERR_OK;
+}
diff --git a/mpm/lib/mykonos/adi_sample/CMakeLists.txt b/mpm/lib/mykonos/adi_sample/CMakeLists.txt
new file mode 100644
index 000000000..e00c31032
--- /dev/null
+++ b/mpm/lib/mykonos/adi_sample/CMakeLists.txt
@@ -0,0 +1,4 @@
+MYKONOS_APPEND_SOURCES(
+    ${CMAKE_CURRENT_SOURCE_DIR}/headless.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_static_config.c
+)
diff --git a/mpm/lib/mykonos/adi_sample/headless.c b/mpm/lib/mykonos/adi_sample/headless.c
new file mode 100644
index 000000000..9fedc9338
--- /dev/null
+++ b/mpm/lib/mykonos/adi_sample/headless.c
@@ -0,0 +1,528 @@
+/**
+ * \file headless.c
+ *
+ * \brief Contains example code for user integration with their application
+ *
+ * All data structures required for operation have been initialized with values which reflect
+ * these settings:
+ *
+ * Device Clock:
+ * 125MHz
+ *
+ * Profiles:
+ * Rx 100MHz, IQrate 125MSPS, Dec5
+ * Tx 20/100MHz, IQrate 125MSPS, Dec5
+ * ORX 100MHz, IQrate 125MSPS, Dec5
+ * SRx 20MHz, IQrate 31.25MSPS, Dec5
+ *
+ */
+
+#include <stdlib.h>
+#include "headless.h"
+#include "t_mykonos.h"
+#include "mykonos.h"
+#include "mykonos_gpio.h"
+#include "mykonos_config.h"
+//#include "mykonos_static_config.h"
+
+/****< Action: Insert rest of required Includes Here >***/
+
+int oldmain()
+{
+	const char* errorString;
+	uint8_t mcsStatus = 0;
+	uint8_t pllLockStatus = 0;
+	uint8_t binary[98304] = {0};  /*** < Action: binary should contain ARM binary file as array  > ***/
+	uint32_t count = sizeof(binary);
+	uint8_t errorFlag = 0;
+	uint8_t errorCode = 0;
+	uint32_t initCalsCompleted = 0;
+	uint16_t errorWord = 0;
+	uint16_t statusWord = 0;
+	uint8_t status = 0;
+	mykonosInitCalStatus_t initCalStatus = {0};
+
+	uint8_t deframerStatus = 0;
+	uint8_t obsFramerStatus = 0;
+	uint8_t framerStatus = 0;
+	uint32_t initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET |
+	TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL |
+	PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT |
+	LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT |
+	RX_LO_DELAY | RX_QEC_INIT;
+
+	uint32_t trackingCalMask = 	TRACK_RX1_QEC |
+	TRACK_RX2_QEC |
+	TRACK_TX1_QEC |
+	TRACK_TX2_QEC |
+	TRACK_ORX1_QEC|
+	TRACK_ORX2_QEC;
+
+	mykonosErr_t mykError = MYKONOS_ERR_OK;
+	mykonosGpioErr_t mykGpioErr = MYKONOS_ERR_GPIO_OK;
+
+	/* Allocating memory for the errorString */
+	errorString = (const char*) malloc(sizeof(char) * 200);
+
+	/*** < Action: Insert System Clock(s) Initialization Code Here          > ***/
+
+	/*** < Action: Insert BBIC Initialization Code Here                     > ***/
+
+	/*************************************************************************/
+	/*****                Mykonos Initialization Sequence                *****/
+	/*************************************************************************/
+
+    // TODO: change to unique ptr
+    mykonos_config config();
+    mykonosDevice_t *mykDevice = &config.device;
+
+
+	/*** < Action: Toggle RESETB pin on Mykonos device                   > ***/
+	if ((mykError = MYKONOS_resetDevice(&mykDevice)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+	if ((mykError = MYKONOS_initialize(&mykDevice)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*************************************************************************/
+	/*****                Mykonos CLKPLL Status Check                    *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_checkPllsLockStatus(&mykDevice, &pllLockStatus)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+	if (pllLockStatus & 0x01)
+	{
+		/*** < User: code here for actions once CLKPLL locked  > ***/
+	}
+	else
+	{
+		/*** < User: code here here for actions since CLKPLL not locked
+		 * ensure lock before proceeding - > ***/
+	}
+
+	/*************************************************************************/
+	/*****                Mykonos Perform MultiChip Sync                 *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_enableMultichipSync(&mykDevice, 1, &mcsStatus)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+
+	/*** < Action: minimum 3 SYSREF pulses from Clock Device has to be produced
+	 * for MulticChip Sync > ***/
+
+	/*************************************************************************/
+	/*****                Mykonos Verify MultiChip Sync                 *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_enableMultichipSync(&mykDevice, 0, &mcsStatus)) != MYKONOS_ERR_OK)
+    {
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+	if ((mcsStatus & 0x0B) == 0x0B)
+	{
+		/*** < Info: MCS successful  > ***/
+	    /*** < Action: extra User code   > ***/
+	}
+	else
+	{
+	    /*** < Info: MCS failed  > ***/
+		/*** < Action: ensure MCS before proceeding  > ***/
+	}
+
+	/*************************************************************************/
+	/*****                Mykonos Load ARM file                          *****/
+	/*************************************************************************/
+	if (pllLockStatus & 0x01)
+	{
+		if ((mykError = MYKONOS_initArm(&mykDevice)) != MYKONOS_ERR_OK)
+        {
+            /*** < Info: errorString will contain log error string in order to debug failure > ***/
+		    errorString = getMykonosErrorMessage(mykError);
+        }
+
+		/*** < Action: User must load ARM binary byte array into variable binary[98304] before calling next command > ***/
+		if ((mykError = MYKONOS_loadArmFromBinary(&mykDevice, &binary[0], count)) != MYKONOS_ERR_OK)
+		{
+		    /*** < Info: errorString will contain log error string in order to debug why
+		     *  ARM did not load properly - check binary and device settings  > ***/
+		    /*** < Action: User code > ***/
+		    errorString = getMykonosErrorMessage(mykError);
+		}
+
+	}
+	else
+	{
+		/*** < Action: check settings for proper CLKPLL lock > ***/
+	}
+
+	/*************************************************************************/
+	/*****                Mykonos Set RF PLL Frequencies                 *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, RX_PLL, mykDevice.rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+    }
+
+	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, TX_PLL, mykDevice.tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, SNIFFER_PLL, mykDevice.obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+	/*** < Action: wait 200ms for PLLs to lock > ***/
+
+	if ((mykError = MYKONOS_checkPllsLockStatus(&mykDevice, &pllLockStatus)) != MYKONOS_ERR_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+    }
+
+	if ((pllLockStatus & 0x0F) == 0x0F)
+	{
+	    /*** < Info: All PLLs locked > ***/
+	}
+	else
+	{
+	    /*** < Info: PLLs not locked  > ***/
+	    /*** < Action: Ensure lock before proceeding - User code here > ***/
+	}
+
+	/*************************************************************************/
+	/*****                Mykonos Set GPIOs                              *****/
+	/*************************************************************************/
+	if ((mykGpioErr = MYKONOS_setRx1GainCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getGpioMykonosErrorMessage(mykGpioErr);
+    }
+
+	if ((mykGpioErr = MYKONOS_setRx2GainCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getGpioMykonosErrorMessage(mykGpioErr);
+    }
+
+	if ((mykGpioErr = MYKONOS_setTx1AttenCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getGpioMykonosErrorMessage(mykGpioErr);
+    }
+
+	if ((mykGpioErr = MYKONOS_setTx2AttenCtrlPin(&mykDevice, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getGpioMykonosErrorMessage(mykGpioErr);
+    }
+
+	if ((mykGpioErr = MYKONOS_setupGpio(&mykDevice)) != MYKONOS_ERR_GPIO_OK)
+    {
+        /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getGpioMykonosErrorMessage(mykGpioErr);
+    }
+
+	/*************************************************************************/
+	/*****                Mykonos Set manual gains values                *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_setRx1ManualGain(&mykDevice, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_setRx2ManualGain(&mykDevice, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_RX1_TXLO, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_RX2_TXLO, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_A, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_B, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_C, 255)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*************************************************************************/
+	/*****                Mykonos Initialize attenuations                *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_setTx1Attenuation(&mykDevice, 0)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_setTx2Attenuation(&mykDevice, 0)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*************************************************************************/
+	/*****           Mykonos ARM Initialization Calibrations             *****/
+	/*************************************************************************/
+
+    if ((mykError = MYKONOS_runInitCals(&mykDevice, (initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK)
+	{
+		/*** < Info: errorString will contain log error string in order to debug failure > ***/
+		errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK)
+	{
+		/*** < Info: errorString will contain log error string in order to debug failure > ***/
+		errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((errorFlag != 0) || (errorCode != 0))
+	{
+		if ((mykError = MYKONOS_getInitCalStatus(&mykDevice, &initCalStatus)) != MYKONOS_ERR_OK)
+		{
+			/*** < Info: errorString will contain log error string in order to debug failure > ***/
+			errorString = getMykonosErrorMessage(mykError);
+		}
+
+		/*** < Info: abort init cals > ***/
+		if ((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK)
+		{
+			/*** < Info: errorString will contain log error string in order to debug failure > ***/
+			errorString = getMykonosErrorMessage(mykError);
+		}
+		if (initCalsCompleted)
+		{
+			/*** < Info: which calls had completed, per the mask > ***/
+		}
+
+		if ((mykError = MYKONOS_readArmCmdStatus(&mykDevice, &errorWord, &statusWord)) != MYKONOS_ERR_OK)
+		{
+			/*** < Info: errorString will contain log error string in order to debug failure > ***/
+			errorString = getMykonosErrorMessage(mykError);
+		}
+
+		if ((mykError = MYKONOS_readArmCmdStatusByte(&mykDevice, 2, &status)) != MYKONOS_ERR_OK)
+		{
+			/*** < Info: errorString will contain log error string in order to debug why  failed > ***/
+			errorString = getMykonosErrorMessage(mykError);
+		}
+		if (status != 0)
+		{
+			/*** < Info: Arm Mailbox Status Error errorWord > ***/
+			/*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/
+		}
+	}
+	else
+	{
+		/*** < Info: Calibrations completed successfully  > ***/
+	}
+
+	/*************************************************************************/
+	/*****  Mykonos ARM Initialization External LOL Calibrations with PA *****/
+	/*************************************************************************/
+	/*** < Action: Please ensure PA is enabled operational at this time > ***/
+	if (initCalMask & TX_LO_LEAKAGE_EXTERNAL)
+	{
+		if ((mykError = MYKONOS_runInitCals(&mykDevice, TX_LO_LEAKAGE_EXTERNAL)) != MYKONOS_ERR_OK)
+		{
+			/*** < Info: errorString will contain log error string in order to debug failure > ***/
+			errorString = getMykonosErrorMessage(mykError);
+		}
+		if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK)
+		{
+			/*** < Info: errorString will contain log error string in order to debug failure > ***/
+			errorString = getMykonosErrorMessage(mykError);
+		}
+		if ((errorFlag != 0) || (errorCode != 0))
+		{
+			if ((mykError = MYKONOS_getInitCalStatus(&mykDevice, &initCalStatus)) != MYKONOS_ERR_OK)
+			{
+				/*** < Info: errorString will contain log error string in order to debug failure > ***/
+				errorString = getMykonosErrorMessage(mykError);
+			}
+
+			/*** < Info: abort init cals > ***/
+			if ((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK)
+			{
+				/*** < Info: errorString will contain log error string in order to debug failure > ***/
+				errorString = getMykonosErrorMessage(mykError);
+			}
+			if (initCalsCompleted)
+			{
+				/*** < Info: which calls had completed, per the mask > ***/
+			}
+
+			if ((mykError = MYKONOS_readArmCmdStatus(&mykDevice, &errorWord, &statusWord)) != MYKONOS_ERR_OK)
+			{
+				/*** < Info: errorString will contain log error string in order to debug failure > ***/
+				errorString = getMykonosErrorMessage(mykError);
+			}
+
+			if ((mykError = MYKONOS_readArmCmdStatusByte(&mykDevice, 2, &status)) != MYKONOS_ERR_OK)
+			{
+				/*** < Info: errorString will contain log error string in order to debug failure > ***/
+				errorString = getMykonosErrorMessage(mykError);
+			}
+			if (status != 0)
+			{
+				/*** < Info: Arm Mailbox Status Error errorWord > ***/
+				/*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/
+			}
+		}
+		else
+		{
+			/*** < Info: Calibrations completed successfully  > ***/
+		}
+	}
+
+	/*************************************************************************/
+	/*****             SYSTEM JESD bring up procedure                    *****/
+	/*************************************************************************/
+	/*** < Action: Make sure SYSREF is stopped/disabled > ***/
+	/*** < Action: Make sure BBIC JESD is reset and ready to recieve CGS chars> ***/
+
+	if ((mykError = MYKONOS_enableSysrefToRxFramer(&mykDevice, 1)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+	    errorString = getMykonosErrorMessage(mykError);
+	}
+	/*** < Info: Mykonos is waiting for sysref in order to start
+	 * transmitting CGS from the RxFramer> ***/
+
+	if ((mykError = MYKONOS_enableSysrefToObsRxFramer(&mykDevice, 1)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+	/*** < Info: Mykonos is waiting for sysref in order to start
+	 * transmitting CGS from the ObsRxFramer> ***/
+
+	/*** < User: Make sure SYSREF is stopped/disabled > ***/
+	if ((mykError = MYKONOS_enableSysrefToDeframer(&mykDevice, 0)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	if ((mykError = MYKONOS_resetDeframer(&mykDevice)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*** < User: make sure BBIC JESD framer is actively transmitting CGS> ***/
+	if ((mykError = MYKONOS_enableSysrefToDeframer(&mykDevice, 1)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*************************************************************************/
+	/*****            Enable SYSREF to Mykonos and BBIC                  *****/
+	/*************************************************************************/
+	/*** < Action: Sends SYSREF Here > ***/
+
+	/*** < Info: Mykonos is actively transmitting CGS from the RxFramer> ***/
+
+	/*** < Info: Mykonos is actively transmitting CGS from the ObsRxFramer> ***/
+
+	/*** < Action: Insert User: BBIC JESD Sync Verification Code Here > ***/
+
+	/*************************************************************************/
+	/*****               Check Mykonos Framer Status                     *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_readRxFramerStatus(&mykDevice, &framerStatus)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+	if ((mykError = MYKONOS_readOrxFramerStatus(&mykDevice, &obsFramerStatus)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*************************************************************************/
+	/*****               Check Mykonos Deframer Status                   *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_readDeframerStatus(&mykDevice, &deframerStatus)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*** < Action: When links have been verified, proceed > ***/
+
+	/*************************************************************************/
+	/*****           Mykonos enable tracking calibrations                *****/
+	/*************************************************************************/
+	if ((mykError = MYKONOS_enableTrackingCals(&mykDevice, trackingCalMask)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug why enableTrackingCals failed > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*** < Info: Allow Rx1/2 QEC tracking and Tx1/2 QEC tracking to run when in the radioOn state
+	     *  Tx calibrations will only run if radioOn and the obsRx path is set to OBS_INTERNAL_CALS > ***/
+
+	/*** < Info: Function to turn radio on, Enables transmitters and receivers
+	 * that were setup during MYKONOS_initialize() > ***/
+	if ((mykError = MYKONOS_radioOn(&mykDevice)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	/*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/
+	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_RXOFF)) != MYKONOS_ERR_OK)
+    {
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+    }
+	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_INTERNALCALS)) != MYKONOS_ERR_OK)
+	{
+	    /*** < Info: errorString will contain log error string in order to debug failure > ***/
+        errorString = getMykonosErrorMessage(mykError);
+	}
+
+	return 0;
+}
\ No newline at end of file
diff --git a/mpm/lib/mykonos/adi_sample/headless.cpp b/mpm/lib/mykonos/adi_sample/headless.cpp
new file mode 100644
index 000000000..93f079cc2
--- /dev/null
+++ b/mpm/lib/mykonos/adi_sample/headless.cpp
@@ -0,0 +1,312 @@
+/**
+ * \file headless.c
+ *
+ * \brief Contains example code for user integration with their application
+ *
+ * All data structures required for operation have been initialized with values which reflect
+ * these settings:
+ *
+ * Device Clock:
+ * 125MHz
+ *
+ * Profiles:
+ * Rx 100MHz, IQrate 125MSPS, Dec5
+ * Tx 20/100MHz, IQrate 125MSPS, Dec5
+ * ORX 100MHz, IQrate 125MSPS, Dec5
+ * SRx 20MHz, IQrate 31.25MSPS, Dec5
+ *
+ */
+
+#include <stdlib.h>
+#include <iostream>
+#include "headless.h"
+#include "../adi/t_mykonos.h"
+#include "../adi/mykonos.h"
+#include "../adi/mykonos_gpio.h"
+#include "../config/mykonos_default_config.h"
+//#include "mykonos_static_config.h"
+
+#include <functional>
+
+// dumb function to make the error reporting reusable within this file
+void call_mykonos_api(std::function<mykonosErr_t()> f)
+{
+    auto error = f();
+    if (error != MYKONOS_ERR_OK)
+    {
+        // TODO: make this an exception and stop normal processing
+        // in the mean time, print an error and continue happily on
+        std::cout << getMykonosErrorMessage(error) << std::endl;
+    }
+}
+
+int headlessinit(mykonosDevice_t *mykDevice)
+{
+	uint32_t initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET |
+	TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL |
+	PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT |
+	LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT |
+	RX_LO_DELAY | RX_QEC_INIT;
+
+	uint32_t trackingCalMask = 	TRACK_RX1_QEC |
+	TRACK_RX2_QEC |
+	TRACK_TX1_QEC |
+	TRACK_TX2_QEC |
+	TRACK_ORX1_QEC|
+	TRACK_ORX2_QEC;
+
+	/*** < Action: Insert System Clock(s) Initialization Code Here          > ***/
+
+	/*** < Action: Insert BBIC Initialization Code Here                     > ***/
+
+	/*************************************************************************/
+	/*****                Mykonos Initialization Sequence                *****/
+	/*************************************************************************/
+
+    /*** < Action: Toggle RESETB pin on Mykonos device > ***/
+    call_mykonos_api(std::bind(MYKONOS_resetDevice, mykDevice));
+    call_mykonos_api(std::bind(MYKONOS_initialize, mykDevice));
+
+	/*************************************************************************/
+	/*****                Mykonos CLKPLL Status Check                    *****/
+	/*************************************************************************/
+
+    // change logic to timeout/wait for PLL lock
+    {
+        uint8_t pllLockStatus = 0;
+        call_mykonos_api(std::bind(MYKONOS_checkPllsLockStatus, mykDevice, &pllLockStatus));
+
+        if (pllLockStatus & 0x01)
+        {
+            /*** < User: code here for actions once CLKPLL locked  > ***/
+        }
+        else
+        {
+            /*** < User: code here here for actions since CLKPLL not locked
+             * ensure lock before proceeding - > ***/
+        }
+    }
+
+    // Multichip sync was here
+
+	/*************************************************************************/
+	/*****                Mykonos Load ARM file                          *****/
+	/*************************************************************************/
+
+    // deleted check for PLL lock here, do not advance until PLL is locked
+
+    call_mykonos_api(std::bind(MYKONOS_initArm, mykDevice));
+    {
+        // TODO: Add code for loading ARM binary here
+        uint8_t binary[98304] = { 0 };
+        uint32_t count = sizeof(binary);
+        call_mykonos_api(std::bind(MYKONOS_loadArmFromBinary, mykDevice, &binary[0], count));
+    }
+
+	/*************************************************************************/
+	/*****                Mykonos Set RF PLL Frequencies                 *****/
+	/*************************************************************************/
+
+    call_mykonos_api(std::bind(MYKONOS_setRfPllFrequency, mykDevice, RX_PLL, mykDevice->rx->rxPllLoFrequency_Hz));
+    call_mykonos_api(std::bind(MYKONOS_setRfPllFrequency, mykDevice, TX_PLL, mykDevice->tx->txPllLoFrequency_Hz));
+    call_mykonos_api(std::bind(MYKONOS_setRfPllFrequency, mykDevice, SNIFFER_PLL, mykDevice->obsRx->snifferPllLoFrequency_Hz));
+
+	/*** < Action: wait 200ms for PLLs to lock > ***/
+
+    // change logic to wait for rest of PLLs to lock
+    {
+        uint8_t pllLockStatus = 0;
+        call_mykonos_api(std::bind(MYKONOS_checkPllsLockStatus, mykDevice, &pllLockStatus));
+
+        if ((pllLockStatus & 0x0F) == 0x0F)
+        {
+            /*** < Info: All PLLs locked > ***/
+        }
+        else
+        {
+            /*** < Info: PLLs not locked  > ***/
+            /*** < Action: Ensure lock before proceeding - User code here > ***/
+        }
+    }
+
+    // GPIO Ctrl set up was here
+
+	/*************************************************************************/
+	/*****                Mykonos Set manual gains values                *****/
+	/*************************************************************************/
+
+    call_mykonos_api(std::bind(MYKONOS_setRx1ManualGain, mykDevice, 255));
+    call_mykonos_api(std::bind(MYKONOS_setRx2ManualGain, mykDevice, 255));
+
+    // setting gain of obs and sniffer channels was here
+
+	/*************************************************************************/
+	/*****                Mykonos Initialize attenuations                *****/
+	/*************************************************************************/
+
+    call_mykonos_api(std::bind(MYKONOS_setTx1Attenuation, mykDevice, 0));
+    call_mykonos_api(std::bind(MYKONOS_setTx2Attenuation, mykDevice, 0));
+
+	/*************************************************************************/
+	/*****           Mykonos ARM Initialization Calibrations             *****/
+	/*************************************************************************/
+
+    call_mykonos_api(std::bind(MYKONOS_runInitCals, mykDevice, (initCalMask & ~TX_LO_LEAKAGE_EXTERNAL)));
+
+    {
+        uint8_t errorFlag = 0;
+        uint8_t errorCode = 0;
+        call_mykonos_api(std::bind(MYKONOS_waitInitCals, mykDevice, 60000, &errorFlag, &errorCode));
+
+        if ((errorFlag != 0) || (errorCode != 0))
+        {
+            mykonosInitCalStatus_t initCalStatus = { 0 };
+            call_mykonos_api(std::bind(MYKONOS_getInitCalStatus, mykDevice, &initCalStatus));
+
+            /*** < Info: abort init cals > ***/
+            uint32_t initCalsCompleted = 0;
+            call_mykonos_api(std::bind(MYKONOS_abortInitCals, mykDevice, &initCalsCompleted));
+            if (initCalsCompleted)
+            {
+                /*** < Info: which calls had completed, per the mask > ***/
+            }
+
+            uint16_t errorWord = 0;
+            uint16_t statusWord = 0;
+            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatus, mykDevice, &errorWord, &statusWord));
+
+            uint8_t status = 0;
+            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatusByte, mykDevice, 2, &status));
+
+            if (status != 0)
+            {
+                /*** < Info: Arm Mailbox Status Error errorWord > ***/
+                /*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/
+            }
+        }
+        else
+        {
+            /*** < Info: Calibrations completed successfully  > ***/
+        }
+    }
+
+	/*************************************************************************/
+	/*****  Mykonos ARM Initialization External LOL Calibrations with PA *****/
+	/*************************************************************************/
+	/*** < Action: Please ensure PA is enabled operational at this time > ***/
+	if (initCalMask & TX_LO_LEAKAGE_EXTERNAL)
+	{
+        call_mykonos_api(std::bind(MYKONOS_runInitCals, mykDevice, TX_LO_LEAKAGE_EXTERNAL));
+
+        uint8_t errorFlag = 0;
+        uint8_t errorCode = 0;
+        call_mykonos_api(std::bind(MYKONOS_waitInitCals, mykDevice, 60000, &errorFlag, &errorCode));
+
+		if ((errorFlag != 0) || (errorCode != 0))
+		{
+            mykonosInitCalStatus_t initCalStatus = { 0 };
+            call_mykonos_api(std::bind(MYKONOS_getInitCalStatus, mykDevice, &initCalStatus));
+
+			/*** < Info: abort init cals > ***/
+            uint32_t initCalsCompleted = 0;
+            call_mykonos_api(std::bind(MYKONOS_abortInitCals, mykDevice, &initCalsCompleted));
+			if (initCalsCompleted)
+			{
+				/*** < Info: which calls had completed, per the mask > ***/
+			}
+
+            uint16_t errorWord = 0;
+            uint16_t statusWord = 0;
+            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatus, mykDevice, &errorWord, &statusWord));
+
+            uint8_t status = 0;
+            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatusByte, mykDevice, 2, &status));
+			if (status != 0)
+			{
+				/*** < Info: Arm Mailbox Status Error errorWord > ***/
+				/*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/
+			}
+		}
+		else
+		{
+			/*** < Info: Calibrations completed successfully  > ***/
+		}
+	}
+
+	/*************************************************************************/
+	/*****             SYSTEM JESD bring up procedure                    *****/
+	/*************************************************************************/
+	/*** < Action: Make sure SYSREF is stopped/disabled > ***/
+	/*** < Action: Make sure BBIC JESD is reset and ready to recieve CGS chars> ***/
+
+    call_mykonos_api(std::bind(MYKONOS_enableSysrefToRxFramer, mykDevice, 1));
+
+	/*** < Info: Mykonos is waiting for sysref in order to start
+	 * transmitting CGS from the RxFramer> ***/
+
+    call_mykonos_api(std::bind(MYKONOS_enableSysrefToObsRxFramer, mykDevice, 1));
+
+	/*** < Info: Mykonos is waiting for sysref in order to start
+	 * transmitting CGS from the ObsRxFramer> ***/
+
+	/*** < User: Make sure SYSREF is stopped/disabled > ***/
+    call_mykonos_api(std::bind(MYKONOS_enableSysrefToDeframer, mykDevice, 0));
+
+    call_mykonos_api(std::bind(MYKONOS_resetDeframer, mykDevice));
+    call_mykonos_api(std::bind(MYKONOS_enableSysrefToDeframer, mykDevice, 1));
+
+	/*** < User: make sure BBIC JESD framer is actively transmitting CGS> ***/
+
+	/*************************************************************************/
+	/*****            Enable SYSREF to Mykonos and BBIC                  *****/
+	/*************************************************************************/
+	/*** < Action: Sends SYSREF Here > ***/
+
+	/*** < Info: Mykonos is actively transmitting CGS from the RxFramer> ***/
+
+	/*** < Info: Mykonos is actively transmitting CGS from the ObsRxFramer> ***/
+
+	/*** < Action: Insert User: BBIC JESD Sync Verification Code Here > ***/
+
+	/*************************************************************************/
+	/*****               Check Mykonos Framer Status                     *****/
+	/*************************************************************************/
+    {
+        uint8_t framerStatus = 0;
+        call_mykonos_api(std::bind(MYKONOS_readRxFramerStatus, mykDevice, &framerStatus));
+    }
+
+    {
+        uint8_t obsFramerStatus = 0;
+        call_mykonos_api(std::bind(MYKONOS_readOrxFramerStatus, mykDevice, &obsFramerStatus));
+    }
+
+	/*************************************************************************/
+	/*****               Check Mykonos Deframer Status                   *****/
+	/*************************************************************************/
+
+    {
+        uint8_t deframerStatus = 0;
+        call_mykonos_api(std::bind(MYKONOS_readDeframerStatus, mykDevice, &deframerStatus));
+    }
+	/*** < Action: When links have been verified, proceed > ***/
+
+	/*************************************************************************/
+	/*****           Mykonos enable tracking calibrations                *****/
+	/*************************************************************************/
+
+    call_mykonos_api(std::bind(MYKONOS_enableTrackingCals, mykDevice, trackingCalMask));
+
+	/*** < Info: Allow Rx1/2 QEC tracking and Tx1/2 QEC tracking to run when in the radioOn state
+	     *  Tx calibrations will only run if radioOn and the obsRx path is set to OBS_INTERNAL_CALS > ***/
+
+	/*** < Info: Function to turn radio on, Enables transmitters and receivers
+	 * that were setup during MYKONOS_initialize() > ***/
+
+    call_mykonos_api(std::bind(MYKONOS_radioOn, mykDevice));
+    /*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/
+    call_mykonos_api(std::bind(MYKONOS_setObsRxPathSource, mykDevice, OBS_RXOFF));
+    call_mykonos_api(std::bind(MYKONOS_setObsRxPathSource, mykDevice, OBS_INTERNALCALS));
+
+	return 0;
+}
diff --git a/mpm/lib/mykonos/adi_sample/headless.h b/mpm/lib/mykonos/adi_sample/headless.h
new file mode 100644
index 000000000..abdfb65bf
--- /dev/null
+++ b/mpm/lib/mykonos/adi_sample/headless.h
@@ -0,0 +1,10 @@
+/**
+ * \file headless.h
+ *
+ * \brief Contains definitions for headless.c
+*/
+#pragma once
+
+#include "mykonos_static_config.h"
+
+int headlessinit(mykonosDevice_t *mykDevice);
diff --git a/mpm/lib/mykonos/adi_sample/mykonos_static_config.c b/mpm/lib/mykonos/adi_sample/mykonos_static_config.c
new file mode 100644
index 000000000..1a70963aa
--- /dev/null
+++ b/mpm/lib/mykonos/adi_sample/mykonos_static_config.c
@@ -0,0 +1,516 @@
+/**
+ * \brief Contains init setting structure declarations for the _instance API
+ *
+ * The top level structure mykonosDevice_t mykDevice uses keyword
+ * extern to allow the application layer main() to have visibility
+ * to these settings.
+ *
+ * All data structures required for operation have been initialized with values which reflect these settings:
+ *
+ * Device Clock:
+ * 125MHz
+ *
+ * Profiles:
+ * Rx 100MHz, IQrate 125MSPS, Dec5
+ * Tx 20/100MHz, IQrate 125MSPS, Dec5
+ * ORX 100MHz, IQrate 125MSPS, Dec5
+ * SRx 20MHz, IQrate 31.25MSPS, Dec5
+ *
+ */
+
+#include "mykonos_static_config.h"
+#include "../adi/t_mykonos_gpio.h"
+#include <stddef.h>
+
+static int16_t txFirCoefs[] = {-94,-26,282,177,-438,-368,756,732,-1170,-1337,1758,2479,-2648,-5088,4064,16760,16759,4110,-4881,-2247,2888,1917,-1440,-1296,745,828,-358,-474,164,298,-16,-94};
+
+static mykonosFir_t txFir =
+{
+    6,              /* Filter gain in dB*/
+    32,             /* Number of coefficients in the FIR filter*/
+    &txFirCoefs[0]  /* A pointer to an array of filter coefficients*/
+};
+
+static int16_t rxFirCoefs[] = {-20,6,66,22,-128,-54,240,126,-402,-248,634,444,-956,-756,1400,1244,-2028,-2050,2978,3538,-4646,-7046,9536,30880,30880,9536,-7046,-4646,3538,2978,-2050,-2028,1244,1400,-756,-956,444,634,-248,-402,126,240,-54,-128,22,66,6,-20};
+
+static mykonosFir_t rxFir =
+{
+    -6,             /* Filter gain in dB*/
+    48,             /* Number of coefficients in the FIR filter*/
+    &rxFirCoefs[0]  /* A pointer to an array of filter coefficients*/
+};
+
+static int16_t obsrxFirCoefs[] = {-14,-19,44,41,-89,-95,175,178,-303,-317,499,527,-779,-843,1184,1317,-1781,-2059,2760,3350,-4962,-7433,9822,32154,32154,9822,-7433,-4962,3350,2760,-2059,-1781,1317,1184,-843,-779,527,499,-317,-303,178,175,-95,-89,41,44,-19,-14};
+static mykonosFir_t obsrxFir =
+{
+    -6,             /* Filter gain in dB*/
+    48,             /* Number of coefficients in the FIR filter*/
+    &obsrxFirCoefs[0]/* A pointer to an array of filter coefficients*/
+};
+
+static int16_t snifferFirCoefs[] = {-1,-5,-14,-23,-16,24,92,137,80,-120,-378,-471,-174,507,1174,1183,98,-1771,-3216,-2641,942,7027,13533,17738,17738,13533,7027,942,-2641,-3216,-1771,98,1183,1174,507,-174,-471,-378,-120,80,137,92,24,-16,-23,-14,-5,-1};
+static mykonosFir_t snifferRxFir=
+{
+    -6,             /* Filter gain in dB*/
+    48,             /* Number of coefficients in the FIR filter*/
+    &snifferFirCoefs[0]/* A pointer to an array of filter coefficients*/
+};
+
+static mykonosJesd204bFramerConfig_t rxFramer =
+{
+    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
+    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
+    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
+    4,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
+    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
+    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
+    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/
+    0x0F,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
+    0xE4,           /* serializerLaneCrossbar*/
+    22,             /* serializerAmplitude - default 22 (valid (0-31)*/
+    4,              /* preEmphasis - < default 4 (valid 0 - 7)*/
+    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
+    0,              /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
+    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
+    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
+    0,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
+    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
+    0               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
+};
+
+static mykonosJesd204bFramerConfig_t obsRxFramer =
+{
+    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
+    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
+    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
+    2,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
+    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
+    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
+    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/
+    0x00,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
+    0xE4,           /* Lane crossbar to map framer lane outputs to physical lanes*/
+    22,             /* serializerAmplitude - default 22 (valid (0-31)*/
+    4,              /* preEmphasis - < default 4 (valid 0 - 7)*/
+    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
+    0,              /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
+    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
+    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
+    1,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
+    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
+    1               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
+};
+
+static mykonosJesd204bDeframerConfig_t deframer =
+{
+    0,              /* bankId extension to Device ID (Valid 0..15)*/
+    0,              /* deviceId  link identification number. (Valid 0..255)*/
+    0,              /* lane0Id Lane0 ID. (Valid 0..31)*/
+    4,              /* M  number of DACss (0, 2, or 4) - 2 DACs per transmit chain */
+    32,             /* K  #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/
+    1,              /* scramble  scrambling off if scramble= 0.*/
+    1,              /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/
+    0x0F,           /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */
+    0xE4,           /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */
+    1,              /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/
+    0,              /* PN inversion per each lane.  bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/
+    0,              /* LMFC_Offset offset value to adjust deterministic latency. Range is 0..31*/
+    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/
+    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
+    0               /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
+};
+
+static mykonosRxGainControl_t rxGainControl =
+{
+    MGC,            /* Current Rx gain control mode setting*/
+    255,            /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* Max gain index for the currently loaded Rx1 Gain table*/
+    195,            /* Min gain index for the currently loaded Rx1 Gain table*/
+    255,            /* Max gain index for the currently loaded Rx2 Gain table*/
+    195,            /* Min gain index for the currently loaded Rx2 Gain table*/
+    0,              /* Stores Rx1 RSSI value read back from the Mykonos*/
+    0               /* Stores Rx2 RSSI value read back from the Mykonos*/
+};
+
+static mykonosORxGainControl_t orxGainControl =
+{
+    MGC,            /* Current ORx gain control mode setting*/
+    255,            /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* Max gain index for the currently loaded ORx Gain table*/
+    237             /* Min gain index for the currently loaded ORx Gain table*/
+};
+
+static mykonosSnifferGainControl_t snifferGainControl =
+{
+    MGC,            /* Current Sniffer gain control mode setting*/
+    255,            /* Current Sniffer gain index. Can be used differently for MANUAL Gain control/AGC*/
+    255,            /* Max gain index for the currently loaded Sniffer Gain table*/
+    203             /* Min gain index for the currently loaded Sniffer Gain table*/
+};
+
+static mykonosPeakDetAgcCfg_t rxPeakAgc =
+{
+    0x00,	/* apdHighThresh: */
+    0x00,	/* apdLowThresh */
+    0x00,	/* hb2HighThresh */
+    0x00,	/* hb2LowThresh */
+    0x00,	/* hb2VeryLowThresh */
+    0x00,	/* apdHighThreshExceededCnt */
+    0x00,	/* apdLowThreshExceededCnt */
+    0x00,	/* hb2HighThreshExceededCnt */
+    0x00,	/* hb2LowThreshExceededCnt */
+    0x00,	/* hb2VeryLowThreshExceededCnt */
+    0x0,	/* apdHighGainStepAttack */
+    0x0,	/* apdLowGainStepRecovery */
+    0x0,	/* hb2HighGainStepAttack */
+    0x0,	/* hb2LowGainStepRecovery */
+    0x0,	/* hb2VeryLowGainStepRecovery */
+    0x0,	/* apdFastAttack */
+    0x0,	/* hb2FastAttack */
+    0x0,	/* hb2OverloadDetectEnable */
+    0x0,	/* hb2OverloadDurationCnt */
+    0x0	/* hb2OverloadThreshCnt */
+};
+
+static mykonosPowerMeasAgcCfg_t rxPwrAgc =
+{
+    0x00,	/* pmdUpperHighThresh */
+    0x00,	/* pmdUpperLowThresh */
+    0x00,	/* pmdLowerHighThresh */
+    0x00,	/* pmdLowerLowThresh */
+    0x0,	/* pmdUpperHighGainStepAttack */
+    0x0,	/* pmdUpperLowGainStepAttack */
+    0x0,	/* pmdLowerHighGainStepRecovery */
+    0x0,	/* pmdLowerLowGainStepRecovery */
+    0x00,	/* pmdMeasDuration */
+    0x00	/* pmdMeasConfig */
+};
+
+static mykonosAgcCfg_t rxAgcConfig =
+{
+    0,	/* agcRx1MaxGainIndex */
+    0,	/* agcRx1MinGainIndex */
+    0,	/* agcRx2MaxGainIndex */
+    0,	/* agcRx2MinGainIndex: */
+    0,	/* agcObsRxMaxGainIndex */
+    0,	/* agcObsRxMinGainIndex */
+    0,		/* agcObsRxSelect */
+    0,		/* agcPeakThresholdMode */
+    0,		/* agcLowThsPreventGainIncrease */
+    0,	/* agcGainUpdateCounter */
+    0,	/* agcSlowLoopSettlingDelay */
+    0,	/* agcPeakWaitTime */
+    0,	/* agcResetOnRxEnable */
+    0,	/* agcEnableSyncPulseForGainCounter */
+    &rxPeakAgc,
+    &rxPwrAgc
+};
+
+static mykonosPeakDetAgcCfg_t obsRxPeakAgc =
+{
+    0x00,	/* apdHighThresh: */
+    0x00,	/* apdLowThresh */
+    0x00,	/* hb2HighThresh */
+    0x00,	/* hb2LowThresh */
+    0x00,	/* hb2VeryLowThresh */
+    0x00,	/* apdHighThreshExceededCnt */
+    0x00,	/* apdLowThreshExceededCnt */
+    0x00,	/* hb2HighThreshExceededCnt */
+    0x00,	/* hb2LowThreshExceededCnt */
+    0x00,	/* hb2VeryLowThreshExceededCnt */
+    0x0,	/* apdHighGainStepAttack */
+    0x0,	/* apdLowGainStepRecovery */
+    0x0,	/* hb2HighGainStepAttack */
+    0x0,	/* hb2LowGainStepRecovery */
+    0x0,	/* hb2VeryLowGainStepRecovery */
+    0x0,	/* apdFastAttack */
+    0x0,	/* hb2FastAttack */
+    0x0,	/* hb2OverloadDetectEnable */
+    0x0,	/* hb2OverloadDurationCnt */
+    0x0		/* hb2OverloadThreshCnt */
+};
+
+static mykonosPowerMeasAgcCfg_t obsRxPwrAgc =
+{
+    0x00,	/* pmdUpperHighThresh */
+    0x00,	/* pmdUpperLowThresh */
+    0x00,	/* pmdLowerHighThresh */
+    0x00,	/* pmdLowerLowThresh */
+    0x0,	/* pmdUpperHighGainStepAttack */
+    0x0,	/* pmdUpperLowGainStepAttack */
+    0x0,	/* pmdLowerHighGainStepRecovery */
+    0x0,	/* pmdLowerLowGainStepRecovery */
+    0x00,	/* pmdMeasDuration */
+    0x00	/* pmdMeasConfig */
+};
+
+static mykonosAgcCfg_t obsRxAgcConfig =
+{
+    0,	/* agcRx1MaxGainIndex */
+    0,	/* agcRx1MinGainIndex */
+    0,	/* agcRx2MaxGainIndex */
+    0,	/* agcRx2MinGainIndex: */
+    0,	/* agcObsRxMaxGainIndex */
+    0,	/* agcObsRxMinGainIndex */
+    0,		/* agcObsRxSelect */
+    0,		/* agcPeakThresholdMode */
+    0,		/* agcLowThsPreventGainIncrease */
+    0,	/* agcGainUpdateCounter */
+    0,		/* agcSlowLoopSettlingDelay */
+    0,		/* agcPeakWaitTime */
+    0,		/* agcResetOnRxEnable */
+    0,		/* agcEnableSyncPulseForGainCounter */
+    &obsRxPeakAgc,
+    &obsRxPwrAgc
+};
+
+
+static mykonosRxProfile_t rxProfile =
+{/* Rx 100MHz, IQrate 125MSPS, Dec5 */
+    1,              /* The divider used to generate the ADC clock*/
+    &rxFir,         /* Pointer to Rx FIR filter structure*/
+    2,              /* Rx FIR decimation (1,2,4)*/
+    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/
+    1,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
+    1,              /* RX Half band 1 decimation (1 or 2)*/
+    125000,         /* Rx IQ data rate in kHz*/
+    100000000,      /* The Rx RF passband bandwidth for the profile*/
+    102000,         /* Rx BBF 3dB corner in kHz*/
+    NULL            /* pointer to custom ADC profile*/
+};
+
+static mykonosRxProfile_t orxProfile =
+{/* ORX 100MHz, IQrate 125MSPS, Dec5 */
+    1,              /* The divider used to generate the ADC clock*/
+    &obsrxFir,      /* Pointer to Rx FIR filter structure or NULL*/
+    2,              /* Rx FIR decimation (1,2,4)*/
+    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/
+    0,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
+    1,              /* RX Half band 1 decimation (1 or 2)*/
+    125000,         /* Rx IQ data rate in kHz*/
+    100000000,      /* The Rx RF passband bandwidth for the profile*/
+    102000,         /* Rx BBF 3dB corner in kHz*/
+    NULL            /* pointer to custom ADC profile*/
+};
+
+
+static mykonosRxProfile_t snifferProfile =
+{ /* SRx 20MHz, IQrate 31.25MSPS, Dec5 */
+    1,              /* The divider used to generate the ADC clock*/
+    &snifferRxFir,  /* Pointer to Rx FIR filter structure or NULL*/
+    4,              /* Rx FIR decimation (1,2,4)*/
+    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/
+    0,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
+    2,              /* RX Half band 1 decimation (1 or 2)*/
+    31250,          /* Rx IQ data rate in kHz*/
+    20000000,       /* The Rx RF passband bandwidth for the profile*/
+    100000,         /* Rx BBF 3dB corner in kHz*/
+    NULL            /* pointer to custom ADC profile*/
+};
+
+
+
+static mykonosTxProfile_t txProfile =
+{ /* Tx 20/100MHz, IQrate 125MSPS, Dec5 */
+    DACDIV_2p5,     /* The divider used to generate the DAC clock*/
+    &txFir,         /* Pointer to Tx FIR filter structure*/
+    2,              /* The Tx digital FIR filter interpolation (1,2,4)*/
+    2,              /* Tx Halfband1 filter interpolation (1,2)*/
+    1,              /* Tx Halfband2 filter interpolation (1,2)*/
+    1,              /* TxInputHbInterpolation (1,2)*/
+    125000,         /* Tx IQ data rate in kHz*/
+    20000000,       /* Primary Signal BW*/
+    102000000,      /* The Tx RF passband bandwidth for the profile*/
+    722000,         /* The DAC filter 3dB corner in kHz*/
+    51000,          /* Tx BBF 3dB corner in kHz*/
+    0               /* Enable DPD, only valid for AD9373*/
+};
+
+static mykonosDigClocks_t mykonosClocks =
+{
+    125000,         /* CLKPLL and device reference clock frequency in kHz*/
+    10000000,       /* CLKPLL VCO frequency in kHz*/
+    VCODIV_2,       /* CLKPLL VCO divider*/
+    4               /* CLKPLL high speed clock divider*/
+};
+
+static mykonosRxSettings_t  rxSettings =
+{
+    &rxProfile,     /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/
+    &rxFramer,      /* Rx JESD204b framer configuration structure*/
+    &rxGainControl, /* Rx Gain control settings structure*/
+    &rxAgcConfig,   /* Rx AGC control settings structure*/
+    3,              /* The desired Rx Channels to enable during initialization*/
+    0,              /* Internal LO = 0, external LO*2 = 1*/
+    2550000000U,    /* Rx PLL LO Frequency (internal or external LO)*/
+    0               /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/
+};
+
+static mykonosDpdConfig_t dpdConfig =
+{
+    5,              /* 1/2^(damping + 8) fraction of power `forgotten' per sample (default: `1/8192' = 5, valid 0 to 15), 0 = infinite damping*/
+    1,              /* number of weights to use for int8_cpx weights weights member of this structure (default = 1)*/
+    2,              /* DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2)*/
+    1,              /* 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS*/
+    20,             /* Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20)*/
+    0,              /* Default off = 0, 1=enables automatic outlier removal during DPD modeling */
+    512,            /* Number of samples to capture (default: 512, valid 64-32768)*/
+    4096,           /* threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1)*/
+    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
+    255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
+    {{64,0},{0,0},{0,0}}/* DPD model error weighting (real/imag valid from -128 to 127)*/
+};
+
+static mykonosClgcConfig_t clgcConfig =
+{
+    -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/
+    -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/
+    0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/
+    0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/
+    75,             /* valid range 1-100, default 75*/
+    75,             /* valid range 1-100, default 45*/
+    0,              /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx1Atten automatically updated*/
+    0,              /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx2Atten automatically updated*/
+    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
+    255             /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
+};
+
+static mykonosVswrConfig_t vswrConfig =
+{
+    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
+    255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
+    0,              /* 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos)*/
+    1,              /* 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos)*/
+    0,              /* 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level)*/
+    0,              /* 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level)*/
+    1,              /* Delay for Tx1 after flipping the VSWR switch until measurement is made. In ms resolution*/
+    1               /* Delay for Tx2 after flipping the VSWR switch until measurement is made. In ms resolution*/
+};
+
+static mykonosTxSettings_t txSettings =
+{
+    &txProfile,     /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/
+    &deframer,      /* Mykonos JESD204b deframer config for the Tx data path*/
+    TX1_TX2,        /* The desired Tx channels to enable during initialization*/
+    0,              /* Internal LO=0, external LO*2 if =1*/
+    2500000000U,    /* Tx PLL LO frequency (internal or external LO)*/
+    TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/
+    10000,          /* Initial and current Tx1 Attenuation mdB*/
+    10000,          /* Initial and current Tx2 Attenuation mdB*/
+    NULL,           /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/
+    NULL,           /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
+    NULL            /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
+};
+
+
+static mykonosObsRxSettings_t obsRxSettings =
+{
+    &orxProfile,    /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/
+    &orxGainControl,/* ObsRx gain control settings structure*/
+    &obsRxAgcConfig,/* ORx AGC control settings structure*/
+    &snifferProfile,/* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/
+    &snifferGainControl,/* SnRx gain control settings structure*/
+    &obsRxFramer,   /* ObsRx JESD204b framer configuration structure */
+    (MYK_ORX1_ORX2 | MYK_SNRXA_B_C),/* obsRxChannel */
+    OBSLO_TX_PLL,   /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */
+    2600000000U,    /* SnRx PLL LO frequency in Hz */
+    0,              /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/
+    NULL,           /* Custom Loopback ADC profile to set the bandwidth of the ADC response */
+    OBS_RXOFF       /* Default ObsRx channel to enter when radioOn called */
+};
+
+static mykonosArmGpioConfig_t armGpio =
+{
+    0,	// useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */
+    0,	// useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */
+    0,	// txRxPinMode;     /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */
+    0,	// orxPinMode;      /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/
+
+    /*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */
+    0,	// orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */
+    0,	// orxMode2Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+    0,	// orxMode1Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+    0,	// orxMode0Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+
+    /* Mykonos ARM output GPIO pins  --  always available, even when pin mode not enabled*/
+    0,	// rx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// rx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// tx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// tx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// orx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// orx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// srxEnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0 	// txObsSelect;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is   */
+    /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/
+};
+
+static mykonosGpio3v3_t gpio3v3 =
+{
+    0,				/*!< Oe per pin, 1=output, 0 = input */
+    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[3:0] */
+    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[7:4] */
+    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[11:8] */
+};
+
+static mykonosGpioLowVoltage_t gpio =
+{
+    0,/* Oe per pin, 1=output, 0 = input */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */
+};
+
+static mykonosAuxIo_t mykonosAuxIo =
+{
+    0,	//auxDacEnableMask uint16_t
+    {0,0,0,0,0,0,0,0,0,0},	 //AuxDacValue uint16[10]
+    {0,0,0,0,0,0,0,0,0,0},	 //AuxDacSlope uint8[10]
+    {0,0,0,0,0,0,0,0,0,0},	 //AuxDacVref uint8[10]
+    &gpio3v3,	//pointer to gpio3v3 struct
+    &gpio,	//pointer to gpio1v8 struct
+    &armGpio
+};
+
+static spiSettings_t mykSpiSettings =
+{
+    1, /* chip select index - valid 1~8 */
+    0, /* the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation */
+    1, /* 1 = 16-bit instruction word, 0 = 8-bit instruction word */
+    1, /* 1 = MSBFirst, 0 = LSBFirst */
+    0, /* clock phase, sets which clock edge the data updates (valid 0 or 1) */
+    0, /* clock polarity 0 = clock starts low, 1 = clock starts high */
+    0, /* Not implemented in ADIs platform layer. SW feature to improve SPI throughput */
+    1, /* Not implemented in ADIs platform layer. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr=addr-1 */
+    1  /* 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode */
+};
+
+static mykonosTempSensorConfig_t tempSensor =
+{
+    7,              /* 3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations; AuxADC_decimation = 256 * 2^tempDecimation*/
+    67,             /* 8-bit offset that gets added to temp sensor code internally*/
+    1,              /* this bit overrides the factory-calibrated fuse offset and uses the value stored in the offset member*/
+    15,             /* 4-bit code with a resolution of 1°C/LSB, each time a temperature measurement is performed, the device compares the current temperature against the previous value.*/
+};
+
+static mykonosTempSensorStatus_t tempStatus =
+{
+    0,              /* 16-bit signed temperature value (in deg C) that is read back*/
+    0,              /* If the absolute value of the difference is greater than the value in temperature configuration tempWindow, the windowExceeded flag is set.*/
+    0,              /* when windowExceeded member gets set, this bit is set to 1 if current value is greater than previous value, else reset*/
+    0,              /* when the reading is complete and a valid temperature value stored in tempCode.*/
+};
+
+mykonosDevice_t mykDevice =
+{
+    &mykSpiSettings,    /* SPI settings data structure pointer */
+    &rxSettings,        /* Rx settings data structure pointer */
+    &txSettings,        /* Tx settings data structure pointer */
+    &obsRxSettings,     /* ObsRx settings data structure pointer */
+    &mykonosAuxIo,          /* Auxiliary IO settings data structure pointer */
+    &mykonosClocks,     /* Holds settings for CLKPLL and reference clock */
+    0                   /* Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */
+};
diff --git a/mpm/lib/mykonos/adi_sample/mykonos_static_config.h b/mpm/lib/mykonos/adi_sample/mykonos_static_config.h
new file mode 100644
index 000000000..8b919fe5b
--- /dev/null
+++ b/mpm/lib/mykonos/adi_sample/mykonos_static_config.h
@@ -0,0 +1,18 @@
+/**
+ * \file myk_init.h
+ *
+ * \brief Contains structure definitions for myk_init.c
+ *
+ * The top level structure mykonosDevice_t mykDevice uses keyword
+ * extern to allow the application layer main() to have visibility
+ * to these settings.
+ */
+
+#ifndef MYK_INIT_H_
+#define MYK_INIT_H_
+
+#include "../adi/t_mykonos.h"
+
+extern mykonosDevice_t mykDevice;
+
+#endif
diff --git a/mpm/lib/mykonos/config/CMakeLists.txt b/mpm/lib/mykonos/config/CMakeLists.txt
new file mode 100644
index 000000000..dc52f2853
--- /dev/null
+++ b/mpm/lib/mykonos/config/CMakeLists.txt
@@ -0,0 +1,4 @@
+MYKONOS_APPEND_SOURCES(
+    ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_fir.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_config_t.cpp
+)
diff --git a/mpm/lib/mykonos/config/ad937x_config_t.cpp b/mpm/lib/mykonos/config/ad937x_config_t.cpp
new file mode 100644
index 000000000..5cfe6351e
--- /dev/null
+++ b/mpm/lib/mykonos/config/ad937x_config_t.cpp
@@ -0,0 +1,110 @@
+#include "ad937x_config_t.h"
+#include "mykonos_default_config.h"
+
+ad937x_config_t::ad937x_config_t()
+{
+    _assign_default_configuration();
+    _init_pointers();
+}
+
+void ad937x_config_t::_assign_default_configuration()
+{
+    // This is a pretty poor way of doing this, but the ADI structs force you
+    // to write spaghetti code sometimes.  This sets none of the required pointers,
+    // relying on a call to _init_pointers() to set all of them after the fact.
+    // TODO: do this better
+    _rx = DEFAULT_RX_SETTINGS;
+
+    _rxProfile = DEFAULT_RX_PROFILE;
+    _framer = DEFAULT_FRAMER;
+    _rxGainCtrl = DEFAULT_RX_GAIN;
+    _rxPeakAgc = DEFAULT_RX_PEAK_AGC;
+    _rxPowerAgc = DEFAULT_RX_POWER_AGC;
+    _rxAgcCtrl = DEFAULT_RX_AGC_CTRL;
+
+    _tx = DEFAULT_TX_SETTINGS;
+
+    _txProfile = DEFAULT_TX_PROFILE;
+    _deframer = DEFAULT_DEFRAMER;
+
+    // TODO: Likely an ADI bug.
+    // The TX bring up, for no reason, requires a valid ORX profile
+    // https://github.com/EttusResearch/uhddev/blob/eb2bcf9001b8e39eca8e62f0d6d5283895fae50d/embedded/libraries/mykonos/adi/mykonos.c#L16236
+
+    _obsRx = DEFAULT_ORX_SETTINGS;
+    _orxFramer = DEFAULT_ORX_FRAMER;
+    _orxProfile = DEFAULT_ORX_PROFILE;
+    _orxGainCtrl = DEFAULT_ORX_GAIN;
+    _orxPeakAgc = DEFAULT_ORX_PEAK_AGC;
+    _orxPowerAgc = DEFAULT_ORX_POWER_AGC;
+    _orxAgcCtrl = DEFAULT_ORX_AGC_CTRL;
+
+    _armGpio = DEFAULT_ARM_GPIO;
+    _gpio3v3 = DEFAULT_GPIO_3V3;
+    _gpio = DEFAULT_GPIO;
+    _auxIo = DEFAULT_AUX_IO;
+
+    _clocks = DEFAULT_CLOCKS;
+
+    _assign_firs();
+}
+
+void ad937x_config_t::_init_pointers()
+{
+    _device.spiSettings = &_spiSettings;
+    _device.rx = &_rx;
+    _device.tx = &_tx;
+    _device.obsRx = &_obsRx;
+    _device.auxIo = &_auxIo;
+    _device.clocks = &_clocks;
+
+    _rx.rxProfile = &_rxProfile;
+    _rxProfile.rxFir = _rx_fir_config.getFir();
+    _rx.framer = &_framer;
+    _rx.rxGainCtrl = &_rxGainCtrl;
+    _rx.rxAgcCtrl = &_rxAgcCtrl;
+    _rxAgcCtrl.peakAgc = &_rxPeakAgc;
+    _rxAgcCtrl.powerAgc = &_rxPowerAgc;
+
+    _tx.txProfile = &_txProfile;
+    _txProfile.txFir = _tx_fir_config.getFir();
+    _tx.deframer = &_deframer;
+
+    // AD9373
+    //_tx.dpdConfig = &_dpdConfig;
+    //_tx.clgcConfig = &_clgcConfig;
+    //_tx.vswrConfig = &_vswrConfig;
+
+    _obsRx.orxProfile = &_orxProfile;
+    _orxProfile.rxFir = _orx_fir_config.getFir();
+    _obsRx.orxGainCtrl = &_orxGainCtrl;
+    _obsRx.orxAgcCtrl = &_orxAgcCtrl;
+    _orxAgcCtrl.peakAgc = &_orxPeakAgc;
+    _orxAgcCtrl.powerAgc = &_orxPowerAgc;
+
+    _obsRx.snifferProfile = &_snifferProfile;
+    _snifferProfile.rxFir = _sniffer_rx_fir_config.getFir();
+    _obsRx.snifferGainCtrl = &_snifferGainCtrl;
+    // sniffer has no AGC ctrl, so leave as null
+    _obsRx.framer = &_orxFramer;
+
+    _auxIo.gpio3v3 = &_gpio3v3;
+    _auxIo.gpio = &_gpio;
+    _auxIo.armGpio = &_armGpio;
+}
+
+void ad937x_config_t::_assign_firs()
+{
+    // TODO: In general, storing just these pointers could lead to Bad Stuff
+    // Consider if it would be helpful to enforce some pointer safety here
+    // (if that's even possible with the C API)
+    _rx_fir_config = { -6,{ 48, 0 } };
+    _rxProfile.rxFir = _rx_fir_config.getFir();
+    _tx_fir_config = { 6,{ 32, 0 } };
+    _txProfile.txFir = _tx_fir_config.getFir();
+    _orx_fir_config = { -6, { 48, 0 } };
+    _orxProfile.rxFir = _orx_fir_config.getFir();
+    _sniffer_rx_fir_config = { -6, { 48, 0 } };
+    _snifferProfile.rxFir = _sniffer_rx_fir_config.getFir();
+}
+
diff --git a/mpm/lib/mykonos/config/ad937x_config_t.hpp b/mpm/lib/mykonos/config/ad937x_config_t.hpp
new file mode 100644
index 000000000..5375e0867
--- /dev/null
+++ b/mpm/lib/mykonos/config/ad937x_config_t.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "../adi/t_mykonos.h"
+#include "ad937x_fir.h"
+#include <boost/noncopyable.hpp>
+
+// This class exists so that the entire mykonos config can be allocated and managed together
+class ad937x_device  : public boost::noncopyable
+{
+    // The top level device struct contains all other structs, so everything is technically "public"
+    // a user could technically modify the pointers in the structs, but we have no way of preventing that
+public:
+    ad937x_device();
+    mykonosDevice_t * const device = &_device;
+
+private:
+    mykonosDevice_t _device;
+
+    // in general, this organization stinks
+    // TODO: group and make more sense of these fields and pointers
+    spiSettings_t _spiSettings;
+    mykonosRxSettings_t _rx;
+    mykonosTxSettings_t _tx;
+    mykonosObsRxSettings_t _obsRx;
+    mykonosAuxIo_t _auxIo;
+    mykonosDigClocks_t _clocks;
+
+    ad937x_fir _rx_fir_config;
+    mykonosRxProfile_t _rxProfile;
+    std::vector<uint16_t> _customRxAdcProfile;
+    mykonosJesd204bFramerConfig_t _framer;
+    mykonosRxGainControl_t _rxGainCtrl;
+    mykonosAgcCfg_t _rxAgcCtrl;
+    mykonosPeakDetAgcCfg_t _rxPeakAgc;
+    mykonosPowerMeasAgcCfg_t _rxPowerAgc;
+
+    ad937x_fir _tx_fir_config;
+    mykonosTxProfile_t _txProfile;
+    mykonosJesd204bDeframerConfig_t _deframer;
+    mykonosDpdConfig_t _dpdConfig;
+    mykonosClgcConfig_t _clgcConfig;
+    mykonosVswrConfig_t _vswrConfig;
+
+    ad937x_fir _orx_fir_config;
+    mykonosRxProfile_t _orxProfile;
+    mykonosORxGainControl_t _orxGainCtrl;
+    mykonosAgcCfg_t _orxAgcCtrl;
+    mykonosPeakDetAgcCfg_t _orxPeakAgc;
+    mykonosPowerMeasAgcCfg_t _orxPowerAgc;
+
+    ad937x_fir _sniffer_rx_fir_config;
+    mykonosRxProfile_t _snifferProfile;
+    mykonosSnifferGainControl_t _snifferGainCtrl;
+    mykonosJesd204bFramerConfig_t _orxFramer;
+    std::vector<uint16_t> _customORxAdcProfile;
+
+    mykonosGpio3v3_t _gpio3v3;
+    mykonosGpioLowVoltage_t _gpio;
+    mykonosArmGpioConfig_t _armGpio;
+
+    void _init_pointers();
+    void _assign_firs();
+    void _assign_default_configuration();
+};
diff --git a/mpm/lib/mykonos/config/ad937x_fir.cpp b/mpm/lib/mykonos/config/ad937x_fir.cpp
new file mode 100644
index 000000000..a9ede3318
--- /dev/null
+++ b/mpm/lib/mykonos/config/ad937x_fir.cpp
@@ -0,0 +1,37 @@
+#include "ad937x_fir.h"
+#include <limits>
+
+ad937x_fir::ad937x_fir(int8_t gain, const std::vector<int16_t>& coefficients)
+{
+   
+    _set_gain(gain);
+}
+
+ad937x_fir::ad937x_fir(int8_t gain, std::vector<int16_t>&& coefficients)
+{
+    set_coefficients(std::move(coefficients));
+    _set_gain(gain);
+}
+
+mykonosFir_t* ad937x_fir::getFir()
+{
+    return &(_fir);
+}
+
+void ad937x_fir::set_coefficients(std::vector<int16_t>&& coefficients)
+{
+    if (coefficients.size() < std::numeric_limits<decltype(mykonosFir_t().numFirCoefs)>::max() ||
+        coefficients.size() > 0)
+    {
+        // TODO: exception
+    }
+    fir_coefficients = std::move(coefficients);
+    _fir.numFirCoefs = static_cast<uint8_t>(fir_coefficients.size());
+    _fir.coefs = &fir_coefficients[0];
+}
+
+void ad937x_fir::_set_gain(int8_t gain)
+{
+    _fir.gain_dB = gain;
+}
+
diff --git a/mpm/lib/mykonos/config/ad937x_fir.h b/mpm/lib/mykonos/config/ad937x_fir.h
new file mode 100644
index 000000000..ff277ef26
--- /dev/null
+++ b/mpm/lib/mykonos/config/ad937x_fir.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <vector>
+#include "../adi/t_mykonos.h"
+
+// wraps FIR allocation
+class ad937x_fir
+{
+    // these should be const, but can't be because of C API
+    // 
+    mykonosFir_t _fir;
+    std::vector<int16_t> fir_coefficients;
+
+    void ad937x_fir::_set_gain(int8_t gain);
+public:
+    ad937x_fir(int8_t gain, const std::vector<int16_t>& coefficients);
+    ad937x_fir(int8_t gain, std::vector<int16_t>&& coefficients);
+
+    mykonosFir_t* getFir();
+};
+
+
diff --git a/mpm/lib/mykonos/config/mykonos_default_config.h b/mpm/lib/mykonos/config/mykonos_default_config.h
new file mode 100644
index 000000000..a5ed4fe6c
--- /dev/null
+++ b/mpm/lib/mykonos/config/mykonos_default_config.h
@@ -0,0 +1,359 @@
+#include "../adi/t_mykonos.h"
+
+// This file is more or less the static config provided by a run of the eval software
+// except all pointers have been changed to NULL
+// Hopefully this helps the compiler use these as purely constants
+// The pointers should be filled in if these data structures are to be actually used with the API
+
+static const mykonosRxSettings_t DEFAULT_RX_SETTINGS =
+{
+    NULL,           /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/
+    NULL,           /* Rx JESD204b framer configuration structure*/
+    NULL,           /* Rx Gain control settings structure*/
+    NULL,           /* Rx AGC control settings structure*/
+    RX1_RX2,        /* The desired Rx Channels to enable during initialization*/
+    0,              /* Internal LO = 0, external LO*2 = 1*/
+    3500000000U, /* Rx PLL LO Frequency (internal or external LO)*/
+    0               /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/
+};
+
+static const mykonosRxProfile_t DEFAULT_RX_PROFILE =
+{/* Rx 100MHz, IQrate 122.88MHz, Dec5 */
+    1,              /* The divider used to generate the ADC clock*/
+    NULL,           /* Pointer to Rx FIR filter structure*/
+    2,              /* Rx FIR decimation (1,2,4)*/
+    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/
+    1,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
+    1,              /* RX Half band 1 decimation (1 or 2)*/
+    122880,         /* Rx IQ data rate in kHz*/
+    100000000,    /* The Rx RF passband bandwidth for the profile*/
+    100000,         /* Rx BBF 3dB corner in kHz*/
+    NULL            /* pointer to custom ADC profile*/
+};
+
+static const mykonosJesd204bFramerConfig_t DEFAULT_FRAMER =
+{
+    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
+    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
+    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
+    4,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
+    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
+    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
+    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/
+    0x0F,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
+    0xE4,           /* serializerLaneCrossbar*/
+    26,             /* serializerAmplitude - default 22 (valid (0-31)*/
+    0,              /* preEmphasis - < default 4 (valid 0 - 7)*/
+    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
+    0,              /* lmfcOffset - LMFC offset value for deterministic latency setting*/
+    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
+    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
+    0,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
+    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
+    0               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
+};
+
+static const mykonosRxGainControl_t DEFAULT_RX_GAIN =
+{
+    MGC,            /* Current Rx gain control mode setting*/
+    255,            /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* Max gain index for the currently loaded Rx1 Gain table*/
+    195,            /* Min gain index for the currently loaded Rx1 Gain table*/
+    255,            /* Max gain index for the currently loaded Rx2 Gain table*/
+    195,            /* Min gain index for the currently loaded Rx2 Gain table*/
+    0,              /* Stores Rx1 RSSI value read back from the Mykonos*/
+    0               /* Stores Rx2 RSSI value read back from the Mykonos*/
+};
+
+static const mykonosPeakDetAgcCfg_t DEFAULT_RX_PEAK_AGC =
+{
+    0x1F,	/* apdHighThresh: */
+    0x16,	/* apdLowThresh */
+    0xB5,	/* hb2HighThresh */
+    0x80,	/* hb2LowThresh */
+    0x40,	/* hb2VeryLowThresh */
+    0x06,	/* apdHighThreshExceededCnt */
+    0x04,	/* apdLowThreshExceededCnt */
+    0x06,	/* hb2HighThreshExceededCnt */
+    0x04,	/* hb2LowThreshExceededCnt */
+    0x04,	/* hb2VeryLowThreshExceededCnt */
+    0x4,	/* apdHighGainStepAttack */
+    0x2,	/* apdLowGainStepRecovery */
+    0x4,	/* hb2HighGainStepAttack */
+    0x2,	/* hb2LowGainStepRecovery */
+    0x4,	/* hb2VeryLowGainStepRecovery */
+    0x1,	/* apdFastAttack */
+    0x1,	/* hb2FastAttack */
+    0x1,	/* hb2OverloadDetectEnable */
+    0x1,	/* hb2OverloadDurationCnt */
+    0x1	    /* hb2OverloadThreshCnt */
+};
+
+static const mykonosPowerMeasAgcCfg_t DEFAULT_RX_POWER_AGC =
+{
+    0x01,	/* pmdUpperHighThresh */
+    0x03,	/* pmdUpperLowThresh */
+    0x0C,	/* pmdLowerHighThresh */
+    0x04,	/* pmdLowerLowThresh */
+    0x4,	/* pmdUpperHighGainStepAttack */
+    0x2,	/* pmdUpperLowGainStepAttack */
+    0x2,	/* pmdLowerHighGainStepRecovery */
+    0x4,	/* pmdLowerLowGainStepRecovery */
+    0x08,	/* pmdMeasDuration */
+    0x02	/* pmdMeasConfig */
+};
+
+static const mykonosAgcCfg_t DEFAULT_RX_AGC_CTRL =
+{
+    255,	/* AGC peak wait time */
+    195,	/* agcRx1MinGainIndex */
+    255,	/* agcRx2MaxGainIndex */
+    195,	/* agcRx2MinGainIndex: */
+    255,	/* agcObsRxMaxGainIndex */
+    203,	/* agcObsRxMinGainIndex */
+    1,		/* agcObsRxSelect */
+    1,		/* agcPeakThresholdMode */
+    1,		/* agcLowThsPreventGainIncrease */
+    30720,	/* agcGainUpdateCounter */
+    3,	    /* agcSlowLoopSettlingDelay */
+    2,	    /* agcPeakWaitTime */
+    0,	    /* agcResetOnRxEnable */
+    0,	    /* agcEnableSyncPulseForGainCounter */
+    NULL,
+    NULL
+};
+
+static const mykonosTxSettings_t DEFAULT_TX_SETTINGS =
+{
+    NULL,           /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/
+    NULL,           /* Mykonos JESD204b deframer config for the Tx data path*/
+    TX1_TX2,        /* The desired Tx channels to enable during initialization*/
+    0,              /* Internal LO=0, external LO*2 if =1*/
+    3500000000U, /* Tx PLL LO frequency (internal or external LO)*/
+    TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/
+    10000,          /* Initial and current Tx1 Attenuation mdB*/
+    10000,          /* Initial and current Tx2 Attenuation mdB*/
+    NULL,           /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/
+    NULL,           /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
+    NULL            /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/
+};
+
+static const mykonosTxProfile_t DEFAULT_TX_PROFILE =
+{ /* Tx 20/100MHz, IQrate 122.88MHz, Dec5 */
+    DACDIV_2p5,     /* The divider used to generate the DAC clock*/
+    NULL,           /* Pointer to Tx FIR filter structure*/
+    2,              /* The Tx digital FIR filter interpolation (1,2,4)*/
+    2,              /* Tx Halfband1 filter interpolation (1,2)*/
+    1,              /* Tx Halfband2 filter interpolation (1,2)*/
+    1,              /* TxInputHbInterpolation (1,2)*/
+    122880,         /* Tx IQ data rate in kHz*/
+    20000000,       /* Primary Signal BW*/
+    100000000,    /* The Tx RF passband bandwidth for the profile*/
+    710539,         /* The DAC filter 3dB corner in kHz*/
+    50000,          /* Tx BBF 3dB corner in kHz*/
+    0               /* Enable DPD, only valid for AD9373*/
+};
+
+static const mykonosJesd204bDeframerConfig_t DEFAULT_DEFRAMER =
+{
+    0,              /* bankId extension to Device ID (Valid 0..15)*/
+    0,              /* deviceId  link identification number. (Valid 0..255)*/
+    0,              /* lane0Id Lane0 ID. (Valid 0..31)*/
+    4,              /* M  number of DACss (0, 2, or 4) - 2 DACs per transmit chain */
+    32,             /* K  #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/
+    0,              /* Scrambling off if scramble = 0, if framerScramble > 0 scrambling is enabled*/
+    1,              /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/
+    0x0F,           /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */
+    0xE4,           /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */
+    1,              /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/
+    0,              /* PN inversion per each lane.  bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/
+    0,              /* LMFC offset value to adjust deterministic latency. Range is 0..31*/
+    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/
+    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
+    0               /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
+};
+
+static const mykonosObsRxSettings_t DEFAULT_ORX_SETTINGS =
+{
+    NULL,           /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/
+    NULL,           /* ObsRx gain control settings structure*/
+    NULL,           /* ORx AGC control settings structure*/
+    NULL,           /* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/
+    NULL,           /* SnRx gain control settings structure*/
+    NULL,           /* ObsRx JESD204b framer configuration structure */
+    MYK_OBS_RXOFF,  /* obsRxChannel */
+    OBSLO_TX_PLL,   /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */
+    2600000000U, /* SnRx PLL LO frequency in Hz */
+    0,              /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/
+    NULL,           /* Custom Loopback ADC profile to set the bandwidth of the ADC response */
+    OBS_RXOFF       /* Default ObsRx channel to enter when radioOn called */
+};
+
+static const mykonosJesd204bFramerConfig_t DEFAULT_ORX_FRAMER =
+{
+    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/
+    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/
+    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/
+    2,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/
+    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/
+    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/
+    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/
+    0x00,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/
+    0xE4,           /* Lane crossbar to map framer lane outputs to physical lanes*/
+    22,             /* serializerAmplitude - default 22 (valid (0-31)*/
+    4,              /* preEmphasis - < default 4 (valid 0 - 7)*/
+    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/
+    0,              /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/
+    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/
+    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/
+    1,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/
+    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/
+    1               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/
+};
+
+static const mykonosORxGainControl_t DEFAULT_ORX_GAIN =
+{
+    MGC,            /* Current ORx gain control mode setting*/
+    255,            /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/
+    255,            /* Max gain index for the currently loaded ORx Gain table*/
+    237             /* Min gain index for the currently loaded ORx Gain table*/
+};
+
+static const mykonosAgcCfg_t DEFAULT_ORX_AGC_CTRL =
+{
+    0,	/* agcRx1MaxGainIndex */
+    0,	/* agcRx1MinGainIndex */
+    0,	/* agcRx2MaxGainIndex */
+    0,	/* agcRx2MinGainIndex: */
+    0,	/* agcObsRxMaxGainIndex */
+    0,	/* agcObsRxMinGainIndex */
+    0,		/* agcObsRxSelect */
+    0,		/* agcPeakThresholdMode */
+    0,		/* agcLowThsPreventGainIncrease */
+    0,	/* agcGainUpdateCounter */
+    0,	/* agcSlowLoopSettlingDelay */
+    0,	/* agcPeakWaitTime */
+    0,	/* agcResetOnRxEnable */
+    0,	/* agcEnableSyncPulseForGainCounter */
+    NULL,
+    NULL
+};
+
+static const mykonosPeakDetAgcCfg_t DEFAULT_ORX_PEAK_AGC =
+{
+    0x00,	/* apdHighThresh: */
+    0x00,	/* apdLowThresh */
+    0x00,	/* hb2HighThresh */
+    0x00,	/* hb2LowThresh */
+    0x00,	/* hb2VeryLowThresh */
+    0x00,	/* apdHighThreshExceededCnt */
+    0x00,	/* apdLowThreshExceededCnt */
+    0x00,	/* hb2HighThreshExceededCnt */
+    0x00,	/* hb2LowThreshExceededCnt */
+    0x00,	/* hb2VeryLowThreshExceededCnt */
+    0x0,	/* apdHighGainStepAttack */
+    0x0,	/* apdLowGainStepRecovery */
+    0x0,	/* hb2HighGainStepAttack */
+    0x0,	/* hb2LowGainStepRecovery */
+    0x0,	/* hb2VeryLowGainStepRecovery */
+    0x0,	/* apdFastAttack */
+    0x0,	/* hb2FastAttack */
+    0x0,	/* hb2OverloadDetectEnable */
+    0x0,	/* hb2OverloadDurationCnt */
+    0x0		/* hb2OverloadThreshCnt */
+};
+
+static const mykonosPowerMeasAgcCfg_t DEFAULT_ORX_POWER_AGC =
+{
+    0x00,	/* pmdUpperHighThresh */
+    0x00,	/* pmdUpperLowThresh */
+    0x00,	/* pmdLowerHighThresh */
+    0x00,	/* pmdLowerLowThresh */
+    0x0,	/* pmdUpperHighGainStepAttack */
+    0x0,	/* pmdUpperLowGainStepAttack */
+    0x0,	/* pmdLowerHighGainStepRecovery */
+    0x0,	/* pmdLowerLowGainStepRecovery */
+    0x00,	/* pmdMeasDuration */
+    0x00	/* pmdMeasConfig */
+};
+
+static const mykonosRxProfile_t DEFAULT_ORX_PROFILE =
+{/* ORX 100MHz, IQrate 125MSPS, Dec5 */
+    1,              /* The divider used to generate the ADC clock*/
+    NULL,           /* Pointer to Rx FIR filter structure or NULL*/
+    2,              /* Rx FIR decimation (1,2,4)*/
+    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/
+    0,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/
+    1,              /* RX Half band 1 decimation (1 or 2)*/
+    125000,        /* Rx IQ data rate in kHz*/
+    100000000,    /* The Rx RF passband bandwidth for the profile*/
+    102000,        /* Rx BBF 3dB corner in kHz*/
+    NULL            /* pointer to custom ADC profile*/
+};
+
+static const mykonosArmGpioConfig_t DEFAULT_ARM_GPIO =
+{
+    0,	// useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */
+    0,	// useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */
+    0,	// txRxPinMode;     /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */
+    0,	// orxPinMode;      /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/
+
+    /*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */
+    0,	// orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */
+    0,	// orxMode2Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+    0,	// orxMode1Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+    0,	// orxMode0Pin;   /*!< Select desired GPIO pin (valid 0-18) */
+
+    /* Mykonos ARM output GPIO pins  --  always available, even when pin mode not enabled*/
+    0,	// rx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// rx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// tx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// tx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// orx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// orx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0,	// srxEnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+    0 	// txObsSelect;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */
+        /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is   */
+        /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/
+};
+
+static const mykonosGpio3v3_t DEFAULT_GPIO_3V3 =
+{
+    0,				/*!< Oe per pin, 1=output, 0 = input */
+    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[3:0] */
+    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[7:4] */
+    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[11:8] */
+};
+
+static const mykonosGpioLowVoltage_t DEFAULT_GPIO =
+{
+    0,/* Oe per pin, 1=output, 0 = input */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */
+    GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */
+};
+
+static const mykonosAuxIo_t DEFAULT_AUX_IO =
+{
+    0,	//auxDacEnableMask uint16_t
+    { 0,0,0,0,0,0,0,0,0,0 },	 //AuxDacValue uint16[10]
+    { 0,0,0,0,0,0,0,0,0,0 },	 //AuxDacSlope uint8[10]
+    { 0,0,0,0,0,0,0,0,0,0 },	 //AuxDacVref uint8[10]
+    NULL,	//pointer to gpio3v3 struct
+    NULL,	//pointer to gpio1v8 struct
+    NULL
+};
+
+static const mykonosDigClocks_t DEFAULT_CLOCKS =
+{
+    122880,         /* CLKPLL and device reference clock frequency in kHz*/
+    9830400,        /* CLKPLL VCO frequency in kHz*/
+    VCODIV_2,       /* CLKPLL VCO divider*/
+    4               /* CLKPLL high speed clock divider*/
+};
+
+
diff --git a/mpm/lib/print_foo.cpp b/mpm/lib/print_foo.cpp
new file mode 100644
index 000000000..4f6d69775
--- /dev/null
+++ b/mpm/lib/print_foo.cpp
@@ -0,0 +1,8 @@
+#include <iostream>
+#include <mpm/print_foo.hpp>
+
+void mpm::print_foo()
+{
+    std::cout << "foo" << std::endl;
+}
+
diff --git a/mpm/lib/spi/CMakeLists.txt b/mpm/lib/spi/CMakeLists.txt
new file mode 100644
index 000000000..b84c0de73
--- /dev/null
+++ b/mpm/lib/spi/CMakeLists.txt
@@ -0,0 +1,8 @@
+SET(SPI_SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/spi_lock.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/spi_config.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/mock_spi.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/spidev_iface.cpp
+)
+
+USRP_PERIPHS_ADD_OBJECT(spi ${SPI_SOURCES})
diff --git a/mpm/lib/spi/mock_spi.cpp b/mpm/lib/spi/mock_spi.cpp
new file mode 100644
index 000000000..2508de3ce
--- /dev/null
+++ b/mpm/lib/spi/mock_spi.cpp
@@ -0,0 +1,117 @@
+//
+// Copyright 2014 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+/*
+#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
+#include "n310_spi.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
+
+class spidev_impl : public spi
+{
+public:
+    
+    spidev_impl(const std::string &device)
+        : _mode(SPI_CPHA),
+        _speed(2000000),
+        _bits(8),
+        _delay(0)
+    {
+        int ret;
+        _fd = open(device.c_str(), O_RDWR);
+        if (_fd < 0)
+            throw uhd::runtime_error(str(boost::format("Could not open spidev device %s") % device));
+
+        ret = ioctl(_fd, SPI_IOC_WR_MODE, &_mode);
+        if (ret == -1)
+            throw uhd::runtime_error("Could not set spidev mode");
+
+        ret = ioctl(_fd, SPI_IOC_RD_MODE, &_mode);
+        if (ret == -1)
+            throw uhd::runtime_error("Could not get spidev mode");
+
+        ret = ioctl(_fd, SPI_IOC_WR_BITS_PER_WORD, &_bits);
+        if (ret == -1)
+            throw uhd::runtime_error("Could not set spidev bits per word");
+
+        ret = ioctl(_fd, SPI_IOC_RD_BITS_PER_WORD, &_bits);
+        if (ret == -1)
+            throw uhd::runtime_error("Could not get spidev bits per word");
+
+        ret = ioctl(_fd, SPI_IOC_WR_MAX_SPEED_HZ, &_speed);
+        if (ret == -1)
+            throw uhd::runtime_error("Could not set spidev max speed");
+
+        ret = ioctl(_fd, SPI_IOC_RD_MAX_SPEED_HZ, &_speed);
+        if (ret == -1)
+            throw uhd::runtime_error("Could not get spidev max speed");
+    }
+
+    virtual ~spidev_impl()
+    {
+        close(_fd);
+    }
+
+    uint32_t transact_spi(int, const uhd::spi_config_t &,
+        uint32_t data, size_t num_bits,
+        bool)
+    {
+        int ret(0);
+        struct spi_ioc_transfer tr;
+
+        uint8_t *tx_data = reinterpret_cast<uint8_t *>(&data);
+
+
+        UHD_ASSERT_THROW(num_bits == 24);
+        uint8_t tx[] = { tx_data[2], tx_data[1], tx_data[0] };
+
+        uint8_t rx[3];
+        tr.tx_buf = (unsigned long)&tx[0];
+        tr.rx_buf = (unsigned long)&rx[0];
+        tr.len = num_bits >> 3;
+        tr.bits_per_word = _bits;
+        tr.tx_nbits = 1;
+        tr.rx_nbits = 1;
+        tr.speed_hz = _speed;
+        tr.delay_usecs = _delay;
+
+        ret = ioctl(_fd, SPI_IOC_MESSAGE(1), &tr);
+        if (ret < 1)
+            throw uhd::runtime_error("Could not send spidev message");
+
+        return rx[2];
+    }
+
+private:
+    int _fd;
+    uint8_t _mode;
+    uint32_t _speed;
+    uint8_t _bits;
+    uint16_t _delay;
+    
+};
+
+spi::sptr spi::make(const std::string &device)
+{
+    return spi::sptr(new spidev_impl(device));
+}
+*/
\ No newline at end of file
diff --git a/mpm/lib/spi/mock_spi.h b/mpm/lib/spi/mock_spi.h
new file mode 100644
index 000000000..c289faa16
--- /dev/null
+++ b/mpm/lib/spi/mock_spi.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <uhd/types/serial.hpp>
+
+class mock_spi : public virtual uhd::spi_iface
+{
+public:
+    typedef boost::shared_ptr<spi> sptr;
+    static sptr make(const std::string &device);
+};
diff --git a/mpm/lib/spi/spi_config.cpp b/mpm/lib/spi/spi_config.cpp
new file mode 100644
index 000000000..69d6d9c2a
--- /dev/null
+++ b/mpm/lib/spi/spi_config.cpp
@@ -0,0 +1,37 @@
+#include "spi_config.h"
+
+
+spi_config_t::spi_config_t(const spi_hwd_settings_t hwd_settings, const spi_device_settings_t device_settings) :
+    full_settings({
+        _convert_to_adi_settings(hwd_settings.chip_select_index, device_settings),
+        hwd_settings })
+{
+
+}
+
+spiSettings_t spi_config_t::_convert_to_adi_settings(const uint8_t chip_select_index, const spi_device_settings_t device_settings)
+{
+    return {
+        chip_select_index,
+        device_settings.writeBitPolarity,
+        device_settings.longInstructionWord,
+        device_settings.MSBFirst,
+        device_settings.CPHA,
+        device_settings.CPOL,
+        device_settings.enSpiStreaming,
+        device_settings.autoIncAddrUp,
+        device_settings.fourWireMode,
+        device_settings.spiClkFreq_Hz,
+    };
+}
+
+const spiSettings_t* spi_config_t::get_spi_settings() const
+{
+    return &(full_settings.adi_settings);
+}
+
+const spi_full_settings_t* spi_config_t::recover_full_spi_settings(const spiSettings_t* settings)
+{
+    // TODO: make this better
+    return reinterpret_cast<const spi_full_settings_t*>(settings);
+}
diff --git a/mpm/lib/spi/spi_config.h b/mpm/lib/spi/spi_config.h
new file mode 100644
index 000000000..a29a9bc64
--- /dev/null
+++ b/mpm/lib/spi/spi_config.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "../mykonos/adi/common.h"
+
+// contains information about the spi configuration
+
+struct spi_device_settings_t
+{
+    uint8_t writeBitPolarity;
+    uint8_t longInstructionWord;    ///< 1 = 16bit instruction word, 0 = 8bit instruction word
+    uint8_t MSBFirst;               ///< 1 = MSBFirst, 0 = LSBFirst
+    uint8_t CPHA;                   ///< clock phase, sets which clock edge the data updates (valid 0 or 1)
+    uint8_t CPOL;                   ///< clock polarity 0 = clock starts low, 1 = clock starts high
+    uint8_t enSpiStreaming;         ///< Not implemented. SW feature to improve SPI throughput.
+    uint8_t autoIncAddrUp;          ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1
+    uint8_t fourWireMode;           ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode.
+    uint32_t spiClkFreq_Hz;
+};
+
+struct spi_hwd_settings_t
+{
+    uint8_t spidev_index;
+    uint8_t chip_select_index;
+};
+
+struct spi_full_settings_t
+{
+    spiSettings_t adi_settings;
+    spi_hwd_settings_t hwd_settings;
+};
+
+class spi_config_t
+{
+public:
+    spi_config_t(spi_hwd_settings_t hwd_settings, spi_device_settings_t device_settings);
+
+private:
+    const spi_full_settings_t full_settings;
+    static spiSettings_t _convert_to_adi_settings(uint8_t chip_select_index, spi_device_settings_t device_settings);
+
+public:
+    const spiSettings_t* get_spi_settings() const;
+    static const spi_full_settings_t* recover_full_spi_settings(const spiSettings_t* settings);
+};
diff --git a/mpm/lib/spi/spi_lock.cpp b/mpm/lib/spi/spi_lock.cpp
new file mode 100644
index 000000000..1796de46a
--- /dev/null
+++ b/mpm/lib/spi/spi_lock.cpp
@@ -0,0 +1,26 @@
+#include "spi_lock.h"
+
+spi_lock::spi_lock(uint8_t spidev_index) :
+    spidev_index(spidev_index)
+{
+
+}
+
+uint8_t spi_lock::get_spidev() const
+{
+    return spidev_index;
+}
+
+void spi_lock::lock()
+{
+    spi_mutex.lock();
+}
+void spi_lock::unlock()
+{
+    spi_mutex.unlock();
+}
+
+spi_lock::sptr spi_lock::make(uint8_t spidev_index)
+{
+    return std::make_shared<spi_lock>(spidev_index);
+}
\ No newline at end of file
diff --git a/mpm/lib/spi/spi_lock.h b/mpm/lib/spi/spi_lock.h
new file mode 100644
index 000000000..55ddb0baf
--- /dev/null
+++ b/mpm/lib/spi/spi_lock.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include <memory>
+#include <mutex>
+
+class spi_lock : public boost::noncopyable
+{
+public:
+    using sptr = std::shared_ptr<spi_lock>;
+    static sptr make(uint8_t spidev_index);
+
+    spi_lock(uint8_t spidev_index);
+
+    uint8_t get_spidev() const;
+
+private:
+    const uint8_t spidev_index;
+
+    // BasicLockable implementation for lock_guard
+    mutable std::mutex spi_mutex;
+    friend class std::lock_guard<spi_lock>;
+    void lock();
+    void unlock();
+};
\ No newline at end of file
diff --git a/mpm/lib/spi/spidev_iface.cpp b/mpm/lib/spi/spidev_iface.cpp
new file mode 100644
index 000000000..7108759f8
--- /dev/null
+++ b/mpm/lib/spi/spidev_iface.cpp
@@ -0,0 +1,155 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "mpm/spi/spidev_iface.hpp"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+#include <boost/format.hpp>
+
+using namespace mpm::spi;
+
+/******************************************************************************
+ * Implementation
+ *****************************************************************************/
+class spidev_iface_impl : public spidev_iface
+{
+public:
+
+    spidev_iface_impl(
+            const std::string &device
+    ) {
+        int ret;
+
+        _fd = open(device.c_str(), O_RDWR);
+        if (_fd < 0) {
+            throw std::runtime_error(str(
+                    boost::format("Could not open spidev device %s")
+                    % device
+            ));
+        }
+
+        ret = ioctl(_fd, SPI_IOC_WR_MODE32, &_mode);
+        if (ret == -1) {
+            throw std::runtime_error("Could not set spidev mode");
+        }
+
+        ret = ioctl(_fd, SPI_IOC_RD_MODE32, &_mode);
+        if (ret == -1) {
+            throw std::runtime_error("Could not get spidev mode");
+        }
+
+        ret = ioctl(_fd, SPI_IOC_WR_BITS_PER_WORD, &_bits);
+        if (ret == -1) {
+            throw std::runtime_error("Could not set spidev bits per word");
+        }
+
+        ret = ioctl(_fd, SPI_IOC_RD_BITS_PER_WORD, &_bits);
+        if (ret == -1) {
+            throw std::runtime_error("Could not get spidev bits per word");
+        }
+
+        ret = ioctl(_fd, SPI_IOC_WR_MAX_SPEED_HZ, &_speed);
+        if (ret == -1) {
+            throw std::runtime_error("Could not set spidev max speed");
+        }
+
+        ret = ioctl(_fd, SPI_IOC_RD_MAX_SPEED_HZ, &_speed);
+        if (ret == -1) {
+            throw std::runtime_error("Could not get spidev max speed");
+        }
+    }
+
+    ~spidev_iface_impl()
+    {
+        close(_fd);
+    }
+
+    uint32_t transact_spi(
+            int /* which_slave */,
+            const uhd::spi_config_t & /* config */,
+            uint32_t data,
+            size_t num_bits,
+            bool readback
+    ) {
+        int ret(0);
+
+        uint8_t *tx_data = reinterpret_cast<uint8_t *>(&data);
+
+        assert(num_bits == 24);
+        uint8_t tx[] = {tx_data[2], tx_data[1], tx_data[0]};
+
+        uint8_t rx[3]; // Buffer length must match tx buffer
+
+        struct spi_ioc_transfer tr;
+        tr.tx_buf = (unsigned long) &tx[0];
+        tr.rx_buf = (unsigned long) &rx[0];
+        tr.len = num_bits >> 3;
+        tr.bits_per_word = _bits;
+        tr.tx_nbits = 1; // Standard SPI
+        tr.rx_nbits = 1; // Standard SPI
+        tr.speed_hz = _speed;
+        tr.delay_usecs = _delay;
+
+        ret = ioctl(_fd, SPI_IOC_MESSAGE(1), &tr);
+        if (ret < 1)
+            throw std::runtime_error("Could not send spidev message");
+
+        return rx[2]; // Assumes that only a single byte is being read.
+    }
+
+    uint32_t read_spi(
+            int which_slave,
+            const uhd::spi_config_t &config,
+            uint32_t data,
+            size_t num_bits
+    ) {
+        return transact_spi(
+                which_slave, config, data, num_bits, true
+        );
+    }
+
+    void write_spi(
+            int which_slave,
+            const uhd::spi_config_t &config,
+            uint32_t data,
+            size_t num_bits
+    ) {
+        transact_spi(
+                which_slave, config, data, num_bits, false
+        );
+    }
+
+private:
+    int _fd;
+    uint8_t _mode = SPI_CPHA | SPI_CPOL;
+    uint32_t _speed = 2000000;
+    uint8_t _bits = 8;
+    uint16_t _delay = 0;
+};
+
+/******************************************************************************
+ * Factory
+ *****************************************************************************/
+spidev_iface::sptr spidev_iface::make(
+        const std::string &device
+) {
+    return sptr(new spidev_iface_impl(device));
+}
+
-- 
cgit v1.2.3