PlutoSDR MIMO: recognize user defined MIMO devices

This commit is contained in:
f4exb 2021-05-02 13:06:10 +02:00
parent 672c0b8a5b
commit 38d2a19338
9 changed files with 128 additions and 11 deletions

View File

@ -494,7 +494,7 @@ struct iio_buffer *DevicePlutoSDRBox::createRxBuffer(unsigned int size, bool cyc
if (m_devRx) { if (m_devRx) {
m_rxBuf = iio_device_create_buffer(m_devRx, size, cyclic ? '\1' : '\0'); m_rxBuf = iio_device_create_buffer(m_devRx, size, cyclic ? '\1' : '\0');
} else { } else {
m_rxBuf = 0; m_rxBuf = nullptr;
} }
return m_rxBuf; return m_rxBuf;
@ -505,7 +505,7 @@ struct iio_buffer *DevicePlutoSDRBox::createTxBuffer(unsigned int size, bool cyc
if (m_devTx) { if (m_devTx) {
m_txBuf = iio_device_create_buffer(m_devTx, size, cyclic ? '\1' : '\0'); m_txBuf = iio_device_create_buffer(m_devTx, size, cyclic ? '\1' : '\0');
} else { } else {
m_txBuf = 0; m_txBuf = nullptr;
} }
return m_txBuf; return m_txBuf;
@ -513,17 +513,19 @@ struct iio_buffer *DevicePlutoSDRBox::createTxBuffer(unsigned int size, bool cyc
void DevicePlutoSDRBox::deleteRxBuffer() void DevicePlutoSDRBox::deleteRxBuffer()
{ {
if (m_rxBuf) { if (m_rxBuf)
{
iio_buffer_destroy(m_rxBuf); iio_buffer_destroy(m_rxBuf);
m_rxBuf = 0; m_rxBuf = nullptr;
} }
} }
void DevicePlutoSDRBox::deleteTxBuffer() void DevicePlutoSDRBox::deleteTxBuffer()
{ {
if (m_txBuf) { if (m_txBuf)
{
iio_buffer_destroy(m_txBuf); iio_buffer_destroy(m_txBuf);
m_txBuf = 0; m_txBuf = nullptr;
} }
} }

View File

@ -44,9 +44,11 @@ PlutoSDRMIMO::PlutoSDRMIMO(DeviceAPI *deviceAPI) :
m_settings(), m_settings(),
m_sourceThread(nullptr), m_sourceThread(nullptr),
m_sinkThread(nullptr), m_sinkThread(nullptr),
m_deviceDescription("BladeRF2MIMO"), m_deviceDescription("PlutoSDRMIMO"),
m_runningRx(false), m_runningRx(false),
m_runningTx(false), m_runningTx(false),
m_plutoRxBuffer(nullptr),
m_plutoTxBuffer(nullptr),
m_plutoParams(nullptr), m_plutoParams(nullptr),
m_open(false), m_open(false),
m_nbRx(0), m_nbRx(0),
@ -83,6 +85,7 @@ void PlutoSDRMIMO::destroy()
bool PlutoSDRMIMO::openDevice() bool PlutoSDRMIMO::openDevice()
{ {
qDebug("PlutoSDRMIMO::openDevice: open device here");
m_plutoParams = new DevicePlutoSDRParams(); m_plutoParams = new DevicePlutoSDRParams();
if (m_deviceAPI->getHardwareUserArguments().size() != 0) if (m_deviceAPI->getHardwareUserArguments().size() != 0)
@ -116,7 +119,11 @@ bool PlutoSDRMIMO::openDevice()
char serial[256]; char serial[256];
strcpy(serial, qPrintable(m_deviceAPI->getSamplingDeviceSerial())); strcpy(serial, qPrintable(m_deviceAPI->getSamplingDeviceSerial()));
if (!m_plutoParams->open(serial)) if (m_plutoParams->open(serial))
{
qDebug("PlutoSDRMIMO::openDevice: device serial %s opened", serial);
}
else
{ {
qCritical("PlutoSDRMIMO::openDevice: open serial %s failed", serial); qCritical("PlutoSDRMIMO::openDevice: open serial %s failed", serial);
return false; return false;
@ -182,6 +189,7 @@ bool PlutoSDRMIMO::startRx()
m_plutoParams->getBox()->openSecondRx(); m_plutoParams->getBox()->openSecondRx();
} }
m_plutoRxBuffer = m_plutoParams->getBox()->createRxBuffer(PlutoSDRMIMOSettings::m_plutoSDRBlockSizeSamples, false);
m_sourceThread->startWork(); m_sourceThread->startWork();
mutexLocker.unlock(); mutexLocker.unlock();
m_runningRx = true; m_runningRx = true;
@ -219,6 +227,7 @@ bool PlutoSDRMIMO::startTx()
m_plutoParams->getBox()->openSecondTx(); m_plutoParams->getBox()->openSecondTx();
} }
m_plutoTxBuffer = m_plutoParams->getBox()->createRxBuffer(PlutoSDRMIMOSettings::m_plutoSDRBlockSizeSamples, false);
m_sinkThread->startWork(); m_sinkThread->startWork();
mutexLocker.unlock(); mutexLocker.unlock();
m_runningTx = true; m_runningTx = true;
@ -248,6 +257,9 @@ void PlutoSDRMIMO::stopRx()
if (m_nbRx > 0) { if (m_nbRx > 0) {
m_plutoParams->getBox()->closeRx(); m_plutoParams->getBox()->closeRx();
} }
m_plutoParams->getBox()->deleteRxBuffer();
m_plutoRxBuffer = nullptr;
} }
void PlutoSDRMIMO::stopTx() void PlutoSDRMIMO::stopTx()
@ -272,6 +284,9 @@ void PlutoSDRMIMO::stopTx()
if (m_nbTx > 0) { if (m_nbTx > 0) {
m_plutoParams->getBox()->closeTx(); m_plutoParams->getBox()->closeTx();
} }
m_plutoParams->getBox()->deleteTxBuffer();
m_plutoRxBuffer = nullptr;
} }
QByteArray PlutoSDRMIMO::serialize() const QByteArray PlutoSDRMIMO::serialize() const

