Giter Club home page Giter Club logo

limesuite's Introduction

Lime Suite

Lime Suite is a collection of software supporting several hardware platforms based on the LMS7002M transceiver RFIC, such as LimeSDR family. It contains the following components:

  • LimeSuite library that provides C-style API;
  • LimeSuiteGUI application for accessing low-level chip and board settings, displaying FFT, updating firmware and more;
  • SoapyLMS plugin for LimeSDR support in SoapySDR;
  • LimeUtil command line tool for listing LimeSDR devices and updating firmware;
  • LimeQuickTest application to run some basic tests;
  • LimeSuite API examples (basicRX, basicTX, singleRX, dualRXTX, gpio_example);
  • Octave plugin (provides some basic functionality only);

Build Status

  • GitHub: Cross platform build status

Documentation

Find build and install instructions for Lime Suite on the wiki:

Information about LimeSDR boards:

Help and support

The discourse forum is a good way to find help and discuss topics:

limesuite's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

limesuite's Issues

Use absolute units Hz in LMS7002M driver

This issue is to modify the API calls to work in units of Hz. Currently API units are in MHz. I recommend putting units in the API calls to avoid accidental breakage: Example TuneTxFilter() becomes TuneTxFilter_Hz().

Very slow initialization for LMS_StreamBoard_FIFO

I was testing with the LMS_StreamBoard, and I couldnt figure out why it took 10 seconds to get data. I found that this seemingly innocent block of code was the culprit. Nothing to do with threads or blocking:

    mRxFIFO = new LMS_StreamBoard_FIFO<SamplesPacket>(1024*2);
    mTxFIFO = new LMS_StreamBoard_FIFO<SamplesPacket>(1024*2);

///calls this which takes 10 seconds or more

            for (int i = 0; i < FIFO_length; ++i)
            {
                mElements.push_back(T());
                ++cnt;
            }

//The packet type (T) is big... but not that big...

        const static int samplesCount = 32768;
        float iqdata[samplesCount];
        int channel;

In addition, I have had some compiles that did not experience this delay (rearguards of master branch or connection work). Its weird... But the fix was to use a pointer instead (other changes needed to compile not shown):

diff --git a/src/LMS_StreamBoard/LMS_StreamBoard_FIFO.h b/src/LMS_StreamBoard/LMS_StreamBoard_FIFO.h
index 51d06cd..53805be 100644
--- a/src/LMS_StreamBoard/LMS_StreamBoard_FIFO.h
+++ b/src/LMS_StreamBoard/LMS_StreamBoard_FIFO.h
@@ -38,7 +38,7 @@ public:
         {
             for (int i = 0; i < FIFO_length; ++i)
             {
-                mElements.push_back(T());
+                mElements.push_back(new T());
                 ++cnt;
             }
             //mElements.resize(FIFO_length, T());
@@ -131,7 +131,7 @@ protected:
        uint32_t mElementsFilled;

     std::mutex mElementsLock; // condition variable for critical section       
-    std::vector<T> mElements;
+    std::vector<T *> mElements;
     std::condition_variable canWrite;
     std::condition_variable canRead;
 };

Ultimately, I don't think that I will use this class for the soapysdr work or the demo. I am just testing for now and I can ignore it. But this issue may come up again, so its good to keep track of stuff like this.

Digital calibrations sweep utility

Create a command line utility that can perform loopback calibration for a specified range of frequencies. The result will be recorded to the LMS7002M sqlite database. The utility should be run on frequencies of interest before using SDR utilities. Without calibration data, the board will operate as normal, but with larger IQ imbalance and transmit DC.

Command line options

  • --start (start frequency)
  • --stop (stop frequency)
  • --channels (A, B, or A+B)
  • --direction (Rx, Tx, both)

Basic mode of operation

At each particular frequency, the calibration algorithm can perform Rx IQ, TX IQ+DC, or all calibrations. The algorithm will use the RF loopback path in the LMS7 to send a strong tone (or tones) from the transmit path to the receiver.

To calibrate the RX IQ imbalance:

  • The transmitter will be tuned at rfFreq + delta, where delta is a frequency between +/- samp_rate/2
  • The transmit gain should be high, but shy of clipping
  • The TxTSP const signal generator should be enabled for a constant DC level.
  • Sweep through possible gain and phase values to minimize the tone level at -delta.
  • Each data acquisition will use the stream API to retrieve a burst.
  • Each tone is measured using FFT analysis.
  • The correction with the minimum imbalance level will be recorded.

