From 5a3abf352cfa3f3c387d9ff8e98525811c478fb8 Mon Sep 17 00:00:00 2001
From: Mark Meserve <mark.meserve@ni.com>
Date: Mon, 10 Apr 2017 19:25:50 -0500
Subject: ad9371: Added JESD init functionality

---
 mpm/lib/mykonos/ad937x_ctrl.cpp                    |  65 ++++++
 mpm/lib/mykonos/ad937x_device.cpp                  | 235 ++++++++++++---------
 mpm/lib/mykonos/ad937x_device.hpp                  |  22 +-
 mpm/lib/mykonos/adi/CMakeLists.txt                 |   2 +
 mpm/lib/mykonos/adi/mykonos_debug/CMakeLists.txt   |   3 +
 .../mykonos/adi/mykonos_debug/mykonos_dbgjesd.h    |   6 +-
 .../mykonos/adi/mykonos_debug/t_mykonos_dbgjesd.h  |   2 +-
 7 files changed, 223 insertions(+), 112 deletions(-)
 create mode 100644 mpm/lib/mykonos/adi/mykonos_debug/CMakeLists.txt

(limited to 'mpm/lib')

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.
-- 
cgit v1.2.3