View File

@ -177,6 +177,8 @@ private:
QString m_deviceDescription; QString m_deviceDescription;
bool m_runningRx; bool m_runningRx;
bool m_runningTx; bool m_runningTx;
struct iio_buffer *m_plutoRxBuffer;
struct iio_buffer *m_plutoTxBuffer;
QNetworkAccessManager *m_networkManager; QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest; QNetworkRequest m_networkRequest;

View File

@ -39,7 +39,7 @@ const PluginDescriptor PlutoSDRMIMOPlugin::m_pluginDescriptor = {
}; };
static constexpr const char* const m_hardwareID = "PlutoSDR"; static constexpr const char* const m_hardwareID = "PlutoSDR";
static constexpr const char* const m_deviceTypeID = PLUTOSDRMIMO_DEVICE_TYPE_ID; const char* const PlutoSDRMIMOPlugin::m_deviceTypeID = PLUTOSDRMIMO_DEVICE_TYPE_ID;
PlutoSDRMIMOPlugin::PlutoSDRMIMOPlugin(QObject* parent) : PlutoSDRMIMOPlugin::PlutoSDRMIMOPlugin(QObject* parent) :
QObject(parent) QObject(parent)

View File

@ -23,7 +23,7 @@
class PluginAPI; class PluginAPI;
#define PLUTOSDRMIMO_DEVICE_TYPE_ID "sdrangel.samplemimo.bladerf2mimo" #define PLUTOSDRMIMO_DEVICE_TYPE_ID "sdrangel.samplemimo.plutosdrmimo"
class PlutoSDRMIMOPlugin : public QObject, public PluginInterface { class PlutoSDRMIMOPlugin : public QObject, public PluginInterface {
Q_OBJECT Q_OBJECT
@ -45,6 +45,9 @@ public:
DeviceUISet *deviceUISet); DeviceUISet *deviceUISet);
virtual DeviceSampleMIMO* createSampleMIMOPluginInstance(const QString& sourceId, DeviceAPI *deviceAPI); virtual DeviceSampleMIMO* createSampleMIMOPluginInstance(const QString& sourceId, DeviceAPI *deviceAPI);
virtual DeviceWebAPIAdapter* createDeviceWebAPIAdapter() const; virtual DeviceWebAPIAdapter* createDeviceWebAPIAdapter() const;
virtual QString getDeviceTypeId() const { return m_deviceTypeID; }
static const char* const m_deviceTypeID;
private: private:
static const PluginDescriptor m_pluginDescriptor; static const PluginDescriptor m_pluginDescriptor;