To calibrate the TX IQ and TX DC imbalance:

  • These calibrations can be performed in the same loop with the same data for FFT analysis
  • Same configuration as above, but also the Tx CORDIC should be configured such that its imbalance tone does not appear at the Rx DC frequency. We must be able to measure this tone, and it cant be confused with Rx DC. The cordic is set to f0
  • While sweeping for minimum IQ imbalance, also sweep across possible DC correction values and measure for minimum DC tone at delta and minimum imbalance tone at delta-f0
  • The correction with the minimum imbalance level will be recorded.
  • The correction with the minimum tx dc level will be recorded.

Follow up GUI

It might be a good follow-up task to implement this calibration into the lms7suite GUI, with displays for live FFT data and correction efficacy.

Soapy wrapper - set default RBB/TBB bandwidth

I was thinking of making the SoapyLime code set the default baseband bandwidth on initialization to some arbitrary default. Probably a bandwidth that is large enough to cover any host-based app. Like 30 MHz. The point being that:

  • its fast -- its always the same value so the RC constants are saved in the calibration cache
  • Its simple -- there is one less parameter to consider when toying it SDR apps (osmosdr, etc)

Of course users can still tweak the bandwidth for out of band rejection if they want to. Thoughts?

runtime loading for user-created connection modules

We want to support dynamic expansion of the connections available in the connection registry. This is so user's can use the stock LMS7002m driver DLL/binaries and expand for their own creation.

  • support scanning runtime directory for user generated DLLs
  • hooks to control and modify runtime directory path (like env variable)
  • example connection module with cmake file

Refactor fftviewer around IConnection streaming API

Currently fftviewer is implemented around LMS_StreamBoard API and StreamerNovena API. But it should be generic for any board supporting streaming under IConnection.

  • In the case of LMS_StreamBoard, IConnection should already support streaming.
  • In the case of StreamerNovena, these functions belong inside of ConnectionNovenaRF7, some re-factoring is required for ConnectionNovenaRF7 to implement the stream hooks.

Thoughts?

STREAM - faster calibration recovery options

I was thinking about a way to remove some of the lag from the calibration sequence. Specifically stopping the threads, disabling FPGA streaming, re-enabling streaming, and then re-restarting the threads. Emphasis on the threads being brought up and down.

There is an issue of the MCLK during calibration being wrong, or too high. The LML clock dividers could be set to match, or the MCLK output could be disabled during calibration. Personally, I'm afraid of any clock glitchiness, I would have configurable enables on everything in the MCLK domain to disable the entire FPGA+LML interface during cal.

My hope is that if the changing clock rate can be removed from the list of issues, that everything else can be left "as-is" during calibration.

lime-suite gui: development thoughts

It was mentioned splitting up the wx GUI into a separate library and application. The main idea here was to let the user instantiate the GUI on their own custom device, therefore re-using the library, but building a new application with the glue logic.

New thoughts: I think with the connection registry idea, this is largely no longer necessary. The connection registry will be extendible at runtime with new devices, and the IConnection will be "virtual" enough to handle any device. So the wx GUI app does not have to change. More on this in the connection registry issue. But I wanted to make a note here of the options for discussion.

Combined STREAM + COM connection support

There is a use case where STREAM board is used over USB3 (only for streaming), combined with a COM connection to EVB7(for control). This is when the SPI resistors are not populated on the STREAM and/or EVB7.

For this issue we will consider supporting TTY/COM connections within the STREAM connection for the purposes of reducing existing code duplication, and future duplication inside of the SoapySDR wrapper.

If there is a general bennefit to have separate control and stream interfaces present throughout the code, then this issue is rather pointless. But if its just the STREAM + COM special use case, I think we can fix this rather elegantly (~ish).

  • This issue originally discussed on: #5

Configuring ConnectionSTREAM + COM

The handle will be extended to specify an optional COM device chosen by the user. When specified, the ConnectionSTREAM will re-use the ConnectionEVB7COM code to connection to the COM device. And it will forward calls to the ConnectionEVB7COM instance for RFIC and other controls.

Even if we do not make any of the additional changes below, this particular addition will allow me to support EVB7 COM + STREAM in SoapySDR wrapper using only one connection. Otherwise, I will use some device constructor args to specify the COM device, and maintain two IConnection pointers.

