diff --git a/CMakeLists.txt b/CMakeLists.txt index a266ec6da..2bb5c80f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,9 @@ if(CMAKE_COMPILER_IS_GNUCXX) #default SIMD configuration uses native build flags #when packaging and x86, use sse3 so the binaries work across multiple x86 variants - set(DEFAULT_SIMD_FLAGS "native") + if(NOT DEFAULT_SIMD_FLAGS) + set(DEFAULT_SIMD_FLAGS "native") + endif() if ("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr" AND X86) set(DEFAULT_SIMD_FLAGS "SSE3") endif() diff --git a/Changelog.txt b/Changelog.txt index 6f0acf9c3..c8b02782f 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,22 @@ +Release 19.04.0 (2019-05-09) +========================== + +LimeSuite library changes: +- Added support for LimeNet-Micro v2.1 +- Fixed Tx ch.B calibration when Rx ch.B is disabled +- Added save and restore of analog DC/IQ calibration values when saving/loading INI file +- Fixed Rx only mode not working on LimeSDR-USB with sample rate <2.5 MSps +- Fixed Rx only mode not working on LimeSDR-USB with sample rate <2.5 MSps +- change coefficents in LMS7002M::GetTemperature() to approximately match actual temperature + +LimeSuiteGUI: +- Updated "Board controls" panel for LimeNet-Micro + +Other changes +- Added LimeNET-Micro support to LimeQuickTest +- LimeSDR-USB v1.4 updated to r2.21 gateware +- LimeSDR-Mini updated to r1.30 gateware + Release 19.01.0 (2019-01-08) ========================== diff --git a/QuickTest/CMakeLists.txt b/QuickTest/CMakeLists.txt index 4bfed719e..0e2cebba4 100644 --- a/QuickTest/CMakeLists.txt +++ b/QuickTest/CMakeLists.txt @@ -6,6 +6,7 @@ if(ENABLE_QUICKTEST) LimeSDRTest.cpp LimeSDRTest_Mini.cpp LimeSDRTest_USB.cpp + LimeNET_Micro_Test.cpp TestGUI.cpp resources/resource.rc ${PROJECT_SOURCE_DIR}/external/kissFFT/kiss_fft.c) diff --git a/QuickTest/LimeNET_Micro_Test.cpp b/QuickTest/LimeNET_Micro_Test.cpp new file mode 100644 index 000000000..3435652a7 --- /dev/null +++ b/QuickTest/LimeNET_Micro_Test.cpp @@ -0,0 +1,131 @@ +#include "LimeSDRTest.h" + +using namespace lime; + +int LimeNET_Micro_Test::ClockNetworkTest() +{ + int ret = 0; + UpdateStatus(LMS_TEST_INFO, "->REF clock test"); + if (GPIFClkTest() == -1) + { + UpdateStatus(LMS_TEST_INFO, "->REF clock test FAILED"); + ret = -1; + } + + UpdateStatus(LMS_TEST_INFO, "->ADF4002 Test"); + if (ADF4002Test() == -1) + { + UpdateStatus(LMS_TEST_INFO, " FAILED"); + ret = -1; + } + + UpdateStatus(LMS_TEST_INFO, "->VCTCXO test"); + if (VCTCXOTest() == -1) + { + UpdateStatus(LMS_TEST_INFO, " FAILED"); + ret = -1; + } + + return ret; +} + + +int LimeNET_Micro_Test::VCTCXOTest() +{ + const uint8_t id = 0; + double val = 0; + unsigned count1; + unsigned count2; + double dac_value; + std::string units = ""; + auto conn = device->GetConnection(); + + if (conn->CustomParameterRead(&id, &dac_value, 1, nullptr) != 0) + return -1; + + auto restore_dac = [&,id](int ret){ + if (conn->CustomParameterWrite(&id, &dac_value, 1, units) != 0) + return -1; + return ret; + }; + + if (conn->CustomParameterWrite(&id, &val, 1, units) != 0) + return -1; + + if ((InitFPGATest(0x04, 1.0) & 0x4) != 0x4) + return restore_dac(-1); + + uint32_t addr[] = { 0x72, 0x73 }; + uint32_t vals[2]; + if (conn->ReadRegisters(addr, vals, 2) != 0) + return restore_dac(-1); + + count1 = vals[0] + (vals[1] << 16); + val = 65500; + if (conn->CustomParameterWrite(&id, &val, 1, units) != 0) + return -1; + + if ((InitFPGATest(0x04, 1.0) & 0x4) != 0x4) + return restore_dac(-1);; + + if (conn->ReadRegisters(addr, vals, 2) != 0) + return restore_dac(-1);; + + count2 = vals[0] + (vals[1] << 16); + std::string str = " Results : " + std::to_string(count1) + " (min); " + std::to_string(count2) + " (max)"; + + if ((count1 + 16 > count2) || (count1 + 64 < count2)) + { + str += " - FAILED"; + UpdateStatus(LMS_TEST_INFO, str.c_str()); + return restore_dac(-1);; + } + str += " - PASSED"; + UpdateStatus(LMS_TEST_INFO, str.c_str()); + return restore_dac(0); +} + +int LimeNET_Micro_Test::RFTest() +{ + auto testPath = [this](float rxfreq, int gain, int lbPath)->bool{ + const float tx_offset = 2e6; + bool passed = true; + if (device->GetLMS()->SetFrequencySX(lime::LMS7002M::Tx, rxfreq+tx_offset)!=0) + return false; + if (device->GetLMS()->SetFrequencySX(lime::LMS7002M::Rx, rxfreq)!=0) + return false; + RFTestData testinfo = {rxfreq, rxfreq+tx_offset, -14, tx_offset, 0}; + device->GetLMS()->Modify_SPI_Reg_bits(LMS7param(MAC), 1); //channel A + device->GetLMS()->SetPathRFE(lbPath==2 ? LMS7002M::PATH_RFE_LB2 : LMS7002M::PATH_RFE_LB1); + device->GetLMS()->SetBandTRF(lbPath); + if (lbPath==1) + device->GetLMS()->Modify_SPI_Reg_bits(LMS7param(SEL_PATH_RFE), 1); + if (device->GetConnection()->WriteRegister(0x17, lbPath==1? 0x5601:0x6501) != 0) + return false; + + device->WriteParam(LMS7_G_RXLOOPB_RFE, gain); + bool testPassed = RunTest(testinfo.peakval,testinfo.peakfreq, 0); + std::string str = RFTestInfo(testinfo, testPassed); + UpdateStatus(LMS_TEST_INFO, str.c_str()); + if (testPassed == false) + passed = false; + return passed; + }; + UpdateStatus(LMS_TEST_INFO, "->Configure LMS"); + device->Init(); + if (device->SetRate(8e6, 0)!=0) + { + UpdateStatus(LMS_TEST_FAIL, "Failed to set sample rate"); + return -1; + } + + device->EnableChannel(true, 0, true); + device->SetTestSignal(true, 0, LMS_TESTSIG_DC, 0x6000, 0x6000); + UpdateStatus(LMS_TEST_INFO, "->Testing using internal LMS7002M loopback"); + UpdateStatus(LMS_TEST_INFO, "->Run Tests (TX_1-> LNA_H):"); + bool passed = testPath(1800e6, 5, 1); + UpdateStatus(LMS_TEST_INFO, "->Run Tests (TX_2 -> LNA_L):"); + passed &= testPath(750e6, 2, 2); + + return passed ? 0 : -1; +} diff --git a/QuickTest/LimeSDRTest.cpp b/QuickTest/LimeSDRTest.cpp index 834b4fa99..867a038b0 100644 --- a/QuickTest/LimeSDRTest.cpp +++ b/QuickTest/LimeSDRTest.cpp @@ -67,23 +67,32 @@ LimeSDRTest* LimeSDRTest::Connect() return nullptr; } - std::string str = "->Device: "; - str += handles[0].serialize(); - UpdateStatus(LMS_TEST_INFO, str.c_str()); - if (str.find("USB 3") == std::string::npos) + auto info = dev->GetInfo(); + if (strstr(info->deviceName, lime::GetDeviceName(lime::LMS_DEV_LIMESDR)) + || strstr(info->deviceName, lime::GetDeviceName(lime::LMS_DEV_LIMESDRMINI))) { - str = "Warning: USB3 not available"; + std::string str = "->Device: "; + str += handles[0].serialize(); UpdateStatus(LMS_TEST_INFO, str.c_str()); + if (str.find("USB 3") == std::string::npos) + { + str = "Warning: USB3 not available"; + UpdateStatus(LMS_TEST_INFO, str.c_str()); + } + UpdateStatus(LMS_TEST_LOGFILE, handles[0].serial.c_str()); } - UpdateStatus(LMS_TEST_LOGFILE, handles[0].serial.c_str()); - auto info = dev->GetInfo(); if (strstr(info->deviceName, lime::GetDeviceName(lime::LMS_DEV_LIMESDR))) return new LimeSDRTest_USB(dev); else if (strstr(info->deviceName, lime::GetDeviceName(lime::LMS_DEV_LIMESDRMINI))) return new LimeSDRTest_Mini(dev); + else if (handles[0].media.find("USB")!=std::string::npos && strstr(info->deviceName, lime::GetDeviceName(lime::LMS_DEV_LIMENET_MICRO))) + return new LimeNET_Micro_Test(dev); else + { + UpdateStatus(LMS_TEST_FAIL, "Board not supported"); return nullptr; + } } diff --git a/QuickTest/LimeSDRTest.h b/QuickTest/LimeSDRTest.h index ccefd3c75..d380ed078 100644 --- a/QuickTest/LimeSDRTest.h +++ b/QuickTest/LimeSDRTest.h @@ -50,7 +50,7 @@ class LimeSDRTest static void UpdateStatus(int event, const char* msg = nullptr); int InitFPGATest(unsigned test, double timeout); int GPIFClkTest(); - int VCTCXOTest(); + virtual int VCTCXOTest(); bool RunTest(float &peakval, float &peakFreq, int ch = 0); static std::string RFTestInfo(const RFTestData& data, bool passed); lime::LMS7_Device* device; @@ -86,11 +86,22 @@ class LimeSDRTest_Mini : public LimeSDRTest class LimeSDRTest_USB : public LimeSDRTest { friend class LimeSDRTest; - LimeSDRTest_USB(lime::LMS7_Device* dev):LimeSDRTest(dev){}; + int ClockNetworkTest() override; int RFTest() override; int Si5351CTest(); +protected: int ADF4002Test(); + LimeSDRTest_USB(lime::LMS7_Device* dev):LimeSDRTest(dev){}; +}; + +class LimeNET_Micro_Test : public LimeSDRTest_USB +{ + friend class LimeSDRTest; + LimeNET_Micro_Test(lime::LMS7_Device* dev):LimeSDRTest_USB(dev){}; + int ClockNetworkTest() override; + int VCTCXOTest() override; + int RFTest() override; }; #endif /* LIMESDRTEST_H */ diff --git a/SoapyLMS7/Settings.cpp b/SoapyLMS7/Settings.cpp index 68fe6e5b9..9d112db09 100644 --- a/SoapyLMS7/Settings.cpp +++ b/SoapyLMS7/Settings.cpp @@ -223,7 +223,7 @@ std::complex SoapyLMS7::getDCOffset(const int direction, const size_t ch bool SoapyLMS7::hasIQBalance(const int /*direction*/, const size_t /*channel*/) const { - return false; + return true; } void SoapyLMS7::setIQBalance(const int direction, const size_t channel, const std::complex &balance) diff --git a/build/mcu_program/calibrationsLMS7_MCU.hex b/build/mcu_program/calibrationsLMS7_MCU.hex index 20269f8f7..8b9324f92 100644 --- a/build/mcu_program/calibrationsLMS7_MCU.hex +++ b/build/mcu_program/calibrationsLMS7_MCU.hex @@ -146,7 +146,7 @@ :10090300241FC39FD39400407612365CFFC3741E2A :1009130095362FF53BFC120367AB35AA34A933A8F0 :100923003212004D12039B7B3D7A00E4FDFC12382A -:100933002CEF25E0FFEE33FE74A92FF582743E3EC3 +:100933002CEF25E0FFEE33FE74B12FF582743E3EBB :10094300F583E493F53C740193F53D540FF9F53EBB :10095300E53CC4F854F0C8E53DC4540F48541FFFA8 :10096300F53F12365CB53F07123663653E6010747F @@ -357,24 +357,24 @@ :1016330022AD69AF68AE6712332C227F207E001281 :1016430039008E2B8F2CE52C540364017006FBFAB2 :101653007D448005E4FBFA7D337F82FE12332C7ECA -:101663003D7FB1123101120003123222A907E96052 +:101663003D7FB9123101120003123222A907E9604A :1016730001227B0112237C12332C1237AAD20412CB :101683002809C004C005C006C0071223511223C194 :10169300D007D006D005D0041200497B007A247904 :1016A3007478C912004D8F308E2F8D2E8C2DC2046D :1016B3001223EC121329A907E96006121793AF014D -:1016C300221236E812237A12332C7A0012240912DA -:1016D300332C1239AD40061217937F0422AD2CAC84 -:1016E3002B7F207E00123A281238D8D204122351BD -:1016F30012236E1234E31224141237E48F2D3001B7 -:1017030054E4FBFA7D777F0C7E0112332CE52D64C4 -:10171300016006E52D64027039E5125403F52EFBD2 -:101723007A0012179FE52E24FFFFE434FFFEEFF447 -:10173300FBEEF4FA7D217F0D7E0112332CE52D148F -:101743007F0070027F01E5121313543F6F602E7FF9 -:1017530007227F0722E52D64016009E52D640260FD -:10176300037F0722E52D2401FBE433FA12179F7D43 -:10177300657F0C1217867D437F0D12178612376D16 +:1016C3002212237A12332C7A0012240912332C1299 +:1016D30039AD40061217937F0422AD2CAC2B7F202B +:1016E3007E00123A281238D8D20412235112236EE4 +:1016F3001234E31224141237E48F2D300154E4FB27 +:10170300FA7D777F0C7E0112332CE52D6401600690 +:10171300E52D64027039E5125403F52EFB7A0012AD +:10172300179FE52E24FFFFE434FFFEEFF4FBEEF4F6 +:10173300FA7D217F0D7E0112332CE52D147F00707D +:10174300027F01E5121313543F6F602E7F07227F40 +:101753000722E52D64016009E52D640260037F071C +:1017630022E52D2401FBE433FA12179F7D657F0CDC +:101773001217867D437F0D1217861236E812376DD6 :101783007F0022E52D6403FB7A007E0112332C22B5 :10179300AD2CAC2B7F207E00123A28227D877F0D53 :1017A3007E0112332C227F207E001239008E418F5E @@ -421,7 +421,7 @@ :101A3300FF740293FD22740493FFAD3EED3395E0F2 :101A4300FC22AB38AA37A936A83502013E7D107FA8 :101A5300137E01227D857F147E01227F207E00126A -:101A630039008E4A8F4B7E3E7F8B123101E54B54FA +:101A630039008E4A8F4B7E3E7F93123101E54B54F2 :101A73000364017006FBFA7D228005E4FBFA7D1105 :101A83007F82FE12332C300327E51213135401FF18 :101A9300C374029FF54CFB12241212332C122445FB @@ -515,8 +515,8 @@ :1020130004368F4E8E4D8D4C8C4BAF4EAE4DAD4C2A :10202300AC4B22E4F549F54A7F20FE1239008E4D70 :102033008F4E20030A9003E8E54DF0A3E54EF079B7 -:1020430024E9605225E02421F582E4343FF583E45A -:1020530093F54B740193F54CE925E02423F582E4D1 +:1020430024E9605225E02429F582E4343FF583E452 +:1020530093F54B740193F54CE925E0242BF582E4C9 :10206300343FF583C3740193954CE493954B40221D :1020730030030512211A80081220FBECF0A3EDF0C7 :10208300054AE54A70020549054CE54C70CA054B03 @@ -572,7 +572,7 @@ :1023A300F018A4FFE92400FDE43405CD2FFFED353B :1023B300F0FE227B017A007DFF7FC07E0522A80408 :1023C300A905AA06AB07227D227B017A007F0C7E3A -:1023D3000422D3903E9D740193954EE493954D2230 +:1023D3000422D3903EA5740193954EE493954D2228 :1023E3007B407A54790912004D8F538E528D518C54 :1023F3005022C3E568956AE567956922C3E543956D :1024030045E5429544227B017D667F1C7E01227A4D @@ -835,7 +835,7 @@ :10341300227F207E001239008E408F41E4F54279ED :1034230002E4F543E54154FCFFE540FCEF4543FD71 :103433007F207E00123A28E543C39405502DE543CF -:1034430025E0249F30011012367A123689E0FCA35E +:1034430025E024A730011012367A123689E0FCA356 :10345300E0FD123A28800E12367A123900123689AC :10346300EEF0A3EFF00542054380CC19E970B2AD4D :1034730041AC407F207E00023A2812306A8F5F8E73 @@ -889,9 +889,9 @@ :10377300008F828E837F207E00123900AD07AC0656 :10378300ED5403640170084305145382EB80064330 :1037930005285382F57F207E00123A28AD82AC8340 -:1037A3007F827E00023A287907E925E0246BF582BF +:1037A3007F827E00023A287907E925E02473F582B7 :1037B300E4343FF583E493FE740193FFE925E024A9 -:1037C30079F582E4343FF583E493FC740193FD12AD +:1037C30081F582E4343FF583E493FC740193FD12A5 :1037D3003A28D9D57BFF7AB97DF87F207E01023361 :1037E3002CA905123900AC06AD07E9C4540F04FF38 :1037F30074FFFEA807088005C333CE33CED8F9F48F @@ -977,43 +977,43 @@ :103CF300FEFEFE67FDE5FD8CFD6EFD9AFE1AFEF3EA :103D03000022019D03540530071608E80A890BDEDB :103D13000CCD0D4903FF008000080084008500AE30 -:103D23000101011302000201020202080400000162 -:103D3300F0000001001C000C07FF07FF0000F8FF64 -:103D43000007F0001801003C000C07FF07FFF10B10 -:103D5300010C011201150116011701180119011AAD -:103D63000400040104020403040404050406040714 -:103D730004080409040A040C0440044204430081B7 -:103D830088E5403200058180280C218C31802E0289 -:103D9300008107FF07FF400000000000000007004C -:103DA3000000000010012098002000000000FF3DEB -:103DB3001DFF3D2FFF3D4109FF3D53FF3D83181775 -:103DC3000084008500AE010C010D011301150119DA -:103DD30004000001F00000000040000C000000009F -:103DE300F8FF0007F000001A0040003CC00080000C -:103DF300010001010102010301040105010601079C -:103E030001080109010A020002010202020802403C -:103E130004000401040204030407040A040C04401C -:103E230005C005CB02030204020502060207024194 -:103E330004040405040604080409044105C105C279 -:103E430005C305C405C505C605C705C805C905CA13 -:103E530005CC00813408600131800A120088000714 -:103E6300318C318C042661C1104C008D07FF07FF94 -:103E730020700020008107FF07FF400007001000AB -:103E83002098002000FF2020FF3DC3FF3DD3FF3DCE -:103E9300E308FF3DF3FF3E57321A70000081010F24 -:103EA3000126040A040C0001001100210002001283 -:103EB30000220032001300230033004300240034A7 -:103EC3000044005400350045005500650046005687 -:103ED3000066007600570067007700870068007867 -:103EE3000088009800790089009900A900AA00BA07 -:103EF30000CA00DA00DB00EB00FB010B011B012B06 -:103F0300013B014B015B016B017B018B019B01AB0E -:103F130001BB01CB01DB01EB01FB01FC01FD01FE58 -:103F230001FF0021002F00810082008400840085AE -:103F330000850086008C009200A700A800A800ADB1 -:103F430000AE010001040105010A010C0114011571 -:103F5300011A0200020C024002610400040F044033 -:103F63000461050005A705C005C0011C011D011E54 -:103F7300011F012101220123AD43040007803640C4 -:063F83003404033F067B3D +:103D23000101020002010202020804000001F00086 +:103D33000001000C07FF07FF0000F8FF0007F00079 +:103D43001801000C07FF07FFF10B010C010D010E19 +:103D5300010F0110011101120113011401150116C4 +:103D6300011701180119011A0400040104020403D4 +:103D73000407040A040C04400441044204430409F4 +:103D83000408040604050404008188E5009E20401D +:103D930030C609940083403203DF008D0005818023 +:103DA300280C218C31802E02008107FF07FF400081 +:103DB300070010012098FF3D1DFF3D2DFF3D3D08ED +:103DC300FF3D4DFF3D8D20160084008500AE010CA4 +:103DD300010D01130115011904000001F000000099 +:103DE3000040000C00000000F8FF0007F000001A7C +:103DF3000040003CC00080000100010101020103FA +:103E0300010401050106010701080109010A020075 +:103E13000201020202080240040004010402040336 +:103E23000407040A040C044005C005CB0203020482 +:103E330002050206020702410404040504060408FD +:103E43000409044105C105C205C305C405C505C66A +:103E530005C705C805C905CA05CC0081340860013A +:103E630031800A1200880007318C318C042661C12D +:103E7300104C008D07FF07FF20700020008107FF13 +:103E830007FF4000070010002098002000FF2020BB +:103E9300FF3DCBFF3DDBFF3DEB08FF3DFBFF3E5FFF +:103EA300321A70000081010F0126040A040C00017C +:103EB300001100210002001200220032001300232F +:103EC300003300430024003400440054003500450F +:103ED30000550065004600560066007600570067EF +:103EE30000770087006800780088009800790089CF +:103EF300009900A900AA00BA00CA00DA00DB00EBAF +:103F030000FB010B011B012B013B014B015B016B0F +:103F1300017B018B019B01AB01BB01CB01DB01EBFE +:103F230001FB01FC01FD01FE01FF0021002F0081C7 +:103F3300008200840084008500850086008C009246 +:103F430000A700A800A800AD00AE01000104010510 +:103F5300010A010C01140115011A0200020C0240AE +:103F630002610400040F04400461050005A705C0B5 +:103F730005C0011C011D011E011F01210122012396 +:0E3F8300AD430400078036403404033F067B44 :00000001FF diff --git a/cmake/DownloadImages.cmake b/cmake/DownloadImages.cmake index 46c390cc3..1a98c06bf 100644 --- a/cmake/DownloadImages.cmake +++ b/cmake/DownloadImages.cmake @@ -12,10 +12,10 @@ message(STATUS "## DOWNLOAD_IMAGES=${DOWNLOAD_IMAGES} specified; syncing images. message(STATUS "######################################################") #download support constants -set(SOURCE_URL "http://downloads.myriadrf.org/project/limesuite/${VERSION_MAJOR}.${VERSION_MINOR}") +set(SOURCE_URL "https://downloads.myriadrf.org/project/limesuite/${VERSION_MAJOR}.${VERSION_MINOR}") set(TEMP_DEST "${CMAKE_CURRENT_BINARY_DIR}/images/${VERSION_MAJOR}.${VERSION_MINOR}") set(INSTALL_DEST "share/LimeSuite/images/${VERSION_MAJOR}.${VERSION_MINOR}") -set(HREF_MATCHER "href=\\\"([\\._A-Za-z_0-9-]+)\\\"") +set(HREF_MATCHER "href=\\\"/project/limesuite/${VERSION_MAJOR}.${VERSION_MINOR}/([\\._A-Za-z_0-9-]+(.rpd|.rbf|.img))\\\"") #conditional download when file is missing function(DOWNLOAD_URL url file) diff --git a/debian/changelog b/debian/changelog index 5932e6bce..38d5315fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +limesuite (19.04.0-1) unstable; urgency=low + + * Release 19.04.0 (2019-05-09) + + -- Lime Microsystems Thu, 09 May 2019 14:30:00 +0300 + limesuite (19.01.0-1) unstable; urgency=low * Release 19.01.0 (2019-02-08) diff --git a/debian/control b/debian/control index 721cf1ea3..334773e5e 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,7 @@ Homepage: https://myriadrf.org/projects/lime-suite/ Vcs-Git: https://github.com/myriadrf/LimeSuite.git Vcs-Browser: https://github.com/myriadrf/LimeSuite.git -Package: liblimesuite19.01-1 +Package: liblimesuite19.04-1 Section: libs Architecture: any Multi-Arch: same @@ -30,7 +30,7 @@ Package: liblimesuite-dev Section: libdevel Architecture: any Depends: - liblimesuite19.01-1 (= ${binary:Version}), + liblimesuite19.04-1 (= ${binary:Version}), ${misc:Depends} Description: Lime Suite - development files Lime Suite application software. @@ -39,7 +39,7 @@ Package: limesuite Section: comm Architecture: any Depends: - liblimesuite19.01-1 (= ${binary:Version}), + liblimesuite19.04-1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, xdg-utils @@ -59,7 +59,7 @@ Section: comm Architecture: any Multi-Arch: same Depends: - liblimesuite19.01-1 (= ${binary:Version}), + liblimesuite19.04-1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Lime Suite - SoapySDR bindings @@ -73,7 +73,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, udev Description: Lime Suite - USB rules for udev Lime Suite application software. -Package: limesuite-images19.01 +Package: limesuite-images19.04 Section: libs Architecture: any Multi-Arch: same @@ -87,7 +87,7 @@ Package: limesuite-images Section: libs Architecture: any Multi-Arch: same -Depends: ${shlibs:Depends}, ${misc:Depends}, limesuite-images19.01 +Depends: ${shlibs:Depends}, ${misc:Depends}, limesuite-images19.04 Description: Lime Suite - Install firmware and gateware images Lime Suite application software. . diff --git a/debian/liblimesuite19.01-1.install b/debian/liblimesuite19.04-1.install similarity index 100% rename from debian/liblimesuite19.01-1.install rename to debian/liblimesuite19.04-1.install diff --git a/docs/doxygen/mainpage.dox b/docs/doxygen/mainpage.dox index 7332da3e5..aa1140a5f 100644 --- a/docs/doxygen/mainpage.dox +++ b/docs/doxygen/mainpage.dox @@ -13,6 +13,13 @@ LMS API is a set of C functions that are exported by LimeSuite library. Its main /*! \page page_changelog Changelog +### v19.04.0 + +\li Added support for LimeNet-Micro +\ii Added saving and loading of analog IQ/DC calibration state to LMS_SaveConfig() and LMS_SaveConfig() +\li Fixed Rx stream failing to start on LimeSDR-USB when Tx is disabled and sample rate is <2.5 MSps +\li Fixed Tx ch.B calibration when Rx ch.B is disabled + ### v19.01.0 \li Changed LMS_VCTCXOWrite() to save value to non-volatile storage diff --git a/mcu_program/common_src/lms7002m_calibrations.c b/mcu_program/common_src/lms7002m_calibrations.c index 20f1bc64f..18194c134 100644 --- a/mcu_program/common_src/lms7002m_calibrations.c +++ b/mcu_program/common_src/lms7002m_calibrations.c @@ -22,8 +22,11 @@ #include #include +#ifdef DRAW_GNU_PLOTS #define PUSH_GMEASUREMENT_VALUES(value, rssi) gMeasurements.push_back({value, rssi}) - +#else +#define PUSH_GMEASUREMENT_VALUES(value, rssi) +#endif #include GNUPlotPipe saturationPlot; GNUPlotPipe IQImbalancePlot; @@ -714,15 +717,15 @@ uint8_t CalibrateTxSetup(bool extLoopback) Modify_SPI_Reg_bits(DC_BYP_TXTSP, 0); Modify_SPI_Reg_bits(GC_BYP_TXTSP, 0); Modify_SPI_Reg_bits(PH_BYP_TXTSP, 0); - Modify_SPI_Reg_bits(GCORRI_TXTSP.address, GCORRI_TXTSP.msblsb , 2047); - Modify_SPI_Reg_bits(GCORRQ_TXTSP.address, GCORRQ_TXTSP.msblsb, 2047); + Modify_SPI_Reg_bits(GCORRI_TXTSP, 2047); + Modify_SPI_Reg_bits(GCORRQ_TXTSP, 2047); Modify_SPI_Reg_bits(CMIX_SC_TXTSP, 0); - Modify_SPI_Reg_bits(LMS7param(CMIX_GAIN_TXTSP), 0); - Modify_SPI_Reg_bits(LMS7param(CMIX_GAIN_TXTSP_R3), 0); + Modify_SPI_Reg_bits(CMIX_GAIN_TXTSP, 0); + Modify_SPI_Reg_bits(CMIX_GAIN_TXTSP_R3, 0); //RXTSP SetDefaults(SECTION_RxTSP); - SetDefaults(SECTION_RxNCO); + //SetDefaults(SECTION_RxNCO); Modify_SPI_Reg_bits(GFIR3_BYP_RXTSP, 0); Modify_SPI_Reg_bits(GFIR2_BYP_RXTSP, 1); Modify_SPI_Reg_bits(GFIR1_BYP_RXTSP, 1); @@ -765,11 +768,11 @@ uint8_t CalibrateTxSetup(bool extLoopback) else Modify_SPI_Reg_bits(PD_RX_AFE2, 0); { - ROM const uint16_t TxSetupAddr[] = {0x0084, 0x0085,0x00AE,0x0101,0x0113,0x0200,0x0201,0x0202,0x0208}; - ROM const uint16_t TxSetupData[] = {0x0400, 0x0001,0xF000,0x0001,0x001C,0x000C,0x07FF,0x07FF,0x0000}; - ROM const uint16_t TxSetupMask[] = {0xF8FF, 0x0007,0xF000,0x1801,0x003C,0x000C,0x07FF,0x07FF,0xF10B}; - ROM const uint16_t TxSetupWrOnlyAddr[] = {0x010C,0x0112,0x0115,0x0116,0x0117,0x0118,0x0119,0x011A,0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040A,0x040C,0x0440,0x0442,0x0443, 0x0081}; - ROM const uint16_t TxSetupWrOnlyData[] = {0x88E5,0x4032,0x0005,0x8180,0x280C,0x218C,0x3180,0x2E02,0x0081,0x07FF,0x07FF,0x4000,0x0000,0x0000,0x0000,0x0700,0x0000,0x0000,0x1001,0x2098,0x0020,0x0000,0x0000}; + ROM const uint16_t TxSetupAddr[] = {0x0084, 0x0085,0x00AE,0x0101,0x0200,0x0201,0x0202,0x0208}; + ROM const uint16_t TxSetupData[] = {0x0400, 0x0001,0xF000,0x0001,0x000C,0x07FF,0x07FF,0x0000}; + ROM const uint16_t TxSetupMask[] = {0xF8FF, 0x0007,0xF000,0x1801,0x000C,0x07FF,0x07FF,0xF10B}; + ROM const uint16_t TxSetupWrOnlyAddr[] = {0x010C,0x010D,0x010E,0x010F,0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011A,0x0400,0x0401,0x0402,0x0403,0x0407,0x040A,0x040C,0x0440, 0x0441, 0x0442, 0x0443 ,0x0409,0x0408,0x0406,0x0405,0x0404,0x0081}; + ROM const uint16_t TxSetupWrOnlyData[] = {0x88E5,0x009E,0x2040,0x30C6,0x0994,0x0083,0x4032,0x03DF,0x008D,0x0005,0x8180,0x280C,0x218C,0x3180,0x2E02,0x0081,0x07FF,0x07FF,0x4000,0x0700,0x1001,0x2098}; // rest of values will be written as zeros ROM const RegisterBatch batch = { TxSetupAddr, TxSetupData, TxSetupMask, sizeof(TxSetupAddr)/sizeof(uint16_t), TxSetupWrOnlyAddr, TxSetupWrOnlyData, sizeof(TxSetupWrOnlyAddr)/sizeof(uint16_t), sizeof(TxSetupWrOnlyData)/sizeof(uint16_t)}; @@ -793,9 +796,6 @@ uint8_t CalibrateTxSetup(bool extLoopback) } } - //if calibrating ch. B enable buffers - EnableMIMOBuffersIfNecessary(); - //SXT{ Modify_SPI_Reg_bits(MAC, 2); //switch to ch. B Modify_SPI_Reg_bits(PD_LOCH_T2RBUF, 1); @@ -853,6 +853,8 @@ uint8_t CalibrateTxSetup(bool extLoopback) Modify_SPI_Reg_bits(0x010D, MSB_LSB(4, 3), sel_band1_2_trf ^ 0x3); } } + //if calibrating ch. B enable buffers + EnableMIMOBuffersIfNecessary(); EnableChannelPowerControls(); return MCU_NO_ERROR; } @@ -963,8 +965,8 @@ uint8_t CalibrateRxSetup(bool extLoopback) Modify_SPI_Reg_bits(0x010C, 7 << 4 | 7, 0); //PD_LNA 0 //RBB - Modify_SPI_Reg_bits(0x0115, MSBLSB(15, 14), 0); //Loopback switches disable - Modify_SPI_Reg_bits(0x0119, MSBLSB(15, 15), 0); //OSW_PGA 0 + Modify_SPI_Reg_bits(0x0115, MSB_LSB(15, 14), 0); //Loopback switches disable + Modify_SPI_Reg_bits(0x0119, MSB_LSB(15, 15), 0); //OSW_PGA 0 //TRF //reset TRF to defaults @@ -990,23 +992,23 @@ uint8_t CalibrateRxSetup(bool extLoopback) Modify_SPI_Reg_bits(ICT_IAMP_GG_FRP_TBB, 6); //XBUF - Modify_SPI_Reg_bits(0x0085, MSBLSB(2, 0), 1); //PD_XBUF_RX 0, PD_XBUF_TX 0, EN_G_XBUF 1 + Modify_SPI_Reg_bits(0x0085, MSB_LSB(2, 0), 1); //PD_XBUF_RX 0, PD_XBUF_TX 0, EN_G_XBUF 1 //TXTSP SetDefaults(SECTION_TxTSP); - SetDefaults(SECTION_TxNCO); + //SetDefaults(SECTION_TxNCO); Modify_SPI_Reg_bits(TSGFCW_TXTSP, 1); Modify_SPI_Reg_bits(TSGMODE_TXTSP, 0x1); Modify_SPI_Reg_bits(INSEL_TXTSP, 1); - Modify_SPI_Reg_bits(0x0208, MSBLSB(6, 4), 0x7); //GFIR3_BYP 1, GFIR2_BYP 1, GFIR1_BYP 1 + Modify_SPI_Reg_bits(0x0208, MSB_LSB(6, 4), 0x7); //GFIR3_BYP 1, GFIR2_BYP 1, GFIR1_BYP 1 Modify_SPI_Reg_bits(CMIX_GAIN_TXTSP, 0); Modify_SPI_Reg_bits(CMIX_SC_TXTSP, 1); Modify_SPI_Reg_bits(CMIX_BYP_TXTSP, 0); //RXTSP SetDefaults(SECTION_RxTSP); - SetDefaults(SECTION_RxNCO); - Modify_SPI_Reg_bits(0x040C, MSBLSB(5, 3), 0x3); //GFIR2_BYP, GFIR1_BYP + //SetDefaults(SECTION_RxNCO); + Modify_SPI_Reg_bits(0x040C, MSB_LSB(5, 3), 0x3); //GFIR2_BYP, GFIR1_BYP Modify_SPI_Reg_bits(HBD_OVR_RXTSP, 4); Modify_SPI_Reg_bits(AGC_MODE_RXTSP, 1); @@ -1026,10 +1028,10 @@ uint8_t CalibrateRxSetup(bool extLoopback) EndBatch(); //BIAS { - uint16_t rp_calib_bias = Get_SPI_Reg_bits(0x0084, MSBLSB(10, 6)); + uint16_t rp_calib_bias = Get_SPI_Reg_bits(0x0084, MSB_LSB(10, 6)); SetDefaults(SECTION_BIAS); - Modify_SPI_Reg_bits(0x0084, MSBLSB(10, 6), rp_calib_bias); - }*/ + Modify_SPI_Reg_bits(0x0084, MSB_LSB(10, 6), rp_calib_bias); + } /*if(!extLoopback) { diff --git a/mcu_program/host_src/main.cpp b/mcu_program/host_src/main.cpp index 8f0489cc9..e845d0911 100644 --- a/mcu_program/host_src/main.cpp +++ b/mcu_program/host_src/main.cpp @@ -337,8 +337,6 @@ int main(int argc, char** argv) //change SPI switch to BB, just in case it was left for MCU lmsControl.SPI_write(0x0006, 0); - RefClk = lmsControl.GetReferenceClk_SX(false); - //load initial chip config for testing string filename; /*if(tx) @@ -353,6 +351,7 @@ int main(int argc, char** argv) lime::ConnectionRegistry::freeConnection(serPort); return -1; } + RefClk = lmsControl.GetReferenceClk_SX(false); lmsControl.UploadAll(); //calibrating A channel //lmsControl.SetActiveChannel(lime::LMS7002M::Channel::ChB); @@ -364,8 +363,8 @@ int main(int argc, char** argv) } //lmsControl.Modify_SPI_Reg_bits(LMS7param(MAC), 2); - float crestFactor = 1; - uint32_t wantedRSSI = 87330 / pow(10.0, (3+crestFactor)/20); + //float crestFactor = 1; + //uint32_t wantedRSSI = 87330 / pow(10.0, (3+crestFactor)/20); //RunAGC(wantedRSSI); int status = 0; diff --git a/mcu_program/host_src/spi.cpp b/mcu_program/host_src/spi.cpp index b7225b1bb..24a971d20 100644 --- a/mcu_program/host_src/spi.cpp +++ b/mcu_program/host_src/spi.cpp @@ -36,7 +36,7 @@ unsigned short SPI_read (unsigned short spiAddrReg) void Modify_SPI_Reg_bits_WrOnly(const uint16_t SPI_reg_addr, const uint8_t bits, const uint16_t new_bits_data, const uint16_t spiDataReg) { - const uint16_t spiMask = (~(~0 << ((bits>>4)-(bits&0xF)+1))) << (bits&0xF); // creates bit mask + const uint16_t spiMask = (~(~0u << ((bits>>4)-(bits&0xF)+1))) << (bits&0xF); // creates bit mask //spiDataReg = (spiDataReg & (~spiMask)) | ((new_bits_data << (bits&0xF)) & spiMask) ;//clear bits if(batchActive) @@ -65,7 +65,7 @@ void Modify_SPI_Reg_bits_WrOnly(const uint16_t SPI_reg_addr, const uint8_t bits, void Modify_SPI_Reg_bits(const uint16_t SPI_reg_addr, const uint8_t bits, const uint16_t new_bits_data) { uint16_t spiDataReg = SPI_read(SPI_reg_addr); //read current SPI reg data - const uint16_t spiMask = (~(~0 << ((bits>>4)-(bits&0xF)+1))) << (bits&0xF); // creates bit mask + const uint16_t spiMask = (~(~0u << ((bits>>4)-(bits&0xF)+1))) << (bits&0xF); // creates bit mask spiDataReg = (spiDataReg & (~spiMask)) | ((new_bits_data << (bits&0xF)) & spiMask) ;//clear bits if(batchActive) @@ -93,7 +93,7 @@ void Modify_SPI_Reg_bits(const uint16_t SPI_reg_addr, const uint8_t bits, const uint16_t Get_SPI_Reg_bits(const uint16_t SPI_reg_addr, const uint8_t bits) { - return (SPI_read(SPI_reg_addr) & (~(~0<<((bits>>4)+1)))) >> (bits&0xF); //shift bits to LSB + return (SPI_read(SPI_reg_addr) & (~(~0u<<((bits>>4)+1)))) >> (bits&0xF); //shift bits to LSB } @@ -119,9 +119,9 @@ void SPI_write_batch(const uint16_t *addr, const uint16_t *values, uint8_t cnt) if(batchActive) { bool found = false; - for(size_t i=0; i zeroValued; + for(int i=0; i=0; --i) + { + bAddr.push_back(bAddr[zeroValued[i]]); // move zero valued registers to end + bAddr.erase(bAddr.begin()+zeroValued[i]); + bMask.erase(bMask.begin()+zeroValued[i]); + bData.erase(bData.begin()+zeroValued[i]); + } + char temp[64]; std::fstream fout; fout.open("Batches.txt", ios::out | ios::app); diff --git a/rerelln.sh b/rerelln.sh old mode 100644 new mode 100755 diff --git a/src/API/LimeNET_micro.cpp b/src/API/LimeNET_micro.cpp index 8d2a52042..5b4437037 100644 --- a/src/API/LimeNET_micro.cpp +++ b/src/API/LimeNET_micro.cpp @@ -15,6 +15,58 @@ namespace lime LMS7_LimeNET_micro::LMS7_LimeNET_micro(lime::IConnection* conn, LMS7_Device *obj): LMS7_LimeSDR_mini(conn, obj) { + if (lms_list[0]->GetReferenceClk_SX(false) < 0) + { + lime::info("Reference clock set to 30.72 MHz"); + lms_list[0]->SetReferenceClk_SX(false, 30.72e6); + } +} + +int LMS7_LimeNET_micro::Init() +{ + struct regVal + { + uint16_t adr; + uint16_t val; + }; + + const std::vector initVals = { + {0x0022, 0x0FFF}, {0x0023, 0x5550}, {0x002B, 0x0038}, {0x002C, 0x0000}, + {0x002D, 0x0641}, {0x0086, 0x4101}, {0x0087, 0x5555}, {0x0088, 0x03F0}, + {0x0089, 0x1078}, {0x008B, 0x2100}, {0x008C, 0x267B}, {0x00A1, 0x656A}, + {0x00A6, 0x0009}, {0x00A7, 0x8A8A}, {0x00A9, 0x8000}, {0x00AC, 0x2000}, + {0x0105, 0x0011}, {0x0108, 0x118C}, {0x0109, 0x6100}, {0x010A, 0x1F4C}, + {0x010B, 0x0001}, {0x010C, 0x8865}, {0x010E, 0x0000}, {0x010F, 0x3142}, + {0x0110, 0x2B14}, {0x0111, 0x0000}, {0x0112, 0x942E}, {0x0113, 0x03C2}, + {0x0114, 0x00D0}, {0x0117, 0x1230}, {0x0119, 0x18D2}, {0x011C, 0x8941}, + {0x011D, 0x0000}, {0x011E, 0x0740}, {0x0120, 0xE6C4}, {0x0121, 0x3650}, + {0x0123, 0x000F}, {0x0200, 0x00E1}, {0x0208, 0x017B}, {0x020B, 0x4000}, + {0x020C, 0x8000}, {0x0400, 0x8081}, {0x0404, 0x0006}, {0x040B, 0x1020}, + {0x040C, 0x00FB} + }; + + lime::LMS7002M* lms = lms_list[0]; + if (lms->ResetChip() != 0) + return -1; + + lms->Modify_SPI_Reg_bits(LMS7param(MAC), 1); + for (auto i : initVals) + lms->SPI_write(i.adr, i.val, true); + lms->EnableChannel(true, false); + + lms->Modify_SPI_Reg_bits(LMS7param(MAC), 2); + lms->SPI_write(0x0123, 0x000F); //SXT + lms->SPI_write(0x0120, 0xE6B4); //SXT + lms->SPI_write(0x011C, 0x8941); //SXT + lms->EnableChannel(false, false); + lms->EnableChannel(true, false); + + lms->Modify_SPI_Reg_bits(LMS7param(MAC), 1); + + if (SetRate(1e6, 16)!=0) + return -1; + + return 0; } std::vector LMS7_LimeNET_micro::GetPathNames(bool dir_tx, unsigned chan) const @@ -27,7 +79,9 @@ std::vector LMS7_LimeNET_micro::GetPathNames(bool dir_tx, unsigned int LMS7_LimeNET_micro::SetRFSwitch(bool isTx, unsigned path) { - int bom_ver = (fpga->ReadRegister(3)>>4); + int reg3 = fpga->ReadRegister(3); + int bom_ver = reg3>>4; + int hw_ver = reg3 & 0xF; if (isTx==false) { if (path==LMS_PATH_LNAW) @@ -37,17 +91,33 @@ int LMS7_LimeNET_micro::SetRFSwitch(bool isTx, unsigned path) else if (path==LMS_PATH_LNAL) { uint16_t value = fpga->ReadRegister(0x17); - value &= ~(3<<8); - fpga->WriteRegister(0x17, value | (1<<8)); + if (hw_ver >= 3) + { + value &= ~(0x0702); + fpga->WriteRegister(0x17, value | 0x0502); + } + else + { + value &= ~(3<<8); + fpga->WriteRegister(0x17, value | (1<<8)); + } } else if (path==LMS_PATH_LNAH) { uint16_t value = fpga->ReadRegister(0x17); - value &= ~(3<<8); - if (bom_ver == 0) - fpga->WriteRegister(0x17, value | (1<<8)); + if (hw_ver >= 3) + { + value &= ~(0x0702); + fpga->WriteRegister(0x17, value | 0x0602); + } else - fpga->WriteRegister(0x17, value | (2<<8)); + { + value &= ~(3<<8); + if (bom_ver == 0) + fpga->WriteRegister(0x17, value | (1<<8)); + else + fpga->WriteRegister(0x17, value | (2<<8)); + } } } else @@ -55,42 +125,65 @@ int LMS7_LimeNET_micro::SetRFSwitch(bool isTx, unsigned path) if (path==LMS_PATH_TX1) { uint16_t value = fpga->ReadRegister(0x17); - value &= ~(3<<12); - fpga->WriteRegister(0x17, value | (1<<12)); + if (hw_ver >= 3) + { + value &= ~(0x7001); + fpga->WriteRegister(0x17, value | 0x5000); + } + else + { + value &= ~(3<<12); + fpga->WriteRegister(0x17, value | (1<<12)); + } } else if (path==LMS_PATH_TX2) { uint16_t value = fpga->ReadRegister(0x17); - value &= ~(3<<12); - if (bom_ver == 0) - fpga->WriteRegister(0x17, value | (1<<12)); + if (hw_ver >= 3) + { + + value &= ~(0x7001); + fpga->WriteRegister(0x17, value | 0x6000); + } else - fpga->WriteRegister(0x17, value | (2<<12)); + { + value &= ~(3<<12); + if (bom_ver == 0) + fpga->WriteRegister(0x17, value | (1<<12)); + else + fpga->WriteRegister(0x17, value | (2<<12)); + } } } return 0; } -std::vector LMS7_LimeNET_micro::GetProgramModes() const -{ - return {program_mode::fpgaFlash, program_mode::fpgaReset, - program_mode::mcuRAM, program_mode::mcuEEPROM, program_mode::mcuReset}; -} - int LMS7_LimeNET_micro::AutoRFPath(bool isTx, double f_Hz) { - if ((fpga->ReadRegister(3)>>4) == 0) + int reg3 = fpga->ReadRegister(3); + int bom_ver = reg3>>4; + int hw_ver = reg3 & 0xF; + if (hw_ver < 3 && bom_ver == 0) return 0; if ((!isTx) && (f_Hz < 1.7e9)) { - lime::info("Selected RX path: LNAL"); - int ret = SetPath(false, 0, LMS_PATH_LNAL); + int ret = 0; + if (GetPath(false, 0)!= LMS_PATH_LNAL) + { + lime::info("Selected RX path: LNAL"); + ret = SetPath(false, 0, LMS_PATH_LNAL); + } auto_rx_path = true; return ret; } return LMS7_LimeSDR_mini::AutoRFPath(isTx, f_Hz); } +int LMS7_LimeNET_micro::SetClockFreq(unsigned clk_id, double freq, int channel) +{ + return LMS7_Device::SetClockFreq(clk_id, freq, channel); +} + }//namespace lime diff --git a/src/API/LimeNET_micro.h b/src/API/LimeNET_micro.h index e0f376d72..09b7d0dd3 100644 --- a/src/API/LimeNET_micro.h +++ b/src/API/LimeNET_micro.h @@ -9,8 +9,9 @@ class LMS7_LimeNET_micro : public LMS7_LimeSDR_mini public: LMS7_LimeNET_micro(lime::IConnection* conn, LMS7_Device *obj = nullptr); std::vector GetPathNames(bool dir_tx, unsigned chan) const override; - std::vector GetProgramModes() const override; + int Init() override; private: + int SetClockFreq(unsigned clk_id, double freq, int channel) override; int SetRFSwitch(bool tx, unsigned path) override; int AutoRFPath(bool isTx, double f_Hz) override; }; diff --git a/src/API/LimeSDR.cpp b/src/API/LimeSDR.cpp index b589935a0..c0f0be8b5 100644 --- a/src/API/LimeSDR.cpp +++ b/src/API/LimeSDR.cpp @@ -62,6 +62,14 @@ int LMS7_LimeSDR::Program(const std::string& mode, const char* data, size_t len, return ret; } +int LMS7_LimeSDR::EnableChannel(bool dir_tx, unsigned chan, bool enabled) +{ + int ret = LMS7_Device::EnableChannel(dir_tx, chan, enabled); + if (dir_tx) //always enable DAC1, otherwise sample rates <2.5MHz do not work + lms_list[0]->Modify_SPI_Reg_bits(LMS7_PD_TX_AFE1, 0); + return ret; +} + } diff --git a/src/API/LimeSDR.h b/src/API/LimeSDR.h index cf0beb7a1..4e24e3b31 100644 --- a/src/API/LimeSDR.h +++ b/src/API/LimeSDR.h @@ -19,6 +19,7 @@ class LMS7_LimeSDR : public LMS7_Generic int SetRate(double f_Hz, int oversample) override; std::vector GetProgramModes() const override; int Program(const std::string& mode, const char* data, size_t len, lime::IConnection::ProgrammingCallback callback) const override; + int EnableChannel(bool dir_tx, unsigned chan, bool enabled) override; }; } diff --git a/src/API/LimeSDR_PCIE.cpp b/src/API/LimeSDR_PCIE.cpp index c4ab45153..fe443ecec 100644 --- a/src/API/LimeSDR_PCIE.cpp +++ b/src/API/LimeSDR_PCIE.cpp @@ -51,6 +51,14 @@ int LMS7_LimeSDR_PCIE::SetRate(double f_Hz, int oversample) return SetFPGAInterfaceFreq(7, 7); } +int LMS7_LimeSDR_PCIE::EnableChannel(bool dir_tx, unsigned chan, bool enabled) +{ + int ret = LMS7_Device::EnableChannel(dir_tx, chan, enabled); + if (dir_tx) //always enable DAC, otherwise sample rates <2.5MHz do not work + lms_list[0]->Modify_SPI_Reg_bits(LMS7_PD_TX_AFE1, 0); + return ret; +} + } diff --git a/src/API/LimeSDR_PCIE.h b/src/API/LimeSDR_PCIE.h index 0c973d255..050277605 100644 --- a/src/API/LimeSDR_PCIE.h +++ b/src/API/LimeSDR_PCIE.h @@ -18,6 +18,7 @@ class LMS7_LimeSDR_PCIE : public LMS7_Generic LMS7_LimeSDR_PCIE(lime::IConnection* conn, LMS7_Device *obj = nullptr); std::vector GetProgramModes() const override; int SetRate(double f_Hz, int oversample) override; + int EnableChannel(bool dir_tx, unsigned chan, bool enabled) override; private: }; diff --git a/src/API/LimeSDR_mini.cpp b/src/API/LimeSDR_mini.cpp index 5a60c2f6c..d7a4d0af1 100644 --- a/src/API/LimeSDR_mini.cpp +++ b/src/API/LimeSDR_mini.cpp @@ -294,14 +294,20 @@ LMS7_Device::Range LMS7_LimeSDR_mini::GetFrequencyRange(bool tx) const int LMS7_LimeSDR_mini::SetClockFreq(unsigned clk_id, double freq, int channel) { if (clk_id == LMS_CLOCK_EXTREF) + { clk_id = LMS_CLOCK_REF; + if (freq <= 0) + lime::error("Switching between int./ext. ref. clock can only be done in HW (R59/R62)"); + else + lime::warning("Using external reference clock requires hardware modification (R59/R62)"); + } return LMS7_Device::SetClockFreq(clk_id, freq, channel); } int LMS7_LimeSDR_mini::EnableChannel(bool dir_tx, unsigned chan, bool enabled) { int ret = LMS7_Device::EnableChannel(dir_tx, chan, enabled); - if (lms_list[0]->Get_SPI_Reg_bits(0x82, 4, 1) == 0xD) + if (lms_list[0]->Get_SPI_Reg_bits(0x82, 4, 1) == 0xD) //TX requires ADC to be enabled lms_list[0]->Modify_SPI_Reg_bits(LMS7_PD_RX_AFE1, 0); return ret; } @@ -316,12 +322,13 @@ int LMS7_LimeSDR_mini::AutoRFPath(bool isTx, double f_Hz) int ret = 0; if (isTx) { - if (f_Hz < 2.0e9) + int path = GetPath(true, 0); + if (f_Hz < 2.0e9 && path != LMS_PATH_TX2) { lime::info("Selected TX path: Band 2"); ret = SetPath(true, 0, LMS_PATH_TX2); } - else + else if (f_Hz >= 2.0e9 && path != LMS_PATH_TX1) { lime::info("Selected TX path: Band 1"); ret = SetPath(true, 0, LMS_PATH_TX1); @@ -330,12 +337,13 @@ int LMS7_LimeSDR_mini::AutoRFPath(bool isTx, double f_Hz) } else { - if (f_Hz < 1.7e9) + int path = GetPath(false, 0); + if (f_Hz < 1.7e9 && path != LMS_PATH_LNAW) { lime::info("Selected RX path: LNAW"); ret = SetPath(false, 0, LMS_PATH_LNAW); } - else + else if (f_Hz >= 1.7e9 && path != LMS_PATH_LNAH) { lime::info("Selected RX path: LNAH"); ret = SetPath(false, 0, LMS_PATH_LNAH); diff --git a/src/API/lms7_api.cpp b/src/API/lms7_api.cpp index 39bcda1b6..990c9fe51 100644 --- a/src/API/lms7_api.cpp +++ b/src/API/lms7_api.cpp @@ -174,12 +174,12 @@ API_EXPORT int CALL_CONV LMS_ReadCustomBoardParam(lms_device_t *device, uint8_t param_id, float_type *val, lms_name_t units) { auto conn = CheckConnection(device); - std::string str; if (conn == nullptr) return -1; - + std::string str; int ret=conn->CustomParameterRead(¶m_id,val,1,&str); - strncpy(units,str.c_str(),sizeof(lms_name_t)-1); + if (units) + strncpy(units,str.c_str(),sizeof(lms_name_t)-1); return ret; } @@ -196,19 +196,20 @@ API_EXPORT int CALL_CONV LMS_WriteCustomBoardParam(lms_device_t *device, API_EXPORT int CALL_CONV LMS_VCTCXOWrite(lms_device_t * device, uint16_t val) { - int ret = LMS_WriteCustomBoardParam(device, 0, val, ""); - - auto conn = CheckConnection(device); - if (conn == nullptr) + if (LMS_WriteCustomBoardParam(device, BOARD_PARAM_DAC, val, "")<0) return -1; + auto conn = CheckConnection(device); auto port = dynamic_cast(conn); - unsigned char packet[64] = {0x8C, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 3};//packet: eeprom write 2 btes, addr 16 - packet[32] = val&0xFF; //values start at offset=32 - packet[33] = val>>8; - if (port->Write(packet, 64) != 64 || port->Read(packet, 64, 2000) != 64 || packet[1] != 1) - return -1; - return ret; + if (port) //can use LMS64C protocol to write eeprom value + { + unsigned char packet[64] = {0x8C, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 3};//packet: eeprom write 2 btes, addr 16 + packet[32] = val&0xFF; //values start at offset=32 + packet[33] = val>>8; + if (port->Write(packet, 64) != 64 || port->Read(packet, 64, 2000) != 64 || packet[1] != 1) + return -1; + } + return LMS_SUCCESS; } API_EXPORT int CALL_CONV LMS_VCTCXORead(lms_device_t * device, uint16_t *val) @@ -217,10 +218,21 @@ API_EXPORT int CALL_CONV LMS_VCTCXORead(lms_device_t * device, uint16_t *val) if (!conn) return -1; auto port = dynamic_cast(conn); - unsigned char packet[64] = {0x8D, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 3}; //packet: eeprom read 2 bytes, addr 16 - if (port->Write(packet, 64) != 64 || port->Read(packet, 64, 2000) != 64 || packet[1] != 1) - return -1; - *val = packet[32] | (packet[33]<<8); //values start at offset=32 + if (port) //can use LMS64C protocol to read eeprom value + { + unsigned char packet[64] = {0x8D, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 3}; //packet: eeprom read 2 bytes, addr 16 + if (port->Write(packet, 64) != 64 || port->Read(packet, 64, 2000) != 64 || packet[1] != 1) + return -1; + *val = packet[32] | (packet[33]<<8); //values start at offset=32 + } + else //fall back to reading runtime value + { + uint8_t id = BOARD_PARAM_DAC; + double dval; + if (conn->CustomParameterRead(&id, &dval, 1, nullptr)!=LMS_SUCCESS) + return -1; + *val = dval; + } return LMS_SUCCESS; } @@ -648,9 +660,11 @@ API_EXPORT int CALL_CONV LMS_ReadFPGAReg(lms_device_t *device, uint32_t address, lime::LMS7_Device* lms = CheckDevice(device); if (!lms) return -1; - *val = lms->ReadFPGAReg(address); - if (*val < 0) - return *val; + int value = lms->ReadFPGAReg(address); + if (value < 0) + return value; // operation failed return error code + else if (val) + *val = value; return LMS_SUCCESS; } @@ -946,4 +960,4 @@ extern "C" API_EXPORT int CALL_CONV LMS_TransferLMS64C(lms_device_t *dev, int cm } return LMS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/API/lms7_device.cpp b/src/API/lms7_device.cpp index 4357c2518..6e1b3abce 100644 --- a/src/API/lms7_device.cpp +++ b/src/API/lms7_device.cpp @@ -1355,14 +1355,13 @@ int LMS7_Device::Init() lms->Modify_SPI_Reg_bits(LMS7param(MAC), 1); for (auto i : initVals) lms->SPI_write(i.adr, i.val, true); - lms->EnableChannel(true, false); - + EnableChannel(true, 2*i, false); lms->Modify_SPI_Reg_bits(LMS7param(MAC), 2); for (auto i : initVals) if (i.adr >= 0x100) lms->SPI_write(i.adr, i.val, true); - lms->EnableChannel(false, false); - lms->EnableChannel(true, false); + EnableChannel(false, 2*i+1, false); + EnableChannel(true, 2*i+1, false); lms->Modify_SPI_Reg_bits(LMS7param(MAC), 1); } @@ -1561,16 +1560,19 @@ int LMS7_Device::SetClockFreq(unsigned clk_id, double freq, int channel) lms_dev_info_t* LMS7_Device::GetInfo() { memset(&devInfo,0,sizeof(lms_dev_info_t)); - auto info = connection->GetDeviceInfo(); - strncpy(devInfo.deviceName,info.deviceName.c_str(),sizeof(devInfo.deviceName)-1); - strncpy(devInfo.expansionName,info.expansionName.c_str(),sizeof(devInfo.expansionName)-1); - strncpy(devInfo.firmwareVersion,info.firmwareVersion.c_str(),sizeof(devInfo.firmwareVersion)-1); - strncpy(devInfo.hardwareVersion,info.hardwareVersion.c_str(),sizeof(devInfo.hardwareVersion)-1); - strncpy(devInfo.protocolVersion,info.protocolVersion.c_str(),sizeof(devInfo.protocolVersion)-1); - strncpy(devInfo.gatewareVersion, (info.gatewareVersion+"."+ info.gatewareRevision).c_str(), sizeof(devInfo.gatewareVersion) - 1); - strncpy(devInfo.gatewareTargetBoard,info.gatewareTargetBoard.c_str(),sizeof(devInfo.gatewareTargetBoard)-1); - info.boardSerialNumber = info.boardSerialNumber; - devInfo.boardSerialNumber = info.boardSerialNumber; + if (connection) + { + auto info = connection->GetDeviceInfo(); + strncpy(devInfo.deviceName,info.deviceName.c_str(),sizeof(devInfo.deviceName)-1); + strncpy(devInfo.expansionName,info.expansionName.c_str(),sizeof(devInfo.expansionName)-1); + strncpy(devInfo.firmwareVersion,info.firmwareVersion.c_str(),sizeof(devInfo.firmwareVersion)-1); + strncpy(devInfo.hardwareVersion,info.hardwareVersion.c_str(),sizeof(devInfo.hardwareVersion)-1); + strncpy(devInfo.protocolVersion,info.protocolVersion.c_str(),sizeof(devInfo.protocolVersion)-1); + strncpy(devInfo.gatewareVersion, (info.gatewareVersion+"."+ info.gatewareRevision).c_str(), sizeof(devInfo.gatewareVersion) - 1); + strncpy(devInfo.gatewareTargetBoard,info.gatewareTargetBoard.c_str(),sizeof(devInfo.gatewareTargetBoard)-1); + info.boardSerialNumber = info.boardSerialNumber; + devInfo.boardSerialNumber = info.boardSerialNumber; + } return &devInfo; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3795549b9..2bd035430 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -149,6 +149,7 @@ include(ConnectionSTREAM_UNITE/CMakeLists.txt) include(ConnectionFTDI/CMakeLists.txt) include(ConnectionXillybus/CMakeLists.txt) include(ConnectionRemote/CMakeLists.txt) +include(ConnectionSPI/CMakeLists.txt) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ConnectionRegistry/BuiltinConnections.in.cpp diff --git a/src/ConnectionRegistry/BuiltinConnections.in.cpp b/src/ConnectionRegistry/BuiltinConnections.in.cpp index c672fbda1..85bca7c07 100644 --- a/src/ConnectionRegistry/BuiltinConnections.in.cpp +++ b/src/ConnectionRegistry/BuiltinConnections.in.cpp @@ -10,6 +10,7 @@ #cmakedefine ENABLE_FTDI #cmakedefine ENABLE_PCIE_XILLYBUS #cmakedefine ENABLE_REMOTE +#cmakedefine ENABLE_SPI void __loadConnectionEVB7COMEntry(void); void __loadConnectionFX3Entry(void); @@ -18,6 +19,7 @@ void __loadConnectionNovenaRF7Entry(void); void __loadConnectionFT601Entry(void); void __loadConnectionXillybusEntry(void); void __loadConnectionRemoteEntry(void); +void __loadConnectionSPIEntry(void); void __loadAllConnections(void) { @@ -48,4 +50,8 @@ void __loadAllConnections(void) #ifdef ENABLE_REMOTE __loadConnectionRemoteEntry(); #endif + + #ifdef ENABLE_SPI + __loadConnectionSPIEntry(); + #endif } diff --git a/src/ConnectionSPI/CMakeLists.txt b/src/ConnectionSPI/CMakeLists.txt new file mode 100644 index 000000000..53515197c --- /dev/null +++ b/src/ConnectionSPI/CMakeLists.txt @@ -0,0 +1,27 @@ +######################################################################## +## Support for Rasp Pi 3 SPI connection +######################################################################## +set(THIS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ConnectionSPI) + +set(CONNECTION_SPI_SOURCES + ${THIS_SOURCE_DIR}/ConnectionSPIEntry.cpp + ${THIS_SOURCE_DIR}/ConnectionSPI.cpp +) + +######################################################################## +## Feature registration +######################################################################## +include(FeatureSummary) +include(CMakeDependentOption) +cmake_dependent_option(ENABLE_SPI "Enable SPI connection" OFF "ENABLE_LIBRARY" OFF) +add_feature_info(ConnectionSPI ENABLE_SPI "Rasp Pi 3 SPI Connection support") +if (NOT ENABLE_SPI) + return() +endif() + +######################################################################## +## Add to library +######################################################################## +target_sources(LimeSuite PRIVATE ${CONNECTION_SPI_SOURCES}) +target_link_libraries(LimeSuite wiringPi crypt) + diff --git a/src/ConnectionSPI/ConnectionSPI.cpp b/src/ConnectionSPI/ConnectionSPI.cpp new file mode 100644 index 000000000..b392de265 --- /dev/null +++ b/src/ConnectionSPI/ConnectionSPI.cpp @@ -0,0 +1,873 @@ +/** + @file ConnectionSPI.cpp + @author Lime Microsystems + @brief Implementation of RPi 3 SPI connection for LimeNET-Micro. +*/ + +#include +#include +#include +#include +#include +#include + +#include "Logger.h" +#include "lime_spi.h" +#include "ConnectionSPI.h" +#include "SystemResources.h" + +using namespace std; +using namespace lime; + +#define SPI_STREAM_SPEED_HZ 50000000 +#define SPI_CTRL_SPEED_HZ 1000000 + +ConnectionSPI* ConnectionSPI::pthis = nullptr; +char ConnectionSPI::last_flags = 0x10; //no sync +uint64_t ConnectionSPI::rx_timestamp = 0; +std::atomic ConnectionSPI::program_mode(false); +std::atomic ConnectionSPI::program_ready(false); +/** @brief Initializes port type and object necessary to communicate to usb device. +*/ +ConnectionSPI::ConnectionSPI(const unsigned index) : + fd_stream(-1), + fd_stream_clocks(-1), + fd_control_lms(-1), + fd_control_fpga(-1), + int_pin(26) +{ + pthis = this; + program_ready.store(false); + program_mode.store(false); + if (Open(index) < 0) + lime::error("Failed to open SPI device"); + if (index == SPIDEV) + { + std::ifstream file("/proc/device-tree/model"); + if (file.good()) + { + std::string str; + std::getline(file, str); + lime::info(str.c_str()); + if (str.find("Module")!=std::string::npos) + int_pin = 12; + } + + wiringPiSetup(); + pinMode(int_pin, INPUT); + pullUpDnControl(int_pin, PUD_OFF); + wiringPiISR(int_pin, INT_EDGE_RISING, &ConnectionSPI::StreamISR); + } + + uint8_t id = 0; + double val = 35487; + CustomParameterWrite(&id, &val, 1, ""); +} +/** @brief Closes connection to chip and deallocates used memory. +*/ +ConnectionSPI::~ConnectionSPI() +{ + Close(); +} + +/** @brief Tries to open connected USB device and find communication endpoints. + @return Returns 0-Success, other-EndPoints not found or device didn't connect. +*/ +int ConnectionSPI::Open(const unsigned index) +{ + Close(); + const uint32_t mode = 0; + const uint8_t bits = 8; + const uint32_t speed_stream = SPI_STREAM_SPEED_HZ; + const uint32_t speed_control = SPI_CTRL_SPEED_HZ; + + if (index == SPIDEV) + { + if ((fd_stream = open("/dev/spidev0.0", O_RDWR)) != -1) + { + if (ioctl(fd_stream, SPI_IOC_WR_MODE, &mode) < 0) + lime::error("Failed to set SPI write mode"); + if (ioctl(fd_stream, SPI_IOC_RD_MODE, &mode) < 0) + lime::error("Failed to set SPI read mode"); + if (ioctl(fd_stream, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (write)"); + if (ioctl(fd_stream, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (read)"); + if (ioctl(fd_stream, SPI_IOC_WR_MAX_SPEED_HZ, &speed_stream) < 0) + lime::error("Failed to set SPI write max speed"); + if (ioctl(fd_stream, SPI_IOC_RD_MAX_SPEED_HZ, &speed_stream) < 0) + lime::error("Failed to set SPI read max speed"); + } + + if ((fd_stream_clocks = open("/dev/spidev0.1", O_RDWR)) != -1) + { + if (ioctl(fd_stream_clocks, SPI_IOC_WR_MODE, &mode) < 0) + lime::error("Failed to set SPI write mode"); + if (ioctl(fd_stream_clocks, SPI_IOC_RD_MODE, &mode) < 0) + lime::error("Failed to set SPI read mode"); + if (ioctl(fd_stream_clocks, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (write)"); + if (ioctl(fd_stream_clocks, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (read)"); + if (ioctl(fd_stream_clocks, SPI_IOC_WR_MAX_SPEED_HZ, &speed_stream) < 0) + lime::error("Failed to set SPI write max speed"); + if (ioctl(fd_stream_clocks, SPI_IOC_RD_MAX_SPEED_HZ, &speed_stream) < 0) + lime::error("Failed to set SPI read max speed"); + } + } + else if((fd_stream = open("/dev/lime_spi", O_RDWR)) < 0) + lime::error("Failed to open /dev/lime_spi"); + + if ((fd_control_fpga = open("/dev/spidev1.0", O_RDWR)) != -1) + { + if (ioctl(fd_control_fpga, SPI_IOC_WR_MODE, &mode) < 0) + lime::error("Failed to set SPI write mode"); + if (ioctl(fd_control_fpga, SPI_IOC_RD_MODE, &mode) < 0) + lime::error("Failed to set SPI read mode"); + if (ioctl(fd_control_fpga, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (write)"); + if (ioctl(fd_control_fpga, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (read)"); + if (ioctl(fd_control_fpga, SPI_IOC_WR_MAX_SPEED_HZ, &speed_control) < 0) + lime::error("Failed to set SPI write max speed"); + if (ioctl(fd_control_fpga, SPI_IOC_RD_MAX_SPEED_HZ, &speed_control) < 0) + lime::error("Failed to set SPI read max speed"); + } + + if ((fd_control_lms = open("/dev/spidev1.1", O_RDWR)) != -1) + { + if (ioctl(fd_control_lms, SPI_IOC_WR_MODE, &mode) < 0) + lime::error("Failed to set SPI write mode"); + if (ioctl(fd_control_lms, SPI_IOC_RD_MODE, &mode) < 0) + lime::error("Failed to set SPI read mode"); + if (ioctl(fd_control_lms, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (write)"); + if (ioctl(fd_control_lms, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + lime::error("Failed to set SPI bits per word (read)"); + if (ioctl(fd_control_lms, SPI_IOC_WR_MAX_SPEED_HZ, &speed_control) < 0) + lime::error("Failed to set SPI write max speed"); + if (ioctl(fd_control_lms, SPI_IOC_RD_MAX_SPEED_HZ, &speed_control) < 0) + lime::error("Failed to set SPI read max speed"); + } + + return IsOpen() ? 0 : -1; +} + +/** @brief Closes communication to device. +*/ +void ConnectionSPI::Close() +{ + if (fd_stream != -1) + close(fd_stream); + if (fd_stream_clocks != -1) + close(fd_stream_clocks); + if (fd_control_lms != -1) + close(fd_control_lms); + if (fd_control_fpga != -1) + close(fd_control_fpga); + fd_stream = -1; + fd_stream_clocks = -1; + fd_control_lms = -1; + fd_control_fpga = -1; +} + +/** @brief Returns connection status + @return 1-connection open, 0-connection closed. +*/ +bool ConnectionSPI::IsOpen() +{ + if (fd_stream < 0 || fd_control_lms < 0 || fd_control_fpga < 0) + return false; + return true; +} + +int ConnectionSPI::TransactSPI(const int addr, const uint32_t *writeData, uint32_t *readData, const size_t size) +{ + if (not this->IsOpen()) + { + ReportError(ENOTCONN, "connection is not open"); + return -1; + } + + //perform spi writes when there is no read data + if (readData == nullptr) switch(addr) + { + case 0x10: return this->WriteLMS7002MSPI(writeData, size); + case 0x30: return this->WriteADF4002SPI(writeData, size); + } + + if (readData != nullptr && addr == 0x10) + return this->ReadLMS7002MSPI(writeData, readData, size); + + return ReportError(ENOTSUP, "unknown spi address"); +} + +int ConnectionSPI::TransferSPI(int fd, const void *tx, void *rx, uint32_t len) +{ + spi_ioc_transfer tr = { (unsigned long)tx, + (unsigned long)rx, + len, + SPI_CTRL_SPEED_HZ, + 0, + 8 }; + int ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (pthis->callback_logData) + { + pthis->callback_logData(true, (const unsigned char*)tx, len); + pthis->callback_logData(false, (const unsigned char*)rx, len); + } + return ret; +} + +void ConnectionSPI::SetChipSelect(int cs) +{ + uint32_t addr = 0x12, val = ~(1<>16)&0xff; + writeData[1] = (data[i]>>8)&0xff; + writeData[2] = data[i]&0xff; + SetChipSelect(2); + if (TransferSPI(fd_control_lms, writeData, readData, 3)!=3) + { + lime::error("Write ADF: SPI transfer error"); + return -1; + } + SetChipSelect(0); + } + return 0; +} + +/*********************************************************************** + * LMS7002M SPI access + **********************************************************************/ +int ConnectionSPI::WriteLMS7002MSPI(const uint32_t *data, size_t size, unsigned /*periphID*/) +{ + uint32_t* readData = new uint32_t[size]; + uint8_t* writeData = new uint8_t[size*4]; + int ret = 0; + + for (unsigned i = 0; i < size; i++) + { + writeData[4*i] = (data[i]>>24)&0xff; + writeData[4*i+1] = (data[i]>>16)&0xff; + writeData[4*i+2] = (data[i]>>8)&0xff; + writeData[4*i+3] = data[i]&0xff; + } + + SetChipSelect(0); + if (TransferSPI(fd_control_lms, writeData, readData, size*4)!=size*4) + { + lime::error("Write LMS7: SPI transfer error"); + ret = -1; + } + delete [] readData; + delete [] writeData; + return ret; +} + +int ConnectionSPI::ReadLMS7002MSPI(const uint32_t *data_in, uint32_t *data_out, size_t size, unsigned periphID) +{ + uint8_t* readData = new uint8_t[size*4]; + uint8_t* writeData = new uint8_t[size*4]; + int ret = 0; + + for (unsigned i = 0; i < size; i++) + { + writeData[4*i] = (data_in[i]>>24)&0xff; + writeData[4*i+1] = (data_in[i]>>16)&0xff; + writeData[4*i+2] = 0; + writeData[4*i+3] = 0; + } + + SetChipSelect(0); + if (TransferSPI(fd_control_lms, writeData, readData, size*4) != size*4) + { + lime::error("Read LMS7: SPI transfer error"); + ret = -1; + } + + for (unsigned i = 0; i < size; i++) + data_out[i] = readData[4*i+3] | (readData[4*i+2]<<8); + + delete [] readData; + delete [] writeData; + return ret; +} + +int ConnectionSPI::WriteRegisters(const uint32_t *addrs, const uint32_t *vals, const size_t size) +{ + uint32_t* readData = new uint32_t[size]; + uint8_t* writeData = new uint8_t[size*4]; + int ret = 0; + for (unsigned i = 0; i < size; i++) + { + writeData[4*i] = ((addrs[i]>>8)&0xff)|0x80; + writeData[4*i+1] = addrs[i]&0xff; + writeData[4*i+2] = (vals[i]>>8)&0xff; + writeData[4*i+3] = vals[i]&0xff; + } + + if (TransferSPI(fd_control_fpga, writeData, readData, size*4) != size*4) + { + lime::error("Write FPGA: SPI transfer error"); + ret = -1; + } + + delete [] readData; + delete [] writeData; + return ret; +} + +int ConnectionSPI::ReadRegisters(const uint32_t *addrs, uint32_t *vals, const size_t size) +{ + uint8_t* readData = new uint8_t[size*4]; + uint8_t* writeData = new uint8_t[size*4]; + int ret = 0; + for (unsigned i = 0; i < size; i++) + { + writeData[4*i] = (addrs[i]>>8)&0xff; + writeData[4*i+1] = addrs[i]&0xff; + writeData[4*i+2] = 0; + writeData[4*i+3] = 0; + } + if (TransferSPI(fd_control_fpga, writeData, readData, size*4) != size*4) + { + lime::error("Read FPGA: SPI transfer error"); + ret = -1; + } + + for (unsigned i = 0; i < size; i++) + vals[i] = readData[4*i+3] | (readData[4*i+2]<<8); + + delete [] readData; + delete [] writeData; + return ret; +} + +int ConnectionSPI::CustomParameterRead(const uint8_t *ids, double *values, const size_t count, std::string* units) +{ + for (unsigned i = 0; i < count; i++) + values[i] = ids[i] == 0 ? dac_value : 0; + + return 0; +} + +int ConnectionSPI::CustomParameterWrite(const uint8_t *ids, const double *vals, const size_t count, const std::string& units) +{ + int ret = 0; + + for (unsigned i = 0; i < count; i++) + if (ids[i] == 0) + { + //disable ADF + uint8_t writeData[12] = {0x1F, 0x81, 0xF3, 0x1F, 0x81, 0xF2, 0, 1, 0xF4, 1, 0x80, 1}; + uint8_t readData[3]; + for (unsigned i = 0; i < sizeof(writeData); i+=3) + { + SetChipSelect(2); + if (TransferSPI(fd_control_lms, writeData+i, readData, 3)!=3) + { + lime::error("Write ADF: SPI transfer error"); + ret = -1; + } + SetChipSelect(0); + } + + if (TransferSPI(fd_control_lms, writeData, readData, 12)!=12) + lime::error("Write ADF: SPI transfer error"); + + uint8_t rx[3]; + dac_value = vals[i]; + uint8_t tx[3] = {0, (dac_value>>8), (dac_value&0xFF)}; + SetChipSelect(1); + lime::info("DAC write: %d", dac_value); + if (TransferSPI(fd_control_lms, &tx, &rx, 3) != 3) + { + lime::error("Write DAC: SPI transfer error"); + ret = -1; + } + } + + return ret; +} + +DeviceInfo ConnectionSPI::GetDeviceInfo(void) +{ + DeviceInfo info; + info.deviceName = "LimeNET-Micro"; + info.protocolVersion = "0"; + info.firmwareVersion = "0"; + info.expansionName = "EXP_BOARD_UNKNOWN"; + + const uint32_t addrs[] = {0, 1, 2, 3}; + uint32_t vals[4] = {0}; + + ReadRegisters(addrs, vals, 4); + info.gatewareTargetBoard = GetDeviceName(eLMS_DEV(vals[0])); + info.gatewareVersion = std::to_string(vals[1]); + info.gatewareRevision = std::to_string(vals[2]); + info.hardwareVersion = std::to_string(vals[3]&0xF) + " BOM " + std::to_string(vals[3]>>4); + return info; +} + +int ConnectionSPI::DeviceReset(int ind) +{ + const uint32_t addrs[2] = {0x13, 0x13}; + uint32_t vals[2] = {}; + ReadRegisters(addrs, vals, 1); + vals[0] = vals[0] & (~0x02); + vals[1] = vals[0] | 0x02; + WriteRegisters(addrs, vals, 2); + return 0; +} + +int ConnectionSPI::ResetStreamBuffers() +{ + if (fd_stream_clocks < 0) //lime spi + { + if (fd_stream != -1) + close(fd_stream); + if((fd_stream = open("/dev/lime_spi", O_RDWR)) < 0) + { + lime::error("Failed to open /dev/lime_spi"); + return -1; + } + return 0; + } + + { + std::lock_guard lock(mTxStreamLock); + txQueue = std::queue(); + } + { + std::lock_guard lock(mRxStreamLock); + rxQueue = std::queue(); + } + program_mode.store(false); + last_flags = 0x10; //no sync + rx_timestamp = 0; + return 0; +} + +int ConnectionSPI::GetBuffersCount() const +{ + return 1; +} + +int ConnectionSPI::CheckStreamSize(int size) const +{ + return 1; +} + +/** + @brief Reads data from board + @param buffer array where to store received data + @param length number of bytes to read + @param timeout read timeout in milliseconds + @return number of bytes received +*/ +int ConnectionSPI::ReceiveData(char *buffer, int length, int epIndex, int timeout_ms) +{ + const int count = length/sizeof(FPGA_DataPacket); + int offset = 0; + for (int i = 0; i < count; i++) + { + if (WaitForReading(0, timeout_ms)== false) + return i * sizeof(FPGA_DataPacket); + FinishDataReading(buffer+offset, sizeof(FPGA_DataPacket), 0); + offset += sizeof(FPGA_DataPacket); + } + return count * sizeof(FPGA_DataPacket); +} + +void ConnectionSPI::AbortReading(int epIndex) +{ + return; +} + +/** + @brief sends data to board + @param *buffer buffer to send + @param length number of bytes to send + @param timeout data write timeout in milliseconds + @return number of bytes sent +*/ +int ConnectionSPI::SendData(const char *buffer, int length, int epIndex, int timeout_ms) +{ + const int count = length/sizeof(FPGA_DataPacket); + int offset = 0; + for (int i = 0; i < count; i++) + { + BeginDataSending(buffer+offset, length, 0); + if (WaitForSending(0, timeout_ms) == false) + return i * sizeof(FPGA_DataPacket); + offset += sizeof(FPGA_DataPacket); + } + return count * sizeof(FPGA_DataPacket); +} + +void ConnectionSPI::AbortSending(int epIndex) +{ + return; +} + +int ConnectionSPI::BeginDataReading(char* buffer, uint32_t length, int ep) +{ + return 0; +} + +bool ConnectionSPI::WaitForReading(int contextHandle, unsigned int timeout_ms) +{ + if (fd_stream_clocks < 0) //lime spi + return true; + auto t1 = chrono::high_resolution_clock::now(); + do + { + { + std::lock_guard lock(mRxStreamLock); + if (!rxQueue.empty()) + return true; + } + std::this_thread::sleep_for(std::chrono::microseconds(250)); + } + while (std::chrono::duration_cast(chrono::high_resolution_clock::now() - t1).count() < timeout_ms); + return false; +} + +int ConnectionSPI::FinishDataReading(char* buffer, uint32_t length, int contextHandle) +{ + if (fd_stream_clocks < 0) //lime spi + { + auto t1 = chrono::high_resolution_clock::now(); + do + { + int cnt = read(fd_stream, buffer, sizeof(FPGA_DataPacket)); + if (cnt >= 0) + return cnt; + std::this_thread::sleep_for(std::chrono::microseconds(300)); + }while (std::chrono::duration_cast(chrono::high_resolution_clock::now() - t1).count() < 3000); + return 0; + } + + FPGA_DataPacket* packet = reinterpret_cast(buffer); + std::lock_guard lock(mRxStreamLock); + if (!rxQueue.empty()) + { + *packet = rxQueue.front(); + rxQueue.pop(); + return sizeof(FPGA_DataPacket);; + } + return 0; +} + +int ConnectionSPI::BeginDataSending(const char* buffer, uint32_t length, int ep) +{ + if (fd_stream_clocks < 0) //lime spi + { + auto t1 = chrono::high_resolution_clock::now(); + do + { + int cnt = write(fd_stream, buffer, sizeof(FPGA_DataPacket)); + if (cnt >= 0) + return cnt; + std::this_thread::sleep_for(std::chrono::microseconds(300)); + }while (std::chrono::duration_cast(chrono::high_resolution_clock::now() - t1).count() < 3000); + return 0; + } + const FPGA_DataPacket* packet = reinterpret_cast(buffer); + std::lock_guard lock(mTxStreamLock); + if (txQueue.size() < 10) + { + txQueue.push(*packet); + return sizeof(FPGA_DataPacket); + } + return 0; +} + + +bool ConnectionSPI::WaitForSending(int contextHandle, uint32_t timeout_ms) +{ + if (fd_stream_clocks < 0) //lime spi + return true; + auto t1 = chrono::high_resolution_clock::now(); + do + { + { + std::lock_guard lock(mTxStreamLock); + if (txQueue.size() < 10) + return true; + } + std::this_thread::sleep_for(std::chrono::microseconds(250)); + } + while (std::chrono::duration_cast(chrono::high_resolution_clock::now() - t1).count() < timeout_ms); + return false; +} + +int ConnectionSPI::FinishDataSending(const char* buffer, uint32_t length, int contextHandle) +{ + return contextHandle; +} + +void ConnectionSPI::StreamISR() +{ + if (program_mode.load()) + { + program_ready.store(true); + return; + } + static const FPGA_DataPacket dummy_packet = {0}; + FPGA_DataPacket rx_packet; + FPGA_DataPacket tx_packet; + while (1) + { + pthis->mTxStreamLock.lock(); + if (pthis->txQueue.empty() || (!(tx_packet.reserved[0]&0x10) && pthis->txQueue.front().counter > rx_timestamp+12000)) + { + pthis->mTxStreamLock.unlock(); + tx_packet = dummy_packet; + tx_packet.reserved[0] = last_flags; + } + else + { + tx_packet = pthis->txQueue.front(); + last_flags = tx_packet.reserved[0]; + pthis->txQueue.pop(); + pthis->mTxStreamLock.unlock(); + if (!(tx_packet.reserved[0]&0x10) && tx_packet.counter < rx_timestamp+6000) + continue; + } + break; + } + + { + spi_ioc_transfer tr = { (unsigned long)&tx_packet, + (unsigned long)&rx_packet, + sizeof(tx_packet), + SPI_STREAM_SPEED_HZ, + 0, + 8 }; + ioctl(pthis->fd_stream, SPI_IOC_MESSAGE(1), &tr); + } + + rx_timestamp = rx_packet.counter; + + pthis->mRxStreamLock.lock(); + + if (pthis->rxQueue.size() >= 10) + pthis->rxQueue.pop(); + pthis->rxQueue.push(rx_packet); + pthis->mRxStreamLock.unlock(); + + { + spi_ioc_transfer tr = { (unsigned long)&dummy_packet, + (unsigned long)&rx_packet, + 2, + SPI_STREAM_SPEED_HZ, + 0, + 8 }; + ioctl(pthis->fd_stream_clocks, SPI_IOC_MESSAGE(1), &tr); + } +} + +int ConnectionSPI::ProgramWrite(const char *data, size_t length, int prog_mode, int device, ProgrammingCallback cb) +{ + if (device != 2) + { + lime::error("Unsupported programming target"); + return -1; + } + if (prog_mode != 1 && prog_mode != 2) + { + lime::error("Programming mode not supported"); + return -1; + } + + uint32_t addr = 0x7F; + uint32_t val = 0x00; + WriteRegisters(&addr, &val, 1); + val = 0x01; + WriteRegisters(&addr, &val, 1); + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (prog_mode != 2) + { + if (fd_stream_clocks < 0) + { + ioctl(fd_stream, IOCTL_PROGSTART, 0); + } + else + { + program_mode.store(true); + program_ready.store(false); + } + } + + val = 0x00; + WriteRegisters(&addr, &val, 1); + val = 0x01; + WriteRegisters(&addr, &val, 1); + + if (prog_mode == 2) + return 0; + + std::this_thread::sleep_for(std::chrono::seconds(1)); + + static unsigned char rx_buffer[4096]; + const int sizeUFM = 0x8000; + const int sizeCFM0 = 0x42000; + const int startUFM = 0x1000; + const int startCFM0 = 0x4B000; + + if (length != startCFM0 + sizeCFM0) + { + lime::error("Invalid image file"); + return -1; + } + std::vector buffer(sizeUFM + sizeCFM0); + memcpy(buffer.data(), data + startUFM, sizeUFM); + memcpy(buffer.data() + sizeUFM, data + startCFM0, sizeCFM0); + + unsigned data_sent = 0; + int ret = 0; + while (data_sent < buffer.size()) + { + int cnt = 0; + auto t1 = chrono::high_resolution_clock::now(); + + while (std::chrono::duration_cast(chrono::high_resolution_clock::now() - t1).count() < 3000) + { + if (fd_stream_clocks < 0) //lime_spi + { + cnt = write(fd_stream, &buffer[data_sent], sizeof(FPGA_DataPacket)); + std::this_thread::sleep_for(std::chrono::milliseconds(85)); + if (cnt > 0) + break; + cnt = 0; + + } + else if (program_ready.load()) + { + cnt = buffer.size() - data_sent; + if (cnt > 4096) + cnt = 4096; + { + spi_ioc_transfer tr = { (unsigned long)(&buffer[data_sent]), + (unsigned long)&rx_buffer, + cnt, + SPI_STREAM_SPEED_HZ, + 0, + 8 }; + ioctl(pthis->fd_stream, SPI_IOC_MESSAGE(1), &tr); + } + program_ready.store(false); + { + spi_ioc_transfer tr = { (unsigned long)&rx_buffer, + (unsigned long)&rx_buffer, + 2, + SPI_STREAM_SPEED_HZ, + 0, + 8 }; + ioctl(pthis->fd_stream_clocks, SPI_IOC_MESSAGE(1), &tr); + } + break; + } + } + if (cnt <= 0) + { + lime::error("timeout"); + ret = -1; + break; + } + data_sent +=cnt; + if(cb && cb(data_sent, buffer.size(), "")) + { + lime::info("aborted"); + ret = -1; + break; + } + } + + if (fd_stream_clocks < 0) //lime_spi + ioctl(fd_stream, IOCTL_PROGSTOP, 0); + else + program_mode.store(false); + return ret; +} + + +int ConnectionSPI::ProgramUpdate(const bool download, const bool force, IConnection::ProgrammingCallback callback) +{ + const int updateGW = 1; + const int updateGWr = 3; + const std::string image = "LimeNET-Micro_lms7_trx_HW_2.1_SPI_r1.3.rpd"; + + const uint32_t addrs[] = {1, 2}; + uint32_t vals[2] = {0}; + + ReadRegisters(addrs, vals, 2); + + int gwVersion = vals[0]; + int gwRevision = vals[1]; + + //download images when missing + if (download && lime::locateImageResource(image).empty()) + { + const std::string msg("Downloading: " + image); + if (callback) + callback(0, 1, msg.c_str()); + int ret = lime::downloadImageResource(image); + if (ret != 0) + return ret; //error set by download call + if (callback) + callback(1, 1, "Done!"); + } + + if (!force && gwVersion == updateGW && gwRevision == updateGWr) + { + lime::info("Existing gateware is same as update (%d.%d)", updateGW, updateGWr); + } + else //load gateware into flash + { + if (callback) + callback(0, 1, image.c_str()); + //open file + std::ifstream file; + const auto path = lime::locateImageResource(image); + file.open(path.c_str(), std::ios::in | std::ios::binary); + if (not file.good()) return lime::ReportError("Error opening %s", path.c_str()); + //read file + std::streampos fileSize; + file.seekg(0, std::ios::end); + fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + std::vector progData(fileSize, 0); + file.read(progData.data(), fileSize); + + int device = 2; //FPGA + int progMode = 1; //FLASH + auto status = this->ProgramWrite(progData.data(), progData.size(), progMode, device, callback); + if (status != 0) + return status; + if (callback) + callback(1, 1, "Done!"); + } + + return 0; +} + + + diff --git a/src/ConnectionSPI/ConnectionSPI.h b/src/ConnectionSPI/ConnectionSPI.h new file mode 100644 index 000000000..d10e23675 --- /dev/null +++ b/src/ConnectionSPI/ConnectionSPI.h @@ -0,0 +1,97 @@ +/** + @file ConnectionSPI.h + @author Lime Microsystems +*/ + +#pragma once + +#include +#include +#include + +#include "ConnectionRegistry.h" +#include "LMS64CProtocol.h" +#include "dataTypes.h" + +namespace lime{ + +class ConnectionSPI : public IConnection +{ +public: + ConnectionSPI(const unsigned index); + ~ConnectionSPI(void); + + int Open(const unsigned index); + void Close(); + bool IsOpen(); + int GetOpenedIndex(); + enum + { + SPIDEV = 1, + LIMESPI = 2 + }; + + int WriteLMS7002MSPI(const uint32_t *writeData, size_t size, unsigned periphID = 0) override; + int ReadLMS7002MSPI(const uint32_t *writeData, uint32_t *readData, size_t size, unsigned periphID = 0) override; + int WriteRegisters(const uint32_t *addrs, const uint32_t *data, const size_t size) override; + int ReadRegisters(const uint32_t *addrs, uint32_t *data, const size_t size) override; + int CustomParameterRead(const uint8_t *ids, double *values, const size_t count, std::string* units) override; + int CustomParameterWrite(const uint8_t *ids, const double *values, const size_t count, const std::string& units) override; + DeviceInfo GetDeviceInfo(void) override; + int DeviceReset(int ind) override; + int ResetStreamBuffers() override; + int ProgramWrite(const char *data, size_t length, int progMode, int ind, ProgrammingCallback cb) override; + int TransactSPI(const int addr, const uint32_t *writeData, uint32_t *readData, const size_t size) override; + int ProgramUpdate(const bool download, const bool force, IConnection::ProgrammingCallback callback) override; +protected: + int GetBuffersCount() const override; + int CheckStreamSize(int size) const override; + + int ReceiveData(char* buffer, int length, int epIndex, int timeout = 100) override; + int SendData(const char* buffer, int length, int epIndex, int timeout = 100) override; + + int BeginDataReading(char* buffer, uint32_t length, int ep) override; + bool WaitForReading(int contextHandle, unsigned int timeout_ms) override; + int FinishDataReading(char* buffer, uint32_t length, int contextHandle) override; + void AbortReading(int epIndex); + + int BeginDataSending(const char* buffer, uint32_t length, int ep) override; + bool WaitForSending(int contextHandle, uint32_t timeout_ms) override; + int FinishDataSending(const char* buffer, uint32_t length, int contextHandle) override; + void AbortSending(int epIndex); + +private: + void SetChipSelect(int cs); + int WriteADF4002SPI(const uint32_t *writeData, const size_t size); + static int TransferSPI(int fd, const void *tx, void *rx, uint32_t len); + static ConnectionSPI* pthis; + static char last_flags; + static uint64_t rx_timestamp; + static void StreamISR(); + static std::atomic program_ready; + static std::atomic program_mode; + int fd_stream; + int fd_stream_clocks; + int fd_control_lms; + int fd_control_fpga; + int dac_value; + int int_pin; + std::mutex mTxStreamLock; + std::mutex mRxStreamLock; + std::queue rxQueue; + std::queue txQueue; +}; + +class ConnectionSPIEntry : public ConnectionRegistryEntry +{ +public: + ConnectionSPIEntry(void); + + ~ConnectionSPIEntry(void); + + std::vector enumerate(const ConnectionHandle &hint); + + IConnection *make(const ConnectionHandle &handle); +}; + +} diff --git a/src/ConnectionSPI/ConnectionSPIEntry.cpp b/src/ConnectionSPI/ConnectionSPIEntry.cpp new file mode 100644 index 000000000..80b696d57 --- /dev/null +++ b/src/ConnectionSPI/ConnectionSPIEntry.cpp @@ -0,0 +1,60 @@ +/** + @file ConnectionSPI.cpp + @author Lime Microsystems + @brief Implementation of SPI board connection. +*/ +#ifdef __unix__ +#include +#endif +#include "ConnectionSPI.h" +using namespace lime; +#include + + +void __loadConnectionSPIEntry(void) +{ + static ConnectionSPIEntry SPIEntry; +} + + +ConnectionSPIEntry::ConnectionSPIEntry(void): + ConnectionRegistryEntry("SPI") +{ +} + +ConnectionSPIEntry::~ConnectionSPIEntry(void) +{ +} + +std::vector ConnectionSPIEntry::enumerate(const ConnectionHandle &hint) +{ + std::vector handles; + ConnectionHandle handle; + handle.media = "SPI"; + + if ((access("/dev/spidev1.0", F_OK ) != -1) + && (access("/dev/spidev1.1", F_OK ) != -1) + && (access("/dev/spidev1.2", F_OK ) != -1)) + { + if (access("/dev/lime_spi", F_OK ) != -1) + { + handle.name = "Rasp PI 3 SPI (lime spi)"; + handle.index = ConnectionSPI::LIMESPI; + handles.push_back(handle); + } + else if ((access("/dev/spidev0.0", F_OK ) != -1) + && (access("/dev/spidev0.1", F_OK ) != -1)) + { + handle.name = "Rasp PI 3 SPI (spidev)"; + handle.index = ConnectionSPI::SPIDEV; + handles.push_back(handle); + } + + } + return handles; +} + +IConnection *ConnectionSPIEntry::make(const ConnectionHandle &handle) +{ + return new ConnectionSPI(handle.index); +} diff --git a/src/ConnectionSPI/lime_spi.h b/src/ConnectionSPI/lime_spi.h new file mode 100644 index 000000000..08ea6dc82 --- /dev/null +++ b/src/ConnectionSPI/lime_spi.h @@ -0,0 +1,21 @@ +//Lime Microsystems Limited, +//LimeNET-micro spi stream driver module +//Copyright 2018 Norbertas Kremeris, LIME MICROSYSTEMS LTD. + + +#ifndef LIME_SPI_H +#define LIME_SPI_H + +#include + +#define MAGIC_NUM 117 +#define IOCTL_PROGSTOP _IO(MAGIC_NUM, 1) +#define IOCTL_PROGSTART _IO(MAGIC_NUM, 0) + + +//file operations on chardevice +#define DEVICE_NAME "lime_spi" +#define CLASS_NAME "lime" + +#endif + diff --git a/src/FPGA_common/FPGA_Mini.cpp b/src/FPGA_common/FPGA_Mini.cpp index b5c09cc62..9cca7da95 100644 --- a/src/FPGA_common/FPGA_Mini.cpp +++ b/src/FPGA_common/FPGA_Mini.cpp @@ -56,7 +56,6 @@ int FPGA_Mini::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, double txPha */ int FPGA_Mini::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) { - int status = 0; uint32_t reg20; const double rxPhC1 = 89.46; const double rxPhC2 = 1.24e-6; @@ -78,7 +77,6 @@ int FPGA_Mini::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) std::vector dataWr; dataWr.resize(spiAddr.size()); dataRd.resize(spiAddr.size()); - lime::FPGA::FPGA_PLL_clock clocks[4]; //backup registers dataWr[0] = (uint32_t(0x0020) << 16); @@ -91,16 +89,20 @@ int FPGA_Mini::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) dataWr[i] = (spiAddr[i] << 16); connection->ReadLMS7002MSPI(dataWr.data(),dataRd.data(), bakRegCnt, 0); - //Config Rx - { + { //Config Rx const std::vector spiData = { 0x0E9F, 0x07FF, 0x5550, 0xE4E4, 0xE4E4, 0x0086, 0x028D, 0x00FF, 0x5555, 0x02CD, 0xAAAA, 0x02ED }; - //Load test config const int setRegCnt = spiData.size(); for (int i = 0; i < setRegCnt; ++i) dataWr[i] = (1 << 31) | (uint32_t(spiAddr[i]) << 16) | spiData[i]; //msbit 1=SPI write connection->WriteLMS7002MSPI(dataWr.data(), setRegCnt, 0); + } + bool phaseSearchSuccess = false; + lime::FPGA::FPGA_PLL_clock clocks[4]; + + for (int i = 0; i < 10; i++) //attempt phase search 10 times + { clocks[0].index = 3; clocks[0].outFrequency = rxRate_Hz; clocks[0].phaseShift_deg = rxPhC1 + rxPhC2 * rxRate_Hz; @@ -108,38 +110,46 @@ int FPGA_Mini::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) clocks[1] = clocks[0]; clocks[2] = clocks[0]; clocks[3] = clocks[0]; - if (SetPllFrequency(0, rxRate_Hz, clocks, 4)!=0) + if (SetPllFrequency(0, rxRate_Hz, clocks, 4)==0) { - status = -1; - SetInterfaceFreq(txRate_Hz, rxRate_Hz, txPhC1 + txPhC2 * txRate_Hz, rxPhC1 + rxPhC2 * rxRate_Hz, 0); + phaseSearchSuccess = true; + break; } } - //Config TX - if (status == 0) + if (phaseSearchSuccess) { + //Config TX + phaseSearchSuccess = false; const std::vector spiData = { 0x0E9F, 0x07FF, 0x5550, 0xE4E4, 0xE4E4, 0x0484 }; WriteRegister(0x000A, 0x0000); - //Load test config const int setRegCnt = spiData.size(); for (int i = 0; i < setRegCnt; ++i) dataWr[i] = (1 << 31) | (uint32_t(spiAddr[i]) << 16) | spiData[i]; //msbit 1=SPI write connection->WriteLMS7002MSPI(dataWr.data(), setRegCnt, 0); - clocks[0].index = 1; - clocks[0].outFrequency = txRate_Hz; - clocks[0].phaseShift_deg = txPhC1 + txPhC2 * txRate_Hz; - clocks[0].findPhase = true; - clocks[1] = clocks[0]; - clocks[2] = clocks[0]; - clocks[3] = clocks[0]; - WriteRegister(0x000A, 0x0200); - if (SetPllFrequency(0, txRate_Hz, clocks, 4)!=0) + for (int i = 0; i < 10; i++) //attempt phase search 10 times { - status = -1; - SetInterfaceFreq(txRate_Hz, rxRate_Hz, txPhC1 + txPhC2 * txRate_Hz, rxPhC1 + rxPhC2 * rxRate_Hz, 0); + clocks[0].index = 1; + clocks[0].outFrequency = txRate_Hz; + clocks[0].phaseShift_deg = txPhC1 + txPhC2 * txRate_Hz; + clocks[0].findPhase = true; + clocks[1] = clocks[0]; + clocks[2] = clocks[0]; + clocks[3] = clocks[0]; + WriteRegister(0x000A, 0x0200); + if (SetPllFrequency(0, txRate_Hz, clocks, 4)==0) + { + phaseSearchSuccess = true; + break; + } } + if (!phaseSearchSuccess) + lime::error("LML TX phase search FAIL"); } + else + lime::error("LML RX phase search FAIL"); + //Restore registers for (int i = 0; i < bakRegCnt; ++i) @@ -149,7 +159,13 @@ int FPGA_Mini::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) connection->WriteLMS7002MSPI(dataWr.data(), 1, channel); WriteRegister(0x000A, 0); - return status; + if (!phaseSearchSuccess) + { + SetInterfaceFreq(txRate_Hz, rxRate_Hz, txPhC1 + txPhC2 * txRate_Hz, rxPhC1 + rxPhC2 * rxRate_Hz, 0); + return -1; + } + + return 0; } int FPGA_Mini::UploadWFM(const void* const* samples, uint8_t chCount, size_t sample_count, StreamConfig::StreamDataFormat format, int epIndex) diff --git a/src/FPGA_common/FPGA_common.cpp b/src/FPGA_common/FPGA_common.cpp index aee563350..ff5c9c974 100644 --- a/src/FPGA_common/FPGA_common.cpp +++ b/src/FPGA_common/FPGA_common.cpp @@ -474,7 +474,7 @@ int FPGA::SetPllFrequency(const uint8_t pllIndex, const double inputFreq, FPGA_P if (!done && t2 - t1 > timeout) lime::error("SetPllFrequency: timeout, busy bit is still 1"); if (error) - lime::error("SetPllFrequency: error configuring phase"); + lime::warning("SetPllFrequency: error configuring phase"); addrs.push_back(0x0023); values.push_back(reg23val & ~PHCFG_START); if (WriteRegisters(addrs.data(), values.data(), values.size()) != 0) lime::error("SetPllFrequency: configure FPGA PLL, failed to write registers"); @@ -799,15 +799,27 @@ int FPGA::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) connection->WriteLMS7002MSPI(dataWr.data(), setRegCnt, channel); } + bool phaseSearchSuccess = false; lime::FPGA::FPGA_PLL_clock clocks[2]; - clocks[0].index = 1; - clocks[0].outFrequency = bypassRx ? 2*rxRate_Hz : rxRate_Hz; - clocks[0].phaseShift_deg = rxPhC1 + rxPhC2 * rxRate_Hz; - clocks[0].findPhase = true; - clocks[1] = clocks[0]; - if (SetPllFrequency(pll_ind+1, rxRate_Hz, clocks, 2)!=0) + + for (int i = 0; i < 10; i++) //attempt phase search 10 times { - status = -1; + clocks[0].index = 1; + clocks[0].outFrequency = bypassRx ? 2*rxRate_Hz : rxRate_Hz; + clocks[0].phaseShift_deg = rxPhC1 + rxPhC2 * rxRate_Hz; + clocks[0].findPhase = true; + clocks[1] = clocks[0]; + if (SetPllFrequency(pll_ind+1, rxRate_Hz, clocks, 2)==0) + { + phaseSearchSuccess = true; + break; + } + } + + if (!phaseSearchSuccess) + { + lime::error("LML RX phase search FAIL"); + status = -1; clocks[0].index = 0; clocks[0].phaseShift_deg = 0; clocks[0].findPhase = false; @@ -828,14 +840,25 @@ int FPGA::SetInterfaceFreq(double txRate_Hz, double rxRate_Hz, int channel) connection->WriteLMS7002MSPI(dataWr.data(), setRegCnt, channel); } - clocks[0].index = 1; - clocks[0].outFrequency = bypassTx ? 2*txRate_Hz:txRate_Hz; - clocks[0].phaseShift_deg = txPhC1 + txPhC2 * txRate_Hz; - clocks[0].findPhase = true; - clocks[1] = clocks[0]; - WriteRegister(0x000A, 0x0200); - if (SetPllFrequency(pll_ind, txRate_Hz, clocks, 2)!=0) + phaseSearchSuccess = false; + for (int i = 0; i < 10; i++) //attempt phase search 10 times + { + clocks[0].index = 1; + clocks[0].outFrequency = bypassTx ? 2*txRate_Hz:txRate_Hz; + clocks[0].phaseShift_deg = txPhC1 + txPhC2 * txRate_Hz; + clocks[0].findPhase = true; + clocks[1] = clocks[0]; + WriteRegister(0x000A, 0x0200); + if (SetPllFrequency(pll_ind, txRate_Hz, clocks, 2)==0) + { + phaseSearchSuccess = true; + break; + } + } + + if (!phaseSearchSuccess) { + lime::error("LML TX phase search FAIL"); status = -1; clocks[0].index = 0; clocks[0].phaseShift_deg = 0; diff --git a/src/FPGAcontrols_wxgui/FPGAcontrols_wxgui.cpp b/src/FPGAcontrols_wxgui/FPGAcontrols_wxgui.cpp index 47488851b..6a012d1c3 100644 --- a/src/FPGAcontrols_wxgui/FPGAcontrols_wxgui.cpp +++ b/src/FPGAcontrols_wxgui/FPGAcontrols_wxgui.cpp @@ -131,7 +131,7 @@ FPGAcontrols_wxgui::FPGAcontrols_wxgui(wxWindow* parent,wxWindowID id,const wxSt void FPGAcontrols_wxgui::Initialize(lms_device_t* dataPort) { lmsControl = dataPort; - + if (LMS_GetNumChannels(lmsControl,LMS_CH_TX) > 2) cmbDevice->Show(); else @@ -212,14 +212,14 @@ void FPGAcontrols_wxgui::OnbtnOpenFileClick(wxCommandEvent& event) } void FPGAcontrols_wxgui::OnbtnPlayWFMClick(wxCommandEvent& event) -{ +{ LMS_EnableTxWFM(lmsControl, cmbDevice->GetSelection()*2, true); } void FPGAcontrols_wxgui::OnbtnStopWFMClick(wxCommandEvent& event) { LMS_EnableTxWFM(lmsControl, cmbDevice->GetSelection()*2, false); -}; +} int FPGAcontrols_wxgui::UploadFile(const wxString &filename) { @@ -375,13 +375,13 @@ void FPGAcontrols_wxgui::OnChkDigitalLoopbackEnableClick(wxCommandEvent& event) const uint16_t address = 0x0008; unsigned short regValue = 0; - if (LMS_WriteFPGAReg(lmsControl, 0xFFFF, 1<< cmbDevice->GetSelection())!=0 + if (LMS_WriteFPGAReg(lmsControl, 0xFFFF, 1<< cmbDevice->GetSelection())!=0 || LMS_ReadFPGAReg(lmsControl, address, ®Value)!=0) { wxMessageBox(_("Failed to write SPI"), _("Error"), wxICON_ERROR); return; } - + regValue = (regValue & ~(1<<10)) | chkDigitalLoopbackEnable->IsChecked() << 10; if (LMS_WriteFPGAReg(lmsControl, address, regValue)!=0) wxMessageBox(_("Failed to write SPI"), _("Error"), wxICON_ERROR); diff --git a/src/Si5351C/Si5351C.cpp b/src/Si5351C/Si5351C.cpp index 3192ca74f..e88923ad3 100644 --- a/src/Si5351C/Si5351C.cpp +++ b/src/Si5351C/Si5351C.cpp @@ -302,12 +302,12 @@ Si5351C::Status Si5351C::UploadConfiguration() std::string outBuffer; //Disable outputs outBuffer.push_back(3); - outBuffer.push_back(0xFF); + outBuffer.push_back(uint8_t(0xFF)); //Power down all output drivers for(int i=0; i<8; ++i) { outBuffer.push_back(16 + i); - outBuffer.push_back(0x84); + outBuffer.push_back(uint8_t(0x84)); } //write new configuration for (int i = 15; i <= 92; ++i) @@ -321,8 +321,8 @@ Si5351C::Status Si5351C::UploadConfiguration() outBuffer.push_back(m_newConfiguration[i]); } //apply soft reset - outBuffer.push_back(177); - outBuffer.push_back(0xAC); + outBuffer.push_back(uint8_t(177)); + outBuffer.push_back(uint8_t(0xAC)); //Enabe desired outputs outBuffer.push_back(3); outBuffer.push_back(m_newConfiguration[3]); diff --git a/src/SystemResources.in.cpp b/src/SystemResources.in.cpp index 961930ba3..bb84349fc 100644 --- a/src/SystemResources.in.cpp +++ b/src/SystemResources.in.cpp @@ -165,7 +165,7 @@ int lime::downloadImageResource(const std::string &name) { const std::string destDir(lime::getAppDataDirectory() + "/images/@VERSION_MAJOR@.@VERSION_MINOR@"); const std::string destFile(destDir + "/" + name); - const std::string sourceUrl("http://downloads.myriadrf.org/project/limesuite/@VERSION_MAJOR@.@VERSION_MINOR@/" + name); + const std::string sourceUrl("https://downloads.myriadrf.org/project/limesuite/@VERSION_MAJOR@.@VERSION_MINOR@/" + name); //check if the directory already exists struct stat s; diff --git a/src/boards_wxgui/lms7002m_novena_wxgui.h b/src/boards_wxgui/lms7002m_novena_wxgui.h index fbd05cb2f..ba19e695c 100644 --- a/src/boards_wxgui/lms7002m_novena_wxgui.h +++ b/src/boards_wxgui/lms7002m_novena_wxgui.h @@ -26,7 +26,7 @@ class LMS7002M_Novena_wxgui : public wxPanel void OnWriteAll(wxCommandEvent &event); lms_device_t* lmsControl; int m_rficSpiAddr; - DECLARE_EVENT_TABLE(); + DECLARE_EVENT_TABLE() }; #endif //LMS7002M_NOVENA_H diff --git a/src/boards_wxgui/pnlBuffers.h b/src/boards_wxgui/pnlBuffers.h index 605a66667..394f43b4b 100644 --- a/src/boards_wxgui/pnlBuffers.h +++ b/src/boards_wxgui/pnlBuffers.h @@ -25,7 +25,7 @@ class pnlBuffers : public wxPanel wxCheckBox* chkIQ_SEL2_DIR; wxCheckBox* chkG_PWR_DWN; lms_device_t *lmsControl; - DECLARE_EVENT_TABLE(); + DECLARE_EVENT_TABLE() }; #endif diff --git a/src/boards_wxgui/pnlLimeNetMicro.cpp b/src/boards_wxgui/pnlLimeNetMicro.cpp index d437fb8a8..dc400e033 100644 --- a/src/boards_wxgui/pnlLimeNetMicro.cpp +++ b/src/boards_wxgui/pnlLimeNetMicro.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "lms7suiteEvents.h" using namespace std; @@ -13,6 +14,11 @@ using namespace std; BEGIN_EVENT_TABLE(pnlLimeNetMicro, wxPanel) END_EVENT_TABLE() +static const std::vector rxSwVal = {0x0502, 0x0602, 0x0101, 0x0201, 0x0600, 0x0500}; +static const std::vector rxSwMask = {0x0702, 0x0702, 0x0701, 0x0701, 0x0702, 0x0702}; +static const std::vector txSwVal = {0x5000, 0x6000, 0x6001, 0x5001, 0x1000, 0x2000}; +static const std::vector txSwMask = {0x7001, 0x7001, 0x7001, 0x7001, 0x7002, 0x7002}; + pnlLimeNetMicro::pnlLimeNetMicro(wxWindow* parent,wxWindowID id, const wxPoint& pos,const wxSize& size, int style, wxString name) { lmsControl = nullptr; @@ -33,7 +39,7 @@ pnlLimeNetMicro::pnlLimeNetMicro(wxWindow* parent,wxWindowID id, const wxPoint& cmbRxPath->SetSelection(0); Connect(cmbRxPath->GetId(), wxEVT_CHOICE, wxCommandEventHandler(pnlLimeNetMicro::OnLoopbackChange), NULL, this); lbSizer->Add(cmbRxPath, 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP, 5); - + lbSizer->Add(new wxStaticText(this, wxID_ANY, _("TX RF port path:")), 1, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5); wxArrayString txChoices; txChoices.push_back(_("Band 1")); @@ -42,7 +48,7 @@ pnlLimeNetMicro::pnlLimeNetMicro(wxWindow* parent,wxWindowID id, const wxPoint& cmbTxPath->SetSelection(0); Connect(cmbTxPath->GetId(), wxEVT_CHOICE, wxCommandEventHandler(pnlLimeNetMicro::OnLoopbackChange), NULL, this); lbSizer->Add(cmbTxPath, 1, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP, 5); - + mainSizer->Add(lbSizer, 1, wxEXPAND | wxALL, 5); Bind(READ_ALL_VALUES, &pnlLimeNetMicro::OnReadAll, this, this->GetId()); Bind(WRITE_ALL_VALUES, &pnlLimeNetMicro::OnLoopbackChange, this, this->GetId()); @@ -51,6 +57,34 @@ pnlLimeNetMicro::pnlLimeNetMicro(wxWindow* parent,wxWindowID id, const wxPoint& void pnlLimeNetMicro::Initialize(lms_device_t* pControl) { lmsControl = pControl; + cmbRxPath->Clear(); + cmbRxPath->Append(wxString(_("LNAL RX"))); + cmbRxPath->Append(wxString(_("LNAH RX"))); + cmbTxPath->Clear(); + cmbTxPath->Append(wxString(_("Band 1 TX"))); + cmbTxPath->Append(wxString(_("Band 2 TX"))); + uint16_t addr = 3; + uint16_t value = 0; + if (pControl) + { + uint16_t reg3 = 0; + if (LMS_ReadFPGAReg(lmsControl, 0x3, ®3) == LMS_SUCCESS) + { + int bom_ver = reg3>>4; + int hw_ver = reg3 & 0xF; + if (hw_ver == 3 && bom_ver != 1) + { + cmbRxPath->Append(wxString(_("LNAL Duplexer A"))); + cmbRxPath->Append(wxString(_("LNAH Duplexer A"))); + cmbRxPath->Append(wxString(_("LNAL Duplexer B"))); + cmbRxPath->Append(wxString(_("LNAH Duplexer B"))); + cmbTxPath->Append(wxString(_("Band 1 Duplexer A"))); + cmbTxPath->Append(wxString(_("Band 2 Duplexer A"))); + cmbTxPath->Append(wxString(_("Band 1 Duplexer B"))); + cmbTxPath->Append(wxString(_("Band 2 Duplexer B"))); + } + } + } mainSizer->Fit(this); mainSizer->SetSizeHints(this); Layout(); @@ -66,8 +100,51 @@ void pnlLimeNetMicro::OnLoopbackChange(wxCommandEvent& event) { uint16_t addr = 0x0017; uint16_t value = 0; - value |= cmbRxPath->GetSelection() == 1 ? 1<<9 : 1<<8; - value |= cmbTxPath->GetSelection() == 1 ? 1<<13 : 1<<12; + + uint16_t reg3 = 0; + LMS_ReadFPGAReg(lmsControl, 0x3, ®3); + int bom_ver = reg3>>4; + int hw_ver = reg3 & 0xF; + + if (hw_ver == 3 && bom_ver != 1) + { + if (event.GetEventObject() == cmbRxPath) + { + value = txSwVal[cmbTxPath->GetSelection()]; + value &= ~rxSwMask[cmbRxPath->GetSelection()]; + value |= rxSwVal[cmbRxPath->GetSelection()]; + if ((value & txSwMask[cmbTxPath->GetSelection()]) != txSwVal[cmbTxPath->GetSelection()]) + { + for (unsigned index = 0; index < txSwVal.size(); index++) + if (txSwVal[index] == (value&txSwMask[index])) + { + cmbTxPath->SetSelection(index); + break; + } + } + } + else + { + value = rxSwVal[cmbRxPath->GetSelection()]; + value &= ~txSwMask[cmbTxPath->GetSelection()]; + value |= txSwVal[cmbTxPath->GetSelection()]; + if ((value & rxSwMask[cmbRxPath->GetSelection()]) != rxSwVal[cmbRxPath->GetSelection()]) + { + for (unsigned index = 0; index < rxSwVal.size(); index++) + if (rxSwVal[index] == (value&rxSwMask[index])) + { + cmbRxPath->SetSelection(index); + break; + } + } + } + + } + else + { + value |= cmbRxPath->GetSelection() == 1 ? 1<<9 : 1<<8; + value |= cmbTxPath->GetSelection() == 1 ? 1<<13 : 1<<12; + } if(LMS_WriteFPGAReg(lmsControl,addr, value)) wxMessageBox(_("Failed to write FPGA registers"), _("Error"), wxICON_ERROR | wxOK); } @@ -81,8 +158,31 @@ void pnlLimeNetMicro::UpdatePanel() wxMessageBox(_("Failed to read FPGA registers"), _("Error"), wxICON_ERROR | wxOK); return; } - cmbRxPath->SetSelection((value >> 9) & 0x1); - cmbTxPath->SetSelection((value >> 13) & 0x1); + uint16_t reg3 = 0; + LMS_ReadFPGAReg(lmsControl, 0x3, ®3); + int bom_ver = reg3>>4; + int hw_ver = reg3 & 0xF; + + if (hw_ver == 3 && bom_ver != 1) + { + for (unsigned index = 0; index < txSwVal.size(); index++) + if (txSwVal[index] == (value&txSwMask[index])) + { + cmbTxPath->SetSelection(index); + break; + } + for (unsigned index = 0; index < rxSwVal.size(); index++) + if (rxSwVal[index] == (value&rxSwMask[index])) + { + cmbRxPath->SetSelection(index); + break; + } + } + else + { + cmbRxPath->SetSelection((value >> 9) & 0x1); + cmbTxPath->SetSelection((value >> 13) & 0x1); + } } void pnlLimeNetMicro::OnReadAll(wxCommandEvent &event) diff --git a/src/boards_wxgui/pnlQSpark.cpp b/src/boards_wxgui/pnlQSpark.cpp index 340aad764..4524067b9 100644 --- a/src/boards_wxgui/pnlQSpark.cpp +++ b/src/boards_wxgui/pnlQSpark.cpp @@ -310,7 +310,7 @@ pnlQSpark::pnlQSpark(wxWindow* parent,wxWindowID id, const wxString &title, cons controlsPtr2Registers[spinRX_GCORRQ] = Register(0x00A1, 10, 0, 2047); controlsPtr2Registers[spinRX_GCORRI] = Register(0x00A2, 10, 0, 2047); controlsPtr2Registers[spinRX_PHCORR] = Register(0x00A3, 11, 0, 0); - + controlsPtr2Registers[chkLB_1A] = Register(0x0017, 1, 0, 2); controlsPtr2Registers[chkLB_1B] = Register(0x0017, 5, 4, 2); controlsPtr2Registers[chkLB_2A] = Register(0x0017, 9, 8, 2); @@ -326,7 +326,7 @@ pnlQSpark::pnlQSpark(wxWindow* parent,wxWindowID id, const wxString &title, cons controlsPtr2Registers[cmbInsel] = Register(0x0080, 2, 2, 0); - + Bind(READ_ALL_VALUES, &pnlQSpark::OnReadAll, this, this->GetId()); Bind(WRITE_ALL_VALUES, &pnlQSpark::OnWriteAll, this, this->GetId()); } @@ -340,7 +340,7 @@ void pnlQSpark::Initialize(lms_device_t* pControl) txtPllFreqRxMHz->SetValue(wxString::Format("%1.3f", freqHz/1e6)); LMS_GetSampleRate(lmsControl, LMS_CH_TX, 4, &freqHz,nullptr); txtPllFreqTxMHz->SetValue(wxString::Format("%1.3f", freqHz/1e6)); - + } void pnlQSpark::RegisterParameterChangeHandler(wxCommandEvent& event) @@ -352,11 +352,11 @@ void pnlQSpark::RegisterParameterChangeHandler(wxCommandEvent& event) int mac = (reg.address!=0x17) && (rbChannelB->GetValue()) ? 0x2 : 0x1; if (LMS_WriteFPGAReg(lmsControl, 0xFFFF, mac)!=0) { - wxMessageBox(_("Write FPGA register failed"), _("Error"), wxICON_ERROR | wxOK); + wxMessageBox(_("Write FPGA register failed"), _("Error"), wxICON_ERROR | wxOK); return; } - unsigned short mask = (~(~0 << (reg.msb - reg.lsb + 1))) << reg.lsb; // creates bit mask + unsigned short mask = (~(~0u << (reg.msb - reg.lsb + 1))) << reg.lsb; // creates bit mask uint16_t regValue; LMS_ReadFPGAReg(lmsControl,reg.address,®Value); @@ -384,20 +384,20 @@ void pnlQSpark::OnbtnUpdateAll(wxCommandEvent& event) wxClassInfo* choicectr = wxClassInfo::FindClass("wxChoice"); if (LMS_WriteFPGAReg(lmsControl, 0xFFFF, rbChannelB->GetValue() ? 0x2 : 0x1)!= 0) { - wxMessageBox(_("Write FPGA register failed"), _("Error"), wxICON_ERROR | wxOK); - return; + wxMessageBox(_("Write FPGA register failed"), _("Error"), wxICON_ERROR | wxOK); + return; } for (iter = controlsPtr2Registers.begin(); iter != controlsPtr2Registers.end(); ++iter) { Register reg = iter->second; - unsigned short mask = (~(~0 << (reg.msb - reg.lsb + 1))) << reg.lsb; // creates bit mask + unsigned short mask = (~(~0u << (reg.msb - reg.lsb + 1))) << reg.lsb; // creates bit mask uint16_t value; LMS_ReadFPGAReg(lmsControl,reg.address,&value); value = value & mask; value = value >> reg.lsb; - + if (iter->first == chkLB_1A || iter->first == chkLB_1B || iter->first == chkLB_2A || iter->first == chkLB_2B) value = value == 2 ? 1 : 0; if (iter->first->IsKindOf(spinctr)) diff --git a/src/fftviewer_wxgui/fftviewer_frFFTviewer.cpp b/src/fftviewer_wxgui/fftviewer_frFFTviewer.cpp index 46398bd43..018a621bd 100644 --- a/src/fftviewer_wxgui/fftviewer_frFFTviewer.cpp +++ b/src/fftviewer_wxgui/fftviewer_frFFTviewer.cpp @@ -372,7 +372,7 @@ void fftviewer_frFFTviewer::StreamingLoop(fftviewer_frFFTviewer* pthis, const un } buffers = new lime::complex16_t*[channelsCount]; for (int i = 0; i < channelsCount; ++i) - buffers[i] = new complex16_t[fftSize+16]; + buffers[i] = new complex16_t[fftSize]; vector captureBuffer[cMaxChCount]; uint32_t samplesToCapture[cMaxChCount]; @@ -425,7 +425,7 @@ void fftviewer_frFFTviewer::StreamingLoop(fftviewer_frFFTviewer* pthis, const un pthis->mStreamRunning.store(true); lms_stream_meta_t meta; meta.waitForTimestamp = syncTx; - meta.flushPartialPacket = true; + meta.flushPartialPacket = false; int fftCounter = 0; while (pthis->stopProcessing.load() == false) @@ -436,7 +436,7 @@ void fftviewer_frFFTviewer::StreamingLoop(fftviewer_frFFTviewer* pthis, const un uint64_t ts[cMaxChCount]; for(int i=0; irxStreams[i], &buffers[i][0], fftSize+16, &meta, 1000); + samplesPopped[i] = LMS_RecvStream(&pthis->rxStreams[i], &buffers[i][0], fftSize, &meta, 1000); ts[i] = meta.timestamp + fifoSize/4; } diff --git a/src/lime/LimeSuite.h b/src/lime/LimeSuite.h index ffb23709d..6013b7a96 100644 --- a/src/lime/LimeSuite.h +++ b/src/lime/LimeSuite.h @@ -177,7 +177,8 @@ API_EXPORT int CALL_CONV LMS_Init(lms_device_t *device); API_EXPORT int CALL_CONV LMS_GetNumChannels(lms_device_t *device, bool dir_tx); /** - * Enable or disable specified RX channel. + * Enable or disable specified RX or TX channel. Some API functions will fail + * when performed on disabled channel. * * @param[in] device Device handle previously obtained by LMS_Open(). * @param dir_tx Select RX or TX @@ -237,7 +238,7 @@ API_EXPORT int CALL_CONV LMS_GetSampleRateRange(lms_device_t *device, bool dir_t * * @note channels A and B in LMS7 chip share the same clock so ability to set * different frequencies for channels A and B is very limited. This function - * will attempt to achieve diffrent requested frequencies using NCO when + * will attempt to achieve different requested frequencies using NCO when * possible, however often changing frequency for one (A or B) channel will * result in frequency being changed for both (A and B) channels. * @@ -745,7 +746,7 @@ API_EXPORT int CALL_CONV LMS_SetGFIR(lms_device_t * device, bool dir_tx, /** - * Enables or disable caching of calibration values. + * Enables or disable caching of LMS7 and FPGA register values. * * @deprecated calibration cache has been removed from LimeSuite. Use * LMS_EnableCache() to enable caching of register values @@ -923,7 +924,7 @@ API_EXPORT int CALL_CONV LMS_WriteCustomBoardParam(lms_device_t *device, * * Set to positive value to enable usage of external reference clock of the * specified frequency. Set to 0 or negative value to disable usage of external - * reference clock + * reference clock (if switching reference clock source is supported by HW) */ #define LMS_CLOCK_EXTREF 0x0006 @@ -944,9 +945,6 @@ API_EXPORT int CALL_CONV LMS_GetClockFreq(lms_device_t *dev, size_t clk_id, /** * Set frequency of the specified clock * - * @note setting ::LMS_CLOCK_EXTREF changes clock source to external, use - * ::LMS_VCTCXOWrite() to change back to VCTCXO - * * @param dev Device handle previously obtained by LMS_Open(). * @param clk_id Clock identifier (\ref LMS_CLOCK_ID) * @param freq Clock frequency in Hz. Pass zero or negative value to only diff --git a/src/lms7002_wxgui/lms7002_pnlR3.cpp b/src/lms7002_wxgui/lms7002_pnlR3.cpp index 4b636eb2d..dc54ebdc9 100644 --- a/src/lms7002_wxgui/lms7002_pnlR3.cpp +++ b/src/lms7002_wxgui/lms7002_pnlR3.cpp @@ -479,7 +479,7 @@ void lms7002_pnlR3_view::ParameterChangeHandler(wxCommandEvent& event) MCU_WaitForStatus(100); LMS_ReadLMSReg(lmsControl, 0x040B, &rdVal); - uint16_t mask = (~0) << (parameter.msb-parameter.lsb+1); + uint16_t mask = (~0u) << (parameter.msb-parameter.lsb+1); mask = ~mask; mask <<= parameter.lsb; rdVal &= ~mask; diff --git a/src/lms7002_wxgui/pnlBoardControls.cpp b/src/lms7002_wxgui/pnlBoardControls.cpp index 89395993e..f2b4958dc 100644 --- a/src/lms7002_wxgui/pnlBoardControls.cpp +++ b/src/lms7002_wxgui/pnlBoardControls.cpp @@ -346,7 +346,7 @@ std::vector pnlBoardControls::getBoardParams(const st else paramList.push_back(ADC_DAC{ "VCTCXO DAC (runtime)", true, 0, 0, adcUnits2string(RAW), 0, 0, 255 }); if (boardID != GetDeviceName(LMS_DEV_LIMESDRMINI)) - paramList.push_back(ADC_DAC{"Board Temperature", false, 0, 1, adcUnits2string(TEMPERATURE)}); + paramList.push_back(ADC_DAC{"Board Temperature", false, 0, 1, adcUnits2string(TEMPERATURE), 0, 0, 65535}); } return paramList; } diff --git a/src/lms7002m/LMS7002M.cpp b/src/lms7002m/LMS7002M.cpp index e0b111510..dd25121ef 100644 --- a/src/lms7002m/LMS7002M.cpp +++ b/src/lms7002m/LMS7002M.cpp @@ -718,7 +718,17 @@ int LMS7002M::SaveConfig(const char* filename) this->SetActiveChannel(ChA); for (uint16_t i = 0; i < addrToRead.size(); ++i) { + if (addrToRead[i] >= 0x5C3 && addrToRead[i] <= 0x5CA) + SPI_write(addrToRead[i], 0x4000); //perform read-back from DAC dataReceived[i] = Get_SPI_Reg_bits(addrToRead[i], 15, 0, false); + + //registers 0x5C3 - 0x53A return inverted value field when DAC value read-back is performed + if (addrToRead[i] >= 0x5C3 && addrToRead[i] <= 0x5C6 && (dataReceived[i]&0x400)) //sign bit 10 + dataReceived[i] = 0x400 | (~dataReceived[i]&0x3FF); //magnitude bits 9:0 + else if (addrToRead[i] >= 0x5C7 && addrToRead[i] <= 0x5CA && (dataReceived[i]&0x40)) //sign bit 6 + dataReceived[i] = 0x40 | (~dataReceived[i]&0x3F); //magnitude bits 5:0 + else if (addrToRead[i] == 0x5C2) + dataReceived[i] &= 0xFF00; //do not save calibration start triggers sprintf(addr, "0x%04X", addrToRead[i]); sprintf(value, "0x%04X", dataReceived[i]); fout << addr << "=" << value << endl; @@ -1400,7 +1410,7 @@ uint16_t LMS7002M::Get_SPI_Reg_bits(const LMS7Parameter ¶m, bool fromChip) */ uint16_t LMS7002M::Get_SPI_Reg_bits(uint16_t address, uint8_t msb, uint8_t lsb, bool fromChip) { - return (SPI_read(address, fromChip) & (~(~0<<(msb+1)))) >> lsb; //shift bits to LSB + return (SPI_read(address, fromChip) & (~(~0u<<(msb+1)))) >> lsb; //shift bits to LSB } /** @brief Change given parameter value @@ -1421,7 +1431,7 @@ int LMS7002M::Modify_SPI_Reg_bits(const LMS7Parameter ¶m, const uint16_t val int LMS7002M::Modify_SPI_Reg_bits(const uint16_t address, const uint8_t msb, const uint8_t lsb, const uint16_t value, bool fromChip) { uint16_t spiDataReg = SPI_read(address, fromChip); //read current SPI reg data - uint16_t spiMask = (~(~0 << (msb - lsb + 1))) << (lsb); // creates bit mask + uint16_t spiMask = (~(~0u << (msb - lsb + 1))) << (lsb); // creates bit mask spiDataReg = (spiDataReg & (~spiMask)) | ((value << lsb) & spiMask);//clear bits return SPI_write(address, spiDataReg); //write modified data back to SPI reg } @@ -2707,8 +2717,8 @@ float_type LMS7002M::GetTemperature() float Vptat = reg606 & 0xFF; Vptat *= 1.84; float Vdiff = Vptat-Vtemp; - Vdiff /= 3.9; - float temperature = 50.7+Vdiff; + Vdiff /= 1.05; + float temperature = 45.0+Vdiff; Modify_SPI_Reg_bits(LMS7_MUX_BIAS_OUT, biasMux); lime::debug("Vtemp 0x%04X, Vptat 0x%04X, Vdiff = %.2f, temp= %.3f", (reg606 >> 8) & 0xFF, reg606 & 0xFF, Vdiff, temperature); return temperature; diff --git a/src/lms7002m/mcu_dc_iq_calibration.cpp b/src/lms7002m/mcu_dc_iq_calibration.cpp index 62e80de87..e637da79a 100644 --- a/src/lms7002m/mcu_dc_iq_calibration.cpp +++ b/src/lms7002m/mcu_dc_iq_calibration.cpp @@ -148,7 +148,7 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0xFF,0xE5,0x36,0x24,0x1F,0xC3,0x9F,0xD3,0x94,0x00,0x40,0x76,0x12,0x36,0x5C,0xFF, 0xC3,0x74,0x1E,0x95,0x36,0x2F,0xF5,0x3B,0xFC,0x12,0x03,0x67,0xAB,0x35,0xAA,0x34, 0xA9,0x33,0xA8,0x32,0x12,0x00,0x4D,0x12,0x03,0x9B,0x7B,0x3D,0x7A,0x00,0xE4,0xFD, -0xFC,0x12,0x38,0x2C,0xEF,0x25,0xE0,0xFF,0xEE,0x33,0xFE,0x74,0xA9,0x2F,0xF5,0x82, +0xFC,0x12,0x38,0x2C,0xEF,0x25,0xE0,0xFF,0xEE,0x33,0xFE,0x74,0xB1,0x2F,0xF5,0x82, 0x74,0x3E,0x3E,0xF5,0x83,0xE4,0x93,0xF5,0x3C,0x74,0x01,0x93,0xF5,0x3D,0x54,0x0F, 0xF9,0xF5,0x3E,0xE5,0x3C,0xC4,0xF8,0x54,0xF0,0xC8,0xE5,0x3D,0xC4,0x54,0x0F,0x48, 0x54,0x1F,0xFF,0xF5,0x3F,0x12,0x36,0x5C,0xB5,0x3F,0x07,0x12,0x36,0x63,0x65,0x3E, @@ -359,24 +359,24 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0x12,0x39,0x26,0x22,0xAD,0x69,0xAF,0x68,0xAE,0x67,0x12,0x33,0x2C,0x22,0x7F,0x20, 0x7E,0x00,0x12,0x39,0x00,0x8E,0x2B,0x8F,0x2C,0xE5,0x2C,0x54,0x03,0x64,0x01,0x70, 0x06,0xFB,0xFA,0x7D,0x44,0x80,0x05,0xE4,0xFB,0xFA,0x7D,0x33,0x7F,0x82,0xFE,0x12, -0x33,0x2C,0x7E,0x3D,0x7F,0xB1,0x12,0x31,0x01,0x12,0x00,0x03,0x12,0x32,0x22,0xA9, +0x33,0x2C,0x7E,0x3D,0x7F,0xB9,0x12,0x31,0x01,0x12,0x00,0x03,0x12,0x32,0x22,0xA9, 0x07,0xE9,0x60,0x01,0x22,0x7B,0x01,0x12,0x23,0x7C,0x12,0x33,0x2C,0x12,0x37,0xAA, 0xD2,0x04,0x12,0x28,0x09,0xC0,0x04,0xC0,0x05,0xC0,0x06,0xC0,0x07,0x12,0x23,0x51, 0x12,0x23,0xC1,0xD0,0x07,0xD0,0x06,0xD0,0x05,0xD0,0x04,0x12,0x00,0x49,0x7B,0x00, 0x7A,0x24,0x79,0x74,0x78,0xC9,0x12,0x00,0x4D,0x8F,0x30,0x8E,0x2F,0x8D,0x2E,0x8C, 0x2D,0xC2,0x04,0x12,0x23,0xEC,0x12,0x13,0x29,0xA9,0x07,0xE9,0x60,0x06,0x12,0x17, -0x93,0xAF,0x01,0x22,0x12,0x36,0xE8,0x12,0x23,0x7A,0x12,0x33,0x2C,0x7A,0x00,0x12, -0x24,0x09,0x12,0x33,0x2C,0x12,0x39,0xAD,0x40,0x06,0x12,0x17,0x93,0x7F,0x04,0x22, -0xAD,0x2C,0xAC,0x2B,0x7F,0x20,0x7E,0x00,0x12,0x3A,0x28,0x12,0x38,0xD8,0xD2,0x04, -0x12,0x23,0x51,0x12,0x23,0x6E,0x12,0x34,0xE3,0x12,0x24,0x14,0x12,0x37,0xE4,0x8F, -0x2D,0x30,0x01,0x54,0xE4,0xFB,0xFA,0x7D,0x77,0x7F,0x0C,0x7E,0x01,0x12,0x33,0x2C, -0xE5,0x2D,0x64,0x01,0x60,0x06,0xE5,0x2D,0x64,0x02,0x70,0x39,0xE5,0x12,0x54,0x03, -0xF5,0x2E,0xFB,0x7A,0x00,0x12,0x17,0x9F,0xE5,0x2E,0x24,0xFF,0xFF,0xE4,0x34,0xFF, -0xFE,0xEF,0xF4,0xFB,0xEE,0xF4,0xFA,0x7D,0x21,0x7F,0x0D,0x7E,0x01,0x12,0x33,0x2C, -0xE5,0x2D,0x14,0x7F,0x00,0x70,0x02,0x7F,0x01,0xE5,0x12,0x13,0x13,0x54,0x3F,0x6F, -0x60,0x2E,0x7F,0x07,0x22,0x7F,0x07,0x22,0xE5,0x2D,0x64,0x01,0x60,0x09,0xE5,0x2D, -0x64,0x02,0x60,0x03,0x7F,0x07,0x22,0xE5,0x2D,0x24,0x01,0xFB,0xE4,0x33,0xFA,0x12, -0x17,0x9F,0x7D,0x65,0x7F,0x0C,0x12,0x17,0x86,0x7D,0x43,0x7F,0x0D,0x12,0x17,0x86, +0x93,0xAF,0x01,0x22,0x12,0x23,0x7A,0x12,0x33,0x2C,0x7A,0x00,0x12,0x24,0x09,0x12, +0x33,0x2C,0x12,0x39,0xAD,0x40,0x06,0x12,0x17,0x93,0x7F,0x04,0x22,0xAD,0x2C,0xAC, +0x2B,0x7F,0x20,0x7E,0x00,0x12,0x3A,0x28,0x12,0x38,0xD8,0xD2,0x04,0x12,0x23,0x51, +0x12,0x23,0x6E,0x12,0x34,0xE3,0x12,0x24,0x14,0x12,0x37,0xE4,0x8F,0x2D,0x30,0x01, +0x54,0xE4,0xFB,0xFA,0x7D,0x77,0x7F,0x0C,0x7E,0x01,0x12,0x33,0x2C,0xE5,0x2D,0x64, +0x01,0x60,0x06,0xE5,0x2D,0x64,0x02,0x70,0x39,0xE5,0x12,0x54,0x03,0xF5,0x2E,0xFB, +0x7A,0x00,0x12,0x17,0x9F,0xE5,0x2E,0x24,0xFF,0xFF,0xE4,0x34,0xFF,0xFE,0xEF,0xF4, +0xFB,0xEE,0xF4,0xFA,0x7D,0x21,0x7F,0x0D,0x7E,0x01,0x12,0x33,0x2C,0xE5,0x2D,0x14, +0x7F,0x00,0x70,0x02,0x7F,0x01,0xE5,0x12,0x13,0x13,0x54,0x3F,0x6F,0x60,0x2E,0x7F, +0x07,0x22,0x7F,0x07,0x22,0xE5,0x2D,0x64,0x01,0x60,0x09,0xE5,0x2D,0x64,0x02,0x60, +0x03,0x7F,0x07,0x22,0xE5,0x2D,0x24,0x01,0xFB,0xE4,0x33,0xFA,0x12,0x17,0x9F,0x7D, +0x65,0x7F,0x0C,0x12,0x17,0x86,0x7D,0x43,0x7F,0x0D,0x12,0x17,0x86,0x12,0x36,0xE8, 0x12,0x37,0x6D,0x7F,0x00,0x22,0xE5,0x2D,0x64,0x03,0xFB,0x7A,0x00,0x7E,0x01,0x12, 0x33,0x2C,0x22,0xAD,0x2C,0xAC,0x2B,0x7F,0x20,0x7E,0x00,0x12,0x3A,0x28,0x22,0x7D, 0x87,0x7F,0x0D,0x7E,0x01,0x12,0x33,0x2C,0x22,0x7F,0x20,0x7E,0x00,0x12,0x39,0x00, @@ -423,7 +423,7 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0x74,0x01,0x93,0xFF,0x74,0x02,0x93,0xFD,0x22,0x74,0x04,0x93,0xFF,0xAD,0x3E,0xED, 0x33,0x95,0xE0,0xFC,0x22,0xAB,0x38,0xAA,0x37,0xA9,0x36,0xA8,0x35,0x02,0x01,0x3E, 0x7D,0x10,0x7F,0x13,0x7E,0x01,0x22,0x7D,0x85,0x7F,0x14,0x7E,0x01,0x22,0x7F,0x20, -0x7E,0x00,0x12,0x39,0x00,0x8E,0x4A,0x8F,0x4B,0x7E,0x3E,0x7F,0x8B,0x12,0x31,0x01, +0x7E,0x00,0x12,0x39,0x00,0x8E,0x4A,0x8F,0x4B,0x7E,0x3E,0x7F,0x93,0x12,0x31,0x01, 0xE5,0x4B,0x54,0x03,0x64,0x01,0x70,0x06,0xFB,0xFA,0x7D,0x22,0x80,0x05,0xE4,0xFB, 0xFA,0x7D,0x11,0x7F,0x82,0xFE,0x12,0x33,0x2C,0x30,0x03,0x27,0xE5,0x12,0x13,0x13, 0x54,0x01,0xFF,0xC3,0x74,0x02,0x9F,0xF5,0x4C,0xFB,0x12,0x24,0x12,0x12,0x33,0x2C, @@ -517,8 +517,8 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0xE0,0x0B,0x12,0x04,0x36,0x8F,0x4E,0x8E,0x4D,0x8D,0x4C,0x8C,0x4B,0xAF,0x4E,0xAE, 0x4D,0xAD,0x4C,0xAC,0x4B,0x22,0xE4,0xF5,0x49,0xF5,0x4A,0x7F,0x20,0xFE,0x12,0x39, 0x00,0x8E,0x4D,0x8F,0x4E,0x20,0x03,0x0A,0x90,0x03,0xE8,0xE5,0x4D,0xF0,0xA3,0xE5, -0x4E,0xF0,0x79,0x24,0xE9,0x60,0x52,0x25,0xE0,0x24,0x21,0xF5,0x82,0xE4,0x34,0x3F, -0xF5,0x83,0xE4,0x93,0xF5,0x4B,0x74,0x01,0x93,0xF5,0x4C,0xE9,0x25,0xE0,0x24,0x23, +0x4E,0xF0,0x79,0x24,0xE9,0x60,0x52,0x25,0xE0,0x24,0x29,0xF5,0x82,0xE4,0x34,0x3F, +0xF5,0x83,0xE4,0x93,0xF5,0x4B,0x74,0x01,0x93,0xF5,0x4C,0xE9,0x25,0xE0,0x24,0x2B, 0xF5,0x82,0xE4,0x34,0x3F,0xF5,0x83,0xC3,0x74,0x01,0x93,0x95,0x4C,0xE4,0x93,0x95, 0x4B,0x40,0x22,0x30,0x03,0x05,0x12,0x21,0x1A,0x80,0x08,0x12,0x20,0xFB,0xEC,0xF0, 0xA3,0xED,0xF0,0x05,0x4A,0xE5,0x4A,0x70,0x02,0x05,0x49,0x05,0x4C,0xE5,0x4C,0x70, @@ -574,7 +574,7 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0x28,0x84,0x75,0xF0,0x18,0xA4,0xFF,0xE9,0x24,0x00,0xFD,0xE4,0x34,0x05,0xCD,0x2F, 0xFF,0xED,0x35,0xF0,0xFE,0x22,0x7B,0x01,0x7A,0x00,0x7D,0xFF,0x7F,0xC0,0x7E,0x05, 0x22,0xA8,0x04,0xA9,0x05,0xAA,0x06,0xAB,0x07,0x22,0x7D,0x22,0x7B,0x01,0x7A,0x00, -0x7F,0x0C,0x7E,0x04,0x22,0xD3,0x90,0x3E,0x9D,0x74,0x01,0x93,0x95,0x4E,0xE4,0x93, +0x7F,0x0C,0x7E,0x04,0x22,0xD3,0x90,0x3E,0xA5,0x74,0x01,0x93,0x95,0x4E,0xE4,0x93, 0x95,0x4D,0x22,0x7B,0x40,0x7A,0x54,0x79,0x09,0x12,0x00,0x4D,0x8F,0x53,0x8E,0x52, 0x8D,0x51,0x8C,0x50,0x22,0xC3,0xE5,0x68,0x95,0x6A,0xE5,0x67,0x95,0x69,0x22,0xC3, 0xE5,0x43,0x95,0x45,0xE5,0x42,0x95,0x44,0x22,0x7B,0x01,0x7D,0x66,0x7F,0x1C,0x7E, @@ -837,7 +837,7 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0x12,0x04,0x94,0x22,0x7F,0x20,0x7E,0x00,0x12,0x39,0x00,0x8E,0x40,0x8F,0x41,0xE4, 0xF5,0x42,0x79,0x02,0xE4,0xF5,0x43,0xE5,0x41,0x54,0xFC,0xFF,0xE5,0x40,0xFC,0xEF, 0x45,0x43,0xFD,0x7F,0x20,0x7E,0x00,0x12,0x3A,0x28,0xE5,0x43,0xC3,0x94,0x05,0x50, -0x2D,0xE5,0x43,0x25,0xE0,0x24,0x9F,0x30,0x01,0x10,0x12,0x36,0x7A,0x12,0x36,0x89, +0x2D,0xE5,0x43,0x25,0xE0,0x24,0xA7,0x30,0x01,0x10,0x12,0x36,0x7A,0x12,0x36,0x89, 0xE0,0xFC,0xA3,0xE0,0xFD,0x12,0x3A,0x28,0x80,0x0E,0x12,0x36,0x7A,0x12,0x39,0x00, 0x12,0x36,0x89,0xEE,0xF0,0xA3,0xEF,0xF0,0x05,0x42,0x05,0x43,0x80,0xCC,0x19,0xE9, 0x70,0xB2,0xAD,0x41,0xAC,0x40,0x7F,0x20,0x7E,0x00,0x02,0x3A,0x28,0x12,0x30,0x6A, @@ -892,8 +892,8 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0x07,0xAC,0x06,0xED,0x54,0x03,0x64,0x01,0x70,0x08,0x43,0x05,0x14,0x53,0x82,0xEB, 0x80,0x06,0x43,0x05,0x28,0x53,0x82,0xF5,0x7F,0x20,0x7E,0x00,0x12,0x3A,0x28,0xAD, 0x82,0xAC,0x83,0x7F,0x82,0x7E,0x00,0x02,0x3A,0x28,0x79,0x07,0xE9,0x25,0xE0,0x24, -0x6B,0xF5,0x82,0xE4,0x34,0x3F,0xF5,0x83,0xE4,0x93,0xFE,0x74,0x01,0x93,0xFF,0xE9, -0x25,0xE0,0x24,0x79,0xF5,0x82,0xE4,0x34,0x3F,0xF5,0x83,0xE4,0x93,0xFC,0x74,0x01, +0x73,0xF5,0x82,0xE4,0x34,0x3F,0xF5,0x83,0xE4,0x93,0xFE,0x74,0x01,0x93,0xFF,0xE9, +0x25,0xE0,0x24,0x81,0xF5,0x82,0xE4,0x34,0x3F,0xF5,0x83,0xE4,0x93,0xFC,0x74,0x01, 0x93,0xFD,0x12,0x3A,0x28,0xD9,0xD5,0x7B,0xFF,0x7A,0xB9,0x7D,0xF8,0x7F,0x20,0x7E, 0x01,0x02,0x33,0x2C,0xA9,0x05,0x12,0x39,0x00,0xAC,0x06,0xAD,0x07,0xE9,0xC4,0x54, 0x0F,0x04,0xFF,0x74,0xFF,0xFE,0xA8,0x07,0x08,0x80,0x05,0xC3,0x33,0xCE,0x33,0xCE, @@ -979,46 +979,46 @@ const uint8_t mcu_program_lms7_dc_iq_calibration_bin[16384] = { 0x29,0xFF,0x9A,0xFE,0xFE,0xFE,0x67,0xFD,0xE5,0xFD,0x8C,0xFD,0x6E,0xFD,0x9A,0xFE, 0x1A,0xFE,0xF3,0x00,0x22,0x01,0x9D,0x03,0x54,0x05,0x30,0x07,0x16,0x08,0xE8,0x0A, 0x89,0x0B,0xDE,0x0C,0xCD,0x0D,0x49,0x03,0xFF,0x00,0x80,0x00,0x08,0x00,0x84,0x00, -0x85,0x00,0xAE,0x01,0x01,0x01,0x13,0x02,0x00,0x02,0x01,0x02,0x02,0x02,0x08,0x04, -0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0x00,0x1C,0x00,0x0C,0x07,0xFF,0x07,0xFF,0x00, -0x00,0xF8,0xFF,0x00,0x07,0xF0,0x00,0x18,0x01,0x00,0x3C,0x00,0x0C,0x07,0xFF,0x07, -0xFF,0xF1,0x0B,0x01,0x0C,0x01,0x12,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01, -0x19,0x01,0x1A,0x04,0x00,0x04,0x01,0x04,0x02,0x04,0x03,0x04,0x04,0x04,0x05,0x04, -0x06,0x04,0x07,0x04,0x08,0x04,0x09,0x04,0x0A,0x04,0x0C,0x04,0x40,0x04,0x42,0x04, -0x43,0x00,0x81,0x88,0xE5,0x40,0x32,0x00,0x05,0x81,0x80,0x28,0x0C,0x21,0x8C,0x31, -0x80,0x2E,0x02,0x00,0x81,0x07,0xFF,0x07,0xFF,0x40,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x20,0x98,0x00,0x20,0x00,0x00,0x00, -0x00,0xFF,0x3D,0x1D,0xFF,0x3D,0x2F,0xFF,0x3D,0x41,0x09,0xFF,0x3D,0x53,0xFF,0x3D, -0x83,0x18,0x17,0x00,0x84,0x00,0x85,0x00,0xAE,0x01,0x0C,0x01,0x0D,0x01,0x13,0x01, -0x15,0x01,0x19,0x04,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x00,0x40,0x00,0x0C,0x00, -0x00,0x00,0x00,0xF8,0xFF,0x00,0x07,0xF0,0x00,0x00,0x1A,0x00,0x40,0x00,0x3C,0xC0, -0x00,0x80,0x00,0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01, -0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0A,0x02,0x00,0x02,0x01,0x02,0x02,0x02, -0x08,0x02,0x40,0x04,0x00,0x04,0x01,0x04,0x02,0x04,0x03,0x04,0x07,0x04,0x0A,0x04, -0x0C,0x04,0x40,0x05,0xC0,0x05,0xCB,0x02,0x03,0x02,0x04,0x02,0x05,0x02,0x06,0x02, -0x07,0x02,0x41,0x04,0x04,0x04,0x05,0x04,0x06,0x04,0x08,0x04,0x09,0x04,0x41,0x05, -0xC1,0x05,0xC2,0x05,0xC3,0x05,0xC4,0x05,0xC5,0x05,0xC6,0x05,0xC7,0x05,0xC8,0x05, -0xC9,0x05,0xCA,0x05,0xCC,0x00,0x81,0x34,0x08,0x60,0x01,0x31,0x80,0x0A,0x12,0x00, -0x88,0x00,0x07,0x31,0x8C,0x31,0x8C,0x04,0x26,0x61,0xC1,0x10,0x4C,0x00,0x8D,0x07, -0xFF,0x07,0xFF,0x20,0x70,0x00,0x20,0x00,0x81,0x07,0xFF,0x07,0xFF,0x40,0x00,0x07, -0x00,0x10,0x00,0x20,0x98,0x00,0x20,0x00,0xFF,0x20,0x20,0xFF,0x3D,0xC3,0xFF,0x3D, -0xD3,0xFF,0x3D,0xE3,0x08,0xFF,0x3D,0xF3,0xFF,0x3E,0x57,0x32,0x1A,0x70,0x00,0x00, -0x81,0x01,0x0F,0x01,0x26,0x04,0x0A,0x04,0x0C,0x00,0x01,0x00,0x11,0x00,0x21,0x00, -0x02,0x00,0x12,0x00,0x22,0x00,0x32,0x00,0x13,0x00,0x23,0x00,0x33,0x00,0x43,0x00, -0x24,0x00,0x34,0x00,0x44,0x00,0x54,0x00,0x35,0x00,0x45,0x00,0x55,0x00,0x65,0x00, -0x46,0x00,0x56,0x00,0x66,0x00,0x76,0x00,0x57,0x00,0x67,0x00,0x77,0x00,0x87,0x00, -0x68,0x00,0x78,0x00,0x88,0x00,0x98,0x00,0x79,0x00,0x89,0x00,0x99,0x00,0xA9,0x00, -0xAA,0x00,0xBA,0x00,0xCA,0x00,0xDA,0x00,0xDB,0x00,0xEB,0x00,0xFB,0x01,0x0B,0x01, -0x1B,0x01,0x2B,0x01,0x3B,0x01,0x4B,0x01,0x5B,0x01,0x6B,0x01,0x7B,0x01,0x8B,0x01, -0x9B,0x01,0xAB,0x01,0xBB,0x01,0xCB,0x01,0xDB,0x01,0xEB,0x01,0xFB,0x01,0xFC,0x01, -0xFD,0x01,0xFE,0x01,0xFF,0x00,0x21,0x00,0x2F,0x00,0x81,0x00,0x82,0x00,0x84,0x00, -0x84,0x00,0x85,0x00,0x85,0x00,0x86,0x00,0x8C,0x00,0x92,0x00,0xA7,0x00,0xA8,0x00, -0xA8,0x00,0xAD,0x00,0xAE,0x01,0x00,0x01,0x04,0x01,0x05,0x01,0x0A,0x01,0x0C,0x01, -0x14,0x01,0x15,0x01,0x1A,0x02,0x00,0x02,0x0C,0x02,0x40,0x02,0x61,0x04,0x00,0x04, -0x0F,0x04,0x40,0x04,0x61,0x05,0x00,0x05,0xA7,0x05,0xC0,0x05,0xC0,0x01,0x1C,0x01, -0x1D,0x01,0x1E,0x01,0x1F,0x01,0x21,0x01,0x22,0x01,0x23,0xAD,0x43,0x04,0x00,0x07, -0x80,0x36,0x40,0x34,0x04,0x03,0x3F,0x06,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x85,0x00,0xAE,0x01,0x01,0x02,0x00,0x02,0x01,0x02,0x02,0x02,0x08,0x04,0x00,0x00, +0x01,0xF0,0x00,0x00,0x01,0x00,0x0C,0x07,0xFF,0x07,0xFF,0x00,0x00,0xF8,0xFF,0x00, +0x07,0xF0,0x00,0x18,0x01,0x00,0x0C,0x07,0xFF,0x07,0xFF,0xF1,0x0B,0x01,0x0C,0x01, +0x0D,0x01,0x0E,0x01,0x0F,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01, +0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1A,0x04,0x00,0x04,0x01,0x04, +0x02,0x04,0x03,0x04,0x07,0x04,0x0A,0x04,0x0C,0x04,0x40,0x04,0x41,0x04,0x42,0x04, +0x43,0x04,0x09,0x04,0x08,0x04,0x06,0x04,0x05,0x04,0x04,0x00,0x81,0x88,0xE5,0x00, +0x9E,0x20,0x40,0x30,0xC6,0x09,0x94,0x00,0x83,0x40,0x32,0x03,0xDF,0x00,0x8D,0x00, +0x05,0x81,0x80,0x28,0x0C,0x21,0x8C,0x31,0x80,0x2E,0x02,0x00,0x81,0x07,0xFF,0x07, +0xFF,0x40,0x00,0x07,0x00,0x10,0x01,0x20,0x98,0xFF,0x3D,0x1D,0xFF,0x3D,0x2D,0xFF, +0x3D,0x3D,0x08,0xFF,0x3D,0x4D,0xFF,0x3D,0x8D,0x20,0x16,0x00,0x84,0x00,0x85,0x00, +0xAE,0x01,0x0C,0x01,0x0D,0x01,0x13,0x01,0x15,0x01,0x19,0x04,0x00,0x00,0x01,0xF0, +0x00,0x00,0x00,0x00,0x40,0x00,0x0C,0x00,0x00,0x00,0x00,0xF8,0xFF,0x00,0x07,0xF0, +0x00,0x00,0x1A,0x00,0x40,0x00,0x3C,0xC0,0x00,0x80,0x00,0x01,0x00,0x01,0x01,0x01, +0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01, +0x0A,0x02,0x00,0x02,0x01,0x02,0x02,0x02,0x08,0x02,0x40,0x04,0x00,0x04,0x01,0x04, +0x02,0x04,0x03,0x04,0x07,0x04,0x0A,0x04,0x0C,0x04,0x40,0x05,0xC0,0x05,0xCB,0x02, +0x03,0x02,0x04,0x02,0x05,0x02,0x06,0x02,0x07,0x02,0x41,0x04,0x04,0x04,0x05,0x04, +0x06,0x04,0x08,0x04,0x09,0x04,0x41,0x05,0xC1,0x05,0xC2,0x05,0xC3,0x05,0xC4,0x05, +0xC5,0x05,0xC6,0x05,0xC7,0x05,0xC8,0x05,0xC9,0x05,0xCA,0x05,0xCC,0x00,0x81,0x34, +0x08,0x60,0x01,0x31,0x80,0x0A,0x12,0x00,0x88,0x00,0x07,0x31,0x8C,0x31,0x8C,0x04, +0x26,0x61,0xC1,0x10,0x4C,0x00,0x8D,0x07,0xFF,0x07,0xFF,0x20,0x70,0x00,0x20,0x00, +0x81,0x07,0xFF,0x07,0xFF,0x40,0x00,0x07,0x00,0x10,0x00,0x20,0x98,0x00,0x20,0x00, +0xFF,0x20,0x20,0xFF,0x3D,0xCB,0xFF,0x3D,0xDB,0xFF,0x3D,0xEB,0x08,0xFF,0x3D,0xFB, +0xFF,0x3E,0x5F,0x32,0x1A,0x70,0x00,0x00,0x81,0x01,0x0F,0x01,0x26,0x04,0x0A,0x04, +0x0C,0x00,0x01,0x00,0x11,0x00,0x21,0x00,0x02,0x00,0x12,0x00,0x22,0x00,0x32,0x00, +0x13,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x24,0x00,0x34,0x00,0x44,0x00,0x54,0x00, +0x35,0x00,0x45,0x00,0x55,0x00,0x65,0x00,0x46,0x00,0x56,0x00,0x66,0x00,0x76,0x00, +0x57,0x00,0x67,0x00,0x77,0x00,0x87,0x00,0x68,0x00,0x78,0x00,0x88,0x00,0x98,0x00, +0x79,0x00,0x89,0x00,0x99,0x00,0xA9,0x00,0xAA,0x00,0xBA,0x00,0xCA,0x00,0xDA,0x00, +0xDB,0x00,0xEB,0x00,0xFB,0x01,0x0B,0x01,0x1B,0x01,0x2B,0x01,0x3B,0x01,0x4B,0x01, +0x5B,0x01,0x6B,0x01,0x7B,0x01,0x8B,0x01,0x9B,0x01,0xAB,0x01,0xBB,0x01,0xCB,0x01, +0xDB,0x01,0xEB,0x01,0xFB,0x01,0xFC,0x01,0xFD,0x01,0xFE,0x01,0xFF,0x00,0x21,0x00, +0x2F,0x00,0x81,0x00,0x82,0x00,0x84,0x00,0x84,0x00,0x85,0x00,0x85,0x00,0x86,0x00, +0x8C,0x00,0x92,0x00,0xA7,0x00,0xA8,0x00,0xA8,0x00,0xAD,0x00,0xAE,0x01,0x00,0x01, +0x04,0x01,0x05,0x01,0x0A,0x01,0x0C,0x01,0x14,0x01,0x15,0x01,0x1A,0x02,0x00,0x02, +0x0C,0x02,0x40,0x02,0x61,0x04,0x00,0x04,0x0F,0x04,0x40,0x04,0x61,0x05,0x00,0x05, +0xA7,0x05,0xC0,0x05,0xC0,0x01,0x1C,0x01,0x1D,0x01,0x1E,0x01,0x1F,0x01,0x21,0x01, +0x22,0x01,0x23,0xAD,0x43,0x04,0x00,0x07,0x80,0x36,0x40,0x34,0x04,0x03,0x3F,0x06, +0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff --git a/src/lms7suiteApp.cpp b/src/lms7suiteApp.cpp index f328d2cb8..03ffba723 100644 --- a/src/lms7suiteApp.cpp +++ b/src/lms7suiteApp.cpp @@ -22,9 +22,9 @@ #include #include #ifndef NDEBUG -IMPLEMENT_APP_CONSOLE(lms7suiteApp); +IMPLEMENT_APP_CONSOLE(lms7suiteApp) #else -IMPLEMENT_APP(lms7suiteApp); +IMPLEMENT_APP(lms7suiteApp) #endif #include "resources/splash.h" @@ -41,7 +41,7 @@ bool lms7suiteApp::OnInit() wxYield(); //linux needs this to load splash image LMS7SuiteAppFrame* frame = new LMS7SuiteAppFrame(0L); #ifndef NDEBUG - wxLongLong t1 = wxGetUTCTimeMillis(); + wxLongLong t1 = wxGetUTCTimeMillis(); std::cout << "Create time " << (wxGetUTCTimeMillis() - t1).ToString() << " ms\n"; #endif splash->Destroy(); diff --git a/src/lms7suiteAppFrame.cpp b/src/lms7suiteAppFrame.cpp index 8f4dfb430..e08a86b8c 100644 --- a/src/lms7suiteAppFrame.cpp +++ b/src/lms7suiteAppFrame.cpp @@ -356,7 +356,7 @@ void LMS7SuiteAppFrame::OnShowFFTviewer(wxCommandEvent& event) void LMS7SuiteAppFrame::OnLmsChanged(wxCommandEvent& event) { - return; + m_lmsSelection = event.GetInt(); } void LMS7SuiteAppFrame::OnADF4002Close(wxCloseEvent& event) diff --git a/src/oglGraph/dlgMarkers.cpp b/src/oglGraph/dlgMarkers.cpp index 55a610e83..1adb92626 100644 --- a/src/oglGraph/dlgMarkers.cpp +++ b/src/oglGraph/dlgMarkers.cpp @@ -146,7 +146,7 @@ void dlgMarkers::OnMarkerChange(wxCommandEvent& event) int markerIndex = event.GetId() - 1000; if (event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED) event.GetString().ToDouble(&freq); - else + else freqs[markerIndex]->GetValue().ToDouble(&freq); freq *= 1000000; parent_graph->SetMarker(markerIndex, freq, enables[markerIndex]->IsChecked(), shows[markerIndex]->IsChecked()); diff --git a/src/protocols/ConnectionImages.cpp b/src/protocols/ConnectionImages.cpp index 286d1735f..656aed1a7 100644 --- a/src/protocols/ConnectionImages.cpp +++ b/src/protocols/ConnectionImages.cpp @@ -37,12 +37,13 @@ static const ConnectionImageEntry &lookupImageEntry(const LMS64CProtocol::LMSinf { static const std::vector imageEntries = { ConnectionImageEntry({LMS_DEV_UNKNOWN, -1, -1, nullptr, -1, -1, nullptr}), - ConnectionImageEntry({LMS_DEV_LIMESDR, 4, 4, "LimeSDR-USB_HW_1.4_r4.0.img", 2, 20, "LimeSDR-USB_HW_1.4_r2.20.rbf"}), + ConnectionImageEntry({LMS_DEV_LIMESDR, 4, 4, "LimeSDR-USB_HW_1.4_r4.0.img", 2, 21, "LimeSDR-USB_HW_1.4_r2.21.rbf"}), ConnectionImageEntry({LMS_DEV_LIMESDR, 3, 3, "LimeSDR-USB_HW_1.3_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}), ConnectionImageEntry({LMS_DEV_LIMESDR, 2, 3, "LimeSDR-USB_HW_1.2_r3.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}), ConnectionImageEntry({LMS_DEV_LIMESDR, 1, 7, "LimeSDR-USB_HW_1.1_r7.0.img", 1, 20, "LimeSDR-USB_HW_1.1_r1.20.rbf"}), ConnectionImageEntry({LMS_DEV_STREAM, 3, 8, "STREAM-USB_HW_1.1_r8.0.img", 1, 2, "STREAM-USB_HW_1.3_r1.2.rbf"}), - ConnectionImageEntry({LMS_DEV_LIMESDRMINI, 0, 0, nullptr, 1, 29, "LimeSDR-Mini_HW_1.2_r1.29.rpd"}), + ConnectionImageEntry({LMS_DEV_LIMENET_MICRO, 3, 0, nullptr, 1, 2, "LimeNET-Micro_lms7_trx_HW_2.1_r1.2.rpd"}), + ConnectionImageEntry({LMS_DEV_LIMESDRMINI, 0, 0, nullptr, 1, 30, "LimeSDR-Mini_HW_1.2_r1.30.rpd"}), }; for(const auto &iter : imageEntries) diff --git a/src/protocols/Streamer.cpp b/src/protocols/Streamer.cpp index 23c0b9814..73476c60c 100644 --- a/src/protocols/Streamer.cpp +++ b/src/protocols/Streamer.cpp @@ -608,6 +608,7 @@ int Streamer::UpdateThreads(bool stopAll) const uint32_t data[] = {reg9 | (5 << 1), reg9 & ~(5 << 1)}; fpga->StartStreaming(); fpga->WriteRegisters(addr, data, 2); + lms->ResetLogicregisters(); } else if(not needTx and not needRx) { diff --git a/src/utilities_gui/SPI_wxgui.cpp b/src/utilities_gui/SPI_wxgui.cpp index 6c45a791b..f156ed060 100644 --- a/src/utilities_gui/SPI_wxgui.cpp +++ b/src/utilities_gui/SPI_wxgui.cpp @@ -29,7 +29,7 @@ void SPI_wxgui::onLMSwrite( wxCommandEvent& event ) const std::vector wrStatus = { lblLMSwriteStatus, lblLMSwriteStatus1, lblLMSwriteStatus2, lblLMSwriteStatus3, lblLMSwriteStatus4, lblLMSwriteStatus5, lblLMSwriteStatus6, lblLMSwriteStatus7}; auto object = event.GetEventObject(); - int index; + unsigned int index; for (index = 0; index < wrbtn.size(); index++) if (object == wrbtn[index]) break; @@ -63,11 +63,11 @@ void SPI_wxgui::onLMSread( wxCommandEvent& event ) const std::vector rdStatus = { lblLMSwriteStatus, lblLMSwriteStatus1, lblLMSwriteStatus2, lblLMSwriteStatus3, lblLMSwriteStatus4, lblLMSwriteStatus5, lblLMSwriteStatus6, lblLMSwriteStatus7 }; auto object = event.GetEventObject(); - int index; + unsigned int index; for (index = 0; index < rdbtn.size(); index++) if (object == rdbtn[index]) break; - + wxString address = rdAddr[index]->GetValue(); long addr = 0; address.ToLong(&addr, 16); @@ -101,7 +101,7 @@ void SPI_wxgui::onBoardWrite( wxCommandEvent& event ) lblBoardwriteStatus4, lblBoardwriteStatus5, lblBoardwriteStatus6, lblBoardwriteStatus7 }; auto object = event.GetEventObject(); - int index; + unsigned int index; for (index = 0; index < wrbtn.size(); index++) if (object == wrbtn[index]) break; @@ -138,7 +138,7 @@ void SPI_wxgui::OnBoardRead( wxCommandEvent& event ) lblBoardwriteStatus4, lblBoardwriteStatus5, lblBoardwriteStatus6, lblBoardwriteStatus7 }; auto object = event.GetEventObject(); - int index; + unsigned int index; for (index = 0; index < rdbtn.size(); index++) if (object == rdbtn[index]) break; diff --git a/src/utilities_gui/dlgConnectionSettings.cpp b/src/utilities_gui/dlgConnectionSettings.cpp index a1a424133..7d0e178dc 100644 --- a/src/utilities_gui/dlgConnectionSettings.cpp +++ b/src/utilities_gui/dlgConnectionSettings.cpp @@ -43,7 +43,7 @@ void dlgConnectionSettings::OnConnect( wxCommandEvent& event ) auto list = lime::LMS7_Device::GetDeviceList(); const int selection = mListLMS7ports->GetSelection(); - if(selection != wxNOT_FOUND && selection < list.size()) + if(selection != wxNOT_FOUND && (size_t)selection < list.size()) { if (list[selection].module == "Z_Remote") {