mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 20:40:20 -04:00 
			
		
		
		
	PlutoSDR: set FIR filter (2)
This commit is contained in:
		
							parent
							
								
									7acd2bb7ed
								
							
						
					
					
						commit
						11b657a841
					
				| @ -15,7 +15,6 @@ | ||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <cstdio> | ||||
| #include <cstring> | ||||
| #include <regex> | ||||
| @ -23,6 +22,7 @@ | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <QtGlobal> | ||||
| 
 | ||||
| #include "dsp/wfir.h" | ||||
| #include "deviceplutosdrbox.h" | ||||
| 
 | ||||
| DevicePlutoSDRBox::DevicePlutoSDRBox(const std::string& uri) : | ||||
| @ -397,13 +397,20 @@ bool DevicePlutoSDRBox::parseSampleRates(const std::string& rateStr, SampleRates | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void DevicePlutoSDRBox::set_filterBW(DeviceUse use, uint32_t intdec, uint32_t bw) | ||||
| void DevicePlutoSDRBox::setFIR(DeviceUse use, uint32_t intdec, uint32_t bw, int gain) | ||||
| { | ||||
|     SampleRates sampleRates; | ||||
|     std::ostringstream ostr; | ||||
| 
 | ||||
|     uint32_t nbTaps; | ||||
|     float normalizedBW; | ||||
|     double normalizedBW; | ||||
| 
 | ||||
|     // set a dummy minimal filter first to get the sample rates right
 | ||||
| 
 | ||||
|     formatFIRHeader(ostr, use, intdec, gain); | ||||
|     formatFIRCoefficients(ostr, 16, 0.5); | ||||
|     setFilter(ostr.str()); | ||||
|     ostr.str(""); // reset string stream
 | ||||
| 
 | ||||
|     if (use == USE_RX) | ||||
|     { | ||||
| @ -428,7 +435,27 @@ void DevicePlutoSDRBox::set_filterBW(DeviceUse use, uint32_t intdec, uint32_t bw | ||||
|         normalizedBW = ((float) bw) / sampleRates.m_hb1Rate; | ||||
|         normalizedBW = normalizedBW < 0.1 ? 0.1 : normalizedBW > 0.9 ? 0.9 : normalizedBW; | ||||
|     } | ||||
| 
 | ||||
|     // set the right filter
 | ||||
| 
 | ||||
|     formatFIRHeader(ostr, use, intdec, gain); | ||||
|     formatFIRCoefficients(ostr, nbTaps, normalizedBW); | ||||
|     setFilter(ostr.str()); | ||||
| } | ||||
| 
 | ||||
| void DevicePlutoSDRBox::formatFIRHeader(std::ostringstream& ostr, DeviceUse use, uint32_t intdec, int32_t gain) | ||||
| { | ||||
|     ostr << use == USE_RX ? "RX 1" : "TX 1" << " GAIN " << gain << " DEC " << intdec << std::endl; | ||||
| } | ||||
| 
 | ||||
| void DevicePlutoSDRBox::formatFIRCoefficients(std::ostringstream& ostr, uint32_t nbTaps, double normalizedBW) | ||||
| { | ||||
|     double fcoeffs = new double[nbTaps]; | ||||
|     WFIR::BasicFIR(fcoeffs, nbTaps, WFIR::LPF, 0.0, normalizedBW, WFIR::wtBLACKMAN_HARRIS, 0.0); | ||||
| 
 | ||||
|     for (int i = 0; i < nbTaps; i++) { | ||||
|         ostr << (uint16_t) (fcoeffs[i] * 32768.0) << std::endl; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -17,6 +17,7 @@ | ||||
| #ifndef DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ | ||||
| #define DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ | ||||
| 
 | ||||
| #include <sstream> | ||||
| #include <stdint.h> | ||||
| #include <sys/types.h> | ||||
| #include "deviceplutosdrscan.h" | ||||
| @ -79,7 +80,7 @@ public: | ||||
|     char* txBufferFirst(); | ||||
|     bool getRxSampleRates(SampleRates& sampleRates); | ||||
|     bool getTxSampleRates(SampleRates& sampleRates); | ||||
|     void set_filterBW(DeviceUse use, uint32_t intdec, uint32_t bw); | ||||
|     void setFIR(DeviceUse use, uint32_t intdec, uint32_t bw, int gain); | ||||
| 
 | ||||
| private: | ||||
|     struct iio_context *m_ctx; | ||||
| @ -93,7 +94,9 @@ private: | ||||
|     bool m_valid; | ||||
| 
 | ||||
|     bool parseSampleRates(const std::string& rateStr, SampleRates& sampleRates); | ||||
|     void set_filter(const std::string &filterConfigStr); | ||||
|     void set_filter(const std::string& filterConfigStr); | ||||
|     void formatFIRHeader(std::ostringstream& str, DeviceUse use, uint32_t intdec, int32_t gain); | ||||
|     void formatFIRCoefficients(std::ostringstream& str, uint32_t nbTaps, double normalizedBW); | ||||
| }; | ||||
| 
 | ||||
| #endif /* DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ */ | ||||
|  | ||||
| @ -242,11 +242,13 @@ void PlutoSDRInput::resumeBuddies() | ||||
| bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool force) | ||||
| { | ||||
|     bool forwardChangeOwnDSP    = false; | ||||
|     bool forwardChangeAllDSP    = false; | ||||
|     bool forwardChangeOtherDSP  = false; | ||||
|     bool suspendOwnThread       = false; | ||||
|     bool ownThreadWasRunning    = false; | ||||
|     bool suspendAllOtherThreads = false; // All others means Tx in fact
 | ||||
|     bool doCalibration = false; | ||||
|     bool firFilterSet = false; | ||||
|     DevicePlutoSDRBox *plutoBox =  m_deviceShared.m_deviceParams->getBox(); | ||||
| 
 | ||||
|     // determine if buddies threads or own thread need to be suspended
 | ||||
| 
 | ||||
| @ -299,7 +301,7 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo | ||||
| 
 | ||||
|     // TODO: apply settings (all cases)
 | ||||
| 
 | ||||
|     // Change affecting device baseband sample rate potentially affecting all buddies device/host sample rate
 | ||||
|     // Change affecting device sample rate chain potentially affecting other 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) || | ||||
| @ -310,10 +312,71 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo | ||||
|         QString rateGovStr; | ||||
|         PlutoSDRInputSettings::translateGovernor(settings.m_rateGovernor, rateGovStr); | ||||
|         params.push_back(QString(tr("trx_rate_governor=%1").arg(rateGovStr)).toStdString()); | ||||
|         params.push_back(QString(tr("in_voltage_filter_fir_en=%1").arg(settings.m_lpfFIREnable ? 1 : 0)).toStdString()); | ||||
|         forwardChangeAllDSP = true; | ||||
|         plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); // set end point frequency and rate governor first
 | ||||
| 
 | ||||
|         // Unless unconditionally forced to change settings change FIR settings if FIR is enabled AND
 | ||||
|         //   - FIR was not enabled before OR
 | ||||
|         //   - Host interface sample rate has changed OR
 | ||||
|         //   - Decimation chain rate governor has changed OR
 | ||||
|         //   - FIR decimation has changed
 | ||||
|         if ((settings.m_lpfFIREnable && (!m_settings.m_lpfFIREnable | ||||
|                 || (m_settings.m_devSampleRate != settings.m_devSampleRate) | ||||
|                 || (m_settings.m_rateGovernor != settings.m_rateGovernor) | ||||
|                 || (m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim))) || force) | ||||
|         { | ||||
|             plutoBox->set_filterBW(DevicePlutoSDRBox::USE_RX, (1<<settings.m_lpfFIRlog2Decim), settings.m_lpfFIRBW, settings.m_lpfFIRGain); | ||||
|             firFilterSet = true; | ||||
|         } | ||||
| 
 | ||||
|         // Reset the filter if gain or bandwidth changes without change to any of the sample rates and not done at previous step
 | ||||
|         if (((settings.m_lpfFIRBW != m_settings.m_lpfFIRBW) || | ||||
|              (settings.m_lpfFIRGain != m_settings.m_lpfFIRGain)) && !firFilterSet) | ||||
|         { | ||||
|             plutoBox->set_filterBW(DevicePlutoSDRBox::USE_RX, (1<<settings.m_lpfFIRlog2Decim), settings.m_lpfFIRBW, settings.m_lpfFIRGain); | ||||
|             firFilterSet = true; | ||||
|         } | ||||
| 
 | ||||
|         if ((m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) || force) | ||||
|         { | ||||
|             params.clear(); | ||||
|             params.push_back(QString(tr("in_voltage_filter_fir_en=%1").arg(settings.m_lpfFIREnable ? 1 : 0)).toStdString()); | ||||
|             plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); // eventually enable/disable FIR
 | ||||
|         } | ||||
| 
 | ||||
|         plutoBox->getRxSampleRates(m_deviceSampleRates); // pick up possible new rates
 | ||||
|         qDebug() << "PlutoSDRInput::applySettings: BBPLL: " << m_deviceSampleRates.m_bbRate | ||||
|                  << " ADC: " << m_deviceSampleRates.m_addaConnvRate | ||||
|                  << " -HB3-> " << m_deviceSampleRates.m_hb3Rate | ||||
|                  << " -HB2-> " << m_deviceSampleRates.m_hb2Rate | ||||
|                  << " -HB1-> " << m_deviceSampleRates.m_hb1Rate | ||||
|                  << " -FIR-> " << m_deviceSampleRates.m_firRate; | ||||
| 
 | ||||
|         forwardChangeOtherDSP = true; | ||||
|         forwardChangeOwnDSP = (m_settings.m_devSampleRate != settings.m_devSampleRate); | ||||
|     } | ||||
| 
 | ||||