More ideas below...

Discovering ConnectionSTREAM + COM

Determining which COM ports are actually an EVB7 is difficult. Also it cannot be known which COM ports belong to the STREAM board (in the case of multiple devices).

  • One solution is to discover all possible combinations (M STREAM X N COMS)
  • A variant of this solution is to test-connect to the STREAM board over USB and check for RFIC communication. STREAM boards that have working RFIC communication should not be discovered with the COM port (and vice-versa)
  • Another option is to only discover STREAM + COM combinations when a special device addr flag is passed -- to avoid polluting the discovered devices list unless desired.

GUI presentation of ConnectionSTREAM + COM

Currently we have two connection columns and two separate connections.

  • One option would be to have a single column for all possible device combinations novena, COM, stream, (M STREAM X N COMS)
  • Other could be one column for regular devices (novena, COM, stream), and a separate special column for only COM devices. The user could select a combination of a regular device and a COM device, and the connection dialogue would pass the selected COM device to the ConnectionHandle for the STREAM board (mentioned in Configuring ConnectionSTREAM + COM section). This option maintains a single connection, but allows the user to select from separate columns to eliminate M x N elements. Still, its a bit special cased...

Support multiple/simultaneous stream boards

The ConnectionSTREAM should support multiple + simultaneous boards. I don't think this is a priority, but lets track it here to remember.

  1. Consider the case where multiple STREAM boards are attached VIA USB. We need a way to select a specific board. It looks like currently the Cypress API supports this using the device index, but the libusb API uses a VID/PID lookup that may be ambiguous with multiple boards.

  2. Consider the case using simultaneous stream boards where someone may use two STREAM connections in the same process. In addition to 1), It also looks like the Cypress API implementation shares a device pointer for all open devices. So its currently limited to one device at a time.

Incorrect readback sample rate on channel 1/side B

Setting the rate on side B appears to readback the incorrect interpolation, and hence the wrong sample rate. Also, this sample rate is used to set the PLL, so although the correct rate is really set, the PLL is not correct. So far, affected applications end up causing a second calibration which corrects the PLL. The problem is probably in:

liblms7_status LMS7002M::SetInterfaceFrequency(
    float_type cgen_freq_MHz, const uint8_t interpolation, const uint8_t decimation)

or

float_type LMS7002M::GetSampleRate(bool tx)

Seen when running osmotrx:

-- SoapyLMS7::setSampleRate(Tx, 0, 4.333333 MHz), baseRate 17.333333 MHz, factor 4.000000
LMS_StreamBoard::ConfigurePLL(tx=4.33333MHz, rx=17.3333MHz)
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
libusb: warning [handle_timeout] async cancel failed -5 errno=22
-- SoapyLMS7::setSampleRate(Tx, 1, 4.333333 MHz), baseRate 17.333333 MHz, factor 4.000000
LMS_StreamBoard::ConfigurePLL(tx=4.33333MHz, rx=17.3333MHz)

UHD Warning:
    The hardware does not support the requested TX sample rate:
    Target sample rate: 4.333333 MSps
    Actual sample rate: 8.666667 MSps

Simultaneous support for both CyAPI and libusb

This is more of a thought at the moment and note for the future: The current ConnectionSTREAM has a a dual implementation for both libusb and CyAPI separated by a lot of #ifdef __unix__.

  • However it should be the case that any platform could be built for either api regardless. The ifdefs should reflect the API or rather we should have two separate ConnectionSTREAM implementations for each rather than all of the ifdefs in one single implementation.
  • And further, the way connection registry is handled, both ConnectionSTREAMLibUSB and ConnectionSTREAMCyAPI could be compiled at the same time -- Bladerf actually does this support for both as a redundancy when one usb library is causing a problem.

soapy lms7 - calibration cleanup

  • removing the background thread for calibrate on idle
  • removing special cases like calOnce through the args
  • use the new digital corrections API call + warning message

STREAM: support sample rates below 2.5 MSps

Due to the limitations of the PLL in the fpga, the minimum supported sample rate is 2.5 MSps or 5 MHz PLL. Some applications (like GSM) and user testing may require lower sample rates.

One suggested fix may be to use a clock mux to switch between the PLL and an alternative clock for lower rates. A slower clock with appropriate phase relationship could be generated in register logic by oversampling the MCLK with a faster clock and creating the required phase delay.

