aboutsummaryrefslogtreecommitdiffstats
path: root/mpm
diff options
context:
space:
mode:
authorMark Meserve <mark.meserve@ni.com>2017-04-10 19:25:50 -0500
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:45 -0800
commit5a3abf352cfa3f3c387d9ff8e98525811c478fb8 (patch)
tree20f912d5f3380debc34fd7c21a9b356cd04dbc1a /mpm
parent58510168d5a033af1450f3ddf4d87ab8f8fa1a6a (diff)
downloaduhd-5a3abf352cfa3f3c387d9ff8e98525811c478fb8.tar.gz
uhd-5a3abf352cfa3f3c387d9ff8e98525811c478fb8.tar.bz2
uhd-5a3abf352cfa3f3c387d9ff8e98525811c478fb8.zip
ad9371: Added JESD init functionality
Diffstat (limited to 'mpm')
-rw-r--r--mpm/include/mpm/ad937x/ad937x_ctrl.hpp22
-rw-r--r--mpm/lib/mykonos/ad937x_ctrl.cpp65
-rw-r--r--mpm/lib/mykonos/ad937x_device.cpp235
-rw-r--r--mpm/lib/mykonos/ad937x_device.hpp22
-rw-r--r--mpm/lib/mykonos/adi/CMakeLists.txt2
-rw-r--r--mpm/lib/mykonos/adi/mykonos_debug/CMakeLists.txt3
-rw-r--r--mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h6
-rw-r--r--mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h2
8 files changed, 245 insertions, 112 deletions
diff --git a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
index 04332393e..837d617c9 100644
--- a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
+++ b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
@@ -62,6 +62,18 @@ public:
mpm::ad937x::gpio::gain_pins_t gain_pins);
virtual ~ad937x_ctrl(void) {}
+ virtual void begin_initialization() = 0;
+ virtual void finish_initialization() = 0;
+ virtual void start_jesd_rx() = 0;
+ virtual void start_jesd_tx() = 0;
+ virtual uint8_t get_multichip_sync_status() = 0;
+ virtual uint8_t get_framer_status() = 0;
+ virtual uint8_t get_deframer_status() = 0;
+
+ virtual uint8_t get_deframer_irq() = 0;
+ virtual uint16_t get_ilas_config_match() = 0;
+ virtual void enable_jesd_loopback(uint8_t enable) = 0;
+
//! get the RF frequency range for the AD9371
static uhd::meta_range_t get_rf_freq_range(void);
@@ -158,6 +170,16 @@ void export_mykonos(){
bp::class_<ad937x_ctrl, boost::noncopyable, std::shared_ptr<ad937x_ctrl> >("ad937x_ctrl", bp::no_init)
.def("make", &ad937x_ctrl::make)
+ .def("begin_initialization", &ad937x_ctrl::begin_initialization)
+ .def("finish_initialization", &ad937x_ctrl::finish_initialization)
+ .def("start_jesd_rx", &ad937x_ctrl::start_jesd_rx)
+ .def("start_jesd_tx", &ad937x_ctrl::start_jesd_tx)
+ .def("get_multichip_sync_status", &ad937x_ctrl::get_multichip_sync_status)
+ .def("get_framer_status", &ad937x_ctrl::get_framer_status)
+ .def("get_deframer_status", &ad937x_ctrl::get_deframer_status)
+ .def("get_deframer_irq", &ad937x_ctrl::get_deframer_irq)
+ .def("get_ilas_config_match", &ad937x_ctrl::get_ilas_config_match)
+ .def("enable_jesd_loopback", &ad937x_ctrl::enable_jesd_loopback)
.def("get_rf_freq_range", &ad937x_ctrl::get_rf_freq_range)
.def("get_bw_filter_range", &ad937x_ctrl::get_bw_filter_range)
.def("get_clock_rates", &ad937x_ctrl::get_clock_rates)
diff --git a/mpm/lib/mykonos/ad937x_ctrl.cpp b/mpm/lib/mykonos/ad937x_ctrl.cpp
index cef729686..dc4682598 100644
--- a/mpm/lib/mykonos/ad937x_ctrl.cpp
+++ b/mpm/lib/mykonos/ad937x_ctrl.cpp
@@ -128,6 +128,71 @@ public:
}
+ virtual void begin_initialization()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ device.begin_initialization();
+ }
+
+ virtual void finish_initialization()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ device.finish_initialization();
+ }
+
+ virtual void start_jesd_rx()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ device.start_jesd_rx();
+ }
+
+ virtual void start_jesd_tx()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ device.start_jesd_tx();
+ }
+
+ // TODO: interpret the status byte
+ // or provide means to do so
+ virtual uint8_t get_multichip_sync_status()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ return device.get_multichip_sync_status();
+ }
+
+ // TODO: interpret the status byte
+ // or provide means to do so
+ virtual uint8_t get_framer_status()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ return device.get_framer_status();
+ }
+
+ // TODO: interpret the status byte
+ // or provide means to do so
+ virtual uint8_t get_deframer_status()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ return device.get_deframer_status();
+ }
+
+ virtual uint8_t get_deframer_irq()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ return device.get_deframer_irq();
+ }
+
+ virtual uint16_t get_ilas_config_match()
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ return device.get_ilas_config_match();
+ }
+ virtual void enable_jesd_loopback(uint8_t enable)
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ device.enable_jesd_loopback(enable);
+ }
+
virtual uint8_t get_product_id()
{
std::lock_guard<std::mutex> lock(*spi_mutex);
diff --git a/mpm/lib/mykonos/ad937x_device.cpp b/mpm/lib/mykonos/ad937x_device.cpp
index 2eb1db60a..663acbf30 100644
--- a/mpm/lib/mykonos/ad937x_device.cpp
+++ b/mpm/lib/mykonos/ad937x_device.cpp
@@ -18,6 +18,7 @@
#include "ad937x_device.hpp"
#include "adi/mykonos.h"
#include "adi/mykonos_gpio.h"
+#include "adi/mykonos_debug/mykonos_dbgjesd.h"
#include <functional>
#include <iostream>
@@ -111,7 +112,84 @@ void ad937x_device::_call_gpio_api_function(std::function<mykonosGpioErr_t()> fu
}
}
-void ad937x_device::_initialize()
+void ad937x_device::_call_debug_api_function(std::function<mykonosDbgErr_t()> func)
+{
+ auto error = func();
+ if (error != MYKONOS_ERR_DBG_OK)
+ {
+ std::cout << getDbgJesdMykonosErrorMessage(error);
+ // TODO: make UHD exception
+ //throw std::exception(getMykonosErrorMessage(error));
+ }
+}
+
+// TODO: delete this comment closer to release
+/*
+EX 1 Preconditions
+EX 1. Check revision register
+EX 2. Initialize Clocking
+EX 3. Initialize FPGA JESD
+
+begin_initialize()
+IN 2 Start
+IN 1. Reset Myk
+IN 2. Init Myk
+IN 3. Check base PLL
+IN 4. Start Multichip Sync
+
+EX 3 Multichip Pulses
+EX 1. Send 2 SYSREF pulses
+
+finish_initialize()
+IN 4 Verify Multichip
+IN 1. Verify Multichip
+IN 2. Complete Init
+
+--skipping this for now using special hack from jepson
+--IN 3. Load ARM
+--IN 4. RF Start
+--IN Set RF Freq
+--IN Check RF PLLs
+--IN Set GPIO controls
+--IN Set gain
+--IN Init TX attenuations
+--IN Initialization Calibrations
+--IN External LOL Calibration (do we need this ???)
+
+--separate functions here for reusability--
+
+start_jesd_rx()
+IN 5 Start Myk JESD RX
+IN 1. Reset Myk JESD RX (???)
+IN 2. Enable Myk JESD RX Transmitter
+
+EX 6 Start FPGA CGS
+EX 1. Reset and Ready RX JESD for CGS
+EX 2. Reset and Ready TX JESD for CGS
+
+start_jesd_tx()
+IN 7 Start Myk JESD TX
+IN 1. Disable Myk JESD Receiver
+IN 2. Reset Myk JESD Receiver
+IN 3. Enable Myk JESD Receiver
+
+EX 8 Finish CGS
+EX 1. Enable FPGA LMFC Generator
+EX 2. Send SYSREF Pulse
+EX 3. Wait (200 ms ???)
+EX 4. Check TX Core is Synced
+EX 5. Check RX Core is Synced
+
+OTHER FUNCTIONS THAT SHOULD BE WRITTEN
+get_framer_status() get_deframer_status() Read framer/deframer status
+get_deframer_irq() Read Deframer IRQ
+get_ilas_config_match() Check ILAS Config Match
+set_jesd_loopback() Enable Loopback
+stop_jesd() Stop Link
+
+*/
+
+void ad937x_device::begin_initialization()
{
// TODO: make this reset actually do something (implement CMB_HardReset or replace)
_call_api_function(std::bind(MYKONOS_resetDevice, mykonos_config.device));
@@ -128,129 +206,82 @@ void ad937x_device::_initialize()
throw runtime_error("AD937x CLK_SYNTH PLL failed to lock in initialize()");
}
- std::vector<uint8_t> binary(98304, 0);
- _load_arm(binary);
-
- // TODO: Add multi-chip sync code
+ uint8_t mcs_status = 0;
+ _call_api_function(std::bind(MYKONOS_enableMultichipSync, mykonos_config.device, 1, &mcs_status));
+}
- tune(RX_DIRECTION, RX_DEFAULT_FREQ);
- tune(TX_DIRECTION, TX_DEFAULT_FREQ);
+void ad937x_device::finish_initialization()
+{
+ // to check status, just call the same function with a 0 instead of a 1, seems good
+ uint8_t mcs_status = 0;
+ _call_api_function(std::bind(MYKONOS_enableMultichipSync, mykonos_config.device, 0, &mcs_status));
- // TODO: wait 200ms or change to polling
- if (!get_pll_lock_status(pll_t::RX_SYNTH))
- {
- throw runtime_error("AD937x RX PLL failed to lock in initialize()");
- }
- if (!get_pll_lock_status(pll_t::TX_SYNTH))
+ if ((mcs_status & 0x0A) != 0x0A)
{
- throw runtime_error("AD937x TX PLL failed to lock in initialize()");
+ throw runtime_error("Multichip sync failed!");
}
- // TODO: ADD GPIO CTRL setup here
+ _call_api_function(std::bind(MYKONOS_initSubRegisterTables, mykonos_config.device));
+ // according to djepson, we can call only this function and avoid loading the ARM or
+ // doing an RF stuff
+ // TODO: fix all this once we want to more than just loopback
- set_gain(RX_DIRECTION, chain_t::ONE, 0);
- set_gain(RX_DIRECTION, chain_t::TWO, 0);
- set_gain(TX_DIRECTION, chain_t::ONE, 0);
- set_gain(TX_DIRECTION, chain_t::TWO, 0);
-
- _run_initialization_calibrations();
-
- // TODO: do external LO leakage calibration here if hardware supports it
- // I don't think we do?
-
- _start_jesd();
- _enable_tracking_calibrations();
-
- // radio is ON!
- _call_api_function(std::bind(MYKONOS_radioOn, mykonos_config.device));
-
- // TODO: ordering of this doesn't seem right, intuitively, verify this works
- _call_api_function(std::bind(MYKONOS_setObsRxPathSource, mykonos_config.device, OBS_RXOFF));
- _call_api_function(std::bind(MYKONOS_setObsRxPathSource, mykonos_config.device, OBS_INTERNALCALS));
-
- _apply_gain_pins(RX_DIRECTION, chain_t::ONE);
- _apply_gain_pins(RX_DIRECTION, chain_t::TWO);
- _apply_gain_pins(TX_DIRECTION, chain_t::ONE);
- _apply_gain_pins(TX_DIRECTION, chain_t::TWO);
+ // load ARM
+ // ARM init
+ // RF setup
}
-// TODO: review const-ness in this function with respect to ADI API
-void ad937x_device::_load_arm(std::vector<uint8_t> & binary)
+void ad937x_device::start_jesd_rx()
{
- _call_api_function(std::bind(MYKONOS_initArm, mykonos_config.device));
-
- if (binary.size() == ARM_BINARY_SIZE)
- {
- throw runtime_error("ad937x_device ARM is not the correct size!");
- }
-
- _call_api_function(std::bind(MYKONOS_loadArmFromBinary, mykonos_config.device, &binary[0], binary.size()));
+ _call_api_function(std::bind(MYKONOS_enableSysrefToRxFramer, mykonos_config.device, 1));
}
-void ad937x_device::_run_initialization_calibrations()
+void ad937x_device::start_jesd_tx()
{
- _call_api_function(std::bind(MYKONOS_runInitCals, mykonos_config.device, INIT_CALS));
-
- uint8_t errorFlag = 0;
- uint8_t errorCode = 0;
- _call_api_function(
- std::bind(MYKONOS_waitInitCals,
- mykonos_config.device,
- INIT_CAL_TIMEOUT_MS,
- &errorFlag,
- &errorCode));
-
- if ((errorFlag != 0) || (errorCode != 0))
- {
- mykonosInitCalStatus_t initCalStatus = { 0 };
- _call_api_function(std::bind(MYKONOS_getInitCalStatus, mykonos_config.device, &initCalStatus));
-
- // abort init cals
- uint32_t initCalsCompleted = 0;
- _call_api_function(std::bind(MYKONOS_abortInitCals, mykonos_config.device, &initCalsCompleted));
- // init cals completed contains mask of cals that did finish
-
- uint16_t errorWord = 0;
- uint16_t statusWord = 0;
- _call_api_function(std::bind(MYKONOS_readArmCmdStatus, mykonos_config.device, &errorWord, &statusWord));
-
- uint8_t status = 0;
- _call_api_function(std::bind(MYKONOS_readArmCmdStatusByte, mykonos_config.device, 2, &status));
- }
+ _call_api_function(std::bind(MYKONOS_enableSysrefToDeframer, mykonos_config.device, 0));
+ _call_api_function(std::bind(MYKONOS_resetDeframer, mykonos_config.device));
+ _call_api_function(std::bind(MYKONOS_enableSysrefToDeframer, mykonos_config.device, 1));
}
-void ad937x_device::_start_jesd()
+uint8_t ad937x_device::get_multichip_sync_status()
{
- // Stop and/or disable SYSREF
- // ensure BBIC JESD is reset and ready to receive CGS characters
-
- // prepare to transmit CGS when sysref starts
- _call_api_function(std::bind(MYKONOS_enableSysrefToRxFramer, mykonos_config.device, 1));
-
- // prepare to transmit CGS when sysref starts
- //_call_api_function(std::bind(MYKONOS_enableSysrefToObsRxFramer, mykonos_config.device, 1));
+ uint8_t mcs_status = 0;
+ _call_api_function(std::bind(MYKONOS_enableMultichipSync, mykonos_config.device, 0, &mcs_status));
+ return mcs_status;
+}
- // prepare to transmit CGS when sysref starts
- _call_api_function(std::bind(MYKONOS_enableSysrefToDeframer, mykonos_config.device, 0));
+uint8_t ad937x_device::get_framer_status()
+{
+ uint8_t status = 0;
+ _call_api_function(std::bind(MYKONOS_readRxFramerStatus, mykonos_config.device, &status));
+ return status;
+}
- _call_api_function(std::bind(MYKONOS_resetDeframer, mykonos_config.device));
- _call_api_function(std::bind(MYKONOS_enableSysrefToDeframer, mykonos_config.device, 1));
+uint8_t ad937x_device::get_deframer_status()
+{
+ uint8_t status = 0;
+ _call_api_function(std::bind(MYKONOS_readDeframerStatus, mykonos_config.device, &status));
+ return status;
+}
- // make sure BBIC JESD framer is actively transmitting CGS
- // Start SYSREF
+uint8_t ad937x_device::get_deframer_irq()
+{
+ uint8_t irq_status = 0;
+ _call_debug_api_function(std::bind(MYKONOS_deframerGetIrq, mykonos_config.device, &irq_status));
+ return irq_status;
+}
- // verify sync code here
- // verify links
- uint8_t framerStatus = 0;
- _call_api_function(std::bind(MYKONOS_readRxFramerStatus, mykonos_config.device, &framerStatus));
+uint16_t ad937x_device::get_ilas_config_match()
+{
+ uint16_t ilas_status = 0;
+ _call_api_function(std::bind(MYKONOS_jesd204bIlasCheck, mykonos_config.device, &ilas_status));
+ return ilas_status;
- uint8_t deframerStatus = 0;
- _call_api_function(std::bind(MYKONOS_readDeframerStatus, mykonos_config.device, &deframerStatus));
}
-void ad937x_device::_enable_tracking_calibrations()
+void ad937x_device::enable_jesd_loopback(uint8_t enable)
{
- _call_api_function(std::bind(MYKONOS_enableTrackingCals, mykonos_config.device, TRACKING_CALS));
+ _call_api_function(std::bind(MYKONOS_setRxFramerDataSource, mykonos_config.device, enable));
}
ad937x_device::ad937x_device(spi_iface::sptr iface, gain_pins_t gain_pins) :
@@ -258,7 +289,7 @@ ad937x_device::ad937x_device(spi_iface::sptr iface, gain_pins_t gain_pins) :
mykonos_config(&full_spi_settings.spi_settings),
gain_ctrl(gain_pins)
{
- _initialize();
+
}
uint8_t ad937x_device::get_product_id()
diff --git a/mpm/lib/mykonos/ad937x_device.hpp b/mpm/lib/mykonos/ad937x_device.hpp
index ccc696714..1b21a5a04 100644
--- a/mpm/lib/mykonos/ad937x_device.hpp
+++ b/mpm/lib/mykonos/ad937x_device.hpp
@@ -25,6 +25,7 @@
#include "mpm/ad937x/ad937x_ctrl_types.hpp"
#include "adi/t_mykonos.h"
#include "adi/t_mykonos_gpio.h"
+#include "adi/mykonos_debug/t_mykonos_dbgjesd.h"
#include <uhd/exception.hpp>
@@ -40,6 +41,20 @@ public:
ad937x_device(uhd::spi_iface::sptr iface, mpm::ad937x::gpio::gain_pins_t gain_pins);
+ void begin_initialization();
+ void finish_initialization();
+ void start_jesd_rx();
+ void start_jesd_tx();
+ uint8_t get_multichip_sync_status();
+ uint8_t get_framer_status();
+ uint8_t get_deframer_status();
+
+ // debug functions for JESD
+ // TODO: make these returns useful
+ uint8_t get_deframer_irq();
+ uint16_t get_ilas_config_match();
+ void enable_jesd_loopback(uint8_t enable);
+
uint8_t get_product_id();
uint8_t get_device_rev();
mpm::ad937x::device::api_version_t get_api_version();
@@ -77,16 +92,11 @@ private:
ad937x_config_t mykonos_config;
ad937x_gain_ctrl_config_t gain_ctrl;
- void _initialize();
- void _load_arm(std::vector<uint8_t> & binary);
- void _run_initialization_calibrations();
- void _start_jesd();
- void _enable_tracking_calibrations();
-
void _apply_gain_pins(uhd::direction_t direction, mpm::ad937x::device::chain_t chain);
void _call_api_function(std::function<mykonosErr_t()> func);
void _call_gpio_api_function(std::function<mykonosGpioErr_t()> func);
+ void _call_debug_api_function(std::function<mykonosDbgErr_t()> func);
static uint8_t _convert_rx_gain(double gain);
static uint16_t _convert_tx_gain(double gain);
diff --git a/mpm/lib/mykonos/adi/CMakeLists.txt b/mpm/lib/mykonos/adi/CMakeLists.txt
index b54a604b9..87a16854e 100644
--- a/mpm/lib/mykonos/adi/CMakeLists.txt
+++ b/mpm/lib/mykonos/adi/CMakeLists.txt
@@ -3,3 +3,5 @@ MYKONOS_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/mykonos_gpio.c
${CMAKE_CURRENT_SOURCE_DIR}/mykonos_user.c
)
+
+ADD_SUBDIRECTORY(mykonos_debug)
diff --git a/mpm/lib/mykonos/adi/mykonos_debug/CMakeLists.txt b/mpm/lib/mykonos/adi/mykonos_debug/CMakeLists.txt
new file mode 100644
index 000000000..4ee1a4209
--- /dev/null
+++ b/mpm/lib/mykonos/adi/mykonos_debug/CMakeLists.txt
@@ -0,0 +1,3 @@
+MYKONOS_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_dbgjesd.c
+)
diff --git a/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h b/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h
index deb0702bd..dfeb3d7e9 100644
--- a/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h
+++ b/mpm/lib/mykonos/adi/mykonos_debug/mykonos_dbgjesd.h
@@ -13,10 +13,10 @@
extern "C" {
#endif
-#include "mykonos.h"
-#include "t_mykonos_gpio.h"
+#include "../mykonos.h"
+#include "../t_mykonos_gpio.h"
#include "t_mykonos_dbgjesd.h"
-#include "mykonos_user.h"
+#include "../mykonos_user.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
index da98c56e1..0f612920d 100644
--- a/mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h
+++ b/mpm/lib/mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h
@@ -13,7 +13,7 @@
extern "C" {
#endif
-#include "common.h"
+#include "../common.h"
/**
* \brief Enum of unique error codes from the Mykonos DBG API functions.