mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04:00 
			
		
		
		
	PlutoSDR: set FIR filter (2)
This commit is contained in:
		
							parent
							
								
									7acd2bb7ed
								
							
						
					
					
						commit
						11b657a841
					
				| @ -15,7 +15,6 @@ | |||||||
| ///////////////////////////////////////////////////////////////////////////////////
 | ///////////////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <sstream> |  | ||||||
| #include <cstdio> | #include <cstdio> | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <regex> | #include <regex> | ||||||
| @ -23,6 +22,7 @@ | |||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| #include <QtGlobal> | #include <QtGlobal> | ||||||
| 
 | 
 | ||||||
|  | #include "dsp/wfir.h" | ||||||
| #include "deviceplutosdrbox.h" | #include "deviceplutosdrbox.h" | ||||||
| 
 | 
 | ||||||
| DevicePlutoSDRBox::DevicePlutoSDRBox(const std::string& uri) : | 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; |     SampleRates sampleRates; | ||||||
|     std::ostringstream ostr; |     std::ostringstream ostr; | ||||||
| 
 | 
 | ||||||
|     uint32_t nbTaps; |     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) |     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 = ((float) bw) / sampleRates.m_hb1Rate; | ||||||
|         normalizedBW = normalizedBW < 0.1 ? 0.1 : normalizedBW > 0.9 ? 0.9 : normalizedBW; |         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_ | #ifndef DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ | ||||||
| #define DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ | #define DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ | ||||||
| 
 | 
 | ||||||
|  | #include <sstream> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include "deviceplutosdrscan.h" | #include "deviceplutosdrscan.h" | ||||||
| @ -79,7 +80,7 @@ public: | |||||||
|     char* txBufferFirst(); |     char* txBufferFirst(); | ||||||
|     bool getRxSampleRates(SampleRates& sampleRates); |     bool getRxSampleRates(SampleRates& sampleRates); | ||||||
|     bool getTxSampleRates(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: | private: | ||||||
|     struct iio_context *m_ctx; |     struct iio_context *m_ctx; | ||||||
| @ -93,7 +94,9 @@ private: | |||||||
|     bool m_valid; |     bool m_valid; | ||||||
| 
 | 
 | ||||||
|     bool parseSampleRates(const std::string& rateStr, SampleRates& sampleRates); |     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_ */ | #endif /* DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ */ | ||||||
|  | |||||||
| @ -242,11 +242,13 @@ void PlutoSDRInput::resumeBuddies() | |||||||
| bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool force) | bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool force) | ||||||
| { | { | ||||||
|     bool forwardChangeOwnDSP    = false; |     bool forwardChangeOwnDSP    = false; | ||||||
|     bool forwardChangeAllDSP    = false; |     bool forwardChangeOtherDSP  = false; | ||||||
|     bool suspendOwnThread       = false; |     bool suspendOwnThread       = false; | ||||||
|     bool ownThreadWasRunning    = false; |     bool ownThreadWasRunning    = false; | ||||||
|     bool suspendAllOtherThreads = false; // All others means Tx in fact
 |     bool suspendAllOtherThreads = false; // All others means Tx in fact
 | ||||||
|     bool doCalibration = false; |     bool doCalibration = false; | ||||||
|  |     bool firFilterSet = false; | ||||||
|  |     DevicePlutoSDRBox *plutoBox =  m_deviceShared.m_deviceParams->getBox(); | ||||||
| 
 | 
 | ||||||
|     // determine if buddies threads or own thread need to be suspended
 |     // 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)
 |     // 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) || |     if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || | ||||||
|         (m_settings.m_rateGovernor != settings.m_rateGovernor) || |         (m_settings.m_rateGovernor != settings.m_rateGovernor) || | ||||||
|         (m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim) || |         (m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim) || | ||||||
| @ -310,10 +312,71 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo | |||||||
|         QString rateGovStr; |         QString rateGovStr; | ||||||
|         PlutoSDRInputSettings::translateGovernor(settings.m_rateGovernor, rateGovStr); |         PlutoSDRInputSettings::translateGovernor(settings.m_rateGovernor, rateGovStr); | ||||||
|         params.push_back(QString(tr("trx_rate_governor=%1").arg(rateGovStr)).toStdString()); |         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()); |         plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); // set end point frequency and rate governor first
 | ||||||
