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