[hamradio-commits] [limesuite] 01/05: New upstream version 17.09.1+dfsg

Andreas E. Bombe aeb at moszumanska.debian.org
Wed Sep 27 17:33:03 UTC 2017


This is an automated email from the git hooks/post-receive script.

aeb pushed a commit to branch master
in repository limesuite.

commit 9d0cf60127b20d43e1896e6ba1113a6fd04a5e94
Author: Andreas Bombe <aeb at debian.org>
Date:   Wed Sep 27 15:00:14 2017 +0200

    New upstream version 17.09.1+dfsg
---
 Changelog.txt                                      |  18 ++++
 SoapyLMS7/BasicStreamTests.py                      |   5 +-
 SoapyLMS7/Streaming.cpp                            |  45 ++++++---
 debian/changelog                                   |   6 ++
 mcu_program/host_src/main.cpp                      |   2 -
 src/API/lms7_api.cpp                               |  55 ++++++++++-
 src/API/lms7_device.cpp                            |  19 ++--
 src/ConnectionEVB7COM/ConnectionEVB7COM.cpp        |   2 -
 src/ConnectionSTREAM/ConnectionSTREAM.cpp          |   4 +-
 src/ConnectionSTREAM/ConnectionSTREAMImages.cpp    |   2 +-
 src/ConnectionXillybus/ConnectionXillybusing.cpp   |   2 +-
 src/Connection_uLimeSDR/Connection_uLimeSDR.cpp    | 103 +++++++++++++++------
 src/Connection_uLimeSDR/Connection_uLimeSDR.h      |   3 +-
 .../Connection_uLimeSDREntry.cpp                   |  17 ++--
 src/Connection_uLimeSDR/Connection_uLimeSDRing.cpp |  11 +--
 src/Logger.cpp                                     |   6 +-
 src/Logger.h                                       |  10 +-
 src/examples/CMakeLists.txt                        |   4 +
 src/examples/gpio_example.cpp                      |  90 ++++++++++++++++++
 src/lime/LimeSuite.h                               |  16 ++++
 src/lms7002m/LMS7002M.cpp                          |  12 +--
 src/lms7002m/LMS7002M_RxTxCalibrations.cpp         |   8 +-
 src/lms7002m/LMS7002M_filtersCalibration.cpp       |   9 +-
 src/lms7002m_mcu/MCU_BD.cpp                        |   8 +-
 src/lms7002m_mcu/MCU_BD.h                          |   1 -
 src/protocols/LMS64CProtocol.cpp                   |   3 -
 src/protocols/fifo.h                               |   6 ++
 src/utilities_gui/pnlMiniLog.cpp                   |   4 +
 28 files changed, 362 insertions(+), 109 deletions(-)

diff --git a/Changelog.txt b/Changelog.txt
index d3b8256..7f7c586 100644
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -1,3 +1,21 @@
+Release 17.09.1 (2017-09-21)
+==========================
+
+SoapyLMS changes:
+- SoapyLMS7 caches stream enable and disables on close
+- Fixed late packet reporting in SoapyLMS7 stream status
+
+LMS API changes:
+- Added simple GPIO example utilizing functions from LimeSuite.h
+- Fixed WriteStream() end of burst flushing in fifo.h
+- Fixed abs() overload compiler issue in lms7_device.cpp
+- Removed private include in mcu_program/host_src/main.cpp
+- Fixed error checking bug causing compilation error on MacOS in LMS_GetGaindB() and LMS_GetNormalizedGain() 
+
+Other changes:
+- LimeSDR v1.4 updated to r2.10 gateware
+
+
 Release 17.09.0 (2017-09-01)
 ==========================
 
diff --git a/SoapyLMS7/BasicStreamTests.py b/SoapyLMS7/BasicStreamTests.py
index 392eee2..6c1b43b 100755
--- a/SoapyLMS7/BasicStreamTests.py
+++ b/SoapyLMS7/BasicStreamTests.py
@@ -59,7 +59,6 @@ class TestBasicStreaming(unittest.TestCase):
         print(sr)
         self.assertEqual(sr.ret, SOAPY_SDR_TIMEOUT)
 
-
     def testRxBurstNow(self):
         print('===== receive a burst asap =====')
         numElemsRequest = 10000
@@ -147,7 +146,6 @@ class TestBasicStreaming(unittest.TestCase):
 
         self.sdr.deactivateStream(self.rxStream)
 
-    """
     def testTxLate(self):
         print('===== test txing a late packet =====')
         self.sdr.activateStream(self.txStream)
@@ -180,11 +178,10 @@ class TestBasicStreaming(unittest.TestCase):
 
         print('readStreamStatus for a timeout...')
         r1 = self.sdr.readStreamStatus(self.txStream)
-        self.assertEqual(r1.ret, SOAPY_SDR_TIMEOUT)
+        self.assertNotEqual(r1.ret, SOAPY_SDR_TIME_ERROR)
 
         self.sdr.deactivateStream(self.txStream)
         self.sdr.deactivateStream(self.rxStream)
-    """
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/SoapyLMS7/Streaming.cpp b/SoapyLMS7/Streaming.cpp
index e7cd4fe..39832d2 100644
--- a/SoapyLMS7/Streaming.cpp
+++ b/SoapyLMS7/Streaming.cpp
@@ -24,6 +24,7 @@ struct IConnectionStream
     int direction;
     size_t elemSize;
     size_t elemMTU;
+    bool enabled;
 
     //rx cmd requests
     bool hasCmd;
@@ -138,6 +139,7 @@ SoapySDR::Stream *SoapyLMS7::setupStream(
             throw std::runtime_error("SoapyLMS7::setupStream() failed: " + std::string(GetLastErrorMessage()));
         stream->streamID.push_back(streamID);
         stream->elemMTU = _conn->GetStreamSize(streamID);
+        stream->enabled = false;
     }
 
     //calibrate these channels when activated
@@ -155,6 +157,13 @@ void SoapyLMS7::closeStream(SoapySDR::Stream *stream)
     auto icstream = (IConnectionStream *)stream;
     const auto &streamID = icstream->streamID;
 
+    //disable stream if left enabled
+    if (icstream->enabled)
+    {
+        for(auto i : streamID)
+            _conn->ControlStream(i, false);
+    }
+
     for(auto i : streamID)
         _conn->CloseStream(i);
 }
@@ -197,12 +206,16 @@ int SoapyLMS7::activateStream(
     icstream->numElems = numElems;
     icstream->hasCmd = true;
 
-    for(auto i : streamID)
+    if (not icstream->enabled)
     {
-        int status = _conn->ControlStream(i, true);
-        if(status != 0)
-            return SOAPY_SDR_STREAM_ERROR;
+        for(auto i : streamID)
+        {
+            int status = _conn->ControlStream(i, true);
+            if(status != 0) return SOAPY_SDR_STREAM_ERROR;
+        }
+        icstream->enabled = true;
     }
+
     return 0;
 }
 
