SetLPFBW for RX causes uncertain behaviour

#1

Hi @IgnasJ,
I am using Lime Suite API for Development of custom product with LMS7002M chip . I was trying to tune the RX filter bandwidth to different bandwidths. The function returned correct value 0 as it was tuned . However, on observing the output I see a noisy spectrum. This is a random issue as sometimes a particular BW setting works and sometimes it doesn’t.
Should I add delay after the SetLPFBW bandwidth function ?

#2

Hi @kishores,

Do you have a chance to share your source code?

#3

Sure @Zack .

   enum ARG_LIST{
      TYPE=1,
      VALUE=2,
      CHAN=3,
    };

    enum ERRORS{
      NO_DEV=-1,
      NOT_OPEN=-2,
      ERROR_ARG=-3
    };
    int ERROR_STAT = 0;
    lms_device_t* device = NULL;

    using namespace std;
    using namespace lime;

    void setValue(char** argv){
     string type = argv[TYPE];
     if(type == "CGEN"){
     	double cgen=atof(argv[VALUE]);       
     	if(LMS_SetClockFreq(device,LMS_CLOCK_CGEN,cgen*1e6)){//setting for both channels
      		//lime::error("Could not set SXT");
      		cout<<"Could not set CGEN"<<endl;
      		ERROR_STAT = 1;
     	}
     }
     else if(type == "SXT" ){
    	double sxt=atof(argv[VALUE]);
             if(LMS_SetClockFreq(device,LMS_CLOCK_SXT,sxt*1e6)){//setting for both channels
               //lime::error("Could not set SXT");
                cout<<"Could not set SXT"<<endl;
                ERROR_STAT = 1;
    	}
     }
    else if(type == "SXR" ){
             double sxr=atof(argv[VALUE]);
             if(LMS_SetClockFreq(device,LMS_CLOCK_SXR,sxr*1e6)){//setting for both channels
              //lime::error("Could not set SXR");
             cout<<"Could not set SXR"<<endl;
             ERROR_STAT = 1;
             }
    }
    }

    int main(int argc,char** argv){
      if(argc!=4){
     	cout<<"Error in arguments"<<endl;
      	return ERROR_ARG;//Error in arguments	
       }
      int n;
      int channel=atoi(argv[CHAN]);
      lms_info_str_t list[8];
    //INITIALIZE THE BOARD FOR COMMUNCATION
      //get device list
      if((n = LMS_GetDeviceList(list)) < 0){
    	cout<<"Could not get devices";
    	return NO_DEV;
      }
     //open the device
      if(LMS_Open(&device,list[0],NULL)){
       	cout<<"Could not open device";
    	return NOT_OPEN;
      }
      LMS_SetClockFreq(device,LMS_CLOCK_REF,RFD_EXT_CLK);
      string type = argv[TYPE];
      if(type == "BW_TX" || type == "BW_RX" ){
         if(type == "BW_TX"){
         	double bw_tx = atof(argv[VALUE]);
    	if(channel == 2){
           	  if(LMS_SetLPFBW(device,LMS_CH_TX,0,bw_tx*1e6)){
            	 cout<<"Could not set TX LPFBW for channel "<<char('A'+0)<<endl;
        		ERROR_STAT = 1;
                    return ERROR_STAT;
               }
               if(LMS_SetLPFBW(device,LMS_CH_TX,1,bw_tx*1e6)){
                     cout<<"Could not set TX LPFBW for channel "<<char('A'+1)<<endl;
                    ERROR_STAT = 1;
                    return ERROR_STAT;
               }
            }
            else{			
               if(LMS_SetLPFBW(device,LMS_CH_TX,channel,bw_tx*1e6)){
                     cout<<"Could not set TX LPFBW for channel "<<char('A'+channel)<<endl;
                    ERROR_STAT = 1;
    		return ERROR_STAT;
               }          
             }
         }
         else if(type == "BW_RX"){
             double bw_rx = atof(argv[VALUE]);
             if(channel == 2){
                if(LMS_SetLPFBW(device,LMS_CH_RX,0,bw_rx*1e6)){
                       cout<<"Could not set RX LPFBW for channel "<<char('A'+0)<<endl;
                      ERROR_STAT = 1;
                      return ERROR_STAT;
                 }
                 if(LMS_SetLPFBW(device,LMS_CH_RX,1,bw_rx*1e6)){
                       cout<<"Could not set RX LPFBW for channel "<<char('A'+1)<<endl;
                      ERROR_STAT = 1;
                      return ERROR_STAT;
                 }
            }
            else{
               if(LMS_SetLPFBW(device,LMS_CH_RX,channel,bw_rx*1e6)){
                     cout<<"Could not set RX LPFBW for channel "<<char('A'+channel)<<endl;
                    ERROR_STAT = 1;
                    return ERROR_STAT;
               }
             }
         }	
      }
      else{
      	setValue(argv);
      }
      return ERROR_STAT;
     }
        
         else if(type == "BW_RX"){
             double bw_rx = atof(argv[VALUE]);
             if(channel == 2){
              //Set for channel A
              if(LMS_SetLPFBW(device,LMS_CH_RX,0,bw_rx*1e6)){
                     cout<<"Could not set RX LPFBW for channel "<<char('A'+0)<<endl;
                    ERROR_STAT = 1;
                    return ERROR_STAT;
               }
               //Set for channel B
               if(LMS_SetLPFBW(device,LMS_CH_RX,1,bw_rx*1e6)){
                     cout<<"Could not set RX LPFBW for channel "<<char('A'+1)<<endl;
                    ERROR_STAT = 1;
                    return ERROR_STAT;
               }
            }
            else{
               if(LMS_SetLPFBW(device,LMS_CH_RX,channel,bw_rx*1e6)){
                     cout<<"Could not set RX LPFBW for channel "<<char('A'+channel)<<endl;
                    ERROR_STAT = 1;
                    return ERROR_STAT;
               }
             }
         }	
      }
      else{
      	setValue(argv);
      }
      return ERROR_STAT;
     }

I am passing arguments to my script as sudo ./script BW_RX 20 0 for configuring channel A .
The arguments I am passing are BW_RX(RX Filter Bandwidth), Value(in MHz) and Channel(0 -->A, 1 --> B, 2 -->AB)
I realized the function does not give any error but affects the spectrum as CGEN is getting tuned by the MCU code indirectly every time I change the filter bandwidth.
Our system (FPGA for collecting I,Q samples ) is very sensitive to timing constraints as we see noisy sine waves on output if CGEN is not in phase with our reference clock.