udev rules for USB stream board (linux)

  • provide udev rules for the STREAM board to support non-root user
  • instructions/readme/wiki for installing the rules
  • also debian packaging can properly install rules

libusbx warnings.

Frequently get libusbx warnings of the sort:

2016-03-20 12:34:15 ::1: libusbx: warning [handle_timeout] async cancel failed -5 errno=22

E.g. when using PothosGui and changing settings or deactivating a topology.

lime suite: The IConnection overhaul

About IConnection

IConnection is our entry point for communication and streaming with a device. The LMS7 driver class uses IConnection to interface with the device; and devices creators implement IConnection's methods to specify communication specifics.

Major goals

The main goals to come out of this re-work:

  • IConnection is device and protocol independent. It represents a device with a lime RFIC (or more). And says nothing about interface and protocol. There shouldn't be any enums in the public headers for stream or novena, or usb, pcie for example.
  • IConnection has API calls for all of the things we want to do with a device. SPI comms, streaming, control external switches associated with the bandselect.

RFIC enumeration interface

One or more RFICs may be present on a device. We need to enumerate the number of devices and to know which channels and slaves are present for that RFIC.

  • query the number of RFICs (default 1)
  • query a structure for each RFIC index that specifies:
    • a list of streaming rx channels
    • a list of streaming tx channels
    • spi slave number for RFIC
    • optional spi slave for external clock

New streaming interface

  • synchronous read and write interfaces with timeouts
  • each API call takes a channel index number
  • configuration commands to start streaming, request busts

New spi interface

  • bulk writes of spi addresses
  • bulk reads of spi addresses
  • each api calls takes a spi slave number

Other configuration calls

  • query capabilities, anything needed to implement device-specific behaviour in a general way (TBD)
  • query and set device time from FPGA registers
  • calls to handle band selection change by the lms-driver that might need to trigger external antenna switches
  • etc

soapy sdr wrapper for lime-suite

Given the new work based around the connection registry and IConnection expansion, we should be able to create a generic SoapySDR wrapper about these interfaces. This means that any device expressed under IConnection can be used under the SoapySDR API. This opens a world of possibilities for simply doing the work of filling in the IConnection and ConnectionRegistryEntry.

  • SoapySDR discovery function will wrap the ConnectionRegistry enumeration() call
  • SoapySDR factory function will wrap the ConnectionRegistry make() call
  • SoapySDR IConnection wrapper will take the IConnection and implement its various configuration methods around the lms7 driver, and streaming methods around the IConnection streaming.

The TODO list:

  • connection registry
  • enable/disable channels
  • streaming
  • band select
  • set sample rate
  • set bandwidth
  • set gain
  • tuning
  • clock rate
  • logging hooks

New connection module: EVB7 + COM

New connection module for EVB7 + COM: As part of the connection registry work, the COM connection will be reshaped around the new connection API. The streaming calls will be default not implemented, but its discovery, factory, and communication calls will be used under the new API.

Transmit stops working after pause in stream

Whenever there is a pause in the transmit stream, accidental/underflow or forced/end of burst, the transmit samples seem to have no effect. It looks like we just see the TX LO at whatever level was previously the last sample. The following example sleeps every 3 seconds for 3 seconds, it should cause a tone to go on an off. Once the tone appears, it goes away forever. If the zero-flush at the end is removed, the LO can be seen at full power (possibly because the last tx sample before the sleep was at full amplitude)

python demo_tx_recovery_issue.py --clockRate=32e6 --txAnt=BAND1 --txGain=40 --args="driver=lime" --freq=433.92e6 --ampl=0.7 --rate=4e6 --waveFreq=300e3

FPGA load detection

Automatic loading at runtime

For the soapy sdr bindings, we are going to want this use case to be some-what automated. This includes checking that the FPGA is loaded and that the correct image is loaded. When the driver is initialized, there where be some code to..

  • check the state of the board.
  • look for images on the file system,
  • and to load the correct image.

Questions:

transfer timed out/Error: popping from RX/rate: 0 kB/s failures:2