@@ -220,12 +233,17 @@ int SoapyLMS7::deactivateStream(
     metadata.timestamp = SoapySDR::timeNsToTicks(timeNs, _conn->GetHardwareTimestampRate());
     metadata.hasTimestamp = (flags & SOAPY_SDR_HAS_TIME) != 0;
     metadata.endOfBurst = (flags & SOAPY_SDR_END_BURST) != 0;
-    for(auto i : streamID)
+
+    if (icstream->enabled)
     {
-        int status = _conn->ControlStream(i, false);
-        if(status != 0)
-            return SOAPY_SDR_STREAM_ERROR;
+        for(auto i : streamID)
+        {
+            int status = _conn->ControlStream(i, false);
+            if(status != 0) return SOAPY_SDR_STREAM_ERROR;
+        }
+        icstream->enabled = false;
     }
+
     return 0;
 }
 
@@ -384,10 +402,14 @@ int SoapyLMS7::readStreamStatus(
                 if (GetLastError() == EPERM) return SOAPY_SDR_NOT_SUPPORTED;
                 return SOAPY_SDR_TIMEOUT;
             }
+
+            //packet dropped doesnt mean anything for tx streams
+            if (icstream->direction == SOAPY_SDR_TX) metadata.packetDropped = false;
+
+            //stop when event is detected
+            if (metadata.endOfBurst || metadata.lateTimestamp || metadata.packetDropped)
+                goto found;
         }
-        //stop when event is detected
-        if (metadata.endOfBurst || metadata.lateTimestamp || metadata.packetDropped)
-            break;
         //check timeout
         std::chrono::duration<double> seconds = std::chrono::high_resolution_clock::now()-start;
         if (seconds.count()> (double)timeoutUs/1e6)
@@ -399,6 +421,7 @@ int SoapyLMS7::readStreamStatus(
             std::this_thread::sleep_for(std::chrono::microseconds(1+timeoutUs/2));
     }
 
+    found:
     timeNs = SoapySDR::ticksToTimeNs(metadata.timestamp, _conn->GetHardwareTimestampRate());
     //output metadata
     if (metadata.endOfBurst) flags |= SOAPY_SDR_END_BURST;
diff --git a/debian/changelog b/debian/changelog
index cacf916..e9f0274 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+limesuite (17.09.1-1) unstable; urgency=low
+
+  * Release 17.09.1 (2017-09-21)
+
+ -- Lime Microsystems <info at limemicro.com>  Fri Sep 1 15:43:31 2017 +0300
+
 limesuite (17.09.0-1) unstable; urgency=low
 
   * Release 17.09.0 (2017-09-01)
diff --git a/mcu_program/host_src/main.cpp b/mcu_program/host_src/main.cpp
index ef0c654..3312327 100644
--- a/mcu_program/host_src/main.cpp
+++ b/mcu_program/host_src/main.cpp
@@ -1,5 +1,3 @@
-#include "ConnectionSTREAM.h"
-
 #include <stdio.h>
 #include "lms7002m_calibrations.h"
 #include "lms7002m_controls.h"
diff --git a/src/API/lms7_api.cpp b/src/API/lms7_api.cpp
index 9498f18..941b6ea 100644
--- a/src/API/lms7_api.cpp
+++ b/src/API/lms7_api.cpp
@@ -9,6 +9,8 @@
 #include "VersionInfo.h"
 #include <assert.h>
 #include "FPGA_common.h"
+#include "Logger.h"
+#include "LMS64CProtocol.h"
 
 using namespace std;
 
@@ -733,7 +735,7 @@ API_EXPORT int CALL_CONV LMS_GetNormalizedGain(lms_device_t *device, bool dir_tx
     }
 
     *gain = lms->GetNormalizedGain(dir_tx,chan);
-    if (gain < 0)
+    if (*gain < 0)
         return -1;
     return LMS_SUCCESS;
 }
@@ -754,9 +756,10 @@ API_EXPORT int CALL_CONV LMS_GetGaindB(lms_device_t *device, bool dir_tx, size_t
         return -1;
     }
 
-    *gain = lms->GetGain(dir_tx,chan);
-    if (gain < 0)
+    int ret = lms->GetGain(dir_tx,chan);
+    if (ret < 0)
         return -1;
+    *gain = ret;
     return LMS_SUCCESS;
 }
 
@@ -1332,4 +1335,50 @@ API_EXPORT const char* LMS_GetLibraryVersion()
     static char libraryVersion[32];
     sprintf(libraryVersion, "%.32s", lime::GetLibraryVersion().c_str());
     return libraryVersion;
+}
+
+static LMS_LogHandler api_msg_handler;
+static void APIMsgHandler(const lime::LogLevel level, const char *message)
+{
+    api_msg_handler(level,message);
+}
+
+API_EXPORT void LMS_RegisterLogHandler(LMS_LogHandler handler)
+{
+    lime::registerLogHandler(APIMsgHandler);
+    api_msg_handler = handler;
+}
+
+API_EXPORT int CALL_CONV LMS_TransferLMS64C(lms_device_t *dev, int cmd, uint8_t* data, size_t *len)
+{
+    if (dev == nullptr)
+    {
+        lime::ReportError(EINVAL, "Device cannot be NULL.");
+            return -1;
+    }
+    LMS7_Device* lms = (LMS7_Device*)dev;
+    lime::LMS64CProtocol::GenericPacket pkt;
+    auto conn = lms->GetConnection();
+    if (conn == nullptr)
+    {
+        lime::ReportError(EINVAL, "Device not connected");
+        return -1;
+    }
+
+    pkt.cmd = lime::eCMD_LMS(cmd);
+    for (size_t i = 0; i < *len; ++i)
+        pkt.outBuffer.push_back(data[i]);
+
+    lime::LMS64CProtocol* port = dynamic_cast<lime::LMS64CProtocol *>(conn);
+    if (port->TransferPacket(pkt) != 0)
+        return -1;
+
+    for (size_t i = 0; i < pkt.inBuffer.size(); ++i)
+        data[i] = pkt.inBuffer[i];
+    *len = pkt.inBuffer.size();
+
+    if (pkt.status != lime::STATUS_COMPLETED_CMD)
+        return lime::ReportError(-1, "%s", lime::status2string(pkt.status));
+
+    return 0;
 }
\ No newline at end of file
diff --git a/src/API/lms7_device.cpp b/src/API/lms7_device.cpp
index 3b3641b..55b9eb0 100644
--- a/src/API/lms7_device.cpp
+++ b/src/API/lms7_device.cpp
@@ -22,6 +22,7 @@
 #include "ConnectionRegistry.h"
 #include "ADF4002.h"
 #include "mcu_programs.h"
+#include "Logger.h"
 
 const double LMS7_Device::LMS_CGEN_MAX = 640e6;
 
