From 7ddb62fb0de4686d246f9be76d06effac9e2f1c9 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 15 May 2019 08:33:13 +0200 Subject: [PATCH] MIMO support (2) --- sdrbase/dsp/dspdevicemimoengine.cpp | 207 +++++++++++++++++++++++++++- sdrbase/dsp/dspdevicemimoengine.h | 14 ++ 2 files changed, 220 insertions(+), 1 deletion(-) diff --git a/sdrbase/dsp/dspdevicemimoengine.cpp b/sdrbase/dsp/dspdevicemimoengine.cpp index 810b1bc6b..095ea6266 100644 --- a/sdrbase/dsp/dspdevicemimoengine.cpp +++ b/sdrbase/dsp/dspdevicemimoengine.cpp @@ -268,4 +268,209 @@ void DSPDeviceMIMOEngine::work(int nbWriteSamples, int nbReadSamples) } // for stream source // TODO: sinks -} \ No newline at end of file +} + +// notStarted -> idle -> init -> running -+ +// ^ | +// +-----------------------+ + +DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoIdle() +{ + qDebug() << "DSPDeviceMIMOEngine::gotoIdle"; + + switch(m_state) { + case StNotStarted: + return StNotStarted; + + case StIdle: + case StError: + return StIdle; + + case StReady: + case StRunning: + break; + } + + if (m_deviceSampleMIMO == 0) + { + return StIdle; + } + + // stop everything + + std::vector::const_iterator vbit = m_basebandSampleSinks.begin(); + + for (; vbit != m_basebandSampleSinks.end(); ++vbit) + { + for (BasebandSampleSinks::const_iterator it = vbit->begin(); it != vbit->end(); ++it) { + (*it)->stop(); + } + } + + std::vector::const_iterator vtit = m_threadedBasebandSampleSinks.begin(); + + for (; vtit != m_threadedBasebandSampleSinks.end(); vtit++) + { + for (ThreadedBasebandSampleSinks::const_iterator it = vtit->begin(); it != vtit->end(); ++it) { + (*it)->stop(); + } + } + + m_deviceSampleMIMO->stop(); + m_deviceDescription.clear(); + + for (std::vector::iterator it = m_sourceStreamSampleRates.begin(); it != m_sourceStreamSampleRates.end(); ++it) { + *it = 0; + } + + return StIdle; +} + +DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit() +{ + switch(m_state) { + case StNotStarted: + return StNotStarted; + + case StRunning: // FIXME: assumes it goes first through idle state. Could we get back to init from running directly? + return StRunning; + + case StReady: + return StReady; + + case StIdle: + case StError: + break; + } + + if (m_deviceSampleMIMO == 0) { + return gotoError("No sample MIMO configured"); + } + + // init: pass sample rate and center frequency to all sample rate and/or center frequency dependent sinks and wait for completion + + + m_deviceDescription = m_deviceSampleMIMO->getDeviceDescription(); + + qDebug() << "DSPDeviceMIMOEngine::gotoInit: " + << " m_deviceDescription: " << m_deviceDescription.toStdString().c_str(); + + for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSourceFifos(); isource++) + { + if (isource < m_sourcesCorrections.size()) + { + m_sourcesCorrections[isource].m_iOffset = 0; + m_sourcesCorrections[isource].m_qOffset = 0; + m_sourcesCorrections[isource].m_iRange = 1 << 16; + m_sourcesCorrections[isource].m_qRange = 1 << 16; + } + + if ((isource < m_sourceCenterFrequencies.size()) && (isource < m_sourceStreamSampleRates.size())) + { + m_sourceCenterFrequencies[isource] = m_deviceSampleMIMO->getSourceCenterFrequency(isource); + m_sourceStreamSampleRates[isource] = m_deviceSampleMIMO->getSourceSampleRate(isource); + + qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceCenterFrequencies[%d] = %llu", isource, m_sourceCenterFrequencies[isource]); + qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceStreamSampleRates[%d] = %d", isource, m_sourceStreamSampleRates[isource]); + + DSPSignalNotification notif(m_sourceStreamSampleRates[isource], m_sourceCenterFrequencies[isource]); + + if (isource < m_basebandSampleSinks.size()) + { + for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[isource].begin(); it != m_basebandSampleSinks[isource].end(); ++it) + { + qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing " << (*it)->objectName().toStdString().c_str(); + (*it)->handleMessage(notif); + } + } + + if (isource < m_threadedBasebandSampleSinks.size()) + { + for (ThreadedBasebandSampleSinks::const_iterator it = m_threadedBasebandSampleSinks[isource].begin(); it != m_threadedBasebandSampleSinks[isource].end(); ++it) + { + qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")"; + (*it)->handleSinkMessage(notif); + } + } + + // pass data to listeners + // if (m_deviceSampleSource->getMessageQueueToGUI()) + // { + // DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy for the output queue + // m_deviceSampleSource->getMessageQueueToGUI()->push(rep); + // } + } + } + + return StReady; +} + +DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoRunning() +{ + qDebug() << "DSPDeviceMIMOEngine::gotoRunning"; + + switch(m_state) + { + case StNotStarted: + return StNotStarted; + + case StIdle: + return StIdle; + + case StRunning: + return StRunning; + + case StReady: + case StError: + break; + } + + if (!m_deviceSampleMIMO) { + return gotoError("DSPDeviceMIMOEngine::gotoRunning: No sample source configured"); + } + + qDebug() << "DSPDeviceMIMOEngine::gotoRunning: " << m_deviceDescription.toStdString().c_str() << " started"; + + // Start everything + + if (!m_deviceSampleMIMO->start()) + { + return gotoError("Could not start sample source"); + } + + std::vector::const_iterator vbit = m_basebandSampleSinks.begin(); + + for (; vbit != m_basebandSampleSinks.end(); ++vbit) + { + for (BasebandSampleSinks::const_iterator it = vbit->begin(); it != vbit->end(); ++it) + { + qDebug() << "DSPDeviceMIMOEngine::gotoRunning: starting " << (*it)->objectName().toStdString().c_str(); + (*it)->start(); + } + } + + std::vector::const_iterator vtit = m_threadedBasebandSampleSinks.begin(); + + for (; vtit != m_threadedBasebandSampleSinks.end(); vtit++) + { + for (ThreadedBasebandSampleSinks::const_iterator it = vtit->begin(); it != vtit->end(); ++it) + { + qDebug() << "DSPDeviceMIMOEngine::gotoRunning: starting ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")"; + (*it)->start(); + } + } + + qDebug() << "DSPDeviceMIMOEngine::gotoRunning:input message queue pending: " << m_inputMessageQueue.size(); + + return StRunning; +} + +DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoError(const QString& errorMessage) +{ + qDebug() << "DSPDeviceMIMOEngine::gotoError: " << errorMessage; + + m_errorMessage = errorMessage; + m_deviceDescription.clear(); + m_state = StError; + return StError; +} diff --git a/sdrbase/dsp/dspdevicemimoengine.h b/sdrbase/dsp/dspdevicemimoengine.h index 153fb1cdd..0d26f12f7 100644 --- a/sdrbase/dsp/dspdevicemimoengine.h +++ b/sdrbase/dsp/dspdevicemimoengine.h @@ -211,6 +211,17 @@ public: QString deviceDescription(); //!< Return the device description private: + struct SourceCorrection + { + bool m_dcOffsetCorrection; + bool m_iqImbalanceCorrection; + double m_iOffset; + double m_qOffset; + int m_iRange; + int m_qRange; + int m_imbalance; + }; + uint32_t m_uid; //!< unique ID State m_state; @@ -232,8 +243,11 @@ private: typedef std::list ThreadedBasebandSampleSources; std::vector m_threadedBasebandSampleSources; //!< channel sample sources on their own threads (per output stream) + std::vector m_sourceCenterFrequencies; //!< device sources streams (Rx) sample rates + std::vector m_sinkCenterFrequencies; //!< device sink streams (Tx) sample rates std::vector m_sourceStreamSampleRates; //!< device sources streams (Rx) sample rates std::vector m_sinkStreamSampleRates; //!< device sink streams (Tx) sample rates + std::vector m_sourcesCorrections; BasebandSampleSink *m_spectrumSink; //!< The spectrum sink