View File

@ -40,6 +40,7 @@ void DeviceEnumerator::addNonDiscoverableDevices(PluginManager *pluginManager, c
QList<DeviceUserArgs::Args>::const_iterator argsIt = args.begin(); QList<DeviceUserArgs::Args>::const_iterator argsIt = args.begin();
unsigned int rxIndex = m_rxEnumeration.size(); unsigned int rxIndex = m_rxEnumeration.size();
unsigned int txIndex = m_txEnumeration.size(); unsigned int txIndex = m_txEnumeration.size();
unsigned int mimoIndex = m_mimoEnumeration.size();
for (; argsIt != args.end(); ++argsIt) for (; argsIt != args.end(); ++argsIt)
{ {
@ -47,6 +48,7 @@ void DeviceEnumerator::addNonDiscoverableDevices(PluginManager *pluginManager, c
continue; continue;
} }
// qDebug("DeviceEnumerator::addNonDiscoverableDevices: device: %s[%d]", qPrintable(argsIt->m_id), argsIt->m_sequence);
QString serial = QString("%1-%2").arg(argsIt->m_id).arg(argsIt->m_sequence); QString serial = QString("%1-%2").arg(argsIt->m_id).arg(argsIt->m_sequence);
PluginInterface *rxPlugin = getRxRegisteredPlugin(pluginManager, argsIt->m_id); PluginInterface *rxPlugin = getRxRegisteredPlugin(pluginManager, argsIt->m_id);
@ -99,7 +101,7 @@ void DeviceEnumerator::addNonDiscoverableDevices(PluginManager *pluginManager, c
deviceId, // id deviceId, // id
serial, serial,
argsIt->m_sequence, argsIt->m_sequence,
rxPlugin->getSamplingDeviceType(), txPlugin->getSamplingDeviceType(),
PluginInterface::SamplingDevice::StreamSingleTx, PluginInterface::SamplingDevice::StreamSingleTx,
deviceNbItems, // deviceNbItems deviceNbItems, // deviceNbItems
deviceIndex // deviceItemIndex deviceIndex // deviceItemIndex
@ -114,6 +116,39 @@ void DeviceEnumerator::addNonDiscoverableDevices(PluginManager *pluginManager, c
txIndex++; txIndex++;
} }
} }
PluginInterface *mimoPlugin = getMIMORegisteredPlugin(pluginManager, argsIt->m_id);
if (mimoPlugin && !isMIMOEnumerated(argsIt->m_id, argsIt->m_sequence))
{
int deviceNbItems = mimoPlugin->getDefaultMIMONbItems();
QString deviceId = mimoPlugin->getDeviceTypeId();
for (int deviceIndex = 0; deviceIndex < deviceNbItems; deviceIndex++)
{
QString description = QString("%1[%2:%3] user defined").arg(argsIt->m_id).arg(argsIt->m_sequence).arg(deviceIndex);
qDebug("DeviceEnumerator::addNonDiscoverableDevices: MIMO: %s", qPrintable(description));
PluginInterface::SamplingDevice ndDevice(
description,
argsIt->m_id,
deviceId, // id
serial,
argsIt->m_sequence,
mimoPlugin->getSamplingDeviceType(),
PluginInterface::SamplingDevice::StreamMIMO,
deviceNbItems, // deviceNbItems
deviceIndex // deviceItemIndex
);
m_mimoEnumeration.push_back(
DeviceEnumeration(
ndDevice,
mimoPlugin,
mimoIndex
)
);
mimoIndex++;
}
}
} // loop through user args } // loop through user args
} }
@ -180,6 +215,37 @@ bool DeviceEnumerator::isTxEnumerated(const QString& deviceHwId, int deviceSeque
return false; return false;
} }
PluginInterface *DeviceEnumerator::getMIMORegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId)
{
PluginAPI::SamplingDeviceRegistrations& mimoDeviceRegistrations = pluginManager->getMIMODeviceRegistrations();
PluginInterface *mimoPlugin = nullptr;
for (int i = 0; i < mimoDeviceRegistrations.count(); i++)
{
if (deviceHwId == mimoDeviceRegistrations[i].m_deviceHardwareId)
{
mimoPlugin = mimoDeviceRegistrations[i].m_plugin;
break;
}
}
return mimoPlugin;
}
bool DeviceEnumerator::isMIMOEnumerated(const QString& deviceHwId, int deviceSequence)
{
std::vector<DeviceEnumeration>::const_iterator mimoIt = m_mimoEnumeration.begin();
for (; mimoIt != m_mimoEnumeration.end(); ++mimoIt)
{
if ((mimoIt->m_samplingDevice.hardwareId == deviceHwId) && (mimoIt->m_samplingDevice.sequence == deviceSequence)) {
return true;
}
}
return false;
}
void DeviceEnumerator::enumerateRxDevices(PluginManager *pluginManager) void DeviceEnumerator::enumerateRxDevices(PluginManager *pluginManager)
{ {
m_rxEnumeration.clear(); m_rxEnumeration.clear();

View File

@ -87,8 +87,10 @@ private:
PluginInterface *getRxRegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId); PluginInterface *getRxRegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId);
PluginInterface *getTxRegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId); PluginInterface *getTxRegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId);
PluginInterface *getMIMORegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId);
bool isRxEnumerated(const QString& deviceHwId, int deviceSequence); bool isRxEnumerated(const QString& deviceHwId, int deviceSequence);
bool isTxEnumerated(const QString& deviceHwId, int deviceSequence); bool isTxEnumerated(const QString& deviceHwId, int deviceSequence);
bool isMIMOEnumerated(const QString& deviceHwId, int deviceSequence);
}; };
#endif /* SDRBASE_DEVICE_DEVICEENUMERATOR_H_ */ #endif /* SDRBASE_DEVICE_DEVICEENUMERATOR_H_ */

