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