@rjonaitis I'm having trouble getting useful data out of the stream board. I am really looking for a positive confirmation of IQ samples. Here are the steps that I took, and whats happening:

  • This is using the master branch (and not the connection development work). I have a STREAM board that is attached via USB3, and EVB7 attached via COM. This EVB7 does not have the resistors populated, and the power jumper is not populated.
  • This FPGA image was burned to flash: https://github.com/myriadrf/STREAM/tree/master/apps/STREAM_LMS7EVB_distro_07v/gateware/bitstreams
  • After power cycle the led3 is solid and eventually goes off. I assume this means that the FPGA has loaded properly.
  • launch the app, sudo bin/lms7suite
  • Connect to stream and com ports

screenshot

  • This is the correct FW version, right?

screenshot

screenshot

sudo bin/lms7suite 
Visible GUI update time: 0
GUI update time: 0
Create time 1172 ms
Claimed Interface
Visible GUI update time: 17
GUI update time: 264

(lms7suite:7120): Gtk-CRITICAL **: IA__gtk_window_resize: assertion 'width > 0' failed

(lms7suite:7120): Gtk-CRITICAL **: IA__gtk_window_resize: assertion 'width > 0' failed

(lms7suite:7120): Gtk-CRITICAL **: IA__gtk_window_resize: assertion 'width > 0' failed
        Error: popping from RX
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
        Error: popping from RX
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
        Error: popping from RX
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
        Error: popping from RX
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
        Error: popping from RX
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
        Error: popping from RX
transfer timed out
        Error: popping from RX
Rx: 0.0%         rate: 0 kB/s failures:2
        Error: popping from RX
Processing finished

osmotrx, timestamps, and non-monotonic

Because of the re-calibrations, the streaming is disabled and enabled. This may be causing the timestamp to reset to 0. One possible fix would be to copy the last timestamp into the timestamp offset. This will make the timestamps appear monotonic from the API perspective:

Example, although this did not immediately work (caused application to exit):

diff --git a/src/ConnectionSTREAM/ConnectionSTREAMing.cpp b/src/ConnectionSTREAM/ConnectionSTREAMing.cpp
index f9a9ae1..826eabd 100644
--- a/src/ConnectionSTREAM/ConnectionSTREAMing.cpp
+++ b/src/ConnectionSTREAM/ConnectionSTREAMing.cpp
@@ -158,6 +158,10 @@ struct USBStreamService : StreamerLTE
         //clear any residual data from FIFO
         ResetUSBFIFO(dynamic_cast<LMS64CProtocol *>(mDataPort));

+        //hardware time resets to zero, correct with offset + 100 ms
+        mTimestampOffset += mLastRxTimestamp + mHwCounterRate*0.1;
+        mLastRxTimestamp = 0;
+
         //switch on Rx
         auto regVal = Reg_read(mDataPort, 0x0005);
         int syncDis = txTimeEnabled?0:(1 << 5);

STREAM: support image update with runtime image

To add to the wishlist. If the FX3 firmware and lime suite and supported burning to flash. We could avoid booting into factory with the jumper. This may be useful for firmware updates in the future.

smart clock rate and sample rate selection

In SoapyLMS: Based on the desired sample rate, automatically select clock rate to make this possible with half-band chain. If the user never specifies a custom clock rate, then using sample rate hook to automatically select clock to match is a good idea. When both TX and RX rates are specified, try to make this work, error if no common clock rate can be figured out.

Digital corrections - LMS7002M driver hooks

Adding a new API call to LMS7002M that can lookup cached corrections in the database, perform interpolation between points, and apply the correction:

int ApplyDigitalCorrectionsFromCache(const bool isTx)
{
    //get the active channel ChA or ChB (chan)
    //get the current SXX/LO frequency (freq)
    //search the database for the nearest two points before and after freq, given chan, and isTx

    //no points found?
      return ReportError("Cant find entry in db for %f MHz on Rx channel A, etc..");

   //if (isTx)
  {
    //linear interpolate DC real correction, DC imag correction
    //linear interpolate IQ balance phase, and IQ balance gain     
  }
  else
  {
    //linear interpolate IQ balance phase, and IQ balance gain     
  }
}

using the new call in SoapyLMS7

The setFrequency() call will try to apply corrections for both channels after the LO is re-tuned. If the corrections do not have possible entries in the database, then a warning will be logged.

Replace ini parse submodule with subtree

