19 #include <QNetworkReply> 36 #define PLUTOSDR_BLOCKSIZE_SAMPLES (16*1024) //complex samples per buffer (must be multiple of 64) 42 m_deviceAPI(deviceAPI),
47 m_plutoSDROutputThread(0)
49 m_deviceAPI->setNbSinkStreams(1);
50 m_deviceSampleRates.m_addaConnvRate = 0;
51 m_deviceSampleRates.m_bbRateHz = 0;
52 m_deviceSampleRates.m_firRate = 0;
53 m_deviceSampleRates.m_hb1Rate = 0;
54 m_deviceSampleRates.m_hb2Rate = 0;
55 m_deviceSampleRates.m_hb3Rate = 0;
61 m_networkManager =
new QNetworkAccessManager();
62 connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(networkManagerFinished(QNetworkReply*)));
96 qDebug(
"PlutoSDROutput::start: thread created");
183 qDebug() <<
"PlutoSDROutput::handleMessage: MsgConfigurePlutoSDR";
187 qDebug(
"PlutoSDROutput::handleMessage config error");
208 qDebug() <<
"PlutoSDROutput::handleMessage: MsgStartStop: " << (cmd.
getStartStop() ?
"start" :
"stop");
241 qDebug(
"PlutoSDROutput::openDevice: look at Rx buddy");
249 qCritical(
"PlutoSDROutput::openDevice: cannot get device parameters from Rx buddy");
254 qDebug(
"PlutoSDROutput::openDevice: getting device parameters from Rx buddy");
261 qDebug(
"PlutoSDROutput::openDevice: open device here");
325 bool forwardChangeOwnDSP =
false;
326 bool forwardChangeOtherDSP =
false;
327 bool ownThreadWasRunning =
false;
328 bool suspendAllOtherThreads =
false;
331 QList<QString> reverseAPIKeys;
346 <<
" force: " << force;
349 reverseAPIKeys.append(
"devSampleRate");
352 reverseAPIKeys.append(
"lpfFIREnable");
355 reverseAPIKeys.append(
"lpfFIRlog2Interp");
358 reverseAPIKeys.append(
"lpfFIRBW");
361 reverseAPIKeys.append(
"lpfFIRGain");
364 reverseAPIKeys.append(
"LOppmTenths");
381 suspendAllOtherThreads =
true;
384 if (suspendAllOtherThreads)
387 std::vector<DeviceAPI*>::const_iterator itSink = sourceBuddies.begin();
389 for (; itSink != sourceBuddies.end(); ++itSink)
407 ownThreadWasRunning =
true;
431 forwardChangeOtherDSP =
true;
437 reverseAPIKeys.append(
"log2Interp");
443 qDebug() <<
"PlutoSDROutput::applySettings: set soft interpolation in thread to " << (1<<settings.
m_log2Interp);
446 forwardChangeOwnDSP =
true;
452 forwardChangeOtherDSP =
true;
455 std::vector<std::string> params;
456 bool paramsToSet =
false;
459 reverseAPIKeys.append(
"centerFrequency");
462 reverseAPIKeys.append(
"transverterMode");
465 reverseAPIKeys.append(
"transverterDeltaFrequency");
475 deviceCenterFrequency = deviceCenterFrequency < 0 ? 0 : deviceCenterFrequency;
478 params.push_back(QString(tr(
"out_altvoltage1_TX_LO_frequency=%1").
arg(deviceCenterFrequency)).toStdString());
480 forwardChangeOwnDSP =
true;
482 qDebug() <<
"PlutoSDROutput::applySettings: center freq: " << settings.
m_centerFrequency <<
" Hz" 483 <<
" device center freq: " << deviceCenterFrequency <<
" Hz";
489 reverseAPIKeys.append(
"lpfBW");
490 params.push_back(QString(tr(
"out_voltage_rf_bandwidth=%1").
arg(settings.
m_lpfBW)).toStdString());
496 reverseAPIKeys.append(
"antennaPath");
499 params.push_back(QString(tr(
"out_voltage0_rf_port_select=%1").
arg(rfPortStr)).toStdString());
505 reverseAPIKeys.append(
"att");
506 float attF = settings.
m_att * 0.25f;
507 params.push_back(QString(tr(
"out_voltage0_hardwaregain=%1").
arg(attF)).toStdString());
527 if (suspendAllOtherThreads)
530 std::vector<DeviceAPI*>::const_iterator itSource = sourceBuddies.begin();
532 for (; itSource != sourceBuddies.end(); ++itSource)
542 if (ownThreadWasRunning) {
547 if (forwardChangeOtherDSP)
549 qDebug(
"PlutoSDROutput::applySettings: forwardChangeOtherDSP");
552 std::vector<DeviceAPI*>::const_iterator itSource = sourceBuddies.begin();
554 for (; itSource != sourceBuddies.end(); ++itSource)
563 if ((*itSource)->getSamplingDeviceGUIMessageQueue())
566 (*itSource)->getSamplingDeviceGUIMessageQueue()->push(msgToGUI);
569 (*itSource)->getSamplingDeviceInputMessageQueue()->push(msg);
573 if (forwardChangeOwnDSP)
575 qDebug(
"PlutoSDROutput::applySettings: forward change to self");
628 QString& errorMessage)
638 QString& errorMessage)
656 QString& errorMessage)
667 const QStringList& deviceSettingsKeys,
669 QString& errorMessage)
674 if (deviceSettingsKeys.contains(
"centerFrequency")) {
677 if (deviceSettingsKeys.contains(
"devSampleRate")) {
680 if (deviceSettingsKeys.contains(
"LOppmTenths")) {
683 if (deviceSettingsKeys.contains(
"lpfFIREnable")) {
686 if (deviceSettingsKeys.contains(
"lpfFIRBW")) {
689 if (deviceSettingsKeys.contains(
"lpfFIRlog2Interp")) {
692 if (deviceSettingsKeys.contains(
"lpfFIRGain")) {
695 if (deviceSettingsKeys.contains(
"log2Interp")) {
698 if (deviceSettingsKeys.contains(
"lpfBW")) {
701 if (deviceSettingsKeys.contains(
"att")) {
704 if (deviceSettingsKeys.contains(
"antennaPath")) {
709 if (deviceSettingsKeys.contains(
"transverterDeltaFrequency")) {
712 if (deviceSettingsKeys.contains(
"transverterMode")) {
715 if (deviceSettingsKeys.contains(
"useReverseAPI")) {
718 if (deviceSettingsKeys.contains(
"reverseAPIAddress")) {
721 if (deviceSettingsKeys.contains(
"reverseAPIPort")) {
724 if (deviceSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
743 QString& errorMessage)
800 if (deviceSettingsKeys.contains(
"centerFrequency") || force) {
803 if (deviceSettingsKeys.contains(
"devSampleRate") || force) {
806 if (deviceSettingsKeys.contains(
"LOppmTenths") || force) {
809 if (deviceSettingsKeys.contains(
"lpfFIREnable") || force) {
812 if (deviceSettingsKeys.contains(
"lpfFIRBW") || force) {
815 if (deviceSettingsKeys.contains(
"lpfFIRlog2Interp") || force) {
818 if (deviceSettingsKeys.contains(
"lpfFIRGain") || force) {
821 if (deviceSettingsKeys.contains(
"log2Interp") || force) {
824 if (deviceSettingsKeys.contains(
"lpfBW") || force) {
827 if (deviceSettingsKeys.contains(
"att") || force) {
830 if (deviceSettingsKeys.contains(
"antennaPath") || force) {
833 if (deviceSettingsKeys.contains(
"transverterDeltaFrequency") || force) {
836 if (deviceSettingsKeys.contains(
"transverterMode") || force) {
840 QString deviceSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/device/settings")
845 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
847 QBuffer *buffer=
new QBuffer();
848 buffer->open((QBuffer::ReadWrite));
849 buffer->write(swgDeviceSettings->
asJson().toUtf8());
855 delete swgDeviceSettings;
865 QString deviceSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/device/run")
870 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
872 QBuffer *buffer=
new QBuffer();
873 buffer->open((QBuffer::ReadWrite));
874 buffer->write(swgDeviceSettings->
asJson().toUtf8());
883 delete swgDeviceSettings;
888 QNetworkReply::NetworkError replyError = reply->error();
892 qWarning() <<
"PlutoSDROutput::networkManagerFinished:" 893 <<
" error(" << (int) replyError
894 <<
"): " << replyError
895 <<
": " << reply->errorString();
899 QString answer = reply->readAll();
901 qDebug(
"PlutoSDROutput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
qint32 m_LOppmTenths
XO correction.
void webapiReverseSendStartStop(bool start)
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
QString m_reverseAPIAddress
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
void setSampleRate(uint32_t sampleRate)
struct iio_buffer * m_plutoTxBuffer
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
void setPlutoSdrOutputSettings(SWGPlutoSdrOutputSettings *pluto_sdr_output_settings)
uint32_t getLpfFiRlog2IntDec() const
bool m_threadWasRunning
flag to know if thread needs to be resumed after suspend
void setReverseApiAddress(QString *reverse_api_address)
bool isLpfFirEnable() const
virtual QString asJson() override
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
qint64 getTransverterDeltaFrequency()
qint32 getTransverterMode()
ThreadInterface * m_thread
holds the thread address if started else 0
void setCenterFrequency(qint64 center_frequency)
void setLog2Interp(qint32 log2_interp)
void setLpfFirbw(qint32 lpf_firbw)
void setTransverterMode(qint32 transverter_mode)
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
SWGPlutoSdrOutputSettings * getPlutoSdrOutputSettings()
qint32 m_att
"hardware" attenuation in dB fourths
bool getTxRSSI(std::string &rssiStr, unsigned int chan)
void setRssi(QString *rssi)
void setLpfFiRlog2Interp(qint32 lpf_fi_rlog2_interp)
virtual const QString & getDeviceDescription() const
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
void setOriginatorIndex(qint32 originator_index)
DevicePlutoSDRParams * m_deviceParams
unique hardware device parameters
void setLpfFirEnable(qint32 lpf_fir_enable)
bool open(const std::string &serial)
uint32_t m_hb3Rate
Rate of the HB3/(DEC3 or INT3) filter (Rx: out, Tx: in) - this is the HB2 working sample rate...
static MsgCrossReportToBuddy * create(uint64_t devSampleRate, bool lpfFIREnable, uint32_t lpfFIRlog2Interp, uint32_t lpfFIRBW, int32_t loPPMTenths)
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
void setDacRate(qint32 dac_rate)
virtual quint64 getCenterFrequency() const
Center frequency exposed by the sink.
MessageQueue m_inputMessageQueue
Input queue to the sink.
void setFIREnable(bool enable)
void getRSSI(std::string &rssiStr)
uint16_t m_reverseAPIDeviceIndex
int getDeviceSetIndex() const
SWGPlutoSdrOutputReport * getPlutoSdrOutputReport()
qint32 getReverseApiDeviceIndex()
qint64 getCenterFrequency()
void * getBuddySharedPtr() const
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
quint32 m_lpfBW
analog lowpass filter bandwidth (Hz)
bool deserialize(const QByteArray &data)
void setAntennaPath(qint32 antenna_path)
void setLOPPMTenths(int ppmTenths)
qint32 getLpfFiRlog2Interp()
PlutoSDROutputThread * m_plutoSDROutputThread
void setPlutoSdrOutputReport(SWGPlutoSdrOutputReport *pluto_sdr_output_report)
DevicePlutoSDRBox::SampleRates m_deviceSampleRates
void setTemperature(float temperature)
void setFIR(uint32_t sampleRate, uint32_t intdec, DeviceUse use, uint32_t bw, int gain)
uint16_t m_reverseAPIPort
bool m_lpfFIREnable
enable digital lowpass FIR filter
qint32 getDevSampleRate()
void setBuddySharedPtr(void *ptr)
QNetworkRequest m_networkRequest
virtual bool deserialize(const QByteArray &data)
QString * getReverseApiAddress()
QByteArray serialize() const
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const PlutoSDROutputSettings &settings, bool force)
virtual void stopWork()=0
static bool match(const Message *message)
static void translateRFPath(RFPath path, QString &s)
uint32_t getLpfFirbw() const
void networkManagerFinished(QNetworkReply *reply)
int32_t getLoPPMTenths() const
void setDevSampleRate(qint32 dev_sample_rate)
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
bool getTxSampleRates(SampleRates &sampleRates)
DevicePlutoSDRShared m_deviceShared
void getTxLORange(uint64_t &minLimit, uint64_t &maxLimit)
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
struct iio_buffer * createTxBuffer(unsigned int size, bool cyclic)
uint32_t m_firRate
Rate of FIR filter (Rx: out, Tx: in) - this is the host/device communication sample rate...
quint32 m_lpfFIRlog2Interp
digital lowpass FIR filter log2 of interpolation factor (0..2)
DevicePlutoSDRBox * getBox()
void getDeviceEngineStateStr(QString &state)
bool applySettings(const PlutoSDROutputSettings &settings, bool force=false)
uint32_t m_hb2Rate
Rate of the HB2 filter (Rx: out, Tx: in) - this is the HB1 working sample rate.
void resize(uint32_t size)
const QString & getSamplingDeviceSerial() const
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
void setLpfBw(qint32 lpf_bw)
virtual QByteArray serialize() const
void setTransverterDeltaFrequency(qint64 transverter_delta_frequency)
quint64 m_devSampleRate
Host interface sample rate.
bool getStartStop() const
QNetworkAccessManager * m_networkManager
uint32_t m_hb1Rate
Rate of the HB1 filter (Rx: out, Tx: in) - this is the FIR working sample rate.
void getbbLPRange(quint32 &minLimit, quint32 &maxLimit)
SampleSourceFifo m_sampleSourceFifo
const std::vector< DeviceAPI * > & getSourceBuddies() const
void setUseReverseApi(qint32 use_reverse_api)
void setLpfFirGain(qint32 lpf_fir_gain)
uint32_t m_bbRateHz
Baseband PLL rate (Hz) - used internally.
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const PlutoSDROutputSettings &settings)
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport &response)
qint64 m_transverterDeltaFrequency
void setReverseApiPort(qint32 reverse_api_port)
static MsgStartStop * create(bool startStop)
void getLORange(qint64 &minLimit, qint64 &maxLimit)
quint64 m_centerFrequency
QString m_deviceDescription
#define PLUTOSDR_BLOCKSIZE_SAMPLES
void setDirection(qint32 direction)
uint32_t m_addaConnvRate
A/D or D/A converter rat - this is the HB3 working sample rate.
uint32_t getDACSampleRate() const
virtual void setCenterFrequency(qint64 centerFrequency)
int m_lpfFIRGain
digital lowpass FIR filter gain (dB)
virtual int getSampleRate() const
Sample rate exposed by the sink.
quint32 m_lpfFIRBW
digital lowpass FIR filter bandwidth (Hz)
void getbbLPTxRange(uint32_t &minLimit, uint32_t &maxLimit)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
qint32 getUseReverseApi()
PlutoSDROutputSettings m_settings
T max(const T &x, const T &y)
virtual int webapiReportGet(SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
qint32 getReverseApiPort()
virtual void startWork()=0
void setDeviceHwType(QString *device_hw_type)
void setLog2Interpolation(unsigned int log2_interp)
void set_params(DeviceType devType, const std::vector< std::string > ¶ms)
virtual bool handleMessage(const Message &message)
uint64_t getDevSampleRate() const
T min(const T &x, const T &y)
unsigned __int64 uint64_t
void setLOppmTenths(qint32 l_oppm_tenths)