C++ Instrument Catalog
MFC3045.cpp
Go to the documentation of this file.
1 //--------------------------------------------------------------------------------------------------------
2 // File: MFC3045.cpp Driver
3 // Description: MFC3045 Metrolab Probe-Array Instrument Driver
4 // Note:
5 // This API is working with MFC3045 Firmware version 2.22 (february 2001)
6 // The MFC - 3045 is controlled with a set of commands sent by a computer via a RS - 232C link. An
7 // MFC - 3045 command consists of 3 ASCII characters (which are the command mnemonic) followed
8 // either by a terminator or by a comma, a decimal number (the parameter) and a terminator.The
9 // terminator consists of either the 2 characters "Carriage - Return and Line - Feed" <CR - LF> or of a
10 // semicolon <;>. The semicolon terminator is used to send several commands on one line.
11 // See MFC3045 manual (ver3.0) for more details on RS 232 commands.
12 // The following commands are not supported by this driver : SMA,x ; UPD,x ; ERA
13 // (In comment text the abreviations PA is used for the probe array, MU for the main unit)
14 //--------------------------------------------------------------------------------------------------------
15 
16 // Standard includes
17 #include <locale>
18 #include <regex>
19 #include <iomanip>
20 #include <sstream>
21 
22 //Personal includes
23 #include "MFC3045.h"
24 #include "OSDefines.h"
25 #include "Helpers.h"
26 #include "Exception.h"
27 
28 // External tools includes
29 #include "date.h"
30 
31 //------------------------------------------------------------------//
32 // Definitions
33 //------------------------------------------------------------------//
34 #define DEBUG_MTL_INSTRUMENT_MFC3045 1
35 #define DEBUG_MTL_INSTRUMENT_MFC3045_ERRORS_ONLY 1
36 #if (defined(_DEBUG) && defined(DEBUG_MTL_INSTRUMENT_MFC3045) && DEBUG_MTL_INSTRUMENT_MFC3045)
37 #if (defined(DEBUG_MTL_INSTRUMENT_MFC3045_ERRORS_ONLY) && DEBUG_MTL_INSTRUMENT_MFC3045_ERRORS_ONLY)
38 #define MTL_INSTRUMENT_MFC3045_DEBUG_COUT(__X__)
39 #else
40 #define MTL_INSTRUMENT_MFC3045_DEBUG_COUT(__X__) COUT(__X__)
41 #endif
42 #define MTL_INSTRUMENT_MFC3045_DEBUG_CERR(__X__) CERR(__X__)
43 #else
44 #define MTL_INSTRUMENT_MFC3045_DEBUG_COUT(__X__)
45 #define MTL_INSTRUMENT_MFC3045_DEBUG_CERR(__X__)
46 #endif
47 
48 #define SMA_PA "PA\r\n"
49 #define SMA_UP "UP\r\n"
50 #define SMA_DN "DN\r\n"
51 #define SMA_EE "EE\r\n"
52 #define SMA_RS "RS\r\n"
53 #define SMA_ME "ME\r\n"
54 #define SMA_CE "CE\r\n"
55 #define SMA_DR "DR\r\n"
56 
57 
58 
59 using namespace MTL::Instrument;
60 using namespace MTL::Instrument::MFC3045Types;
61 
62 //----------------------------------------------------------------------//
63 // Exceptions //
64 //----------------------------------------------------------------------//
66 
67 
68 //----------------------------------------------------------------------//
69 // Private Utilities //
70 //----------------------------------------------------------------------//
71 // Configure the Host Serial Port (VISA) to communicate with MFC3045 Main Unit.
72 // Note: To be able to communicate, the host serial setting must be the same as the MFC3045 main unit serial settings.
73 //
74 bool CMFC3045Instrument::l_SerialPortHostConfig(const sSerialPortSettings & rSerialSettings)
75 {
76  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
77  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
78 
79  try {
80  if (!CVISAInstrument::ConfigSerialPort(rSerialSettings))
81  throw CMFC3045InsException(std::string("Fail to configure serial port ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
82  }
83  catch (CMFC3045InsException & rE)
84  {
86  MTL_Unused(rE)
87  return false;
88  }
89  return true;
90 }
91 
92 // Clear (flush) RX and TX (VISA) Host serial Buffer and send a break
93 bool CMFC3045Instrument::l_ClearHostSerialBufferRxTx()
94 {
95  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
96  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
97 
98  try
99  {
100  if (!CVISAInstrument::Clear()) // clear the visa input and output buffer
101  throw CMFC3045InsException("Could not clear RX TX Visa buffer", MTL__LOCATION__);
102  }
103  catch (CMFC3045InsException & rE)
104  {
106  MTL_Unused(rE)
107  return false;
108  }
109  return true;
110 }
111 
112 // Get the number of unreaded byte in the Rx (VISA) buffer
113 bool CMFC3045Instrument::l_GetNewDataRxBufferLength(U32 & rRxBufferLength)
114 {
115  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
116  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
117 
118  try
119  {
120  U32 l_rxBuffLength(0);
121 
122  if (!CVISAInstrument::GetAttribute(VI_ATTR_ASRL_AVAIL_NUM, &l_rxBuffLength)) // get visa input rx buffer length
123  throw CMFC3045InsException("Could not get new data length in RX Visa buffer", MTL__LOCATION__);
124  rRxBufferLength = l_rxBuffLength;
125  }
126  catch (CMFC3045InsException & rE)
127  {
129  MTL_Unused(rE)
130  rRxBufferLength =0;
131  return false;
132  }
133  return true;
134 }
135 
136 // Wait on new data available in host RX (VISA) buffer
137 // The timeout is in millisecond. Each check of RX new data length is done every 10 ms
138 bool CMFC3045Instrument::l_WaitAvailableDataRX(const U32 & rTimeoutRx, U32 & rRXBufferLength, const bool & rErrorOnTimoute)
139 {
140  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
141  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
142  try {
143  U8 l_TimetoCheckMs(10);
144  U32 l_Wait10Ms = rTimeoutRx / l_TimetoCheckMs;
145  if (l_Wait10Ms < 1)
146  l_Wait10Ms = 1; // at least wait 10ms
147  rRXBufferLength = 0;
148 
149  for (U32 it = 0; (0 == rRXBufferLength && it < l_Wait10Ms); it++)
150  {
151  if (m_AbortSerialTransfert)
152  throw CMFC3045InsException("Abort serial command received.", MTL__LOCATION__);
153  MTL_SleepMs(l_TimetoCheckMs);
154  if (!l_GetNewDataRxBufferLength(rRXBufferLength)) // read number of available data in received buffer
155  throw CMFC3045InsException("Fail to get data length", MTL__LOCATION__);
156  }
157  if (0 == rRXBufferLength)
158  {
159  if(rErrorOnTimoute)
160  throw CMFC3045InsException("Timeout reached on wait data RX buffer.", MTL__LOCATION__);
161  else
162  return false; // return false but without exception.
163  }
164  }
165  catch (CMFC3045InsException & rE)
166  {
168  MTL_Unused(rE)
169  return false;
170  }
171  return true;
172 }
173 
174 // Extract SMA (send message automatically) message string from an input string and set the according flag in SMAValue if required.
175 bool CMFC3045Instrument::l_ExtractSmaMsgFromDataRX(const std::string & rNewRxBufferStrIn, uSMAByte & rSMAValue, std::string & rNewRxBufferStrOut)
176 {
177  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
178  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
179  rSMAValue.RawSMAB = 0;
180  rNewRxBufferStrOut.clear();
181  std::string l_StrTemp;
182  try {
183  if (0 == rNewRxBufferStrIn.size())
184  throw CMFC3045InsException("Empty RX buffer.", MTL__LOCATION__);
185  rNewRxBufferStrOut = rNewRxBufferStrIn;
186 
187  // find "DR\r\n" data ready message
188  std::size_t l_Pos = rNewRxBufferStrOut.find(SMA_DR);
189  if (std::string::npos != l_Pos)
190  {
191  rSMAValue.SMAByte.DRST1 = 1;
192  rNewRxBufferStrOut.erase(l_Pos, 4);
193  }
194 
195  // find "PA\r\n" Probe Array not conected message
196  l_Pos = rNewRxBufferStrOut.find(SMA_PA);
197  if (std::string::npos != l_Pos)
198  {
199  rSMAValue.SMAByte.PANST2 = 1;
200  rNewRxBufferStrOut.erase(l_Pos, 4);
201  }
202 
203  // find "CE\r\n" Command Error message
204  l_Pos = rNewRxBufferStrOut.find(SMA_CE);
205  if (std::string::npos != l_Pos)
206  {
207  rSMAValue.SMAByte.CEST1 = 1;
208  rNewRxBufferStrOut.erase(l_Pos, 4);
209  }
210 
211  // find "RS\r\n" Serial communication error message
212  l_Pos = rNewRxBufferStrOut.find(SMA_RS);
213  if (std::string::npos != l_Pos)
214  {
215  rSMAValue.SMAByte.RSST1 = 1;
216  rNewRxBufferStrOut.erase(l_Pos, 4);
217  }
218 
219  // find "ME\r\n" Modulation error message
220  l_Pos = rNewRxBufferStrOut.find(SMA_ME);
221  if (std::string::npos != l_Pos)
222  {
223  rSMAValue.SMAByte.MEST1 = 1;
224  rNewRxBufferStrOut.erase(l_Pos, 4);
225  }
226 
227  // find "EE\r\n" Miscelaneous (EEPROM) error message
228  l_Pos = rNewRxBufferStrOut.find(SMA_EE);
229  if (std::string::npos != l_Pos)
230  {
231  rSMAValue.SMAByte.EEST1 = 1;
232  rNewRxBufferStrOut.erase(l_Pos, 4);
233  }
234 
235  // find "DN\r\n" Remote Box button pressed message
236  l_Pos = rNewRxBufferStrOut.find(SMA_DN);
237  if (std::string::npos != l_Pos)
238  {
239  rSMAValue.SMAByte.DNRB = 1;
240  rNewRxBufferStrOut.erase(l_Pos, 4);
241  }
242 
243  // find "UP\r\n" Remote Box button released message
244  l_Pos = rNewRxBufferStrOut.find(SMA_UP);
245  if (std::string::npos != l_Pos)
246  {
247  rSMAValue.SMAByte.UPRB = 1;
248  rNewRxBufferStrOut.erase(l_Pos, 4);
249  }
250 
251  }
252  catch (CMFC3045InsException & rE)
253  {
255  MTL_Unused(rE)
256  return false;
257  }
258  return true;
259 }
260 
261 // Write a string adding the termination char "\r\n"
262 bool CMFC3045Instrument::l_Write(const std::string & rWriteStr, const bool & rForceWrite)
263 {
264  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
265  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
266 
267  try
268  {
269  if(m_AbortSerialTransfert && !rForceWrite)
270  throw CMFC3045InsException("Abort serial command received.", MTL__LOCATION__);
271  // Write
272  std::string l_WriteStr;
273  l_WriteStr = rWriteStr + "\r\n"; // add termination char
274  MTL_SleepMs(50); // wait to let the MFC3045 to process any older Write command before to send any other one.
275  if (!CVISAInstrument::Write(reinterpret_cast<ViBuf>(const_cast<char *>(l_WriteStr.data())), static_cast<ViUInt32>(l_WriteStr.size())))
276  throw CMFC3045InsException("Could not write command " + l_WriteStr, MTL__LOCATION__);
277  }
278  catch (CMFC3045InsException & rE)
279  {
281  MTL_Unused(rE)
282  return false;
283  }
284  return true;
285 }
286 
287 // Read N strings (with Terrm Char "\r\n") in the Serial Input Buffer and concatenate them.
288 // Termination character is specified by SerialPortInit() (default should be "\n")
289 // Termination char is remove if it is "\r\n" or End of transmission Block (0x17)
290 bool CMFC3045Instrument::l_ReadString(std::string & rRxBufferStr, const U8 & rNStringAssembly, const bool & rCheckSmaMsg)
291 {
292  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
293  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
294 
295  try
296  {
297  U32 l_RxNewDataLength(0);
298  rRxBufferStr.clear();
299  std::string l_TempRdStrOut;
300  uSMAByte l_SMAMsg;
301  l_SMAMsg.RawSMAB =0;
302  U8 l_NbSmaMsg = 0;
303 
304  // Read received N strings with term char and concatenate them
305  for (size_t i = 0; i < rNStringAssembly + l_NbSmaMsg; i++)
306  {
307  if(!l_WaitAvailableDataRX(m_WaitTimeRdData_ms, l_RxNewDataLength)) // wait and check durring m_WaitTimeRdData_ms for new data available in Rx Buffer before to read it
308  throw CMFC3045InsException("Fail to read data length in RX buffer or buffer is empty. In ", MTL__LOCATION__);
309  m_ReadBuffer.clear();
310  if (!CVISAInstrument::Read(m_ReadBuffer,false))
311  {
312  ViStatus l_VisaStatus = Status();
313  if ((VI_ERROR_TMO == l_VisaStatus) &&
314  (1 <= m_ReadBuffer.size()) && (static_cast<char>(DATA_END_ETB) == m_ReadBuffer[m_ReadBuffer.size() - 1]))
315  {
316  m_ReadBuffer.resize(m_ReadBuffer.size() - 1); // receveid End of transmission block character
317  l_TempRdStrOut = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
318  break; // quit loop, but we do not consider it as an error!
319  }
320  else
321  throw CMFC3045InsException("Could not read", MTL__LOCATION__);
322  }
323  else
324  {
325  if(m_SMAEnabled || rCheckSmaMsg)
326  {
327  l_ExtractSmaMsgFromDataRX(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end()), l_SMAMsg, l_TempRdStrOut);
328  m_SMAValue.RawSMAB |= l_SMAMsg.RawSMAB;
329  if (l_SMAMsg.RawSMAB >0) // message received was an automatic sent message (SMA) from main unit
330  l_NbSmaMsg ++; // allow to do one more "for loop" to read the expected message (other than SMA message)
331  }
332  else
333  {
334  l_TempRdStrOut = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
335  }
336  if(0 != l_TempRdStrOut.size())
337  {
338  // Remove the term char "\r\n" or the end of transmission bloc char from the read string (cleaned from the SMA message if exists)
339  if (l_TempRdStrOut.size() >= 2 && l_TempRdStrOut[l_TempRdStrOut.size() - 2] == '\r' && l_TempRdStrOut[l_TempRdStrOut.size() - 1] == '\n')
340  l_TempRdStrOut.resize(l_TempRdStrOut.size() - 2);
341  else if (1 <= l_TempRdStrOut.size() && static_cast<char>(DATA_END_ETB) == l_TempRdStrOut[l_TempRdStrOut.size() - 1])
342  {
343  l_TempRdStrOut.resize(l_TempRdStrOut.size() - 1);
344  }
345  else
346  throw CMFC3045InsException("Read doesn't contain termination Chars", MTL__LOCATION__);
347  }
348  }
349  rRxBufferStr.append(l_TempRdStrOut); // concatenate received string messages
350  }
351  }
352  catch (CMFC3045InsException & rE)
353  {
355  MTL_Unused(rE)
356  return false;
357  }
358  return true;
359 }
360 
361 // Read serial input buffer of size N-char without any End of Char termination mode.
362 // This mode is used to read EEPROM content received after a specific EEPROM command (SMU, SPA, CPS, ...)
363 bool CMFC3045Instrument::l_ReadNCharNoTerm(CVISABuffer & rReadBuffer, const U16 & rReadNChar)
364 {
365  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
366  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
367 
368  try
369  {
370  // Change the Read Termination Mode to None for EEPROM reading
371  sSerialPortSettings l_SerialParmsNoTerm = m_HostSerialConfig;
372  l_SerialParmsNoTerm.ReadTermMode = eSerialTermMode::kEndNone;
373  l_SerialPortHostConfig(l_SerialParmsNoTerm); //Disable serial port termination.
374 
375  rReadBuffer.clear();
376  ViUInt32 l_RetLength(0);
377  ViUInt32 l_NbCharToRead = static_cast<ViUInt32>(rReadNChar) + 1; // add Last char "End of Transmission Block" to Char count
378  U32 l_RxNewDataLength(0);
379 
380  if (!l_WaitAvailableDataRX(m_WaitTimeRdData_ms, l_RxNewDataLength)) // wait and check durring m_WaitTimeRdData_ms for new data available in Rx Buffer before to read it
381  throw CMFC3045InsException("Fail to read data length in RX buffer, or buffer is empty. In ", MTL__LOCATION__);
382  if (!CVISAInstrument::Read(reinterpret_cast<ViPBuf>(rReadBuffer.data()), l_NbCharToRead, l_RetLength))
383  {
384  throw CMFC3045InsException("Fail to Read EEPROM in ", MTL__LOCATION__);
385  }
386  rReadBuffer.resize(l_RetLength);
387  if ((l_RetLength == l_NbCharToRead) && static_cast<char>(DATA_END_ETB) == rReadBuffer[l_RetLength - 1])
388  {
389  rReadBuffer.resize(l_RetLength - 1);//Remove last character "End of Transmission Block"
390  }
391  else
392  throw CMFC3045InsException("Fail to Read EEPROM. Wrong expected data size read, in ", MTL__LOCATION__);
393 
394  // Set back the read termination mode as it was (with end character) & clear serial Rx Tx buffers
395  l_SerialPortHostConfig(m_HostSerialConfig);
396  }
397  catch (CMFC3045InsException & rE)
398  {
400  MTL_Unused(rE)
401  l_SerialPortHostConfig(m_HostSerialConfig); // set back the read termination mode as it was (with end character)
402  return false;
403  }
404  return true;
405 }
406 
407 // Converts string date format dd/mm/yy (at UTC) to number representing the amount of seconds since 00:00:00, Jan 1 1970 UTC
408 bool CMFC3045Instrument::l_DateStrToDateTimeUtc(const std::string & rUtcDateStr, std::time_t & rUtcDateTime)
409 {
410  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
411 
412  try {
413  std::match_results<std::string::const_iterator> l_DateMatch;
414  // Match 3 groups of 2 digits seperated by "/" (String date format read is : dd/mm/yy)
415  if (!std::regex_match(rUtcDateStr, l_DateMatch, std::regex("^([0-9]{2})/([0-9]{2})/([0-9]{2})")))
416  throw CMFC3045InsException("Invalid date answer format", MTL__LOCATION__);
417 
418  std::stringstream l_DateStream;
419  std::chrono::system_clock::time_point l_TimePointUTC;
420  int l_TempDD, l_TempMM, l_TempYY;
421  l_TempDD = std::stoi(l_DateMatch[1]); //dd
422  l_TempMM = std::stoi(l_DateMatch[2]); //mm
423  l_TempYY = std::stoi(l_DateMatch[3]); //yy
424 
425  // if date not set yet
426  if (0 == l_TempDD || 0 == l_TempMM || 0 == l_TempYY)
427  rUtcDateTime = 0; // set 0 correpsonding to 1970/01/01
428  else
429  { //test if date format is valid
430  if(l_TempDD < 1 || l_TempDD > 31)
431  throw CMFC3045InsException("Invalid Day format", MTL__LOCATION__);
432 
433  if (l_TempMM < 0 || l_TempMM > 12)
434  throw CMFC3045InsException("Invalid Month format", MTL__LOCATION__);
435 
436  if (l_TempYY >= 80) // if above than 80 we consider the date to be between 1980 to 1999
437  {
438  l_DateStream << "19" + l_DateMatch[3].str() + "-" + l_DateMatch[2].str() + "-" + l_DateMatch[1].str() + " 00:00:00";
439  }
440  else // we consider to be in year 2000 to 2079
441  {
442  l_DateStream << "20" + l_DateMatch[3].str() + "-" + l_DateMatch[2].str() + "-" + l_DateMatch[1].str() + " 00:00:00";
443  }
444 
445  l_DateStream >> date::parse("%F %T", l_TimePointUTC); // parse string (UTC) date to time_point UTC
446  rUtcDateTime = std::chrono::system_clock::to_time_t(l_TimePointUTC); // convert to time_t (UTC)
447  }
448  }
449  catch (CMFC3045InsException & rE)
450  {
452  MTL_Unused(rE)
453  rUtcDateTime = -1;
454  return false;
455  }
456  return true;
457 }
458 
459 // Converts UTC date (number representing the amount of seconds since 00:00, Jan 1 1970 UTC) to a string date format ddmmyy (UTC)
460 // (as it must be when writing in CDP and CDU registers). Note: No "/" in string between day month year values when writing.
461 bool CMFC3045Instrument::l_DateTimeToDateStrUtc(const std::time_t & rUtcDateTime, std::string & rUtcDateStr)
462 {
463  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
464 
465  try {
466  auto l_TimePointUTC = std::chrono::system_clock::from_time_t(rUtcDateTime);
467  rUtcDateStr = date::format("%d%m%g", date::floor<std::chrono::seconds>(l_TimePointUTC)); // convert date UTC in ddmmy string format
468  }
469  catch (CMFC3045InsException & rE)
470  {
471  MTL_Unused(rE)
472  rUtcDateStr.clear();
473  return false;
474  }
475  return true;
476 }
477 
478 //------------------------------------------------------------------//
479 // Constructors / Destructors
480 //------------------------------------------------------------------//
482  : CVISAInstrument(rRM, Rsrc),
483  m_WaitTimeRdData_ms(RS_WAIT_DATARD_MS),
484  m_AbortSerialTransfert(false),
485  m_ReadBuffer(RS_RD_BUFF_DEFAULT_SIZE),
486  m_AdvancedMode(eAdvancedMode::kNone), // default value in MFC3045 after reset
487  m_DataBlockMode(eDataBlockMode::kOneByOne), // default value in MFC3045 after reset
488  m_NbProbesInPA(0),
489  m_SMAEnabled(false)
490 {
491 
492 }
493 
495 {
496  Abort();
498 }
499 
500 //------------------------------------------------------------------//
501 // Connect / Disconnect to Instrument with Serial Port (VISA)
502 //------------------------------------------------------------------//
503 // Check serial connection to instrument (Main Unit)
504 // Send a command to check MFC3045 main unit firmware version. Search "MFC" string in answer.
506 {
507  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
508  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
509 
510  try
511  {
512  std::string l_Answer;
513  bool l_TestOk(false);
514 
515  for (int i = 0; i < rNbRetry; i++)
516  {
517  if (!l_Write("VER"))
518  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
519  if (l_ReadString(l_Answer,1,true)) // try to read the version information. Answer must start with "MFC"
520  {
521  if (std::string::npos != l_Answer.find(MFC_ASCII))
522  {
523  l_TestOk = true;
524  break;
525  }
526  }
527  }
528  if (!l_TestOk)
529  throw CMFC3045InsException(std::string("No MFC3045 Connected on Serial Port"), MTL__LOCATION__);
530  }
531  catch (CMFC3045InsException & rE)
532  {
534  MTL_Unused(rE)
535  return false;
536  }
537  return true;
538 }
539 
540 // Connect to MFC3045 main unit instrument
541 // Open host serial port, check serial connection to MFC3045 main unit and
542 // configure some main unit registers (AdvancedMode to level 0 and DataBlockMode to Decimal)
543 bool CMFC3045Instrument::ConnectInstrument(const sSerialPortSettings & rSerialSettings, const U32 & rInitialTimeout_ms)
544 {
545  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
546  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
547 
548  try
549  {
550  // Open Host Serial Port and set Visa Timeout
551  if (!CVISAInstrument::Open(eOpenAccessMode::ExclusiveLock, rInitialTimeout_ms))
552  throw CMFC3045InsException("Fail to open VISA serial port", MTL__LOCATION__);
553  if (!CVISAInstrument::SetTimeout(rInitialTimeout_ms))
554  throw CMFC3045InsException("Fail to set VISA timeout", MTL__LOCATION__);
555  // Acquire VISA lock
556  if (!CVISAInstrument::LockExclusive(rInitialTimeout_ms))
557  throw CMFC3045InsException("Failed acquiring VISA lock", MTL__LOCATION__);
558  // Clear the VISA input and output serial buffer
559  if (!CVISAInstrument::Clear())
560  throw CMFC3045InsException("Fail to clear serial RX TX buffers", MTL__LOCATION__);
561 
562  // Configure (VISA) host serial port
563  m_HostSerialConfig = rSerialSettings; // store current serial configuration
564  m_HostSerialConfig.ReadTermMode = eSerialTermMode::kEndTermChar; // by default set end char mode to activ
565  m_HostSerialConfig.ReadTermChar = '\n'; // by default set end char to '\n'
566  if(!l_SerialPortHostConfig(m_HostSerialConfig))
567  throw CMFC3045InsException("Failed configure serial port, in ", MTL__LOCATION__);
568 
569  //Check instrument connection
570  m_WaitTimeRdData_ms = 2000; // for checking connection set x sec of waiting RX buffer to be field by any response.
571  if (!CheckInstrumentConnection(3)) // try 3 times to communicate and verify presence of MFC3045 main unit
572  throw CMFC3045InsException(std::string("No MFC3045 connected on serial port, in "), MTL__LOCATION__);
573 
574  m_WaitTimeRdData_ms = rInitialTimeout_ms; // for further use set wait time on RX buffer to receive data at the same value as VISA timeout
575 
576  U8 l_RegStat(0);
577  if(!StatusGet(eStatusRegister::kStatus3, l_RegStat)) // Read status register 3 doesn't clear bits
578  throw CMFC3045InsException(std::string("Fail to read Status 3, in"), MTL__LOCATION__);
579  if (l_RegStat > 1) //measurement may be in progress.
580  {
581  if (!BreakMeasSet())
582  throw CMFC3045InsException(std::string("Fail to send Break command, in "), MTL__LOCATION__);
583  }
584  // Configure instrument
585  if (!DisableSMA()) // Disable SMA (already default state in MFC3045) . We do not want to use it in normal case to avoid conflict during a read command
586  throw CMFC3045InsException(std::string("Fail to disable MFC3045 SMA, in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
587  if (!AdvancedCommandModeSet(eAdvancedMode::kNone)) // Set Advanced Command Mode register to 0 (kNone)
588  throw CMFC3045InsException(std::string("Fail to set MFC3045 Advanced Mode to 0, in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
589  if (!DataBlockModeDecimalSet()) // Set Data transfert block mode to "Decimal"
590  throw CMFC3045InsException(std::string("Fail to set MFC3045 Decimal Data Block Mode, in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
591  }
592  catch (CMFC3045InsException & rE)
593  {
595  MTL_Unused(rE)
596  // Try to release the VISA lock
598  // Try to close the VISA serial connection
600  return false;
601  }
602  return true;
603 }
604 
605 // Disconnect instrument => unlock and close (VISA) Serial Port from main Unit
607 {
608  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
609  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
610 
611  bool l_Success(true);
612  // Try to clear the VISA input and output serial buffer
614  // Try to release the VISA lock
616  l_Success = false;
617  // Try to close the VISA serial connection
619  return l_Success;
620 }
621 
622 //------------------------------------------------------------------------//
623 // Special public utilities
624 //------------------------------------------------------------------------//
625 // Abort any serial command and send a break acquisition to instrument.
627 {
628  bool AbortSucceded = true;
629  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
630  m_AbortSerialTransfert = true;
631  if(!BreakMeasSet()) // the only write cmd allowed.
632  AbortSucceded = false;
633  MTL_SleepMs(200);
634  m_AbortSerialTransfert = false;
635  return AbortSucceded;
636 }
637 
638 // Read a register with a custom command String (see MFC3045 Manual for correct command syntax).
639 // The read register must be only one single string. (termination \r\n is automatically removed)
640 bool CMFC3045Instrument::ReadWithCustomCmd(const std::string & rCommandStr, std::string & rRegValStr)
641 {
642  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
643  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
644 
645  try {
646  if (!l_Write(rCommandStr))
647  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
648  if (!l_ReadString(rRegValStr))
649  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
650  }
651  catch (CMFC3045InsException & rE)
652  {
654  MTL_Unused(rE)
655  return false;
656  }
657  return true;
658 }
659 
660 // Get maximum time in ms to wait before expecting new data in RX buffer to read
662 {
663  rRdDataTimeout_ms = m_WaitTimeRdData_ms;
664 }
665 
666 // Set maximum time in ms to wait before expecting new data in RX buffer to read
667 void CMFC3045Instrument::SetTimeoutRdNewDataMs(const U32 & rNewdataTimeout_ms)
668 {
669  m_WaitTimeRdData_ms = rNewdataTimeout_ms;
670 }
671 
672 //------------------------------------------------------------------//
673 // RS232 Settings
674 //------------------------------------------------------------------//
675 // Parse Serial RS232 Parmameters from a sSerialPortSettings to RSP register format
676 bool CMFC3045Instrument::ParseParmForRSP(const sSerialPortSettings & rSerialSettings, U16 & rParmRSPSettings)
677 {
678  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
679  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
680 
681  try {
682  uRSPByte l_Setting;
683  l_Setting.RawRSPB = 0;
684 
685  switch (rSerialSettings.DataBits) // Data bit (bit 0 of RSP)
686  {
687  case eSerialDataBits::k7:
688  l_Setting.RSPByte.PBL8 = 0;
689  break;
690  case eSerialDataBits::k8:
691  l_Setting.RSPByte.PBL8 = 1;
692  break;
693  default:
694  throw CMFC3045InsException(std::string("Fail to parse Data bit value in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
695  }
696 
697  switch (rSerialSettings.StopBits) //Stop bit (bit 1 of RSP). Value 1 or 2 only; 1.5 not supported
698  {
699  case eSerialStopBits::k1:
700  l_Setting.RSPByte.PSB2 = 0;
701  break;
702  case eSerialStopBits::k2:
703  l_Setting.RSPByte.PSB2 = 1;
704  break;
705  default:
706  throw CMFC3045InsException(std::string("Fail to parse Stop_bit value in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
707  }
708 
709  switch (rSerialSettings.Parity) // Parity (bit 2 and 3 of RSP). Only None, Odd, Even Parity supported.
710  {
712  l_Setting.RSPByte.PPAS = 0;
713  break;
715  l_Setting.RSPByte.PPAS = 1;
716  l_Setting.RSPByte.PPAE = 1;
717  break;
718  case eSerialParity::kOdd:
719  l_Setting.RSPByte.PPAS = 1;
720  l_Setting.RSPByte.PPAE = 0;
721  break;
722  default:
723  throw CMFC3045InsException(std::string("Fail to parse Parity value in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
724  }
725 
726  switch (rSerialSettings.Handshake) // Handshake (bit 4 and 5 of RSP)
727  {
729  l_Setting.RSPByte.PSHE = 0;
730  l_Setting.RSPByte.PHHE = 0;
731  break;
732  case eSerialHandshake::kXonXoff: // Software
733  l_Setting.RSPByte.PSHE = 1;
734  l_Setting.RSPByte.PHHE = 0;
735  break;
736  case eSerialHandshake::kHardware: //RTS/CTS
737  l_Setting.RSPByte.PSHE = 0;
738  l_Setting.RSPByte.PHHE = 1;
739  break;
740  case eSerialHandshake::kHardAndSoft: // RTS/CTS & Xon/Xoff
741  l_Setting.RSPByte.PSHE = 1;
742  l_Setting.RSPByte.PHHE = 1;
743  break;
744  default:
745  throw CMFC3045InsException(std::string("Fail to parse Handshake value in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
746  }
747 
748  switch (rSerialSettings.Baudrate) // Baud Rate (bit 8-10 of RSP)
749  {
751  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k2400);
752  break;
754  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k4800);
755  break;
757  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k9600);
758  break;
760  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k19200);
761  break;
763  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k28800);
764  break;
766  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k38400);
767  break;
769  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k57600);
770  break;
772  l_Setting.RSPByte.PRBR = static_cast<U8>(eMFCSerialBDR::k115200);
773  break;
774  default:
775  throw CMFC3045InsException(std::string("Fail to parse Baud Rate value in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
776  }
777  rParmRSPSettings = l_Setting.RawRSPB;
778  }
779  catch (CMFC3045InsException & rE)
780  {
782  MTL_Unused(rE)
783  return false;
784  }
785  return true;
786 }
787 
788 // Parse Serial RS232 Parmameters from RSP register to a sSerialPortSettings
789 bool CMFC3045Instrument::ParseParmFromRSP(const U16 & rParmRSPSettings, sSerialPortSettings & rSerialSettings)
790 {
791  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
792  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
793 
794  try {
795  uRSPByte l_ParmSetting;
796  sSerialPortSettings l_ParsedSetting;
797 
798  l_ParmSetting.RawRSPB = rParmRSPSettings;
799  l_ParsedSetting = rSerialSettings; // preserve COM Port number, End Term Char if already stored
800 
801  if (l_ParmSetting.RSPByte.PBL8) // Data bit (bit 0 of RSP)
802  l_ParsedSetting.DataBits = eSerialDataBits::k8;
803  else
804  l_ParsedSetting.DataBits = eSerialDataBits::k7;
805 
806  if (l_ParmSetting.RSPByte.PSB2) // Stop bit (bit 1 of RSP). Value 1 or 2 only; 1.5 not supported
807  l_ParsedSetting.StopBits = eSerialStopBits::k2; // 1 => 2 stop bit
808  else
809  l_ParsedSetting.StopBits = eSerialStopBits::k1; // 0 => 1 stop bit
810 
811  if (l_ParmSetting.RSPByte.PPAS) // Parity (bit 2 and 3 of RSP). Only None, Odd, Even Parity supported.
812  {
813  if (l_ParmSetting.RSPByte.PPAE)
814  l_ParsedSetting.Parity = eSerialParity::kEven;
815  else
816  l_ParsedSetting.Parity = eSerialParity::kOdd;
817  }
818  else
819  l_ParsedSetting.Parity = eSerialParity::kNone;
820 
821  if (l_ParmSetting.RSPByte.PSHE) // Handshake (bit 4 of RSP)
822  {
823  if (l_ParmSetting.RSPByte.PHHE)
824  l_ParsedSetting.Handshake = eSerialHandshake::kHardAndSoft;
825  else
826  l_ParsedSetting.Handshake = eSerialHandshake::kXonXoff;
827  }
828  else
829  {
830  if (l_ParmSetting.RSPByte.PHHE)
831  l_ParsedSetting.Handshake = eSerialHandshake::kHardware;
832  else
833  l_ParsedSetting.Handshake = eSerialHandshake::kNone;
834  }
835 
836  switch (static_cast<eMFCSerialBDR>(l_ParmSetting.RSPByte.PRBR)) // Baud Rate (bit 8-10 of RSP)
837  {
838  case eMFCSerialBDR::k2400:
839  l_ParsedSetting.Baudrate = eSerialBaudrate::k2400;
840  break;
841  case eMFCSerialBDR::k4800:
842  l_ParsedSetting.Baudrate = eSerialBaudrate::k4800;
843  break;
844  case eMFCSerialBDR::k9600:
845  l_ParsedSetting.Baudrate = eSerialBaudrate::k9600;
846  break;
847  case eMFCSerialBDR::k19200:
848  l_ParsedSetting.Baudrate = eSerialBaudrate::k19200;
849  break;
850  case eMFCSerialBDR::k28800:
851  l_ParsedSetting.Baudrate = eSerialBaudrate::k28800;
852  break;
853  case eMFCSerialBDR::k38400:
854  l_ParsedSetting.Baudrate = eSerialBaudrate::k38400;
855  break;
856  case eMFCSerialBDR::k57600:
857  l_ParsedSetting.Baudrate = eSerialBaudrate::k57600;
858  break;
859  case eMFCSerialBDR::k115200:
860  l_ParsedSetting.Baudrate = eSerialBaudrate::k115200;
861  break;
862  default:
863  throw CMFC3045InsException(std::string("Fail to parse Baud Rate value in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
864  }
865 
866  rSerialSettings = l_ParsedSetting;
867  }
868  catch (CMFC3045InsException & rE)
869  {
871  MTL_Unused(rE)
872  return false;
873  }
874  return true;
875 }
876 
877 // Write register RSP (RS 232 Parameters). Command {RSP,x}, with x = deciaml value (see manual)
878 // Set main unit RS232 communication settings. New RS232 settings are active only if saved in main unit EEPROM (use MainUnitEepromWrite() method),
879 // and after a main unit reset (use SystemResetSet() method).
880 bool CMFC3045Instrument::SerialRSPSet(const U16 & rRegVal)
881 {
882  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
883  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
884 
885  try {
886  std::string l_Command("RSP,");
887 
888  if (eAdvancedMode::k2 != m_AdvancedMode)
889  throw CMFC3045InsException(std::string("RSP Set not allowed. Advanced mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
890  if(rRegVal < RSP_MIN || rRegVal > RSP_MAX)
891  throw CMFC3045InsException(std::string("RSP Set not allowed. Value out of range. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
892  l_Command += std::to_string(rRegVal);
893  if (!l_Write(l_Command))
894  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
895  }
896  catch (CMFC3045InsException & rE)
897  {
899  MTL_Unused(rE)
900  return false;
901  }
902  return true;
903 }
904 
905 // Read register RSP (RS 232 Parameters). Command [RSP]
906 // Get main unit RS232 communication settings
908 {
909  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
910  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
911 
912  try {
913  std::string l_RdStr;
914  if (eAdvancedMode::kNone == m_AdvancedMode)
915  throw CMFC3045InsException(std::string("RSP Get not allowed. Advanced mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
916  if (!l_Write("RSP"))
917  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
918  if (!l_ReadString(l_RdStr, 2)) // read and concatenate 2 strings of 8 bit with therminal char \r\n
919  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
920  rRegVal = static_cast<U16>(std::stoul(l_RdStr,0,2));
921  }
922  catch (CMFC3045InsException & rE)
923  {
925  MTL_Unused(rE)
926  return false;
927  }
928  return true;
929 }
930 
931 //------------------------------------------------------------------//
932 // Miscellaneous Commands
933 //------------------------------------------------------------------//
934 // Write register ADV (ADVanced commands). Command ADV,x with x = 0 or 1 or 2
935 // Set advanced command mode level and update m_AdvancedMode attribute.
937 {
938  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
939  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
940 
941  try {
942  std::string l_Command("ADV,");
943 
944  l_Command += std::to_string(static_cast<U8>(rRegVal));
945 
946  if (!l_Write(l_Command))
947  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
948  m_AdvancedMode = rRegVal;
949  }
950  catch (CMFC3045InsException & rE)
951  {
952  m_AdvancedMode = eAdvancedMode::kNone;
954  MTL_Unused(rE)
955  return false;
956  }
957  return true;
958 }
959 
960 // Read register ADV (ADVanced commands). Command ADV
961 // Get advanced command mode level and update m_AdvancedMode attribute.
963 {
964  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
965  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
966 
967  try {
968  U32 l_AdvancedMode(255);
969  std::string l_RdStr;
970  if (!l_Write("ADV"))
971  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
972  if (!l_ReadString(l_RdStr))
973  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
974  l_AdvancedMode = static_cast<U32>(std::stoul(l_RdStr));
975  switch (l_AdvancedMode)
976  {
977  case static_cast<U32>(eAdvancedMode::kNone):
978  rRegVal = eAdvancedMode::kNone;
979  break;
980  case static_cast<U32>(eAdvancedMode::k1):
981  rRegVal = eAdvancedMode::k1;
982  break;
983  case static_cast<U32>(eAdvancedMode::k2):
984  rRegVal = eAdvancedMode::k2;
985  break;
986  default:
987  MTL_Assert("UnHandled value Type");
988  throw CMFC3045InsException(std::string("Failed: Get wrong value for ADV in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
989  break;
990  }
991  m_AdvancedMode = rRegVal; // store Advanced Mode result
992  }
993  catch (CMFC3045InsException & rE)
994  {
995  m_AdvancedMode = eAdvancedMode::kNone; // store as if it was the most restrictive one
997  MTL_Unused(rE)
998  return false;
999  }
1000  return true;
1001 }
1002 
1003 // Write register RST (ReSeT the system). Command RST
1004 // Reset the main unit
1006 {
1007  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1008  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1009 
1010  try {
1011  if (!l_Write("RST"))
1012  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1013  m_AdvancedMode = eAdvancedMode::kNone;
1014  m_DataBlockMode = eDataBlockMode::kOneByOne;
1015  l_ClearHostSerialBufferRxTx(); // try to clear RX TX buffers
1016  }
1017  catch (CMFC3045InsException & rE)
1018  {
1020  MTL_Unused(rE)
1021  return false;
1022  }
1023  return true;
1024 }
1025 
1026 // Read register VER (VERsion). Command VER
1027 // Get the main unit MFC3045 firmware version information
1028 bool CMFC3045Instrument::VersionGet(std::string & rVersionInfo, F32 & rFwVersion)
1029 {
1030  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1031  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1032 
1033  try {
1034  if (!l_Write("VER"))
1035  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1036  if (!l_ReadString(rVersionInfo))
1037  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1038 
1039  if (rVersionInfo.size() > 30)
1040  rFwVersion = static_cast<F32>(std::stof(std::string(rVersionInfo.end() - 4, rVersionInfo.end()).c_str()));
1041  else
1042  rFwVersion = 0.0;
1043 
1044  }
1045  catch (CMFC3045InsException & rE)
1046  {
1048  MTL_Unused(rE)
1049  return false;
1050  }
1051  return true;
1052 }
1053 
1054 // Read register VER (VERsion). Command VER,x with x= 0 or 1 or 2
1055 // Get MFC3045 firmware version (x=0), or Main unit EEPROM version (x=1), or Probe-Array version (x=2)
1056 bool CMFC3045Instrument::VersionGet(std::string & rVersionInfo, F32 & rFwVersion, const eWhoVersion & rSelect)
1057 {
1058  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1059  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1060 
1061  try {
1062  std::string l_Command("VER,");
1063 
1064  l_Command += std::to_string(static_cast<U8>(rSelect));
1065 
1066  if (!l_Write(l_Command))
1067  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1068  if (!l_ReadString(rVersionInfo))
1069  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1070 
1071  // Parse version number
1072  rFwVersion = 0.0;
1073  switch (rSelect)
1074  {
1075  case eWhoVersion::kMUFirmVer:
1076  if (rVersionInfo.size() > 30)
1077  rFwVersion = static_cast<F32>(std::stof(std::string(rVersionInfo.end() - 4, rVersionInfo.end()).c_str()));
1078  break;
1079  case eWhoVersion::kMUEepromVer:
1080  case eWhoVersion::kPAEepromVer:
1081  if (rVersionInfo.size() > 0)
1082  rFwVersion = static_cast<F32>(std::stof(rVersionInfo));
1083  break;
1084  default:
1085  MTL_Assert(false);
1086  break;
1087  }
1088  }
1089  catch (CMFC3045InsException & rE)
1090  {
1092  MTL_Unused(rE)
1093  return false;
1094  }
1095  return true;
1096 }
1097 
1098 // Read register S/N (Serial Number). Command S/N
1099 // Get the main unit serial number
1100 bool CMFC3045Instrument::SerialNumberGet(std::string & rSerialNum)
1101 {
1102  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1103  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1104 
1105  try {
1106  if (!l_Write("S/N"))
1107  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1108  if (!l_ReadString(rSerialNum))
1109  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1110  }
1111  catch (CMFC3045InsException & rE)
1112  {
1114  MTL_Unused(rE)
1115  return false;
1116  }
1117  return true;
1118 }
1119 
1120 // Read register S/N (Serial Number). Command S/N,x with x = 0 or 1 or 2
1121 // Get serial number of main unit (x=0,1) or probe-array (x=2)
1122 bool CMFC3045Instrument::SerialNumberGet(std::string & rSerialNum, const eWhoSerialNum & rSelect)
1123 {
1124  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1125  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1126 
1127  try {
1128  std::string l_Command("S/N,");
1129 
1130  l_Command += std::to_string(static_cast<U8>(rSelect));
1131 
1132  if (!l_Write(l_Command))
1133  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1134  if (!l_ReadString(rSerialNum))
1135  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1136  }
1137  catch (CMFC3045InsException & rE)
1138  {
1140  MTL_Unused(rE)
1141  return false;
1142  }
1143  return true;
1144 }
1145 
1146 // Write register LED (Remote box busy led). Command LED,x with x = 0 to 5 (see manual)
1147 // Set the state of the remote box busy led.
1149 {
1150  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1151  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1152 
1153  try {
1154  std::string l_Command("LED,");
1155 
1156  l_Command += std::to_string(static_cast<U8>(rRemoteLed));
1157 
1158  if (!l_Write(l_Command))
1159  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1160  }
1161  catch (CMFC3045InsException & rE)
1162  {
1164  MTL_Unused(rE)
1165  return false;
1166  }
1167  return true;
1168 }
1169 
1170 // Read register LED (Remote box busy led). Command LED
1171 // Get the state of the remote box busy led
1173 {
1174  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1175  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1176 
1177  try {
1178  U8 l_RemoteLed(255);
1179  std::string l_RdStr;
1180  if (!l_Write("LED"))
1181  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1182  if (!l_ReadString(l_RdStr))
1183  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1184  l_RemoteLed = static_cast<U8>(std::stoul(l_RdStr));
1185  switch (l_RemoteLed)
1186  {
1187  case static_cast<U8>(eRemoteBusyLed::kRemoteLedOff):
1188  rRemoteLed = eRemoteBusyLed::kRemoteLedOff;
1189  break;
1190  case static_cast<U8>(eRemoteBusyLed::kRemoteLedMeasuring):
1191  rRemoteLed = eRemoteBusyLed::kRemoteLedMeasuring;
1192  break;
1193  case static_cast<U8>(eRemoteBusyLed::kRemoteLedOffEndMeas):
1194  rRemoteLed = eRemoteBusyLed::kRemoteLedOffEndMeas;
1195  break;
1196  case static_cast<U8>(eRemoteBusyLed::kRemoteLedOn):
1197  rRemoteLed = eRemoteBusyLed::kRemoteLedOn;
1198  break;
1199  case static_cast<U8>(eRemoteBusyLed::kRemoteLedBlinkSlow):
1200  rRemoteLed = eRemoteBusyLed::kRemoteLedBlinkSlow;
1201  break;
1202  case static_cast<U8>(eRemoteBusyLed::kRemoteLedBlinkFast):
1203  rRemoteLed = eRemoteBusyLed::kRemoteLedBlinkFast;
1204  break;
1205  default:
1206  MTL_Assert("UnHandled value Type");
1207  throw CMFC3045InsException(std::string("Failed: Get wrong value for LED in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1208  break;
1209  }
1210  }
1211  catch (CMFC3045InsException & rE)
1212  {
1214  MTL_Unused(rE)
1215  return false;
1216  }
1217  return true;
1218 }
1219 
1220 // Write register DFF (Dds Fixed Frequency). Command [DFF,x] with x = decimal value in dHz
1221 // Set DDS fixed frequency value (dHz) for the un-modulated RF signal output.
1222 // A command DFF,0 or BRK stops the DDS frequecncy RF output
1223 bool CMFC3045Instrument::DdsFrequencySet(const U32 & rRegVal)
1224 {
1225  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1226  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1227 
1228  try {
1229  std::string l_Command("DFF,");
1230 
1231  if (eAdvancedMode::kNone == m_AdvancedMode)
1232  throw CMFC3045InsException(std::string("DFF Set not allowed. Advanced mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1233  if (rRegVal > FSW_DFF_MAX)
1234  throw CMFC3045InsException(std::string("Failed, DDS Fix Freq out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1235  else
1236  l_Command += std::to_string(rRegVal);
1237  if (!l_Write(l_Command))
1238  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1239  }
1240  catch (CMFC3045InsException & rE)
1241  {
1243  MTL_Unused(rE)
1244  return false;
1245  }
1246  return true;
1247 }
1248 
1249 // Read register DFF (Dds Fixed Frequency). Command [DFF]
1250 // Get the DDS fixed frequency unmodulated RF signal output in dHz
1252 {
1253  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1254  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1255 
1256  try {
1257  std::string l_RdStr;
1258 
1259  if (eAdvancedMode::kNone == m_AdvancedMode)
1260  throw CMFC3045InsException(std::string("DFF Set not allowed. Advanced mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1261 
1262  if (!l_Write("DFF"))
1263  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1264  if (!l_ReadString(l_RdStr))
1265  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1266  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1267  }
1268  catch (CMFC3045InsException & rE)
1269  {
1271  MTL_Unused(rE)
1272  return false;
1273  }
1274  return true;
1275 }
1276 
1277 // Write register FSW (Frequency Sweep). Command [FSW,x] with x = -1,0,1 or decimal value in dHz >1
1278 // Set the modulated central frequency sweep shift value (see manual)
1279 // The attribute rFreqStepVal is the frequency step value in dHz to set if mode eSweepFreqMode::kSetValue is choosed, otherwise it's not used.
1280 bool CMFC3045Instrument::FrequencySweepSet(const eSweepFreqMode & rSweepMode, const U32 & rFreqStepVal)
1281 {
1282  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1283  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1284 
1285  try {
1286  std::string l_Command("FSW,");
1287 
1288  if (eAdvancedMode::kNone == m_AdvancedMode)
1289  throw CMFC3045InsException(std::string("FSW Set not allowed. Advanced mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1290 
1291  switch (rSweepMode)
1292  {
1293  case eSweepFreqMode::kdisable:
1294  l_Command += "0";
1295  break;
1296  case eSweepFreqMode::k20Step:
1297  l_Command += "1";
1298  break;
1299  case eSweepFreqMode::kPaRange:
1300  l_Command += "-1";
1301  break;
1302  case eSweepFreqMode::kSetValue:
1303  if (rFreqStepVal < 2 || rFreqStepVal > FSW_DFF_MAX)
1304  throw CMFC3045InsException(std::string("Failed, FreqSweep out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1305  else
1306  l_Command += std::to_string(rFreqStepVal);
1307  break;
1308  default:
1309  MTL_Assert(false);
1310  break;
1311  }
1312  if (!l_Write(l_Command))
1313  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1314  }
1315  catch (CMFC3045InsException & rE)
1316  {
1318  MTL_Unused(rE)
1319  return false;
1320  }
1321  return true;
1322 }
1323 
1324 // Shift the modulated central frequency up or down after a command FSW,x
1326 {
1327  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1328  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1329 
1330  try {
1331  std::string l_Command;
1332  l_Command += std::to_string(static_cast<U8>(rShiftDirection));
1333  if (!l_Write(l_Command))
1334  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1335  }
1336  catch (CMFC3045InsException & rE)
1337  {
1339  MTL_Unused(rE)
1340  return false;
1341  }
1342  return true;
1343 }
1344 
1345 //----------------------------------------------------------------------//
1346 // Status Handling
1347 //----------------------------------------------------------------------//
1348 // Read register ST1 to ST6 (Status). Command ST1 ST2 to ST6
1349 // Get one Status Register
1350 bool CMFC3045Instrument::StatusGet(const eStatusRegister & rStatRegSel, U8 & rStatus)
1351 {
1352  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1353  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1354 
1355  std::string l_Command;
1356 
1357  // Prepare status register command
1358  switch (rStatRegSel)
1359  {
1360  case eStatusRegister::kStatus1:
1361  l_Command += "ST1"; // Note: Status Bits are cleared after reading
1362  break;
1363  case eStatusRegister::kStatus2:
1364  l_Command += "ST2"; // Note: Status Bits are cleared after reading
1365  break;
1366  case eStatusRegister::kStatus3:
1367  l_Command += "ST3";
1368  break;
1369  case eStatusRegister::kStatus4:
1370  l_Command += "ST4"; // Note: Status Bits 2,4,7 are cleared after reading
1371  break;
1372  case eStatusRegister::kStatus5:
1373  l_Command += "ST5"; // Note: Status Bits 3 to 7 are cleared after reading
1374  break;
1375  case eStatusRegister::kStatus6:
1376  l_Command += "ST6";
1377  break;
1378  default:
1379  MTL_Assert(false);
1380  break;
1381  }
1382  try {
1383  //Write cmd
1384  if (!l_Write(l_Command))
1385  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1386  //Reads Status register
1387  std::string l_RdStr;
1388  if (!l_ReadString(l_RdStr))
1389  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1390  rStatus = static_cast<U8>(std::stoul(l_RdStr, nullptr, 2)); //String Binary results convert to decimal
1391  } // try
1392  catch (CMFC3045InsException & rE)
1393  {
1395  MTL_Unused(rE)
1396  rStatus = 0;
1397  return false;
1398  }
1399  return true;
1400 }
1401 
1402 // Read register ST1 to ST6 (Status). Command ST1;ST2; to ST6
1403 // Get several Status Registers
1404 bool CMFC3045Instrument::StatusGet(const std::vector<eStatusRegister> & rStatRegSel, std::vector<U8> & rStatus)
1405 {
1406  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1407  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1408 
1409  rStatus.clear();
1410  std::string l_Command;
1411 
1412  for (std::vector<eStatusRegister>::const_iterator it = rStatRegSel.begin(); it != rStatRegSel.end(); it++)
1413  {
1414  if (it != rStatRegSel.begin())
1415  l_Command += ";";
1416  switch (*it)
1417  {
1418  case eStatusRegister::kStatus1:
1419  l_Command += "ST1";
1420  break;
1421  case eStatusRegister::kStatus2:
1422  l_Command += "ST2";
1423  break;
1424  case eStatusRegister::kStatus3:
1425  l_Command += "ST3";
1426  break;
1427  case eStatusRegister::kStatus4:
1428  l_Command += "ST4";
1429  break;
1430  case eStatusRegister::kStatus5:
1431  l_Command += "ST5";
1432  break;
1433  case eStatusRegister::kStatus6:
1434  l_Command += "ST6";
1435  break;
1436  default:
1437  MTL_Assert(false);
1438  break;
1439  }
1440  }
1441  try {
1442  if (!l_Write(l_Command))
1443  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1444 
1445  //Reads N Status register
1446  std::string l_RdStr;
1447  for (size_t i = rStatRegSel.size(); i > 0; i--)
1448  {
1449  if(!l_ReadString(l_RdStr))
1450  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1451  rStatus.push_back(static_cast<U8>(std::stoul(l_RdStr, nullptr, 2))); //String Binary results convert to decimal
1452  }
1453  } // try
1454  catch (CMFC3045InsException & rE)
1455  {
1457  MTL_Unused(rE)
1458  return false;
1459  }
1460  return true;
1461 }
1462 
1463 // Read register ERR (ERRor). Command ERR
1464 // Get 3 first caracters acccording to the Last Command Error (see also bit 1 of Status1)
1465 bool CMFC3045Instrument::LastCmdErrorGet(std::string & rCmdError)
1466 {
1467  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1468  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1469 
1470  try {
1471  if (!l_Write("ERR"))
1472  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1473  if (!l_ReadString(rCmdError))
1474  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1475  }
1476  catch (CMFC3045InsException & rE)
1477  {
1479  MTL_Unused(rE)
1480  return false;
1481  }
1482  return true;
1483 }
1484 
1485 // Read register SMA (Send Message Automatically). Command SMA
1486 // Get SMA register state
1487 bool CMFC3045Instrument::SMAGet(U8 & rRegVal)
1488 {
1489  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1490  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1491 
1492  try {
1493  std::string l_RdStr;
1494  if (!l_Write("SMA"))
1495  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1496  if (!l_ReadString(l_RdStr))
1497  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1498  rRegVal = static_cast<U8>(std::stoul(l_RdStr, nullptr, 2)); //String Binary results convert to decimal
1499  if(rRegVal)
1500  m_SMAEnabled = 1;
1501  else
1502  m_SMAEnabled = 0;
1503  }
1504  catch (CMFC3045InsException & rE)
1505  {
1507  MTL_Unused(rE)
1508  return false;
1509  }
1510  return true;
1511 }
1512 
1513 // Disable SMA (Send Message Automatically) mode
1515 {
1516  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1517  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1518 
1519  try {
1520  U32 l_RxNewDataLength(0);
1521  U32 l_NbSmaMsg(0);
1522  uSMAByte l_SMARegValRead;
1523  l_SMARegValRead.RawSMAB = 0;
1524  if (!l_SMASet(0))
1525  throw CMFC3045InsException(std::string("Fail to disable SMA in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1526  if(l_WaitAvailableDataRX(200, l_RxNewDataLength, false)) // wait and check for new data available in Rx Buffer before to read it
1527  {
1528  if (l_RxNewDataLength >= 4)
1529  l_NbSmaMsg = l_RxNewDataLength / 4; // size per SMA message (= 2 ascii char + 2 term char)
1530  for(size_t l_i = 0; l_i < l_NbSmaMsg ; l_i++)// purge any SMA message
1531  {
1532  m_ReadBuffer.clear();
1533  CVISAInstrument::Read(m_ReadBuffer,false); // read any other SMA message received before SMA has been really disabled.
1534  }
1535  }
1536  if (!SMAGet(l_SMARegValRead.RawSMAB))
1537  throw CMFC3045InsException(std::string("Fail to read back SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1538  if(0 != l_SMARegValRead.RawSMAB)
1539  throw CMFC3045InsException(std::string("Fail, SMA is not disabled") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1540  m_SMAEnabled = 0; //SMA is disabled
1541  m_SMAValue.RawSMAB = 0; // clear any previous SMA message received
1542  }
1543  catch (CMFC3045InsException & rE)
1544  {
1546  MTL_Unused(rE)
1547  return false;
1548  }
1549  return true;
1550 }
1551 
1552 // Set SMA (Send Message Automatically) mode
1553 bool CMFC3045Instrument::l_SMASet(const U8 & rRegVal)
1554 {
1555  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1556  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1557 
1558  try {
1559  std::string l_Command("SMA,");
1560  l_Command += std::to_string(rRegVal);
1561  if (!l_Write(l_Command))
1562  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1563  if(rRegVal)
1564  m_SMAEnabled = 1;
1565  else
1566  m_SMAEnabled = 0;
1567  }
1568  catch (CMFC3045InsException & rE)
1569  {
1571  MTL_Unused(rE)
1572  return false;
1573  }
1574  return true;
1575 }
1576 
1577 //----------------------------------------------------------------------//
1578 // Modulation Parameters //
1579 //----------------------------------------------------------------------//
1580 // Write register MDA (Modulation Amplitude). Command MDA,x with x = value in ppm
1581 // Set the total amplitude peak peak value of freaquency modulation in ppm (referenced to PCF register : PA central freq)
1583 {
1584  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1585  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1586 
1587  try {
1588  std::string l_Command("MDA,");
1589  if ((rRegVal < MDA_MIN) || (rRegVal > MDA_MAX))
1590  throw CMFC3045InsException(std::string("Failed, MDA out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1591  else
1592  l_Command += std::to_string(rRegVal);
1593  if (!l_Write(l_Command))
1594  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1595  }
1596  catch (CMFC3045InsException & rE)
1597  {
1599  MTL_Unused(rE)
1600  return false;
1601  }
1602  return true;
1603 }
1604 
1605 // Read register MDA (Modulation Amplitude). Command MDA
1606 // Get the total amplitude peak peak value of freaquency modulation in ppm (referenced to PCF register : PA central freq and not MCF!)
1608 {
1609  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1610  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1611 
1612  try {
1613  std::string l_RdStr;
1614  if (!l_Write("MDA"))
1615  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1616  if (!l_ReadString(l_RdStr))
1617  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1618  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1619  }
1620  catch (CMFC3045InsException & rE)
1621  {
1623  MTL_Unused(rE)
1624  return false;
1625  }
1626  return true;
1627 }
1628 
1629 // Write register MCF (Modulation Central Frequency). Command MCF,x with x = value in dHz
1630 // Set the central frequency of modulation signal in dHz
1632 {
1633  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1634  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1635 
1636  try {
1637  std::string l_Command("MCF,");
1638  if ((rRegVal < MOD_FREQ_MIN_DHZ) || (rRegVal > MOD_FREQ_MAX_DHZ))
1639  throw CMFC3045InsException(std::string("Failed, MCF out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1640  else
1641  l_Command += std::to_string(rRegVal);
1642  if (!l_Write(l_Command))
1643  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1644  }
1645  catch (CMFC3045InsException & rE)
1646  {
1648  MTL_Unused(rE)
1649  return false;
1650  }
1651  return true;
1652 }
1653 
1654 // Read register MCF (Modulation Central Frequency). Command MCF
1655 // Get the central frequency of modulation signal in dHz
1657 {
1658  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1659  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1660 
1661  try {
1662  std::string l_RdStr;
1663  if (!l_Write("MCF"))
1664  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1665  if (!l_ReadString(l_RdStr))
1666  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1667  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1668  }
1669  catch (CMFC3045InsException & rE)
1670  {
1672  MTL_Unused(rE)
1673  return false;
1674  }
1675  return true;
1676 }
1677 
1678 // Write register MLF (Modulation Lowest Frequency). Command MLF,x with x = value in dHz
1679 // Set the lowest (bottom plateau) frequency of modulation signal in dHz
1681 {
1682  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1683  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1684 
1685  try {
1686  std::string l_Command("MLF,");
1687  if ((rRegVal < MOD_FREQ_MIN_DHZ) || (rRegVal > MOD_FREQ_MAX_DHZ))
1688  throw CMFC3045InsException(std::string("Failed, MLF out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1689  else
1690  l_Command += std::to_string(rRegVal);
1691  if (!l_Write(l_Command))
1692  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1693  }
1694  catch (CMFC3045InsException & rE)
1695  {
1697  MTL_Unused(rE)
1698  return false;
1699  }
1700  return true;
1701 }
1702 
1703 // Read register MLF (Modulation Lowest Frequency). Command MLF
1704 // Get the lowest (bottom plateau) frequency of modulation signal in dHz
1706 {
1707  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1708  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1709 
1710  try {
1711  std::string l_RdStr;
1712  if (!l_Write("MLF"))
1713  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1714  if (!l_ReadString(l_RdStr))
1715  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1716  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1717  }
1718  catch (CMFC3045InsException & rE)
1719  {
1721  MTL_Unused(rE)
1722  return false;
1723  }
1724  return true;
1725 }
1726 
1727 
1728 // Write register MHF (Modulation Highest Frequency). Command MHF,x with x = value in dHz
1729 // Set the highest (top plateau) frequency of modulation signal in dHz
1731 {
1732  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1733  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1734 
1735  try {
1736  std::string l_Command("MHF,");
1737  if ((rRegVal < MOD_FREQ_MIN_DHZ) || (rRegVal > MOD_FREQ_MAX_DHZ))
1738  throw CMFC3045InsException(std::string("Failed, MHF out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1739  else
1740  l_Command += std::to_string(rRegVal);
1741  if (!l_Write(l_Command))
1742  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1743  }
1744  catch (CMFC3045InsException & rE)
1745  {
1747  MTL_Unused(rE)
1748  return false;
1749  }
1750  return true;
1751 }
1752 
1753 // Read register MHF (Modulation Highest Frequency). Command MHF
1754 // Get the highest (top plateau) frequency of modulation signal in dHz
1756 {
1757  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1758  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1759 
1760  try {
1761  std::string l_RdStr;
1762  if (!l_Write("MHF"))
1763  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1764  if (!l_ReadString(l_RdStr))
1765  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1766  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1767  }
1768  catch (CMFC3045InsException & rE)
1769  {
1771  MTL_Unused(rE)
1772  return false;
1773  }
1774  return true;
1775 }
1776 
1777 // Write register MRE (Modulation Referenced frequency). Command MRE,x with x = 0 to 3 (see manual)
1778 // Set which modulation frequency (MDA, MCF, MLF, MHF) is used as a reference
1780 {
1781  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1782  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1783 
1784  try {
1785  std::string l_Command("MRE,");
1786 
1787  l_Command += std::to_string(static_cast<U8>(rRegVal));
1788 
1789  if (!l_Write(l_Command))
1790  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1791  }
1792  catch (CMFC3045InsException & rE)
1793  {
1795  MTL_Unused(rE)
1796  return false;
1797  }
1798  return true;
1799 }
1800 
1801 // Read register MRE (Modulation Highest Frequency). Command MRE
1802 // Get the modulation reference
1804 {
1805  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1806  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1807 
1808  try {
1809  U32 l_Modulation(255);
1810  std::string l_RdStr;
1811  if (!l_Write("MRE"))
1812  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1813  if (!l_ReadString(l_RdStr))
1814  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1815  l_Modulation = static_cast<U32>(std::stoul(l_RdStr));
1816  switch (l_Modulation)
1817  {
1818  case static_cast<U32>(eModulationRef::kMDA):
1819  rRegVal = eModulationRef::kMDA;
1820  break;
1821  case static_cast<U32>(eModulationRef::kMCF):
1822  rRegVal = eModulationRef::kMCF;
1823  break;
1824  case static_cast<U32>(eModulationRef::kMLF):
1825  rRegVal = eModulationRef::kMLF;
1826  break;
1827  case static_cast<U32>(eModulationRef::kMHF):
1828  rRegVal = eModulationRef::kMHF;
1829  break;
1830  default:
1831  MTL_Assert(false);
1832  break;
1833  }
1834  }
1835  catch (CMFC3045InsException & rE)
1836  {
1838  MTL_Unused(rE)
1839  return false;
1840  }
1841  return true;
1842 }
1843 
1844 // Write register MDP (Modulation Period). Command [MDP,x] with x = value in ms
1845 // Set the period of frequency modulation cycle in ms
1847 {
1848  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1849  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1850 
1851  try {
1852  std::string l_Command("MDP,");
1853 
1854  if (eAdvancedMode::kNone == m_AdvancedMode)
1855  throw CMFC3045InsException(std::string("MDP Set not allowed. Advanced mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1856  if (rRegVal < 1)
1857  throw CMFC3045InsException(std::string("Failed, MDP out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1858  else
1859  l_Command += std::to_string(rRegVal);
1860  if (!l_Write(l_Command))
1861  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1862  }
1863  catch (CMFC3045InsException & rE)
1864  {
1866  MTL_Unused(rE)
1867  return false;
1868  }
1869  return true;
1870 }
1871 
1872 // Read register MDP (Modulation Period). Command MDP
1873 // Get the period of frequency modulation cycle in ms
1875 {
1876  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1877  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1878 
1879  try {
1880  std::string l_RdStr;
1881  if (!l_Write("MDP"))
1882  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1883  if (!l_ReadString(l_RdStr))
1884  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1885  rRegVal = static_cast<U16>(std::stoul(l_RdStr));
1886  }
1887  catch (CMFC3045InsException & rE)
1888  {
1890  MTL_Unused(rE)
1891  return false;
1892  }
1893  return true;
1894 }
1895 
1896 // Read register NSR (Number of Steps Ramp). Command [NSR]
1897 // Get the number of steps for ramp modulation
1899 {
1900  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1901  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1902 
1903  try {
1904  std::string l_RdStr;
1905  if (eAdvancedMode::kNone == m_AdvancedMode)
1906  throw CMFC3045InsException(std::string("NSR get not allowed. Advanced mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1907  if (!l_Write("NSR"))
1908  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1909  if (!l_ReadString(l_RdStr))
1910  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1911  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1912  }
1913  catch (CMFC3045InsException & rE)
1914  {
1916  MTL_Unused(rE)
1917  return false;
1918  }
1919  return true;
1920 }
1921 
1922 // Read register NSP (Number of Steps Plateau). Command [NSP]
1923 // Get the number of steps for plateau modulation
1925 {
1926  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1927  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1928 
1929  try {
1930  std::string l_RdStr;
1931  if (eAdvancedMode::kNone == m_AdvancedMode)
1932  throw CMFC3045InsException(std::string("NSP get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1933  if (!l_Write("NSP"))
1934  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1935  if (!l_ReadString(l_RdStr))
1936  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1937  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1938  }
1939  catch (CMFC3045InsException & rE)
1940  {
1942  MTL_Unused(rE)
1943  return false;
1944  }
1945  return true;
1946 }
1947 
1948 // Read register DBR (DDS Bit Resolution of Steps Plateau). Command [DBR]
1949 // Get the register value to calculate the resolution of the RF steps during ramping up and down. (see manual)
1951 {
1952  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1953  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1954 
1955  try {
1956  std::string l_RdStr;
1957  if (eAdvancedMode::kNone == m_AdvancedMode)
1958  throw CMFC3045InsException(std::string("DBR get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1959  if (!l_Write("DBR"))
1960  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1961  if (!l_ReadString(l_RdStr))
1962  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1963  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
1964  }
1965  catch (CMFC3045InsException & rE)
1966  {
1968  MTL_Unused(rE)
1969  return false;
1970  }
1971  return true;
1972 }
1973 
1974 // Read register DBR (DDS Bit Resolution of Steps Plateau). Command [DBR]
1975 // Get the DDS resolution in dHZ with the given formula: 0.256*(DBR+1)*RFH
1976 // DBR is DDS Bit Resolution register and RFH is the RF Harmonic Register
1977 bool CMFC3045Instrument::DdsBitResolutionFdhzGet(F32 & rDdsResolutionFdhz)
1978 {
1979  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
1980  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
1981 
1982  try {
1983  U32 l_DdsResolution;
1984  eRFH l_RfHarmonic;
1985 
1986  if (!DdsBitResolutionGet(l_DdsResolution))
1987  throw CMFC3045InsException(std::string("Fail to read DBR register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1988  if (!RfHarmonicGet(l_RfHarmonic))
1989  throw CMFC3045InsException(std::string("Fail to read DBR register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
1990  rDdsResolutionFdhz = 0.256f*(static_cast<F32>(l_DdsResolution) + 1.0f)*(static_cast<F32>(l_RfHarmonic));
1991  }
1992  catch (CMFC3045InsException & rE)
1993  {
1995  MTL_Unused(rE)
1996  return false;
1997  }
1998  return true;
1999 }
2000 
2001 //----------------------------------------------------------------------//
2002 // Measurement Parameters //
2003 //----------------------------------------------------------------------//
2004 // Write register NCY (Number of Measurement Cycles). Command NCY,x with x = decimal value (see manual)
2005 // Set the number of measurement (or modulation) cycles
2007 {
2008  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2009  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2010 
2011  try {
2012  std::string l_Command("NCY,");
2013 
2014  if ((rRegVal < NCY_MIN) || (rRegVal > NCY_MAX))
2015  throw CMFC3045InsException(std::string("Failed, NCY out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2016  else
2017  l_Command += std::to_string(rRegVal);
2018  if (!l_Write(l_Command))
2019  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2020  }
2021  catch (CMFC3045InsException & rE)
2022  {
2024  MTL_Unused(rE)
2025  return false;
2026  }
2027  return true;
2028 }
2029 
2030 // Read register NCY (Number of Measurement Cycles). Command NCY
2031 // Get the number of measurement (or modulation) cycles
2033 {
2034  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2035  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2036 
2037  try {
2038  std::string l_RdStr;
2039  if (!l_Write("NCY"))
2040  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2041  if (!l_ReadString(l_RdStr))
2042  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2043  rRegVal = static_cast<U16>(std::stoul(l_RdStr));
2044  }
2045  catch (CMFC3045InsException & rE)
2046  {
2048  MTL_Unused(rE)
2049  return false;
2050  }
2051  return true;
2052 }
2053 
2054 // Write register NPC (Number of Preliminary Cycles). Command {NPC,x} with x = decimal value (see manual)
2055 // Set the number of dummy preliminary cycle before any measurement
2056 bool CMFC3045Instrument::NumberPreCycleSet(const U16 & rRegVal)
2057 {
2058  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2059  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2060 
2061  try {
2062  std::string l_Command("NPC,");
2063 
2064  if (eAdvancedMode::k2 != m_AdvancedMode)
2065  throw CMFC3045InsException(std::string("NPC Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2066  if (rRegVal > NPC_MAX)
2067  throw CMFC3045InsException(std::string("Failed, NPC out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2068  else
2069  l_Command += std::to_string(rRegVal);
2070  if (!l_Write(l_Command))
2071  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2072  }
2073  catch (CMFC3045InsException & rE)
2074  {
2076  MTL_Unused(rE)
2077  return false;
2078  }
2079  return true;
2080 }
2081 
2082 // Read register NPC (Number of Preliminary Cycles). Command [NPC]
2083 // Get the number of dummy preliminary cycle before any measurement
2085 {
2086  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2087  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2088 
2089  try {
2090  std::string l_RdStr;
2091  if (eAdvancedMode::kNone == m_AdvancedMode)
2092  throw CMFC3045InsException(std::string("NPC Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2093  if (!l_Write("NPC"))
2094  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2095  if (!l_ReadString(l_RdStr))
2096  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2097  rRegVal = static_cast<U16>(std::stoul(l_RdStr));
2098  }
2099  catch (CMFC3045InsException & rE)
2100  {
2102  MTL_Unused(rE)
2103  return false;
2104  }
2105  return true;
2106 }
2107 
2108 // Write register NPT (Time duration of Preliminary cycles). Command {NPT,x} with x = value in ms (see manual)
2109 // Set the maximum time duration in ms of the preminilary cycles.
2110 bool CMFC3045Instrument::TimePreCycleSet(const U16 & rRegVal)
2111 {
2112  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2113  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2114 
2115  try {
2116  std::string l_Command("NPT,");
2117 
2118  if (eAdvancedMode::k2 != m_AdvancedMode)
2119  throw CMFC3045InsException(std::string("NPT Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2120  if (rRegVal > NPT_MAX)
2121  throw CMFC3045InsException(std::string("Failed, NPT out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2122  else
2123  l_Command += std::to_string(rRegVal);
2124  if (!l_Write(l_Command))
2125  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2126  }
2127  catch (CMFC3045InsException & rE)
2128  {
2130  MTL_Unused(rE)
2131  return false;
2132  }
2133  return true;
2134 }
2135 
2136 // Read register NPT (Time duration of Preliminary Cycles). Command [NPT]
2137 // Get the maximum time duration in ms of the preminilary cycles.
2139 {
2140  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2141  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2142 
2143  try {
2144  std::string l_RdStr;
2145  if (eAdvancedMode::kNone == m_AdvancedMode)
2146  throw CMFC3045InsException(std::string("NPT Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2147  if (!l_Write("NPT"))
2148  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2149  if (!l_ReadString(l_RdStr))
2150  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2151  rRegVal = static_cast<U16>(std::stoul(l_RdStr));
2152  }
2153  catch (CMFC3045InsException & rE)
2154  {
2156  MTL_Unused(rE)
2157  return false;
2158  }
2159  return true;
2160 }
2161 
2162 // Write register RSO (Rejection Signal Offset). Command [RSO,x] with x = value in ppm (see manual)
2163 // Set the offset between NMR signals of the ramps up and down in ppm (referenced to PCF register : PA central freq)
2165 {
2166  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2167  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2168 
2169  try {
2170  std::string l_Command("RSO,");
2171 
2172  if (eAdvancedMode::kNone == m_AdvancedMode)
2173  throw CMFC3045InsException(std::string("RSO Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2174  if ((rRegVal < RSO_MIN) || (rRegVal > RSO_MAX))
2175  throw CMFC3045InsException(std::string("Failed, RSO out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2176  else
2177  l_Command += std::to_string(rRegVal);
2178  if (!l_Write(l_Command))
2179  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2180  }
2181  catch (CMFC3045InsException & rE)
2182  {
2184  MTL_Unused(rE)
2185  return false;
2186  }
2187  return true;
2188 }
2189 
2190 // Read register RSO (Rejection Signal Offset). Command [RSO]
2191 // Get the offset between NMR signals of the ramps up and down in ppm (referenced to PCF register : PA central freq)
2193 {
2194  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2195  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2196 
2197  try {
2198  std::string l_RdStr;
2199  if (eAdvancedMode::kNone == m_AdvancedMode)
2200  throw CMFC3045InsException(std::string("RSO Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2201  if (!l_Write("RSO"))
2202  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2203  if (!l_ReadString(l_RdStr))
2204  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2205  rRegVal = static_cast<U16>(std::stoul(l_RdStr));
2206  }
2207  catch (CMFC3045InsException & rE)
2208  {
2210  MTL_Unused(rE)
2211  return false;
2212  }
2213  return true;
2214 }
2215 
2216 // Write register RSG (Rejection Signal Gap). Command [RSG,x] with x = value in ppm (see manual)
2217 // Set the gap limit in ppm (referenced to PCF register : PA central freq) between NMR signal ramps to reject a measurement
2218 bool CMFC3045Instrument::RejectionGapSet(const U16 & rRegVal)
2219 {
2220  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2221  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2222 
2223  try {
2224  std::string l_Command("RSG,");
2225 
2226  if (eAdvancedMode::kNone == m_AdvancedMode)
2227  throw CMFC3045InsException(std::string("RSG Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2228  if ((rRegVal < RSG_MIN) || (rRegVal > RSG_MAX))
2229  throw CMFC3045InsException(std::string("Failed, RSG out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2230  else
2231  l_Command += std::to_string(rRegVal);
2232  if (!l_Write(l_Command))
2233  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2234  }
2235  catch (CMFC3045InsException & rE)
2236  {
2238  MTL_Unused(rE)
2239  return false;
2240  }
2241  return true;
2242 }
2243 
2244 // Read register RSG (Rejection Signal Gap). Command [RSG]
2245 // Get the gap limit in ppm (referenced to PCF register : PA central freq) between NMR signal ramps to reject a measurement
2247 {
2248  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2249  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2250 
2251  try {
2252  std::string l_RdStr;
2253  if (eAdvancedMode::kNone == m_AdvancedMode)
2254  throw CMFC3045InsException(std::string("RSG Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2255  if (!l_Write("RSG"))
2256  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2257  if (!l_ReadString(l_RdStr))
2258  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2259  rRegVal = static_cast<U16>(std::stoul(l_RdStr));
2260  }
2261  catch (CMFC3045InsException & rE)
2262  {
2264  MTL_Unused(rE)
2265  return false;
2266  }
2267  return true;
2268 }
2269 
2270 // Write register TVP (Time Versus Precision). Command TVP,x with x = 0 or 1 (see manual)
2271 // Set time versus precision measurement optimisation
2273 {
2274  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2275  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2276 
2277  try {
2278  std::string l_Command("TVP,");
2279 
2280  l_Command += std::to_string(static_cast<U8>(rRegVal));
2281  if (!l_Write(l_Command))
2282  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2283  }
2284  catch (CMFC3045InsException & rE)
2285  {
2287  MTL_Unused(rE)
2288  return false;
2289  }
2290  return true;
2291 }
2292 
2293 // Read register TVP (Time Versus Precision). Command TVP
2294 // Get time versus precision measurement optimisation register value
2296 {
2297  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2298  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2299 
2300  try {
2301  U8 l_Precision(255);
2302  std::string l_RdStr;
2303  if (!l_Write("TVP"))
2304  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2305  if (!l_ReadString(l_RdStr))
2306  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2307  l_Precision = static_cast<U8>(std::stoul(l_RdStr));
2308  switch (l_Precision)
2309  {
2310  case static_cast<U8>(ePrecision::kHighPrecision):
2311  rRegVal = ePrecision::kHighPrecision;
2312  break;
2313  case static_cast<U8>(ePrecision::kLowPrecision):
2314  rRegVal = ePrecision::kLowPrecision;
2315  break;
2316  default:
2317  MTL_Assert(false);
2318  break;
2319  }
2320  }
2321  catch (CMFC3045InsException & rE)
2322  {
2324  MTL_Unused(rE)
2325  return false;
2326  }
2327  return true;
2328 }
2329 
2330 //----------------------------------------------------------------------//
2331 // Data Acquisition (Measurement) //
2332 //----------------------------------------------------------------------//
2333 // Write register RUN (Run measurement). Command RUN
2334 // Starts a NMR measurement (of NCY Cycles) on all probes of probe-array.
2335 // (Note: then read measurement results with BFV command)
2337 {
2338  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2339  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2340 
2341  try {
2342  if (!l_Write("RUN"))
2343  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2344  }
2345  catch (CMFC3045InsException & rE)
2346  {
2348  MTL_Unused(rE)
2349  return false;
2350  }
2351  return true;
2352 }
2353 
2354 // Write register RUN (Run measurement). Command RUN,x wih x= probe number 0 to nbProbe in PA
2355 // Starts a NMR measurement of (NCY Cycles) on an individual probe (if x>1 to nbProbes PA) or on all PA (if x=0)
2356 // (Note: then read measurement result with BFV,x command)
2357 bool CMFC3045Instrument::MeasCycleStart(const U8 & rProbeSel)
2358 {
2359  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2360  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2361 
2362  try {
2363  if (rProbeSel > m_NbProbesInPA)
2364  throw CMFC3045InsException(std::string("Probe selection out of range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2365 
2366  std::string l_Command("RUN,");
2367  l_Command += std::to_string(rProbeSel);
2368  if (!l_Write(l_Command))
2369  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2370  }
2371  catch (CMFC3045InsException & rE)
2372  {
2374  MTL_Unused(rE)
2375  return false;
2376  }
2377  return true;
2378 }
2379 
2380 // Activate SMA (send message automatically from main unit) and Start a NMR measurement on the whole probe array.
2381 // Only PA not connected and Data Ready SMA bit in register are activated.
2382 // Warning: after this method, avoid using any get (Write + Read) commands. Use only the WaitSmaMeasureDataReady()
2383 // to wait on the measurement data ready message.
2384 // You must disable the SMA before to send any get (Write + Read) commands.
2386 {
2387  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2388  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2389 
2390  try {
2391  m_SMAValue.RawSMAB =0; // clear previous SMA message flag received
2392 
2393  // Set SMA for PA & DR
2394  uSMAByte l_SMARegValRead;
2395  uSMAByte l_SMARegVal;
2396  l_SMARegValRead.RawSMAB =0;
2397  l_SMARegVal.RawSMAB =0;
2398  l_SMARegVal.SMAByte.DRST1 =1;
2399  l_SMARegVal.SMAByte.PANST2 =1;
2400  if (!l_SMASet(l_SMARegVal.RawSMAB))
2401  throw CMFC3045InsException(std::string("Fail to set SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2402  if (!SMAGet(l_SMARegValRead.RawSMAB))
2403  throw CMFC3045InsException(std::string("Fail to read back SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2404  if(l_SMARegVal.RawSMAB != l_SMARegValRead.RawSMAB)
2405  throw CMFC3045InsException(std::string("Fail. SMA is not enable") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2406  // Start measurement
2407  if (!MeasCycleStart())
2408  throw CMFC3045InsException(std::string("Fail to start measurement in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2409  }
2410  catch (CMFC3045InsException & rE)
2411  {
2413  MTL_Unused(rE)
2414  return false;
2415  }
2416  return true;
2417 }
2418 
2419 // Activate SMA (send message automatically from main unit) and Start a NMR measurement on a specific single probe.
2420 // Only PA not connected and Data Ready SMA bit in register are activated.
2421 // Warning: after this method, avoid using any get (Write + Read) commands. Use only the WaitSmaMeasureDataReady()
2422 // to wait on the measurement data ready message.
2423 bool CMFC3045Instrument::MeasStartWithSMA(const U8 & rProbeSel)
2424 {
2425  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2426  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2427 
2428  try {
2429  m_SMAValue.RawSMAB =0; // clear previous SMA message flag received
2430 
2431  // Set SMA for PA & DR
2432  uSMAByte l_SMARegValRead;
2433  uSMAByte l_SMARegVal;
2434  l_SMARegValRead.RawSMAB =0;
2435  l_SMARegVal.RawSMAB =0;
2436  l_SMARegVal.SMAByte.DRST1 =1;
2437  l_SMARegVal.SMAByte.PANST2 =1;
2438  if (!l_SMASet(l_SMARegVal.RawSMAB))
2439  throw CMFC3045InsException(std::string("Fail to set SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2440  if (!SMAGet(l_SMARegValRead.RawSMAB))
2441  throw CMFC3045InsException(std::string("Fail to read back SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2442  if(l_SMARegVal.RawSMAB != l_SMARegValRead.RawSMAB)
2443  throw CMFC3045InsException(std::string("Fai. SMA is not enable") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2444  // Start measurement
2445  if (!MeasCycleStart(rProbeSel))
2446  throw CMFC3045InsException(std::string("Fail to start measurement in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2447  }
2448  catch (CMFC3045InsException & rE)
2449  {
2451  MTL_Unused(rE)
2452  return false;
2453  }
2454  return true;
2455 }
2456 
2457 // When measurement is processing and SMA is activated use this method to wait during
2458 // x milliseconds on SMA message "DR" (data ready) or "PA" (probe array not connected).
2459 // SMA is disable after "DR" or "PA" message.
2460 // Note: be sure to never use this method while waiting for another standard Read command!
2461 bool CMFC3045Instrument::WaitSmaMeasureDataReady(const U32 & rMeasWaitTimeout_ms, uSMAByte & rSmaValue)
2462 {
2463  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2464  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2465  rSmaValue.RawSMAB = 0;
2466  try {
2467  // Wait for SMA Flag DR or PA with a milliseconds timeout
2468  if(m_SMAEnabled)
2469  {
2470  U32 l_RxNewDataLength(0);
2471  std::string l_TempRdStrOut;
2472  uSMAByte l_SMAMsg;
2473  l_SMAMsg.RawSMAB =0;
2474  U32 l_NbSmaMsg(0);
2475 
2476  if(l_WaitAvailableDataRX(rMeasWaitTimeout_ms, l_RxNewDataLength, false)) // wait and check durring m_WaitTimeRdData_ms for new data available in Rx Buffer before to read it
2477  {
2478  if (l_RxNewDataLength >= 4)
2479  l_NbSmaMsg = l_RxNewDataLength / 4; // size per SMA message (= 2 ascii char + 2 term char)
2480  for(size_t l_i =0; l_i < l_NbSmaMsg ; l_i++)
2481  {
2482  m_ReadBuffer.clear();
2483  if (!CVISAInstrument::Read(m_ReadBuffer,false))
2484  {
2485  ViStatus l_VisaStatus = Status();
2486  if (!((VI_ERROR_TMO == l_VisaStatus) &&
2487  (1 <= m_ReadBuffer.size()) && (static_cast<char>(DATA_END_ETB) == m_ReadBuffer[m_ReadBuffer.size() - 1])))
2488  {
2489  throw CMFC3045InsException("Could not read", MTL__LOCATION__);
2490  }
2491  }
2492  else
2493  {
2494  l_ExtractSmaMsgFromDataRX(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end()), l_SMAMsg, l_TempRdStrOut);
2495  m_SMAValue.RawSMAB |= l_SMAMsg.RawSMAB;
2496  }
2497  }
2498  }
2499  rSmaValue = m_SMAValue;
2500  if (m_SMAValue.SMAByte.DRST1 || m_SMAValue.SMAByte.PANST2)
2501  {
2502  // Stop SMA
2503  if (!DisableSMA())
2504  throw CMFC3045InsException(std::string("Fail to disable SMA in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2505  }
2506  m_SMAValue.RawSMAB =0; // global SMA value has been read. Clear it!
2507  }
2508  }
2509  catch (CMFC3045InsException & rE)
2510  {
2512  MTL_Unused(rE)
2513  return false;
2514  }
2515  return true;
2516 }
2517 
2518 // Write register SRC (Search NMR signal). Command SRC
2519 // Starts a NMR search over the full probe-array range frequency using all probes
2520 // (Note: then read search results with BFV,x command)
2522 {
2523  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2524  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2525 
2526  try {
2527  if (!l_Write("SRC"))
2528  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2529  }
2530  catch (CMFC3045InsException & rE)
2531  {
2533  MTL_Unused(rE)
2534  return false;
2535  }
2536  return true;
2537 }
2538 
2539 // Write register SRC (Search NMR signal). Command SRC,x wih x= probe number 0 to nbProbe in PA
2540 // Starts a NMR search over the full probe-array range frequency using an individual probe (if x>1 to nbProbes PA) or on all PA (if x=0)
2541 // (Note: then read measurement result with BFV,x command)
2542 bool CMFC3045Instrument::SearchStart(const U8 & rProbeSel)
2543 {
2544  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2545  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2546 
2547  try {
2548  if (rProbeSel > m_NbProbesInPA)
2549  throw CMFC3045InsException(std::string("Probe selection out of range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2550 
2551  std::string l_Command("SRC,");
2552  l_Command += std::to_string(rProbeSel);
2553  if (!l_Write(l_Command))
2554  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2555  }
2556  catch (CMFC3045InsException & rE)
2557  {
2559  MTL_Unused(rE)
2560  return false;
2561  }
2562  return true;
2563 }
2564 
2565 
2566 // Activate SMA (send message automatically from main unit) and Start a NMR Search on the whole probe array.
2567 // Only PA not connected and Data Ready SMA bit in register are activated.
2568 // Warning: after this method, avoid using any get (Write + Read) commands. Use only the WaitSmaMeasureDataReady()
2569 // to wait on the measurement data ready message.
2570 // You must disable the SMA before to send any get (Write + Read) commands.
2572 {
2573  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2574  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2575 
2576  try {
2577  m_SMAValue.RawSMAB =0; // clear previous SMA message flag received
2578 
2579  // Set SMA for PA & DR
2580  uSMAByte l_SMARegValRead;
2581  uSMAByte l_SMARegVal;
2582  l_SMARegValRead.RawSMAB =0;
2583  l_SMARegVal.RawSMAB =0;
2584  l_SMARegVal.SMAByte.DRST1 =1;
2585  l_SMARegVal.SMAByte.PANST2 =1;
2586  if (!l_SMASet(l_SMARegVal.RawSMAB))
2587  throw CMFC3045InsException(std::string("Fail to set SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2588  if (!SMAGet(l_SMARegValRead.RawSMAB))
2589  throw CMFC3045InsException(std::string("Fail to read back SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2590  if(l_SMARegVal.RawSMAB != l_SMARegValRead.RawSMAB)
2591  throw CMFC3045InsException(std::string("Fail. SMA is not enable") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2592  // Start search
2593  if (!SearchStart())
2594  throw CMFC3045InsException(std::string("Fail to start Search in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2595  }
2596  catch (CMFC3045InsException & rE)
2597  {
2599  MTL_Unused(rE)
2600  return false;
2601  }
2602  return true;
2603 }
2604 
2605 // Activate SMA (send message automatically from main unit) and Start a NMR search on a specific single probe.
2606 // Only PA not connected and Data Ready SMA bit in register are activated.
2607 // Warning: after this method, avoid using any get (Write + Read) commands. Use only the WaitSmaMeasureDataReady()
2608 // to wait on the measurement data ready message.
2609 // You must disable the SMA before to send any get (Write + Read) commands.
2610 bool CMFC3045Instrument::SearchStartWithSMA(const U8 & rProbeSel)
2611 {
2612  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2613  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2614 
2615  try {
2616  m_SMAValue.RawSMAB =0; // clear previous SMA message flag received
2617 
2618  // Set SMA for PA & DR
2619  uSMAByte l_SMARegValRead;
2620  uSMAByte l_SMARegVal;
2621  l_SMARegValRead.RawSMAB =0;
2622  l_SMARegVal.RawSMAB =0;
2623  l_SMARegVal.SMAByte.DRST1 =1;
2624  l_SMARegVal.SMAByte.PANST2 =1;
2625  if (!l_SMASet(l_SMARegVal.RawSMAB))
2626  throw CMFC3045InsException(std::string("Fail to set SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2627  if (!SMAGet(l_SMARegValRead.RawSMAB))
2628  throw CMFC3045InsException(std::string("Fail to read back SMA register in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2629  if(l_SMARegVal.RawSMAB != l_SMARegValRead.RawSMAB)
2630  throw CMFC3045InsException(std::string("Fail. SMA is not enable") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2631  // Start search
2632  if (!SearchStart(rProbeSel))
2633  throw CMFC3045InsException(std::string("Fail to start Search in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2634  }
2635  catch (CMFC3045InsException & rE)
2636  {
2638  MTL_Unused(rE)
2639  return false;
2640  }
2641  return true;
2642 }
2643 
2644 // Write register CTN (Continuous measurement). Command CTN
2645 // Starts a continuous measurement (infinite modulation cycles) until a BRK command
2647 {
2648  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2649  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2650 
2651  try {
2652  if (!l_Write("CTN"))
2653  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2654  }
2655  catch (CMFC3045InsException & rE)
2656  {
2658  MTL_Unused(rE)
2659  return false;
2660  }
2661  return true;
2662 }
2663 
2664 // Write register BRK (Break). Command BRK
2665 // Interrupts any data acquisition (stop measurement or data block transfert)
2667 {
2668  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2669  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2670 
2671  try {
2672  if (!l_Write("BRK", true))
2673  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2674  }
2675  catch (CMFC3045InsException & rE)
2676  {
2678  MTL_Unused(rE)
2679  return false;
2680  }
2681  return true;
2682 }
2683 
2684 //----------------------------------------------------------------------//
2685 // Data Reading //
2686 //----------------------------------------------------------------------//
2687 // Write register BLK (Data transfert Block Mode). Command BLK,x with x= 0 to 2 mode
2688 // Set the data transfert block mode. (see manual)
2689 // This mode is used for reading data as measurements & calibration corrections table
2690 bool CMFC3045Instrument::l_DataBlockModeSet(const eDataBlockMode & rRegVal)
2691 {
2692  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2693  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2694 
2695  try {
2696  std::string l_Command("BLK,");
2697  l_Command += std::to_string(static_cast<U8>(rRegVal));
2698  if (!l_Write(l_Command))
2699  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2700  m_DataBlockMode = rRegVal;
2701  }
2702  catch (CMFC3045InsException & rE)
2703  {
2704  m_DataBlockMode = eDataBlockMode::kOneByOne; // default main unit value after reset
2706  MTL_Unused(rE)
2707  return false;
2708  }
2709  return true;
2710 }
2711 
2712 // Write & Read register BLK (Data transfert Block Mode) to decimal. Commands BLK,1 and BLK
2713 // Set data transfert block mode to decimal and read back value
2715 {
2716  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2717  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2718 
2719  try {
2720  eDataBlockMode l_BlockMode;
2721  if(!l_DataBlockModeSet(eDataBlockMode::kAllDecimal))
2722  throw CMFC3045InsException(std::string("Fail to set decimal data block mode in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2723  if (!DataBlockModeGet(l_BlockMode))
2724  throw CMFC3045InsException(std::string("Fail to get data block mode in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2725  if(eDataBlockMode::kAllDecimal != l_BlockMode)
2726  throw CMFC3045InsException(std::string("Failed: read back data block mode is not decimal in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2727  }
2728  catch (CMFC3045InsException & rE)
2729  {
2731  MTL_Unused(rE)
2732  return false;
2733  }
2734  return true;
2735 }
2736 
2737 // Read register BLK (Data transfert Block Mode). Command BLK
2738 // Get the data transfert block mode. (see manual)
2739 // This mode is used for reading data as measurements & calibration corrections table
2741 {
2742  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2743  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2744 
2745  try {
2746  U32 l_BlockMode(255);
2747  std::string l_RdStr;
2748  if (!l_Write("BLK"))
2749  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2750  if (!l_ReadString(l_RdStr))
2751  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2752  l_BlockMode = static_cast<U32>(std::stoul(l_RdStr));
2753  switch (l_BlockMode)
2754  {
2755  case static_cast<U32>(eDataBlockMode::kOneByOne):
2756  rRegVal = eDataBlockMode::kOneByOne;
2757  break;
2758  case static_cast<U32>(eDataBlockMode::kAllDecimal):
2759  rRegVal = eDataBlockMode::kAllDecimal;
2760  break;
2761  case static_cast<U32>(eDataBlockMode::kAllHexa):
2762  rRegVal = eDataBlockMode::kAllHexa;
2763  break;
2764  default:
2765  MTL_Assert("UnHandled value Type");
2766  throw CMFC3045InsException(std::string("Failed: Get wrong value for BLK in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2767  break;
2768  }
2769  m_DataBlockMode = rRegVal;
2770  }
2771  catch (CMFC3045InsException & rE)
2772  {
2773  m_DataBlockMode = eDataBlockMode::kOneByOne;
2775  MTL_Unused(rE)
2776  return false;
2777  }
2778  return true;
2779 }
2780 
2781 // Read the expected End of transmission Block character
2782 // Note: Change the termination character to end of transmission block 0x17 and read it.
2783 // then set back the previous Termination Char.
2784 // (This is needed after the last measurement data read of a block transfer)
2785 bool CMFC3045Instrument::l_ReadEndTransmissionBlockChar()
2786 {
2787  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2788  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2789 
2790  try {
2791  std::string l_RdStr;
2792  // Change the Termination Char to End of transmission Block 0x17 to read it after the last measurement data
2793  sSerialPortSettings l_SerialParms = m_HostSerialConfig;
2794  l_SerialParms.ReadTermChar = static_cast<char>(DATA_END_ETB);
2795  if(!l_SerialPortHostConfig(l_SerialParms))
2796  throw CMFC3045InsException(std::string("Failed: to modify VISA serial term char in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2797  if(!l_ReadString(l_RdStr)) // read end of transmission Block ETB character
2798  throw CMFC3045InsException(std::string("Failed: Didn't get end of transmission block char in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2799  if (!l_SerialPortHostConfig(m_HostSerialConfig)) // set back previous ReadTermChar in Serial Port config & clear Serial Rx Tx buffers
2800  throw CMFC3045InsException(std::string("Failed: to modify VISA serial term char in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2801  }
2802  catch (CMFC3045InsException & rE)
2803  {
2805  MTL_Unused(rE)
2806  l_SerialPortHostConfig(m_HostSerialConfig); // set back previous ReadTermChar in Serial Port config & clear Serial Rx Tx buffers
2807  return false;
2808  }
2809  return true;
2810 }
2811 
2812 // Get, according to a write string cmd, data measurements in a block of decimal data
2813 // Note: Data is read according to the active block mode (BLK). We need BLK = 1 = kAllDecimal
2814 // The rData vector size must have been initialized to the exepcted number of data to be received.
2815 // NumberProbesGet() or NumberProbesSet() must have been called once before it to set attribute m_NbProbesInPA
2816 bool CMFC3045Instrument::l_ReadMeasurementTableBlock(const std::string rStringCMD, std::vector<U32> & rData)
2817 {
2818  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2819  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2820 
2821  try {
2822  if ((0 == rData.size()) || (rData.size() < m_NbProbesInPA) || (NPR_MAX < rData.size()))
2823  throw CMFC3045InsException(std::string("Failed. Vector size out of range to store received data.") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2824  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
2825  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2826 
2827  if (!l_Write(rStringCMD))
2828  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2829 
2830  for (size_t i = 0; i < rData.size(); i++)
2831  {
2832  std::string l_StrData;
2833  if (!l_ReadString(l_StrData))
2834  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2835  if (l_StrData.empty())
2836  rData[i] = 0;
2837  else
2838  rData[i] = static_cast<U32>(std::stoul(l_StrData));
2839  }
2840  // Read the char End of transmission Block 0x17 after the last measurement data
2841  if (!l_ReadEndTransmissionBlockChar())
2842  throw CMFC3045InsException(std::string("Read failed ETB in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2843  }
2844  catch (CMFC3045InsException & rE)
2845  {
2847  MTL_Unused(rE)
2848  return false;
2849  }
2850  return true;
2851 }
2852 
2853 // Read register BFV (B Magnetic Field Value). Command BFV
2854 // Get the magnetic field value in dHz from last measurements or search operation for all probes
2855 // Note: Data is read according to the active block mode (BLK). We need BLK = 1 = kAllDecimal
2856 // rNbMeasurements must have been initialized to the number of probes in PA.
2857 bool CMFC3045Instrument::DataMagneticFieldGet(const U8 & rNbMeasurements, std::vector<U32> & rData)
2858 {
2859  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2860  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2861  rData.clear();
2862  try {
2863  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
2864  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2865 
2866  rData.resize(rNbMeasurements);
2867  if (!l_ReadMeasurementTableBlock("BFV", rData))
2868  throw CMFC3045InsException(std::string("Read failed measurement block in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2869 
2870  }
2871  catch (CMFC3045InsException & rE)
2872  {
2874  MTL_Unused(rE)
2875  return false;
2876  }
2877  return true;
2878 }
2879 
2880 // Read register BFV (B Magnetic Field Value). Command BFV,x with x= probe number 1 to nbProbe in PA
2881 // Get the magnetic field value in dHz from last measurement or search operation of a specified probe
2882 // Note: Data is read according to the active block mode (BLK). We need BLK = 1 = kAllDecimal
2883 bool CMFC3045Instrument::DataMagneticFieldGet(U32 & rData, const U8 & rProbeSel)
2884 {
2885  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2886  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2887 
2888  try {
2889  if (rProbeSel < 1 || rProbeSel > m_NbProbesInPA)
2890  throw CMFC3045InsException(std::string("Probe selection out of range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2891  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
2892  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2893 
2894  std::string l_Command("BFV,");
2895  l_Command += std::to_string(rProbeSel);
2896  std::string l_StrData;
2897  if (!l_Write(l_Command))
2898  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2899  if (!l_ReadString(l_StrData))
2900  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2901  if (l_StrData.empty())
2902  rData = 0;
2903  else
2904  rData = static_cast<U32>(std::stoul(l_StrData));
2905  }
2906  catch (CMFC3045InsException & rE)
2907  {
2909  MTL_Unused(rE)
2910  return false;
2911  }
2912  return true;
2913 }
2914 
2915 // Read register BSD (B Magnetic standard Deviation). Command BSD
2916 // Get the standard deviation in dHz of each probe measurement
2917 // Note: Block mode must be 1 (kAllDecimal). BSD is not available in CTN measurement mode
2918 // rNbMeasurements must have been initialized to the number of probes in PA.
2919 bool CMFC3045Instrument::DataStdDeviationGet(const U8 & rNbMeasurements, std::vector<U32> & rData)
2920 {
2921  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2922  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2923  rData.clear();
2924  try {
2925  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
2926  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2927 
2928  rData.resize(rNbMeasurements);
2929  if (!l_ReadMeasurementTableBlock("BSD", rData))
2930  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2931  }
2932  catch (CMFC3045InsException & rE)
2933  {
2935  MTL_Unused(rE)
2936  return false;
2937  }
2938  return true;
2939 }
2940 
2941 // Read register BSD (B Magnetic standard Deviation). Command BSD,x with x= probe number 1 to nbProbe in PA
2942 // Get the standard deviation in dHz of a selected probe measurement
2943 // Block mode must be 1 (kAllDecimal). BSD is not available in CTN measurement mode
2944 bool CMFC3045Instrument::DataStdDeviationGet(U32 & rData, const U8 & rProbeSel)
2945 {
2946  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2947  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2948 
2949  try {
2950  if (rProbeSel < 1 || rProbeSel > m_NbProbesInPA)
2951  throw CMFC3045InsException(std::string("Probe selection out of range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2952  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
2953  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2954 
2955  std::string l_Command("BSD,");
2956  l_Command += std::to_string(rProbeSel);
2957  std::string l_StrData;
2958  if (!l_Write(l_Command))
2959  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2960  if (!l_ReadString(l_StrData))
2961  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2962  if (l_StrData.empty())
2963  rData = 0;
2964  else
2965  rData = static_cast<U32>(std::stoul(l_StrData));
2966  }
2967  catch (CMFC3045InsException & rE)
2968  {
2970  MTL_Unused(rE)
2971  return false;
2972  }
2973  return true;
2974 }
2975 
2976 // Read register BNC (Number of valid Cycle). Command BNC
2977 // Get the number of valid NMR Cycles acquisition during last measurements of each probe
2978 // Note: Block mode must be 1 (kAllDecimal). BNC is not available in CTN measurement mode
2979 // rNbMeasurements must have been initialized to the number of probes in PA.
2980 bool CMFC3045Instrument::DataNumberValidCycleGet(const U8 & rNbMeasurements, std::vector<U32> & rData)
2981 {
2982  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
2983  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
2984  rData.clear();
2985  try {
2986  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
2987  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2988 
2989  rData.resize(rNbMeasurements);
2990  if (!l_ReadMeasurementTableBlock("BNC", rData))
2991  throw CMFC3045InsException(std::string("Fail to read measurement block in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
2992  }
2993  catch (CMFC3045InsException & rE)
2994  {
2996  MTL_Unused(rE)
2997  return false;
2998  }
2999  return true;
3000 }
3001 
3002 // Read register BNC (Number of valid Cycle). Command BNC,x with x= probe number 1 to nbProbe in PA
3003 // Get the number of valid NMR Cycles acquisition during last measurement of selected probe
3004 // Block mode must be 1 (kAllDecimal). BNC is not available in CTN measurement mode
3005 bool CMFC3045Instrument::DataNumberValidCycleGet(U32 & rData, const U8 & rProbeSel)
3006 {
3007  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3008  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3009 
3010  try {
3011  if (rProbeSel < 1 || rProbeSel > m_NbProbesInPA)
3012  throw CMFC3045InsException(std::string("Probe selection out of range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3013  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
3014  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3015 
3016  std::string l_Command("BNC,");
3017  l_Command += std::to_string(rProbeSel);
3018  std::string l_StrData;
3019  if (!l_Write(l_Command))
3020  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3021  if (!l_ReadString(l_StrData))
3022  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3023  if (l_StrData.empty())
3024  rData = 0;
3025  else
3026  rData = static_cast<U32>(std::stoul(l_StrData));
3027  }
3028  catch (CMFC3045InsException & rE)
3029  {
3031  MTL_Unused(rE)
3032  return false;
3033  }
3034  return true;
3035 }
3036 
3037 // Read register BIN (Individual NMR frequency). Command BIN
3038 // Get two NMR Frequency measurements in dHz, one for ramp up and one for ramp down according to the last previous individual RUN,x or SRC,x cmd
3039 // The first measurement value returned is ramp up, the second value is ramp down.
3040 // Block mode must be 1 (kAllDecimal). BIN is not available in CTN measurement mode
3041 bool CMFC3045Instrument::DataIndividualFrequencyGet(U32 & rDataUp, U32 & rDataDown)
3042 {
3043  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3044  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3045 
3046  try {
3047  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
3048  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3049 
3050  if (!l_Write("BIN"))
3051  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3052  std::string l_StrDataUp;
3053  if (!l_ReadString(l_StrDataUp))
3054  throw CMFC3045InsException(std::string("Read failed ramp up in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3055  if (l_StrDataUp.empty())
3056  rDataUp = 0;
3057  else
3058  rDataUp = static_cast<U32>(std::stoul(l_StrDataUp));
3059 
3060  std::string l_StrDataDwn;
3061  if (!l_ReadString(l_StrDataDwn))
3062  throw CMFC3045InsException(std::string("Read failed ramp down in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3063  if (l_StrDataDwn.empty())
3064  rDataDown = 0;
3065  else
3066  rDataDown = static_cast<U32>(std::stoul(l_StrDataDwn));
3067 
3068  // Read the char End of transmission Block 0x17 after the last measurement data
3069  if (!l_ReadEndTransmissionBlockChar())
3070  throw CMFC3045InsException(std::string("Read failed ETB in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3071  }
3072  catch (CMFC3045InsException & rE)
3073  {
3075  MTL_Unused(rE)
3076  return false;
3077  }
3078  return true;
3079 }
3080 
3081 // Read register BFC (Central NMR frequency). Command BFC
3082 // Get the central (median, not average) NMR Frequency in dHz of all valid probes measurement.
3084 {
3085  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3086  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3087 
3088  try {
3089  std::string l_StrData;
3090  if (!l_Write("BFC"))
3091  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3092  if (!l_ReadString(l_StrData))
3093  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3094  if (l_StrData.empty())
3095  rData = 0;
3096  else
3097  rData = static_cast<U32>(std::stoul(l_StrData));
3098  }
3099  catch (CMFC3045InsException & rE)
3100  {
3102  MTL_Unused(rE)
3103  return false;
3104  }
3105  return true;
3106 }
3107 
3108 // Read register BFL (Lowest NMR frequency). Command BFL
3109 // Get the lowest NMR Frequency in dHz of all valid probes measurement.
3111 {
3112  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3113  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3114 
3115  try {
3116  std::string l_StrData;
3117  if (!l_Write("BFL"))
3118  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3119  if (!l_ReadString(l_StrData))
3120  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3121  if (l_StrData.empty())
3122  rData = 0;
3123  else
3124  rData = static_cast<U32>(std::stoul(l_StrData));
3125  }
3126  catch (CMFC3045InsException & rE)
3127  {
3129  MTL_Unused(rE)
3130  return false;
3131  }
3132  return true;
3133 }
3134 
3135 // Read register BFH (Highest NMR frequency). Command BFH
3136 // Get the highest NMR Frequency in dHz of all valid probes measurement.
3138 {
3139  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3140  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3141 
3142  try {
3143  std::string l_StrData;
3144  if (!l_Write("BFH"))
3145  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3146  if (!l_ReadString(l_StrData))
3147  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3148  if (l_StrData.empty())
3149  rData = 0;
3150  else
3151  rData = static_cast<U32>(std::stoul(l_StrData));
3152  }
3153  catch (CMFC3045InsException & rE)
3154  {
3156  MTL_Unused(rE)
3157  return false;
3158  }
3159  return true;
3160 }
3161 
3162 // Read register BFD (Difference highest-lowest NMR frequency). Command BFD
3163 // Get the difference (highest - lowest) NMR Frequency in ppm (referenced to BFC register value) of all valid probes measurement.
3165 {
3166  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3167  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3168 
3169  try {
3170  std::string l_StrData;
3171  if (!l_Write("BFD"))
3172  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3173  if (!l_ReadString(l_StrData))
3174  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3175  if (l_StrData.empty())
3176  rData = 0;
3177  else
3178  rData = static_cast<U32>(std::stoul(l_StrData));
3179  }
3180  catch (CMFC3045InsException & rE)
3181  {
3183  MTL_Unused(rE)
3184  return false;
3185  }
3186  return true;
3187 }
3188 
3189 //----------------------------------------------------------------------//
3190 // Probe Array Informations //
3191 //----------------------------------------------------------------------//
3192 // Write register NPR (Number of PRobes). Command {NPR,x} with x = 1 to Nb_of_ProbesPA
3193 // Set the total number of probes (measurement points) in the Probe-Array
3194 bool CMFC3045Instrument::NumberProbesSet(const U8 & rRegVal)
3195 {
3196  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3197  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3198 
3199  try {
3200  std::string l_Command("NPR,");
3201 
3202  if (eAdvancedMode::k2 != m_AdvancedMode)
3203  throw CMFC3045InsException(std::string("NPR Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3204  if ((rRegVal < 1) || (rRegVal > NPR_MAX))
3205  throw CMFC3045InsException(std::string("Failed, NPR out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3206  l_Command += std::to_string(rRegVal);
3207  if (!l_Write(l_Command))
3208  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3209  m_NbProbesInPA = rRegVal; // save number of Probe-array probes
3210  }
3211  catch (CMFC3045InsException & rE)
3212  {
3213  m_NbProbesInPA = 0; // clear number of Probe-array probes
3215  MTL_Unused(rE)
3216  return false;
3217  }
3218  return true;
3219 }
3220 
3221 // Read register NPR (Number of PRobes). Command NPR
3222 // Get the total number of probes (measurement points) in the Probe-Array
3224 {
3225  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3226  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3227 
3228  try {
3229  std::string l_RdStr;
3230  if (!l_Write("NPR"))
3231  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3232  if (!l_ReadString(l_RdStr))
3233  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3234  rRegVal = static_cast<U8>(std::stoul(l_RdStr));
3235  m_NbProbesInPA = rRegVal; // save number of probes in Probe-array
3236  }
3237  catch (CMFC3045InsException & rE)
3238  {
3239  m_NbProbesInPA = 0; // clear number of Probe-array probes
3241  MTL_Unused(rE)
3242  return false;
3243  }
3244  return true;
3245 }
3246 
3247 // Write register PCF (Probe array Central Frequency). Command {PCF,x} with x = value in dHz
3248 // Set the probe array central frequency in dHz
3249 bool CMFC3045Instrument::PaCentralFreqSet(const U32 & rRegVal)
3250 {
3251  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3252  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3253 
3254  try {
3255  std::string l_Command("PCF,");
3256  if ((rRegVal < PA_FREQ_MIN_DHZ) || (rRegVal > PA_FREQ_MAX_DHZ))
3257  throw CMFC3045InsException(std::string("Failed, PCF out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3258  if (eAdvancedMode::k2 != m_AdvancedMode)
3259  throw CMFC3045InsException(std::string("PCF Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3260 
3261  l_Command += std::to_string(rRegVal);
3262  if (!l_Write(l_Command))
3263  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3264  }
3265  catch (CMFC3045InsException & rE)
3266  {
3268  MTL_Unused(rE)
3269  return false;
3270  }
3271  return true;
3272 }
3273 
3274 // Read register PCF (Probe array Central Frequency). Command PCF
3275 // Get the probe array central frequency in dHz
3277 {
3278  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3279  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3280 
3281  try {
3282  std::string l_RdStr;
3283  if (!l_Write("PCF"))
3284  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3285  if (!l_ReadString(l_RdStr))
3286  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3287  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
3288  }
3289  catch (CMFC3045InsException & rE)
3290  {
3292  MTL_Unused(rE)
3293  return false;
3294  }
3295  return true;
3296 }
3297 
3298 // Write register PLF (Probe array Lowest Frequency). Command {PLF,x} with x = value in dHz
3299 // Set probe array lowest frequency in dHz
3300 bool CMFC3045Instrument::PaLowestFreqSet(const U32 & rRegVal)
3301 {
3302  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3303  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3304 
3305  try {
3306  std::string l_Command("PLF,");
3307  if ((rRegVal < PA_FREQ_MIN_DHZ) || (rRegVal > PA_FREQ_MAX_DHZ))
3308  throw CMFC3045InsException(std::string("Failed, PLF out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3309  if (eAdvancedMode::k2 != m_AdvancedMode)
3310  throw CMFC3045InsException(std::string("PLF Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3311 
3312  l_Command += std::to_string(rRegVal);
3313  if (!l_Write(l_Command))
3314  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3315  }
3316  catch (CMFC3045InsException & rE)
3317  {
3319  MTL_Unused(rE)
3320  return false;
3321  }
3322  return true;
3323 }
3324 
3325 // Read register PLF (Probe array Lowest Frequency). Command PLF
3326 // Get the probe array lowest entral frequency in dHz
3328 {
3329  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3330  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3331 
3332  try {
3333  std::string l_RdStr;
3334  if (!l_Write("PLF"))
3335  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3336  if (!l_ReadString(l_RdStr))
3337  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3338  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
3339  }
3340  catch (CMFC3045InsException & rE)
3341  {
3343  MTL_Unused(rE)
3344  return false;
3345  }
3346  return true;
3347 }
3348 
3349 // Write register PHF (Probe array Highest Frequency). Command {PHF,x} with x = value in dHz
3350 // Set probe array highest frequency in dHz
3351 bool CMFC3045Instrument::PaHighestFreqSet(const U32 & rRegVal)
3352 {
3353  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3354  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3355 
3356  try {
3357  std::string l_Command("PHF,");
3358  if ((rRegVal < PA_FREQ_MIN_DHZ) || (rRegVal > PA_FREQ_MAX_DHZ))
3359  throw CMFC3045InsException(std::string("Failed, PHF out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3360  if (eAdvancedMode::k2 != m_AdvancedMode)
3361  throw CMFC3045InsException(std::string("PHF Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3362 
3363  l_Command += std::to_string(rRegVal);
3364  if (!l_Write(l_Command))
3365  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3366  }
3367  catch (CMFC3045InsException & rE)
3368  {
3370  MTL_Unused(rE)
3371  return false;
3372  }
3373  return true;
3374 }
3375 
3376 // Read register PHF (Probe array Highest Frequency). Command PHF
3377 // Get the probe array highest entral frequency in dHz
3379 {
3380  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3381  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3382 
3383  try {
3384  std::string l_RdStr;
3385  if (!l_Write("PHF"))
3386  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3387  if (!l_ReadString(l_RdStr))
3388  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3389  rRegVal = static_cast<U32>(std::stoul(l_RdStr));
3390  }
3391  catch (CMFC3045InsException & rE)
3392  {
3394  MTL_Unused(rE)
3395  return false;
3396  }
3397  return true;
3398 }
3399 
3400 // Write register RFH (RF Harmonic). Command {RFH,x} with x = 1,3,5,7
3401 // Set RF harmonic
3403 {
3404  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3405  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3406 
3407  try {
3408  std::string l_Command("RFH,");
3409 
3410  if (eAdvancedMode::k2 != m_AdvancedMode)
3411  throw CMFC3045InsException(std::string("RFH Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3412 
3413  l_Command += std::to_string(static_cast<U8>(rRegVal));
3414  if (!l_Write(l_Command))
3415  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3416  }
3417  catch (CMFC3045InsException & rE)
3418  {
3420  MTL_Unused(rE)
3421  return false;
3422  }
3423  return true;
3424 }
3425 
3426 // Read register RFH (RF Harmonic). Command RFH
3427 // Get RF harmonic
3429 {
3430  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3431  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3432 
3433  try {
3434  U32 l_RFHarmonic(0);
3435  std::string l_RdStr;
3436  if (!l_Write("RFH"))
3437  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3438  if (!l_ReadString(l_RdStr))
3439  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3440  l_RFHarmonic = static_cast<U32>(std::stoul(l_RdStr));
3441  switch (l_RFHarmonic)
3442  {
3443  case static_cast<U32>(eRFH::k1):
3444  rRegVal = eRFH::k1;
3445  break;
3446  case static_cast<U32>(eRFH::k3):
3447  rRegVal = eRFH::k3;
3448  break;
3449  case static_cast<U32>(eRFH::k5):
3450  rRegVal = eRFH::k5;
3451  break;
3452  case static_cast<U32>(eRFH::k7):
3453  rRegVal = eRFH::k7;
3454  break;
3455  default:
3456  MTL_Assert("UnHandled value Type");
3457  throw CMFC3045InsException(std::string("Failed: Get wrong value for RFH in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3458  break;
3459  }
3460  }
3461  catch (CMFC3045InsException & rE)
3462  {
3464  MTL_Unused(rE)
3465  return false;
3466  }
3467  return true;
3468 }
3469 
3470 // Write register NST (NMR Signal Threshold). Command {NST,x} with x = 0 to 255
3471 // Set DC threshold level to detect NMR signal
3472 bool CMFC3045Instrument::NmrThresholdSet(const U8 & rRegVal)
3473 {
3474  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3475  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3476 
3477  try {
3478  std::string l_Command("NST,");
3479 
3480  if (eAdvancedMode::k2 != m_AdvancedMode)
3481  throw CMFC3045InsException(std::string("NST Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3482 
3483  l_Command += std::to_string(rRegVal);
3484  if (!l_Write(l_Command))
3485  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3486  }
3487  catch (CMFC3045InsException & rE)
3488  {
3490  MTL_Unused(rE)
3491  return false;
3492  }
3493  return true;
3494 }
3495 
3496 // read register NST (NMR Signal Threshold). Command [NST]
3497 // Get DC threshold level to detect NMR signal
3499 {
3500  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3501  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3502 
3503  try {
3504  std::string l_RdStr;
3505  if (eAdvancedMode::kNone == m_AdvancedMode)
3506  throw CMFC3045InsException(std::string("NST Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3507  if (!l_Write("NST"))
3508  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3509  if (!l_ReadString(l_RdStr))
3510  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3511  rRegVal = static_cast<U8>(std::stoul(l_RdStr));
3512  }
3513  catch (CMFC3045InsException & rE)
3514  {
3516  MTL_Unused(rE)
3517  return false;
3518  }
3519  return true;
3520 }
3521 
3522 //----------------------------------------------------------------------//
3523 // EEPROMs (Main unit & PA) and Probe Array Normalisation //
3524 //----------------------------------------------------------------------//
3525 // Write register SMU (Settings of Main Unit). Command [SMU,>EEP]
3526 // Copy main unit settings parameters from main unit RAM to main unit EEPROM.
3528 {
3529  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3530  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3531 
3532  try {
3533  if (eAdvancedMode::kNone == m_AdvancedMode)
3534  throw CMFC3045InsException(std::string("SMU Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3535 
3536  if (!l_Write("SMU,>EEP"))
3537  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3538  }
3539  catch (CMFC3045InsException & rE)
3540  {
3542  MTL_Unused(rE)
3543  return false;
3544  }
3545  return true;
3546 }
3547 
3548 // Read register SMU (Settings of Main Unit). Command [SMU]
3549 // Read main unit settings parameters from main unit EEPROM.
3550 bool CMFC3045Instrument::MainUnitEepromRead(std::vector<char> & rEEPROMContent)
3551 {
3552  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3553  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3554 
3555  try {
3556  if (eAdvancedMode::kNone == m_AdvancedMode)
3557  throw CMFC3045InsException(std::string("SMU Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3558 
3559  if (!l_Write("SMU"))
3560  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3561 
3562  if (!l_ReadNCharNoTerm(m_ReadBuffer, MU_EEPROM_CHARSIZE + CHECKSUM_CHARSIZE)) // Main unit EEPROM has 80 bytes => 160 ASCII Hexa characters. We add 4 char for CheckSum-16bit
3563  throw CMFC3045InsException(std::string("Read failed Main Unit EEPROM in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3564 
3565  rEEPROMContent.assign(m_ReadBuffer.begin(), m_ReadBuffer.end());
3566  }
3567  catch (CMFC3045InsException & rE)
3568  {
3570  MTL_Unused(rE)
3571  return false;
3572  }
3573  return true;
3574 }
3575 
3576 // Write register SPA (Settings of Probe Array). Command [SPA,>EEP]
3577 // Write probe array settings parameters and calibration probe table (from Main unit RAM) to probe array EEPROM.
3579 {
3580  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3581  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3582 
3583  try {
3584  if (eAdvancedMode::kNone == m_AdvancedMode)
3585  throw CMFC3045InsException(std::string("SPA Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3586 
3587  if (!l_Write("SPA,>EEP"))
3588  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3589  }
3590  catch (CMFC3045InsException & rE)
3591  {
3593  MTL_Unused(rE)
3594  return false;
3595  }
3596  return true;
3597 }
3598 
3599 // Read register SPA (Settings of Probe Array). Command [SPA]
3600 // Read probe array settings parameters and calibration probe table from the probe array EEPROM.
3601 bool CMFC3045Instrument::ProbeArrayEepromRead(std::vector<char> & rEEPROMContent)
3602 {
3603  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3604  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3605 
3606  try {
3607  if (eAdvancedMode::kNone == m_AdvancedMode)
3608  throw CMFC3045InsException(std::string("SPA Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3609 
3610  if (!l_Write("SPA"))
3611  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3612  if (!l_ReadNCharNoTerm(m_ReadBuffer, PA_EEPROM_CHARSIZE + CHECKSUM_CHARSIZE))
3613  throw CMFC3045InsException(std::string("Read failed Probe Array EEPROM in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3614 
3615  rEEPROMContent.assign(m_ReadBuffer.begin(), m_ReadBuffer.end());
3616  }
3617  catch (CMFC3045InsException & rE)
3618  {
3620  MTL_Unused(rE)
3621  return false;
3622  }
3623  return true;
3624 }
3625 
3626 // Write register CPS (Calibration Probe Selection). Command [CPS,x], with x = a probe number
3627 // Fill main unit RAM calibration measurement table with a probe measurement.
3628 // After a measurement, copy the measurement of a selected probe to the main unit RAM probe measurement table (without correction) used for calibration.
3630 {
3631  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3632  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3633 
3634  try {
3635  std::string l_Command("CPS,");
3636  U8 l_PaProbeNumber(0);
3637 
3638  if (eAdvancedMode::kNone == m_AdvancedMode)
3639  throw CMFC3045InsException(std::string("CPS Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3640  if(!NumberProbesGet(l_PaProbeNumber))
3641  throw CMFC3045InsException(std::string("Failed Get PA Probes Number in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3642  if ((rProbeSel == 0) || (rProbeSel > m_NbProbesInPA))
3643  throw CMFC3045InsException(std::string("Failed, CPS probe target out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3644  l_Command += std::to_string(rProbeSel);
3645  if (!l_Write(l_Command))
3646  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3647  }
3648  catch (CMFC3045InsException & rE)
3649  {
3651  MTL_Unused(rE)
3652  return false;
3653  }
3654  return true;
3655 }
3656 
3657 // Write register CPS (Calibration Probe Selection). Command [CPS,0]
3658 // Clear all main unit RAM probe measurement table (without correction) used for calibration.
3660 {
3661  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3662  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3663 
3664  try {
3665  if (eAdvancedMode::kNone == m_AdvancedMode)
3666  throw CMFC3045InsException(std::string("CPS Clear Table not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3667  if (!l_Write("CPS,0"))
3668  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3669  }
3670  catch (CMFC3045InsException & rE)
3671  {
3673  MTL_Unused(rE)
3674  return false;
3675  }
3676  return true;
3677 }
3678 
3679 // Read register CPS (Calibration Probe Selection). Command [CPS]
3680 // Get from main unit RAM the whole calibration probe measurement table (without correction) in dHz.
3681 // Block mode must be 1 (kAllDecimal). NbMeasurement must be = NbProbes in PA
3682 // Data[0] is the first probe measurement. Data[n] is the measurement of probe n.
3683 bool CMFC3045Instrument::CalibrationProbeMeasurementTableGet(const U8 & rNbMeasurements, std::vector<U32> & rData)
3684 {
3685  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3686  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3687  rData.clear();
3688  try {
3689  U8 l_PaProbeNumber(0);
3690  if (eAdvancedMode::kNone == m_AdvancedMode)
3691  throw CMFC3045InsException(std::string("CPS Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3692  if (!NumberProbesGet(l_PaProbeNumber))
3693  throw CMFC3045InsException(std::string("Failed Get PA Probes Number in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3694  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
3695  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3696  rData.resize(rNbMeasurements);
3697  if (!l_ReadMeasurementTableBlock("CPS", rData))
3698  throw CMFC3045InsException(std::string("Fail to read Calibration measurement block in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3699  }
3700  catch (CMFC3045InsException & rE)
3701  {
3703  MTL_Unused(rE)
3704  return false;
3705  }
3706  return true;
3707 }
3708 
3709 // Write register CPS (Calibration Probe Selection). Command [CPS,x], with x > number of probes in PA
3710 // Compute and get the average (in dHz) of the calibration probe measurement table (RAM measurement table without correction).
3712 {
3713  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3714  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3715 
3716  try {
3717  std::string l_Command("CPS,");
3718  std::string l_RdStr;
3719  if (eAdvancedMode::kNone == m_AdvancedMode)
3720  throw CMFC3045InsException(std::string("CPS Set not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3721  l_Command += std::to_string(NPR_MAX + 1);
3722  if (!l_Write(l_Command)) // send parameter value > than NPR
3723  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3724  if (!l_ReadString(l_RdStr))
3725  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3726  rData = static_cast<U32>(std::stoul(l_RdStr));
3727  }
3728  catch (CMFC3045InsException & rE)
3729  {
3731  MTL_Unused(rE)
3732  return false;
3733  }
3734  return true;
3735 }
3736 
3737 // Write register CBT (Calibration Build Table). Command {CBT,-1}
3738 // Copy the calibration correction table from the probe array EEPROM to the main unit RAM table.
3740 {
3741  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3742  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3743 
3744  try {
3745  if (eAdvancedMode::k2 != m_AdvancedMode)
3746  throw CMFC3045InsException(std::string("CBT Table Copy not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3747  if (!l_Write("CBT,-1"))
3748  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3749  }
3750  catch (CMFC3045InsException & rE)
3751  {
3753  MTL_Unused(rE)
3754  return false;
3755  }
3756  return true;
3757 }
3758 
3759 // Write register CBT (Calibration Build Table). Command {CBT,0}
3760 // Clear in main unit RAM the calibration correction table.
3762 {
3763  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3764  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3765 
3766  try {
3767  if (eAdvancedMode::k2 != m_AdvancedMode)
3768  throw CMFC3045InsException(std::string("CBT Table Clear not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3769  if (!l_Write("CBT,0"))
3770  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3771  }
3772  catch (CMFC3045InsException & rE)
3773  {
3775  MTL_Unused(rE)
3776  return false;
3777  }
3778  return true;
3779 }
3780 
3781 // Write register CBT (Calibration Build Table). Command {CBT,x}, with x > number of probes in PA
3782 // Set the target value (in dHz) and create the calibration correction table from the difference between the target and the measurement table (previously filled).
3783 // rTarget must be bigger than number of probes in the probe-array
3784 // The correction table will be store in main-unit RAM. To store it permanently in the probe-array EEPROM, call the ProbeArrayEepromWrite() method after it.
3786 {
3787  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3788  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3789 
3790  try {
3791  std::string l_Command("CBT,");
3792  U8 l_PaProbeNumber(0);
3793 
3794  if (eAdvancedMode::k2 != m_AdvancedMode)
3795  throw CMFC3045InsException(std::string("CBT Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3796  if (!NumberProbesGet(l_PaProbeNumber))
3797  throw CMFC3045InsException(std::string("Failed: Get PA Probes Number in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3798  if (rTarget <= m_NbProbesInPA)
3799  throw CMFC3045InsException(std::string("Failed: CBT target out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3800  l_Command += std::to_string(rTarget);
3801  if (!l_Write(l_Command))
3802  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3803  }
3804  catch (CMFC3045InsException & rE)
3805  {
3807  MTL_Unused(rE)
3808  return false;
3809  }
3810  return true;
3811 }
3812 
3813 // Read register CBT (Calibration Build Table). Command [CBT]
3814 // Get all calibration correction table. The stored values, are the corrections in dHz to apply to each probe measurement to be normalized to the target value.
3815 // Data[0] is the first probe correction. Data[n] is the n probe correction.
3816 // Block mode must be 1 (kAllDecimal)
3817 // rData.size must be = NbProbes
3818 bool CMFC3045Instrument::CalibrationBuildTableGet(const U8 & rNbMeasurements, std::vector<I32> & rData)
3819 {
3820  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3821  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3822  rData.clear();
3823  try {
3824  U8 l_PaProbeNumber(0);
3825 
3826  if (!NumberProbesGet(l_PaProbeNumber)) // update and read m_NbProbesInPA
3827  throw CMFC3045InsException(std::string("Failed Get PA Probes Number in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3828  if ((0 == rNbMeasurements) || (rNbMeasurements < m_NbProbesInPA) || (NPR_MAX < rNbMeasurements))
3829  throw CMFC3045InsException(std::string("Failed. Vector size out of range to store received data.") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3830  if (eAdvancedMode::kNone == m_AdvancedMode)
3831  throw CMFC3045InsException(std::string("CBT Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3832  if (eDataBlockMode::kAllDecimal != m_DataBlockMode)
3833  throw CMFC3045InsException(std::string("Failed. Wrong Block mode. Block mode must be 1 in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3834  if (!l_Write("CBT"))
3835  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3836 
3837  rData.resize(rNbMeasurements);
3838  std::string l_RdStr;
3839  for (size_t i = 0; i < rData.size(); i++)
3840  {
3841  if (!l_ReadString(l_RdStr))
3842  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3843  rData[i] = static_cast<I32>(std::stoul(l_RdStr));
3844  }
3845  // Read the End of transmission block char after the last data in block
3846  if(!l_ReadEndTransmissionBlockChar())
3847  throw CMFC3045InsException(std::string("Read failed ETB char in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3848  }
3849  catch (CMFC3045InsException & rE)
3850  {
3852  MTL_Unused(rE)
3853  return false;
3854  }
3855  return true;
3856 }
3857 
3858 // Read register CBT (Calibration Build Table). Command [CBT,r], with r = a valid probe unmber
3859 // Get correction value (dHz) for a specific probe; (read a correction in main-unit RAM correction table)
3860 // This method set as well a pointer to the correction table for a CET command
3861 bool CMFC3045Instrument::CalibrationBuildProbeGet(I32 & rData, const U8 & rProbeSel)
3862 {
3863  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3864  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3865 
3866  try {
3867  std::string l_Command("CBT,");
3868  U8 l_PaProbeNumber(0);
3869  std::string l_RdStr;
3870 
3871  if (eAdvancedMode::kNone == m_AdvancedMode)
3872  throw CMFC3045InsException(std::string("CBT Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3873  if (!NumberProbesGet(l_PaProbeNumber))
3874  throw CMFC3045InsException(std::string("Failed: Get PA Probes Number in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3875  if ((rProbeSel == 0) || (rProbeSel > m_NbProbesInPA))
3876  throw CMFC3045InsException(std::string("Failed, CBT target out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3877  l_Command += std::to_string(rProbeSel);
3878  if (!l_Write(l_Command))
3879  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3880  if (!l_ReadString(l_RdStr))
3881  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3882  rData = static_cast<I32>(std::stoul(l_RdStr));
3883  }
3884  catch (CMFC3045InsException & rE)
3885  {
3887  MTL_Unused(rE)
3888  return false;
3889  }
3890  return true;
3891 }
3892 
3893 // Write register CET (Calibration Edit Table). Command {CET,x}, with x = correction value in dHz
3894 // Set a correction value in dHz for a specific probe in the calibration correction table (in RAM). Correction value must be in range [-37768, 37767]
3895 // The CalibrationBuildProbeGet() method must be called before to set a pointer to the desired probe in the correction table.
3896 // The correction will be store in Main-Unit RAM. To Store it permanently in the Probe-Array EEPROM, call the ProbeArrayEepromWrite() method after it.
3898 {
3899  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3900  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3901 
3902  try {
3903  if ((rData < CORRECT_POBE_MIN_DHZ) || (rData > CORRECT_POBE_MAX_DHZ))
3904  throw CMFC3045InsException(std::string("Failed, Correction value is out of Range in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3905  std::string l_Command("CET,");
3906 
3907  if (eAdvancedMode::k2 != m_AdvancedMode)
3908  throw CMFC3045InsException(std::string("Failed, CET Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3909  l_Command += std::to_string(rData);
3910  if (!l_Write(l_Command))
3911  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3912  }
3913  catch (CMFC3045InsException & rE)
3914  {
3916  MTL_Unused(rE)
3917  return false;
3918  }
3919  return true;
3920 }
3921 
3922 // Write register CET (Calibration Edit Table). Command {CET,x}, with x = correction value in dHz
3923 // Set a correction value in dHz for a specific probe in the calibration correction table (in RAM). Correction value must be in range [-37768, 37767]
3924 // The CalibrationBuildProbeGet() is called in this to set a pointer to the desired probe in the correction table.
3925 // The correction will be store in Main-Unit RAM. To Store it permanently in the Probe-Array EEPROM, call the ProbeArrayEepromWrite() method after it.
3926 bool CMFC3045Instrument::CalibrationEditTableSet(const I32 & rData, const U8 & rProbeSel)
3927 {
3928  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3929  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3930 
3931  try {
3932  U8 l_probeIdxCET(0);
3933  I32 l_Correction(0);
3934 
3935  if(!CalibrationBuildProbeGet(l_Correction,rProbeSel)) // Read the correction value of a probe in the table to set the CET pointer at the correct position
3936  throw CMFC3045InsException(std::string("Fail to set pointer to the desired probe with CBT,r cmd in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3937 
3938  if(!CalibrationEditTableGetProbePointed(l_probeIdxCET)) // Read probe number pointed in table
3939  throw CMFC3045InsException(std::string("Failed with read CET cmd in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3940  if (l_probeIdxCET != rProbeSel)
3941  throw CMFC3045InsException(std::string("Failed, CET not at the deisred probe position in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3942  if(!CalibrationEditTableSet(rData)) // write the new correction value for the desired probe
3943  throw CMFC3045InsException(std::string("Fail to edit Correction table for this probe in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3944  }
3945  catch (CMFC3045InsException & rE)
3946  {
3948  MTL_Unused(rE)
3949  return false;
3950  }
3951  return true;
3952 
3953 }
3954 
3955 // Read register CET (Calibration Edit Table). Command [CET]
3956 // Get probe number pointed by CET (This allows to verify the probe position in table to be correct before edition).(Manual info is wrong!)
3958 {
3959  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3960  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3961 
3962  try {
3963  std::string l_RdStr;
3964  if (eAdvancedMode::kNone == m_AdvancedMode)
3965  throw CMFC3045InsException(std::string("CET Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3966  if (!l_Write("CET"))
3967  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3968  if (!l_ReadString(l_RdStr))
3969  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3970  rProbeIdxCET = static_cast<U8>(std::stoul(l_RdStr));
3971  }
3972  catch (CMFC3045InsException & rE)
3973  {
3975  MTL_Unused(rE)
3976  return false;
3977  }
3978  return true;
3979 }
3980 
3981 // Write register CDP (Calibration Date of Probe Array). Command {CDP,d}, with d = date in decimal format ddmmyy
3982 // Set probe array calibration date (in string format ddmmyy )
3983 // This method saves permanently the calibration date in PA-EEPROM
3984 bool CMFC3045Instrument::CalibrationDatePASet(const U8 & rDayDD, const U8 & rMonthMM, const U8 & rYearYY, const bool & rSaveInEeprom)
3985 {
3986  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
3987  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
3988 
3989  try {
3990  std::ostringstream l_StringFormated;
3991  std::string l_Command("CDP,");
3992 
3993  if (eAdvancedMode::k2 != m_AdvancedMode)
3994  throw CMFC3045InsException(std::string("CDP Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3995 
3996  if(rDayDD < 1 || rDayDD >31)
3997  throw CMFC3045InsException(std::string("CDP Set not allowed. Wrong input Day format. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
3998  l_StringFormated << std::setw(2) << std::setfill('0') << std::to_string(rDayDD);
3999 
4000  if (rMonthMM < 1 || rMonthMM > 12)
4001  throw CMFC3045InsException(std::string("CDP Set not allowed. Wrong input Month format. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4002  l_StringFormated << std::setw(2) << std::setfill('0') << std::to_string(rMonthMM);
4003 
4004  if (rYearYY > 99)
4005  throw CMFC3045InsException(std::string("CDP Set not allowed. Wrong input Year format. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4006  l_StringFormated << std::setw(2) << std::setfill('0') << std::to_string(rYearYY);
4007  l_Command += l_StringFormated.str();
4008 
4009  if (!l_Write(l_Command))
4010  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4011  if(rSaveInEeprom)
4012  {
4013  if(!ProbeArrayEepromWrite()) // save Calibration date in PA EEPROM
4014  throw CMFC3045InsException(std::string("Fail to save in PA EEPROM in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4015  }
4016  }
4017  catch (CMFC3045InsException & rE)
4018  {
4020  MTL_Unused(rE)
4021  return false;
4022  }
4023  return true;
4024 }
4025 
4026 // Write register CDP (Calibration Date of Probe Array). Command {CDP,d}, with d = date in decimal format ddmmyy
4027 // Set probe array calibration date from an UTC date format (in second since 1970)
4028 // This method saves permanently the calibration date in probe array EEPROM
4029 bool CMFC3045Instrument::CalibrationDatePASet(const std::time_t & rUtcDate, const bool & rSaveInEeprom)
4030 {
4031  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
4032  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
4033 
4034  try {
4035  std::string l_Command("CDP,");
4036  std::string l_StrDate("");
4037 
4038  if (eAdvancedMode::k2 != m_AdvancedMode)
4039  throw CMFC3045InsException(std::string("CDP Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4040 
4041  if (!l_DateTimeToDateStrUtc(rUtcDate, l_StrDate)) //convert UTC time_t format to string date format
4042  throw CMFC3045InsException("Fail to convert date from UTC time_t format", MTL__LOCATION__);
4043  l_Command += l_StrDate;
4044 
4045  if (!l_Write(l_Command))
4046  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4047  if(rSaveInEeprom)
4048  {
4049  if (!ProbeArrayEepromWrite()) // save Calibration date in PA EEPROM
4050  throw CMFC3045InsException(std::string("Fail to save in PA EEPROM in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4051  }
4052  }
4053  catch (CMFC3045InsException & rE)
4054  {
4056  MTL_Unused(rE)
4057  return false;
4058  }
4059  return true;
4060 }
4061 
4062 // Read register CDP (Calibration Date of Probe Array). Command [CDP]
4063 // Get probe array calibration date. Get string as date (local time) format "dd/mm/yy", and get a time_t (at UTC) date format in second since 1970 UTC
4064 bool CMFC3045Instrument::CalibrationDatePAGet(std::string & rStrDate, std::time_t & rUtcDate)
4065 {
4066  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
4067  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
4068 
4069  try {
4070  if (eAdvancedMode::kNone == m_AdvancedMode)
4071  throw CMFC3045InsException(std::string("CDP Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4072  if (!l_Write("CDP"))
4073  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4074  if (!l_ReadString(rStrDate))
4075  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4076 
4077  if (!l_DateStrToDateTimeUtc(rStrDate, rUtcDate)) //convert string date (UTC) format to time_t UTC
4078  throw CMFC3045InsException("Fail to convert UTC string date in time_t format", MTL__LOCATION__);
4079  }
4080  catch (CMFC3045InsException & rE)
4081  {
4083  MTL_Unused(rE)
4084  rStrDate.clear();
4085  rUtcDate = -1;
4086  return false;
4087  }
4088  return true;
4089 }
4090 
4091 // Write register CDU (Calibration Date of main Unit). Command {CDU,d}, with d = date in decimal format ddmmyy
4092 // Set main unit calibration date (in string format ddmmyy )
4093 // This method saves permanently the calibration date in main unit EEPROM
4094 bool CMFC3045Instrument::CalibrationDateMUSet(const U8 & rDayDD, const U8 & rMonthMM, const U8 & rYearYY, const bool & rSaveInEeprom)
4095 {
4096  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
4097  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
4098 
4099  try {
4100  std::ostringstream l_StringFormated;
4101  std::string l_Command("CDU,");
4102 
4103  if (eAdvancedMode::k2 != m_AdvancedMode)
4104  throw CMFC3045InsException(std::string("CDU Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4105 
4106  if (rDayDD < 1 || rDayDD >31)
4107  throw CMFC3045InsException(std::string("CDU Set not allowed. Wrong input Date format. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4108  l_StringFormated << std::setw(2) << std::setfill('0') << std::to_string(rDayDD); //left padding with 0
4109 
4110 
4111  if (rMonthMM < 1 || rMonthMM > 12)
4112  throw CMFC3045InsException(std::string("CDU Set not allowed. Wrong input Date format. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4113  l_StringFormated << std::setw(2) << std::setfill('0') << std::to_string(rMonthMM); //left padding with 0
4114 
4115 
4116  if (rYearYY > 99)
4117  throw CMFC3045InsException(std::string("CDU Set not allowed. Wrong input Date format. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4118  l_StringFormated << std::setw(2) << std::setfill('0') << std::to_string(rYearYY); //left padding with 0
4119  l_Command += l_StringFormated.str();
4120 
4121  if (!l_Write(l_Command))
4122  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4123  if(rSaveInEeprom)
4124  {
4125  if (!MainUnitEepromWrite()) // save Calibration date in the Main-Unit EEPROM
4126  throw CMFC3045InsException(std::string("Fail to save in MU EEPROM in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4127  }
4128  }
4129  catch (CMFC3045InsException & rE)
4130  {
4132  MTL_Unused(rE)
4133  return false;
4134  }
4135  return true;
4136 }
4137 
4138 // Write register CDU (Calibration Date of main Unit). Command {CDU,d}, with d = date in decimal format ddmmyy
4139 // Set main unit calibration date from an UTC date format (in second since 1970)
4140 // This method saves permanently the calibration date in main unit-EEPROM
4141 bool CMFC3045Instrument::CalibrationDateMUSet(const std::time_t & rUtcDate, const bool & rSaveInEeprom)
4142 {
4143  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
4144  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
4145 
4146  try {
4147  std::string l_Command("CDU,");
4148  std::string l_StrDate("");
4149 
4150  if (eAdvancedMode::k2 != m_AdvancedMode)
4151  throw CMFC3045InsException(std::string("CDU Set not allowed. Advance mode < 2 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4152 
4153  if (!l_DateTimeToDateStrUtc(rUtcDate, l_StrDate)) //convert UTC time_t format to string date format
4154  throw CMFC3045InsException("Fail to convert date from UTC time_t format", MTL__LOCATION__);
4155  l_Command += l_StrDate;
4156 
4157  if (!l_Write(l_Command))
4158  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4159  if(rSaveInEeprom)
4160  {
4161  if (!MainUnitEepromWrite()) // save Calibration date in the Main-Unit EEPROM
4162  throw CMFC3045InsException(std::string("Fail to save in MU EEPROM in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4163  }
4164  }
4165  catch (CMFC3045InsException & rE)
4166  {
4168  MTL_Unused(rE)
4169  return false;
4170  }
4171  return true;
4172 }
4173 
4174 // Read register CDU (Calibration Date of main Unit). Command [CDU]
4175 // Get main unit calibration date. Returned string date format is "dd/mm/yy", UTC date format is in second since 1970
4176 bool CMFC3045Instrument::CalibrationDateMUGet(std::string & rStrDate, std::time_t & rUtcDate)
4177 {
4178  MTL_INSTRUMENT_MFC3045_DEBUG_COUT(MTL__FUNCTION_NAME__ << std::endl);
4179  CLockGuard<CRecursiveMutex> l_LockGuard(m_Lock);
4180 
4181  try {
4182  if (eAdvancedMode::kNone == m_AdvancedMode)
4183  throw CMFC3045InsException(std::string("CDU Get not allowed. Advance mode < 1 in MFC3045. ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4184  if (!l_Write("CDU"))
4185  throw CMFC3045InsException(std::string("Write failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4186  if (!l_ReadString(rStrDate))
4187  throw CMFC3045InsException(std::string("Read failed in ") + MTL__FUNCTION_NAME__, MTL__LOCATION__);
4188 
4189  if (!l_DateStrToDateTimeUtc(rStrDate, rUtcDate)) //convert string date UTC format to time_t UTC
4190  throw CMFC3045InsException("Fail to convert date string in UTC format", MTL__LOCATION__);
4191  }
4192  catch (CMFC3045InsException & rE)
4193  {
4195  MTL_Unused(rE)
4196  rStrDate.clear();
4197  rUtcDate = -1;
4198  return false;
4199  }
4200  return true;
4201 }
4202 
4203 
MTL::Instrument::CMFC3045Instrument::PaLowestFreqSet
bool PaLowestFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:3300
MTL::Instrument::eSerialBaudrate::k2400
@ k2400
FSW_DFF_MAX
#define FSW_DFF_MAX
Definition: MFC3045Types.h:17
MTL::Instrument::CMFC3045Instrument::SMAGet
bool SMAGet(U8 &rRegVal)
Definition: MFC3045.cpp:1487
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::DNRB
U8 DNRB
Definition: MFC3045Types.h:211
MTL::Instrument::eSerialParity::kOdd
@ kOdd
MTL::Instrument::CMFC3045Instrument::CheckInstrumentConnection
bool CheckInstrumentConnection(const U8 &rl_Retry=3)
Definition: MFC3045.cpp:505
MTL::Instrument::CVISAInstrument::ConfigSerialPort
bool ConfigSerialPort(const sSerialPortSettings &rPortSettings)
Definition: VISAInstrument.cpp:765
SMA_DR
#define SMA_DR
Definition: MFC3045.cpp:55
MTL::Instrument::CMFC3045Instrument::ModulationPeriodGet
bool ModulationPeriodGet(U16 &rRegVal)
Definition: MFC3045.cpp:1874
MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte::PSHE
U8 PSHE
Definition: MFC3045Types.h:251
MTL_INSTRUMENT_MFC3045_DEBUG_CERR
#define MTL_INSTRUMENT_MFC3045_DEBUG_CERR(__X__)
Definition: MFC3045.cpp:45
MTL::Instrument::MFC3045Types::uRSPByte::RSPByte
struct MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte RSPByte
MTL::Instrument::CMFC3045Instrument::DataStdDeviationGet
bool DataStdDeviationGet(const U8 &rNbMeasurements, std::vector< U32 > &rData)
Definition: MFC3045.cpp:2919
MTL::Instrument::CVISABuffer::clear
void clear()
Definition: VISAInstrumentBuffer.h:61
MTL::Instrument::CMFC3045Instrument::ModulationReferenceGet
bool ModulationReferenceGet(eModulationRef &rRegVal)
Definition: MFC3045.cpp:1803
MTL::Instrument::CMFC3045Instrument::CalibrationProbeMeasurementTableClear
bool CalibrationProbeMeasurementTableClear()
Definition: MFC3045.cpp:3659
MTL::Instrument::sSerialPortSettings::Handshake
eSerialHandshake Handshake
Definition: VISAInstrumentTypes.h:178
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableClearRAM
bool CalibrationBuildTableClearRAM()
Definition: MFC3045.cpp:3761
MTL::Instrument::CMFC3045Instrument::CalibrationProbeMeasurementSet
bool CalibrationProbeMeasurementSet(const U8 &rProbeSel)
Definition: MFC3045.cpp:3629
MTL::Instrument::CMFC3045Instrument::SearchStartWithSMA
bool SearchStartWithSMA()
Definition: MFC3045.cpp:2571
MTL::Instrument::CMFC3045Instrument::NumberPreCycleGet
bool NumberPreCycleGet(U16 &rRegVal)
Definition: MFC3045.cpp:2084
MTL::Instrument::CMFC3045Instrument::CMFC3045Instrument
CMFC3045Instrument(CVISAResourceManager &rRM, tResourceName Rsrc)
Constructors / destructors.
Definition: MFC3045.cpp:481
CHECKSUM_CHARSIZE
#define CHECKSUM_CHARSIZE
Definition: MFC3045Types.h:43
MTL::Instrument::CVISAInstrument::GetAttribute
bool GetAttribute(ViAttr Attribute, void *Value)
Definition: VISAInstrument.cpp:695
MTL::Instrument::sSerialPortSettings::ReadTermMode
eSerialTermMode ReadTermMode
Definition: VISAInstrumentTypes.h:179
MTL::Instrument::CMFC3045Instrument::PaCentralFreqGet
bool PaCentralFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:3276
MTL::Instrument::eSerialDataBits::k8
@ k8
MTL::Instrument::CVISAInstrument::Read
bool Read(CVISABuffer &rBuf, bool Append=false)
Definition: VISAInstrument.cpp:430
MTL::Instrument::CMFC3045Instrument::RfHarmonicGet
bool RfHarmonicGet(eRFH &rRegVal)
Definition: MFC3045.cpp:3428
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::Instrument::CMFC3045Instrument::RejectionGapGet
bool RejectionGapGet(U16 &rRegVal)
Definition: MFC3045.cpp:2246
MU_EEPROM_CHARSIZE
#define MU_EEPROM_CHARSIZE
Definition: MFC3045Types.h:42
MTL::Instrument::MFC3045Types::eModulationRef
eModulationRef
Definition: MFC3045Types.h:58
SMA_UP
#define SMA_UP
Definition: MFC3045.cpp:49
SMA_RS
#define SMA_RS
Definition: MFC3045.cpp:52
MTL::Instrument::sSerialPortSettings::Baudrate
eSerialBaudrate Baudrate
Definition: VISAInstrumentTypes.h:174
MTL::Instrument::CMFC3045Instrument::MeasStartWithSMA
bool MeasStartWithSMA()
Definition: MFC3045.cpp:2385
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::DRST1
U8 DRST1
Definition: MFC3045Types.h:206
MTL::Instrument::eSerialParity::kEven
@ kEven
MTL::Instrument::CMFC3045Instrument::NumberPreCycleSet
bool NumberPreCycleSet(const U16 &rRegVal)
Definition: MFC3045.cpp:2056
MTL::Instrument::CMFC3045Instrument::DdsBitResolutionFdhzGet
bool DdsBitResolutionFdhzGet(F32 &rDdsResolutionFdhz)
Definition: MFC3045.cpp:1977
MTL::Instrument::CMFC3045Instrument::CalibrationProbeMeasurementTableGet
bool CalibrationProbeMeasurementTableGet(const U8 &rNbMeasurements, std::vector< U32 > &rData)
Definition: MFC3045.cpp:3683
MTL::Instrument::eSerialHandshake::kHardware
@ kHardware
DATA_END_ETB
#define DATA_END_ETB
Definition: MFC3045Types.h:37
MTL::Instrument::MFC3045Types::eRemoteBusyLed
eRemoteBusyLed
Definition: MFC3045Types.h:299
MTL::Instrument::CMFC3045Instrument::DataHighestFrequencyGet
bool DataHighestFrequencyGet(U32 &rData)
Definition: MFC3045.cpp:3137
MDA_MAX
#define MDA_MAX
Definition: MFC3045Types.h:19
MTL::Instrument::CMFC3045Instrument::NumberProbesGet
bool NumberProbesGet(U8 &rRegVal)
Definition: MFC3045.cpp:3223
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::MFC3045Types::eShiftFreq
eShiftFreq
Definition: MFC3045Types.h:321
MTL::Instrument::CMFC3045Instrument::DataCentralFrequencyGet
bool DataCentralFrequencyGet(U32 &rData)
Definition: MFC3045.cpp:3083
date::parse
auto parse(const std::basic_string< CharT, Traits, Alloc > &format, Parsable &tp) -> decltype(from_stream(std::declval< std::basic_istream< CharT, Traits > & >(), format.c_str(), tp), parse_manip< Parsable, CharT, Traits, Alloc >
Definition: date.h:7837
MTL::Instrument::CMFC3045Instrument::DataBlockModeDecimalSet
bool DataBlockModeDecimalSet()
Definition: MFC3045.cpp:2714
MTL::Instrument::CMFC3045Instrument::ModulationPeriodSet
bool ModulationPeriodSet(const U16 &rRegVal)
Definition: MFC3045.cpp:1846
SMA_CE
#define SMA_CE
Definition: MFC3045.cpp:54
MTL::Instrument::CMFC3045Instrument::SetTimeoutRdNewDataMs
void SetTimeoutRdNewDataMs(const U32 &rNewdataTimeout_ms=RS_WAIT_DATARD_MS)
Definition: MFC3045.cpp:667
MTL::Instrument::MFC3045Types::eWhoVersion
eWhoVersion
Definition: MFC3045Types.h:281
MTL::Instrument::CMFC3045Instrument::DataLowestFrequencyGet
bool DataLowestFrequencyGet(U32 &rData)
Definition: MFC3045.cpp:3110
MTL_SleepMs
#define MTL_SleepMs(_ms_)
Definition: Helpers.h:46
NPT_MAX
#define NPT_MAX
Definition: MFC3045Types.h:27
MTL::Instrument::CMFC3045Instrument::TimeVsPrecisionSet
bool TimeVsPrecisionSet(const ePrecision &rRegVal)
Definition: MFC3045.cpp:2272
MTL::Instrument::sSerialPortSettings
Definition: VISAInstrumentTypes.h:173
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableWithTargetSet
bool CalibrationBuildTableWithTargetSet(const U32 &rTarget)
Definition: MFC3045.cpp:3785
MTL::Instrument::MFC3045Types::eWhoSerialNum
eWhoSerialNum
Definition: MFC3045Types.h:290
MTL::Instrument::eSerialTermMode::kEndNone
@ kEndNone
MTL::Instrument::CMFC3045Instrument::NmrThresholdGet
bool NmrThresholdGet(U8 &rRegVal)
Definition: MFC3045.cpp:3498
MTL::Instrument::CMFC3045Instrument::ModulationAmplitudeGet
bool ModulationAmplitudeGet(U32 &rRegVal)
Definition: MFC3045.cpp:1607
MTL::Instrument::CMFC3045Instrument::~CMFC3045Instrument
virtual ~CMFC3045Instrument()
Definition: MFC3045.cpp:494
MTL::Instrument::CVISABuffer::resize
void resize(size_t size)
Definition: VISAInstrumentBuffer.h:74
NCY_MIN
#define NCY_MIN
Definition: MFC3045Types.h:24
MTL::Instrument::CVISABuffer::begin
std::vector< MTL_VISA_BUFFER_TYPE >::iterator begin()
Definition: VISAInstrumentBuffer.h:99
MTL::Instrument::CVISAInstrument::SetTimeout
bool SetTimeout(ViUInt32 Timeout)
Definition: VISAInstrument.cpp:468
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableCopyEEPROMToRAM
bool CalibrationBuildTableCopyEEPROMToRAM()
Definition: MFC3045.cpp:3739
MTL::Instrument::CMFC3045Instrument::DataBlockModeGet
bool DataBlockModeGet(eDataBlockMode &rRegVal)
Definition: MFC3045.cpp:2740
MTL::Instrument::CMFC3045Instrument::MainUnitEepromWrite
bool MainUnitEepromWrite()
Definition: MFC3045.cpp:3527
MTL::Instrument::CMFC3045Instrument::ModulationAmplitudeSet
bool ModulationAmplitudeSet(const U32 &rRegVal)
Definition: MFC3045.cpp:1582
MTL::Instrument::CMFC3045Instrument::RemoteBusyLedGet
bool RemoteBusyLedGet(eRemoteBusyLed &rRemoteLed)
Definition: MFC3045.cpp:1172
MTL_INSTRUMENT_MFC3045_DEBUG_COUT
#define MTL_INSTRUMENT_MFC3045_DEBUG_COUT(__X__)
Definition: MFC3045.cpp:44
RSO_MAX
#define RSO_MAX
Definition: MFC3045Types.h:29
MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte::PRBR
U8 PRBR
Definition: MFC3045Types.h:255
MTL::Instrument::CMFC3045Instrument::DisconnectInstrument
bool DisconnectInstrument()
Definition: MFC3045.cpp:606
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::EEST1
U8 EEST1
Definition: MFC3045Types.h:210
MTL::Instrument::MFC3045Types::uRSPByte
Definition: MFC3045Types.h:243
MTL::Instrument::CMFC3045Instrument::CalibrationEditTableGetProbePointed
bool CalibrationEditTableGetProbePointed(U8 &rProbeIdxCET)
Definition: MFC3045.cpp:3957
MTL::Instrument::CVISAInstrument::m_Lock
CRecursiveMutex m_Lock
Definition: VISAInstrument.h:63
MTL::Instrument::CMFC3045Instrument::DisableSMA
bool DisableSMA()
Definition: MFC3045.cpp:1514
NPR_MAX
#define NPR_MAX
Definition: MFC3045Types.h:32
MTL::Instrument::MFC3045Types::eSweepFreqMode
eSweepFreqMode
Definition: MFC3045Types.h:311
SMA_EE
#define SMA_EE
Definition: MFC3045.cpp:51
MTL::Instrument::MFC3045Types::eAdvancedMode
eAdvancedMode
Definition: MFC3045Types.h:272
MTL::Instrument::CMFC3045Instrument::DdsFrequencyGet
bool DdsFrequencyGet(U32 &rRegVal)
Definition: MFC3045.cpp:1251
MTL::Instrument::CMFC3045Instrument::TimePreCycleSet
bool TimePreCycleSet(const U16 &rRegVal)
Definition: MFC3045.cpp:2110
MTL::Instrument::CMFC3045Instrument::Abort
bool Abort()
Definition: MFC3045.cpp:626
Helpers.h
Collection of utility macros for error messages.
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::Instrument::MFC3045Types::eRFH
eRFH
Definition: MFC3045Types.h:221
MTL_Assert
#define MTL_Assert
Definition: Helpers.h:44
MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte::PHHE
U8 PHHE
Definition: MFC3045Types.h:252
MTL::Instrument::CVISAInstrument::LockExclusive
bool LockExclusive(ViUInt32 Timeout)
Definition: VISAInstrument.cpp:557
MTL::Instrument::MFC3045Types::eStatusRegister
eStatusRegister
Definition: MFC3045Types.h:87
MTL::Instrument::CMFC3045Instrument::CalibrationEditTableSet
bool CalibrationEditTableSet(const I32 &rData)
Definition: MFC3045.cpp:3897
MTL::Instrument::CMFC3045Instrument::ContinuousMeasStart
bool ContinuousMeasStart()
Definition: MFC3045.cpp:2646
MTL::Instrument::CMFC3045Instrument::RfHarmonicSet
bool RfHarmonicSet(const eRFH &rRegVal)
Definition: MFC3045.cpp:3402
MTL::Instrument::CMFC3045Instrument::DdsBitResolutionGet
bool DdsBitResolutionGet(U32 &rRegVal)
Definition: MFC3045.cpp:1950
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::MEST1
U8 MEST1
Definition: MFC3045Types.h:208
MTL::Instrument::CMFC3045Instrument::NumberMeasCycleSet
bool NumberMeasCycleSet(const U16 &rRegVal)
Definition: MFC3045.cpp:2006
MTL::Instrument::CMFC3045Instrument::SystemResetSet
bool SystemResetSet()
Definition: MFC3045.cpp:1005
MTL::Instrument::CMFC3045Instrument::ModulationCentralFreqSet
bool ModulationCentralFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:1631
date.h
MTL::Instrument::CMFC3045Instrument::ModulationHighestFreqGet
bool ModulationHighestFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:1755
MTL::Instrument::CVISAInstrument::Write
bool Write(const char *Str)
Definition: VISAInstrument.cpp:393
MTL::Instrument::CMFC3045Instrument::ModulationHighestFreqSet
bool ModulationHighestFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:1730
SMA_DN
#define SMA_DN
Definition: MFC3045.cpp:50
MTL::Instrument
Definition: MFC3045.h:25
MTL::Instrument::eSerialDataBits::k7
@ k7
MTL::Instrument::CMFC3045Instrument::ModulationLowestFreqGet
bool ModulationLowestFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:1705
MTL::Instrument::CMFC3045Instrument::AdvancedCommandModeGet
bool AdvancedCommandModeGet(eAdvancedMode &rRegVal)
Definition: MFC3045.cpp:962
MTL::Instrument::CMFC3045Instrument::SerialNumberGet
bool SerialNumberGet(std::string &rSerialNum)
Definition: MFC3045.cpp:1100
MTL::Instrument::CVISAInstrument::Close
void Close()
Definition: VISAInstrument.cpp:356
MTL::Instrument::eSerialParity::kNone
@ kNone
MTL::Instrument::CMFC3045Instrument::CalibrationBuildTableGet
bool CalibrationBuildTableGet(const U8 &rNbMeasurements, std::vector< I32 > &rData)
Definition: MFC3045.cpp:3818
RS_RD_BUFF_DEFAULT_SIZE
#define RS_RD_BUFF_DEFAULT_SIZE
Definition: MFC3045Types.h:38
MTL::Instrument::CMFC3045Instrument::NumberProbesSet
bool NumberProbesSet(const U8 &rRegVal)
Definition: MFC3045.cpp:3194
MTL::Instrument::eSerialTermMode::kEndTermChar
@ kEndTermChar
MTL::Instrument::MFC3045Types::uRSPByte::RawRSPB
U16 RawRSPB
Definition: MFC3045Types.h:244
MTL::Instrument::CMFC3045Instrument::RejectionOffsetGet
bool RejectionOffsetGet(U16 &rRegVal)
Definition: MFC3045.cpp:2192
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::UPRB
U8 UPRB
Definition: MFC3045Types.h:212
MTL::Instrument::CMFC3045Instrument::GetCurrentTimeoutRdDataMs
void GetCurrentTimeoutRdDataMs(U32 &rRdDataTimeout_ms)
Definition: MFC3045.cpp:661
MTL::Instrument::eSerialBaudrate::k28800
@ k28800
MTL::Instrument::CVISABuffer::end
std::vector< MTL_VISA_BUFFER_TYPE >::iterator end()
Definition: VISAInstrumentBuffer.h:111
MTL::Instrument::CMFC3045Instrument::RemoteBusyLedSet
bool RemoteBusyLedSet(const eRemoteBusyLed &rRemoteLed)
Definition: MFC3045.cpp:1148
PA_FREQ_MIN_DHZ
#define PA_FREQ_MIN_DHZ
Definition: MFC3045Types.h:22
MTL::Instrument::MFC3045Types
Definition: MFC3045Types.h:53
MTL::Instrument::sSerialPortSettings::DataBits
eSerialDataBits DataBits
Definition: VISAInstrumentTypes.h:175
MTL::Instrument::CMFC3045Instrument::CalibrationMeasurementAverageProbeGet
bool CalibrationMeasurementAverageProbeGet(U32 &rData)
Definition: MFC3045.cpp:3711
MTL::Instrument::MFC3045Types::eDataBlockMode
eDataBlockMode
Definition: MFC3045Types.h:78
MTL::Instrument::CMFC3045Instrument::ConnectInstrument
bool ConnectInstrument(const sSerialPortSettings &rSerialSettings, const U32 &rInitialTimeout_ms=RS_RDWR_VISA_TIMEOUT_MS)
Definition: MFC3045.cpp:543
MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte::PPAE
U8 PPAE
Definition: MFC3045Types.h:250
MTL::Instrument::CMFC3045Instrument::ModulationCentralFreqGet
bool ModulationCentralFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:1656
MTL::Instrument::CMFC3045Instrument::CalibrationDateMUSet
bool CalibrationDateMUSet(const U8 &rDayDD, const U8 &rMonthMM, const U8 &rYearYY, const bool &rSaveInEeprom=false)
Definition: MFC3045.cpp:4094
RS_WAIT_DATARD_MS
#define RS_WAIT_DATARD_MS
Definition: MFC3045Types.h:40
RSO_MIN
#define RSO_MIN
Definition: MFC3045Types.h:28
MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte::PSB2
U8 PSB2
Definition: MFC3045Types.h:248
MTL::Instrument::CMFC3045Instrument::ModulationReferenceSet
bool ModulationReferenceSet(const eModulationRef &rRegVal)
Definition: MFC3045.cpp:1779
MTL::Instrument::CMFC3045Instrument::RejectionGapSet
bool RejectionGapSet(const U16 &rRegVal)
Definition: MFC3045.cpp:2218
MTL::Instrument::CMFC3045Instrument::StatusGet
bool StatusGet(const eStatusRegister &rStatRegSel, U8 &rStatus)
Definition: MFC3045.cpp:1350
MTL::Instrument::CVISAInstrument::Open
bool Open(eOpenAccessMode AccessMode=eOpenAccessMode::NoLock, ViUInt32 Timeout_ms=0)
Definition: VISAInstrument.cpp:335
MTL::Instrument::sSerialPortSettings::Parity
eSerialParity Parity
Definition: VISAInstrumentTypes.h:176
MFC3045.h
Interface definition for C++ API for Metrolab MFC3045.
MTL::Instrument::eSerialHandshake::kHardAndSoft
@ kHardAndSoft
NCY_MAX
#define NCY_MAX
Definition: MFC3045Types.h:25
MTL::Instrument::CMFC3045Instrument::ModulationNumberStepRampGet
bool ModulationNumberStepRampGet(U32 &rRegVal)
Definition: MFC3045.cpp:1898
MTL::Instrument::CMFC3045Instrument::CalibrationDateMUGet
bool CalibrationDateMUGet(std::string &rStrDate, std::time_t &rUtcDate)
Definition: MFC3045.cpp:4176
MTL::Instrument::CMFC3045Instrument::ParseParmFromRSP
bool ParseParmFromRSP(const U16 &rParmRSPSettings, sSerialPortSettings &rSerialSettings)
Definition: MFC3045.cpp:789
MTL::Instrument::CMFC3045Instrument::PaHighestFreqSet
bool PaHighestFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:3351
MTL::Instrument::MFC3045Types::uSMAByte
Definition: MFC3045Types.h:202
MTL::CException
Exception to be thrown.
Definition: Exception.h:16
MTL::Instrument::CMFC3045Instrument::DataDifferenceFrequencyGet
bool DataDifferenceFrequencyGet(U32 &rData)
Definition: MFC3045.cpp:3164
CMFC3045InsException
MTL::CException< CMFC3045Instrument > CMFC3045InsException
Definition: MFC3045.cpp:65
MTL::Instrument::CMFC3045Instrument::AdvancedCommandModeSet
bool AdvancedCommandModeSet(const eAdvancedMode &rRegVal)
Definition: MFC3045.cpp:936
MTL::CException::what
virtual const char * what() const noexcept
Return string describing what happened.
Definition: Exception.h:34
MTL::Instrument::CMFC3045Instrument::MainUnitEepromRead
bool MainUnitEepromRead(std::vector< char > &rEEPROMContent)
Definition: MFC3045.cpp:3550
MTL::Instrument::eSerialBaudrate::k57600
@ k57600
MTL::Instrument::CMFC3045Instrument::DdsFrequencySet
bool DdsFrequencySet(const U32 &rRegVal)
Definition: MFC3045.cpp:1223
MTL::Instrument::CMFC3045Instrument::TimeVsPrecisionGet
bool TimeVsPrecisionGet(ePrecision &rRegVal)
Definition: MFC3045.cpp:2295
MTL::Instrument::eSerialBaudrate::k4800
@ k4800
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::CEST1
U8 CEST1
Definition: MFC3045Types.h:207
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::Instrument::CMFC3045Instrument::NmrThresholdSet
bool NmrThresholdSet(const U8 &rRegVal)
Definition: MFC3045.cpp:3472
CORRECT_POBE_MAX_DHZ
#define CORRECT_POBE_MAX_DHZ
Definition: MFC3045Types.h:34
MDA_MIN
#define MDA_MIN
Definition: MFC3045Types.h:18
MOD_FREQ_MIN_DHZ
#define MOD_FREQ_MIN_DHZ
Definition: MFC3045Types.h:20
MTL::Instrument::eSerialHandshake::kNone
@ kNone
MTL::Instrument::tResourceName
std::string tResourceName
Definition: VISAInstrumentTypes.h:21
SMA_PA
#define SMA_PA
Definition: MFC3045.cpp:48
MFC_ASCII
#define MFC_ASCII
Definition: MFC3045Types.h:13
MTL::Instrument::CMFC3045Instrument::PaHighestFreqGet
bool PaHighestFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:3378
MTL::Instrument::CMFC3045Instrument::MeasCycleStart
bool MeasCycleStart()
Definition: MFC3045.cpp:2336
MTL::Instrument::MFC3045Types::eMFCSerialBDR
eMFCSerialBDR
Definition: MFC3045Types.h:231
MTL::Instrument::eSerialBaudrate::k38400
@ k38400
MTL::Instrument::eSerialHandshake::kXonXoff
@ kXonXoff
MTL::Instrument::CMFC3045Instrument::CalibrationDatePASet
bool CalibrationDatePASet(const U8 &rDayDD, const U8 &rMonthMM, const U8 &rYearYY, const bool &rSaveInEeprom=false)
Definition: MFC3045.cpp:3984
RSG_MIN
#define RSG_MIN
Definition: MFC3045Types.h:30
MTL::Instrument::CVISABuffer
Definition: VISAInstrumentBuffer.h:37
MTL::Instrument::MFC3045Types::eAdvancedMode::kNone
@ kNone
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::Instrument::MFC3045Types::uRSPByte::sRSPByte::PPAS
U8 PPAS
Definition: MFC3045Types.h:249
MTL::Instrument::MFC3045Types::uSMAByte::RawSMAB
U8 RawSMAB
Definition: MFC3045Types.h:203
MTL::Instrument::eSerialBaudrate::k115200
@ k115200
MTL::Instrument::sSerialPortSettings::ReadTermChar
char ReadTermChar
Definition: VISAInstrumentTypes.h:180
MTL::Instrument::MFC3045Types::eDataBlockMode::kOneByOne
@ kOneByOne
MTL::Instrument::MFC3045Types::ePrecision
ePrecision
Definition: MFC3045Types.h:69
MTL::Instrument::eSerialBaudrate::k9600
@ k9600
MTL::Instrument::CMFC3045Instrument::LastCmdErrorGet
bool LastCmdErrorGet(std::string &rCmdError)
Definition: MFC3045.cpp:1465
SMA_ME
#define SMA_ME
Definition: MFC3045.cpp:53
MTL::Instrument::CMFC3045Instrument::FrequencySweepSet
bool FrequencySweepSet(const eSweepFreqMode &rSweepMode, const U32 &rFreqStepVal=0)
Definition: MFC3045.cpp:1280
PA_EEPROM_CHARSIZE
#define PA_EEPROM_CHARSIZE
Definition: MFC3045Types.h:41
MTL::Instrument::CMFC3045Instrument::PaLowestFreqGet
bool PaLowestFreqGet(U32 &rRegVal)
Definition: MFC3045.cpp:3327
RSP_MAX
#define RSP_MAX
Definition: MFC3045Types.h:16
MTL::Instrument::eSerialStopBits::k2
@ k2
MTL::Instrument::CVISAInstrument::Status
const ViStatus & Status()
Definition: VISAInstrument.cpp:378
MTL::Instrument::CMFC3045Instrument::PaCentralFreqSet
bool PaCentralFreqSet(const U32 &rRegVal)
Definition: MFC3045.cpp:3249
MTL::Instrument::CMFC3045Instrument::FrequencySweepShiftSet
bool FrequencySweepShiftSet(const eShiftFreq &rShiftDirection)
Definition: MFC3045.cpp:1325
MTL::Instrument::CVISABuffer::data
MTL_VISA_BUFFER_TYPE * data() noexcept
Definition: VISAInstrumentBuffer.h:124
MTL::Instrument::MFC3045Types::uSMAByte::sSMAByte::RSST1
U8 RSST1
Definition: MFC3045Types.h:209
MTL::Instrument::CMFC3045Instrument::ReadWithCustomCmd
bool ReadWithCustomCmd(const std::string &rCommandStr, std::string &rRegValStr)
Definition: MFC3045.cpp:640
RSG_MAX
#define RSG_MAX
Definition: MFC3045Types.h:31
MOD_FREQ_MAX_DHZ
#define MOD_FREQ_MAX_DHZ
Definition: MFC3045Types.h:21
MTL::Instrument::CMFC3045Instrument::BreakMeasSet
bool BreakMeasSet()
Definition: MFC3045.cpp:2666
MTL::Synchronization::CLockGuard
Lock.
Definition: Synchronization.h:62
OSDefines.h
Platform Dependent Definitions.
MTL::Instrument::MFC3045Types::uRSPByte::sRSPByte::PBL8
U8 PBL8
Definition: MFC3045Types.h:247
MTL::Instrument::eSerialBaudrate::k19200
@ k19200
MTL::Instrument::CMFC3045Instrument::CalibrationDatePAGet
bool CalibrationDatePAGet(std::string &rStrDate, std::time_t &rUtcDate)
Definition: MFC3045.cpp:4064
MTL::Instrument::eSerialStopBits::k1
@ k1
Exception.h
Exception handling utilities.
MTL::Instrument::CMFC3045Instrument::ProbeArrayEepromRead
bool ProbeArrayEepromRead(std::vector< char > &rEEPROMContent)
Definition: MFC3045.cpp:3601
MTL::Instrument::CMFC3045Instrument::NumberMeasCycleGet
bool NumberMeasCycleGet(U16 &rRegVal)
Definition: MFC3045.cpp:2032
MTL::Instrument::CVISAInstrument
VISA instrument class.
Definition: VISAInstrument.h:60
MTL::Instrument::sSerialPortSettings::StopBits
eSerialStopBits StopBits
Definition: VISAInstrumentTypes.h:177
MTL::Instrument::CMFC3045Instrument::DataNumberValidCycleGet
bool DataNumberValidCycleGet(const U8 &rNbMeasurements, std::vector< U32 > &rData)
Definition: MFC3045.cpp:2980
MTL::Instrument::CMFC3045Instrument::ModulationNumberStepPlateauGet
bool ModulationNumberStepPlateauGet(U32 &rRegVal)
Definition: MFC3045.cpp:1924
MTL::Instrument::CMFC3045Instrument::TimePreCycleGet
bool TimePreCycleGet(U16 &rRegVal)
Definition: MFC3045.cpp:2138
CORRECT_POBE_MIN_DHZ
#define CORRECT_POBE_MIN_DHZ
Definition: MFC3045Types.h:33
MTL_Unused
#define MTL_Unused(x)
Definition: Helpers.h:47
MTL::Instrument::CMFC3045Instrument::DataIndividualFrequencyGet
bool DataIndividualFrequencyGet(U32 &rDataUp, U32 &rDataDown)
Definition: MFC3045.cpp:3041
MTL::Instrument::CVISABuffer::size
size_t size() const
Definition: VISAInstrumentBuffer.h:86
MTL::Instrument::CVISAResourceManager
VISA Resource Manager class.
Definition: VISAInstrument.h:35
PA_FREQ_MAX_DHZ
#define PA_FREQ_MAX_DHZ
Definition: MFC3045Types.h:23
MTL__LOCATION__
#define MTL__LOCATION__
Definition: Helpers.h:22
MTL::Instrument::CMFC3045Instrument::SearchStart
bool SearchStart()
Definition: MFC3045.cpp:2521
MTL::Instrument::CMFC3045Instrument::ProbeArrayEepromWrite
bool ProbeArrayEepromWrite()
Definition: MFC3045.cpp:3578
NPC_MAX
#define NPC_MAX
Definition: MFC3045Types.h:26
MTL::Instrument::CVISAInstrument::Clear
bool Clear()
Definition: VISAInstrument.cpp:477
MTL::Instrument::CMFC3045Instrument::CalibrationBuildProbeGet
bool CalibrationBuildProbeGet(I32 &rData, const U8 &rProbeSel)
Definition: MFC3045.cpp:3861
MTL::Instrument::eOpenAccessMode::ExclusiveLock
@ ExclusiveLock
MTL::Instrument::CVISAInstrument::Unlock
bool Unlock()
Definition: VISAInstrument.cpp:591
MTL::Instrument::CMFC3045Instrument::VersionGet
bool VersionGet(std::string &rVersionInfo, F32 &rFwVersion)
Definition: MFC3045.cpp:1028
MTL::Instrument::CMFC3045Instrument::RejectionOffsetSet
bool RejectionOffsetSet(const U16 &rRegVal)
Definition: MFC3045.cpp:2164