Git subtree attempts to copy or squash another git repo -- rather than submodule which is more like a lightweight symlink. Should we consider replacing the ini parse submodule with subtree instead to

  • eliminate some confusion when building from source (forgetting to run git submodule update)
  • ensure that tarballs from github release tags are build-able (cant use git from a tarball)
    • example -- homebrew builds on osx using release tag tarballs from github

I like submodules a lot, but since this is the only case so far, it may be easier to go with subtree.

LMS7002M API and reference frequency

Some calls take a reference frequency, some dont:

    float_type GetReferenceClk_SX(bool tx);
    float_type GetFrequencyCGEN_MHz();
        //...I believe this uses the ref freq that was last set by SetFrequencySX
    liblms7_status SetFrequencyCGEN(float_type freq_MHz);
    float_type GetFrequencySX_MHz(bool tx, float_type refClk_MHz);
    liblms7_status SetFrequencySX(bool tx, float_type freq_MHz, float_type refClk_MHz);
    liblms7_status SetNCOFrequency(bool tx, uint8_t index, float_type freq_MHz);
        ///...although this refClk_MHz is the DSP/ADC rate
    float_type GetNCOFrequency_MHz(bool tx, uint8_t index, float_type refClk_MHz, bool fromChip = true);

Possible changes

One of the things that I did to IConnection was add a call to query the reference frequency. The reference frequency is set by the board, external to LMS7002M. Some boards will have it fixed, some will have a synthesizer like stream.

I propose that all of these calls drop the reference frequency parameter, and in addition, LMS7002M does not cache the reference freq. Ref freq is always queried from one place, the IConnection.

IConnection.h

    /*!
     * Query the frequency of the reference clock.
     * Some implementations have a fixed reference,
     * some have a programmable synthesizer like Si5351C.
     * @return the reference clock rate in Hz
     */
    virtual double GetReferenceClockRate(void)

baseband filter calibration - performance improvements

We will still need fast baseband filter calibration, lets do as much as possible to speed up the algorithms.

  • Read modify write should use fromChip = false

We have a cache of LMS700m registers, so it should be possible to specify fromChip false. This should cut down the operation time of all Modify_SPI_Reg_bits() used in the filter setup.

  • Use bulk writes during cal setup

Rather than writing out to the LMS7 registers on each call to Modify_SPI_Reg_bits(), we could also implement a toChip = false for Modify_SPI_Reg_bits(). Then perform a single bulk write of all affected registers.

Example: The readRSSI() function can be sped-up with two writes only for the capture register, and one bulk read for the 3-byte readback value.

  • Combine RX filter TIA (RFE) and LPFL/H (RBB) calibration

Rather than a separate cal operation for both RFE and RBB, (and only when the requested BW is the same for both filters)... most of the calibration uses the same setup (same clock rate, same loopback, same LO). One operation with a shared initial setup should be faster.

  • Calibration database for RC cal values - Moved! See #42

Store all calibration results in the database. Unless the user is sweeping over possible bw settings, we are likely to see the same values come up again and again. 1) an initial value set by the driver that is good for most applications, and 2) an application specific value that is used over and over.

LimeSDR LED documentation and repurposing thoughts

What is the purpose of the current LEDs near the usb connector. Perhaps FPGA and FX3 boot indicators? I was wondering about documenting it to help new users when they first power on the hardware.

Secondly, could any of the LEDs be re-purposed after boot as some kind of status indicator for things like:

  • reference lock
  • rx streaming
  • tx streaming
  • etc

Adding convenience calls in LMS7002M.h

While making the wrapper calls for various settings for the SoapySDR wrapper. I was thinking that it would make sense if this logic was embedded into the LMS7002M.h API itself for maximum re-use.

TODO checklist

  • RX RF frontend paths
  • TX RF frontend paths
  • TX gain in dB
  • RX gain in dB
  • LML DIQ mode
  • LML sample pos
  • XBUF config
  • LDO config
  • LO range

Examples:

RF switches

SetPathRFE(some enum)
{
//this call sets SEL_PATH_RFE as well as the required enables like EN_INSHSW_*
//Also it would call _conn->UpdateExternalBandSelect(...)
}

SetBandTRF(int band)
{
//band is 1 or 2
//set SEL_BAND1_TRF and SEL_BAND2_TRF
//also UpdateExternalBandSelect(...)
}

Gain settings

SetGainPGARBB(const double gain_dB)
{
//set G_PGA_RBB gain in dB
//another other enables or calibrations...
}

//Rx LNA, Tx PAD, etc...