|         forwardChangeAllDSP = true; | 
 | ||||||
|  |         // 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) |     if (suspendAllOtherThreads) | ||||||
|     { |     { | ||||||
|         const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies(); |         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; |     return false; | ||||||
| } | } | ||||||
|  | |||||||
| @ -86,6 +86,8 @@ public: | |||||||
| 
 | 
 | ||||||
|     virtual bool handleMessage(const Message& message); |     virtual bool handleMessage(const Message& message); | ||||||
| 
 | 
 | ||||||
|  |     uint32_t getADCSampleRate() const { return m_deviceSampleRates.m_addaConnvRate; } | ||||||
|  | 
 | ||||||
|  private: |  private: | ||||||
|     DeviceSourceAPI *m_deviceAPI; |     DeviceSourceAPI *m_deviceAPI; | ||||||
|     FileRecord *m_fileSink; |     FileRecord *m_fileSink; | ||||||
| @ -95,6 +97,7 @@ public: | |||||||
|     DevicePlutoSDRShared m_deviceShared; |     DevicePlutoSDRShared m_deviceShared; | ||||||
|     struct iio_buffer *m_plutoRxBuffer; |     struct iio_buffer *m_plutoRxBuffer; | ||||||
|     PlutoSDRInputThread *m_plutoSDRInputThread; |     PlutoSDRInputThread *m_plutoSDRInputThread; | ||||||
|  |     DevicePlutoSDRBox::SampleRates m_deviceSampleRates; | ||||||
|     QMutex m_mutex; |     QMutex m_mutex; | ||||||
| 
 | 
 | ||||||
|     bool openDevice(); |     bool openDevice(); | ||||||
|  | |||||||
| @ -49,6 +49,7 @@ QByteArray PlutoSDRInputSettings::serialize() const | |||||||
| 	SimpleSerializer s(1); | 	SimpleSerializer s(1); | ||||||
| 
 | 
 | ||||||
|     s.writeS32(1, m_LOppmTenths); |     s.writeS32(1, m_LOppmTenths); | ||||||
|  |     s.writeS32(2, m_lpfFIRGain); | ||||||
|     s.writeU32(3, m_lpfFIRlog2Decim); |     s.writeU32(3, m_lpfFIRlog2Decim); | ||||||
|     s.writeU32(4, m_log2Decim); |     s.writeU32(4, m_log2Decim); | ||||||
| 	s.writeS32(5, m_fcPos); | 	s.writeS32(5, m_fcPos); | ||||||
| @ -82,6 +83,7 @@ bool PlutoSDRInputSettings::deserialize(const QByteArray& data) | |||||||
| 		uint32_t uintval; | 		uint32_t uintval; | ||||||
| 
 | 
 | ||||||
|         d.readS32(1, &m_LOppmTenths, 0); |         d.readS32(1, &m_LOppmTenths, 0); | ||||||
|  |         d.readS32(2, &m_lpfFIRGain, 0); | ||||||
|         d.readU32(3, &uintval, 0); |         d.readU32(3, &uintval, 0); | ||||||
|         if (uintval > 2) { |         if (uintval > 2) { | ||||||
|             m_lpfFIRlog2Decim = 2; |             m_lpfFIRlog2Decim = 2; | ||||||
|  | |||||||
| @ -72,6 +72,7 @@ struct PlutoSDRInputSettings { | |||||||
|     bool    m_lpfFIREnable;    //!< enable digital lowpass FIR filter
 |     bool    m_lpfFIREnable;    //!< enable digital lowpass FIR filter
 | ||||||
|     float   m_lpfFIRBW;        //!< digital lowpass FIR filter bandwidth (Hz)
 |     float   m_lpfFIRBW;        //!< digital lowpass FIR filter bandwidth (Hz)
 | ||||||
|     quint32 m_lpfFIRlog2Decim; //!< digital lowpass FIR filter log2 of decimation factor (0..2)
 |     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
 |     uint32_t m_gain;           //!< "hardware" gain
 | ||||||
|     RFPath  m_antennaPath; |     RFPath  m_antennaPath; | ||||||
|     GainMode m_gainMode; |     GainMode m_gainMode; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user