├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake └── Modules │ └── FindCyAPI.cmake └── src ├── ExtIO_LimeSDR.aps ├── ExtIO_LimeSDR.cpp ├── ExtIO_LimeSDR.def ├── ExtIO_LimeSDR.h ├── ExtIO_LimeSDR.rc ├── LC_ExtIO_Types.h └── resource.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Directories 35 | /Release/* 36 | /Debug/* 37 | /ExtIO_LimeSDR/Release/* 38 | /ExtIO_LimeSDR/Debug/* 39 | /.vs/* 40 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Project setup 3 | ######################################################################## 4 | cmake_minimum_required (VERSION 2.8) 5 | 6 | #Check if using correct Visual studio version 7 | if(MSVC_TOOLSET_VERSION LESS 140) 8 | message(FATAL_ERROR "MSVC version should be atleast v140(Visual Studio 2015") 9 | endif() 10 | 11 | project (ExtIO_LimeSDR) 12 | 13 | cmake_policy(SET CMP0015 NEW) 14 | cmake_policy(SET CMP0021 NEW) 15 | 16 | #select the release build by default 17 | if(NOT CMAKE_BUILD_TYPE) 18 | set(CMAKE_BUILD_TYPE "Release") 19 | message(STATUS "Build type not specified: defaulting to release.") 20 | endif(NOT CMAKE_BUILD_TYPE) 21 | set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") 22 | 23 | option (BUILD_SHARED_LIBS "Build shared library" ON) 24 | 25 | #include modules for finding CyAPI 26 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") 27 | 28 | message(STATUS "Make sure that BUILD_SHARED_LIBS option matches BUILD_SHARED_LIBS option when LimeSuite was built") 29 | message(STATUS "Only LimeSuite source and build directories should be needed, everything else is found automatically") 30 | ######################################################################## 31 | # Find LimeSuite 32 | ######################################################################## 33 | find_path(LIMESUITE_BUILD_DIR 34 | NAMES LimeSuite 35 | PATHS NO_DEFAULT_PATH 36 | ) 37 | find_path(LIMESUITE_SOURCE_DIR 38 | PATHS NO_DEFAULT_PATH 39 | ) 40 | 41 | find_path(LIMESUITE_INCLUDE_DIR 42 | NAMES LimeSuite.h 43 | HINTS ${LIMESUITE_SOURCE_DIR}/src/lime 44 | ) 45 | 46 | find_library(LIMESUITE_LIB 47 | NAMES LimeSuite limesuite 48 | HINTS ${LIMESUITE_BUILD_DIR}/src/Release 49 | ${LIMESUITE_BUILD_DIR}/src/Debug 50 | ) 51 | ######################################################################## 52 | # Add shared dll 53 | ######################################################################## 54 | add_library(ExtIO_LimeSDR SHARED 55 | ${CMAKE_SOURCE_DIR}/src/ExtIO_LimeSDR.cpp 56 | ${CMAKE_SOURCE_DIR}/src/ExtIO_LimeSDR.h 57 | ${CMAKE_SOURCE_DIR}/src/ExtIO_LimeSDR.def 58 | ${CMAKE_SOURCE_DIR}/src/LC_ExtIO_Types.h 59 | ${CMAKE_SOURCE_DIR}/src/resource.h 60 | ${CMAKE_SOURCE_DIR}/src/ExtIO_LimeSDR.def 61 | ${CMAKE_SOURCE_DIR}/src/ExtIO_LimeSDR.rc 62 | ) 63 | #add LimeSuite libraries 64 | target_link_libraries(ExtIO_LimeSDR PUBLIC ${LIMESUITE_LIB}) 65 | target_include_directories(ExtIO_LimeSDR PUBLIC ${LIMESUITE_INCLUDE_DIR}) 66 | ######################################################################## 67 | # Check if linking the dll statically and find required libraries 68 | ######################################################################## 69 | if(BUILD_SHARED_LIBS STREQUAL "OFF") 70 | #find FTD3XX 71 | find_path(FTD3XX_INCLUDE_DIR 72 | NAMES FTD3XX.h 73 | HINTS ${LIMESUITE_SOURCE_DIR}/src/ConnectionFTDI/FTD3XXLibrary 74 | ) 75 | find_library(FTD3XX_LIB_STATIC 76 | NAMES FTD3XX.lib 77 | HINTS ${FTD3XX_INCLUDE_DIR}/Win32/Static 78 | ) 79 | 80 | #find CyAPI 81 | include(FindCyAPI) 82 | 83 | #add libraries 84 | target_include_directories(ExtIO_LimeSDR PUBLIC ${FTD3XX_INCLUDE_DIR}) 85 | target_link_libraries(ExtIO_LimeSDR PUBLIC ${FTD3XX_LIB_STATIC} ${CYAPI_LIBRARY}) 86 | endif() 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright(c) 2017 Jiang Wei 4 | New and modified work Copyright(c) 2018 Lime Microsystems Ltd 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files(the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions : 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ExtIO_LimeSDR 2 | 3 | This repository contains HDSDR ExtIO plugin for LimeSDR-USB and LimeSDR-mini boards. 4 | 5 | ## Prebuilt library 6 | 7 | You can download prebuilt library dll by following this link: 8 | 9 | https://downloads.myriadrf.org/project/limesuite/ 10 | 11 | ## Documentation 12 | 13 | Find build and install instructions for this plugin by following this link: 14 | 15 | https://wiki.myriadrf.org/LimeSDR_ExtIO_Plugin_for_HDSDR 16 | 17 | ## Help and support 18 | 19 | The discourse forum is a good way to find help and discuss topics: 20 | 21 | * https://discourse.myriadrf.org/ 22 | -------------------------------------------------------------------------------- /cmake/Modules/FindCyAPI.cmake: -------------------------------------------------------------------------------- 1 | # Locate the Cypress API for 2 | # 3 | # This module defines the following variables: 4 | # CYAPI_FOUND TRUE if the Cypress API was found 5 | # CYAPI_HEADER_FILE The location of the API header 6 | # CYAPI_INCLUDE_DIRS The location of header files 7 | # CYAPI_LIBRARIES The Cypress library files 8 | # CYPRESS_LICENSE Path to Cypress license shipped with FX3 SDK 9 | 10 | if(NOT WIN32) 11 | return() 12 | endif() 13 | 14 | if(MSVC) 15 | set(FX3_SDK_PATH "$ENV{FX3_INSTALL_PATH}" CACHE PATH "Path to the Cypress FX3 SDK") 16 | if(NOT EXISTS "${FX3_SDK_PATH}") 17 | message(STATUS 18 | "Cypress backend not available. The following location does not exist: FX3_SDK_PATH=${FX3_SDK_PATH}") 19 | return() 20 | endif() 21 | find_file(CYAPI_HEADER_FILE 22 | NAMES 23 | CyAPI.h 24 | PATHS 25 | "${FX3_SDK_PATH}/library/cpp" 26 | PATH_SUFFIXES 27 | include inc 28 | ) 29 | mark_as_advanced(CYAPI_HEADER_FILE) 30 | get_filename_component(CYAPI_INCLUDE_DIRS "${CYAPI_HEADER_FILE}" PATH) 31 | 32 | if(MSVC) 33 | if(CMAKE_CL_64) 34 | set(CYAPI_ARCH x64) 35 | else(CMAKE_CL_64) 36 | set(CYAPI_ARCH x86) 37 | endif(CMAKE_CL_64) 38 | elseif(CMAKE_COMPILER_IS_GNUCC) 39 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 40 | set(CYAPI_ARCH x64) 41 | else(CMAKE_SIZEOF_VOID_P EQUAL 8) 42 | set(CYAPI_ARCH x86) 43 | endif(CMAKE_SIZEOF_VOID_P EQUAL 8) 44 | endif() 45 | 46 | find_library(CYAPI_LIBRARY 47 | NAMES 48 | CyAPI 49 | PATHS 50 | "${FX3_SDK_PATH}/library/cpp" 51 | PATH_SUFFIXES 52 | lib/${CYAPI_ARCH} 53 | ) 54 | mark_as_advanced(CYAPI_LIBRARY) 55 | 56 | if(CYAPI_LIBRARY) 57 | set(CYAPI_LIBRARIES "${CYAPI_LIBRARY}" SetupAPI.lib) 58 | endif() 59 | 60 | set(CYPRESS_LICENSE "${FX3_SDK_PATH}/license/license.txt") 61 | endif(MSVC) 62 | 63 | if(CMAKE_COMPILER_IS_GNUCC) 64 | set(CYAPI_USBSUITE_SOURCE_PATH "" CACHE PATH "Path to the Cypress USB Suite Source") 65 | if(NOT EXISTS "${CYAPI_USBSUITE_SOURCE_PATH}") 66 | message(STATUS 67 | "Cypress backend not available. The following location does not exist: CYAPI_USBSUITE_SOURCE_PATH=${CYAPI_USBSUITE_SOURCE_PATH}") 68 | return() 69 | endif() 70 | find_file(CYAPI_HEADER_FILE 71 | NAMES 72 | CyAPI.h 73 | PATHS 74 | "${CYAPI_USBSUITE_SOURCE_PATH}/CyAPI_lib_cpp" 75 | PATH_SUFFIXES 76 | include inc 77 | ) 78 | mark_as_advanced(CYAPI_HEADER_FILE) 79 | get_filename_component(CYAPI_INCLUDE_DIRS "${CYAPI_HEADER_FILE}" PATH) 80 | message(STATUS "CyAPI include dir: ${CYAPI_INCLUDE_DIRS}") 81 | 82 | find_file(CYAPI_SOURCE_FILE 83 | NAMES 84 | CyAPI.cpp 85 | PATHS 86 | "${CYAPI_USBSUITE_SOURCE_PATH}/CyAPI_lib_cpp" 87 | PATH_SUFFIXES 88 | include src 89 | ) 90 | mark_as_advanced(CYAPI_SOURCE_FILE) 91 | 92 | #disable unicode 93 | ADD_DEFINITIONS(-UUNICODE) 94 | ADD_DEFINITIONS(-U_UNICODE) 95 | add_library(CYAPI_LIB STATIC ${CYAPI_SOURCE_FILE}) 96 | target_include_directories(CYAPI_LIB PUBLIC "${CYAPI_USBSUITE_SOURCE_PATH}/CyAPI_lib_cpp/inc") 97 | mark_as_advanced(CYAPI_INCLUDE_DIRS) 98 | target_link_libraries(CYAPI_LIB SetupAPI) 99 | set(CYAPI_LIBRARIES ${CYAPI_LIB}) 100 | ADD_DEFINITIONS(-DUNICODE) 101 | ADD_DEFINITIONS(-D_UNICODE) 102 | set(CYPRESS_LICENSE "${CYAPI_USBSUITE_SOURCE_PATH}/License/license.txt") 103 | endif(CMAKE_COMPILER_IS_GNUCC) 104 | 105 | if(CYAPI_INCLUDE_DIRS AND CYAPI_LIBRARIES) 106 | set(CYAPI_FOUND TRUE) 107 | endif() 108 | if(CYAPI_FOUND) 109 | set(CMAKE_REQUIRED_INCLUDES "${CYAPI_INCLUDE_DIRS}") 110 | message(STATUS "CyAPI includes: ${CYAPI_INCLUDE_DIRS}") 111 | message(STATUS "CyAPI libs: ${CYAPI_LIBRARIES}") 112 | endif() 113 | if(NOT CYAPI_FOUND AND REQUIRED) 114 | message(FATAL_ERROR "Cypress API not found. Double-check your FX3_SDK_PATH value.") 115 | endif() -------------------------------------------------------------------------------- /src/ExtIO_LimeSDR.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/ExtIO_LimeSDR/47a2759bc47552495fe1001911569c6b8baa0282/src/ExtIO_LimeSDR.aps -------------------------------------------------------------------------------- /src/ExtIO_LimeSDR.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License 3 | 4 | Copyright(c) 2017 Jiang Wei 5 | New and modified work Copyright(c) 2018 Lime Microsystems Ltd 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files(the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions : 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE 24 | */ 25 | 26 | /*---------------------------------------------------------------------------*/ 27 | #define EXTIO_EXPORTS 1 28 | #define HWNAME "ExtIO_Lime" 29 | #define HWMODEL "ExtIO_Lime" 30 | #define VERNUM "1.07" 31 | #define EXT_BLOCKLEN 4096 /* only multiples of 512 */ 32 | //--------------------------------------------------------------------------- 33 | #include "ExtIO_LimeSDR.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "resource.h" 40 | #include 41 | //--------------------------------------------------------------------------- 42 | 43 | #ifdef _DEBUG 44 | #define _MYDEBUG // Activate a debug console 45 | #endif 46 | 47 | #ifdef _MYDEBUG 48 | /* Debug Trace Enabled */ 49 | #include 50 | #define DbgPrintf printf 51 | #else 52 | /* Debug Trace Disabled */ 53 | #define DbgPrintf(Message) MessageBox(NULL, Message, NULL, MB_OK|MB_ICONERROR) 54 | #endif 55 | 56 | #pragma warning(disable : 4996) 57 | #define snprintf _snprintf 58 | //--------------------------------------------------------------------------- 59 | float_type sampleRates[] = 60 | { 61 | 2000000, 62 | 4000000, 63 | 8000000, 64 | 10000000, 65 | 15000000, 66 | 20000000, 67 | 25000000, 68 | 30000000 69 | }; 70 | 71 | enum CalibrationStatus { 72 | Calibrated = 1, 73 | NotCalibrated = 0, 74 | CalibrationErr = -1 75 | }; 76 | 77 | int isCalibrated = NotCalibrated; 78 | bool isRunning = false; 79 | bool LPFenable = false; 80 | bool error_enabled = true; 81 | char lastUsedDeviceName[32]; 82 | pfnExtIOCallback ExtIOCallback = nullptr; 83 | int16_t* buffer = nullptr; 84 | 85 | lms_stream_t streamId; 86 | lms_info_str_t deviceList[10]; 87 | lms_device_t * device = nullptr; 88 | LMS_LogHandler log_handler = nullptr; 89 | 90 | HANDLE thread_handle = INVALID_HANDLE_VALUE; 91 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 92 | HWND h_dialog = nullptr; 93 | HWND error_dialog = nullptr; 94 | 95 | std::string DeviceInfo[10][10]; 96 | int currentDeviceIndex = 0; 97 | int numOfDevices = 0; 98 | int numOfChannels = 0; 99 | size_t channel = 0; 100 | size_t oversample = 2; 101 | int sr_idx = 1; 102 | int ant_select = LMS_PATH_AUTO; 103 | int64_t CurrentLOfreq = 28.5e6; // default HDSDR LO freq 104 | float_type LPFbandwidth = sampleRates[sr_idx]; 105 | float_type CalibrationBandwidth = sampleRates[sr_idx]; 106 | 107 | /* 53 dB gain */ 108 | uint16_t LNA = 10; 109 | uint16_t TIA = 3; 110 | uint16_t PGA = 12; 111 | //--------------------------------------------------------------------------- 112 | static void RecvThread(void *p) 113 | { 114 | while (isRunning) { 115 | 116 | int samplesRead = LMS_RecvStream(&streamId, buffer, EXT_BLOCKLEN, NULL, 1000); 117 | if (ExtIOCallback != nullptr) { 118 | ExtIOCallback(samplesRead * 2, 0, 0, buffer); 119 | } 120 | } 121 | _endthread(); 122 | } 123 | //--------------------------------------------------------------------------- 124 | static void error(int lvl, const char *msg) 125 | { 126 | #ifdef _MYDEBUG 127 | DbgPrintf(msg); 128 | DbgPrintf("\n"); 129 | #else 130 | if (error_enabled && lvl < 2) 131 | { 132 | if (lvl == 1) { 133 | ExtIOCallback(-1, extHw_Stop, 0, NULL); 134 | } 135 | DbgPrintf(msg); 136 | } 137 | #endif 138 | } 139 | //--------------------------------------------------------------------------- 140 | static int SetGain() 141 | { 142 | int rcc_ctl_pga_rbb = (430 * (pow(0.65, ((double)PGA / 10))) - 110.35) / 20.4516 + 16; //From datasheet 143 | 144 | if (LMS_WriteParam(device, LMS7param(G_LNA_RFE), LNA) != 0 145 | || LMS_WriteParam(device, LMS7param(G_PGA_RBB), PGA) != 0 146 | || LMS_WriteParam(device, LMS7param(RCC_CTL_PGA_RBB), rcc_ctl_pga_rbb) != 0 147 | || LMS_WriteParam(device, LMS7param(G_TIA_RFE), TIA) != 0) { 148 | return -1; 149 | } 150 | return 0; 151 | } 152 | //--------------------------------------------------------------------------- 153 | static void PerformCalibration(bool enable_error) 154 | { 155 | int64_t freq = -1; 156 | if (isRunning) { 157 | freq = GetHWLO64(); 158 | StopHW(); 159 | } 160 | error_enabled = enable_error; 161 | 162 | isCalibrated = Calibrated; 163 | if (LMS_Calibrate(device, LMS_CH_RX, channel, CalibrationBandwidth, 0) != 0) { 164 | isCalibrated = CalibrationErr; 165 | } 166 | 167 | error_enabled = true; 168 | if (freq != -1) 169 | StartHW64(freq); 170 | } 171 | //--------------------------------------------------------------------------- 172 | static int DisableLPF() 173 | { 174 | int64_t freq = -1; 175 | if (isRunning) { 176 | freq = GetHWLO64(); 177 | StopHW(); 178 | } 179 | 180 | /* Making sure that tia isn't -12dB */ 181 | if (LMS_WriteParam(device, LMS7param(G_TIA_RFE), 3) != 0) { 182 | return -1; 183 | } 184 | 185 | /* If the bandwidth is higher than 110e6, LPF is bypassed */ 186 | if (LMS_SetLPFBW(device, LMS_CH_RX, channel, 130e6) != 0) { 187 | return -1; 188 | } 189 | 190 | LPFenable = false; 191 | 192 | if (LMS_WriteParam(device, LMS7param(G_TIA_RFE), TIA) != 0) { 193 | return -1; 194 | } 195 | if (freq != -1) 196 | StartHW64(freq); 197 | 198 | return 0; 199 | } 200 | //--------------------------------------------------------------------------- 201 | static int EnableLPF() 202 | { 203 | if (LPFbandwidth > 1.4e6 && LPFbandwidth <= 130e6) { 204 | int64_t freq = -1; 205 | 206 | if (isRunning) { 207 | freq = GetHWLO64(); 208 | StopHW(); 209 | } 210 | 211 | if (LMS_WriteParam(device, LMS7param(G_TIA_RFE), 3) != 0) { 212 | return -1; 213 | } 214 | 215 | if (LMS_SetLPFBW(device, LMS_CH_RX, channel, LPFbandwidth) != 0) { 216 | return -1; 217 | } 218 | 219 | if (LMS_WriteParam(device, LMS7param(G_TIA_RFE), TIA) != 0) { 220 | return -1; 221 | } 222 | LPFenable = true; 223 | 224 | if (LPFbandwidth > 2.5e6) 225 | CalibrationBandwidth = LPFbandwidth; 226 | else 227 | CalibrationBandwidth = 2.5e6; 228 | 229 | 230 | if (freq != -1) 231 | StartHW64(freq); 232 | } 233 | else { 234 | DbgPrintf("RxLPF frequency out of range, available range from 1.4 to 130 MHz"); 235 | return -1; 236 | } 237 | 238 | return 0; 239 | } 240 | //--------------------------------------------------------------------------- 241 | static int InitializeLMS() 242 | { 243 | if (LMS_Open(&device, deviceList[currentDeviceIndex], NULL) != LMS_SUCCESS) { 244 | return -1; 245 | } 246 | 247 | numOfChannels = LMS_GetNumChannels(device, LMS_CH_RX); 248 | if (numOfChannels == -1) { 249 | return -1; 250 | } 251 | 252 | if (LMS_Init(device) != LMS_SUCCESS) { 253 | return -1; 254 | } 255 | if (LMS_SetSampleRate(device, sampleRates[sr_idx], oversample) != LMS_SUCCESS) { 256 | return -1; 257 | } 258 | 259 | if (LMS_EnableChannel(device, LMS_CH_RX, channel, true) != LMS_SUCCESS) { 260 | return -1; 261 | } 262 | /* TX channel needs to be enabled for LPF and calibration */ 263 | if (LMS_EnableChannel(device, LMS_CH_TX, channel, true) != LMS_SUCCESS) { 264 | return -1; 265 | } 266 | if (LMS_SetAntenna(device, LMS_CH_RX, channel, ant_select) != LMS_SUCCESS) { 267 | return -1; 268 | } 269 | 270 | if (LPFenable) { 271 | if (EnableLPF() != 0) 272 | return -1; 273 | } 274 | else { 275 | if (DisableLPF() != 0) 276 | return -1; 277 | } 278 | if (SetGain() != 0) 279 | return -1; 280 | 281 | if (LMS_SetLOFrequency(device, LMS_CH_RX, channel, float_type(CurrentLOfreq)) != LMS_SUCCESS) { 282 | return -1; 283 | } 284 | PerformCalibration(false); 285 | 286 | return 0; 287 | } 288 | 289 | //--------------------------------------------------------------------------- 290 | void UpdateDialog() 291 | { 292 | Button_SetCheck(GetDlgItem(h_dialog, IDC_CHECK_ALPF), LPFenable); // LPF checkbox 293 | ComboBox_SetCurSel(GetDlgItem(h_dialog, IDC_COMBO_CHAN), channel); // Channel dropdown 294 | ComboBox_SetCurSel(GetDlgItem(h_dialog, IDC_COMBO_DEVICE), currentDeviceIndex);// Device dropdown 295 | 296 | /* Set antenna selection */ 297 | for (int i = 0; i < ComboBox_GetCount(GetDlgItem(h_dialog, IDC_COMBO_ANT)); i++) 298 | if (ComboBox_GetItemData(GetDlgItem(h_dialog, IDC_COMBO_ANT), i) == ant_select) 299 | ComboBox_SetCurSel(GetDlgItem(h_dialog, IDC_COMBO_ANT), i); 300 | 301 | /* Update LNA slider */ 302 | LMS_ReadParam(device, LMS7param(G_LNA_RFE), &LNA); 303 | SendDlgItemMessage(h_dialog, IDC_SLIDER_LNA, TBM_SETPOS, TRUE, 16 - ((int)LNA)); 304 | std::string lna_value = std::to_string(LNA > 8 ? (LNA - 15) : (LNA - 11) * 3); 305 | lna_value.append(" dB"); 306 | Static_SetText(GetDlgItem(h_dialog, IDC_TEXT_LNA), lna_value.c_str()); 307 | 308 | /* Update TIA slider */ 309 | LMS_ReadParam(device, LMS7param(G_TIA_RFE), &TIA); 310 | SendDlgItemMessage(h_dialog, IDC_SLIDER_TIA, TBM_SETPOS, TRUE, 4 - ((int)TIA)); 311 | std::string tia_value = std::to_string((TIA == 3) ? 0 : (TIA == 2) ? -3 : -12); 312 | tia_value.append(" dB"); 313 | Static_SetText(GetDlgItem(h_dialog, IDC_TEXT_TIA), tia_value.c_str()); 314 | 315 | /* Update PGA slider */ 316 | LMS_ReadParam(device, LMS7param(G_PGA_RBB), &PGA); 317 | SendDlgItemMessage(h_dialog, IDC_SLIDER_PGA, TBM_SETPOS, TRUE, 31 - ((int)PGA)); 318 | std::string pga_value = std::to_string(PGA - 12); 319 | pga_value.append(" dB"); 320 | Static_SetText(GetDlgItem(h_dialog, IDC_TEXT_PGA), pga_value.c_str()); 321 | 322 | /* Update LPF bandwidth */ 323 | char bandwidth[7]; 324 | sprintf(bandwidth, "%3.2f", LPFbandwidth / 1e6); 325 | SetDlgItemText(h_dialog, IDC_ALPF_BW, bandwidth); 326 | 327 | /* Update calibration bandwidth */ 328 | sprintf(bandwidth, "%3.2f", CalibrationBandwidth / 1e6); 329 | SetDlgItemText(h_dialog, IDC_CAL_BW, bandwidth); 330 | 331 | /* Update calibration text */ 332 | if (isCalibrated == Calibrated) 333 | Static_SetText(GetDlgItem(h_dialog, IDC_TEXT_CALIBRATED), "Calibrated"); 334 | else if (isCalibrated == NotCalibrated) 335 | Static_SetText(GetDlgItem(h_dialog, IDC_TEXT_CALIBRATED), "Not calibrated"); 336 | else if (isCalibrated == CalibrationErr) 337 | Static_SetText(GetDlgItem(h_dialog, IDC_TEXT_CALIBRATED), "Calibration failed"); 338 | } 339 | //--------------------------------------------------------------------------- 340 | static INT_PTR CALLBACK MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 341 | { 342 | 343 | switch (uMsg) { 344 | /* Init starting variables */ 345 | case WM_INITDIALOG: 346 | { 347 | /* Add device choices */ 348 | for (int i = 0; i < numOfDevices; i++) { 349 | std::string info = std::to_string(i + 1) + ". " + DeviceInfo[i][0] + " (" + DeviceInfo[i][1] + ")"; 350 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_DEVICE), info.c_str()); 351 | } 352 | ComboBox_SetCurSel(GetDlgItem(hwndDlg, IDC_COMBO_DEVICE), currentDeviceIndex); 353 | 354 | 355 | /* Add antenna choices */ 356 | if (DeviceInfo[currentDeviceIndex][0] == "LimeSDR Mini") { 357 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "Auto"); 358 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0, 255); 359 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_H"); 360 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 1, 1); 361 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_W"); 362 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 2, 3); 363 | } else if (DeviceInfo[currentDeviceIndex][0] == "LimeNET-Micro") { 364 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "Auto"); 365 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0, 255); 366 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_H"); 367 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 1, 1); 368 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_L"); 369 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 2, 2); 370 | } else { 371 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_H"); 372 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0, 1); 373 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_L"); 374 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 1, 2); 375 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_W"); 376 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 2, 3); 377 | } 378 | 379 | 380 | /* Add channel choices */ 381 | for (int i = 0; i < numOfChannels; i++) { 382 | std::string channels = "RX" + std::to_string(i + 1); 383 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_CHAN), channels.c_str()); 384 | } 385 | 386 | /* Add tickmarks, set range for LNA slider */ 387 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_LNA, TBM_SETRANGEMIN, FALSE, 1); 388 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_LNA, TBM_SETRANGEMAX, FALSE, 15); 389 | for (int i = 0; i < 15; i++) { 390 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_LNA, TBM_SETTIC, FALSE, i); 391 | } 392 | 393 | /* Add tickmarks, set range for TIA slider */ 394 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_TIA, TBM_SETRANGEMIN, FALSE, 1); 395 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_TIA, TBM_SETRANGEMAX, FALSE, 3); 396 | for (int i = 0; i < 3; i++) { 397 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_TIA, TBM_SETTIC, FALSE, i); 398 | } 399 | 400 | /* Add tickmarks, set range for PGA slider */ 401 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_PGA, TBM_SETRANGEMIN, FALSE, 0); 402 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_PGA, TBM_SETRANGEMAX, FALSE, 31); 403 | for (int i = 0; i < 31; i++) { 404 | SendDlgItemMessage(hwndDlg, IDC_SLIDER_PGA, TBM_SETTIC, FALSE, i); 405 | } 406 | 407 | /* Add library version */ 408 | Static_SetText(GetDlgItem(hwndDlg, IDC_TEXT_LIBVER), LMS_GetLibraryVersion()); 409 | /* Add ExtIO version */ 410 | Static_SetText(GetDlgItem(hwndDlg, IDC_TEXT_EXTVER), VERNUM); 411 | 412 | UpdateDialog(); 413 | return TRUE; 414 | } 415 | break; 416 | 417 | /* Update dialog */ 418 | case WM_SHOWWINDOW: 419 | { 420 | UpdateDialog(); 421 | return TRUE; 422 | } 423 | break; 424 | /* Scroll message */ 425 | case WM_VSCROLL: 426 | { 427 | /* LNA slider moved */ 428 | if (GetDlgItem(hwndDlg, IDC_SLIDER_LNA) == (HWND)lParam) { 429 | if (LNA != 16 - SendDlgItemMessage(hwndDlg, IDC_SLIDER_LNA, TBM_GETPOS, 0, NULL)) { 430 | LNA = 16 - SendDlgItemMessage(hwndDlg, IDC_SLIDER_LNA, TBM_GETPOS, 0, NULL); 431 | std::string lna_value = std::to_string(LNA > 8 ? (LNA - 15) : (LNA - 11) * 3); // Calculate from index to dB 432 | lna_value.append(" dB"); 433 | Static_SetText(GetDlgItem(hwndDlg, IDC_TEXT_LNA), lna_value.c_str()); 434 | 435 | if (LNA <= 15) 436 | LMS_WriteParam(device, LMS7param(G_LNA_RFE), LNA); 437 | 438 | ExtIOCallback(-1, extHw_Changed_ATT, 0, NULL); 439 | isCalibrated = NotCalibrated; 440 | UpdateDialog(); 441 | return TRUE; 442 | } 443 | } 444 | /* TIA slider moved */ 445 | if (GetDlgItem(hwndDlg, IDC_SLIDER_TIA) == (HWND)lParam) { 446 | if (TIA != 4 - SendDlgItemMessage(hwndDlg, IDC_SLIDER_TIA, TBM_GETPOS, 0, NULL)) { 447 | TIA = 4 - SendDlgItemMessage(hwndDlg, IDC_SLIDER_TIA, TBM_GETPOS, 0, NULL); 448 | std::string tia_value = std::to_string((TIA == 3) ? 0 : (TIA == 2) ? -3 : -12); // Calculate from index to dB 449 | tia_value.append(" dB"); 450 | Static_SetText(GetDlgItem(hwndDlg, IDC_TEXT_TIA), tia_value.c_str()); 451 | 452 | if (TIA <= 3) 453 | LMS_WriteParam(device, LMS7param(G_TIA_RFE), TIA); 454 | 455 | ExtIOCallback(-1, extHw_Changed_ATT, 0, NULL); 456 | isCalibrated = NotCalibrated; 457 | UpdateDialog(); 458 | return TRUE; 459 | } 460 | } 461 | /* PGA slider moved */ 462 | if (GetDlgItem(hwndDlg, IDC_SLIDER_PGA) == (HWND)lParam) { 463 | if (PGA != 31 - SendDlgItemMessage(hwndDlg, IDC_SLIDER_PGA, TBM_GETPOS, 0, NULL)) { 464 | PGA = 31 - SendDlgItemMessage(hwndDlg, IDC_SLIDER_PGA, TBM_GETPOS, 0, NULL); 465 | std::string pga_value = std::to_string(PGA - 12); // Calculate from index to dB 466 | pga_value.append(" dB"); 467 | Static_SetText(GetDlgItem(hwndDlg, IDC_TEXT_PGA), pga_value.c_str()); 468 | 469 | int rcc_ctl_pga_rbb = (430 * (pow(0.65, ((double)PGA / 10))) - 110.35) / 20.4516 + 16; //From datasheet 470 | 471 | if (PGA <= 31) { 472 | LMS_WriteParam(device, LMS7param(G_PGA_RBB), PGA); 473 | LMS_WriteParam(device, LMS7param(RCC_CTL_PGA_RBB), rcc_ctl_pga_rbb); 474 | } 475 | 476 | ExtIOCallback(-1, extHw_Changed_ATT, 0, NULL); 477 | isCalibrated = NotCalibrated; 478 | UpdateDialog(); 479 | return TRUE; 480 | } 481 | } 482 | } 483 | break; 484 | /* Command message */ 485 | case WM_COMMAND: 486 | { 487 | switch (GET_WM_COMMAND_ID(wParam, lParam)) { 488 | 489 | /* Changed antenna */ 490 | case IDC_COMBO_ANT: 491 | { 492 | if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) { 493 | 494 | int currentSel = ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam)); 495 | ant_select = ComboBox_GetItemData(GET_WM_COMMAND_HWND(wParam, lParam), currentSel); 496 | 497 | int64_t freq = -1; 498 | if (isRunning) { 499 | freq = GetHWLO64(); 500 | StopHW(); 501 | } 502 | 503 | if (LMS_SetAntenna(device, LMS_CH_RX, channel, ant_select) != LMS_SUCCESS) { 504 | break; 505 | } 506 | 507 | PerformCalibration(false); 508 | 509 | if (freq != -1) 510 | StartHW64(freq); 511 | 512 | UpdateDialog(); 513 | 514 | return TRUE; 515 | } 516 | } 517 | break; 518 | /* Changed device */ 519 | case IDC_COMBO_DEVICE: 520 | { 521 | if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) { 522 | if (currentDeviceIndex != ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam))) { 523 | 524 | int64_t freq = -1; 525 | if (isRunning) { 526 | freq = GetHWLO64(); 527 | StopHW(); 528 | } 529 | if (LMS_Close(device) != LMS_SUCCESS) 530 | break; 531 | 532 | currentDeviceIndex = ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam)); 533 | 534 | /* Default settings */ 535 | channel = 0; 536 | sr_idx = 1; 537 | ant_select = LMS_PATH_LNAH; 538 | 539 | LNA = 10; 540 | TIA = 3; 541 | PGA = 16; 542 | 543 | LPFenable = true; 544 | LPFbandwidth = sampleRates[sr_idx]; 545 | CalibrationBandwidth = sampleRates[sr_idx]; 546 | 547 | InitializeLMS(); 548 | 549 | /* Remove all channel selections */ 550 | while (ComboBox_GetCount(GetDlgItem(hwndDlg, IDC_COMBO_CHAN)) != 0) 551 | ComboBox_DeleteString(GetDlgItem(hwndDlg, IDC_COMBO_CHAN), 0); 552 | 553 | /* Add channel selections */ 554 | for (int i = 0; i < numOfChannels; i++) { 555 | std::string channels = "RX" + std::to_string(i + 1); 556 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_CHAN), channels.c_str()); 557 | } 558 | 559 | while (ComboBox_GetCount(GetDlgItem(hwndDlg, IDC_COMBO_ANT)) != 0) 560 | ComboBox_DeleteString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0); 561 | 562 | /* Add antenna choices */ 563 | if (DeviceInfo[currentDeviceIndex][0] == "LimeSDR Mini") { 564 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "Auto"); 565 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0, 255); 566 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_H"); 567 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 1, 1); 568 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_W"); 569 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 2, 3); 570 | } 571 | else if (DeviceInfo[currentDeviceIndex][0] == "LimeNET-Micro") { 572 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "Auto"); 573 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0, 255); 574 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_H"); 575 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 1, 1); 576 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_L"); 577 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 2, 2); 578 | } 579 | else { 580 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_H"); 581 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 0, 1); 582 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_L"); 583 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 1, 2); 584 | ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO_ANT), "LNA_W"); 585 | ComboBox_SetItemData(GetDlgItem(hwndDlg, IDC_COMBO_ANT), 2, 3); 586 | } 587 | 588 | UpdateDialog(); 589 | 590 | /* Change last used device name */ 591 | strcpy(lastUsedDeviceName, DeviceInfo[currentDeviceIndex][0].c_str()); 592 | 593 | ExtIOCallback(-1, extHw_Changed_SampleRate, 0, NULL); 594 | ExtIOCallback(-1, extHw_Changed_ATT, 0, NULL); 595 | 596 | if (freq != -1) 597 | StartHW64(freq); 598 | 599 | return TRUE; 600 | } 601 | } 602 | } 603 | break; 604 | 605 | /* Changed channel */ 606 | case IDC_COMBO_CHAN: 607 | { 608 | if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) { 609 | if (channel != ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam))) { 610 | int64_t freq = -1; 611 | if (isRunning) { 612 | freq = GetHWLO64(); 613 | StopHW(); 614 | } 615 | 616 | if (LMS_EnableChannel(device, LMS_CH_RX, channel, false) != LMS_SUCCESS) 617 | break; 618 | if (LMS_EnableChannel(device, LMS_CH_TX, channel, false) != LMS_SUCCESS) 619 | break; 620 | channel = ComboBox_GetCurSel(GET_WM_COMMAND_HWND(wParam, lParam)); 621 | 622 | if (LMS_EnableChannel(device, LMS_CH_RX, channel, true) != LMS_SUCCESS) 623 | break; 624 | if (LMS_EnableChannel(device, LMS_CH_TX, channel, true) != LMS_SUCCESS) 625 | break; 626 | if (LMS_SetAntenna(device, LMS_CH_RX, channel, ant_select) != LMS_SUCCESS) 627 | break; 628 | 629 | if (LPFenable) 630 | EnableLPF(); 631 | else 632 | DisableLPF(); 633 | 634 | if (SetGain() != 0) 635 | break; 636 | 637 | PerformCalibration(false); 638 | 639 | if (freq != -1) 640 | StartHW64(freq); 641 | 642 | UpdateDialog(); 643 | 644 | return TRUE; 645 | } 646 | } 647 | } 648 | break; 649 | 650 | /* Pressed Calibrate button */ 651 | case IDC_BUTTON_CAl: 652 | { 653 | if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED) { 654 | 655 | int buffSize = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_CAL_BW)); 656 | char *textBuffer = new char[buffSize + 1]; 657 | 658 | GetDlgItemText(hwndDlg, IDC_CAL_BW, textBuffer, buffSize + 1); 659 | 660 | CalibrationBandwidth = atof(textBuffer)*1e6; 661 | if (CalibrationBandwidth >= 2.5e6 && CalibrationBandwidth <= 120e6) { 662 | PerformCalibration(true); 663 | 664 | UpdateDialog(); 665 | } 666 | else { 667 | DbgPrintf("Frequency out of range, available range from 2.5 to 120 MHz"); 668 | CalibrationBandwidth = sampleRates[sr_idx]; 669 | if (CalibrationBandwidth < 2.5e6) 670 | CalibrationBandwidth = 2.5e6; 671 | UpdateDialog(); 672 | } 673 | 674 | free(textBuffer); 675 | return TRUE; 676 | } 677 | } 678 | break; 679 | 680 | /* Pressed Set button*/ 681 | case IDC_BUTTON_SET: 682 | { 683 | if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED) { 684 | 685 | int buffSize = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ALPF_BW)); 686 | char *textBuffer = new char[buffSize + 1]; 687 | 688 | GetDlgItemText(hwndDlg, IDC_ALPF_BW, textBuffer, buffSize + 1); 689 | 690 | LPFbandwidth = atof(textBuffer)*1e6; 691 | EnableLPF(); 692 | PerformCalibration(false); 693 | UpdateDialog(); 694 | 695 | free(textBuffer); 696 | return TRUE; 697 | } 698 | } 699 | break; 700 | /* LPF checkbox clicked */ 701 | case IDC_CHECK_ALPF: 702 | { 703 | if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED) { 704 | if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALPF) == BST_CHECKED) { 705 | EnableLPF(); 706 | PerformCalibration(false); 707 | UpdateDialog(); 708 | } 709 | else if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_ALPF) == BST_UNCHECKED) { 710 | DisableLPF(); 711 | PerformCalibration(false); 712 | UpdateDialog(); 713 | } 714 | } 715 | return TRUE; 716 | } 717 | break; 718 | 719 | /* Pressed Reset button */ 720 | case IDC_BUTTON_DEFAULT: 721 | { 722 | if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED) { 723 | int64_t freq = -1; 724 | if (isRunning) { 725 | freq = GetHWLO64(); 726 | StopHW(); 727 | } 728 | 729 | /* Default settings */ 730 | LPFenable = true; 731 | channel = 0; 732 | sr_idx = 1; 733 | LPFbandwidth = sampleRates[sr_idx]; 734 | CalibrationBandwidth = LPFbandwidth; 735 | ant_select = LMS_PATH_AUTO; 736 | 737 | LNA = 10; 738 | TIA = 3; 739 | PGA = 16; 740 | 741 | LMS_Close(device); 742 | InitializeLMS(); 743 | 744 | ExtIOCallback(-1, extHw_Changed_SampleRate, 0, NULL); 745 | ExtIOCallback(-1, extHw_Changed_ATT, 0, NULL); 746 | 747 | if (freq != -1) 748 | StartHW64(freq); 749 | 750 | UpdateDialog(); 751 | 752 | return TRUE; 753 | } 754 | } 755 | break; 756 | } 757 | } 758 | break; 759 | /* Static text color message */ 760 | case WM_CTLCOLORSTATIC: 761 | { 762 | /* Calibrated text color */ 763 | if (GetDlgCtrlID((HWND)lParam) == IDC_TEXT_CALIBRATED) { 764 | HDC hdcStatic = (HDC)wParam; 765 | if (isCalibrated == Calibrated) 766 | SetTextColor(hdcStatic, RGB(24, 135, 0)); 767 | else if (isCalibrated == NotCalibrated) 768 | SetTextColor(hdcStatic, RGB(0, 0, 0)); 769 | else if (isCalibrated == CalibrationErr) 770 | SetTextColor(hdcStatic, RGB(255, 0, 0)); 771 | 772 | SetBkColor((HDC)wParam, COLORREF(GetSysColor(COLOR_3DFACE))); 773 | return (INT_PTR)GetSysColorBrush(COLOR_3DFACE); 774 | } 775 | } 776 | break; 777 | /* Closed dialog window */ 778 | case WM_CLOSE: 779 | ShowWindow(h_dialog, SW_HIDE); 780 | return TRUE; 781 | break; 782 | /* Destroy dialog window */ 783 | case WM_DESTROY: 784 | ShowWindow(h_dialog, SW_HIDE); 785 | h_dialog = NULL; 786 | return TRUE; 787 | break; 788 | } 789 | return FALSE; 790 | } 791 | //--------------------------------------------------------------------------- 792 | extern "C" 793 | bool __declspec(dllexport) __stdcall InitHW(char *name, char *model, int& type) 794 | { 795 | /* Create debug console window */ 796 | #ifdef _MYDEBUG 797 | if (AllocConsole()) { 798 | FILE* f; 799 | freopen_s(&f, "CONOUT$", "wt", stdout); 800 | SetConsoleTitle(TEXT("Debug Console ExtIO_Lime " VERNUM)); 801 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED); 802 | } 803 | #endif 804 | log_handler = &error; 805 | LMS_RegisterLogHandler(log_handler); 806 | numOfDevices = LMS_GetDeviceList(deviceList); 807 | if (numOfDevices < 1) { 808 | DbgPrintf("No LMS device\n"); 809 | return false; 810 | } 811 | else if (numOfDevices < currentDeviceIndex + 1) 812 | currentDeviceIndex = 0; 813 | 814 | /* Get device info */ 815 | for (int i = 0; i < numOfDevices; i++) { 816 | std::string string = deviceList[i]; 817 | 818 | /* Find serial */ 819 | size_t find = string.find("serial="); 820 | DeviceInfo[i][1] = string.substr(find + 7); 821 | find = DeviceInfo[i][1].find(","); 822 | DeviceInfo[i][1] = DeviceInfo[i][1].substr(0, find); 823 | /* Remove trailing zeroes */ 824 | while (DeviceInfo[i][1][0] == '0') 825 | DeviceInfo[i][1].erase(0, 1); 826 | 827 | /* Find name */ 828 | find = string.find(","); 829 | DeviceInfo[i][0] = string.substr(0, find); 830 | } 831 | 832 | /* If device was changed, reset settings to default */ 833 | if (strcmp(lastUsedDeviceName, DeviceInfo[currentDeviceIndex][0].c_str()) != 0) { 834 | LPFenable = true; 835 | sr_idx = 1; 836 | LPFbandwidth = sampleRates[sr_idx]; 837 | CalibrationBandwidth = LPFbandwidth; 838 | channel = 0; 839 | if (DeviceInfo[currentDeviceIndex][0] == "LimeSDR-USB") 840 | ant_select = LMS_PATH_LNAH; 841 | else 842 | ant_select = LMS_PATH_AUTO; 843 | LNA = 10; 844 | TIA = 3; 845 | PGA = 16; 846 | } 847 | 848 | strcpy(lastUsedDeviceName, DeviceInfo[currentDeviceIndex][0].c_str()); 849 | type = exthwUSBdata16; 850 | strcpy(name, HWNAME); 851 | strcpy(model, DeviceInfo[currentDeviceIndex][0].c_str()); 852 | 853 | return true; 854 | } 855 | //--------------------------------------------------------------------------- 856 | extern "C" 857 | bool EXTIO_API OpenHW(void) 858 | { 859 | if (InitializeLMS() != 0) 860 | return false; 861 | 862 | h_dialog = CreateDialog((HINSTANCE)&__ImageBase, MAKEINTRESOURCE(ExtioDialog), NULL, (DLGPROC)MainDlgProc); 863 | ShowWindow(h_dialog, SW_HIDE); 864 | 865 | buffer = new (std::nothrow) int16_t[EXT_BLOCKLEN * 2]; 866 | 867 | return true; 868 | } 869 | 870 | //--------------------------------------------------------------------------- 871 | extern "C" 872 | int EXTIO_API StartHW(long LOfreq) 873 | { 874 | int64_t ret = StartHW64((int64_t)LOfreq); 875 | return (int)ret; 876 | } 877 | //--------------------------------------------------------------------------- 878 | extern "C" 879 | int EXTIO_API StartHW64(int64_t LOfreq) 880 | { 881 | SetHWLO64(LOfreq); 882 | 883 | streamId.channel = channel; 884 | streamId.fifoSize = 1024 * 128; 885 | streamId.throughputVsLatency = 1; 886 | streamId.isTx = false; 887 | streamId.dataFmt = lms_stream_t::LMS_FMT_I16; 888 | 889 | if (LMS_SetupStream(device, &streamId) != LMS_SUCCESS) 890 | return -1; 891 | 892 | if (LMS_StartStream(&streamId) != LMS_SUCCESS) 893 | return -1; 894 | 895 | isRunning = true; 896 | 897 | thread_handle = (HANDLE)_beginthread(RecvThread, 0, NULL); 898 | SetThreadPriority(thread_handle, THREAD_PRIORITY_TIME_CRITICAL); 899 | 900 | return EXT_BLOCKLEN; 901 | } 902 | //--------------------------------------------------------------------------- 903 | extern "C" 904 | void EXTIO_API StopHW(void) 905 | { 906 | if (isRunning) { 907 | isRunning = false; 908 | 909 | WaitForSingleObject(thread_handle, INFINITE); 910 | thread_handle = INVALID_HANDLE_VALUE; 911 | 912 | LMS_StopStream(&streamId); 913 | LMS_DestroyStream(device, &streamId); 914 | } 915 | } 916 | //--------------------------------------------------------------------------- 917 | extern "C" 918 | void EXTIO_API CloseHW(void) 919 | { 920 | LMS_Close(device); 921 | delete buffer; 922 | DestroyWindow(h_dialog); 923 | } 924 | //--------------------------------------------------------------------------- 925 | extern "C" 926 | int EXTIO_API SetHWLO(long LOfreq) 927 | { 928 | int64_t ret = SetHWLO64((int64_t)LOfreq); 929 | return (ret & 0xFFFFFFFF); 930 | } 931 | //--------------------------------------------------------------------------- 932 | extern "C" 933 | int64_t EXTIO_API SetHWLO64(int64_t LOfreq) 934 | { 935 | int64_t ret = 0; 936 | float_type freq = float_type(LOfreq); 937 | if (LOfreq < 1e3) { 938 | freq = 1e3; 939 | ret = -1 * (1e3); 940 | } 941 | 942 | if (LOfreq > 3800e6) { 943 | freq = 3800e6; 944 | ret = 3800e6; 945 | } 946 | 947 | if (isRunning && freq < 30e6) { 948 | StopHW(); 949 | StartHW64(freq); 950 | } 951 | else { 952 | if (CurrentLOfreq != LOfreq) { 953 | isCalibrated = NotCalibrated; 954 | LMS_SetLOFrequency(device, LMS_CH_RX, channel, freq); 955 | 956 | 957 | UpdateDialog(); 958 | ExtIOCallback(-1, extHw_Changed_LO, 0, NULL); 959 | } 960 | } 961 | 962 | return ret; 963 | } 964 | //--------------------------------------------------------------------------- 965 | extern "C" 966 | int EXTIO_API GetStatus(void) 967 | { 968 | return 0; 969 | } 970 | //--------------------------------------------------------------------------- 971 | extern "C" 972 | void EXTIO_API SetCallback(pfnExtIOCallback funcptr) 973 | { 974 | ExtIOCallback = funcptr; 975 | return; 976 | } 977 | //--------------------------------------------------------------------------- 978 | extern "C" 979 | void EXTIO_API VersionInfo(const char * progname, int ver_major, int ver_minor) 980 | { 981 | return; 982 | } 983 | //--------------------------------------------------------------------------- 984 | extern "C" 985 | long EXTIO_API GetHWLO(void) 986 | { 987 | int64_t glLOfreq = GetHWLO64(); 988 | return (long)(glLOfreq & 0xFFFFFFFF); 989 | } 990 | //--------------------------------------------------------------------------- 991 | extern "C" 992 | int64_t EXTIO_API GetHWLO64(void) 993 | { 994 | float_type freq; 995 | LMS_GetLOFrequency(device, LMS_CH_RX, channel, &freq); 996 | freq = ceil(freq); 997 | CurrentLOfreq = int64_t(freq); 998 | return CurrentLOfreq; 999 | } 1000 | //--------------------------------------------------------------------------- 1001 | extern "C" 1002 | long EXTIO_API GetHWSR(void) 1003 | { 1004 | long SampleRate; 1005 | 1006 | if (device != nullptr) { 1007 | float_type freq; 1008 | 1009 | LMS_GetSampleRate(device, LMS_CH_RX, channel, &freq, nullptr); 1010 | 1011 | SampleRate = round(freq); 1012 | } 1013 | return SampleRate; 1014 | } 1015 | //--------------------------------------------------------------------------- 1016 | extern "C" 1017 | int EXTIO_API GetAttenuators(int atten_idx, float * attenuation) 1018 | { 1019 | if (atten_idx < 74) { 1020 | *attenuation = atten_idx; 1021 | return 0; 1022 | } 1023 | return -1; // Finished 1024 | } 1025 | //--------------------------------------------------------------------------- 1026 | extern "C" 1027 | int EXTIO_API GetActualAttIdx(void) 1028 | { 1029 | unsigned int _gain = 0; 1030 | 1031 | if (device != nullptr) { 1032 | if (LMS_GetGaindB(device, LMS_CH_RX, channel, &_gain) != LMS_SUCCESS) { 1033 | return -1; // ERROR 1034 | } 1035 | } 1036 | return _gain; 1037 | } 1038 | //--------------------------------------------------------------------------- 1039 | extern "C" 1040 | int EXTIO_API SetAttenuator(int atten_idx) 1041 | { 1042 | if (device != nullptr) { 1043 | if (LMS_SetGaindB(device, LMS_CH_RX, channel, atten_idx) != LMS_SUCCESS) { 1044 | return -1; // ERROR 1045 | } 1046 | isCalibrated = NotCalibrated; 1047 | UpdateDialog(); 1048 | } 1049 | return 0; 1050 | } 1051 | //--------------------------------------------------------------------------- 1052 | extern "C" 1053 | int EXTIO_API ExtIoGetSrates(int srate_idx, double * samplerate) 1054 | { 1055 | if (srate_idx < (sizeof(sampleRates) / sizeof(sampleRates[0]))) { 1056 | *samplerate = sampleRates[srate_idx]; 1057 | return 0; 1058 | } 1059 | else { 1060 | return -1; // Finished 1061 | } 1062 | } 1063 | //--------------------------------------------------------------------------- 1064 | extern "C" 1065 | int EXTIO_API ExtIoGetActualSrateIdx(void) 1066 | { 1067 | return sr_idx; 1068 | } 1069 | //--------------------------------------------------------------------------- 1070 | extern "C" 1071 | int EXTIO_API ExtIoSetSrate(int srate_idx) 1072 | { 1073 | if (srate_idx >= 0 && srate_idx < (sizeof(sampleRates) / sizeof(sampleRates[0]))) { 1074 | int64_t freq = 0; 1075 | 1076 | if (isRunning) { 1077 | freq = GetHWLO64(); 1078 | StopHW(); 1079 | } 1080 | 1081 | if (LMS_SetSampleRate(device, sampleRates[srate_idx], oversample) != LMS_SUCCESS) { 1082 | return -1; 1083 | } 1084 | 1085 | CalibrationBandwidth = LPFbandwidth = sampleRates[srate_idx]; 1086 | if (CalibrationBandwidth < 2.5e6) 1087 | CalibrationBandwidth = 2.5e6; 1088 | 1089 | if (LPFenable) 1090 | EnableLPF(); 1091 | 1092 | PerformCalibration(false); 1093 | 1094 | if (freq != 0) { 1095 | StartHW64(freq); 1096 | } 1097 | 1098 | sr_idx = srate_idx; 1099 | ExtIOCallback(-1, extHw_Changed_SampleRate, 0, NULL); 1100 | 1101 | UpdateDialog(); 1102 | return 0; 1103 | } 1104 | 1105 | return -1; // ERROR 1106 | } 1107 | //--------------------------------------------------------------------------- 1108 | extern "C" 1109 | int EXTIO_API ExtIoGetSetting(int idx, char * description, char * value) 1110 | { 1111 | 1112 | switch (idx) { 1113 | case 0: 1114 | snprintf(description, 1024, "%s", "HW Name"); 1115 | strcpy_s(value, 1024, lastUsedDeviceName); 1116 | return 0; 1117 | case 1: 1118 | snprintf(description, 1024, "%s", "Channel"); 1119 | snprintf(value, 1024, "%d", channel); 1120 | return 0; 1121 | case 2: 1122 | snprintf(description, 1024, "%s", "Antenna"); 1123 | snprintf(value, 1024, "%d", ant_select); 1124 | return 0; 1125 | case 3: 1126 | snprintf(description, 1024, "%s", "LPF bandwidth"); 1127 | snprintf(value, 1024, "%f", LPFbandwidth); 1128 | return 0; 1129 | case 4: 1130 | snprintf(description, 1024, "%s", "LPF enable"); 1131 | snprintf(value, 1024, "%d", LPFenable); 1132 | return 0; 1133 | case 5: 1134 | snprintf(description, 1024, "%s", "Srate index"); 1135 | snprintf(value, 1024, "%d", sr_idx); 1136 | return 0; 1137 | case 6: 1138 | snprintf(description, 1024, "%s", "LNA gain"); 1139 | snprintf(value, 1024, "%d", LNA); 1140 | return 0; 1141 | case 7: 1142 | snprintf(description, 1024, "%s", "TIA gain"); 1143 | snprintf(value, 1024, "%d", TIA); 1144 | return 0; 1145 | case 8: 1146 | snprintf(description, 1024, "%s", "PGA gain"); 1147 | snprintf(value, 1024, "%d", PGA); 1148 | return 0; 1149 | case 9: 1150 | snprintf(description, 1024, "%s", "Current Device index"); 1151 | snprintf(value, 1024, "%d", currentDeviceIndex); 1152 | return 0; 1153 | case 10: 1154 | snprintf(description, 1024, "%s", "Calibration bandwidth"); 1155 | snprintf(value, 1024, "%f", CalibrationBandwidth); 1156 | return 0; 1157 | case 11: 1158 | snprintf(description, 1024, "%s", "Current LO frequency"); 1159 | snprintf(value, 1024, "%lld", CurrentLOfreq); 1160 | return 0; 1161 | default: return -1; // ERROR 1162 | } 1163 | return -1; // ERROR 1164 | } 1165 | //--------------------------------------------------------------------------- 1166 | extern "C" 1167 | void EXTIO_API ExtIoSetSetting(int idx, const char * value) 1168 | { 1169 | int tempInt; 1170 | int64_t temp64Int; 1171 | float_type tempFloat; 1172 | switch (idx) { 1173 | case 0: 1174 | strcpy(lastUsedDeviceName, value); 1175 | return; 1176 | case 1: 1177 | tempInt = atoi(value); 1178 | 1179 | if (tempInt >= 0 && tempInt < 2) { 1180 | channel = tempInt; 1181 | } 1182 | return; 1183 | case 2: 1184 | tempInt = atoi(value); 1185 | 1186 | if (tempInt >= 0 && tempInt < 4) { 1187 | ant_select = tempInt; 1188 | } 1189 | return; 1190 | case 3: 1191 | tempFloat = atof(value); 1192 | 1193 | if (tempFloat > 1.4e6 && tempFloat <= 130e6) { 1194 | LPFbandwidth = tempFloat; 1195 | } 1196 | return; 1197 | case 4: 1198 | tempInt = atoi(value); 1199 | 1200 | if (tempInt == 0 || tempInt == 1) { 1201 | LPFenable = tempInt; 1202 | } 1203 | return; 1204 | case 5: 1205 | tempInt = atoi(value); 1206 | 1207 | if (tempInt >= 0 && tempInt < (sizeof(sampleRates) / sizeof(sampleRates[0]))) { 1208 | sr_idx = tempInt; 1209 | } 1210 | return; 1211 | case 6: 1212 | tempInt = atoi(value); 1213 | 1214 | if (tempInt > 0 && tempInt < 16) { 1215 | LNA = tempInt; 1216 | } 1217 | return; 1218 | case 7: 1219 | tempInt = atoi(value); 1220 | 1221 | if (tempInt > 0 && tempInt < 4) { 1222 | TIA = tempInt; 1223 | } 1224 | return; 1225 | case 8: 1226 | tempInt = atoi(value); 1227 | 1228 | if (tempInt >= 0 && tempInt < 32) { 1229 | PGA = tempInt; 1230 | } 1231 | return; 1232 | case 9: 1233 | currentDeviceIndex = atoi(value); 1234 | return; 1235 | case 10: 1236 | tempFloat = atof(value); 1237 | 1238 | if (tempFloat >= 2.5e6 && tempFloat <= 120e6) { 1239 | CalibrationBandwidth = tempFloat; 1240 | } 1241 | return; 1242 | case 11: 1243 | temp64Int = _atoi64(value); 1244 | 1245 | if (temp64Int > 1e3 && temp64Int <= 3800e6) { 1246 | CurrentLOfreq = temp64Int; 1247 | } 1248 | return; 1249 | default: return; 1250 | } 1251 | } 1252 | //--------------------------------------------------------------------------- 1253 | extern "C" 1254 | void EXTIO_API ShowGUI() 1255 | { 1256 | ShowWindow(h_dialog, SW_SHOW); 1257 | return; 1258 | } 1259 | //--------------------------------------------------------------------------- 1260 | extern "C" 1261 | void EXTIO_API HideGUI() 1262 | { 1263 | ShowWindow(h_dialog, SW_HIDE); 1264 | return; 1265 | } 1266 | //--------------------------------------------------------------------------- 1267 | extern "C" 1268 | void EXTIO_API SwitchGUI() 1269 | { 1270 | if (IsWindowVisible(h_dialog)) 1271 | ShowWindow(h_dialog, SW_HIDE); 1272 | else 1273 | ShowWindow(h_dialog, SW_SHOW); 1274 | return; 1275 | } 1276 | //--------------------------------------------------------------------------- -------------------------------------------------------------------------------- /src/ExtIO_LimeSDR.def: -------------------------------------------------------------------------------- 1 | LIBRARY ExtIO_LimeSDR.DLL 2 | 3 | EXPORTS 4 | InitHW = _InitHW@12 5 | OpenHW = _OpenHW@0 6 | StartHW = _StartHW@4 7 | StartHW64 = _StartHW64@8 8 | StopHW = _StopHW@0 9 | CloseHW = _CloseHW@0 10 | SetHWLO = _SetHWLO@4 11 | GetStatus = _GetStatus@0 12 | SetCallback = _SetCallback@4 13 | 14 | GetHWLO = _GetHWLO@0 15 | GetHWSR = _GetHWSR@0 16 | 17 | ShowGUI = _ShowGUI@0 18 | HideGUI = _HideGUI@0 19 | 20 | VersionInfo = _VersionInfo@12 21 | 22 | GetAttenuators = _GetAttenuators@8 23 | GetActualAttIdx = _GetActualAttIdx@0 24 | SetAttenuator = _SetAttenuator@4 25 | 26 | ; 64 Bit: 27 | 28 | SetHWLO64 = _SetHWLO64@8 29 | GetHWLO64 = _GetHWLO64@0 30 | 31 | ; Samplerate / Bandwidth: 32 | ExtIoGetSrates = _ExtIoGetSrates@8 33 | ExtIoGetActualSrateIdx = _ExtIoGetActualSrateIdx@0 34 | ExtIoSetSrate = _ExtIoSetSrate@4 35 | 36 | ; Settings 37 | ExtIoGetSetting = _ExtIoGetSetting@12 38 | ExtIoSetSetting = _ExtIoSetSetting@8 39 | 40 | -------------------------------------------------------------------------------- /src/ExtIO_LimeSDR.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License 3 | 4 | Copyright(c) 2018 Lime Microsystems Ltd 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files(the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions : 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE 23 | */ 24 | #ifdef EXTIO_EXPORTS 25 | #define EXTIO_API __declspec(dllexport) __stdcall 26 | #else 27 | #define EXTIO_API __declspec(dllimport) 28 | #endif 29 | 30 | #include "LC_ExtIO_Types.h" 31 | 32 | #define ExtIO_LimeSDR_VERSION @ExtIO_LimeSDR_VERSION@ 33 | 34 | extern "C" bool EXTIO_API InitHW(char *name, char *model, int& type); 35 | extern "C" int EXTIO_API StartHW64(int64_t freq); 36 | extern "C" bool EXTIO_API OpenHW(void); 37 | extern "C" int EXTIO_API StartHW(long freq); 38 | extern "C" void EXTIO_API StopHW(void); 39 | extern "C" void EXTIO_API CloseHW(void); 40 | 41 | extern "C" int EXTIO_API SetHWLO(long LOfreq); 42 | extern "C" int64_t EXTIO_API SetHWLO64(int64_t LOfreq); 43 | extern "C" long EXTIO_API GetHWLO(void); 44 | extern "C" int64_t EXTIO_API GetHWLO64(void); 45 | extern "C" long EXTIO_API GetHWSR(void); 46 | 47 | extern "C" int EXTIO_API GetStatus(void); 48 | extern "C" void EXTIO_API SetCallback(pfnExtIOCallback funcptr); 49 | 50 | extern "C" void EXTIO_API VersionInfo(const char * progname, int ver_major, int ver_minor); 51 | extern "C" int EXTIO_API GetAttenuators(int idx, float * attenuation); // fill in attenuation 52 | // use positive attenuation levels if signal is amplified (LNA) 53 | // use negative attenuation levels if signal is attenuated 54 | // sort by attenuation: use idx 0 for highest attenuation / most damping 55 | // this functions is called with incrementing idx 56 | // - until this functions return != 0 for no more attenuator setting 57 | extern "C" int EXTIO_API GetActualAttIdx(void); // returns -1 on error 58 | extern "C" int EXTIO_API SetAttenuator(int idx); // returns != 0 on error 59 | 60 | extern "C" int EXTIO_API ExtIoGetSrates(int idx, double * samplerate); // fill in possible samplerates 61 | extern "C" int EXTIO_API ExtIoGetActualSrateIdx(void); // returns -1 on error 62 | extern "C" int EXTIO_API ExtIoSetSrate(int idx); // returns != 0 on error 63 | extern "C" int EXTIO_API ExtIoGetSetting( int idx, char * description, char * value ); // will be called (at least) before exiting application 64 | extern "C" void EXTIO_API ExtIoSetSetting( int idx, const char * value ); // before calling InitHW() !!! 65 | 66 | extern "C" void EXTIO_API ShowGUI(); 67 | extern "C" void EXTIO_API HideGUI(); 68 | extern "C" void EXTIO_API SwitchGUI(); 69 | 70 | -------------------------------------------------------------------------------- /src/ExtIO_LimeSDR.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/ExtIO_LimeSDR/47a2759bc47552495fe1001911569c6b8baa0282/src/ExtIO_LimeSDR.rc -------------------------------------------------------------------------------- /src/LC_ExtIO_Types.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myriadrf/ExtIO_LimeSDR/47a2759bc47552495fe1001911569c6b8baa0282/src/LC_ExtIO_Types.h -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by ExtIO_LimeSDR.rc 4 | // 5 | #define ExtioDialog 9 6 | #define IDC_COMBO_ANT 1001 7 | #define IDC_COMBO_CHAN 1010 8 | #define IDC_COMBO_DEVICE 1011 9 | #define IDC_BUTTON_CAl 1015 10 | #define IDC_ALPF_BW 1016 11 | #define IDC_BUTTON_SET 1018 12 | #define IDC_CHECK_ALPF 1020 13 | #define IDC_BUTTON_DEFAULT 1021 14 | #define IDC_CHECK_ALPF2 1022 15 | #define IDC_BUTTON_DEBUG 1027 16 | #define IDC_CAL_BW 1028 17 | #define IDC_RADIO1 1029 18 | #define IDC_SLIDER_LNA 1030 19 | #define IDC_SLIDER_TIA 1031 20 | #define IDC_SLIDER_PGA 1032 21 | #define IDC_TEXT_LNA 1033 22 | #define IDC_TEXT_TIA 1034 23 | #define IDC_TEXT_PGA 1035 24 | #define IDC_TEXT_LIBVER 1036 25 | #define IDC_TEXT_CALIBRATED 1042 26 | #define IDC_TEXT_EXTVER 1043 27 | 28 | // Next default values for new objects 29 | // 30 | #ifdef APSTUDIO_INVOKED 31 | #ifndef APSTUDIO_READONLY_SYMBOLS 32 | #define _APS_NEXT_RESOURCE_VALUE 103 33 | #define _APS_NEXT_COMMAND_VALUE 40001 34 | #define _APS_NEXT_CONTROL_VALUE 1045 35 | #define _APS_NEXT_SYMED_VALUE 101 36 | #endif 37 | #endif 38 | --------------------------------------------------------------------------------