#ifndef _OneOscilloscope_H_ #define _OneOscilloscope_H_ #include #include #include #include "USBInterFace.h" #include "spdlog/spdlog.h" #include "GlobalInfo.h" #include "RingQueue/RingQueue.hpp" class EyeDataMatrix; class EyeColorMatrix; struct EyeDataT; #define OneOscData OneOscilloscope class OneOscilloscope : public QObject { Q_OBJECT const uint32_t BUFFER_SIZE = 1024 * 128 ; /* 缓冲区大小,OSCA02的缓冲区应该是128KB的SRAM */ using Vec2Data = std::vector>; private: OneOscilloscope(const OneOscilloscope&) = delete; OneOscilloscope& operator=(const OneOscilloscope&) = delete; public: OneOscilloscope(); ~OneOscilloscope(); /* 初始化示波器 */ void initOSC(int oscNum); /* 打开示波器 */ bool openOSC(); /* 关闭示波器 */ void closeOSC(); /* 示波器是否打开 */ bool isOpen() { return m_isOpen; } /* 开始采集数据 */ bool startCapture(); /* 开启采集数据,带有条件判断 */ bool startCaptureWithCondition(); /* 停止采集数据 */ void stopCapture(); /* 获取颜色矩阵内存指针 */ EyeColorMatrix* getColorMatrixPtr(OscChannel chn); /* 设置颜色矩阵,把外部的颜色矩阵设置过来,通过这里的子线程拷贝进去 */ void setColorMatrixPtr(OscChnNum num, EyeColorMatrix* colorMatrix); /***** 设置示波器的功能命令 *****/ /* 设置示波器的采样率 */ void setSampleRate(OscSampleRate rate); /* 将示波器两个通道合并为一个通道 */ void setChannelMerge(bool merge); /* 设置通道A输入量程 */ void setChannelARange(OscVoltageRange range); /* 设置通道B输入量程 */ void setChannelBRange(OscVoltageRange range); /* 设置通道耦合方式 */ void setChannelCoupling(OscChannel channel, OscChannelCoupling coupling); /* 开启或关闭通道A触发 */ void setChannelATrigger(bool enable); /* 开启外触发 */ void setExternalTrigger(bool enable); /* 设置触发方式 */ void setTriggerMode(OscTriggerMode mode); /* 设置触发电平 */ void setTriggerLevel(unsigned char level); /* 设置触发灵敏度 */ void setTriggerSensitivity(OscTriggerSensitivity sensitivity); /* 设置触发在缓冲区的哪个位置 */ void setTriggerPosition(unsigned char lowByte, unsigned char highByte); /* 设置时间刻度 */ void setTimeGridValue(OscTimeGridValue value); /* 获取示波器不同档位下的零电压值 */ void getZeroVoltage(); /* 打印出零电压值 */ void printZeroVoltage(OscChannel channel); /* 获取不同档位下电压校准系数 */ void getVoltageCalibration(); /* 打印出电压校准系数 */ void printVoltageCalibration(OscChannel channel); /***** 示波器其他属性 *****/ int getOscNum() { return m_oscNum; } /* 清空数据 */ void resetData(); /* 设置示波器的两个通道是否在使用,都不使用则停止采集 */ void setChannelUsed(OscChnNum chn, bool used); signals: /* 重新连接示波器 */ void signal_reconnectOsc(); private: // public: /* 采集数据,这个是子线程 */ void threadCaptureData(); /* 处理数据线程 */ void threadSeparateData(); /* 处理A通道数据 */ void threadProcessData_A(); /* 处理B通道数据 */ void threadProcessData_B(); /* 拷贝数据线程 */ void threadCopyData(OscChannel chn); /* 解析数据,眼图需要的数据 */ bool parseEyeMapData(OscChannel chn, unsigned char* buffer, unsigned int size); /* 设置零电压值和电压校准系数 */ void setZeroVoltageAndCalibration(OscChannel chn, OscVoltageRange range); /* 校准电压 */ inline double calibrationVoltageA(uint8_t& data); inline double calibrationVoltageB(uint8_t& data); /* 初始化数据矩阵很颜色矩阵 */ bool initMatrixPtr(); /* 等待所有线程退出,调用此函数之前,需要先设置线程运行标志为false,并发送所有的条件变量 * 这个函数会阻塞一直等待所有线程退出 */ void waitAllThreadExit(); /* 发送示波器在线或者离线状态 */ void sendOscState(bool state); private slots: /* 示波器离线了,重新连接 */ void do_reconnectOsc(); private: std::shared_ptr m_logger = nullptr; std::shared_ptr m_usbInterface = nullptr; std::atomic_bool m_isOpen = false; /* 示波器是否打开 */ std::atomic_bool m_isConnected = false; /* 示波器是否连接 */ std::atomic_bool m_runCapture = false; /* 线程运行的变量 */ std::map m_mapThreadState; /* 线程是否正在运行的标志位 */ std::atomic_bool m_isRunCapture = false; /* 线程运行标志,这个标志位作为线程运行的标志 */ QTimer m_timerConnect; /* 连接定时器 */ std::atomic_bool m_isCapturedData = false; /* 是否采集到数据 */ std::condition_variable m_condCapture; /* 采集数据的条件变量 */ std::condition_variable m_condBuffer_A; /* 通道A的条件变量 */ std::condition_variable m_condBuffer_B; /* 通道B的条件变量 */ std::condition_variable m_condCopyData_A; /* 拷贝数据的条件变量 */ std::condition_variable m_condCopyData_B; /* 拷贝数据的条件变量 */ std::mutex m_mutexBuffer; /* 互斥锁,用于保护采集到的数据 */ std::mutex m_mutexBuffer_A; /* 互斥锁,用于保护采集到的数据 */ std::mutex m_mutexBuffer_B; /* 互斥锁,用于保护采集到的数据 */ std::mutex m_mutexThreadState; /* 互斥锁,用于保护线程状态 */ unsigned char* m_devBuffer = nullptr; /* 设备缓冲区指针,拷贝数据用的 */ unsigned char* m_buffer = nullptr; /* 缓冲区指针,用于存储拷贝出来的数据 */ unsigned char* m_bufferChnA = nullptr; /* 通道A的缓冲区指针 */ unsigned char* m_bufferChnB = nullptr; /* 通道B的缓冲区指针 */ int m_oscNum = 0; /* 示波器编号 */ OscChnNum m_chnNumA = OscChnNum::Osc_None; /* 示波器通道数 */ OscChnNum m_chnNumB = OscChnNum::Osc_None; /* 示波器通道数 */ bool m_chnUsedA = false; /* 通道A是否在使用 */ bool m_chnUsedB = false; /* 通道B是否在使用 */ /************* 示波器控制相关 *************/ unsigned char m_ctrlByte0 = 0; /* 控制字节0 */ unsigned char m_ctrlByte1 = 0; /* 控制字节1 */ QMap m_mapChAZeroVoltage; /* 通道A的零电压值 */ QMap m_mapChBZeroVoltage; /* 通道B的零电压值 */ QMap m_mapChAVoltageAmplitudeRatio; /* 通道A的电压校准系数 */ QMap m_mapChBVoltageAmplitudeRatio; /* 通道B的电压校准系数 */ unsigned char m_zeroVoltageA = 0; /* 通道A零电压值 */ unsigned char m_zeroVoltageB = 0; /* 通道B零电压值 */ char m_diffVoltageA = 0; /* 通道A零电压差值 */ char m_diffVoltageB = 0; /* 通道B零电压差值 */ double m_voltageCalibrationA = 0; /* 通道A电压校准系数 */ double m_voltageCalibrationB = 0; /* 通道B电压校准系数 */ double m_rangeRatioA = 0.0; /* 通道A量程比例 */ double m_rangeRatioB = 0.0; /* 通道B量程比例 */ OscVoltageRange m_rangeA = OscVoltageRange::CR_2V5; /* 通道A输入量程,用于记录外部设置的当前输入量程 */ OscVoltageRange m_rangeB = OscVoltageRange::CR_2V5; /* 通道B输入量程 */ std::atomic_int m_oneTimeGrid = 0; /* 一个时间刻度的时间长度,单位ns,和枚举值OscTimeGridValue相对应 */ std::atomic m_SampleIntervalTime = 0; /* 采样点之间的时间间隔,单位ns(采样率的倒数,设置采样率的时候会设置) */ // std::atomic_int m_eyeMapWidth = 0; /* 眼图x轴宽度(像素矩形的个数) */ /************* 数据指针 *************/ EyeDataMatrix* m_dataMatrix_A = nullptr; /* 眼图数据矩阵,A通道 */ EyeDataMatrix* m_dataMatrix_B = nullptr; /* 眼图数据矩阵,B通道 */ EyeColorMatrix* m_colorMatrix_A = nullptr; /* 眼图颜色矩阵,A通道 */ EyeColorMatrix* m_colorMatrix_B = nullptr; /* 眼图颜色矩阵,B通道 */ EyeColorMatrix* m_gColorMatrix_A = nullptr; /* 外部的颜色矩阵,A通道,一帧完成后拷贝给全局的矩阵 */ EyeColorMatrix* m_gColorMatrix_B = nullptr; /* 外部的颜色矩阵,B通道,一帧完成后拷贝给全局的矩阵 */ }; #endif /* _OneOscilloscope_H_ */