OneOsc.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #ifndef _OneOscilloscope_H_
  2. #define _OneOscilloscope_H_
  3. #include <QObject>
  4. #include <QMap>
  5. #include <QTimer>
  6. #include "USBInterFace.h"
  7. #include "spdlog/spdlog.h"
  8. #include "GlobalInfo.h"
  9. #include "RingQueue/RingQueue.hpp"
  10. class EyeDataMatrix;
  11. class EyeColorMatrix;
  12. struct EyeDataT;
  13. #define OneOscData OneOscilloscope
  14. class OneOscilloscope : public QObject
  15. {
  16. Q_OBJECT
  17. const uint32_t BUFFER_SIZE = 1024 * 128 ; /* 缓冲区大小,OSCA02的缓冲区应该是128KB的SRAM */
  18. using Vec2Data = std::vector<std::vector<EyeDataT>>;
  19. private:
  20. OneOscilloscope(const OneOscilloscope&) = delete;
  21. OneOscilloscope& operator=(const OneOscilloscope&) = delete;
  22. public:
  23. OneOscilloscope();
  24. ~OneOscilloscope();
  25. /* 初始化示波器 */
  26. void initOSC(int oscNum);
  27. /* 打开示波器 */
  28. bool openOSC();
  29. /* 关闭示波器 */
  30. void closeOSC();
  31. /* 示波器是否打开 */
  32. bool isOpen() { return m_isOpen; }
  33. /* 开始采集数据 */
  34. bool startCapture();
  35. /* 开启采集数据,带有条件判断 */
  36. bool startCaptureWithCondition();
  37. /* 停止采集数据 */
  38. void stopCapture();
  39. /* 获取颜色矩阵内存指针 */
  40. EyeColorMatrix* getColorMatrixPtr(OscChannel chn);
  41. /* 设置颜色矩阵,把外部的颜色矩阵设置过来,通过这里的子线程拷贝进去 */
  42. void setColorMatrixPtr(OscChnNum num, EyeColorMatrix* colorMatrix);
  43. /***** 设置示波器的功能命令 *****/
  44. /* 设置示波器的采样率 */
  45. void setSampleRate(OscSampleRate rate);
  46. /* 将示波器两个通道合并为一个通道 */
  47. void setChannelMerge(bool merge);
  48. /* 设置通道A输入量程 */
  49. void setChannelARange(OscVoltageRange range);
  50. /* 设置通道B输入量程 */
  51. void setChannelBRange(OscVoltageRange range);
  52. /* 设置通道耦合方式 */
  53. void setChannelCoupling(OscChannel channel, OscChannelCoupling coupling);
  54. /* 开启或关闭通道A触发 */
  55. void setChannelATrigger(bool enable);
  56. /* 开启外触发 */
  57. void setExternalTrigger(bool enable);
  58. /* 设置触发方式 */
  59. void setTriggerMode(OscTriggerMode mode);
  60. /* 设置触发电平 */
  61. void setTriggerLevel(unsigned char level);
  62. /* 设置触发灵敏度 */
  63. void setTriggerSensitivity(OscTriggerSensitivity sensitivity);
  64. /* 设置触发在缓冲区的哪个位置 */
  65. void setTriggerPosition(unsigned char lowByte, unsigned char highByte);
  66. /* 设置时间刻度 */
  67. void setTimeGridValue(OscTimeGridValue value);
  68. /* 获取示波器不同档位下的零电压值 */
  69. void getZeroVoltage();
  70. /* 打印出零电压值 */
  71. void printZeroVoltage(OscChannel channel);
  72. /* 获取不同档位下电压校准系数 */
  73. void getVoltageCalibration();
  74. /* 打印出电压校准系数 */
  75. void printVoltageCalibration(OscChannel channel);
  76. /***** 示波器其他属性 *****/
  77. int getOscNum() { return m_oscNum; }
  78. /* 清空数据 */
  79. void resetData();
  80. /* 设置示波器的两个通道是否在使用,都不使用则停止采集 */
  81. void setChannelUsed(OscChnNum chn, bool used);
  82. signals:
  83. /* 重新连接示波器 */
  84. void signal_reconnectOsc();
  85. private:
  86. // public:
  87. /* 采集数据,这个是子线程 */
  88. void threadCaptureData();
  89. /* 处理数据线程 */
  90. void threadSeparateData();
  91. /* 处理A通道数据 */
  92. void threadProcessData_A();
  93. /* 处理B通道数据 */
  94. void threadProcessData_B();
  95. /* 拷贝数据线程 */
  96. void threadCopyData(OscChannel chn);
  97. /* 解析数据,眼图需要的数据 */
  98. bool parseEyeMapData(OscChannel chn, unsigned char* buffer, unsigned int size);
  99. /* 设置零电压值和电压校准系数 */
  100. void setZeroVoltageAndCalibration(OscChannel chn, OscVoltageRange range);
  101. /* 校准电压 */
  102. inline double calibrationVoltageA(uint8_t& data);
  103. inline double calibrationVoltageB(uint8_t& data);
  104. /* 初始化数据矩阵很颜色矩阵 */
  105. bool initMatrixPtr();
  106. /* 等待所有线程退出,调用此函数之前,需要先设置线程运行标志为false,并发送所有的条件变量
  107. * 这个函数会阻塞一直等待所有线程退出 */
  108. void waitAllThreadExit();
  109. /* 发送示波器在线或者离线状态 */
  110. void sendOscState(bool state);
  111. private slots:
  112. /* 示波器离线了,重新连接 */
  113. void do_reconnectOsc();
  114. private:
  115. std::shared_ptr<spdlog::logger> m_logger = nullptr;
  116. std::shared_ptr<USBInterface> m_usbInterface = nullptr;
  117. std::atomic_bool m_isOpen = false; /* 示波器是否打开 */
  118. std::atomic_bool m_isConnected = false; /* 示波器是否连接 */
  119. std::atomic_bool m_runCapture = false; /* 线程运行的变量 */
  120. std::map<std::thread::id, bool> m_mapThreadState; /* 线程是否正在运行的标志位 */
  121. std::atomic_bool m_isRunCapture = false; /* 线程运行标志,这个标志位作为线程运行的标志 */
  122. QTimer m_timerConnect; /* 连接定时器 */
  123. std::atomic_bool m_isCapturedData = false; /* 是否采集到数据 */
  124. std::condition_variable m_condCapture; /* 采集数据的条件变量 */
  125. std::condition_variable m_condBuffer_A; /* 通道A的条件变量 */
  126. std::condition_variable m_condBuffer_B; /* 通道B的条件变量 */
  127. std::condition_variable m_condCopyData_A; /* 拷贝数据的条件变量 */
  128. std::condition_variable m_condCopyData_B; /* 拷贝数据的条件变量 */
  129. std::mutex m_mutexBuffer; /* 互斥锁,用于保护采集到的数据 */
  130. std::mutex m_mutexBuffer_A; /* 互斥锁,用于保护采集到的数据 */
  131. std::mutex m_mutexBuffer_B; /* 互斥锁,用于保护采集到的数据 */
  132. std::mutex m_mutexThreadState; /* 互斥锁,用于保护线程状态 */
  133. unsigned char* m_devBuffer = nullptr; /* 设备缓冲区指针,拷贝数据用的 */
  134. unsigned char* m_buffer = nullptr; /* 缓冲区指针,用于存储拷贝出来的数据 */
  135. unsigned char* m_bufferChnA = nullptr; /* 通道A的缓冲区指针 */
  136. unsigned char* m_bufferChnB = nullptr; /* 通道B的缓冲区指针 */
  137. int m_oscNum = 0; /* 示波器编号 */
  138. OscChnNum m_chnNumA = OscChnNum::Osc_None; /* 示波器通道数 */
  139. OscChnNum m_chnNumB = OscChnNum::Osc_None; /* 示波器通道数 */
  140. bool m_chnUsedA = false; /* 通道A是否在使用 */
  141. bool m_chnUsedB = false; /* 通道B是否在使用 */
  142. /************* 示波器控制相关 *************/
  143. unsigned char m_ctrlByte0 = 0; /* 控制字节0 */
  144. unsigned char m_ctrlByte1 = 0; /* 控制字节1 */
  145. QMap<OscVoltageRange, unsigned char> m_mapChAZeroVoltage; /* 通道A的零电压值 */
  146. QMap<OscVoltageRange, unsigned char> m_mapChBZeroVoltage; /* 通道B的零电压值 */
  147. QMap<OscVoltageRange, unsigned char> m_mapChAVoltageAmplitudeRatio; /* 通道A的电压校准系数 */
  148. QMap<OscVoltageRange, unsigned char> m_mapChBVoltageAmplitudeRatio; /* 通道B的电压校准系数 */
  149. unsigned char m_zeroVoltageA = 0; /* 通道A零电压值 */
  150. unsigned char m_zeroVoltageB = 0; /* 通道B零电压值 */
  151. char m_diffVoltageA = 0; /* 通道A零电压差值 */
  152. char m_diffVoltageB = 0; /* 通道B零电压差值 */
  153. double m_voltageCalibrationA = 0; /* 通道A电压校准系数 */
  154. double m_voltageCalibrationB = 0; /* 通道B电压校准系数 */
  155. double m_rangeRatioA = 0.0; /* 通道A量程比例 */
  156. double m_rangeRatioB = 0.0; /* 通道B量程比例 */
  157. OscVoltageRange m_rangeA = OscVoltageRange::CR_2V5; /* 通道A输入量程,用于记录外部设置的当前输入量程 */
  158. OscVoltageRange m_rangeB = OscVoltageRange::CR_2V5; /* 通道B输入量程 */
  159. std::atomic_int m_oneTimeGrid = 0; /* 一个时间刻度的时间长度,单位ns,和枚举值OscTimeGridValue相对应 */
  160. std::atomic<double> m_SampleIntervalTime = 0; /* 采样点之间的时间间隔,单位ns(采样率的倒数,设置采样率的时候会设置) */
  161. // std::atomic_int m_eyeMapWidth = 0; /* 眼图x轴宽度(像素矩形的个数) */
  162. /************* 数据指针 *************/
  163. EyeDataMatrix* m_dataMatrix_A = nullptr; /* 眼图数据矩阵,A通道 */
  164. EyeDataMatrix* m_dataMatrix_B = nullptr; /* 眼图数据矩阵,B通道 */
  165. EyeColorMatrix* m_colorMatrix_A = nullptr; /* 眼图颜色矩阵,A通道 */
  166. EyeColorMatrix* m_colorMatrix_B = nullptr; /* 眼图颜色矩阵,B通道 */
  167. EyeColorMatrix* m_gColorMatrix_A = nullptr; /* 外部的颜色矩阵,A通道,一帧完成后拷贝给全局的矩阵 */
  168. EyeColorMatrix* m_gColorMatrix_B = nullptr; /* 外部的颜色矩阵,B通道,一帧完成后拷贝给全局的矩阵 */
  169. };
  170. #endif /* _OneOscilloscope_H_ */