|     if ((m_settings.m_log2Decim != settings.m_log2Decim) || force) | ||||
|     { | ||||
|         if (m_plutoSDRInputThread != 0) | ||||
|         { | ||||
|             m_plutoSDRInputThread->setLog2Decimation(settings.m_log2Decim); | ||||
|             qDebug() << "PlutoSDRInput::applySettings: set soft decimation to " << (1<<m_settings.m_log2Decim); | ||||
|         } | ||||
| 
 | ||||
|         forwardChangeOwnDSP = true; | ||||
|     } | ||||
| 
 | ||||
|     if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) | ||||
|     { | ||||
|         std::vector<std::string> params; | ||||
|         params.push_back(QString(tr("in_voltage_sampling_frequency=%1").arg(settings.m_centerFrequency)).toStdString()); | ||||
|         plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); | ||||
| 
 | ||||
|         forwardChangeOwnDSP = true; | ||||
|     } | ||||
| 
 | ||||
|     m_settings = settings; | ||||
| 
 | ||||
|     if (suspendAllOtherThreads) | ||||
|     { | ||||
|         const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies(); | ||||
| @ -336,5 +399,17 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // TODO: forward changes to other (Tx) DSP
 | ||||
| 
 | ||||
|     if (forwardChangeOwnDSP) | ||||
|     { | ||||
|         qDebug("PlutoSDRInput::applySettings: forward change to self"); | ||||
| 
 | ||||
|         int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim); | ||||
|         DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency); | ||||
|         m_fileSink->handleMessage(*notif); // forward to file sink
 | ||||