lime-suite: connection registry development

The connection registry api:

  • Applications can discover and instantiate connections
  • And developers can extend it for new devices

Major interfaces:

ConnectionHandle represents a discovered device. It holds serials and addresses. It can also be filled in partially to narrow down the search for a specific device.

ConnectionRegistry is the application API that allows ConnectionHandles to be discovered, and IConnections to be instantiated with the ConnectionHandle.

ConnectionRegistryEntry is a class that the hardware developer overloads to implement discovering available devices and instantiating IConnections.

Runtime extending ConnectionRegistry:

The idea is to make ConnectionRegistry extensible without building the lime-suite for new devices or custom devices. Custom ConnectionRegistryEntry and associated custom IConnections can be registered with the ConnectionRegistry at runtime via LoadLibrary/dlopen(). We do this by building the ConnectionRegistryEntry into a library and installing it into a well known location to be loaded at runtime.

lime-suite integration of the C LMS7002M-driver

LMS7002M-driver

LMS7002M-driver is its own stand-alone C driver project for the LMS7

Common calibration utilities

This may become a separate issue on the tracker, but a major benefit of this work should be creating a common calibration algorithm set for both drivers. This implies re-writing some of the calibration algorithms in C and generalizing it around the spi interface. Its definitely possible since this was actually done for the LMS7002M-driver. Hopefully we end up with a stronger and better tested calibration algorithm overall.

lime-suite: namespaces for public headers

This might be more of a matter of taste, but since the lime-suite is largely C++, we might want to put namespace lime {} around classes and enums found in public headers. There should not be many changes to the code-base. The implementation cpp files would gain the line using namespace lime, and the headers would gain the line namespace lime { and a closing bracked }.

Refactor the return codes API

So there are a few different error enums, to name a few:

  • liblms7_status
  • OperationStatus
  • eCMD_STATUS

I was thinking that it might be cleaner to follow a different model for dealing with error codes and error reporting. Basically, there would be one error reporting and querying API. And most API calls would simply return pass/fail true/false 0/-1. The user would be able to query the actual error code and message string when the call failed, and if they were interested. Its a lot like errno or windows getlasterror().

Possible API

list of pre-defined error codes that users will encounter when using lime suite

SUCCESS = 0
ERROR_CONNECTION,
ERROR_RANGE
ERROR_BUFFER
etc...

When API calls fail, they should first report the error code
and an optional message string with more details

void ReportError(int code, string message = "");

//variant for reporting after system call failures that use errno/getlasterror
void ReportError(int code, errno);

When a user wants to query the error:

//get the error code reported
int GetLastError(void);

//get the error code to string + any optional message reported
const char *GetLastErrorMessage(void);

Example

The LMS API call CalibrateTx():

bool LMS7002M::CalibrateTx(float_type bandwidth_MHz)
{
    if (bandwidth_MHz <= 0.0)
    {
        lime::ReportError(ERROR_RANGE, "LMS7002M::CalibrateTx() expects BW > 0");
        return false;
    }

    return true;
}

The user's code:

if (not rfic->CalibrateTx(-100))
{
    std::cout << "Failed to calibrate! " << lime::GetLastErrorMessage() << std::endl;
}

Notes

The error reporting API is global, its not tied to any particular class or instance. The error reporting API will store error codes and messages in thread-local-storage to make it thread-safe. As long as a user queries the error after a failure before making a new lime-suite API call, there will never be a problem.

baseband filter calibration - caching to database

The baseband filters for RBB, RFE(TIA), and TBB should cache results in the database. Initially, we aren't looking for any fancy interpolation. Once a bandwidth is calibrated for, its RC values will be saved and applied next time.

This work will modify the existing calibration algorithms to check, retrieve, and apply RC constants from the database. If a particular bandwidth cannot be found with a few Hz of error, then the manual calibration must be performed. The result will be stored in the database.

merge Iconnection work into master

Can we merge Iconnection branch, and should we merge before things diverge any more? My concerns are:

  • novena has diverged in master branch
  • possible bugs introduced in Iconnection

Complete connection module for Novena + LMS7

This issue should start by implementing the connection registry module for the Novena with spi interface only, no streaming.

However, the work for Novena LMS6 driver with streaming should be applicable to this work. Possibly using the existing FPGA driver work from LMS6, Novena has a functional streaming RX and TX channel that can be used.

