Facebook
From Dan, 2 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 98
  1. /* QWQNG_Linux Library
  2.  
  3.   Version 1.4
  4.  
  5.   Copyright (c) 2019, The Quantum World Corporation.
  6.   All rights reserved.
  7.  
  8.   New BSD License
  9.  
  10.   Redistribution and use in source and binary forms, with or without
  11.   modification, are permitted provided that the following conditions are met:
  12.       * Redistributions of source code must retain the above copyright
  13.         notice, this list of conditions and the following disclaimer.
  14.       * Redistributions in binary form must reproduce the above copyright
  15.         notice, this list of conditions and the following disclaimer in the
  16.         documentation and/or other materials provided with the distribution.
  17.       * Neither the name of the <organization> nor the
  18.         names of its contributors may be used to endorse or promote products
  19.         derived from this software without specific prior written permission.
  20.  
  21.   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22.   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23.   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24.   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  25.   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26.   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27.   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  28.   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29.   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30.   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  
  32.  */
  33.  
  34. #ifndef __qwqng_hpp__
  35. #define __qwqng_hpp__
  36.  
  37. //
  38. // Custom definitions
  39. //
  40.  
  41. #define FTDIDEVICE_ID_PREFIX_               "QWR"
  42. #define FTDIDEVICE_ID_DEVELOPMENT_          "D"
  43. #define FTDIDEVICE_STREAM_TIMEOUT_MILLIS_   5000
  44. #define FTDIDEVICE_TX_TIMEOUT_MILLIS_       100
  45. #define FTDIDEVICE_TX_ATTEMPTS_             40
  46. #define FTDIDEVICE_START_DISCARD_BYTES_     256
  47.  
  48. #define FTDIDEVICE_START_COMMAND_           0x96U
  49. #define FTDIDEVICE_STOP_COMMAND_            0xe0U
  50. #define FTDIDEVICE_DELIMIT_COMMAND_         0x60U
  51.  
  52. #define FTDIDEVICE_TEST_STATUS_COMMAND_     0xb0U
  53. #define FTDIDEVICE_TEST_FINAL_BASE_         0xa0U
  54. #define FTDIDEVICE_TEST_CHANNELS_BASE_      0x70U
  55. #define FTDIDEVICE_TEST_BAD_STATS_MASK_     0x0004
  56. #define FTDIDEVICE_TEST_CLEAR_STATS_FLAG_   0xc0U
  57.  
  58. #define FTDIDEVICE_QNG_GEN1_                1
  59. #define FTDIDEVICE_QNG_GEN2_                2
  60. #define FTDIDEVICE_QNG_GEN3_                3
  61. #define FTDIDEVICE_QNG_GEN4_                4
  62. #define FTDIDEVICE_QNG_GEN5_                5
  63.  
  64. #define FTDIDEVICE_MAX_ARRAY_SIZE_          8192
  65. #define FTDIDEVICE_READ_FRAME_SIZE_         512
  66. #define FTDIDEVICE_WRITE_FRAME_SIZE_        512
  67.  
  68. #define FTDIDEVICE_FAST_MAX_ARRAY_SIZE_     65536
  69. #define FTDIDEVICE_FAST_READ_FRAME_SIZE_    65536
  70. #define FTDIDEVICE_FAST_WRITE_FRAME_SIZE_   65536
  71.  
  72. #define FTDIDEVICE_HALF_OF_UNIFORM_LSB_     1.7763568394002505e-15
  73. #define FTDIDEVICE_2_PI_                    6.283185307179586
  74.  
  75. #define FTDIDEVICE_RNG_OUTPUT_ENABLED_MASK_ 0X0001
  76. #define FTDIDEVICE_USB_STREAMING_MASK_      0X0002
  77. #define FTDIDEVICE_TEST_BAD_STATS_MASK_     0x0004
  78. #define FTDIDEVICE_CLIENT_CONNECTED_MASK_   0X0008
  79.  
  80. //
  81. // Custom QNG HRESULT messages
  82. //
  83.  
  84. //
  85. // MessageId:   QNG_S_OK
  86. // MessageText: QNG device reports success.
  87. //
  88. #define QNG_S_OK                                                0x00044400L
  89.  
  90. //
  91. // MessageId:   QNG_E_GENERAL_FAILURE
  92. // MessageText: QNG general error.
  93. //
  94. #define QNG_E_GENERAL_FAILURE                   0x80044401L
  95.  
  96. //
  97. // MessageId:   QNG_E_IO_ERROR
  98. // MessageText: QNG I/O error.
  99. //
  100. #define QNG_E_IO_ERROR                                  0x80044402L
  101.  
  102. //
  103. // MessageId:   QNG_E_IO_TIMEOUT
  104. // MessageText: QNG I/O request has timed out.
  105. //
  106. #define QNG_E_IO_TIMEOUT                                0x80044403L
  107.  
  108. //
  109. // MessageId:   QNG_E_IO_ARRAY_OVERSIZED
  110. // MessageText: QNG read array size exceeds max size.
  111. //
  112. #define QNG_E_IO_ARRAY_OVERSIZED                0x80044404L
  113.  
  114. //
  115. // MessageId:   QNG_E_STATS_EXCEPTION
  116. // MessageText: QNG test statistics exception.
  117. //
  118. #define QNG_E_STATS_EXCEPTION                   0x80044406L
  119.  
  120. //
  121. // MessageId:   QNG_E_STATS_UNSUPPORTED
  122. // MessageText: QNG stats not supported with this device.
  123. //
  124. #define QNG_E_STATS_UNSUPPORTED                 0x80044407L
  125.  
  126. //
  127. // MessageId:   QNG_E_DIAGX_UNSUPPORTED
  128. // MessageText: QNG diagnostics not supported with this device.
  129. //
  130. #define QNG_E_DIAGX_UNSUPPORTED                 0x80044408L
  131.  
  132. //
  133. // MessageId:   QNG_E_DEVICE_NOT_OPENED
  134. // MessageText: QNG device not found or already in use.
  135. //
  136. #define QNG_E_DEVICE_NOT_OPENED                 0x8004440AL
  137.  
  138. //
  139. // MessageId:   S_OK
  140. // MessageText: No error occurred.
  141. //
  142. #define S_OK                                                    0x00000000L
  143.  
  144. //
  145. // Includes
  146. //
  147.  
  148. #include "stdint.h"
  149. #include <sys/types.h>
  150. #include <sys/time.h>
  151. #include <pthread.h>
  152. #include <unistd.h>
  153. #include <vector>
  154. #include <math.h>
  155. #include <string>
  156. #include <string.h>
  157. #include <iostream>
  158. #include <ftdi.h>
  159.  
  160. //
  161. // DEBUG MACROS
  162. //
  163.  
  164. #if __STDC_VERSION__ < 199901L
  165.      # if __GNUC__ >= 2
  166.             #  define __func__ __FUNCTION__
  167.         # else
  168.             #  define __func__ "<unknown>"
  169.      # endif
  170. #endif
  171.  
  172. // uncomment line below to use debug macro
  173. //#define DEBUGOUTDO
  174.  
  175. #ifdef DEBUGOUTDO
  176.     #define DEBUGTOUCH() std::cout << "@ " << __FUNCTION__ << " " << __LINE__ << "\n"
  177.     #define DEBUGOUT(val) std::cout << "> " << __FUNCTION__ << " " << __LINE__ << std::hex << " " #val ": " << val << "\n" << std::dec
  178.     //#define DEBUGTEST(left, op, right) if ((left op right) == false) std::cout << "? " << __FUNCTION__ << " " << __LINE__ << std::hex << " " #left ": " << left << " " #op " " #right ": " << right << " FALSE\n" << std::dec
  179. #else
  180.     #define DEBUGTOUCH()
  181.     #define DEBUGOUT(val)
  182.     //#define DEBUGTEST(left, op, right)
  183.  
  184. #endif
  185.  
  186. //
  187. // CLASSES
  188. //
  189.  
  190. /* Forward Declaration */
  191. class FtdiDevice;
  192. class IDevice;
  193. class QngStatus;
  194. class Mutex;
  195. class MutexSync;
  196.  
  197. class QWQNG
  198. {  
  199. public:
  200.   /* Public Constructor */
  201.   QWQNG();
  202.  
  203.   /* Construct Indirectly (backwards compatibility)*/
  204.   static QWQNG* Instance();  
  205.  
  206.   /* Public Destructor */
  207.   ~QWQNG();
  208.  
  209.    
  210. protected:
  211.   /* Pointer to Class IDevice */
  212.   IDevice* pDevice;    
  213.      
  214. public:
  215.   /* Properties */
  216.   char* statusString_; 
  217.   char* devId_;        
  218.  
  219.   /* Device Manipulators */
  220.   char* StatusString();
  221.   char* DeviceID();  
  222.   int RandInt32(long* pVal);
  223.   int RandUniform(double* pVal);
  224.   int RandNormal(double *pVal);
  225.   int RandBytes(char* pval, long length);
  226.   int Clear();
  227.   int Reset();
  228.   int RuntimeInfo(float* pVal);
  229.   int Diagnostics(char dxCode, char* dxInfo);
  230. };
  231.  
  232.  
  233. class IDevice
  234. {
  235. public:
  236.     int deviceType_;
  237. protected:
  238.     std::string deviceId_;
  239.     int commandResponseLength_[256];
  240.     //int deviceType_;
  241.     QngStatus* qngStatus;
  242.  
  243. public:
  244.     IDevice(QngStatus* qngStatus) : deviceType_(0), qngStatus(qngStatus)
  245.     {
  246.         // Return Length For Command Bytes
  247.         //  00       :     0 bytes - NEVER USE
  248.         //  01 - 0F  :  1024 bytes
  249.         //  10 - 3F  :   128 bytes
  250.         //  40 - 5F  :     1 byte
  251.         //  60       :     6 bytes - DELIMITER
  252.         //  61 - 95  :     4 bytes
  253.         //  96       :     0 bytes - START
  254.         //  97 - BF  :     4 bytes
  255.         //  C0 - FE  :     0 bytes
  256.         //  FF       :     0 bytes - NEVER USE
  257.  
  258.         commandResponseLength_[0x00] = 0;
  259.         for (int i=0x01; i<=0x0F; i++)
  260.             commandResponseLength_[i] = 1024;
  261.         for (int i=0x10; i<=0x3F; i++)
  262.             commandResponseLength_[i] = 128;
  263.         for (int i=0x40; i<=0x5F; i++)
  264.             commandResponseLength_[i] = 1;
  265.         commandResponseLength_[0x60] = 6;
  266.         for (int i=0x61; i<=0xBF; i++)
  267.             commandResponseLength_[i] = 4;
  268.         commandResponseLength_[0x96] = 0;
  269.         for (int i=0xC0; i<=0xFF; i++)
  270.             commandResponseLength_[i] = 0;
  271.     }
  272.  
  273.     /* Functions */
  274.     virtual void Open() = 0;
  275.     virtual void Close() = 0;
  276.     virtual void Clear() = 0;
  277.     virtual void Reset() = 0;
  278.  
  279.     virtual void GetBytes(char* bytes, int bytesRequested) = 0;
  280.     virtual void GetInt32(int32_t* int32) = 0;
  281.     virtual void GetUniform(double* uniform) = 0;
  282.     virtual void GetNormal(double* normal) = 0;
  283.  
  284.     virtual void GetRuntimeInfo(float* testData) = 0;
  285.     virtual void Diagnostics(uint8_t dxCode, uint8_t* dxData) = 0;
  286.  
  287.     virtual std::string& GetDeviceId() = 0;
  288.     virtual void SetDeviceId(std::string deviceId) = 0;
  289.     virtual int GetDeviceType() = 0;
  290. };
  291.  
  292.  
  293. class FtdiDevice : public IDevice
  294. {
  295. private:
  296.     /* Main context structure for all libftdi functions */
  297.     struct ftdi_context* ftdic;                        
  298.    
  299.     /* Structure for Finding Multiple FTDI Devices */
  300.     struct QNGdev
  301.         {
  302.       struct ftdi_device_list *devlist, *curdev;
  303.       int VID;
  304.       int PID;
  305.     };  
  306.     struct QNGdev Buffer[2]; // Init QNGdev Structure
  307.  
  308.     /* Structure for Connected FTDI Devices' Parameters ( Initialize in FindOpen() ) */
  309.     struct QNGparam
  310.         {
  311.       char manufacturer[128], description[128], serialnumber[9];
  312.     };
  313.    
  314.     /* Properties */
  315.     char serialInfo[9];
  316.     char descInfo[128];
  317.     char manuInfo[128];
  318.     int devPID;
  319.     int devVID;  
  320.     int txchunksize;
  321.     int rxchunksize;
  322.     int ftdiStatus;    
  323.              
  324.     uint8_t delimiter_[6];
  325.     bool haveNormU1_;
  326.     double normU1_;
  327.     double normalConjugate_;
  328.  
  329.     bool isStreaming_;
  330.     uint32_t prevDxCode_;
  331.  
  332.     timeval start, stop;
  333.     double elapsedTime;
  334.  
  335. public:
  336.     /* Constructor, Destructor */
  337.     FtdiDevice(QngStatus* qngStatus);
  338.     ~FtdiDevice();
  339.  
  340.     /* Functions */
  341.     virtual void Open();
  342.     virtual void Close();
  343.     virtual void Clear();
  344.     virtual void Reset();
  345.  
  346.     virtual void GetBytes(char* bytes, int bytesRequested);
  347.     virtual void GetInt32(int32_t* int32);
  348.     virtual void GetUniform(double* uniform);
  349.     virtual void GetNormal(double* normal);
  350.  
  351.     virtual void GetRuntimeInfo(float* runtimeInfo);
  352.     virtual void Diagnostics(uint8_t dxCode, uint8_t* dxData);
  353.  
  354.     virtual std::string& GetDeviceId();
  355.     virtual void SetDeviceId(std::string deviceId);
  356.     virtual int GetDeviceType();
  357.    
  358. private:  
  359.     /* Functions */
  360.     void FtdiClose();
  361.     void FindOpen();
  362.     void Initialize();
  363.     void FtdiRead(void* receiveBuffer, int bytesRequested, bool statsUnchecked);
  364.     void FtdiWrite(void* transmitBuffer, int bytesToTransmit);
  365.     bool FtdiCommandResponse(uint8_t command, uint8_t* response);
  366.     bool StartStreaming();
  367.     bool StopStreaming();
  368.     bool DetermineDelimiter();
  369.     void CheckTestStatsStatus();
  370.     double Uint48ToUniform(uint64_t uint48);
  371.     float CalcEntropy(double p);  
  372. };
  373.  
  374.  
  375. class QngStatus
  376. {
  377. public:
  378.     /* Constructor, Destructor */
  379.     QngStatus();
  380.     ~QngStatus();
  381.    
  382.     /* Functions */
  383.     long GetStatus();
  384.     std::string& GetStatusString();
  385.     long SetStatus(long newStatus);
  386.  
  387. private:  
  388.     /* properties */
  389.     long status_;
  390.     std::string statusString_;  
  391. };
  392.  
  393.  
  394. class Mutex
  395. {
  396. public:
  397.         /* Constructor, Destructor */
  398.     Mutex();
  399.     ~Mutex();
  400.  
  401.         /* Functions */
  402.     void Lock();
  403.     void Unlock();
  404.  
  405. private:
  406.         /* properties */
  407.     pthread_mutex_t mutex_;    
  408. };
  409.  
  410.  
  411. class MutexSync
  412. {
  413. public:
  414.     /* Constructor, Destructor */
  415.     MutexSync(Mutex& mutex);
  416.     ~MutexSync();
  417.  
  418. private:
  419.         /* properties */
  420.         Mutex& mutex_;
  421. };
  422.  
  423. #endif
  424.  
  425.  
  426.