1 #include "lms7_device.h"
2 #include <iostream>
3 #include <iomanip>
4 #include <getopt.h>
5 #include <string>
6 #include <algorithm>
7 #include <cctype>
8 #include <fstream>
9 #include <chrono>
10 #include "FPGA_common.h"
11 #include "Logger.h"
12 
13 using namespace std;
14 using namespace lime;
15 
16 auto t1 = chrono::high_resolution_clock::now();
17 auto t2 = chrono::high_resolution_clock::now();
18 
19 bool ConfigureCGEN(LMS7_Device* device, double freqMHz);
20 
21 int printHelp(void);
22 
23 int log_level = 3;
24 
log_func(const lime::LogLevel level,const char * message)25 void log_func(const lime::LogLevel level, const char *message)
26 {
27     if (level <= log_level)
28         std::cout << message << std::endl;
29 }
30 
main(int argc,char ** argv)31 int main(int argc, char** argv)
32 {
33     double beginFreq = 50e6;
34     double endFreq = 500e6;
35     double stepFreq = 1e6;
36     string configFilename = "";
37     bool init = false;
38     int deviceIndex = -1;
39 
40     int c;
41     while (1)
42     {
43         static struct option long_options[] =
44         {
45             {"beginFreq",   required_argument, 0, 'b'},
46             {"stepFreq",    required_argument, 0, 's'},
47             {"endFreq",     required_argument, 0, 'e'},
48             {"log",         required_argument, 0, 'l'},
49             {"config",      required_argument, 0, 'c'},
50             {"device",      required_argument, 0, 'd'},
51             {"help",        no_argument, 0, 'h'},
52             {0, 0, 0, 0}
53         };
54         /* getopt_long stores the option index here. */
55         int option_index = 0;
56         c = getopt_long (argc, argv, "b:s:e:l:c::d:h", long_options, &option_index);
57 
58         if (c == -1) //no parameters given
59             break;
60         switch (c)
61         {
62         case 'b':{
63             stringstream ss;
64             ss << optarg;
65             ss >> beginFreq;
66             break;
67         }
68         case 's':{
69             stringstream ss;
70             ss << optarg;
71             ss >> stepFreq;
72             break;
73         }
74         case 'e':{
75             stringstream ss;
76             ss << optarg;
77             ss >> endFreq;
78             break;
79         }
80         case 'l':{
81             stringstream ss;
82             ss << optarg;
83             ss >> log_level;
84             break;
85         }
86         case 'c':{
87             if (optarg != NULL){
88                 stringstream ss;
89                 ss << optarg;
90                 ss >> configFilename;
91             }
92             else init = true;
93             break;
94         }
95         case 'd':{
96             stringstream ss;
97             ss << optarg;
98             ss >> deviceIndex;
99             break;
100         }
101         case 'h':
102             printHelp();
103             return 0;
104         case '?':
105             /* getopt_long already printed an error message. */
106             break;
107         default:
108             std::cout << "Invalid option" << std::endl;
109             abort();
110         }
111     }
112 
113     cout << "beginFreq = " << beginFreq/1e6 << " MHz" << endl;
114     cout << "stepFreq  = " << stepFreq/1e6 << " MHz" << endl;
115     cout << "endFreq   = " << endFreq/1e6 << " MHz" << endl;
116 
117     LMS7_Device* device;
118     std::vector<lime::ConnectionHandle> handles = LMS7_Device::GetDeviceList();
119     if(handles.size() == 0)
120     {
121         cout << "No devices found" << endl;
122         return -1;
123     }
124     if(handles.size() == 1) //open the only available device
125         device = lime::LMS7_Device::CreateDevice(handles[0],nullptr);
126     else //display device selection
127     {
128         if(deviceIndex < 0)
129         {
130             cout << "Device list:" << endl;
131             for (size_t i = 0; i < handles.size(); i++)
132                cout << setw(2) << i << ". " << handles[i].name << endl;
133             cout << "Select device index (0-" << handles.size()-1 << "): ";
134             int selection = 0; cin >> selection;
135             selection = selection % handles.size();
136             device = lime::LMS7_Device::CreateDevice(handles[selection],nullptr);
137         }
138         else
139             device = lime::LMS7_Device::CreateDevice(handles[deviceIndex],nullptr);
140     }
141     if(device == nullptr)
142     {
143         cout << "Failed to connected to device" << endl;
144         return -1;
145     }
146     auto info = device->GetInfo();
147     cout << "\nConnected to: " << info->deviceName
148     << " FW: " << info->firmwareVersion << " HW: " << info->hardwareVersion << endl;
149 
150     if(configFilename.length() > 0)
151     {
152         if(device->LoadConfig(configFilename.c_str()) != 0)
153         {
154             return -1;
155         }
156     }
157     else if (init)
158     {
159         device->Init();
160     }
161 
162     lime::registerLogHandler(log_func);
163     int errors = 0;
164     for (double freq = beginFreq; freq < endFreq; freq += stepFreq)
165         if (ConfigureCGEN(device, freq)==false)
166             errors++;
167     cout << "Errors: " << errors << endl;
168     delete device;
169     return 0;
170 }
171 
ConfigureCGEN(LMS7_Device * device,double freqMHz)172 bool ConfigureCGEN(LMS7_Device* device, double freqMHz)
173 {
174     std::cout << "Set CGEN " << freqMHz/1e6 << " MHz: ";
175     LMS7002M* lms = device->GetLMS();
176     lms->Modify_SPI_Reg_bits(LMS7param(MAC),1,true);
177     int interp = lms->Get_SPI_Reg_bits(LMS7param(HBI_OVR_TXTSP));
178     int decim = lms->Get_SPI_Reg_bits(LMS7param(HBD_OVR_RXTSP));
179     if (lms->SetInterfaceFrequency(freqMHz, interp, decim)!=0)
180     {
181         std::cout << "LMS VCO Fail" << endl;
182         return false;
183     }
184 
185     auto chipInd = lms->GetActiveChannelIndex()/2;
186     auto fpgaTxPLL = lms->GetReferenceClk_TSP(lime::LMS7002M::Tx);
187     if (interp != 7)
188         fpgaTxPLL /= pow(2.0, interp);
189     auto fpgaRxPLL = lms->GetReferenceClk_TSP(lime::LMS7002M::Rx);
190     if (decim != 7)
191         fpgaRxPLL /= pow(2.0, decim);
192     auto fpga = device->GetFPGA();
193     if (fpga)
194     {
195         int status = fpga->SetInterfaceFreq(fpgaTxPLL,fpgaRxPLL,chipInd);
196         if (status != 0)
197         {
198             std::cout << "FPGA Fail" << endl;
199             return false;
200         }
201     }
202     std::cout << "OK" << endl;
203     return true;
204 }
205 
206 /***********************************************************************
207  * print help
208  **********************************************************************/
printHelp(void)209 int printHelp(void)
210 {
211     std::cout << "Usage pll_sweep [options]" << std::endl;
212     std::cout << "available options:" << std::endl;
213     std::cout << "    --help \t\t Print this help message" << std::endl;
214     std::cout << "    --beginFreq \t sweep start frequency" << std::endl;
215     std::cout << "    --endFreq \t\t sweep end frequency" << std::endl;
216     std::cout << "    --stepFreq \t\t sweep frequency step" << std::endl;
217     std::cout << "    --log \t\t log level" << std::endl;
218     std::cout << "    --config \t\t load config" << std::endl;
219     std::cout << "    --device \t\t device index" << std::endl;
220     std::cout << std::endl;
221     return EXIT_SUCCESS;
222 }
223 
224