|         m_deviceAPI->getDeviceInputMessageQueue()->push(notif); | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @ -86,6 +86,8 @@ public: | ||||
| 
 | ||||
|     virtual bool handleMessage(const Message& message); | ||||
| 
 | ||||
|     uint32_t getADCSampleRate() const { return m_deviceSampleRates.m_addaConnvRate; } | ||||
| 
 | ||||
|  private: | ||||
|     DeviceSourceAPI *m_deviceAPI; | ||||
|     FileRecord *m_fileSink; | ||||
| @ -95,6 +97,7 @@ public: | ||||
|     DevicePlutoSDRShared m_deviceShared; | ||||
|     struct iio_buffer *m_plutoRxBuffer; | ||||
|     PlutoSDRInputThread *m_plutoSDRInputThread; | ||||
|     DevicePlutoSDRBox::SampleRates m_deviceSampleRates; | ||||
|     QMutex m_mutex; | ||||
| 
 | ||||
|     bool openDevice(); | ||||
|  | ||||
| @ -49,6 +49,7 @@ QByteArray PlutoSDRInputSettings::serialize() const | ||||
| 	SimpleSerializer s(1); | ||||
| 
 | ||||
|     s.writeS32(1, m_LOppmTenths); | ||||
|     s.writeS32(2, m_lpfFIRGain); | ||||
|     s.writeU32(3, m_lpfFIRlog2Decim); | ||||
|     s.writeU32(4, m_log2Decim); | ||||
| 	s.writeS32(5, m_fcPos); | ||||
| @ -82,6 +83,7 @@ bool PlutoSDRInputSettings::deserialize(const QByteArray& data) | ||||
| 		uint32_t uintval; | ||||
| 
 | ||||
|         d.readS32(1, &m_LOppmTenths, 0); | ||||
|         d.readS32(2, &m_lpfFIRGain, 0); | ||||
|         d.readU32(3, &uintval, 0); | ||||
|         if (uintval > 2) { | ||||
|             m_lpfFIRlog2Decim = 2; | ||||
|  | ||||
| @ -72,6 +72,7 @@ struct PlutoSDRInputSettings { | ||||
|     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)
 | ||||
|     int     m_lpfFIRGain;      //!< digital lowpass FIR filter gain (dB)
 | ||||
|     uint32_t m_gain;           //!< "hardware" gain
 | ||||
|     RFPath  m_antennaPath; | ||||
|     GainMode m_gainMode; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user