mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
PlutoSDR input: implemented input class interim state (1)
This commit is contained in:
parent
e1c3a66983
commit
7b437e41ba
@ -19,6 +19,7 @@
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <iio.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "deviceplutosdrbox.h"
|
||||
|
||||
@ -327,7 +328,38 @@ char* DevicePlutoSDRBox::txBufferFirst()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DevicePlutoSDRBox::parseSampleRates(const std::string& rateStr, SampleRates& sampleRates)
|
||||
{
|
||||
// Rx: "BBPLL:983040000 ADC:245760000 R2:122880000 R1:61440000 RF:30720000 RXSAMP:30720000"
|
||||
// Tx: "BBPLL:983040000 DAC:122880000 T2:122880000 T1:61440000 TF:30720000 TXSAMP:30720000"
|
||||
std::regex desc_regex("BBPLL:(.+) ..C:(.+) .2:(.+) .1:(.+) .F:(.+) .XSAMP:(.+)");
|
||||
std::smatch desc_match;
|
||||
std::regex_search(rateStr, desc_match, desc_regex);
|
||||
std::string valueStr;
|
||||
|
||||
if (desc_match.size() == 7)
|
||||
{
|
||||
try
|
||||
{
|
||||
sampleRates.m_bbRate = boost::lexical_cast<uint32_t>(desc_match[1]);
|
||||
sampleRates.m_addaConnvRate = boost::lexical_cast<uint32_t>(desc_match[2]);
|
||||
sampleRates.m_hb3Rate = boost::lexical_cast<uint32_t>(desc_match[3]);
|
||||
sampleRates.m_hb2Rate = boost::lexical_cast<uint32_t>(desc_match[4]);
|
||||
sampleRates.m_hb1Rate = boost::lexical_cast<uint32_t>(desc_match[5]);
|
||||
sampleRates.m_firRate = boost::lexical_cast<uint32_t>(desc_match[6]);
|
||||
return true;
|
||||
}
|
||||
catch (const boost::bad_lexical_cast &e)
|
||||
{
|
||||
qWarning("DevicePlutoSDRBox::parseSampleRates: bad conversion to numeric");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -36,6 +36,15 @@ public:
|
||||
int16_t q;
|
||||
};
|
||||
|
||||
struct SampleRates {
|
||||
uint32_t m_bbRate; //!< Baseband PLL rate (Hz) - used internally
|
||||
uint32_t m_addaConnvRate; //!< A/D or D/A converter rate (Hz) - this is the HB3 working sample rate
|
||||
uint32_t m_hb3Rate; //!< Rate of the HB3/(DEC3 or INT3) filter (Rx: out, Tx: in) - this is the HB2 working sample rate
|
||||
uint32_t m_hb2Rate; //!< Rate of the HB2 filter (Rx: out, Tx: in) - this is the HB1 working sample rate
|
||||
uint32_t m_hb1Rate; //!< Rate of the HB1 filter (Rx: out, Tx: in) - this is the FIR working sample rate
|
||||
uint32_t m_firRate; //!< Rate of FIR filter (Rx: out, Tx: in) - this is the host/device communication sample rate
|
||||
};
|
||||
|
||||
DevicePlutoSDRBox(const std::string& uri);
|
||||
~DevicePlutoSDRBox();
|
||||
bool isValid() const { return m_valid; }
|
||||
@ -62,6 +71,8 @@ public:
|
||||
std::ptrdiff_t txBufferStep();
|
||||
char* txBufferEnd();
|
||||
char* txBufferFirst();
|
||||
bool getRxSampleRates(SampleRates& sampleRates);
|
||||
bool getTxSampleRates(SampleRates& sampleRates);
|
||||
|
||||
private:
|
||||
struct iio_context *m_ctx;
|
||||
@ -73,6 +84,8 @@ private:
|
||||
struct iio_buffer *m_rxBuf;
|
||||
struct iio_buffer *m_txBuf;
|
||||
bool m_valid;
|
||||
|
||||
bool parseSampleRates(const std::string& rateStr, SampleRates& sampleRates);
|
||||
};
|
||||
|
||||
#endif /* DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ */
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "plutosdr/deviceplutosdrbox.h"
|
||||
|
||||
#include "plutosdrinput.h"
|
||||
#include "plutosdrinputthread.h"
|
||||
|
||||
#define PLUTOSDR_BLOCKSIZE (1024*1024) //complex samples per buffer
|
||||
|
||||
@ -33,7 +34,8 @@ PlutoSDRInput::PlutoSDRInput(DeviceSourceAPI *deviceAPI) :
|
||||
m_fileSink(0),
|
||||
m_deviceDescription("PlutoSDR"),
|
||||
m_running(false),
|
||||
m_plutoRxBuffer(0)
|
||||
m_plutoRxBuffer(0),
|
||||
m_plutoSDRInputThread(0)
|
||||
{
|
||||
char recFileNameCStr[30];
|
||||
sprintf(recFileNameCStr, "test_%d.sdriq", m_deviceAPI->getDeviceUID());
|
||||
@ -60,29 +62,37 @@ bool PlutoSDRInput::start()
|
||||
|
||||
// start / stop streaming is done in the thread.
|
||||
|
||||
// if ((m_limeSDRInputThread = new LimeSDRInputThread(&m_streamId, &m_sampleFifo)) == 0)
|
||||
// {
|
||||
// qFatal("LimeSDRInput::start: cannot create thread");
|
||||
// stop();
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// qDebug("LimeSDRInput::start: thread created");
|
||||
// }
|
||||
//
|
||||
// m_limeSDRInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
|
||||
//
|
||||
// m_limeSDRInputThread->startWork();
|
||||
//
|
||||
// m_deviceShared.m_thread = m_limeSDRInputThread;
|
||||
// m_running = true;
|
||||
if ((m_plutoSDRInputThread = new PlutoSDRInputThread(PLUTOSDR_BLOCKSIZE, m_deviceShared.m_deviceParams->getBox(), &m_sampleFifo)) == 0)
|
||||
{
|
||||
qFatal("PlutoSDRInput::start: cannot create thread");
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("PlutoSDRInput::start: thread created");
|
||||
}
|
||||
|
||||
m_plutoSDRInputThread->setLog2Decimation(m_settings.m_log2Decim);
|
||||
m_plutoSDRInputThread->startWork();
|
||||
|
||||
m_deviceShared.m_thread = m_plutoSDRInputThread;
|
||||
m_running = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlutoSDRInput::stop()
|
||||
{
|
||||
if (m_plutoSDRInputThread != 0)
|
||||
{
|
||||
m_plutoSDRInputThread->stopWork();
|
||||
delete m_plutoSDRInputThread;
|
||||
m_plutoSDRInputThread = 0;
|
||||
}
|
||||
|
||||
m_deviceShared.m_thread = 0;
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
const QString& PlutoSDRInput::getDeviceDescription() const
|
||||
@ -102,7 +112,19 @@ quint64 PlutoSDRInput::getCenterFrequency() const
|
||||
|
||||
bool PlutoSDRInput::handleMessage(const Message& message)
|
||||
{
|
||||
if (MsgFileRecord::match(message))
|
||||
if (MsgConfigurePlutoSDR::match(message))
|
||||
{
|
||||
MsgConfigurePlutoSDR& conf = (MsgConfigurePlutoSDR&) message;
|
||||
qDebug() << "PlutoSDRInput::handleMessage: MsgConfigurePlutoSDR";
|
||||
|
||||
if (!applySettings(conf.getSettings(), conf.getForce()))
|
||||
{
|
||||
qDebug("PlutoSDRInput::handleMessage config error");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgFileRecord::match(message))
|
||||
{
|
||||
MsgFileRecord& conf = (MsgFileRecord&) message;
|
||||
qDebug() << "PlutoSDRInput::handleMessage: MsgFileRecord: " << conf.getStartStop();
|
||||
@ -219,5 +241,91 @@ void PlutoSDRInput::resumeBuddies()
|
||||
|
||||
bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool force)
|
||||
{
|
||||
bool forwardChangeOwnDSP = false;
|
||||
bool forwardChangeAllDSP = false;
|
||||
bool suspendOwnThread = false;
|
||||
bool ownThreadWasRunning = false;
|
||||
bool suspendAllOtherThreads = false; // All others means Tx in fact
|
||||
bool doCalibration = false;
|
||||
|
||||
// determine if buddies threads or own thread need to be suspended
|
||||
|
||||
// change of global baseband sample rate affecting all buddies can occur if
|
||||
// - device to host sample rate is changed
|
||||
// - rate governor is changed
|
||||
// - FIR filter decimation is changed
|
||||
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) ||
|
||||
(m_settings.m_rateGovernor != settings.m_rateGovernor) ||
|
||||
(m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim) || force)
|
||||
{
|
||||
suspendAllOtherThreads = true;
|
||||
suspendOwnThread = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
suspendOwnThread = true;
|
||||
}
|
||||
|
||||
if (suspendAllOtherThreads)
|
||||
{
|
||||
const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
|
||||
std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin();
|
||||
|
||||
for (; itSink != sinkBuddies.end(); ++itSink)
|
||||
{
|
||||
DevicePlutoSDRShared *buddySharedPtr = (DevicePlutoSDRShared *) (*itSink)->getBuddySharedPtr();
|
||||
|
||||
if (buddySharedPtr->m_thread) {
|
||||
buddySharedPtr->m_thread->stopWork();
|
||||
buddySharedPtr->m_threadWasRunning = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
buddySharedPtr->m_threadWasRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (suspendOwnThread)
|
||||
{
|
||||
if (m_plutoSDRInputThread && m_plutoSDRInputThread->isRunning())
|
||||
{
|
||||
m_plutoSDRInputThread->stopWork();
|
||||
ownThreadWasRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: apply settings (all cases)
|
||||
|
||||
// Change affecting device baseband sample rate potentially affecting all buddies device/host sample rate
|
||||
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) ||
|
||||
(m_settings.m_rateGovernor != settings.m_rateGovernor) ||
|
||||
(m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim) || force)
|
||||
{
|
||||
forwardChangeAllDSP = true;
|
||||
}
|
||||
|
||||
if (suspendAllOtherThreads)
|
||||
{
|
||||
const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
|
||||
std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin();
|
||||
|
||||
for (; itSink != sinkBuddies.end(); ++itSink)
|
||||
{
|
||||
DevicePlutoSDRShared *buddySharedPtr = (DevicePlutoSDRShared *) (*itSink)->getBuddySharedPtr();
|
||||
|
||||
if (buddySharedPtr->m_threadWasRunning) {
|
||||
buddySharedPtr->m_thread->startWork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (suspendOwnThread)
|
||||
{
|
||||
if (ownThreadWasRunning) {
|
||||
m_plutoSDRInputThread->startWork();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -27,9 +27,33 @@
|
||||
|
||||
class DeviceSourceAPI;
|
||||
class FileRecord;
|
||||
class PlutoSDRInputThread;
|
||||
|
||||
class PlutoSDRInput : public DeviceSampleSource {
|
||||
public:
|
||||
class MsgConfigurePlutoSDR : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const PlutoSDRInputSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigurePlutoSDR* create(const PlutoSDRInputSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigurePlutoSDR(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
MsgConfigurePlutoSDR m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigurePlutoSDR(const PlutoSDRInputSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgFileRecord : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
@ -70,6 +94,7 @@ public:
|
||||
bool m_running;
|
||||
DevicePlutoSDRShared m_deviceShared;
|
||||
struct iio_buffer *m_plutoRxBuffer;
|
||||
PlutoSDRInputThread *m_plutoSDRInputThread;
|
||||
QMutex m_mutex;
|
||||
|
||||
bool openDevice();
|
||||
|
@ -38,6 +38,7 @@ void PlutoSDRInputSettings::resetToDefaults()
|
||||
m_lpfBW = 1500000.0f;
|
||||
m_lpfFIREnable = false;
|
||||
m_lpfFIRBW = 500000.0f;
|
||||
m_lpfFIRlog2Decim = 0;
|
||||
m_gain = 40;
|
||||
m_antennaPath = RFPATH_A_BAL;
|
||||
m_gainMode = GAIN_MANUAL;
|
||||
@ -48,6 +49,7 @@ QByteArray PlutoSDRInputSettings::serialize() const
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeS32(1, m_LOppmTenths);
|
||||
s.writeU32(3, m_lpfFIRlog2Decim);
|
||||
s.writeU32(4, m_log2Decim);
|
||||
s.writeS32(5, m_fcPos);
|
||||
s.writeS32(6, m_rateGovernor);
|
||||
@ -77,8 +79,15 @@ bool PlutoSDRInputSettings::deserialize(const QByteArray& data)
|
||||
if (d.getVersion() == 1)
|
||||
{
|
||||
int intval;
|
||||
uint32_t uintval;
|
||||
|
||||
d.readS32(1, &m_LOppmTenths, 0);
|
||||
d.readU32(3, &uintval, 0);
|
||||
if (uintval > 2) {
|
||||
m_lpfFIRlog2Decim = 2;
|
||||
} else {
|
||||
m_lpfFIRlog2Decim = uintval;
|
||||
}
|
||||
d.readU32(4, &m_log2Decim, 0);
|
||||
d.readS32(5, &intval, 0);
|
||||
if ((intval < 0) || (intval > 2)) {
|
||||
|
@ -58,18 +58,21 @@ struct PlutoSDRInputSettings {
|
||||
RATEGOV_END
|
||||
} RateGovernor;
|
||||
|
||||
// global settings to be saved
|
||||
quint64 m_centerFrequency;
|
||||
fcPos_t m_fcPos;
|
||||
qint32 m_LOppmTenths;
|
||||
quint32 m_log2Decim;
|
||||
quint64 m_devSampleRate;
|
||||
RateGovernor m_rateGovernor;
|
||||
// channel settings
|
||||
fcPos_t m_fcPos;
|
||||
qint32 m_LOppmTenths;
|
||||
bool m_dcBlock;
|
||||
bool m_iqCorrection;
|
||||
float m_lpfBW; //!< analog lowpass filter bandwidth (Hz)
|
||||
bool m_lpfFIREnable; //!< enable digital lowpass FIR filter
|
||||
float m_lpfFIRBW; //!< digital lowpass FIR filter bandwidth (Hz)
|
||||
uint32_t m_gain; //!< "hardware" gain
|
||||
quint32 m_log2Decim;
|
||||
float m_lpfBW; //!< analog lowpass filter bandwidth (Hz)
|
||||
bool m_lpfFIREnable; //!< enable digital lowpass FIR filter
|
||||
float m_lpfFIRBW; //!< digital lowpass FIR filter bandwidth (Hz)
|
||||
quint32 m_lpfFIRlog2Decim; //!< digital lowpass FIR filter log2 of decimation factor (0..2)
|
||||
uint32_t m_gain; //!< "hardware" gain
|
||||
RFPath m_antennaPath;
|
||||
GainMode m_gainMode;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user