@@ -408,14 +409,14 @@ int LMS7_Device::SetRate(double f_Hz, int oversample)
         float_type freq[LMS_NCO_VAL_COUNT]={0};
         if (rx_channels[i].cF_offset_nco != 0)
         {
-           freq[0] = abs(rx_channels[i].cF_offset_nco);
+           freq[0] = fabs(rx_channels[i].cF_offset_nco);
            SetNCOFreq(false,i,freq,0);
            SetNCO(false,i,0,rx_channels[i].cF_offset_nco> 0);
         }
 
         if (tx_channels[i].cF_offset_nco != 0)
         {
-           freq[0] = abs(tx_channels[i].cF_offset_nco);
+           freq[0] = fabs(tx_channels[i].cF_offset_nco);
            SetNCOFreq(true,i,freq,0);
            SetNCO(true,i,0,tx_channels[i].cF_offset_nco> 0);
         }
@@ -687,14 +688,14 @@ int LMS7_Device::SetRate(bool tx, double f_Hz, unsigned oversample)
         float_type freq[LMS_NCO_VAL_COUNT]={0};
         if (rx_channels[i].cF_offset_nco != 0)
         {
-           freq[0] = abs(rx_channels[i].cF_offset_nco);
+           freq[0] = fabs(rx_channels[i].cF_offset_nco);
            SetNCOFreq(false,i,freq,0);
            SetNCO(false,i,0,rx_channels[i].cF_offset_nco> 0);
         }
 
         if (tx_channels[i].cF_offset_nco != 0)
         {
-           freq[0] = abs(tx_channels[i].cF_offset_nco);
+           freq[0] = fabs(tx_channels[i].cF_offset_nco);
            SetNCOFreq(true,i,freq,0);
            SetNCO(true,i,0,tx_channels[i].cF_offset_nco> 0);
         }