lime-suite development library: install public headers

In order to use lime-suite as a development library for 1) developers writing drivers and 2) users instantiating lms driver in applications. All necessary headers should be installed into the system in an include/lime-suite directory.

versioning scheme and release tagging for limesuite

Git branches and release tags I am thinking about having a "stable" branch. At least in the future for creating releases from. In this paradigm, the "stable" branch only gets fixes applied and gets merged into the master branch (aka development branch). New development occurs on the master branch which includes API changes and breaking features.

The stable branch is periodically tagged with a new release number. And when stable becomes mature and a feature set also matures on master, we update stable branch for the latest master branch and create a new release series. The cycle continues.

This might be overkill, but something like this in mind:
http://nvie.com/posts/a-successful-git-branching-model/

Version numbering scheme Looks like we currently build version information into version.h:
https://github.com/myriadrf/LimeSuite/blob/master/src/version.h

Versioning with dates is often used and very indicative of the age of a package. Using a version scheme like version.h like "year.month.day" could work quite well.

However, I would also like to consider how fixes are handled using a similar scheme of "year.month.patch". Perhaps a release is made, lets say its named 2016.05.0. After some bug fixes, a new release is tagged 2016.05.1

lime-suite development library: build shared library

A shared library does a few things for us:

  • Good practice for packaging (debian, etc)
  • A shared library can up updated without requiring dependencies to be recompiled
  • May play into the connection registry work (one shared library means one copy of the registry).

Classes and functions in the shared library will need an export macro, example here (works windows and unix): https://gcc.gnu.org/wiki/Visibility

In terms of the build system, everything can stay in place, but we will probably build one shared library as opposed to multiple static libraries and linking them together.

STREAM: flash unique ID for each board

Just an idea, but perhaps with a firmware update, a UUID could be read/written to the FX3 flash. When the cal software sees an uninitialized UUID, it would generate a random one and write it once. This would give us a unique ID for each hardware in the future for calibration data.

Does not support use with lower frequencies.

E.g.

$ osmocom_fft -F -a "driver=lime,soapy=0,clock=40e6,cacheCalibrations=1" -s 5e6 -f 7e6

Results in:

LMS_StreamBoard::ConfigurePLL(tx=10MHz, rx=5MHz)
C[INFO] SoapyLMS7::setFrequency(Rx, 0, RF, 7.000000 MHz), ref 30.720000 MHz
[INFO] SoapyLMS7::setFrequency(Rx, 0, BB, -1897.655000 MHz), ref 30.720000 MHz

See also attached for FFT frequency scale displayed.
030316_gr-fosphor_7mhz

STREAM: TX IQ random swap issue

The IQ can random swap on TX between runs. This might be an issue with GPIFIII state machine. Uncertain. To reproduce, run, ctrl+c, and re-run the siggen app. The tone should be positive of the TX LO, but will sometimes swap positions:

python lms7suite/src/SoapyLMS7/siggen_test.py \
    --clockRate=40e6 --txAnt=BAND1 --txGain=52 \
    --args="driver=lime" --freq=1000.5e6 \
    --ampl=0.7 --rate=5e6 --waveFreq=300e3

PLL issue with different Rx and Tx rates

I had a work-around checked into the siggen app thats sets a matching rx rate when the tx sample rate is set. But not every app has this work around. So it looks like the transmit waveform is unstable, almost like the PLL is not locked when the rates are different. To simulate this, I added --rxRate to the siggen app (checked in just now):

Looks good

python siggen_test.py --clockRate=40e6 --txAnt=BAND1 --txGain=52 --args="driver=lime" --freq=433.92e6 --ampl=0.7 --rate=5e6 --waveFreq=300e3 --rxRate=5e6

Looks bad, but why?

python siggen_test.py --clockRate=40e6 --txAnt=BAND1 --txGain=52 --args="driver=lime" --freq=433.92e6 --ampl=0.7 --rate=5e6 --waveFreq=300e3 --rxRate=2.5e6

LMS7002M GUI theming layout issues

I have noticed this for a while, but I finally tried to look into it because its making the testing near impossible. It looks like wxStaticBoxSizer does not take into account the size of its label, and all of the nested box-sizers gradually loose more and more screen space the deeper they nest... just a guess. But every tab, every dialog looks like this more or less.

Screenshot

@rjonaitis any ideas/hints?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.