presently I am trying to fix this: https://github.com/f4exb/sdrangel/issues/83 This proves very difficult if at all feasible without a good code example on how concurrent streams should be managed whenever a change is made using the LimeSuite API. It is up to the designers of LimeSDR and LimeSuite to provide good documentation so that 3rd party developers can do a good job. Until then I am afraid that LimeSDR support with concurrent streams in SDRangel will be very bad.
For now assume that only single streams work correctly.
let me be more specific about problems encountered when running concurrent streams in concurrent threads having their own life cycle. This is basically what happens in SDRangel: you may start/stop change parameters independently in each of them (I know some parameters are global more on this laterā¦)
No disable channels at this point but the program just exits
Now how this would work if each channel is running concurrently with its own sequence of actions? In particular if I do some setup do I need to stop the other streams? Do I need to do anything special when one of the streams starts or stops? I understand that changing LO frequency, sample rate or hardware decimation/interpolation factor have some effects globally and other threads are affected. This is normally taken into account by sending messages across threads (the Qt way) what seems to be problematic is how to handle the life cycle of the streams when everything runs together.
If some of the LimeSutie developers could shed some light on thisā¦
Generally, SetupStream and DestroyStream should be used only when all streams are stopped. it should be okay to setup (or destroy) TX stream when RX is running (and vice versa), however trying to setup (or destroy) second RX/TX stream while other is running will probably not end up well. I think it would not be hard to modify LimeSuite to workaround this limitation on destroy part (just discard second channel samples but not reconfigure streaming to single channel mode).
Also, functions LMS_SetupStream/LMS_StartStream/LMS_StopStream/LMS_DestroyStream do not perform any locking, so it is probably not safe to call them at about same time from different threads.
Interesting. For the last point I am almost sure that this would not occur since we are in a single operator mode so these actions cannot be fired up from different actors at the same time. This may become a different story when a web API will be available so I have to keep this in mind.
I know a situation where SetupStream and DestroyStream are called while another stream is running. This is because in the Tx part the start/stop actions do SetupStream and DestroyStream and at that time another stream may well be running. This is asymmetrical between Rx and Tx: the reason to destroy the stream when stopping Tx is only because this is the only way I found to actually stop the transmitter suspending the stream with StopStream does not seem to be enough.
Do you see any reason why StopStream does not stop the Tx from transmitting? If I remember right the carrier is still maintained.
Edit: in fact it is LMS_EnableChannel that effectively starts or stops the Tx from transmitting.
StopStream stops sending samples to LimeSDR. Carrier is visible when streaming is not active (its just not being modulated). Disabling channel via LMS_EnableChannel powers down RF parts, so it hides the carrier.
Calibration procedure changes sample rate, so streaming should be stopped.
OK, got it for the powering of RF parts. Concerning calibration as it changes sample rate (seems unrelated to me but you should have your own motivations) I suppose I also have to consider that the sample rate could have changed in other channels and therefore tell the corresponding threads to get new values with LMS_GetSampleRate.
Also when do I need to perform calibration? At the moment this is done systematically upon these changes:
You donāt need to do that. Sample rate after calibration should be same as before calibration. I meant that ADC/DAC sample rate in LMS chip is changed during calibration procedure. It is restored after calibration.
I think @Karolis could give you more information about this as he works on calibrations.
After LO change (for TX or RX, change is bigger than 50MHz);
RX front-end (LNA gain register changes by more than 4 values) or TIA gain change (RX only);
Clock generator changes (TX only, change is 50MHz or more);
TX analog filter and gain calibration (TX only);
Antenna path change (RX and TX);
If possible, it is also recommended to perform IQ/DC calibration for optimal performance:
After any LO change;
After RX PGA gain change;
After TX PA loss change;
After RX analog filter bandwidth tune.
Digital changes (sample rate, decimation, interpolation, FIR filter) does not require re-calibration, if the Clock generator is not change by more than 50MHz.
Thanks for you prompt answer. There is still something unclear for me: how can I know that the clock generator has changed? Is there any function in the LimeSuite API that can tell it or that can return the relevant paramters so that they can be compared before and after an operation?
Thank you and best regards, Edouard.
Note: is that LMS_GetClockFreq with LMS_CLOCK_CGEN as the clock id?
@IgnasJ Another question: when LMS_StopStream returns has the stream actually stopped or does it make some kind of asynchronous call to tell the stream to stop and returns immediately?
In case of single channel. when LMS_StopStream returns the RX (or TX) thread has stopped and streaming is actually stopped. However, when using 2 channels, the thread (and streaming) runs until both channels are stopped so stopping single channel doesnāt do much.
I have tried to apply all the recommendations and also upgraded to LimeSuite 17.10.0 but this didnāt provide any improvement. Things started to get better when I introduced a 0.5s delay after LMS_StartStream and LMS_StopStream so I am not so sure that the effect of these commands is really immediate.
Edit: actually 0.1s is enough which makes the turnaround time more acceptable.
Edit2: when I said this didnāt provide any improvement it was about the lockup problem now streams are supposed to be suspended / resumed and also the calibration done in the right places. This is pushed to dev branch.