...
 
Commits (34)
Release 19.04.1 (pending)
Release 20.01.0 (pending)
==========================
LimeSuite library changes:
- Including LimeRFE support
- Update CGEN calculation to allow lower CGEN values
- Configure RF switches (when possible) to avoid transmission during calibration
- Automatically reconfigure GFIR LPF after sample rate change
......@@ -22,6 +23,7 @@ SoapyLMS:
- Automatically use wide enough bandwidth setting for RF frequencies bellow 30 MHz
- Remove master clock setting
- Add setting descriptions
- Implement read for setting advertised by getSettingInfo()
LimeSuiteGUI:
- Add panel for LMS API function testing
......@@ -36,7 +38,6 @@ Octave plugin:
Other changes:
- Fix LimeQuickTest not outputing to windows command line
Release 19.04.0 (2019-05-09)
==========================
......
......@@ -937,7 +937,8 @@ void SoapyLMS7::writeSetting(const int direction, const size_t channel, const st
if (key == "TSP_CONST")
{
const auto ampl = std::stoi(value);
lms7Device->SetTestSignal(isTx, channel, LMS_TESTSIG_DC, ampl, 0);
lms7Device->SetTestSignal(isTx, channel, LMS_TESTSIG_DC, ampl, ampl);
mChannels[direction].at(channel).tst_dc = ampl;
}
else if (key == "CALIBRATE_TX" or (isTx and key == "CALIBRATE"))
......@@ -947,6 +948,7 @@ void SoapyLMS7::writeSetting(const int direction, const size_t channel, const st
if (lms7Device->Calibrate(true, channel, bw, 0)!=0)
throw std::runtime_error(lime::GetLastErrorMessage());
_channelsToCal.erase(std::make_pair(direction, channel));
mChannels[direction].at(channel).cal_bw = bw;
}
else if (key == "CALIBRATE_RX" or (not isTx and key == "CALIBRATE"))
......@@ -956,6 +958,7 @@ void SoapyLMS7::writeSetting(const int direction, const size_t channel, const st
if (lms7Device->Calibrate(false, channel, bw, 0)!=0)
throw std::runtime_error(lime::GetLastErrorMessage());
_channelsToCal.erase(std::make_pair(direction, channel));
mChannels[direction].at(channel).cal_bw = bw;
}
else if (key == "ENABLE_GFIR_LPF")
......@@ -963,12 +966,14 @@ void SoapyLMS7::writeSetting(const int direction, const size_t channel, const st
double bw = std::stof(value);
SoapySDR::logf(SOAPY_SDR_INFO, "Configurate GFIR LPF %f", bw);
lms7Device->ConfigureGFIR(isTx, channel, true, bw);
mChannels[direction].at(channel).gfir_bw = bw;
}
else if (key == "DISABLE_GFIR_LPF")
{
SoapySDR::logf(SOAPY_SDR_INFO, "Disable GFIR LPF");
lms7Device->ConfigureGFIR(isTx, channel, false, 0.0);
mChannels[direction].at(channel).gfir_bw = -1;
}
else if (key == "TSG_NCO")
......@@ -1003,12 +1008,31 @@ void SoapyLMS7::writeSetting(const int direction, const size_t channel, const st
std::string SoapyLMS7::readSetting(const std::string &key) const
{
if (key == "SAVE_CONFIG" || key == "LOAD_CONFIG")
return "";
if (key == "OVERSAMPLING")
return std::to_string(oversampling);
return readSetting(SOAPY_SDR_TX, 0, key);
}
std::string SoapyLMS7::readSetting(const int direction, const size_t channel, const std::string &key) const
{
std::unique_lock<std::recursive_mutex> lock(_accessMutex);
if (key == "TSG_NCO")
{
switch (lms7Device->GetTestSignal(direction == SOAPY_SDR_TX, channel))
{
case LMS_TESTSIG_NCODIV4F: return "4";
case LMS_TESTSIG_NCODIV8F: return "8";
default: return "-1";
}
}
if (key == "ENABLE_GFIR_LPF")
return std::to_string(mChannels[direction].at(channel).gfir_bw);
if (key == "CALIBRATE")
return std::to_string(mChannels[direction].at(channel).cal_bw);
if (key == "TSP_CONST")
return std::to_string(mChannels[direction].at(channel).tst_dc);
int val = lms7Device->ReadParam(key,channel);
if ( val !=-1)
return std::to_string(val);
......
......@@ -131,7 +131,7 @@ public:
std::complex<double> getDCOffset(const int direction, const size_t channel) const;
bool hasIQBalance(const int direction, const size_t channel) const;
void setIQBalance(const int direction, const size_t channel, const std::complex<double> &balance);
std::complex<double> getIQBalance(const int direction, const size_t channel) const;
......@@ -143,7 +143,7 @@ public:
std::vector<std::string> listGains(const int direction, const size_t channel) const;
void setGain(const int direction, const size_t channel, const double value) override;
double getGain(const int direction, const size_t channel) const;
void setGain(const int direction, const size_t channel, const std::string &name, const double value);
......@@ -165,7 +165,7 @@ public:
void setFrequency(const int direction, const size_t channel, const std::string &name, const double frequency, const SoapySDR::Kwargs &args = SoapySDR::Kwargs());
double getFrequency(const int direction, const size_t channel, const std::string &name) const;
double getFrequency(const int direction, const size_t channel) const override;
std::vector<std::string> listFrequencies(const int direction, const size_t channel) const;
......@@ -256,9 +256,9 @@ public:
SoapySDR::ArgInfoList getSettingInfo(const int direction, const size_t channel) const;
void writeSetting(const int direction, const size_t channel, const std::string &key, const std::string &value);
std::string readSetting(const std::string &key) const;
std::string readSetting(const int direction, const size_t channel, const std::string &key) const;
/*******************************************************************
......@@ -276,16 +276,19 @@ public:
unsigned readGPIODir(const std::string &bank) const;
private:
struct Channel{
Channel():freq(-1),bw(-1),rf_bw(-1){};
Channel():freq(-1),bw(-1),rf_bw(-1),cal_bw(-1),gfir_bw(-1),tst_dc(0){};
double freq;
double bw;
double rf_bw;
double cal_bw;
double gfir_bw;
int tst_dc;
};
int setBBLPF(bool direction, size_t channel, double bw);
const SoapySDR::Kwargs _deviceArgs; //!< stash of constructor arguments
const std::string _moduleName;
lime::LMS7_Device * lms7Device;
......
......@@ -223,7 +223,9 @@ int SoapyLMS7::activateStream(
bool dir = _channelsToCal.begin()->first;
auto ch = _channelsToCal.begin()->second;
auto bw = mChannels[dir].at(ch).rf_bw > 0 ? mChannels[dir].at(ch).rf_bw : sampleRate[dir];
lms7Device->Calibrate(dir== SOAPY_SDR_TX, ch, bw>2.5e6 ? bw : 2.5e6, 0);
bw = bw>2.5e6 ? bw : 2.5e6;
lms7Device->Calibrate(dir== SOAPY_SDR_TX, ch, bw, 0);
mChannels[dir].at(ch).cal_bw = bw;
_channelsToCal.erase(_channelsToCal.begin());
}
//stream requests used with rx
......
limesuite (20.01.0-1) unstable; urgency=low
* Release 20.01.0 (2020-01-28)
-- Lime Microsystems <[email protected]> Thu, 28 Feb 2020 15:00:00 +0300
limesuite (19.04.0-1) unstable; urgency=low
* Release 19.04.0 (2019-05-09)
......
......@@ -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.04-1
Package: liblimesuite20.01-1
Section: libs
Architecture: any
Multi-Arch: same
......@@ -30,7 +30,7 @@ Package: liblimesuite-dev
Section: libdevel
Architecture: any
Depends:
liblimesuite19.04-1 (= ${binary:Version}),
liblimesuite20.01-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.04-1 (= ${binary:Version}),
liblimesuite20.01-1 (= ${binary:Version}),
${shlibs:Depends},
${misc:Depends},
xdg-utils
......@@ -59,7 +59,7 @@ Section: comm
Architecture: any
Multi-Arch: same
Depends:
liblimesuite19.04-1 (= ${binary:Version}),
liblimesuite20.01-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.04
Package: limesuite-images20.01
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.04
Depends: ${shlibs:Depends}, ${misc:Depends}, limesuite-images20.01
Description: Lime Suite - Install firmware and gateware images
Lime Suite application software.
.
......
......@@ -13,13 +13,14 @@ LMS API is a set of C functions that are exported by LimeSuite library. Its main
/*! \page page_changelog Changelog
### v19.04.1
### v20.01.0
\li Remove LMS_EnableCalibCache() function
\li Fixed \ref lms_stream_t::throughputVsLatency setting not working for Tx streams
\li Added automatic reconfiguration of GFIR when sample rate is changed after calling LMS_SetGFIRLPF()
\li Added \ref LMS_ALIGN_CH_PHASE option to run Rx phase alignment for MIMO configuration
\li Fixed RF path being auto-set after it was explicitly selected for LimeSDR-Mini
\li Added log level definition \ref LMS_LOG_CRITICAL
### v19.04.0
......
......@@ -9,6 +9,7 @@
#include "Logger.h"
#include "LMS64CProtocol.h"
#include "Streamer.h"
#include "../limeRFE/RFE_Device.h"
using namespace std;
......@@ -311,7 +312,11 @@ API_EXPORT int CALL_CONV LMS_GetNumChannels(lms_device_t * device, bool dir_tx)
API_EXPORT int CALL_CONV LMS_SetLOFrequency(lms_device_t *device, bool dir_tx, size_t chan, float_type frequency)
{
lime::LMS7_Device* lms = CheckDevice(device, chan);
return lms ? lms->SetFrequency(dir_tx, chan,frequency) : -1;
int ret = lms ? lms->SetFrequency(dir_tx, chan,frequency) : -1;
auto rfe = lms->GetLimeRFE();
if (rfe && ret == 0)
rfe->SetFrequency(dir_tx, chan, frequency);
return ret;
}
API_EXPORT int CALL_CONV LMS_GetLOFrequency(lms_device_t *device, bool dir_tx, size_t chan, float_type *frequency)
......@@ -473,8 +478,13 @@ API_EXPORT int CALL_CONV LMS_Calibrate(lms_device_t *device, bool dir_tx, size_t
lime::LMS7_Device* lms = CheckDevice(device, chan);
if (!lms)
return -1;
return lms->Calibrate(dir_tx, chan, bw, flags);
auto rfe = lms->GetLimeRFE();
if (rfe)
rfe->OnCalibrate(chan, false);
int ret = lms->Calibrate(dir_tx, chan, bw, flags);
if (rfe)
rfe->OnCalibrate(chan, true);
return ret;
}
API_EXPORT int CALL_CONV LMS_LoadConfig(lms_device_t *device, const char *filename)
......@@ -950,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
......@@ -70,7 +70,7 @@ LMS7_Device* LMS7_Device::CreateDevice(const lime::ConnectionHandle& handle, LMS
return device;
}
LMS7_Device::LMS7_Device(LMS7_Device *obj) : connection(nullptr), lms_chip_id(0),fpga(nullptr)
LMS7_Device::LMS7_Device(LMS7_Device *obj) : connection(nullptr), lms_chip_id(0),fpga(nullptr), limeRFE(nullptr)
{
if (obj != nullptr)
{
......@@ -1663,9 +1663,12 @@ int LMS7_Device::LoadConfig(const char *filename, int ind)
if (!lms->Get_SPI_Reg_bits(LMS7param(PD_VCO)))
lms->SetFrequencySX(true, lms->GetFrequencySX(true));
if (!lms->Get_SPI_Reg_bits(LMS7param(PD_VCO_CGEN)))
{
lms->TuneVCO(lime::LMS7002M::VCO_CGEN);
lms->Modify_SPI_Reg_bits(LMS7param(MAC),1,true);
return SetFPGAInterfaceFreq(-1, -1, -1000, -1000);
lms->Modify_SPI_Reg_bits(LMS7param(MAC),1,true);
return SetFPGAInterfaceFreq(-1, -1, -1000, -1000);
}
return 0;
}
return -1;
}
......@@ -1839,4 +1842,13 @@ int LMS7_Device::MCU_AGCStop()
return 0;
}
RFE_Device* LMS7_Device::GetLimeRFE() const
{
return limeRFE;
}
void LMS7_Device::SetLimeRFE(RFE_Device* dev)
{
limeRFE = dev;
}
}//namespace lime
......@@ -14,6 +14,8 @@
#include "Streamer.h"
#include "IConnection.h"
class RFE_Device;
namespace lime
{
class LIME_API LMS7_Device
......@@ -96,6 +98,9 @@ public:
int MCU_AGCStart(uint32_t wantedRSSI);
int MCU_AGCStop();
RFE_Device* GetLimeRFE() const;
void SetLimeRFE(RFE_Device* dev);
protected:
struct ChannelInfo
......@@ -117,6 +122,7 @@ protected:
unsigned lms_chip_id;
std::vector<lime::Streamer*> mStreamers;
lime::FPGA* fpga;
RFE_Device* limeRFE;
};
}
......
......@@ -26,6 +26,7 @@ set(LIME_SUITE_PUBLIC_HEADERS
Si5351C/Si5351C.h
FPGA_common/FPGA_common.h
API/lms7_device.h
limeRFE/limeRFE.h
)
include(FeatureSummary)
......@@ -75,6 +76,9 @@ set(LIME_SUITE_SOURCES
FPGA_common/FPGA_Mini.cpp
FPGA_common/FPGA_Q.cpp
windowFunction.cpp
limeRFE/limeRFE_cmd.cpp
limeRFE/limeRFE_api.cpp
limeRFE/RFE_Device.cpp
)
set(LIME_SUITE_INCLUDES
......@@ -92,8 +96,14 @@ set(LIME_SUITE_INCLUDES
lms7002m_mcu
${PROJECT_SOURCE_DIR}/external/cpp-feather-ini-parser
${PROJECT_SOURCE_DIR}/external/kissFFT/
limeRFE
)
if(MSVC)
list(APPEND LIME_SUITE_SOURCES limeRFE/external/termiWin/termiWin.c)
list(APPEND LIME_SUITE_INCLUDES limeRFE/external/termiWin)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/VersionInfo.in.cpp
${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.cpp @ONLY)
list(APPEND LIME_SUITE_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.cpp)
......@@ -230,8 +240,15 @@ set(LMS7SUITE_GUI_SOURCES
boards_wxgui/pnlLimeSDR.cpp
boards_wxgui/pnlGPIO.cpp
boards_wxgui/pnl5G.cpp
limeRFE/limeRFE_gui.cpp
limeRFE/limeRFE_wxgui.cpp
limeRFE/limeRFE_cmd.cpp
)
if(MSVC)
list(APPEND LMS7SUITE_GUI_SOURCES limeRFE/external/termiWin/termiWin.c)
endif()
include(FeatureSummary)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_GUI "Enable build GUI" ON "ENABLE_LIBRARY;wxWidgets_FOUND" OFF)
......@@ -247,6 +264,8 @@ if (ENABLE_GUI)
include_directories(fftviewer_wxgui)
include_directories(lms7suiteEvents)
include_directories(boards_wxgui)
include_directories(limeRFE)
include(${wxWidgets_USE_FILE})
add_subdirectory(oglGraph)
......@@ -255,6 +274,8 @@ if (ENABLE_GUI)
add_executable(LimeSuiteGUI ${LMS7SUITE_GUI_SOURCES} resources/resource.rc)
set_target_properties(LimeSuiteGUI PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${BINARY_OUTPUT_DIR})
target_compile_definitions(LimeSuiteGUI PRIVATE WIN32_LEAN_AND_MEAN)
target_link_libraries(LimeSuiteGUI LimeSuite oglGraph ${wxWidgets_LIBRARIES})
if (MSVC)
......
......@@ -389,7 +389,11 @@ int ConnectionFX3::Read(unsigned char *buffer, const int length, int timeout_ms)
if(bulkCtrlAvailable && bulkCtrlInProgress)
{
int actual = 0;
libusb_bulk_transfer(dev_handle, ctrlBulkInAddr, buffer, len, &actual, timeout_ms);
int r = libusb_bulk_transfer(dev_handle, ctrlBulkInAddr, buffer, len, &actual, timeout_ms);
if (r == LIBUSB_ERROR_TIMEOUT) {
/* fix a bug in the kernel with AMD chipsets -- see myriadrf/LimeSuite#287 */
libusb_bulk_transfer(dev_handle, ctrlBulkInAddr, buffer, len, &actual, timeout_ms);
}
len = actual;
bulkCtrlInProgress = false;
}
......
......@@ -7,13 +7,11 @@ using namespace std;
using namespace lime;
static const char* rd_ep_names[] = { "/dev/litepcie_read0", "/dev/litepcie_read1", "/dev/litepcie_read2"};
static const char* wr_ep_names[] = { "/dev/litepcie_write0", "/dev/litepcie_write1", "/dev/litepcie_write2"};
ConnectionLitePCIe::ConnectionLitePCIe(const char* control_ep) :
ConnectionLitePCIe::ConnectionLitePCIe(const std::string device_addr) :
isConnected(true)
{
control_fd = open(control_ep, O_RDWR);
deviceConfig.control_name = device_addr + "_control";
control_fd = open(deviceConfig.control_name.c_str(), O_RDWR);
if (control_fd<0)
{
isConnected = false;
......@@ -21,7 +19,11 @@ ConnectionLitePCIe::ConnectionLitePCIe(const char* control_ep) :
return;
}
for (int i = 0; i < MAX_EP_CNT; i++)
{
deviceConfig.rd_ep_name[i] = device_addr + "_read" + std::to_string(i);
deviceConfig.wr_ep_name[i] = device_addr + "_write" + std::to_string(i);
rd_ep_fd[i] = wr_ep_fd[i] = -1;
}
}
ConnectionLitePCIe::~ConnectionLitePCIe()
......@@ -73,7 +75,7 @@ int ConnectionLitePCIe::ReceiveData(char *buffer, int length, int epIndex, int t
{
if (rd_ep_fd[epIndex] == -1)
{
if ((rd_ep_fd[epIndex] = open(rd_ep_names[epIndex], O_RDONLY | O_NOCTTY | O_NONBLOCK))==-1)
if ((rd_ep_fd[epIndex] = open(deviceConfig.rd_ep_name[epIndex].c_str(), O_RDONLY | O_NOCTTY | O_NONBLOCK))==-1)
{
lime::error("open read endpoint failed");
return 0;
......@@ -117,7 +119,7 @@ int ConnectionLitePCIe::SendData(const char *buffer, int length, int epIndex, in
{
if (wr_ep_fd[epIndex] == -1)
{
if ((wr_ep_fd[epIndex] = open(wr_ep_names[epIndex], O_WRONLY | O_NOCTTY | O_NONBLOCK))==-1)
if ((wr_ep_fd[epIndex] = open(deviceConfig.wr_ep_name[epIndex].c_str(), O_WRONLY | O_NOCTTY | O_NONBLOCK))==-1)
{
lime::error("open write endpoint failed");
return 0;
......
......@@ -10,7 +10,7 @@ namespace lime{
class ConnectionLitePCIe : public LMS64CProtocol
{
public:
ConnectionLitePCIe(const char* control_ep);
ConnectionLitePCIe(const std::string device_addr);
~ConnectionLitePCIe(void);
bool IsOpen();
......@@ -36,7 +36,17 @@ protected:
void AbortSending(int epIndex) override;
private:
friend class ConnectionLitePCIeEntry;
static const int MAX_EP_CNT = 3;
static const int MAX_DEV_CNT = 4;
struct EPConfig
{
std::string control_name;
std::string rd_ep_name[MAX_EP_CNT];
std::string wr_ep_name[MAX_EP_CNT];
} deviceConfig;
int control_fd;
int rd_ep_fd[MAX_EP_CNT];
int wr_ep_fd[MAX_EP_CNT];
......
......@@ -10,8 +10,6 @@
using namespace lime;
#include <fstream>
static const char* control_name = "/dev/litepcie_control";
//! make a static-initialized entry in the registry
void __loadConnectionLitePCIeEntry(void) //TODO fixme replace with LoadLibrary/dlopen
{
......@@ -32,17 +30,37 @@ std::vector<ConnectionHandle> ConnectionLitePCIeEntry::enumerate(const Connectio
std::vector<ConnectionHandle> handles;
ConnectionHandle handle;
handle.media = "PCI-E";
if(access(control_name, F_OK ) != -1 )
int n_qpcie = 0;
int n_pcie = 0;
for(int i = 0; i < ConnectionLitePCIe::MAX_DEV_CNT; i++)
{
handle.name = "LitePCIe";
handle.index = 0;
handles.push_back(handle);
std::string device_addr = "/dev/litepcie" + std::to_string(i);
std::string control_name = device_addr + "_control";
if(access(control_name.c_str(), F_OK ) != -1 )
{
if (hint.index < 0 || hint.index == i)
{
std::string ep = device_addr + "_read2";
if(access(ep.c_str(), F_OK) != -1)
{
handle.name = "LimeSDR-QPCIe" + ((n_qpcie>0) ? " (" + std::to_string(n_qpcie) + ")" : "");
n_qpcie++;
}
else
{
handle.name = "LimeSDR-PCIe" + ((n_pcie>0) ? " (" + std::to_string(n_pcie) + ")" : "");
n_pcie++;
}
handle.index = i;
handle.addr = device_addr;
handles.push_back(handle);
}
}
}
return handles;
}
IConnection *ConnectionLitePCIeEntry::make(const ConnectionHandle &handle)
{
return new ConnectionLitePCIe(control_name);
return new ConnectionLitePCIe(handle.addr);
}
......@@ -24,7 +24,7 @@
* #endif
* \endcode
*/
#define LIME_SUITE_API_VERSION 0x20190100
#define LIME_SUITE_API_VERSION 0x20200100
namespace lime
{
......
This diff is collapsed.
#pragma once
#include "lime/LimeSuite.h"
#include <map>
#include <wx/panel.h>
#include <wx/choice.h>
class wxStaticText;
class wxFlexGridSizer;
class wxCheckBox;
class pnlCoreSDR5G : public wxPanel
{
public:
pnlCoreSDR5G(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, int style = 0, wxString name = wxEmptyString);
void Initialize(lms_device_t *pControl);
virtual ~pnlCoreSDR5G();
virtual void UpdatePanel();
void OnReadAll(wxCommandEvent &event);
void OnWriteAll(wxCommandEvent &event);
protected:
void OnLoopbackChange(wxCommandEvent &event);
void OnLoopbackChange2(wxCommandEvent &event);
wxChoice* cmbRx1Path;
wxChoice* cmbTx1Path;
wxCheckBox* tx11En;
wxCheckBox* tx12En;
wxCheckBox* tx2En;
wxChoice* cmbTRx1Path;
wxChoice* cmbTRx2Path;
wxChoice* cmbRx2Path;
wxChoice* cmbRxPathAB;
wxChoice* cmbTx2Path;
wxCheckBox* lnaByp;
wxChoice* cmbRx1Path2;
wxChoice* cmbTx1Path2;
wxChoice* cmbTRx1Path2;
wxChoice* cmbTRx2Path2;
wxChoice* cmbRx2Path2;
wxChoice* cmbTx2Path2;
wxCheckBox* lnaByp2;
wxCheckBox* tx11En2;
wxCheckBox* tx12En2;
wxCheckBox* tx2En2;
lms_device_t *lmsControl;
DECLARE_EVENT_TABLE()
};
......@@ -34,5 +34,14 @@ add_executable(basicTX basicTX.cpp)
set_target_properties(basicTX PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
target_link_libraries(basicTX LimeSuite)
add_executable(limeRFE_USB_example limeRFE_USB_example.cpp)
set_target_properties(limeRFE_USB_example PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
target_link_libraries(limeRFE_USB_example LimeSuite)
add_executable(limeRFE_I2C_example limeRFE_I2C_example.cpp)
set_target_properties(limeRFE_I2C_example PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
target_link_libraries(limeRFE_I2C_example LimeSuite)
add_executable(limeRFE_ADC_example limeRFE_ADC_example.cpp)
set_target_properties(limeRFE_ADC_example PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
target_link_libraries(limeRFE_ADC_example LimeSuite)
\ No newline at end of file
/**
@file limeRFE_ADC_example.cpp
@author Lime Microsystems (www.limemicro.com)
@brief LimeRFE ADC read example
*/
#include <lime/LimeSuite.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <stdio.h>
#include <cmath>
#include "limeRFE.h"
int openPort(char* portName);
void closePort(int fd);
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("Error: Wrong number of parameters\n");
printf("Usage: limeRFE_ADC_test <LimeRFE COM port>\n");
printf("Example: limeRFE_ADC_test COM3\n");
exit(1);
}
//Open port
rfe_dev_t* rfe = RFE_Open(argv[1], nullptr);
if (rfe == nullptr) {
std::cout << "Open device failed" << std::endl;
return -1;
}
else {
std::cout << "Port opened" << std::endl;
}
//This example uses RFE_ConfigureState API function. It is possible to use RFE_Configure API function, as illustrated in other LimeRFE examples.
//Configure LimeRFE to use channel HAM 2m channel in TX mode.
//RX and TX port is J3.
//Notch is off. Attenuation is 0.
//SWR is enabled. SWR source is external (signals from the external coupler are provided, FWD to J18, and REV to J17).
rfe_boardState state;
state.channelIDRX = RFE_CID_HAM_0145;
state.channelIDTX = RFE_CID_HAM_0145;
state.selPortRX = RFE_PORT_1;
state.selPortTX = RFE_PORT_1;
state.mode = RFE_MODE_TX;
state.notchOnOff = RFE_NOTCH_OFF;
state.attValue = 0;
state.enableSWR = RFE_SWR_ENABLE;
state.sourceSWR = RFE_SWR_SRC_EXT;
RFE_ConfigureState(rfe, state);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
int adc1, adc2;
double vADC1, vADC2;
double intercept, slope, k, correction, additionalCorrection, rlCorrection, pin_dBm, rl_dB;
//Read ADC values
RFE_ReadADC(rfe, RFE_ADC1, &adc1);
RFE_ReadADC(rfe, RFE_ADC2, &adc2);
//ADC voltage
vADC1 = RFE_ADC_VREF * (adc1 / pow(2.0, RFE_ADC_BITS));
vADC2 = RFE_ADC_VREF * (adc2 / pow(2.0, RFE_ADC_BITS));
intercept = -87; // From ADL5513 datasheet (https://www.analog.com/media/en/technical-documentation/data-sheets/ADL5513.pdf) for f = 100 MHz
slope = 21E-3; // From ADL5513 datasheet (https://www.analog.com/media/en/technical-documentation/data-sheets/ADL5513.pdf) for f = 100 MHz
k = 2; // ADL5513 output voltage is multiplied by 2 before processed by ADC, so ADL5513 output voltage is vADC/k
correction = 21; // Calculated correction from the LimeRFE schematic (20 dB attenuator and approx. 1 dB for the connector, switch, etc.)
additionalCorrection = -2.0; // Additional correction, empirical, sample & frequency dependent
rlCorrection = -0.5; // Additional reflection correction, empirical, sample & frequency dependent
//User should include the losses in the external coupler used
pin_dBm = intercept + vADC1 / (slope * k) + correction + additionalCorrection;
rl_dB = vADC2 / (k*slope) + rlCorrection;
printf("SWR subsystem source set to 'External'\n");
printf("Power: %f dBm\n", pin_dBm);
printf("RL: %f dB\n", rl_dB);
//Configure LimeRFE to use cellular Band 1.
//RX and TX port is J3.
//Notch is off. Attenuation is 0.
//SWR is enabled. SWR source is internal (signals from the internal coupler from the outputs of the cellular TX amplifier are provided).
state.channelIDRX = RFE_CID_CELL_BAND01;
state.channelIDTX = RFE_CID_CELL_BAND01;
state.selPortRX = RFE_PORT_1;
state.selPortTX = RFE_PORT_1;
state.mode = RFE_MODE_TXRX;
state.notchOnOff = RFE_NOTCH_OFF;
state.attValue = 0;
state.enableSWR = RFE_SWR_ENABLE;
state.sourceSWR = RFE_SWR_SRC_CELL;
RFE_ConfigureState(rfe, state);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//Read ADC values
RFE_ReadADC(rfe, RFE_ADC1, &adc1);
RFE_ReadADC(rfe, RFE_ADC2, &adc2);
//ADC voltage
vADC1 = RFE_ADC_VREF * (adc1 / pow(2.0, RFE_ADC_BITS));
vADC2 = RFE_ADC_VREF * (adc2 / pow(2.0, RFE_ADC_BITS));
intercept = -89; // From ADL5513 datasheet (https://www.analog.com/media/en/technical-documentation/data-sheets/ADL5513.pdf) for f = 2140 MHz
slope = 21E-3; // From ADL5513 datasheet (https://www.analog.com/media/en/technical-documentation/data-sheets/ADL5513.pdf) for f = 2140 MHz
k = 2; // ADL5513 output voltage is multiplied by 2 before processed by ADC, so ADL5513 output voltage is vADC/k
correction = 25; // Calculated correction from the LimeRFE schematic (25 dB coupler, att. and switch approx. 5 dB, and loss from amplifier output to the connector approx. 5 dB)
additionalCorrection = 0; // Additional correction, empirical, sample & frequency dependent
pin_dBm = intercept + vADC1 / (slope * k) + correction + additionalCorrection;
printf("SWR subsystem source set to 'Cellular'\n");
printf("Power: %f dBm\n", pin_dBm);
//Reset LimeRFE
RFE_Reset(rfe);
//Close port
RFE_Close(rfe);
return 0;
}
\ No newline at end of file
CID_WB_1000 = 0
CID_WB_4000 = 1
CID_HAM_0030 = 2
CID_HAM_0145 = 3
CID_HAM_0435 = 4
CID_HAM_1280 = 5
CID_HAM_2400 = 6
CID_HAM_3500 = 7
CID_CELL_BAND01 = 8
CID_CELL_BAND02 = 9
CID_CELL_BAND03 = 10
CID_CELL_BAND07 = 11
CID_CELL_BAND38 = 12
CID_COUNT = 13
NOTCH_VALUE_OFF = 0
NOTCH_VALUE_ON = 1
MODE_RX = 0
MODE_TX = 1
MODE_NONE = 2
MODE_TXRX = 3
PORT_1 = 1
PORT_2 = 2
PORT_3 = 3
/**
@file limeRFE_I2C_example.cpp
@author Lime Microsystems (www.limemicro.com)
@brief LimeRFE example with I2C communication via LimeSDR
*/
#include <lime/LimeSuite.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <stdio.h>
#include "limeRFE.h"
//Device structure, should be initialize to NULL
lms_device_t* device = NULL;
int error()
{
if (device != NULL)
LMS_Close(device);
exit(-1);
}
int main(int argc, char** argv)
{
//Find devices
int n;
lms_info_str_t list[8]; //should be large enough to hold all detected devices
if ((n = LMS_GetDeviceList(list)) < 0) //NULL can be passed to only get number of devices
error();
std::cout << "Devices found: " << n << std::endl; //print number of devices
if (n < 1)
return -1;
rfe_dev_t* rfe;
//open the first device
if (LMS_Open(&device, list[0], NULL))
error();
rfe = RFE_Open(nullptr, device);
unsigned char cinfo[4];
RFE_GetInfo(rfe, cinfo);
printf("LimeRFE Firmware version: %d\n", cinfo[0]);
printf("LimeRFE Hardware version: 0x%x\n", cinfo[1]);
//Configure LimeRFE to use channel HAM 2m channel in receive mode.
//Transmit output is routed to TX/RX output. Notch is off. Attenuation is 0.
RFE_Configure(rfe, RFE_CID_HAM_0145, RFE_CID_HAM_0145, RFE_PORT_1, RFE_PORT_1, RFE_MODE_RX, RFE_NOTCH_OFF, 0, 0, 0);
//or simpler (by using default arguments)
//RFE_Configure(device, 0, RFE_CID_HAM_0145);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//Change mode to transmit
RFE_Mode(rfe, RFE_MODE_TX);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//Reset LimeRFE
RFE_Reset(rfe);
RFE_Close(rfe);
return 0;
}
import ctypes
from ctypes import *
import sys
import os
import time
import limeRFE_H as LH
if os.name == 'nt':
libLimeSuite = ctypes.WinDLL ("C:\\Path\\to\\LimeSuite.dll")
else:
libLimeSuite = ctypes.cdll.LoadLibrary('./libLimeSuite.so')
rfe = c_void_p()
# Open port
if os.name == 'nt':
rfe = libLimeSuite.RFE_Open(c_char_p("COM24"), None);
else:
rfe = libLimeSuite.RFE_Open(c_char_p("/dev/ttyUSB0"), None);
if (rfe == 0):
print("Error initializing serial port")
exit(1)
print "Port opened"
#Configure LimeRFE to use channel HAM 2m channel in receive mode.
#Transmit output is routed to TX/RX output. Notch is off. Attenuation is 0.
result = libLimeSuite.RFE_Configure(rfe, c_int(LH.CID_HAM_0145), c_int(LH.CID_HAM_0145), c_int(LH.PORT_1), c_int(LH.PORT_1), c_int(LH.MODE_RX), c_int(LH.NOTCH_VALUE_OFF), c_int(0))
if(result != 0):
print "RFE_Configure Error Code:", result
print "Check \'LimeRFE error codes' in LimeRFE.h"
libLimeSuite.RFE_Close(rfe)
exit(1)
time.sleep(1.0)
# Change mode to transmit
libLimeSuite.RFE_Mode(rfe, c_int(LH.MODE_TX))
time.sleep(1.0)
# Reset LimeRFE
libLimeSuite.RFE_Reset(rfe)
# Close port
libLimeSuite.RFE_Close(rfe)
\ No newline at end of file
/**
@file limeRFE_I2C_example.cpp
@author Lime Microsystems (www.limemicro.com)
@brief LimeRFE example with I2C communication via LimeSDR
*/
#include <lime/LimeSuite.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <stdio.h>
#include "limeRFE.h"
int openPort(char* portName);
void closePort(int fd);
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("Error: Wrong number of parameters\n");
printf("Usage: limeRFE_USB_test <LimeRFE COM port>\n");
printf("Example: limeRFE_USB_test COM3\n");
exit(1);
}
//Open port
rfe_dev_t* rfe = RFE_Open(argv[1], nullptr);
if (rfe == nullptr) {
std::cout << "Error: failed to open device" << std::endl;
return -1;
}
else {
std::cout << "Port opened" << std::endl;
}
//Configure LimeRFE to use channel HAM 2m channel in receive mode.
//Transmit output is routed to TX/RX output. Notch is off. Attenuation is 0.
RFE_Configure(rfe, RFE_CID_HAM_0145, RFE_CID_HAM_0145, RFE_PORT_1, RFE_PORT_1, RFE_MODE_RX, RFE_NOTCH_OFF, 0, 0, 0);
//or simpler (by using default arguments)
//RFE_Configure(NULL, fd, RFE_CID_HAM_0145);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//Change mode to transmit
RFE_Mode(rfe, RFE_MODE_TX);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//Reset LimeRFE
RFE_Reset(rfe);
//Close port
RFE_Close(rfe);
return 0;
}
......@@ -406,7 +406,7 @@ void fftviewer_frFFTviewer::StreamingLoop(fftviewer_frFFTviewer* pthis, const un
auto fmt = pthis->cmbFmt->GetSelection() == 1 ? lms_stream_t::LMS_FMT_I16 : lms_stream_t::LMS_FMT_I12;
for(int i=0; i<channelsCount; ++i)
{
pthis->rxStreams[i].channel = 2*i;// + ch_offset;
pthis->rxStreams[i].channel = i + ch_offset;
pthis->rxStreams[i].fifoSize = fifoSize;
pthis->rxStreams[i].isTx = false;
pthis->rxStreams[i].dataFmt = fmt;
......@@ -414,7 +414,7 @@ void fftviewer_frFFTviewer::StreamingLoop(fftviewer_frFFTviewer* pthis, const un
LMS_SetupStream(pthis->lmsControl, &pthis->rxStreams[i]);
pthis->txStreams[i].handle = 0;
pthis->txStreams[i].channel = 2*i;// + ch_offset;
pthis->txStreams[i].channel = i + ch_offset;
pthis->txStreams[i].fifoSize = fifoSize;
pthis->txStreams[i].isTx = true;
pthis->txStreams[i].dataFmt = fmt;
......
......@@ -1195,9 +1195,11 @@ API_EXPORT int CALL_CONV LMS_SendStream(lms_stream_t *stream,
* Uploads waveform to on board memory for later use
* @param device Device handle previously obtained by LMS_Open().
* @param samples multiple channel samples data
* @param chCount number of waveform channels
* @param sample_count number of samples in each channel
* @param format waveform data format
* @param chCount number of waveform channels (1 or 2).
* @param sample_count number of samples in each channel. Must be multiple of 4
* @param format waveform data format: 0 - int16 [-2048, 2047],
* 1 - int16 [-32768, 32767]
* 2 - float [-1.0, 1.0]
* @return 0 on success, (-1) on failure
*/
API_EXPORT int CALL_CONV LMS_UploadWFM(lms_device_t *device, const void **samples,
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: RFE_Device.cpp
* Author: ignas
*
* Created on September 4, 2019, 1:18 PM
*/
#include "RFE_Device.h"
#include "limeRFE_constants.h"
#include "API/lms7_device.h"
namespace
{
int FreqToBand(float freq)
{
static constexpr struct {int band; float min; float max;} ranges[] =
{
{RFE_CID_HAM_0030, 0, 30e6},
{RFE_CID_HAM_0070, 50e6, 70e6},
{RFE_CID_HAM_0145, 140e6, 150e6},
{RFE_CID_HAM_0220, 220e6, 225e6},
{RFE_CID_HAM_0435, 400e6, 450e6},
{RFE_CID_HAM_0920, 902e6, 928e6},
{RFE_CID_HAM_1280, 1220e6, 1420e6},
{RFE_CID_HAM_2400, 2.3e9, 2.5e9},
{RFE_CID_HAM_3500, 3.3e9, 3.7e9},
{RFE_CID_WB_1000, 1, 1e9},
{RFE_CID_WB_4000, 100, 4e9}
};
for (auto& val : ranges)
if (freq >= val.min && freq <= val.max)
return val.band;
return RFE_CID_WB_4000;
}
int TxPortCheck(int port, int band)
{
if (port == RFE_PORT_3)
{
printf("tx port 3\n");
if(band == RFE_CID_HAM_0070)
return RFE_CID_HAM_0070;
return RFE_CID_HAM_0030;
}
if ((band == RFE_CID_HAM_0030) ||
(band == RFE_CID_HAM_0070))
return RFE_CID_WB_1000;
return band;
}
int RxPortCheck(int port, int band)
{
if (port == RFE_PORT_3 && band != RFE_CID_HAM_0030 && band != RFE_CID_HAM_0070 && band != RFE_CID_HAM_0145 && band != RFE_CID_HAM_0220 && band != RFE_CID_HAM_0435)
return RFE_CID_WB_1000;
return band;
}
}
RFE_Device::RFE_Device(lms_device_t *dev, RFE_COM com) :
sdrDevice(dev),
com(com),
rxChannel(0),
txChannel(0),
boardState{0},
autoRx(true),
autoTx(true)
{
auto lmsDev = static_cast<lime::LMS7_Device*>(dev);
if (lmsDev && lmsDev->GetConnection())
lmsDev->SetLimeRFE(this);
Cmd_GetConfig(dev, com, &boardState);
}
RFE_Device::~RFE_Device()
{
auto lmsDev = static_cast<lime::LMS7_Device*>(sdrDevice);
if (lmsDev && lmsDev->GetLimeRFE() == this)
lmsDev->SetLimeRFE(nullptr);
}
void RFE_Device::OnCalibrate(int ch, bool en)
{
static constexpr char cellbands[] = {
RFE_CID_CELL_BAND01, RFE_CID_CELL_BAND02, RFE_CID_CELL_BAND03,
RFE_CID_CELL_BAND07, RFE_CID_CELL_BAND38};
if (ch == txChannel)
{
int mode = boardState.mode;
if (mode != RFE_MODE_NONE)
{
for (auto band : cellbands)
if (boardState.channelIDRX == band)
{
if (!en)
{
boardState.channelIDRX = RFE_CID_HAM_0145;
boardState.channelIDTX = RFE_CID_HAM_0145;
boardState.mode = RFE_MODE_NONE;
Cmd_ConfigureState(sdrDevice, com, boardState);
boardState.channelIDRX = band;
boardState.channelIDTX = band;
boardState.mode = mode;
}
else
Cmd_ConfigureState(sdrDevice, com, boardState);
return;
}
if (!en)
{
Cmd_Mode(sdrDevice, com, RFE_MODE_NONE);
boardState.mode = mode;
}
else
Cmd_Mode(sdrDevice, com, mode);
}
}
}
int RFE_Device::SetFrequency(bool dirTx, int ch, float freq)
{
if ((dirTx && ch != txChannel) || (!dirTx && ch != rxChannel))
return 0;
if (!autoRx && !autoTx)
return 0;
if (dirTx && autoTx)
boardState.channelIDTX = TxPortCheck(boardState.selPortTX,FreqToBand(freq));
else if (!dirTx && autoRx)
boardState.channelIDRX = RxPortCheck(boardState.selPortRX,FreqToBand(freq));
return Cmd_ConfigureState(sdrDevice, com, boardState);
}
void RFE_Device::AutoFreq(rfe_boardState& state)
{
if (state.channelIDRX == RFE_CID_AUTO)
{
autoRx = true;
if (sdrDevice)
{
double freq = -1;
LMS_GetLOFrequency(sdrDevice, LMS_CH_RX, rxChannel, &freq);
if (freq > 0)
state.channelIDRX = RxPortCheck(state.selPortRX,FreqToBand(freq));
}
else
state.channelIDRX = RFE_CID_WB_4000;
}
else
autoRx = false;
if (state.channelIDTX == RFE_CID_AUTO)
{
autoTx = true;
if (sdrDevice)
{
double freq = -1;
LMS_GetLOFrequency(sdrDevice, LMS_CH_TX, txChannel, &freq);
if (freq > 0)
state.channelIDTX = TxPortCheck(state.selPortTX,FreqToBand(freq));
}
else
state.channelIDTX = RFE_CID_WB_4000;
}
else
autoTx = false;
}
void RFE_Device::UpdateState(const rfe_boardState& state)
{
if (sdrDevice)
boardState = state;
}
void RFE_Device::UpdateState(int mode)
{
if (sdrDevice)
boardState.mode = mode;
}
void RFE_Device::UpdateState()
{
if (sdrDevice)
Cmd_GetConfig(sdrDevice, com, &boardState);
}
void RFE_Device::SetChannels(int rx, int tx)
{
rxChannel = rx;
txChannel = tx;
}
/*
* File: RFE_Device.h
* Author: ignas
*
* Created on September 4, 2019, 1:18 PM
*/
#ifndef RFE_DEVICE_H
#define RFE_DEVICE_H
#include "limeRFE_constants.h"
class RFE_Device {
public:
RFE_Device(lms_device_t *d, RFE_COM com);
RFE_Device(const RFE_Device&) = delete;
RFE_Device& operator=(const RFE_Device&) = delete;
~RFE_Device();
void OnCalibrate(int ch, bool enable);
int SetFrequency(bool dirTx, int ch, float freq);
void AutoFreq(rfe_boardState& state);
void UpdateState(const rfe_boardState& state);
void UpdateState(int mode);
void UpdateState();
void SetChannels(int rx, int tx);
lms_device_t *sdrDevice;
struct RFE_COM com;
private:
int rxChannel;
int txChannel;
rfe_boardState boardState;
bool autoRx;
bool autoTx;
};
#endif /* RFE_DEVICE_H */
This diff is collapsed.
This diff is collapsed.
/* termiWin.c
*
* Copyright (C) 2017 Christian Visintin - [email protected]
*
* This file is part of "termiWin: a termios porting for Windows"
*
* termiWin is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* termiWin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with termiWin. If not, see <http://www.gnu.org/licenses/>.
*
* Modified by Lime Microsystems (www.limemicro.com)
*
*/
#include "TermiWin.h"
#include <fcntl.h>
#include <stdlib.h>
DCB SerialParams = { 0 }; //Initializing DCB structure
COMMTIMEOUTS timeouts = { 0 }; //Initializing COMMTIMEOUTS structure
//LOCAL functions
/*nbyte 0->7*/
int getByte(tcflag_t flag, int nbyte, int nibble) {
int byte;
if (nibble == 1)
byte = (flag >> (8 * (nbyte)) & 0x0f);
else
byte = (flag >> (8 * (nbyte)) & 0xf0);
return byte;
}
//INPUT FUNCTIONS
int getIXOptions(tcflag_t flag) {
#define i_IXOFF 0x01
#define i_IXON 0x02
#define i_IXOFF_IXON 0x03
#define i_PARMRK 0x04
#define i_PARMRK_IXOFF 0x05
#define i_PARMRK_IXON 0x06
#define i_PARMRK_IXON_IXOFF 0x07
int byte = getByte(flag, 1, 1);
return byte;
}
//LOCALOPT FUNCTIONS
int getEchoOptions(tcflag_t flag) {
#define l_NOECHO 0x00
#define l_ECHO 0x01
#define l_ECHO_ECHOE 0x03
#define l_ECHO_ECHOK 0x05
#define l_ECHO_ECHONL 0x09
#define l_ECHO_ECHOE_ECHOK 0x07
#define l_ECHO_ECHOE_ECHONL 0x0b
#define l_ECHO_ECHOE_ECHOK_ECHONL 0x0f
#define l_ECHO_ECHOK_ECHONL 0x0d
#define l_ECHOE 0x02
#define l_ECHOE_ECHOK 0x06
#define l_ECHOE_ECHONL 0x0a
#define l_ECHOE_ECHOK_ECHONL 0x0e
#define l_ECHOK 0x04
#define l_ECHOK_ECHONL 0x0c
#define l_ECHONL 0x08
int byte = getByte(flag, 1, 1);
return byte;
}
int getLocalOptions(tcflag_t flag) {
#define l_ICANON 0x10
#define l_ICANON_ISIG 0x50
#define l_ICANON_IEXTEN 0x30
#define l_ICANON_NOFLSH 0x90
#define l_ICANON_ISIG_IEXTEN 0x70
#define l_ICANON_ISIG_NOFLSH 0xd0
#define l_ICANON_IEXTEN_NOFLSH 0xb0
#define l_ICANON_ISIG_IEXTEN_NOFLSH 0xf0
#define l_ISIG 0x40
#define l_ISIG_IEXTEN 0x60
#define l_ISIG_NOFLSH 0xc0
#define l_ISIG_IEXTEN_NOFLSH 0xe0
#define l_IEXTEN 0x20
#define l_IEXTEN_NOFLSH 0xa0
#define l_NOFLSH 0x80
int byte = getByte(flag, 1, 0);
return byte;
}
int getToStop(tcflag_t flag) {
#define l_TOSTOP 0x01
int byte = getByte(flag, 1, 1);
return byte;
}
//CONTROLOPT FUNCTIONS
int getCharSet(tcflag_t flag) {
//FLAG IS MADE UP OF 8 BYTES, A FLAG IS MADE UP OF A NIBBLE -> 4 BITS, WE NEED TO EXTRACT THE SECOND NIBBLE (1st) FROM THE FIFTH BYTE (6th).
int byte = getByte(flag, 1, 1);
switch (byte) {
case 0X0:
return CS5;
break;
case 0X4:
return CS6;
break;
case 0X8:
return CS7;
break;
case 0Xc:
return CS8;
break;
default:
return CS8;
break;
}
}
int getControlOptions(tcflag_t flag) {