View File

@ -307,6 +307,10 @@ public:
virtual void deleteSampleMIMOPluginInstanceMIMO(DeviceSampleMIMO *mimo); virtual void deleteSampleMIMOPluginInstanceMIMO(DeviceSampleMIMO *mimo);
virtual int getDefaultMIMONbItems() const {
return 1;
}
// Callback to allow plugin to add elements to top-level GUI (such as menu items) // Callback to allow plugin to add elements to top-level GUI (such as menu items)
virtual bool createTopLevelGUI() virtual bool createTopLevelGUI()
{ {

View File

@ -1794,6 +1794,14 @@ void MainWindow::sampleSourceChanged(int tabIndex, int newDeviceIndex)
deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(newDeviceIndex)); deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(newDeviceIndex));
qDebug() << "MainWindow::sampleSourceChanged:"
<< "newDeviceIndex:" << newDeviceIndex
<< "hardwareId:" << samplingDevice->hardwareId
<< "sequence:" << samplingDevice->sequence
<< "id:" << samplingDevice->id
<< "serial:" << samplingDevice->serial
<< "displayedName:" << samplingDevice->displayedName;
if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default
{ {
qDebug("MainWindow::sampleSourceChanged: non existent device replaced by File Input"); qDebug("MainWindow::sampleSourceChanged: non existent device replaced by File Input");
@ -1899,6 +1907,14 @@ void MainWindow::sampleSinkChanged(int tabIndex, int newDeviceIndex)
deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(newDeviceIndex)); deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(newDeviceIndex));
qDebug() << "MainWindow::sampleSinkChanged:"
<< "newDeviceIndex:" << newDeviceIndex
<< "hardwareId:" << samplingDevice->hardwareId
<< "sequence:" << samplingDevice->sequence
<< "id:" << samplingDevice->id
<< "serial:" << samplingDevice->serial
<< "displayedName:" << samplingDevice->displayedName;
if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default
{ {
qDebug("MainWindow::sampleSinkChanged: non existent device replaced by File Sink"); qDebug("MainWindow::sampleSinkChanged: non existent device replaced by File Sink");
@ -1996,6 +2012,13 @@ void MainWindow::sampleMIMOChanged(int tabIndex, int newDeviceIndex)
deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getMIMOPluginInterface(newDeviceIndex)); deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getMIMOPluginInterface(newDeviceIndex));
qDebug() << "MainWindow::sampleMIMOChanged:"
<< "newDeviceIndex:" << newDeviceIndex
<< "hardwareId:" << samplingDevice->hardwareId
<< "sequence:" << samplingDevice->sequence
<< "id:" << samplingDevice->id
<< "serial:" << samplingDevice->serial
<< "displayedName:" << samplingDevice->displayedName;
if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default
{ {