@@ -1568,7 +1569,7 @@ int LMS7_Device::SetRxFrequency(size_t chan, double f_Hz)
     
     if (rx_channels[chA].freq > 0 && rx_channels[chB].freq > 0) 
     {
-        double delta = abs(rx_channels[chA].freq - rx_channels[chB].freq);
+        double delta = fabs(rx_channels[chA].freq - rx_channels[chB].freq);
         if (delta > 1)
         {
             double rate = GetRate(false,chan);
@@ -1622,7 +1623,7 @@ int LMS7_Device::SetTxFrequency(size_t chan, double f_Hz)
     
     if (tx_channels[chA].freq > 0 && tx_channels[chB].freq > 0) 
     {
-        double delta = abs(tx_channels[chA].freq - tx_channels[chB].freq);
+        double delta = fabs(tx_channels[chA].freq - tx_channels[chB].freq);
         if (delta > 1)
         {
             double rate = GetRate(true,chan);
@@ -2081,12 +2082,12 @@ int LMS7_Device::MCU_AGCStart(uint8_t rssiMin, uint8_t pgaCeil)
     lms_list.at(lms_chip_id)->Modify_SPI_Reg_bits(0x0006, 0, 0, 0);
 
     uint8_t mcuID = mcu->ReadMCUProgramID();
-    printf("Current MCU firmware: %i, expected %i \n", mcuID, MCU_ID_AGC_IMAGE);
+    lime::debug("Current MCU firmware: %i, expected %i", mcuID, MCU_ID_AGC_IMAGE);
     if(mcuID != MCU_ID_AGC_IMAGE)
     {
-        printf("Uploading MCU AGC firmware\n");
+        lime::debug("Uploading MCU AGC firmware");
         int status = mcu->Program_MCU(mcu_program_lms7_agc_bin, lime::IConnection::MCU_PROG_MODE::SRAM);
-        printf("Done\n");
+        lime::info("MCU AGC firmware uploaded");
         if(status != 0)
             return status;
     }
diff --git a/src/ConnectionEVB7COM/ConnectionEVB7COM.cpp b/src/ConnectionEVB7COM/ConnectionEVB7COM.cpp
index f7c3639..f090a96 100644
--- a/src/ConnectionEVB7COM/ConnectionEVB7COM.cpp
+++ b/src/ConnectionEVB7COM/ConnectionEVB7COM.cpp
@@ -180,8 +180,6 @@ int ConnectionEVB7COM::Open(const char *comName, int baudrate)
     hComm = open(comName, O_RDWR | O_NOCTTY | O_SYNC);
     if(hComm < 0)
     {
-//        printf("%s",strerror(errno));
-//        MessageLog::getInstance()->write("Connection manager: failed opening COM port\n", LOG_ERROR);
         return ReportError("failed opening COM port");
     }
 
diff --git a/src/ConnectionSTREAM/ConnectionSTREAM.cpp b/src/ConnectionSTREAM/ConnectionSTREAM.cpp
index bddf2f1..a2ef9d6 100644
--- a/src/ConnectionSTREAM/ConnectionSTREAM.cpp
+++ b/src/ConnectionSTREAM/ConnectionSTREAM.cpp
@@ -160,7 +160,7 @@ double ConnectionSTREAM::DetectRefClk(void)
     }
     double count = (vals2[0] | (vals2[1] << 16)); //cock counter
     count *= fx3Clk / fx3Cnt;   //estimate ref clock based on FX3 Clock
-    lime::info("Estimated reference clock %1.4f MHz", count/1e6);
+    lime::debug("Estimated reference clock %1.4f MHz", count/1e6);
     unsigned i = 0;
     double delta = 100e6;
 
@@ -171,7 +171,7 @@ double ConnectionSTREAM::DetectRefClk(void)
             delta = fabs(count - clkTbl[i++]);
 
     this->SetReferenceClockRate(clkTbl[i-1]);
-    lime::info("Selected reference clock %1.3f MHz", clkTbl[i - 1] / 1e6);
+    lime::info("Reference clock %1.3f MHz", clkTbl[i - 1] / 1e6);
     return clkTbl[i - 1];
 }
 
diff --git a/src/ConnectionSTREAM/ConnectionSTREAMImages.cpp b/src/ConnectionSTREAM/ConnectionSTREAMImages.cpp
index 4f31aa8..93083e8 100644
--- a/src/ConnectionSTREAM/ConnectionSTREAMImages.cpp
+++ b/src/ConnectionSTREAM/ConnectionSTREAMImages.cpp
@@ -39,7 +39,7 @@ static const ConnectionSTREAMImageEntry &lookupImageEntry(const LMS64CProtocol::
 {
     static const std::vector<ConnectionSTREAMImageEntry> imageEntries = {
         ConnectionSTREAMImageEntry({LMS_DEV_UNKNOWN, -1, -1, "Unknown-USB.img", -1, -1, "Unknown-USB.rbf"}),
-        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 4, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 2, 9,  "LimeSDR-USB_HW_1.4_r2.9.rbf"}),
+        ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 4, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 2, 10,  "LimeSDR-USB_HW_1.4_r2.10.rbf"}),
         ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 3, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
         ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 2, 3, "LimeSDR-USB_HW_1.2_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
         ConnectionSTREAMImageEntry({LMS_DEV_LIMESDR, 1, 7, "LimeSDR-USB_HW_1.1_r7.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}),
diff --git a/src/ConnectionXillybus/ConnectionXillybusing.cpp b/src/ConnectionXillybus/ConnectionXillybusing.cpp
index 4069458..69c871d 100644
--- a/src/ConnectionXillybus/ConnectionXillybusing.cpp
+++ b/src/ConnectionXillybus/ConnectionXillybusing.cpp
@@ -353,7 +353,7 @@ void ConnectionXillybus::TransmitPacketsLoop(Streamer* stream)
     }
     catch (const std::bad_alloc& ex) //not enough memory for buffers
     {
-        printf("Error allocating Tx buffers, not enough memory\n");
+        lime::error("Error allocating Tx buffers, not enough memory");
         return;
     }
 
diff --git a/src/Connection_uLimeSDR/Connection_uLimeSDR.cpp b/src/Connection_uLimeSDR/Connection_uLimeSDR.cpp
index 4f825f1..8e8aeeb 100644
--- a/src/Connection_uLimeSDR/Connection_uLimeSDR.cpp
+++ b/src/Connection_uLimeSDR/Connection_uLimeSDR.cpp
@@ -14,6 +14,7 @@
 #include <FPGA_common.h>
 #include <LMS7002M.h>
 #include <ciso646>
+#include "Logger.h"
 
 using namespace std;
 using namespace lime;
@@ -64,10 +65,68 @@ Connection_uLimeSDR::Connection_uLimeSDR(void *arg, const unsigned index, const
 #endif
     if (this->Open(index, vid, pid) != 0)
         std::cerr << GetLastErrorMessage() << std::endl;
-    this->SetReferenceClockRate(52e6);
+    DetectRefClk();
     GetChipVersion();
 }
 
+double Connection_uLimeSDR::DetectRefClk(void)
+{
+    const double fx3Clk = 100e6;   
+    const double fx3Cnt = 16777210;    //fixed fx3 counter in FPGA
+    const double clkTbl[] = { 30.72e6, 38.4e6, 40e6, 52e6 };
+    const uint32_t addr[] = { 0x61, 0x63 };
+    const uint32_t vals[] = { 0x0, 0x0 };
+    if (this->WriteRegisters(addr, vals, 2) != 0)
+    {
+        return -1;
+    }
+    auto start = std::chrono::steady_clock::now();
+    if (this->WriteRegister(0x61, 0x4) != 0)
+    {
+        return -1;
+    }
+
+    while (1) //wait for test to finish
+    {
+        unsigned completed;
+        if (this->ReadRegister(0x65, completed) != 0)
+        {
+            return -1;
+        }
+        if (completed & 0x4)
+            break;
+
+        auto end = std::chrono::steady_clock::now();
+        std::chrono::duration<double> elapsed_seconds = end - start;
+        if (elapsed_seconds.count() > 0.5) //timeout
+        {
+            return -1;
+        }
+    }
+
+    const uint32_t addr2[] = { 0x72, 0x73 };
+    uint32_t vals2[2];
+    if (this->ReadRegisters(addr2, vals2, 2) != 0)
+    {
+        return -1;
+    }
+    double count = (vals2[0] | (vals2[1] << 16)); //cock counter
+    count *= fx3Clk / fx3Cnt;   //estimate ref clock based on FX3 Clock
+    lime::debug("Estimated reference clock %1.4f MHz", count/1e6);
+    unsigned i = 0;
+    double delta = 100e6;
+
+    while (i < sizeof(clkTbl) / sizeof(*clkTbl))
+        if (delta < fabs(count - clkTbl[i]))
+            break;
+        else
+            delta = fabs(count - clkTbl[i++]);
+
+    this->SetReferenceClockRate(clkTbl[i-1]);
+    lime::debug("Selected reference clock %1.3f MHz", clkTbl[i - 1] / 1e6);
+    return clkTbl[i - 1];
+}
+
 /**	@brief Closes connection to chip and deallocates used memory.
 */
 Connection_uLimeSDR::~Connection_uLimeSDR()
@@ -105,7 +164,6 @@ int Connection_uLimeSDR::FT_FlushPipe(unsigned char ep)
 
 int Connection_uLimeSDR::FT_SetStreamPipe(unsigned char ep, size_t size)
 {
-
     int actual = 0;
     unsigned char wbuffer[20]={0};
 
@@ -170,24 +228,22 @@ int Connection_uLimeSDR::Open(const unsigned index, const int vid, const int pid
     libusb_reset_device(dev_handle);
     if(libusb_kernel_driver_active(dev_handle, 1) == 1)   //find out if kernel driver is attached
     {
-        printf("Kernel Driver Active\n");
+        lime::debug("Kernel Driver Active");
         if(libusb_detach_kernel_driver(dev_handle, 1) == 0) //detach it
-            printf("Kernel Driver Detached!\n");
+            lime::debug("Kernel Driver Detached!");
     }
     int r = libusb_claim_interface(dev_handle, 1); //claim interface 0 (the first) of device
     if(r < 0)
     {
-        printf("Cannot Claim Interface\n");
         return ReportError(-1, "Cannot claim interface - %s", libusb_strerror(libusb_error(r)));
     }
     r = libusb_claim_interface(dev_handle, 1); //claim interface 0 (the first) of device
     if(r < 0)
     {
-        printf("Cannot Claim Interface\n");
         return ReportError(-1, "Cannot claim interface - %s", libusb_strerror(libusb_error(r)));
     }
-    printf("Claimed Interface\n");
-
+    lime::debug("Claimed Interface");
+    
     FT_SetStreamPipe(0x82,64);
     FT_SetStreamPipe(0x02,64);
     isConnected = true;
@@ -350,42 +406,31 @@ static void callback_libusbtransfer(libusb_transfer *trans)
     switch(trans->status)
     {
         case LIBUSB_TRANSFER_CANCELLED:
-            //printf("Transfer %i canceled\n", context->id);
             context->bytesXfered = trans->actual_length;
             context->done.store(true);
-            //context->used = false;
-            //context->reset();
             break;
         case LIBUSB_TRANSFER_COMPLETED:
-            //if(trans->actual_length == context->bytesExpected)
-            {
-                context->bytesXfered = trans->actual_length;
-                context->done.store(true);
-            }
+            context->bytesXfered = trans->actual_length;
+            context->done.store(true);
         break;
         case LIBUSB_TRANSFER_ERROR:
-            printf("TRANSFER ERRRO\n");
+            lime::error("TRANSFER ERROR");
             context->bytesXfered = trans->actual_length;
             context->done.store(true);
-            //context->used = false;
             break;
         case LIBUSB_TRANSFER_TIMED_OUT:
-            //printf("transfer timed out %i\n", context->id);
+            lime::error("transfer timed out %i", context->id);
             context->bytesXfered = trans->actual_length;
             context->done.store(true);
-            //context->used = false;
-
             break;
         case LIBUSB_TRANSFER_OVERFLOW:
-            printf("transfer overflow\n");
-
+            lime::error("transfer overflow\n");
             break;
         case LIBUSB_TRANSFER_STALL:
-            printf("transfer stalled\n");
+            lime::error("transfer stalled");
             break;
         case LIBUSB_TRANSFER_NO_DEVICE:
-            printf("transfer no device\n");
-
+            lime::error("transfer no device");
             break;
     }
     lck.unlock();
@@ -414,7 +459,7 @@ int Connection_uLimeSDR::BeginDataReading(char *buffer, uint32_t length)
     }
     if(!contextFound)
     {
-        printf("No contexts left for reading data\n");
+        lime::error("No contexts left for reading data");
         return -1;
     }
     contexts[i].used = true;
@@ -446,7 +491,7 @@ int Connection_uLimeSDR::BeginDataReading(char *buffer, uint32_t length)
     int status = libusb_submit_transfer(tr);
     if(status != 0)
     {
-        printf("ERROR BEGIN DATA READING %s\n", libusb_error_name(status));
+        lime::error("ERROR BEGIN DATA READING %s", libusb_error_name(status));
         contexts[i].used = false;
         return -1;
     }
@@ -598,7 +643,7 @@ int Connection_uLimeSDR::BeginDataSending(const char *buffer, uint32_t length)
     int status = libusb_submit_transfer(tr);
     if(status != 0)
     {
-        printf("ERROR BEGIN DATA SENDING %s\n", libusb_error_name(status));
+        lime::error("ERROR BEGIN DATA SENDING %s", libusb_error_name(status));
         contextsToSend[i].used = false;
         return -1;
     }
diff --git a/src/Connection_uLimeSDR/Connection_uLimeSDR.h b/src/Connection_uLimeSDR/Connection_uLimeSDR.h
index 32cea9b..bdc4754 100644
--- a/src/Connection_uLimeSDR/Connection_uLimeSDR.h
+++ b/src/Connection_uLimeSDR/Connection_uLimeSDR.h
@@ -107,7 +107,8 @@ protected:
     virtual int WaitForSending(int contextHandle, uint32_t timeout_ms);
     virtual int FinishDataSending(const char* buffer, uint32_t length, int contextHandle);
     virtual void AbortSending();
-
+    double DetectRefClk(void);
+    
     int ResetStreamBuffers() override;
 
     eConnectionType GetType(void) {return USB_PORT;}
diff --git a/src/Connection_uLimeSDR/Connection_uLimeSDREntry.cpp b/src/Connection_uLimeSDR/Connection_uLimeSDREntry.cpp
index 0d6132a..eefa1a9 100644
--- a/src/Connection_uLimeSDR/Connection_uLimeSDREntry.cpp
+++ b/src/Connection_uLimeSDR/Connection_uLimeSDREntry.cpp
@@ -5,6 +5,7 @@
 */
 
 #include "Connection_uLimeSDR.h"
+#include "Logger.h"
 using namespace lime;
 
 #ifdef __unix__
@@ -16,7 +17,7 @@ void Connection_uLimeSDREntry::handle_libusb_events()
     while(mProcessUSBEvents.load() == true)
     {
         int r = libusb_handle_events_timeout_completed(ctx, &tv, NULL);
-        if(r != 0) printf("error libusb_handle_events %s\n", libusb_strerror(libusb_error(r)));
+        if(r != 0) lime::error("error libusb_handle_events %s", libusb_strerror(libusb_error(r)));
     }
 }
 #endif // __UNIX__
@@ -37,7 +38,7 @@ Connection_uLimeSDREntry::Connection_uLimeSDREntry(void):
 #else
     int r = libusb_init(&ctx); //initialize the library for the session we just declared
     if(r < 0)
-        printf("Init Error %i\n", r); //there was an error
+        lime::error("Init Error %i", r); //there was an error
     libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
     mProcessUSBEvents.store(true);
     mUSBProcessingThread = std::thread(&Connection_uLimeSDREntry::handle_libusb_events, this);
@@ -81,7 +82,7 @@ std::vector<ConnectionHandle> Connection_uLimeSDREntry::enumerate(const Connecti
     int usbDeviceCount = libusb_get_device_list(ctx, &devs);
 
     if (usbDeviceCount < 0) {
-        printf("failed to get libusb device list: %s\n", libusb_strerror(libusb_error(usbDeviceCount)));
+        lime::error("failed to get libusb device list: %s", libusb_strerror(libusb_error(usbDeviceCount)));
         return handles;
     }
 
@@ -90,7 +91,7 @@ std::vector<ConnectionHandle> Connection_uLimeSDREntry::enumerate(const Connecti
     {
         int r = libusb_get_device_descriptor(devs[i], &desc);
         if(r<0)
-            printf("failed to get device description\n");
+            lime::error("failed to get device description");
         int pid = desc.idProduct;
         int vid = desc.idVendor;
 
@@ -103,11 +104,11 @@ std::vector<ConnectionHandle> Connection_uLimeSDREntry::enumerate(const Connecti
                 if(libusb_kernel_driver_active(tempDev_handle, 0) == 1)   //find out if kernel driver is attached
                 {
                     if(libusb_detach_kernel_driver(tempDev_handle, 0) == 0) //detach it
-                        printf("Kernel Driver Detached!\n");
+                        lime::debug("Kernel Driver Detached!");
                 }
                 if(libusb_claim_interface(tempDev_handle, 0) < 0) //claim interface 0 (the first) of device
                 {
-                    printf("Cannot Claim Interface\n");
+                    lime::error("Cannot Claim Interface");
                 }
 
                 ConnectionHandle handle;
@@ -124,7 +125,7 @@ std::vector<ConnectionHandle> Connection_uLimeSDREntry::enumerate(const Connecti
                 memset(data, 0, 255);
                 int st = libusb_get_string_descriptor_ascii(tempDev_handle, 2, (unsigned char*)data, 255);
                 if(st < 0)
-                    printf("Error getting usb descriptor\n");
+                    lime::error("Error getting usb descriptor");
                 if(strlen(data) > 0)
                     handle.name = std::string(data, size_t(st));
                 handle.addr = std::to_string(int(pid))+":"+std::to_string(int(vid));
@@ -133,7 +134,7 @@ std::vector<ConnectionHandle> Connection_uLimeSDREntry::enumerate(const Connecti
                 {
                     r = libusb_get_string_descriptor_ascii(tempDev_handle,desc.iSerialNumber,(unsigned char*)data, sizeof(data));
                     if(r<0)
-                        printf("failed to get serial number\n");
+                        lime::error("failed to get serial number");
                     else
                         handle.serial = std::string(data, size_t(r));
                 }
diff --git a/src/Connection_uLimeSDR/Connection_uLimeSDRing.cpp b/src/Connection_uLimeSDR/Connection_uLimeSDRing.cpp
index 8e8208e..07f4435 100644
--- a/src/Connection_uLimeSDR/Connection_uLimeSDRing.cpp
+++ b/src/Connection_uLimeSDR/Connection_uLimeSDRing.cpp
@@ -16,6 +16,7 @@
 #include <vector>
 #include <FPGA_common.h>
 #include "ErrorReporting.h"
+#include "Logger.h"
 
 using namespace lime;
 using namespace std;
@@ -135,9 +136,6 @@ int Connection_uLimeSDR::UpdateExternalDataRate(const size_t channel, const doub
         if (phaseSearch)
         {
             {
-#ifndef NDEBUG
-                printf("RX phase config:\n");
-#endif
                 clocks[3].findPhase = true;
                 const std::vector<uint32_t> spiData = { 0x0E9F, 0x07FF, 0x5550, 0xE4E4,
                     0xE4E4, 0x0086, 0x028D, 0x00FF, 0x5555, 0x02CD, 0xAAAA, 0x02ED };
@@ -149,9 +147,6 @@ int Connection_uLimeSDR::UpdateExternalDataRate(const size_t channel, const doub
                 status = lime::fpga::SetPllFrequency(this, 0, rxInterfaceClk, clocks, 4);
             }
             {
-#ifndef NDEBUG
-                printf("TX phase config:\n");
-#endif
                 clocks[3].findPhase = false;
                 const std::vector<uint32_t> spiData = { 0x0E9F, 0x07FF, 0x5550, 0xE4E4, 0xE4E4, 0x0484 };
                 WriteRegister(0x000A, 0x0000);
@@ -322,7 +317,7 @@ void Connection_uLimeSDR::ReceivePacketsLoop(Connection_uLimeSDR::Streamer* stre
                     --resetFlagsDelay;
                 else
                 {
-                    printf("L");
+                    lime::warning("L");
                     resetTxFlags.notify_one();
                     resetFlagsDelay = packetsToBatch*buffersCount;
                     stream->txLastLateTime.store(pkt[pktIndex].counter);
@@ -432,7 +427,7 @@ void Connection_uLimeSDR::TransmitPacketsLoop(Streamer* stream)
     }
     catch (const std::bad_alloc& ex) //not enough memory for buffers
     {
-        printf("Error allocating Tx buffers, not enough memory\n");
+        lime::error("Error allocating Tx buffers, not enough memory");
         return;
     }
 
diff --git a/src/Logger.cpp b/src/Logger.cpp
index c0b547f..f9049e5 100644
--- a/src/Logger.cpp
+++ b/src/Logger.cpp
@@ -9,7 +9,11 @@
 
 static void defaultLogHandler(const lime::LogLevel level, const char *message)
 {
-    fprintf(stderr, "[%s] %s\n", lime::logLevelToName(level), message);
+#ifdef NDEBUG
+    if (level == lime::LOG_LEVEL_DEBUG)
+        return;
+#endif
+    fprintf(stderr, "%s\n", message);
 }
 
 static lime::LogHandler logHandler(&defaultLogHandler);
diff --git a/src/Logger.h b/src/Logger.h
index b7131b4..9e3f5d8 100644
--- a/src/Logger.h
+++ b/src/Logger.h
@@ -16,11 +16,11 @@ namespace lime
 
 enum LogLevel
 {
-    LOG_LEVEL_CRITICAL = 50, //!< A critical error. The application might not be able to continue running successfully.
-    LOG_LEVEL_ERROR    = 40, //!< An error. An operation did not complete successfully, but the application as a whole is not affected.
-    LOG_LEVEL_WARNING  = 30, //!< A warning. An operation completed with an unexpected result.
-    LOG_LEVEL_INFO     = 20, //!< An informational message, usually denoting the successful completion of an operation.
-    LOG_LEVEL_DEBUG    = 10, //!< A debugging message.
+    LOG_LEVEL_CRITICAL = 0, //!< A critical error. The application might not be able to continue running successfully.
+    LOG_LEVEL_ERROR    = 1, //!< An error. An operation did not complete successfully, but the application as a whole is not affected.
+    LOG_LEVEL_WARNING  = 2, //!< A warning. An operation completed with an unexpected result.
+    LOG_LEVEL_INFO     = 3, //!< An informational message, usually denoting the successful completion of an operation.
+    LOG_LEVEL_DEBUG    = 4, //!< A debugging message, only shown in Debug configuration.
 };
 
 //! Log a critical error message with formatting
diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt
index ce3960d..2614e82 100644
--- a/src/examples/CMakeLists.txt
+++ b/src/examples/CMakeLists.txt
@@ -26,5 +26,9 @@ add_executable(dualRXTX dualRXTX.cpp)
 set_target_properties(dualRXTX PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
 target_link_libraries(dualRXTX LimeSuite)
 
+add_executable(gpio_example gpio_example.cpp)
+set_target_properties(gpio_example PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
+target_link_libraries(gpio_example LimeSuite)
+
 
 
diff --git a/src/examples/gpio_example.cpp b/src/examples/gpio_example.cpp
new file mode 100644
index 0000000..bde1305
--- /dev/null
+++ b/src/examples/gpio_example.cpp
@@ -0,0 +1,90 @@
+/**
+    @file   gpio_example.cpp
+    @author Lime Microsystems (www.limemicro.com)
+    @brief  GPIO example
+ */
+#include <lime/LimeSuite.h>
+#include <iostream>
+#include <chrono>
+#include <thread>
+
+//Device structure, should be initialize to NULL
+lms_device_t* device = NULL;
+
+int error()
+{
+    //print last error message
+    std::cout << "ERROR:" << LMS_GetLastErrorMessage();
+    if (device != NULL)
+        LMS_Close(device);
+    exit(-1);
+}
+
+void print_gpio(int gpio_val)
+{
+    for (int i = 0; i < 8; i++)
+    {
+        bool set = gpio_val&(1<<i); 
+        std::cout << "GPIO" << i <<": " << (set ? "High" : "Low") << std::endl;
+    }
+}
+
+int main(int argc, char** argv)
+{
+    //Find devices
+    int n;
+    lms_info_str_t list[8]; //should be large enough to hold all detected devices
+    if ((n = LMS_GetDeviceList(list)) < 0) //NULL can be passed to only get number of devices
+        error();
+
+    std::cout << "Devices found: " << n << std::endl; //print number of devices
+    if (n < 1)
+        return -1;
+
+    //open the first device
+    if (LMS_Open(&device, list[0], NULL))
+        error();
+
+    //Read current GPIO pins state using LMS_GPIORead()
+    std::cout << "Read current GPIO state:" << std::endl;
+    uint8_t gpio_val = 0;
+    if (LMS_GPIORead(device, &gpio_val, 1)!=0) //1 byte buffer is enough to read 8 GPIO pins on LimeSDR-USB
+        error();
+    print_gpio(gpio_val);
+
+    //change GPIO pins direction using LMS_GPIODirWrite()
+    std::cout << std::endl << "Set GPIO0, GPIO1, GPIO2 GPIO3 and GPIO7 to output:" << std::endl;
+    uint8_t gpio_dir = 0x8F; //set bits 0,1,2,3 and 7
+    if (LMS_GPIODirWrite(device, &gpio_dir, 1)!=0) //1 byte buffer is enough to configure 8 GPIO pins on LimeSDR-USB
+        error();
+    std::cout << "Read GPIO:" << std::endl;
+    if (LMS_GPIORead(device, &gpio_val, 1)!=0)
+        error();
+    print_gpio(gpio_val);
+  
+    //set GPIO pins output level using LMS_GPIOWrite(). Only affect GPIO that configured as output
+    std::cout << std::endl << "Set GPIO0, GPIO7 output to High level:" << std::endl;
+    gpio_val = 0x81;
+    if (LMS_GPIOWrite(device, &gpio_val, 1)!=0) //1 byte buffer is enough to set 8 GPIO pins on LimeSDR-USB
+        error();
+    std::cout << "Read GPIO:" << std::endl;
+    if (LMS_GPIORead(device, &gpio_val, 1)!=0)
+        error();
+    print_gpio(gpio_val);
+    
+    //togle single GPIO for some time (~16s)
+    std::cout << std::endl << "Toggle GPIO0" << std::endl;
+    for (int i = 0; i < 16; i++)
+    {
+        gpio_val = 0x81;
+        if (LMS_GPIOWrite(device, &gpio_val, 1)!=0)
+            error();
+        gpio_val = 0x80;
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        if (LMS_GPIOWrite(device, &gpio_val, 1)!=0)
+            error();  
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));      
+    }
+       
+    return 0;
+}
diff --git a/src/lime/LimeSuite.h b/src/lime/LimeSuite.h
index af5b073..039e519 100644
--- a/src/lime/LimeSuite.h
+++ b/src/lime/LimeSuite.h
@@ -1290,6 +1290,22 @@ API_EXPORT const char* LMS_GetLibraryVersion();
  */
 API_EXPORT const char * CALL_CONV LMS_GetLastErrorMessage(void);
 
+/**
+ * Callback function for redirecting API messages
+ * 
+ * @param lvl   lower value represents higher priority/importance message, range [0,4].
+ * @param msg   string containing log message text.
+ */
+ typedef void (*LMS_LogHandler)(int lvl, const char *msg);
+ 
+/*!
+ * Register a new system log handler. Should be called to replace the default
+ * stdio handler.
+ * 
+ * @param handler   function for handling API messages
+ */
+API_EXPORT void LMS_RegisterLogHandler(LMS_LogHandler handler);
+
 /** @} (End FN_VERSION) */
 
 #ifdef __cplusplus
diff --git a/src/lms7002m/LMS7002M.cpp b/src/lms7002m/LMS7002M.cpp
index 825f30e..00ffbcc 100644
--- a/src/lms7002m/LMS7002M.cpp
+++ b/src/lms7002m/LMS7002M.cpp
@@ -1494,7 +1494,7 @@ int LMS7002M::SetFrequencySX(bool tx, float_type freq_Hz, SX_details* output)
     }
     if(foundInCache)
     {
-        printf("SetFrequency using cache values vco:%i, csw:%i\n", vco_query, csw_query);
+        lime::info("SetFrequency using cache values vco:%i, csw:%i", vco_query, csw_query);
         sel_vco = vco_query;
         csw_value = csw_query;
     }
@@ -2191,7 +2191,7 @@ bool LMS7002M::IsSynced()
         }
         if (dataReceived[i] != regValue)
         {
-            printf("Addr: 0x%04X  gui: 0x%04X  chip: 0x%04X\n", addrToRead[i], regValue, dataReceived[i]);
+            lime::debug("Addr: 0x%04X  gui: 0x%04X  chip: 0x%04X", addrToRead[i], regValue, dataReceived[i]);
             isSynced = false;
             goto isSyncedEnding;
         }
@@ -2230,7 +2230,7 @@ bool LMS7002M::IsSynced()
         }
         if (dataReceived[i] != regValue)
         {
-            printf("Addr: 0x%04X  gui: 0x%04X  chip: 0x%04X\n", addrToRead[i], regValue, dataReceived[i]);
+            lime::debug("Addr: 0x%04X  gui: 0x%04X  chip: 0x%04X", addrToRead[i], regValue, dataReceived[i]);
             isSynced = false;
             goto isSyncedEnding;
         }
@@ -2594,7 +2594,7 @@ float_type LMS7002M::GetTemperature()
     Vdiff /= 3.9;
     float temperature = 40.5+Vdiff;
     Modify_SPI_Reg_bits(LMS7_MUX_BIAS_OUT, biasMux);
-    printf("Vtemp 0x%04X, Vptat 0x%04X, Vdiff = %.2f, temp= %.3f\n", (reg606 >> 8) & 0xFF, reg606 & 0xFF, Vdiff, temperature);
+    lime::debug("Vtemp 0x%04X, Vptat 0x%04X, Vdiff = %.2f, temp= %.3f", (reg606 >> 8) & 0xFF, reg606 & 0xFF, Vdiff, temperature);
     return temperature;
 }
 
@@ -2667,7 +2667,7 @@ int LMS7002M::CalibrateAnalogRSSI_DC_Offset()
     }
     if(edges.size() != 2)
     {
-        printf("Not found\n");
+        lime::debug("Not found");
         return ReportError(EINVAL, "Failed to find value");
     }
     int8_t found = (edges[0]+edges[1])/2;
@@ -2675,7 +2675,7 @@ int LMS7002M::CalibrateAnalogRSSI_DC_Offset()
     if(found < 0)
         wrValue |= 0x40;
     Modify_SPI_Reg_bits(LMS7param(RSSIDC_DCO1), wrValue, true);
-    printf("Found %i\n", found);
+    lime::debug("Found %i", found);
     Modify_SPI_Reg_bits(LMS7_EN_INSHSW_W_RFE, 0);
     return 0;
 }
diff --git a/src/lms7002m/LMS7002M_RxTxCalibrations.cpp b/src/lms7002m/LMS7002M_RxTxCalibrations.cpp
index b212293..05ed415 100644
--- a/src/lms7002m/LMS7002M_RxTxCalibrations.cpp
+++ b/src/lms7002m/LMS7002M_RxTxCalibrations.cpp
@@ -15,7 +15,11 @@
 #include <fstream>
 #include "dataTypes.h"
 #include <thread>
+#include "Logger.h"
+
+#ifndef NDEBUG
 #define LMS_VERBOSE_OUTPUT
+#endif
 
 #include "LMS7002M_RegistersMap.h"
 
@@ -1445,7 +1449,7 @@ void LMS7002M::CalibrateTxDCAuto()
 
     Modify_SPI_Reg_bits(LMS7param(GCORRI_TXTSP), 2047);
     Modify_SPI_Reg_bits(LMS7param(GCORRQ_TXTSP), 2047);
-    printf("I: %i, Q: %i\n", ivalue, qvalue);
+    lime::info("I: %i, Q: %i", ivalue, qvalue);
     verbose_printf("Tx DC DONE\n");
 }
 
@@ -1798,7 +1802,7 @@ int LMS7002M::CalibrateRx(float_type bandwidth_Hz, bool useExtLoopback)
         phaseOffset = phOffset;
         if(foundInCache)
         {
-            printf("Rx calibration: using cached values\n");
+            lime::info("Rx calibration: using cached values");
             SetRxDCOFF(dcoffi, dcoffq);
             Modify_SPI_Reg_bits(LMS7param(EN_DCOFF_RXFE_RFE), 1);
             Modify_SPI_Reg_bits(LMS7param(GCORRI_RXTSP), gainI);
diff --git a/src/lms7002m/LMS7002M_filtersCalibration.cpp b/src/lms7002m/LMS7002M_filtersCalibration.cpp
index 3063e9a..7300099 100644
--- a/src/lms7002m/LMS7002M_filtersCalibration.cpp
+++ b/src/lms7002m/LMS7002M_filtersCalibration.cpp
@@ -14,6 +14,7 @@
 #include <assert.h>
 #include "MCU_BD.h"
 #include "mcu_programs.h"
+#include "Logger.h"
 static const uint16_t MCU_PARAMETER_ADDRESS = 0x002D; //register used to pass parameter values to MCU
 
 #ifdef _MSC_VER
@@ -122,14 +123,14 @@ int LMS7002M::TuneRxFilter(float_type rx_lpf_freq_RF)
         //set reference clock parameter inside MCU
         long refClk = GetReferenceClk_SX(false);
         mcuControl->SetParameter(MCU_BD::MCU_REF_CLK, refClk);
-        printf("MCU Ref. clock: %g MHz\n", refClk / 1e6);
+        lime::debug("MCU Ref. clock: %g MHz", refClk / 1e6);
         //set bandwidth for MCU to read from register, value is integer stored in MHz
         mcuControl->SetParameter(MCU_BD::MCU_BW, rx_lpf_freq_RF);
         mcuControl->RunProcedure(5);
         status = mcuControl->WaitForMCU(1000);
         if(status != 0)
         {
-            printf("MCU working too long %i\n", status);
+            lime::error("MCU working too long %i", status);
         }
         //sync registers to cache
         for (int a = 0x010c; a <= 0x0114; a++) this->SPI_read(a, true);
@@ -898,14 +899,14 @@ int LMS7002M::TuneTxFilter(const float_type tx_lpf_freq_RF)
         //set reference clock parameter inside MCU
         long refClk = GetReferenceClk_SX(false);
         mcuControl->SetParameter(MCU_BD::MCU_REF_CLK, refClk);
-        printf("MCU Ref. clock: %g MHz\n", refClk / 1e6);
+        lime::debug("MCU Ref. clock: %g MHz", refClk / 1e6);
         //set bandwidth for MCU to read from register, value is integer stored in MHz
         mcuControl->SetParameter(MCU_BD::MCU_BW, tx_lpf_freq_RF);
         mcuControl->RunProcedure(6);
         status = mcuControl->WaitForMCU(1000);
         if(status != 0)
         {
-            printf("MCU working too long %i\n", status);
+            lime::error("MCU working too long %i", status);
         }
         //sync registers to cache
         for (int a = 0x0105; a <= 0x010b; a++) this->SPI_read(a, true);
diff --git a/src/lms7002m_mcu/MCU_BD.cpp b/src/lms7002m_mcu/MCU_BD.cpp
index 1f92b17..98eb9d8 100644
--- a/src/lms7002m_mcu/MCU_BD.cpp
+++ b/src/lms7002m_mcu/MCU_BD.cpp
@@ -16,6 +16,7 @@ using namespace std;
 #include <list>
 #include "ErrorReporting.h"
 #include "LMS7002M.h"
+#include "Logger.h"
 
 using namespace lime;
 
@@ -969,11 +970,6 @@ int MCU_BD::RunInstr_MCU(unsigned short * pPCVAL)
 	return retval;
 }
 
-void MCU_BD::Log(const char* msg)
-{
-    printf("%s", msg);
-}
-
 /** @brief Returns information about programming or reading data progress
 */
 MCU_BD::ProgressInfo MCU_BD::GetProgressInfo() const
@@ -1036,7 +1032,7 @@ int MCU_BD::WaitForMCU(uint32_t timeout_ms)
     }while (std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() < timeout_ms);
     mSPI_write(0x0006, 0); //return SPI control to PC
     //if((value & 0x7f) != 0)
-        std::printf("MCU algorithm time: %li ms\n", std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count());
+    lime::debug("MCU algorithm time: %li ms", std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count());
     return value & 0x7F;
 }
 
diff --git a/src/lms7002m_mcu/MCU_BD.h b/src/lms7002m_mcu/MCU_BD.h
index ce841a2..203e12c 100644
--- a/src/lms7002m_mcu/MCU_BD.h
+++ b/src/lms7002m_mcu/MCU_BD.h
@@ -55,7 +55,6 @@ class MCU_BD
         std::atomic_ushort stepsDone;
         std::atomic_ushort stepsTotal;
         std::atomic_bool aborted;
-        void Log(const char* msg);
         int WaitUntilWritten();
         int ReadOneByte(unsigned char * data);
         int One_byte_command(unsigned short data1, unsigned char * rdata1);
diff --git a/src/protocols/LMS64CProtocol.cpp b/src/protocols/LMS64CProtocol.cpp
index e414dae..dda0e21 100644
--- a/src/protocols/LMS64CProtocol.cpp
+++ b/src/protocols/LMS64CProtocol.cpp
@@ -419,10 +419,7 @@ int LMS64CProtocol::TransferPacket(GenericPacket& pkt)
     int outBufPos = 0;
     int inDataPos = 0;
     if(outLen == 0)
-    {
-        //printf("packet outlen = 0\n");
         outLen = 1;
-    }
 
     if(protocol == LMS_PROTOCOL_NOVENA)
     {
diff --git a/src/protocols/fifo.h b/src/protocols/fifo.h
index b045874..49dbb05 100644
--- a/src/protocols/fifo.h
+++ b/src/protocols/fifo.h
@@ -133,6 +133,7 @@ public:
 
             while(mElementsFilled > 0 && samplesFilled < samplesCount)
             {
+                const bool hasEOB = mBuffer[mHead].flags & lime::IStreamChannel::Metadata::END_BURST;
                 if (flags != nullptr) *flags |= mBuffer[mHead].flags;
                 const int first = mBuffer[mHead].first;
 
@@ -150,8 +151,13 @@ public:
                 }
                 else
                     mBuffer[mHead].first += cnt;
+
+                //leave the loop early when end of burst is encountered
+                //so that the calling loop can flush out the buffer
+                if (hasEOB) goto done;
             }
         }
+        done:
         lck.unlock();
         hasItems.notify_one();
         return samplesFilled;
diff --git a/src/utilities_gui/pnlMiniLog.cpp b/src/utilities_gui/pnlMiniLog.cpp
index 61c34a5..bf07a3f 100644
--- a/src/utilities_gui/pnlMiniLog.cpp
+++ b/src/utilities_gui/pnlMiniLog.cpp
@@ -20,6 +20,10 @@ void pnlMiniLog::HandleMessage(wxCommandEvent &event)
     strftime(buffer, 80, "%H:%M:%S", timeinfo);
 
     auto level = lime::LogLevel(event.GetInt());
+#ifdef NDEBUG
+    if (level == lime::LOG_LEVEL_DEBUG)
+        return;
+#endif
     if (level == 0) level = lime::LOG_LEVEL_INFO;
     wxString line(wxString::Format("[%s] %s: %s", buffer, lime::logLevelToName(level), event.GetString()));
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/limesuite.git



More information about the pkg-hamradio-commits mailing list