C++ Instrument Catalog
MFC3045Device.cpp
Go to the documentation of this file.
1 
6 // Standard includes
7 #include <regex>
8 #include <bitset>
9 
10 // Personal includes
11 #include "MFC3045Device.h"
12 #include "Exception.h"
13 
14 // External tools includes
15 #include "date.h"
16 
17 #define LOG(__msg__, __level__,__location__) m_rMFCController.l_SendLogMessage(__msg__, __level__, ".MFC3045Device", __location__)
18 
19 
20 //------------------------------------------------------------------//
21 // Constructors / Destructors
22 //------------------------------------------------------------------//
23 CMFC3045Device::CMFC3045Device (CMFCController & rMFCController, CVISAResourceManager & rRM, tResourceName Rsrc, CInstrumentCatalog::sMFC3045SerialPortSettings & rSerialSetting)
24  :
25  m_rMFCController(rMFCController),
26  m_MFC3045(rRM, Rsrc),
27  m_PaSerialNum(""),
28  m_LastCmdError("")
29 {
30  l_ParseSerialSettings(rSerialSetting, m_SerialParms);
31 }
32 
34 {
35 
36 }
37 
38 //--------------------------------------------------------------------------//
39 // Utilities
40 //--------------------------------------------------------------------------//
41 template<typename T>
42 static std::string toBinaryString(const T& x)
43 {
44  std::stringstream ss;
45  ss << std::bitset<sizeof(T) * 8>(x);
46  return ss.str();
47 }
48 
49 F64 l_ConvertdHzToMHz (const U32 & rFreqdHz)
50 {
51  return static_cast <F64>(rFreqdHz)*1.0e-7;
52 }
53 
54 U32 l_ConvertMHzTodHz (const F64 & rFreqMHz)
55 {
56  return static_cast <U32>(rFreqMHz*1.0e7);
57 }
58 
59 F32 l_ConvertNormdHzToMHz (const I32 & rFreqdHz)
60 {
61  return static_cast <F32>(rFreqdHz)*1.0e-7f;
62 }
63 
64 I32 l_ConvertNormMHzTodHz (const F32 & rFreqMHz)
65 {
66  return static_cast <I32>(rFreqMHz*1.0e7f);
67 }
68 
69 F32 l_ConvertStdDevdHzToPpm (const U32 & rStdDevdHz, const U32 & rFreqRefdHz)
70 {
71  F64 l_StdDevppm(DPqNaN);
72  if (rFreqRefdHz > 0 && rStdDevdHz > 0)
73  l_StdDevppm= (static_cast <F64>(rStdDevdHz) * 1.0e6) / static_cast <F64>(rFreqRefdHz);
74  return static_cast <F32>(l_StdDevppm);
75 }
76 
77 bool CMFC3045Device::l_UtcToStrDateISO8601(const std::time_t & rUtcDate, std::string & rStrDate)
78 {
79  try {
80  auto l_TimePointUTC = std::chrono::system_clock::from_time_t(rUtcDate);
81  rStrDate = date::format("%FT%TZ", date::floor<std::chrono::seconds>(l_TimePointUTC)); // convert date time_t UTC in YYYY-MM-DDTHH:MM:SSZ ISO8601 UTC string format
82  if(rStrDate.empty())
83  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to format time_t UTC date to string", MTL__LOCATION__);
84  }
85  catch (sMFCDeviceError & rE)
86  {
87  MTL_Unused(rE)
88  rStrDate.clear();
89  return false;
90  }
91  return true;
92 }
93 
94 bool CMFC3045Device::l_ParseSerialSettings(const CInstrumentCatalog::sMFC3045SerialPortSettings & rSerialSetting, sSerialPortSettings & rVisaSerialSetting)
95 {
96  bool l_Ret(true);
97  // Convert CInstrumentCatalog::sMFC3045SerialPortSettings to sSerialPortSettings (VISAInstrumentTypes.h)
98 
99  switch (rSerialSetting.Baudrate)
100  {
102  rVisaSerialSetting.Baudrate = eSerialBaudrate::k2400;
103  break;
105  rVisaSerialSetting.Baudrate = eSerialBaudrate::k4800;
106  break;
108  rVisaSerialSetting.Baudrate = eSerialBaudrate::k9600;
109  break;
111  rVisaSerialSetting.Baudrate = eSerialBaudrate::k19200;
112  break;
114  rVisaSerialSetting.Baudrate = eSerialBaudrate::k28800;
115  break;
117  rVisaSerialSetting.Baudrate = eSerialBaudrate::k38400;
118  break;
120  rVisaSerialSetting.Baudrate = eSerialBaudrate::k57600;
121  break;
123  rVisaSerialSetting.Baudrate = eSerialBaudrate::k115200;
124  break;
125  default:
126  LOG("Unhandled Serial Baudrate type", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
127  l_Ret = false;
128  break;
129  }
130 
131  switch (rSerialSetting.Parity)
132  {
134  rVisaSerialSetting.Parity = eSerialParity::kNone;
135  break;
137  rVisaSerialSetting.Parity = eSerialParity::kOdd;
138  break;
140  rVisaSerialSetting.Parity = eSerialParity::kEven;
141  break;
142  default:
143  LOG("Unhandled Serial Parity type", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
144  l_Ret = false;
145  break;
146  }
147 
148  switch (rSerialSetting.DataBits)
149  {
151  rVisaSerialSetting.DataBits = eSerialDataBits::k7;
152  break;
154  rVisaSerialSetting.DataBits = eSerialDataBits::k8;
155  break;
156  default:
157  LOG("Unhandled Serial Databits type", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
158  l_Ret = false;
159  break;
160  }
161 
162  switch (rSerialSetting.StopBits)
163  {
165  rVisaSerialSetting.StopBits = eSerialStopBits::k1;
166  break;
168  rVisaSerialSetting.StopBits = eSerialStopBits::k2;
169  break;
170  default:
171  LOG("Unhandled Serial Stopbits type", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
172  l_Ret = false;
173  break;
174  }
175 
176  switch (rSerialSetting.Handshake)
177  {
179  rVisaSerialSetting.Handshake = eSerialHandshake::kNone;
180  break;
182  rVisaSerialSetting.Handshake = eSerialHandshake::kXonXoff; // software handshake
183  break;
185  rVisaSerialSetting.Handshake = eSerialHandshake::kHardware; // CTS/RTS hardware handshake
186  break;
187  default:
188  LOG("Unhandled Serial Handshake type", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
189  l_Ret = false;
190  break;
191  }
192  return l_Ret;
193 }
194 
195 bool CMFC3045Device::l_ReadSomeStatusReg(const uStatusRegSel & rRdSelStatus)
196 {
197  try
198  {
199  if(rRdSelStatus.StRegSelBit.ST1 || rRdSelStatus.StRegSelBit.ALLST > 0)
200  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus1, m_RegStatus1.RawSTB1))
201  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register 1", MTL__LOCATION__);
202  m_LastCmdError = "";
203  if(m_RegStatus1.StatusByte1.ECMD)
204  m_MFC3045.LastCmdErrorGet(m_LastCmdError);
205  if(rRdSelStatus.StRegSelBit.ST2 || rRdSelStatus.StRegSelBit.ALLST > 0)
206  {
207  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus2, m_RegStatus2.RawSTB2))
208  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register 2", MTL__LOCATION__);
209  }
210  if(rRdSelStatus.StRegSelBit.ST3 || rRdSelStatus.StRegSelBit.ALLST > 0)
211  {
212  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus3, m_RegStatus3.RawSTB3))
213  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register 3", MTL__LOCATION__);
214  }
215  if(rRdSelStatus.StRegSelBit.ST4 || rRdSelStatus.StRegSelBit.ALLST > 0)
216  {
217  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus4, m_RegStatus4.RawSTB4))
218  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register 4", MTL__LOCATION__);
219  }
220  if(rRdSelStatus.StRegSelBit.ST5 || rRdSelStatus.StRegSelBit.ALLST > 0)
221  {
222  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus5, m_RegStatus5.RawSTB5))
223  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register 5", MTL__LOCATION__);
224  }
225  if(rRdSelStatus.StRegSelBit.ST6 || rRdSelStatus.StRegSelBit.ALLST > 0)
226  {
227  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus6, m_RegStatus6.RawSTB6))
228  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register 6", MTL__LOCATION__);
229  }
230  }
231  catch (sMFCDeviceError & rE)
232  {
234  return false;
235  }
236  catch (...)
237  {
238  LOG("Unhandled exception type", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
239  return false;
240  }
241  return true;
242 }
243 
244 bool CMFC3045Device::l_SerialCommunicationSuccess()
245 {
246  bool l_Ret(true);
247 
248  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus5, m_RegStatus5.RawSTB5))
249  l_Ret = false;
250  else
251  {
252  if(m_RegStatus5.StatusByte5.EFR || m_RegStatus5.StatusByte5.EOR || m_RegStatus5.StatusByte5.EPY)
253  l_Ret = false;
254  }
255  return l_Ret;
256 }
257 
258 bool CMFC3045Device::l_CheckPAConnected(bool & rPAPresent)
259 {
260  U8 l_StatusTemp(0);
261  try
262  {
263  if(!m_MFC3045.StatusGet(eStatusRegister::kStatus2, l_StatusTemp))
264  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Unable to read Status register", MTL__LOCATION__);
265  m_RegStatus2.RawSTB2 = l_StatusTemp;
266  rPAPresent = (0 == m_RegStatus2.StatusByte2.PANC);
267  }
268  catch (sMFCDeviceError & rE)
269  {
270  MTL_Unused(rE)
271  rPAPresent = false;
272  return false;
273  }
274  return true;
275 }
276 
277 bool CMFC3045Device::l_ConfigurationChanged (CInstrumentCatalog::sInstrumentState lastcfg, CInstrumentCatalog::sInstrumentState newcfg)
278 {
279  return (lastcfg.ProbeSelection != newcfg.ProbeSelection ||
280  *(reinterpret_cast<U64*>(&lastcfg.FreqMin)) != *(reinterpret_cast<U64*>(&newcfg.FreqMin)) || // Compare binary representation of the double values to detect value change
281  *(reinterpret_cast<U64*>(&lastcfg.FreqMax)) != *(reinterpret_cast<U64*>(&newcfg.FreqMax)) || // Compare binary representation of the double values to detect value change
283 }
284 
285 bool CMFC3045Device::l_ConfigureForOperation (const CInstrumentCatalog::sInstrumentState & rInstrState, sMFCDeviceError & rError)
286 {
288 
289  //-----------------------------------------------------
290  // According to the current sInstrumentState, set
291  // ProbeSelection
292  // FreqMin
293  // FreqMax
294  // NbAveragedMeasurements
295  // Data block mode to decimal
296 
297  LOG("Reconfiguration needed", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
298  try
299  {
300  U32 l_FreqdHz(0);
301  U16 l_NbMeasCylce(0);
302 
303  switch (rInstrState.OperatingMode)
304  {
306  if (!m_MFC3045.BreakMeasSet())
307  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not stop any instrument acquisition", MTL__LOCATION__);
308  if (!m_MFC3045.DisableSMA())
309  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not disable SMA on instrument", MTL__LOCATION__);
310  if (!m_MFC3045.DataBlockModeDecimalSet())
311  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set block mode to decimal", MTL__LOCATION__);
312  // Search is always done on all Probe array range. Don't need to configure measurement frequency limits
313  break;
314 
316  if (!m_MFC3045.BreakMeasSet())
317  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not stop any instrument acquisition", MTL__LOCATION__);
318  if (!m_MFC3045.DisableSMA())
319  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not disable SMA on instrument", MTL__LOCATION__);
320  // Set measurement limits
321  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::k1))
322  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
323  //Set MRE to reference = MLF (Fmin) for future measurement
324  if(!m_MFC3045.ModulationReferenceSet(eModulationRef::kMLF))
325  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to set MRE register", MTL__LOCATION__);
326  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone))
327  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
328  // set MLF & MHF (MDA et MCF will be computed from MLF and MHF in the main unit
329  l_FreqdHz = l_ConvertMHzTodHz(rInstrState.FreqMin);
330  if (!m_MFC3045.ModulationLowestFreqSet(l_FreqdHz))
331  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set min Freq measurement", MTL__LOCATION__);
332  l_FreqdHz = l_ConvertMHzTodHz(rInstrState.FreqMax);
333  if (!m_MFC3045.ModulationHighestFreqSet(l_FreqdHz))
334  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set max Freq measurement", MTL__LOCATION__);
335 
336  // Set measurement averaging (number of measurement cycle)
337  if(rInstrState.NbAveragedMeasurements <= NCY_MIN)
338  l_NbMeasCylce = static_cast<U16>(NCY_MIN);
339  else if(rInstrState.NbAveragedMeasurements >= NCY_MAX)
340  l_NbMeasCylce = static_cast<U16>(NCY_MAX);
341  else
342  l_NbMeasCylce = static_cast<U16>(rInstrState.NbAveragedMeasurements);
343  if (!m_MFC3045.NumberMeasCycleSet(l_NbMeasCylce))
344  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set number of measurement cycle", MTL__LOCATION__);
345 
346  if (!m_MFC3045.DataBlockModeDecimalSet())
347  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set block mode to decimal", MTL__LOCATION__);
348  break;
349 
350  default:
351  break;
352  }
353  rError = sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Configuration done.", MTL__LOCATION__);
354  }
355  catch (sMFCDeviceError & rE)
356  {
357  rError = rE;
358  return false;
359  }
360  return true;
361 }
362 
363 bool CMFC3045Device::l_ComputeMaxMeasTimeout(U64 & rMaxTimeOutMs)
364 {
365  rMaxTimeOutMs = 0;
366  try
367  {
368  U16 l_NbMeasCylce(0);
369  U16 l_NbPreMeasCylce(100);
370  U16 l_NbModPeriod(0);
371 
372  if (!m_MFC3045.NumberMeasCycleGet(l_NbMeasCylce))
373  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not get number of measurement cycle", MTL__LOCATION__);
374 
375  if (!m_MFC3045.ModulationPeriodGet(l_NbModPeriod))
376  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not get modulation period", MTL__LOCATION__);
377 
378  // register access with Advance mode 1:
379  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::k1))
380  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
381  if (!m_MFC3045.NumberPreCycleGet(l_NbPreMeasCylce))
382  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not get number of pre cycle", MTL__LOCATION__);
383  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone))
384  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
385  rMaxTimeOutMs = 4*(l_NbModPeriod * (l_NbMeasCylce + l_NbPreMeasCylce));
386  }
387  catch (sMFCDeviceError & rE)
388  {
389  MTL_Unused(rE)
390  return false;
391  }
392  return true;
393 }
394 
395 // Compute the average of the measurements made during the search operation.
396 void CMFC3045Device::l_ComputeAveraging (const std::vector<U32> & rFluxListdHz, F64 & rReturnedAveragingMHz, F64 & rReturnedStdDevppm)
397 {
398  // Compute the mean of the measurements.
399  U8 l_ValidCount = 0;
400  rReturnedAveragingMHz = 0.0l;
401  rReturnedStdDevppm = 0.0l;
402  try
403  {
404  // Check content
405  if (rFluxListdHz.empty())
406  throw false;
407 
408  // Compute averaging
409  for (std::vector<U32>::const_iterator l_it = rFluxListdHz.begin(); l_it != rFluxListdHz.end(); l_it++)
410  {
411  // Make sure that the measurement taken to compute the mean are valid.
412  // An invalid measurement is marked with a mean value being equal to 0.
413  if (*l_it >0)
414  {
415  // Sum up all the NMR frequencies measured.
416  rReturnedAveragingMHz += l_ConvertdHzToMHz(*l_it);
417  // Update the number of valid heads.
418  l_ValidCount++;
419  }
420  }
421  // If we had some valid heads, compute the average.
422  if (l_ValidCount > 0)
423  rReturnedAveragingMHz = rReturnedAveragingMHz / l_ValidCount;
424  else
425  rReturnedAveragingMHz = DPqNaN;
426 
427  // We already know how many valid heads are available.
428  if (l_ValidCount > 1)
429  {
430  for (std::vector<U32>::const_iterator l_it = rFluxListdHz.begin(); l_it != rFluxListdHz.end(); l_it++)
431  {
432  // Make sure that the measurement taken to compute the mean are valid.
433  // An invalid measurement is marked with a mean value being equal to 0.
434  if (*l_it >0)
435  {
436  F64 l_Value = l_ConvertdHzToMHz(*l_it) - rReturnedAveragingMHz;
437  rReturnedStdDevppm += l_Value * l_Value;
438  }
439  }
440  // Compute the standard deviation in ppm from the computed mean.
441  rReturnedStdDevppm = sqrt(rReturnedStdDevppm / (l_ValidCount - 1)) / rReturnedAveragingMHz * 1.0e6;
442  }
443  else
444  rReturnedStdDevppm = DPqNaN;
445  }
446  catch (bool & rE)
447  {
448  MTL_Unused(rE)
449  rReturnedAveragingMHz = DPqNaN;
450  rReturnedStdDevppm = DPqNaN;
451  }
452 }
453 
454 bool CMFC3045Device::l_WriteNormalizationRAM(const CInstrumentCatalog::tNormalizationTable & rNewNormalizationTable, sMFCDeviceError & rError)
455 {
456  try
457  {
458  if(rNewNormalizationTable.size() != m_NbProbesPA)
459  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Wrong Normalization table size", MTL__LOCATION__);
460 
461  // Read current Normalization table from main unit RAM
462  std::vector<I32> l_ReadMFC3045NormalizationdHz;
463  if (!m_MFC3045.CalibrationBuildTableGet(m_NbProbesPA, l_ReadMFC3045NormalizationdHz))
464  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve normalization table", MTL__LOCATION__);
465  if(l_ReadMFC3045NormalizationdHz.size() < m_NbProbesPA)
466  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing normalization result", MTL__LOCATION__);
467 
468  // Convert units & write New Normalization correction to main unit RAM if probe value has changed.
469  U8 l_ProbeIdx(0);
470  for (auto&& Factor_MHz : rNewNormalizationTable)
471  {
472  I32 l_Norm_dHz(0);
473  l_Norm_dHz = l_ConvertNormMHzTodHz(Factor_MHz); // From [MHz]F32 to [dHz]I32
474  if (l_ReadMFC3045NormalizationdHz.at(l_ProbeIdx) !=l_Norm_dHz)
475  {
476  if (!m_MFC3045.CalibrationEditTableSet(l_Norm_dHz, l_ProbeIdx+1))
477  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot set normalization table in RAM", MTL__LOCATION__);
478  }
479  l_ProbeIdx++;
480  }
481  }
482  catch (sMFCDeviceError & rE)
483  {
484  rError = rE;
485  return false;
486  }
487  rError = sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Write RAM done.", MTL__LOCATION__);
488  return true;
489 }
490 
492 {
493  return m_MFC3045.Abort();
494 }
495 
497 {
498  U32 l_TimeoutMs(0);
499  bool l_Connected(false);
500  m_MFC3045.GetCurrentTimeoutRdDataMs(l_TimeoutMs);
501  m_MFC3045.SetTimeoutRdNewDataMs(2000);
502  l_Connected = m_MFC3045.CheckInstrumentConnection(2);
503  m_MFC3045.SetTimeoutRdNewDataMs(l_TimeoutMs);
504  return l_Connected;
505 }
506 
507 //--------------------------------------------------------------------------//
508 // Available Operations
509 //--------------------------------------------------------------------------//
510 // Connect to MFC3045 and get instrument information
512 {
513  try
514  {
515  std::string l_LastCmdError;
516  uStatusRegSel l_SelStatus;
517 
518  if (!m_MFC3045.ConnectInstrument(m_SerialParms,8000))
519  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot connect to requested resource", MTL__LOCATION__);
520  l_SelStatus.SelSTReg = SetSTALL; // read all status registers
521  if(!l_ReadSomeStatusReg(l_SelStatus))
522  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
523  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
524  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
525  if (m_RegStatus4.StatusByte4.HWP || m_RegStatus4.StatusByte4.EMM) //check hardware and MUEEPROM error
526  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 4: 0b" + toBinaryString(m_RegStatus4.RawSTB4), MTL__LOCATION__);
527  // register access with Advance mode 1:
528  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::k1))
529  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
530  // Check host and MFC3045 serial config to be the same.
531  U16 l_ReadRSPRegValue(0);
532  if(!m_MFC3045.SerialRSPGet(l_ReadRSPRegValue))
533  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to read RSP register", MTL__LOCATION__);
534  U16 l_SerialSettings;
535  if(!m_MFC3045.ParseParmForRSP(m_SerialParms,l_SerialSettings))
536  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to parse serial settings to RSP register type", MTL__LOCATION__);
537  if(l_ReadRSPRegValue != l_SerialSettings)
538  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Incompatible host and instrument serial settings. MFC3045 Settings: 0b" + toBinaryString(l_ReadRSPRegValue), MTL__LOCATION__);
539 
540  std::string l_RdString;
541  F32 l_FWVersionValue(0.0);
542  //rInstrInfo.InstrumentConnection is filled in MFCManager
544  if(!m_MFC3045.VersionGet(l_RdString, l_FWVersionValue, eWhoVersion::kMUFirmVer))
545  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to get MU Firmware version", MTL__LOCATION__);
546  rInstrInfo.Description = l_RdString;
547  if(!m_MFC3045.VersionGet(l_RdString, l_FWVersionValue, eWhoVersion::kMUEepromVer))
548  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to get MU-EEPROM Firmware version", MTL__LOCATION__);
549  rInstrInfo.Description += ", MU-EEPROM Version " + l_RdString;
550  if(!m_MFC3045.SerialNumberGet(l_RdString, eWhoSerialNum::kMUSerialNum))
551  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to get MU serial number", MTL__LOCATION__);
552  rInstrInfo.Description += ", S/N " + l_RdString;
553  rInstrInfo.SerialNumber = l_RdString;
554 
555  // Get main unit calibration date
556  std::string l_CalDateUTCStr;
557  std::time_t l_CalDateUTC;
558  if(!m_MFC3045.CalibrationDateMUGet(l_CalDateUTCStr, l_CalDateUTC)) // get UTC date in string and time_t
559  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to get MU calibration date", MTL__LOCATION__);
560  if(!l_UtcToStrDateISO8601(l_CalDateUTC, rInstrInfo.CalibrationDate)) // convert time_t UTC to YYYY-MM-DDTHH:MM:SSZ ISO8601 UTC format
561  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot parse MU date", MTL__LOCATION__);
562  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone))
563  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
564 
565  l_SelStatus.SelSTReg = SetSTALL; // read all status registers
566  if(!l_ReadSomeStatusReg(l_SelStatus))
567  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
568  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
569  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
570  }
571  catch (sMFCDeviceError & rE)
572  {
573  return rE;
574  }
575  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Instrument Connection done.", MTL__LOCATION__);
576 }
577 
578 // Scan Probe Array connected to main unit and get information
580  CInstrumentCatalog::sInstrumentConfiguration & rInstrConfig, bool &rPaInfoChanged)
581 {
582  try
583  {
584  uStatusRegSel l_SelStatus;
585  std::string l_RdString;
586  rPaInfoChanged = false;
587 
588  if(!IsInstrumentConnected())
589  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Instrument connection lost", MTL__LOCATION__);
590 
591  // read status register ST1 & ST2
592  l_SelStatus.SelSTReg = SetST1 | SetST2; // Note: don't read ST4 here to not clear bit for remote button check
593  if(!l_ReadSomeStatusReg(l_SelStatus))
594  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
595  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
596  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
597  if (m_RegStatus2.StatusByte2.PANC) //check if PA connected
598  throw false; // (It's not an error but don't go further)
599 
600  // Get probe array information
601  if(!m_MFC3045.SerialNumberGet(l_RdString, eWhoSerialNum::kPASerialNum))
602  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get PA serial number", MTL__LOCATION__);
603  if(l_RdString != m_PaSerialNum) //Probe array is different than before
604  {
605  // read status register ST4
606  l_SelStatus.SelSTReg = SetST4;
607  if(!l_ReadSomeStatusReg(l_SelStatus))
608  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
609  if (m_RegStatus4.StatusByte4.HWP || m_RegStatus4.StatusByte4.EPM) //check hardware and PA EEPROM error
610  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 4: 0b" + toBinaryString(m_RegStatus4.RawSTB4), MTL__LOCATION__);
611 
612  m_PaSerialNum = l_RdString;
613  m_NbProbesPA = 0;
614  rPAInfo.SerialNumber = l_RdString;
616 
617  // Read modulation (acquisition) period (PA need to be connected)
618  U16 l_MDP_Ms(0);
619  if(!m_MFC3045.ModulationPeriodGet(l_MDP_Ms))
620  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get acquisition period", MTL__LOCATION__);
621  rInstrConfig.AcquisitionPeriod = static_cast<F64>(l_MDP_Ms) / 1000.0; // convert ms to second
622 
623  U32 l_RdFreq(0);
624  // Get PA Central frequency dHz
625  if(!m_MFC3045.PaCentralFreqGet(l_RdFreq))
626  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get PA central Freq", MTL__LOCATION__);
627  rPAInfo.FreqCentral = l_ConvertdHzToMHz(l_RdFreq);
628  // Get PA lowset frequency dHz
629  if(!m_MFC3045.PaLowestFreqGet(l_RdFreq))
630  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get PA min Freq", MTL__LOCATION__);
631  rPAInfo.FreqMin = l_ConvertdHzToMHz(l_RdFreq);
632  // Get PA highest frequency dHz
633  if(!m_MFC3045.PaHighestFreqGet(l_RdFreq))
634  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get PA max Freq", MTL__LOCATION__);
635  rPAInfo.FreqMax = l_ConvertdHzToMHz(l_RdFreq);
636  // Get PA number of probes
637  U8 l_NbProbe(0);
638  if(!m_MFC3045.NumberProbesGet(l_NbProbe))
639  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get PA number of probes", MTL__LOCATION__);
640  if(0==l_NbProbe)
641  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get PA number of probes", MTL__LOCATION__);
642  m_NbProbesPA = l_NbProbe;
643  rPAInfo.ProbeList.clear();
644  for (U8 l_it =1; l_it <= l_NbProbe; l_it++)
645  {
647  l_PI.ProbeNumber = l_it;
648  l_PI.FreqMin = rPAInfo.FreqMin;
649  l_PI.FreqMax = rPAInfo.FreqMax;
650  rPAInfo.ProbeList.push_back(l_PI);
651  }
652 
653  rPAInfo.Description = "MFC3048 : Continuous Wave Camera";
654  rPAInfo.GyroRatio = static_cast <F64>(GYRORATIO_MFC3048_HZT)/1.0e6; // From Hz/T to MHz/T
655 
656  // Get PA normalization date
657  std::string l_NormDateUTCStr;
658  sMFCDeviceError l_RetError = GetNormalizationDate(l_NormDateUTCStr);
659  if(l_RetError.HasError())
660  {
661  throw l_RetError;
662  }
663  rPAInfo.NormalizationDate = l_NormDateUTCStr;
664 
665  // Ok to send new PA information
666  rPaInfoChanged = true;
667  l_SelStatus.SelSTReg = SetST2 | SetST4 | SetST5; // read status registers to clear bits
668  if(!l_ReadSomeStatusReg(l_SelStatus))
669  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
670  }
671  l_SelStatus.SelSTReg = SetST1;
672  if(!l_ReadSomeStatusReg(l_SelStatus)) // read status register ST1
673  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
674  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
675  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
676  }
677  // There is a warning or error
678  catch (sMFCDeviceError & rE)
679  {
680  m_PaSerialNum = "";
681  // If we previously had a PA
682  if (!rPAInfo.ProbeList.empty())
683  {
684  // Update PA Info (empty)
687  rPaInfoChanged = true;
688  }
689  return rE; // Return received error
690  }
691  // There is no error but no camera is available
692  catch (bool & rUsableCamera)
693  {
694  MTL_Unused(rUsableCamera)
695  m_PaSerialNum = "";
696  // If we previously had a PA
697  if (!rPAInfo.ProbeList.empty())
698  {
699  // Update PA Info (empty)
702  rPaInfoChanged = true;
703  }
704  }
705  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Scan PA done.", MTL__LOCATION__);
706 }
707 
709 {
710  uStatusRegSel l_SelStatus;
711  sMFCDeviceError l_ReturnError;
712 
713  try
714  {
715  // read all status registers
716  l_SelStatus.SelSTReg = SetSTALL;
717  if(!l_ReadSomeStatusReg(l_SelStatus))
718  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
719  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
720  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
721  if (m_RegStatus2.StatusByte2.PANC) //check if PA connected
722  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No PA available", MTL__LOCATION__);
723 
724  sMFCDeviceError l_Error;
725  if(!l_ConfigureForOperation(rInstrState,l_Error))
726  throw l_Error;
727 
728  l_SelStatus.SelSTReg = SetST1 | SetST2;
729  if(!l_ReadSomeStatusReg(l_SelStatus))
730  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
731  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
732  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
733  if (m_RegStatus2.StatusByte2.PANC) //check if PA connected
734  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No PA available", MTL__LOCATION__);
735 
736  U64 l_MaxMesTimeoutMs(0);
737  bool l_MaxTimeoutValid = l_ComputeMaxMeasTimeout(l_MaxMesTimeoutMs);
738 
739  // Start Search NMR signal over full PA range
740  bool l_IsContinuous = (CInstrumentCatalog::eRepeatMode::kContinuous == rInstrState.RepeatMode);
741  l_SelStatus.SelSTReg = SetST1 | SetST2 | SetST3;
742  do
743  {
744  U8 l_SearchProg =0;
745  // ENABLE SMA
746  if (!m_MFC3045.SearchStartWithSMA()) // Start search NMR with SMA enable on PA not connected and Data ready.
747  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not start search", MTL__LOCATION__);
748  // WARNING: From now, no Read commands should be sent to main unit until SMA is disable.
749  // We use this search method with SMA waiting on data ready message instead of a status register polling, because the Main unit firmware seems
750  // to have occasionnaly a problem on parsing a command during measurement process (Command error detects "TST" instead of STx)
751  std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait measurement to start in MFC3045
752 
753  // Note: no read status allowed while waiting for SMA (send automatic message from main unit) message
754  // Wait conntinuously while
755  // - we are not requested to stop
756  // - we don't have our measurement results
757  // If system indicates Searching, report search progress
758  uSMAByte l_SmaMsgRd;
759  l_SmaMsgRd.RawSMAB =0;
760  auto l_EndTime = std::chrono::system_clock::now() + std::chrono::milliseconds(l_MaxMesTimeoutMs);
761 
762  for (;
763  !m_rMFCController.l_IsAbortRequested() && !l_SmaMsgRd.SMAByte.DRST1 && !l_SmaMsgRd.SMAByte.PANST2;
764  )
765  {
766  if(l_MaxTimeoutValid)
767  {
768  if(std::chrono::system_clock::now() > l_EndTime) //An error occured during measurement. MFC3045 seems to be blocked or serial communication is not working anymore
769  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Search timeout", MTL__LOCATION__);
770  }
771  // MFC3045 doesn't have search progress. Make one here.
772  l_SearchProg = (l_SearchProg + 1) % 99;
773  m_rMFCController.l_SendSearchProgress(l_SearchProg); //notify controller for search progress
774 
775  std::this_thread::sleep_for(std::chrono::milliseconds(SEARCH_POLLING_PERIOD_MS));
776  // read for received SMA (Data Ready or PA disconnected) message if any (with a timeout)
777  m_MFC3045.WaitSmaMeasureDataReady(SEARCH_POLLING_PERIOD_MS, l_SmaMsgRd);
778  }
779  // DISABLE SMA
780  if(!m_MFC3045.DisableSMA())
781  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "SMA disable failed", MTL__LOCATION__);
782  // Now we can send any Read commands to main unit!
783  // read status register to confirm Data ready
784  if(!l_ReadSomeStatusReg(l_SelStatus)) //SetST1 | SetST2 | SetST3
785  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
786  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
787  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
788  if (m_RegStatus2.StatusByte2.PANC) //check if PA is still connected
789  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No PA available", MTL__LOCATION__);
790 
791  if (!m_rMFCController.l_IsAbortRequested())
792  {
793  // If we have a result to read, read search result and return it
794  if (m_RegStatus3.StatusByte3.DAA) // ||(m_RegStatus1.StatusByte1.DRDY))
795  {
796  std::vector<U32> l_ReadMesDatadHz;
797  if (!m_MFC3045.DataMagneticFieldGet(m_NbProbesPA, l_ReadMesDatadHz))
798  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch search result", MTL__LOCATION__);
799  if(l_ReadMesDatadHz.size() < m_NbProbesPA)
800  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing measurment result", MTL__LOCATION__);
801 
802  MTL_Assert(!l_ReadMesDatadHz.empty());
803  if (l_ReadMesDatadHz.empty())
804  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid search result", MTL__LOCATION__);
805 
806  l_SearchProg = 99;
807  m_rMFCController.l_SendSearchProgress(l_SearchProg);//notify controller for search progress complete
808 
809  // Compute result
810  F64 l_AverageMHz, l_StdDevPpm;
811  l_ComputeAveraging(l_ReadMesDatadHz, l_AverageMHz, l_StdDevPpm); //do average on all valid search probes result
812 
813  // Send result
814  CInstrumentCatalog::sSearchResult l_SearchResult;
815  l_SearchResult.Freq = l_AverageMHz; //in MHz
816  l_SearchResult.StdDev = static_cast<F32>(l_StdDevPpm); // in ppm
817  m_rMFCController.l_SendSearchResult(l_SearchResult);
818  }
819  else
820  {
821  //No error but no measurement result available from instrument.
822  LOG("No search result returned by instrument", CInstrumentCatalog::eLogLevel::kWarning, MTL__LOCATION__);
823  }
824  }
825  else
826  m_MFC3045.BreakMeasSet(); // stop any acquisition in main unit
827  } while (!m_rMFCController.l_IsAbortRequested() && l_IsContinuous);
828 
829  l_SelStatus.SelSTReg = SetSTALL; // read all status registers
830  if(!l_ReadSomeStatusReg(l_SelStatus))
831  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
832  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
833  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
834  l_ReturnError = sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Search operation done.", MTL__LOCATION__);
835  }
836  catch (sMFCDeviceError & rE)
837  {
838  U32 l_ReadTimeoutMs(0);
839  // Signal error
840  l_ReturnError = rE;
841  m_MFC3045.GetCurrentTimeoutRdDataMs(l_ReadTimeoutMs);
842  m_MFC3045.SetTimeoutRdNewDataMs(1000);// set shorter timeout on serial read communication
843  m_MFC3045.BreakMeasSet(); // stop any acquisition in main unit
844  if(!m_MFC3045.DisableSMA()) // DisableSMA() contains a readback of SMA register. If read failed don't try to read Status Register
845  {
846  l_SelStatus.SelSTReg = SetSTALL; // Read all status registers to clear them
847  l_ReadSomeStatusReg(l_SelStatus);
848  }
849  m_MFC3045.SetTimeoutRdNewDataMs(l_ReadTimeoutMs); // set back previous serial read timeout
850  }
851  return l_ReturnError;
852 }
853 
855 {
856  bool l_MeasAllPA = true;
857  uSMAByte l_SmaMsgRd;
858  uStatusRegSel l_SelStatus;
859  sMFCDeviceError l_ReturnError;
860  try
861  {
862  // read all status registers
863  l_SelStatus.SelSTReg = SetSTALL;
864  if(!l_ReadSomeStatusReg(l_SelStatus))
865  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
866  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
867  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
868  if (m_RegStatus2.StatusByte2.PANC) //check if PA connected
869  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No PA available", MTL__LOCATION__);
870 
871  sMFCDeviceError l_Error;
872  if(!l_ConfigureForOperation(rInstrState,l_Error))
873  throw l_Error;
874 
875  l_SelStatus.SelSTReg = SetST1 | SetST2;
876  if(!l_ReadSomeStatusReg(l_SelStatus))
877  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
878  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
879  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
880  if (m_RegStatus2.StatusByte2.MED || m_RegStatus2.StatusByte2.PANC) //check Modulation setting error
881  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 2: 0b" + toBinaryString(m_RegStatus2.RawSTB2), MTL__LOCATION__);
882 
883  U64 l_MaxMesTimeoutMs(0);
884  bool l_MaxTimeoutValid = l_ComputeMaxMeasTimeout(l_MaxMesTimeoutMs);
885 
886  // Start to measure NMR
887  bool l_IsContinuous = (CInstrumentCatalog::eRepeatMode::kContinuous == rInstrState.RepeatMode);
888  l_SelStatus.SelSTReg = SetST1 | SetST2 | SetST3;
889  do
890  {
891  U8 l_SearchProg =0;
892  switch (rInstrState.ProbeSelection.SelectionMode)
893  {
895  {
896  // ENABLE SMA
897  if (!m_MFC3045.MeasStartWithSMA()) // Start measurement with SMA enable on PA not connected and Data ready.
898  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not start measurment", MTL__LOCATION__);
899  }
900  break;
901 
903  {
904  l_MeasAllPA = false;
905  // ENABLE SMA
906  if (!m_MFC3045.MeasStartWithSMA(rInstrState.ProbeSelection.ProbeNumber)) // Start measurement with SMA enable on PA not connected and Data ready.
907  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not start measurment", MTL__LOCATION__);
908  }
909  break;
910  default:
911  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Probe selection mode not supported", MTL__LOCATION__);
912  break;
913  }
914  // WARNING: From now, no read command should be sent until SMA is disable.
915  // We use this measurement method with SMA waiting on data ready message instead of a status register polling, because the Main unit firmware seems
916  // to have occasionnaly a problem on parsing a command during measurement process (eg. Command error detects "TST" instead of STx)
917 
918  std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait measurement to start in MFC3045
919  // Note: no read status allowed while waiting for SMA (send automatic message from main unit)
920  // Wait conntinuously while
921  // - we are not requested to stop
922  // - we don't have our measurement results
923  // If system indicates Searching, report search progress
924 
925  l_SmaMsgRd.RawSMAB =0;
926  auto l_EndTime = std::chrono::system_clock::now() + std::chrono::milliseconds(l_MaxMesTimeoutMs);
927  for (;
928  !m_rMFCController.l_IsAbortRequested() && !l_SmaMsgRd.SMAByte.DRST1 && !l_SmaMsgRd.SMAByte.PANST2;
929  )
930  {
931  if(l_MaxTimeoutValid)
932  {
933  if(std::chrono::system_clock::now() > l_EndTime)
934  {//An error occured during measurement. MFC3045 seems to be blocked or serial communication is not working anymore
935  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Measurement timeout", MTL__LOCATION__);
936  }
937  }
938  // MFC3045 doesn't have search progress. Make one here.
939  l_SearchProg = (l_SearchProg + 2) % 98; // never go to 100
940  m_rMFCController.l_SendSearchProgress(l_SearchProg); // notify controller for search progress
941  std::this_thread::sleep_for(std::chrono::milliseconds(MEAS_POLLING_PERIOD_MS));
942  // read for received SMA (Data Ready or PA disconnected) message if any (with a timeout)
943  m_MFC3045.WaitSmaMeasureDataReady(MEAS_POLLING_PERIOD_MS, l_SmaMsgRd);
944  }
945  // DISABLE SMA
946  if(!m_MFC3045.DisableSMA())
947  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "SMA disable failed", MTL__LOCATION__);
948  // Now, we can send any read command to main unit!
949  // read status register to confirm Data ready
950  if(!l_ReadSomeStatusReg(l_SelStatus)) //SetST1 | SetST2 | SetST3
951  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
952  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
953  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
954  if (m_RegStatus2.StatusByte2.PANC) //check if PA is still connected
955  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No PA available", MTL__LOCATION__);
956 
957  if(!m_rMFCController.l_IsAbortRequested())
958  {
959  // If we have a result to read, read measurement results and return it
960  if (m_RegStatus3.StatusByte3.DAA) // ||(m_RegStatus1.StatusByte1.DRDY))
961  {
962  l_SearchProg = 99;
963  m_rMFCController.l_SendSearchProgress(l_SearchProg);//notify controller for search progress
965  l_MeasResult.Timestamp = static_cast<U64>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()); //ms since epoch
966  if(l_MeasAllPA) // all probes measurement
967  {
968  std::vector<U32> l_ReadMesDatadHz;
969  std::vector<U32> l_ReadStdDevDatadHz;
970  std::vector<U32> l_ReadValidCycleNb;
971  if (!m_MFC3045.DataMagneticFieldGet(m_NbProbesPA, l_ReadMesDatadHz))
972  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch measurment result", MTL__LOCATION__);
973  if(l_ReadMesDatadHz.size() < m_NbProbesPA)
974  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing measurment result", MTL__LOCATION__);
975 
976  if (!m_MFC3045.DataStdDeviationGet(m_NbProbesPA, l_ReadStdDevDatadHz))
977  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch std dev result", MTL__LOCATION__);
978  if(l_ReadStdDevDatadHz.size() < m_NbProbesPA)
979  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing std dev result", MTL__LOCATION__);
980 
981  if (!m_MFC3045.DataNumberValidCycleGet(m_NbProbesPA, l_ReadValidCycleNb))
982  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch nb valid cycle result", MTL__LOCATION__);
983  if(l_ReadValidCycleNb.size() < m_NbProbesPA)
984  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing Valid cycle result", MTL__LOCATION__);
985 
986  // Prepare PA measurement result
987  for (U8 l_it =0; l_it < m_NbProbesPA; l_it++)
988  {
990  l_Meas.ProbeNumber = l_it+1;
991  l_Meas.NbValidMeasurements = l_ReadValidCycleNb.at(l_it);
992  if(l_ReadValidCycleNb.at(l_it) > 0)
993  {
994  l_Meas.Freq = l_ConvertdHzToMHz(l_ReadMesDatadHz.at(l_it));
995  l_Meas.StdDev = l_ConvertStdDevdHzToPpm(l_ReadStdDevDatadHz.at(l_it), l_ReadMesDatadHz.at(l_it));
996  }
997  else
998  {// nb valid cycle =0 on this probe measurement, fill with NaN
999  l_Meas.Freq = DPqNaN;
1000  l_Meas.StdDev = static_cast<F32>(DPqNaN);
1001  }
1002  l_MeasResult.MeasurementList.push_back(l_Meas);
1003  }
1004  }
1005  else // Single probe measurement
1006  {
1007  U32 l_ReadMesDatadHz;
1008  U32 l_ReadStdDevDatadHz;
1009  U32 l_ReadValidCycleNb;
1010 
1011  if (!m_MFC3045.DataMagneticFieldGet(l_ReadMesDatadHz, rInstrState.ProbeSelection.ProbeNumber))
1012  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch measurement result", MTL__LOCATION__);
1013  if (!m_MFC3045.DataStdDeviationGet(l_ReadStdDevDatadHz, rInstrState.ProbeSelection.ProbeNumber))
1014  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch std dev result", MTL__LOCATION__);
1015  if (!m_MFC3045.DataNumberValidCycleGet(l_ReadValidCycleNb, rInstrState.ProbeSelection.ProbeNumber))
1016  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch valid cycle result", MTL__LOCATION__);
1017  // Prepare single probe result
1019  l_Meas.ProbeNumber = rInstrState.ProbeSelection.ProbeNumber;
1020  l_Meas.NbValidMeasurements = l_ReadValidCycleNb;
1021  if(l_ReadValidCycleNb > 0)
1022  {
1023  l_Meas.Freq = l_ConvertdHzToMHz(l_ReadMesDatadHz);
1024  l_Meas.StdDev = l_ConvertStdDevdHzToPpm(l_ReadStdDevDatadHz, l_ReadMesDatadHz);
1025  }
1026  else
1027  { // nb valid cycle =0 on this probe measurement, fill with NaN
1028  l_Meas.Freq = DPqNaN;
1029  l_Meas.StdDev = static_cast<F32>(DPqNaN);
1030  }
1031  l_MeasResult.MeasurementList.push_back(l_Meas);
1032  }
1033  //Send result
1034  m_rMFCController.l_SendMeasResult(l_MeasResult);
1035  if(!l_ReadSomeStatusReg(l_SelStatus)) //SetST1 | SetST2 | SetST3
1036  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1037  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1038  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1039  }
1040  else
1041  {
1042  //No error but no measurement result available from instrument.
1043  LOG("No measurement result returned by instrument", CInstrumentCatalog::eLogLevel::kWarning, MTL__LOCATION__);
1044  }
1045  }
1046  else
1047  m_MFC3045.BreakMeasSet(); // send Stop any acquisition to main unit
1048  } while (!m_rMFCController.l_IsAbortRequested() && l_IsContinuous);
1049 
1050  l_SelStatus.SelSTReg = SetSTALL; // read all status registers
1051  if(!l_ReadSomeStatusReg(l_SelStatus))
1052  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1053  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1054  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1055  l_ReturnError = sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Measurement operation done.", MTL__LOCATION__);
1056  }
1057  catch (sMFCDeviceError & rE)
1058  {
1059  U32 l_ReadTimeoutMs(0);
1060  // Signal error
1061  l_ReturnError = rE;
1062 
1063  m_MFC3045.GetCurrentTimeoutRdDataMs(l_ReadTimeoutMs);
1064  m_MFC3045.SetTimeoutRdNewDataMs(1000);// set shorter timeout on serial read
1065  m_MFC3045.BreakMeasSet(); // stop any acquisition in main unit
1066  if(!m_MFC3045.DisableSMA()) // DisableSMA() contains a readback of SMA register. If read failed don't try to read Status Register
1067  {
1068  l_SelStatus.SelSTReg = SetSTALL;
1069  l_ReadSomeStatusReg(l_SelStatus);// Read all status registers to clear them
1070  }
1071  m_MFC3045.SetTimeoutRdNewDataMs(l_ReadTimeoutMs); // set back previous serial read timeout
1072  }
1073  return l_ReturnError;
1074 }
1075 
1077  CInstrumentCatalog::sNormalization & rReturnedNormalization)
1078 {
1079  try
1080  {
1081  uStatusRegSel l_SelStatus;
1082  // read all status registers
1083  l_SelStatus.SelSTReg = SetSTALL;
1084  if(!l_ReadSomeStatusReg(l_SelStatus))
1085  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1086  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1087  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1088  if (m_RegStatus2.StatusByte2.PANC) //check if PA connected
1089  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No PA available", MTL__LOCATION__);
1090 
1091  rReturnedNormalization.Access = rNewNormalizationRequest.Access;
1092  rReturnedNormalization.Table.clear();
1093 
1094  if (!m_MFC3045.DataBlockModeDecimalSet())
1095  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set block mode to decimal", MTL__LOCATION__);
1096  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::k2))
1097  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
1098  switch (rNewNormalizationRequest.Access)
1099  {
1101  {
1102  // Read Normalization from RAM
1103  std::vector<I32> l_MFC3045NormalizationdHz;
1104  if (!m_MFC3045.CalibrationBuildTableGet(m_NbProbesPA, l_MFC3045NormalizationdHz))
1105  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve normalization table", MTL__LOCATION__);
1106  if(l_MFC3045NormalizationdHz.size() < m_NbProbesPA)
1107  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing normalization result", MTL__LOCATION__);
1108 
1109  // check Status byte (ST1, ST4)
1110  l_SelStatus.SelSTReg = SetST1 | SetST4;
1111  if(!l_ReadSomeStatusReg(l_SelStatus))
1112  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1113  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1114  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1115  if (m_RegStatus4.StatusByte4.EPM) //check if error reading PA EEPROM
1116  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 4: 0b" + toBinaryString(m_RegStatus4.RawSTB4), MTL__LOCATION__);
1117  // Convert units and fill Normalization table
1118  for (auto&& Factor_dHz : l_MFC3045NormalizationdHz)
1119  {
1120  rReturnedNormalization.Table.push_back(l_ConvertNormdHzToMHz(Factor_dHz)); // From [dHz] to [MHz]
1121  }
1122  break;
1123  }
1125  {
1126  // Read Normalization from PA-EEPROM
1127  std::vector<I32> l_MFC3045NormalizationdHz;
1128  if (!m_MFC3045.CalibrationBuildTableClearRAM())
1129  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot clear RAM normalization table", MTL__LOCATION__);
1130  if (!m_MFC3045.CalibrationBuildTableCopyEEPROMToRAM())
1131  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot copy normalization table from EEPROM to RAM", MTL__LOCATION__);
1132  if (!m_MFC3045.CalibrationBuildTableGet(m_NbProbesPA, l_MFC3045NormalizationdHz))
1133  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve normalization table", MTL__LOCATION__);
1134  if(l_MFC3045NormalizationdHz.size() < m_NbProbesPA)
1135  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing normalization result", MTL__LOCATION__);
1136  // check Status byte (ST1, ST4)
1137  l_SelStatus.SelSTReg = SetST1 | SetST4;
1138  if(!l_ReadSomeStatusReg(l_SelStatus))
1139  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1140  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1141  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1142  if (m_RegStatus4.StatusByte4.EPM) //check if error reading PA EEPROM
1143  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 4: 0b" + toBinaryString(m_RegStatus4.RawSTB4), MTL__LOCATION__);
1144  // Convert units and fill Normalization table
1145  for (auto&& Factor_dHz : l_MFC3045NormalizationdHz)
1146  {
1147  rReturnedNormalization.Table.push_back(l_ConvertNormdHzToMHz(Factor_dHz)); // From [dHz] to [MHz]
1148  }
1149  break;
1150  }
1152  {
1153  //Write normalization in RAM
1154  sMFCDeviceError l_Error;
1155  if(!l_WriteNormalizationRAM(rNewNormalizationRequest.Table,l_Error))
1156  throw l_Error;
1157  // check Status byte (ST1, ST4)
1158  l_SelStatus.SelSTReg = SetST1 | SetST4;
1159  if(!l_ReadSomeStatusReg(l_SelStatus))
1160  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1161  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1162  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1163  break;
1164  }
1166  {
1167  // Write Normalization in EEPROM
1168  sMFCDeviceError l_Error;
1169  if(!l_WriteNormalizationRAM(rNewNormalizationRequest.Table,l_Error))
1170  throw l_Error;
1171  //Check Status ST1 for errors
1172  l_SelStatus.SelSTReg = SetST1;
1173  if(!l_ReadSomeStatusReg(l_SelStatus))
1174  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1175  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1176  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1177 
1178  // Update normalization date (UTC) in RAM
1179  std::time_t l_NewDateNorm;
1180  time(&l_NewDateNorm); // get current date & time at UTC (timezone 0)
1181  if (!m_MFC3045.CalibrationDatePASet(l_NewDateNorm))
1182  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to set new normalization date in RAM", MTL__LOCATION__);
1183 
1184  // Save dedicated normalization RAM content to PA-EEPROM
1185  if (!m_MFC3045.ProbeArrayEepromWrite())
1186  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to save normalization table in PA EEPROM", MTL__LOCATION__);
1187 
1188  // Check Status byte (ST1, ST4)
1189  l_SelStatus.SelSTReg = SetST1 | SetST4;
1190  if(!l_ReadSomeStatusReg(l_SelStatus))
1191  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1192  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1193  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1194  if (!m_RegStatus4.StatusByte4.MSW) //check if writting PA EEPROM has succeeded
1195  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 4: 0b" + toBinaryString(m_RegStatus4.RawSTB4), MTL__LOCATION__);
1196 
1197  // Read back EEPROM and compare with written normalization table
1198  std::vector<I32> l_ReadBackMFC3045NormdHz;
1199  if (!m_MFC3045.CalibrationBuildTableClearRAM())
1200  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot clear RAM normalization table", MTL__LOCATION__);
1201  if (!m_MFC3045.CalibrationBuildTableCopyEEPROMToRAM())
1202  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot copy normalization table from EEPROM to RAM", MTL__LOCATION__);
1203  if (!m_MFC3045.CalibrationBuildTableGet(m_NbProbesPA, l_ReadBackMFC3045NormdHz))
1204  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve normalization table", MTL__LOCATION__);
1205  if(l_ReadBackMFC3045NormdHz.size() < m_NbProbesPA)
1206  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Missing normalization result", MTL__LOCATION__);
1207  // check Status byte (ST1, ST4)
1208  l_SelStatus.SelSTReg = SetST1 | SetST4;
1209  if(!l_ReadSomeStatusReg(l_SelStatus))
1210  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1211  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1212  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1213  if (m_RegStatus4.StatusByte4.EPM) //check if error reading PA EEPROM
1214  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 4: 0b" + toBinaryString(m_RegStatus4.RawSTB4), MTL__LOCATION__);
1215  // Compare written normalization table with PA EEPROM table content
1216  for(U8 l_it =0; l_it < m_NbProbesPA; l_it++)
1217  {
1218  if(l_ReadBackMFC3045NormdHz.at(l_it) != l_ConvertNormMHzTodHz(rNewNormalizationRequest.Table.at(l_it)))
1219  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Wrong normalization value in read back PA EEPROM", MTL__LOCATION__);
1220  }
1221  break;
1222  }
1223  default:
1224  MTL_Assert(false);
1225  throw sMFCDeviceError(sMFCDeviceError::eLevel::kFatal,"Software error. Unhandled case", MTL__LOCATION__);
1226  break;
1227  }
1228  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone))
1229  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to change MU Advanced mode", MTL__LOCATION__);
1230  }
1231  catch (sMFCDeviceError & rE)
1232  {
1233  m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone);
1234  return rE;
1235  }
1236  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "New Normalization request done.", MTL__LOCATION__);
1237 }
1238 
1240 {
1241  try
1242  {
1243  uStatusRegSel l_SelStatus;
1244  std::time_t l_NormDateUTC;
1245  std::string l_NormDateUTCStr;
1246 
1247  // Read status register ST1 & ST2
1248  l_SelStatus.SelSTReg = SetST1 | SetST2;
1249  if(!l_ReadSomeStatusReg(l_SelStatus))
1250  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1251  if (m_RegStatus1.StatusByte1.ECOM) //check serial communication error
1252  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1253  if (m_RegStatus2.StatusByte2.PANC) //check if PA connected
1254  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 2: 0b" + toBinaryString(m_RegStatus2.RawSTB2), MTL__LOCATION__);
1255  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::k1))
1256  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to change MU Advanced mode", MTL__LOCATION__);
1257 
1258  // Get PA normalization date
1259  if(!m_MFC3045.CalibrationDatePAGet(l_NormDateUTCStr, l_NormDateUTC)) // Note: this methode request high advance command level mode
1260  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to get normalization date", MTL__LOCATION__);
1261  if(!l_UtcToStrDateISO8601(l_NormDateUTC, rNormDate)) // convert time_t UTC to YYYY-MM-DDTHH:MM:SSZ ISO8601 format
1262  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to parse normalization date", MTL__LOCATION__);
1263 
1264  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone))
1265  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to change MU Advanced mode", MTL__LOCATION__);
1266 
1267  l_SelStatus.SelSTReg = SetST1;
1268  if(!l_ReadSomeStatusReg(l_SelStatus))
1269  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1270  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1271  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1272  }
1273  catch (sMFCDeviceError & rE)
1274  {
1275  return rE;
1276  }
1277  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Get normalization date done.", MTL__LOCATION__);
1278 }
1279 
1281 {
1282  try
1283  {
1284  eRemoteBusyLed l_MFC3045RemoteLedState;
1285  switch (rRBBusyLedState)
1286  {
1288  l_MFC3045RemoteLedState = eRemoteBusyLed::kRemoteLedOff;
1289  break;
1291  l_MFC3045RemoteLedState = eRemoteBusyLed::kRemoteLedMeasuring;
1292  break;
1294  l_MFC3045RemoteLedState = eRemoteBusyLed::kRemoteLedOffEndMeas;
1295  break;
1297  l_MFC3045RemoteLedState = eRemoteBusyLed::kRemoteLedOn;
1298  break;
1300  l_MFC3045RemoteLedState = eRemoteBusyLed::kRemoteLedBlinkSlow;
1301  break;
1303  l_MFC3045RemoteLedState = eRemoteBusyLed::kRemoteLedBlinkFast;
1304  break;
1305  default:
1306  MTL_Assert(false);
1307  throw sMFCDeviceError(sMFCDeviceError::eLevel::kFatal, "Unhandled busy led mode", MTL__LOCATION__);
1308  break;
1309  }
1310  uStatusRegSel l_SelStatus;
1311  l_SelStatus.SelSTReg = SetST1;
1312  if(!l_ReadSomeStatusReg(l_SelStatus))
1313  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1314  if (!m_MFC3045.RemoteBusyLedSet(l_MFC3045RemoteLedState))
1315  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not set remote box busy led state", MTL__LOCATION__);
1316  l_SelStatus.SelSTReg = SetST1 | SetST5;
1317  if(!l_ReadSomeStatusReg(l_SelStatus))
1318  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1319  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1320  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1321  }
1322  catch (sMFCDeviceError & rE)
1323  {
1324  return rE;
1325  }
1326  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Set remote box busy led state done.", MTL__LOCATION__);
1327 }
1328 
1330 {
1331  try
1332  {
1333  uStatusRegSel l_SelStatus;
1334  l_SelStatus.SelSTReg = SetST4;
1335  if(!l_ReadSomeStatusReg(l_SelStatus)) // read status 4
1336  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1337  rRemoteStartPressed = false;
1338  if(m_RegStatus4.StatusByte4.RBC) // beware to not clear the bit in l_ScanPA by reading the status register 4 before here
1339  {
1340  if (!m_RegStatus4.StatusByte4.RBS) //check remote button State
1341  rRemoteStartPressed = true;
1342  }
1343  }
1344  catch (sMFCDeviceError & rE)
1345  {
1346  rRemoteStartPressed = false;
1347  return rE;
1348  }
1349  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Check RemoteBox Status button done.", MTL__LOCATION__);
1350 }
1351 
1353 {
1354  bool l_SystemReset(false);
1355  try
1356  {
1357  sSerialPortSettings l_NewVisaSerialSettings;
1358  U16 l_NewRSPSettings, l_ReadRSPRegValue;
1359  uStatusRegSel l_SelStatus;
1360  l_SelStatus.SelSTReg = SetST1 | SetST4 | SetST5;
1361 
1362  if (!IsInstrumentConnected())
1363  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "No more instrument connected", MTL__LOCATION__);
1364 
1365  if(!l_ReadSomeStatusReg(l_SelStatus)) // read status to clear bits
1366  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1367  if(!l_ParseSerialSettings(rNewSerialSetting, l_NewVisaSerialSettings))
1368  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to parse serial settings", MTL__LOCATION__);
1369 
1370  if(!m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::k2))
1371  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to change MU Advanced mode", MTL__LOCATION__);
1372  if(!m_MFC3045.ParseParmForRSP(l_NewVisaSerialSettings,l_NewRSPSettings))
1373  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to parse serial settings to RSP register type", MTL__LOCATION__);
1374  if(!m_MFC3045.SerialRSPSet(l_NewRSPSettings))
1375  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to set RSP register", MTL__LOCATION__);
1376  // read back register RSP and compare
1377  if(!m_MFC3045.SerialRSPGet(l_ReadRSPRegValue))
1378  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to read RSP register", MTL__LOCATION__);
1379  if(l_ReadRSPRegValue!= l_NewRSPSettings)
1380  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Write and read back RSP register different", MTL__LOCATION__);
1381 
1382  if(!l_ReadSomeStatusReg(l_SelStatus)) //SetST1 | SetST4 | SetST5
1383  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Status registers read failed", MTL__LOCATION__);
1384  if (m_RegStatus1.StatusByte1.ECMD) //check serial command error
1385  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1386  if (m_RegStatus5.StatusByte5.EFR | m_RegStatus5.StatusByte5.EOR | m_RegStatus5.StatusByte5.EPY) //check serial communication error
1387  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Error on Status 5: 0b" + toBinaryString(m_RegStatus5.RawSTB5), MTL__LOCATION__);
1388 
1389  //Save new RS parms in MU-EEPROM
1390  if(!m_MFC3045.MainUnitEepromWrite())
1391  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to save new Serial parms to Main unit EEPROM", MTL__LOCATION__);
1392  MTL_SleepMs(1000);
1393 
1394  // Read status register 1
1395  l_SelStatus.SelSTReg = SetST1 | SetST4;
1396  if(!l_ReadSomeStatusReg(l_SelStatus)) //SetST1 | SetST4
1397  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Status registers read failed", MTL__LOCATION__);
1398  if (m_RegStatus1.StatusByte1.ECMD || m_RegStatus1.StatusByte1.ECOM) //check serial command and communication error
1399  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Error on Status 1: 0b" + toBinaryString(m_RegStatus1.RawSTB1), MTL__LOCATION__);
1400  if (!m_RegStatus4.StatusByte4.MSW)
1401  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to save RS settings in main unit EEPROM", MTL__LOCATION__);
1402 
1403  //Reset Main Unit
1404  l_SystemReset = true;
1405  if(!m_MFC3045.SystemResetSet()) // Beware after a Main unit reset, registers take their default value (For example advanced mode and datablock mode)
1406  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to reset main unit instrument", MTL__LOCATION__);
1407 
1408  m_SerialParms = l_NewVisaSerialSettings;
1409  if(!m_MFC3045.DisconnectInstrument()) // Need to disconnect host Serial port before to reconnect it
1410  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to close VISA connection", MTL__LOCATION__);
1411  MTL_SleepMs(2000); // wait a bit to let the main unit to restart
1412  }
1413  catch (sMFCDeviceError & rE)
1414  {
1415  if(!l_SystemReset)
1416  m_MFC3045.AdvancedCommandModeSet(eAdvancedMode::kNone);
1417  return rE;
1418  }
1419  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Change instrument serial settings done.", MTL__LOCATION__);
1420 }
1421 
MTL::CInstrumentCatalog::eNormalizationAccess::kReadROM
@ kReadROM
l_ConvertStdDevdHzToPpm
F32 l_ConvertStdDevdHzToPpm(const U32 &rStdDevdHz, const U32 &rFreqRefdHz)
Definition: MFC3045Device.cpp:69
MTL::CInstrumentCatalog::tISO8601DateTime
std::string tISO8601DateTime
Definition: InstrumentCatalog.h:28
MTL::CInstrumentCatalog::eNormalizationAccess::kReadRAM
@ kReadRAM
MTL::Instrument::MFC3045Types::uStatusByte5::sStatusByte5::EPY
U8 EPY
Definition: MFC3045Types.h:179
MTL::CInstrumentCatalog::sProbeInformation::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:134
MTL::Instrument::CMFC3045Instrument::CheckInstrumentConnection
bool CheckInstrumentConnection(const U8 &rl_Retry=3)
Definition: MFC3045.cpp:505
MTL::CInstrumentCatalog::sMeasurementResults::MeasurementList
tMeasurementList MeasurementList
Definition: InstrumentCatalog.h:269
SetSTALL
#define SetSTALL
Definition: MFC3045Device.h:28
MTL::Instrument::CMFC3045Instrument::ModulationPeriodGet
bool ModulationPeriodGet(U16 &rRegVal)
Definition: MFC3045.cpp:1874
MTL::CMFC3045Device::IsInstrumentConnected
bool IsInstrumentConnected()
Definition: MFC3045Device.cpp:496
MTL::CInstrumentCatalog::sProbeArrayInformation::GyroRatio
F64 GyroRatio
Definition: InstrumentCatalog.h:153
MTL::Instrument::CMFC3045Instrument::DataStdDeviationGet
bool DataStdDeviationGet(const U8 &rNbMeasurements, std::vector< U32 > &rData)
Definition: MFC3045.cpp:2919
MTL::CInstrumentCatalog::eSerialHandshake::kXonXoff
@ kXonXoff
GYRORATIO_MFC3048_HZT
#define GYRORATIO_MFC3048_HZT
Definition: MFC3045Types.h:49
MTL::Instrument::sSerialPortSettings::Handshake
eSerialHandshake Handshake
Definition: VISAInstrumentTypes.h:178
MTL::CInstrumentCatalog::eSerialStopBits::k2
@ k2
MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4::HWP
U8 HWP
Definition: MFC3045Types.h:152
MTL::CInstrumentCatalog::sMeasurement::StdDev
F32 StdDev
Definition: InstrumentCatalog.h:261
MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4::RBC
U8 RBC
Definition: MFC3045Types.h:156
MTL::CMFC3045Device::Search
sMFCDeviceError Search(const CInstrumentCatalog::sInstrumentState &rInstrState)
Definition: MFC3045Device.cpp:708
MTL::CInstrumentCatalog::sInstrumentState::ProbeSelection
sMeasureProbeSelection ProbeSelection
Definition: InstrumentCatalog.h:215
MTL::Instrument::MFC3045Types::uStatusByte2::sStatusByte2::PANC
U8 PANC
Definition: MFC3045Types.h:124
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableClearRAM
bool CalibrationBuildTableClearRAM()
Definition: MFC3045.cpp:3761
l_ConvertMHzTodHz
U32 l_ConvertMHzTodHz(const F64 &rFreqMHz)
Definition: MFC3045Device.cpp:54
MTL::Instrument::CMFC3045Instrument::SearchStartWithSMA
bool SearchStartWithSMA()
Definition: MFC3045.cpp:2571
uStatusRegSel::sStatusRegSel::ST5
U8 ST5
Definition: MFC3045Device.h:38
MTL::Instrument::CMFC3045Instrument::NumberPreCycleGet
bool NumberPreCycleGet(U16 &rRegVal)
Definition: MFC3045.cpp:2084
MTL::CInstrumentCatalog::sSearchResult::Freq
F64 Freq
Definition: InstrumentCatalog.h:251
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings::StopBits
eSerialStopBits StopBits
Definition: InstrumentCatalog.h:85
uStatusRegSel::SelSTReg
U8 SelSTReg
Definition: MFC3045Device.h:31
MTL::CInstrumentCatalog::sInstrumentState::RepeatMode
eRepeatMode RepeatMode
Definition: InstrumentCatalog.h:214
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings::Parity
eSerialParity Parity
Definition: InstrumentCatalog.h:84
MTL::Instrument::CMFC3045Instrument::PaCentralFreqGet
bool PaCentralFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:3276
MTL::Instrument::CMFC3045Instrument::SerialRSPGet
bool SerialRSPGet(U16 &rRegVal)
Definition: MFC3045.cpp:907
MTL::Instrument::MFC3045Types::uSMAByte::SMAByte
struct MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte SMAByte
MTL::CInstrumentCatalog::sMeasurement
Definition: InstrumentCatalog.h:257
MTL::CInstrumentCatalog::eMeasureSelectionMode::kProbeArray
@ kProbeArray
MTL::CInstrumentCatalog::eMeasureSelectionMode::kSingleProbe
@ kSingleProbe
MTL::Instrument::sSerialPortSettings::Baudrate
eSerialBaudrate Baudrate
Definition: VISAInstrumentTypes.h:174
MTL::CInstrumentCatalog::eRepeatMode::kContinuous
@ kContinuous
MTL::CInstrumentCatalog::eSerialBaudrate::k9600
@ k9600
MTL::Instrument::CMFC3045Instrument::MeasStartWithSMA
bool MeasStartWithSMA()
Definition: MFC3045.cpp:2385
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::DRST1
U8 DRST1
Definition: MFC3045Types.h:206
SetST2
#define SetST2
Definition: MFC3045Device.h:23
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedBlinkSlow
@ kRemoteBusyLedBlinkSlow
MTL::Instrument::MFC3045Types::eRemoteBusyLed
eRemoteBusyLed
Definition: MFC3045Types.h:299
MTL::Instrument::CMFC3045Instrument::NumberProbesGet
bool NumberProbesGet(U8 &rRegVal)
Definition: MFC3045.cpp:3223
MTL::Instrument::MFC3045Types::uStatusByte2::StatusByte2
struct MTL::Instrument::MFC3045Types::uStatusByte2::sStatusByte2 StatusByte2
MTL::Instrument::CMFC3045Instrument::ModulationLowestFreqSet
bool ModulationLowestFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:1680
MTL::Instrument::CMFC3045Instrument::WaitSmaMeasureDataReady
bool WaitSmaMeasureDataReady(const U32 &rMeasWaitTimeout_ms, uSMAByte &rDataReady)
Definition: MFC3045.cpp:2461
MTL::Instrument::CMFC3045Instrument::DataBlockModeDecimalSet
bool DataBlockModeDecimalSet()
Definition: MFC3045.cpp:2714
MTL::CMFC3045Device::AbortInstrument
bool AbortInstrument()
Definition: MFC3045Device.cpp:491
MTL::Instrument::CMFC3045Instrument::SetTimeoutRdNewDataMs
void SetTimeoutRdNewDataMs(const U32 &rNewdataTimeout_ms=RS_WAIT_DATARD_MS)
Definition: MFC3045.cpp:667
MTL::CInstrumentCatalog::sSearchResult::StdDev
F32 StdDev
Definition: InstrumentCatalog.h:252
MTL::Instrument::MFC3045Types::uStatusByte5::StatusByte5
struct MTL::Instrument::MFC3045Types::uStatusByte5::sStatusByte5 StatusByte5
uStatusRegSel::sStatusRegSel::ALLST
U8 ALLST
Definition: MFC3045Device.h:40
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedOffEndMeas
@ kRemoteBusyLedOffEndMeas
MTL_SleepMs
#define MTL_SleepMs(_ms_)
Definition: Helpers.h:46
MTL::Instrument::sSerialPortSettings
Definition: VISAInstrumentTypes.h:173
MTL::CInstrumentCatalog::eSerialDataBits::k8
@ k8
MTL::CMFC3045Device::ScanPA
sMFCDeviceError ScanPA(CInstrumentCatalog::sProbeArrayInformation &rPAInfo, CInstrumentCatalog::sInstrumentConfiguration &rInstrConfig, bool &rPaInfoChanged)
Definition: MFC3045Device.cpp:579
MTL::CInstrumentCatalog::eNormalizationAccess::kWriteRAM
@ kWriteRAM
MTL::CInstrumentCatalog::sMeasurementResults
Definition: InstrumentCatalog.h:267
MTL::CInstrumentCatalog::sSearchResult
Definition: InstrumentCatalog.h:250
MTL::CInstrumentCatalog::eSerialHandshake::kNone
@ kNone
MTL::CInstrumentCatalog::sInstrumentInformation::SerialNumber
std::string SerialNumber
Definition: InstrumentCatalog.h:109
MTL::Instrument::MFC3045Types::uStatusByte3::StatusByte3
struct MTL::Instrument::MFC3045Types::uStatusByte3::sStatusByte3 StatusByte3
MTL::CInstrumentCatalog::sMeasurement::ProbeNumber
U8 ProbeNumber
Definition: InstrumentCatalog.h:258
NCY_MIN
#define NCY_MIN
Definition: MFC3045Types.h:24
l_ConvertNormMHzTodHz
I32 l_ConvertNormMHzTodHz(const F32 &rFreqMHz)
Definition: MFC3045Device.cpp:64
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:150
MTL::CInstrumentCatalog::sMeasureProbeSelection::SelectionMode
eMeasureSelectionMode SelectionMode
Definition: InstrumentCatalog.h:199
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableCopyEEPROMToRAM
bool CalibrationBuildTableCopyEEPROMToRAM()
Definition: MFC3045.cpp:3739
MTL::Instrument::CMFC3045Instrument::MainUnitEepromWrite
bool MainUnitEepromWrite()
Definition: MFC3045.cpp:3527
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqCentral
F64 FreqCentral
Definition: InstrumentCatalog.h:152
MTL::CInstrumentCatalog::sProbeArrayInformation::Type
eProbeArrayType Type
Definition: InstrumentCatalog.h:146
MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4::EMM
U8 EMM
Definition: MFC3045Types.h:158
MTL::CInstrumentCatalog::eSerialBaudrate::k19200
@ k19200
MTL::CMFC3045Device::SetRBBusyLedState
sMFCDeviceError SetRBBusyLedState(const CInstrumentCatalog::eRemoteBoxBusyLedState &rRBBusyLedState)
Definition: MFC3045Device.cpp:1280
MTL::Instrument::CMFC3045Instrument::DisconnectInstrument
bool DisconnectInstrument()
Definition: MFC3045.cpp:606
SetST4
#define SetST4
Definition: MFC3045Device.h:25
MTL::Instrument::MFC3045Types::uStatusByte5::RawSTB5
U8 RawSTB5
Definition: MFC3045Types.h:165
MTL::Instrument::CMFC3045Instrument::DisableSMA
bool DisableSMA()
Definition: MFC3045.cpp:1514
MTL::CInstrumentCatalog::sInstrumentInformation::Description
std::string Description
Definition: InstrumentCatalog.h:110
MTL::CInstrumentCatalog::eLogLevel::kDebug
@ kDebug
MTL::CInstrumentCatalog::sMeasurement::Freq
F64 Freq
Definition: InstrumentCatalog.h:259
MTL::CInstrumentCatalog::sProbeInformation::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:133
MTL::Instrument::MFC3045Types::uStatusByte5::sStatusByte5::EOR
U8 EOR
Definition: MFC3045Types.h:178
MTL::CInstrumentCatalog::sNormalization::Access
eNormalizationAccess Access
Definition: InstrumentCatalog.h:283
uStatusRegSel::sStatusRegSel::ST3
U8 ST3
Definition: MFC3045Device.h:36
MTL::Instrument::CMFC3045Instrument::Abort
bool Abort()
Definition: MFC3045.cpp:626
date::format
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > & >(), fmt, tp), std::basic_string< CharT >
Definition: date.h:6005
MTL_Assert
#define MTL_Assert
Definition: Helpers.h:44
MTL::CInstrumentCatalog::sInstrumentState
Definition: InstrumentCatalog.h:212
MTL::Instrument::CMFC3045Instrument::CalibrationEditTableSet
bool CalibrationEditTableSet(const I32 &rData)
Definition: MFC3045.cpp:3897
MTL::Instrument::MFC3045Types::uStatusByte1::StatusByte1
struct MTL::Instrument::MFC3045Types::uStatusByte1::sStatusByte1 StatusByte1
MTL::CMFCDevice::sMFCDeviceError
Definition: MFCDevice.h:30
MTL::CInstrumentCatalog::eSerialBaudrate::k38400
@ k38400
MTL::Instrument::CMFC3045Instrument::NumberMeasCycleSet
bool NumberMeasCycleSet(const U16 &rRegVal)
Definition: MFC3045.cpp:2006
MTL::Instrument::CMFC3045Instrument::SystemResetSet
bool SystemResetSet()
Definition: MFC3045.cpp:1005
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedOff
@ kRemoteBusyLedOff
MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4::RBS
U8 RBS
Definition: MFC3045Types.h:155
MTL::CInstrumentCatalog::sProbeArrayInformation::Description
std::string Description
Definition: InstrumentCatalog.h:148
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings
Definition: InstrumentCatalog.h:81
date.h
MTL::CInstrumentCatalog::sInstrumentState::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:217
MTL::Instrument::MFC3045Types::uStatusByte2::sStatusByte2::MED
U8 MED
Definition: MFC3045Types.h:123
MTL::CInstrumentCatalog::eLogLevel::kWarning
@ kWarning
MTL::Instrument::CMFC3045Instrument::ModulationHighestFreqSet
bool ModulationHighestFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:1730
MTL::Instrument::MFC3045Types::uStatusByte4::RawSTB4
U8 RawSTB4
Definition: MFC3045Types.h:149
MTL::Instrument::MFC3045Types::uStatusByte1::sStatusByte1::ECOM
U8 ECOM
Definition: MFC3045Types.h:104
MTL::CMFC3045Device::GetNormalizationDate
sMFCDeviceError GetNormalizationDate(CInstrumentCatalog::tISO8601DateTime &rNormDate)
Definition: MFC3045Device.cpp:1239
MTL::CInstrumentCatalog::eSerialDataBits::k7
@ k7
MTL::CInstrumentCatalog::eNormalizationAccess::kWriteROM
@ kWriteROM
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState
eRemoteBoxBusyLedState
Definition: InstrumentCatalog.h:242
MTL::CInstrumentCatalog::sInstrumentInformation::CalibrationDate
tISO8601DateTime CalibrationDate
Definition: InstrumentCatalog.h:111
MTL::Instrument::CMFC3045Instrument::SerialNumberGet
bool SerialNumberGet(std::string &rSerialNum)
Definition: MFC3045.cpp:1100
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableGet
bool CalibrationBuildTableGet(const U8 &rNbMeasurements, std::vector< I32 > &rData)
Definition: MFC3045.cpp:3818
MTL::CInstrumentCatalog::eSerialBaudrate::k57600
@ k57600
MTL::CInstrumentCatalog::sProbeInformation::ProbeNumber
U8 ProbeNumber
Definition: InstrumentCatalog.h:132
MTL::Instrument::CMFC3045Instrument::GetCurrentTimeoutRdDataMs
void GetCurrentTimeoutRdDataMs(U32 &rRdDataTimeout_ms)
Definition: MFC3045.cpp:661
LOG
#define LOG(__msg__, __level__, __location__)
Definition: MFC3045Device.cpp:17
MTL::Instrument::CMFC3045Instrument::RemoteBusyLedSet
bool RemoteBusyLedSet(const eRemoteBusyLed &rRemoteLed)
Definition: MFC3045.cpp:1148
MTL::Instrument::MFC3045Types::uStatusByte3::sStatusByte3::DAA
U8 DAA
Definition: MFC3045Types.h:133
MTL::CInstrumentCatalog::eSerialParity::kEven
@ kEven
MTL::CMFC3045Device::RemoteBoxButtonStatus
sMFCDeviceError RemoteBoxButtonStatus(bool &rRemoteStartPressed)
Definition: MFC3045Device.cpp:1329
MTL::Instrument::sSerialPortSettings::DataBits
eSerialDataBits DataBits
Definition: VISAInstrumentTypes.h:175
MTL::CInstrumentCatalog::eSerialBaudrate::k115200
@ k115200
MTL::Instrument::CMFC3045Instrument::ConnectInstrument
bool ConnectInstrument(const sSerialPortSettings &rSerialSettings, const U32 &rInitialTimeout_ms=RS_RDWR_VISA_TIMEOUT_MS)
Definition: MFC3045.cpp:543
MTL::CInstrumentCatalog::sProbeArrayInformation
Definition: InstrumentCatalog.h:145
MTL::Instrument::CMFC3045Instrument::ModulationReferenceSet
bool ModulationReferenceSet(const eModulationRef &rRegVal)
Definition: MFC3045.cpp:1779
MTL::Instrument::MFC3045Types::uStatusByte5::sStatusByte5::EFR
U8 EFR
Definition: MFC3045Types.h:180
MTL::CMFC3045Device::NewNormalizationRequest
sMFCDeviceError NewNormalizationRequest(const CInstrumentCatalog::sNormalization &rNewNormalizationRequest, CInstrumentCatalog::sNormalization &rReturnedNormalization)
Definition: MFC3045Device.cpp:1076
MTL::CInstrumentCatalog::sInstrumentInformation::Type
eInstrumentType Type
Definition: InstrumentCatalog.h:108
MTL::CInstrumentCatalog::sMeasureProbeSelection::ProbeNumber
U8 ProbeNumber
Definition: InstrumentCatalog.h:200
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings::Baudrate
eSerialBaudrate Baudrate
Definition: InstrumentCatalog.h:82
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedBlinkFast
@ kRemoteBusyLedBlinkFast
MTL::Instrument::MFC3045Types::uStatusByte1::RawSTB1
U8 RawSTB1
Definition: MFC3045Types.h:98
MTL::Instrument::MFC3045Types::uStatusByte2::RawSTB2
U8 RawSTB2
Definition: MFC3045Types.h:114
MTL::Instrument::CMFC3045Instrument::StatusGet
bool StatusGet(const eStatusRegister &rStatRegSel, U8 &rStatus)
Definition: MFC3045.cpp:1350
MTL::CInstrumentCatalog::sProbeInformation
Definition: InstrumentCatalog.h:131
MTL::CInstrumentCatalog::eProbeArrayType::kMFC3048
@ kMFC3048
SetST3
#define SetST3
Definition: MFC3045Device.h:24
MTL::CInstrumentCatalog::eInstrumentType::kMFC3045
@ kMFC3045
MTL::Instrument::sSerialPortSettings::Parity
eSerialParity Parity
Definition: VISAInstrumentTypes.h:176
NCY_MAX
#define NCY_MAX
Definition: MFC3045Types.h:25
MTL::Instrument::CMFC3045Instrument::CalibrationDateMUGet
bool CalibrationDateMUGet(std::string &rStrDate, std::time_t &rUtcDate)
Definition: MFC3045.cpp:4176
l_ConvertdHzToMHz
F64 l_ConvertdHzToMHz(const U32 &rFreqdHz)
Definition: MFC3045Device.cpp:49
MTL::CMFCDevice::sMFCDeviceError::HasError
bool HasError()
Definition: MFCDevice.h:45
MTL::CInstrumentCatalog::sMeasurementResults::Timestamp
U64 Timestamp
Definition: InstrumentCatalog.h:268
uStatusRegSel::sStatusRegSel::ST6
U8 ST6
Definition: MFC3045Device.h:39
MTL::CInstrumentCatalog::eOperatingMode::kMeasure
@ kMeasure
uStatusRegSel::StRegSelBit
struct uStatusRegSel::sStatusRegSel StRegSelBit
MTL::Instrument::MFC3045Types::uSMAByte
Definition: MFC3045Types.h:202
MTL::Instrument::CMFC3045Instrument::AdvancedCommandModeSet
bool AdvancedCommandModeSet(const eAdvancedMode &rRegVal)
Definition: MFC3045.cpp:936
MFC3045Device.h
MTL::Instrument::MFC3045Types::uStatusByte6::RawSTB6
U8 RawSTB6
Definition: MFC3045Types.h:187
MTL::CInstrumentCatalog::eSerialBaudrate::k4800
@ k4800
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::PANST2
U8 PANST2
Definition: MFC3045Types.h:213
MTL::Instrument::CMFC3045Instrument::SerialRSPSet
bool SerialRSPSet(const U16 &rRegVal)
Definition: MFC3045.cpp:880
MTL::CInstrumentCatalog::eSerialBaudrate::k28800
@ k28800
MTL::Instrument::tResourceName
std::string tResourceName
Definition: VISAInstrumentTypes.h:21
MTL::CInstrumentCatalog::sInstrumentState::NbAveragedMeasurements
U32 NbAveragedMeasurements
Definition: InstrumentCatalog.h:218
MTL::Instrument::CMFC3045Instrument::PaHighestFreqGet
bool PaHighestFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:3378
MTL::CMFC3045Device::Connect
sMFCDeviceError Connect(CInstrumentCatalog::sInstrumentInformation &rInstrInfo)
Definition: MFC3045Device.cpp:511
MTL::CMFCController
Definition: MFCController.h:34
MTL::CMFC3045Device::Measure
sMFCDeviceError Measure(const CInstrumentCatalog::sInstrumentState &rInstrState)
Definition: MFC3045Device.cpp:854
MTL::Instrument::CMFC3045Instrument::CalibrationDatePASet
bool CalibrationDatePASet(const U8 &rDayDD, const U8 &rMonthMM, const U8 &rYearYY, const bool &rSaveInEeprom=false)
Definition: MFC3045.cpp:3984
MTL::CInstrumentCatalog::sInstrumentState::OperatingMode
eOperatingMode OperatingMode
Definition: InstrumentCatalog.h:213
l_ConvertNormdHzToMHz
F32 l_ConvertNormdHzToMHz(const I32 &rFreqdHz)
Definition: MFC3045Device.cpp:59
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedMeasuring
@ kRemoteBusyLedMeasuring
MTL::Instrument::CMFC3045Instrument::DataMagneticFieldGet
bool DataMagneticFieldGet(const U8 &rNbMeasurements, std::vector< U32 > &rData)
Definition: MFC3045.cpp:2857
MTL::Instrument::CMFC3045Instrument::ParseParmForRSP
bool ParseParmForRSP(const sSerialPortSettings &rSerialSettings, U16 &rParmRSPSettings)
Definition: MFC3045.cpp:676
MTL::CInstrumentCatalog::eSerialBaudrate::k2400
@ k2400
MTL::CInstrumentCatalog::eSerialHandshake::kHardware
@ kHardware
MTL::Instrument::MFC3045Types::uSMAByte::RawSMAB
U8 RawSMAB
Definition: MFC3045Types.h:203
MTL::CInstrumentCatalog::eSerialStopBits::k1
@ k1
MTL::CMFC3045Device::ChangeSerialParmsOnConnectedInstr
sMFCDeviceError ChangeSerialParmsOnConnectedInstr(const CInstrumentCatalog::sMFC3045SerialPortSettings &rNewSerialSetting)
Definition: MFC3045Device.cpp:1352
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings::DataBits
eSerialDataBits DataBits
Definition: InstrumentCatalog.h:83
MTL::Instrument::CMFC3045Instrument::LastCmdErrorGet
bool LastCmdErrorGet(std::string &rCmdError)
Definition: MFC3045.cpp:1465
MTL::Instrument::MFC3045Types::uStatusByte4::StatusByte4
struct MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4 StatusByte4
MTL::Instrument::CMFC3045Instrument::PaLowestFreqGet
bool PaLowestFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:3327
MTL::CInstrumentCatalog::sProbeArrayInformation::NormalizationDate
tISO8601DateTime NormalizationDate
Definition: InstrumentCatalog.h:149
SetST1
#define SetST1
Definition: MFC3045Device.h:22
MTL::CInstrumentCatalog::eSerialParity::kOdd
@ kOdd
MTL::CInstrumentCatalog::sProbeArrayInformation::SerialNumber
std::string SerialNumber
Definition: InstrumentCatalog.h:147
MTL::CInstrumentCatalog::sInstrumentInformation
Definition: InstrumentCatalog.h:106
MTL::Instrument::CMFC3045Instrument::BreakMeasSet
bool BreakMeasSet()
Definition: MFC3045.cpp:2666
MTL::CInstrumentCatalog::eOperatingMode::kSearch
@ kSearch
MTL::Instrument::CMFC3045Instrument::CalibrationDatePAGet
bool CalibrationDatePAGet(std::string &rStrDate, std::time_t &rUtcDate)
Definition: MFC3045.cpp:4064
Exception.h
Exception handling utilities.
MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4::MSW
U8 MSW
Definition: MFC3045Types.h:157
MTL::Instrument::CMFC3045Instrument::NumberMeasCycleGet
bool NumberMeasCycleGet(U16 &rRegVal)
Definition: MFC3045.cpp:2032
MTL::CInstrumentCatalog::sInstrumentState::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:216
uStatusRegSel::sStatusRegSel::ST1
U8 ST1
Definition: MFC3045Device.h:34
MTL::CInstrumentCatalog::sNormalization::Table
tNormalizationTable Table
Definition: InstrumentCatalog.h:284
MTL::Instrument::sSerialPortSettings::StopBits
eSerialStopBits StopBits
Definition: VISAInstrumentTypes.h:177
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedOn
@ kRemoteBusyLedOn
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings::Handshake
eSerialHandshake Handshake
Definition: InstrumentCatalog.h:86
MTL::Instrument::CMFC3045Instrument::DataNumberValidCycleGet
bool DataNumberValidCycleGet(const U8 &rNbMeasurements, std::vector< U32 > &rData)
Definition: MFC3045.cpp:2980
uStatusRegSel::sStatusRegSel::ST4
U8 ST4
Definition: MFC3045Device.h:37
uStatusRegSel::sStatusRegSel::ST2
U8 ST2
Definition: MFC3045Device.h:35
SetST5
#define SetST5
Definition: MFC3045Device.h:26
MTL_Unused
#define MTL_Unused(x)
Definition: Helpers.h:47
MTL::Instrument::MFC3045Types::uStatusByte1::sStatusByte1::ECMD
U8 ECMD
Definition: MFC3045Types.h:102
MTL::CInstrumentCatalog::sMeasurement::NbValidMeasurements
U32 NbValidMeasurements
Definition: InstrumentCatalog.h:260
MTL::CInstrumentCatalog::tNormalizationTable
std::vector< tNormalizationCorrection > tNormalizationTable
Definition: InstrumentCatalog.h:281
MTL::Instrument::MFC3045Types::uStatusByte4::sStatusByte4::EPM
U8 EPM
Definition: MFC3045Types.h:159
MTL::Instrument::CVISAResourceManager
VISA Resource Manager class.
Definition: VISAInstrument.h:35
MTL::CInstrumentCatalog::sInstrumentConfiguration
Definition: InstrumentCatalog.h:116
MTL::Instrument::MFC3045Types::uStatusByte3::RawSTB3
U8 RawSTB3
Definition: MFC3045Types.h:130
MTL__LOCATION__
#define MTL__LOCATION__
Definition: Helpers.h:22
MTL::CInstrumentCatalog::sNormalization
Definition: InstrumentCatalog.h:282
MTL::Instrument::CMFC3045Instrument::ProbeArrayEepromWrite
bool ProbeArrayEepromWrite()
Definition: MFC3045.cpp:3578
MTL::CInstrumentCatalog::eSerialParity::kNone
@ kNone
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:151
MTL::CInstrumentCatalog::sProbeArrayInformation::ProbeList
std::vector< sProbeInformation > ProbeList
Definition: InstrumentCatalog.h:154
MTL::CInstrumentCatalog::sInstrumentConfiguration::AcquisitionPeriod
F64 AcquisitionPeriod
Definition: InstrumentCatalog.h:117
MTL::Instrument::CMFC3045Instrument::VersionGet
bool VersionGet(std::string &rVersionInfo, F32 &rFwVersion)
Definition: MFC3045.cpp:1028
uStatusRegSel
Definition: MFC3045Device.h:30
MTL::CMFC3045Device::~CMFC3045Device
virtual ~CMFC3045Device()
Definition: MFC3045Device.cpp:33