You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

671 lines
25 KiB

2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "mainwindow.h"
  2. #include <QDateTime>
  3. #include <QMessageBox>
  4. #include <QtConcurrent>
  5. #include <QtSerialPort/QSerialPort>
  6. #include <QtSerialPort/QSerialPortInfo>
  7. #include "./ui_mainwindow.h"
  8. #include "ads129x/ads129x_type.h"
  9. #include "electrocardiograph_tester.hpp"
  10. #include "logger.hpp"
  11. #include "qt_serial_datachannel.hpp"
  12. #include "widgetplot2d.h"
  13. #include "zexception.hpp"
  14. WidgetPlot2D *wp2d;
  15. using namespace std;
  16. using namespace iflytop;
  17. typedef enum {
  18. kone_lead_ecg,
  19. kthree_lead_ecg,
  20. kone_lead_ecg_v2,
  21. } device_type_t;
  22. static MainWindow *m_mainWindow;
  23. static QTDataChannel G_QTDataChannel;
  24. static device_type_t m_devicetype;
  25. #define TAG "MainWindow"
  26. static const char *fmt(const char *fmt, ...) {
  27. va_list args;
  28. va_start(args, fmt);
  29. static char buf[1024] = {0};
  30. vsnprintf(buf, sizeof(buf), fmt, args);
  31. va_end(args);
  32. return buf;
  33. }
  34. void MainWindow::log_output(QtMsgType type, const QMessageLogContext &context, const QString &msg) {}
  35. void MainWindow::doinui_slot(QFunction func) {
  36. if (func.get()) func.get()();
  37. }
  38. void MainWindow::ishow(const char *fmt, ...) {
  39. va_list args;
  40. va_start(args, fmt);
  41. char buf[1024] = {0};
  42. vsnprintf(buf, sizeof(buf), fmt, args);
  43. va_end(args);
  44. QString text(buf);
  45. QString info;
  46. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  47. info.append(" |");
  48. info.append(text);
  49. emit doinui_signal(QFunction([this, info]() { ui->instructionPreview->append(info); }));
  50. }
  51. void MainWindow::instructionPreviewClear() { ui->instructionPreview->document()->clear(); }
  52. void MainWindow::reportPreviewShow(const char *fmt, ...) {
  53. va_list args;
  54. va_start(args, fmt);
  55. char buf[1024] = {0};
  56. vsnprintf(buf, sizeof(buf), fmt, args);
  57. va_end(args);
  58. QString text(buf);
  59. QString info;
  60. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  61. info.append(text);
  62. emit doinui_signal(QFunction([this, info]() {
  63. if (ui->reportPreview->document()->lineCount() > 1000) {
  64. ui->reportPreview->document()->clear();
  65. }
  66. ui->reportPreview->append(info);
  67. }));
  68. }
  69. void MainWindow::blockDataUploadPreviewShow(const char *fmt, ...) {
  70. va_list args;
  71. va_start(args, fmt);
  72. char buf[1024] = {0};
  73. vsnprintf(buf, sizeof(buf), fmt, args);
  74. va_end(args);
  75. QString text(buf);
  76. QString info;
  77. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz "));
  78. info.append(text);
  79. emit doinui_signal(QFunction([this, info]() {
  80. if (ui->uploadDataPreview->document()->lineCount() > 1000) {
  81. ui->uploadDataPreview->document()->clear();
  82. }
  83. ui->uploadDataPreview->append(info);
  84. }));
  85. }
  86. void MainWindow::rawDataPreviewShow(const char *fmt, ...) {
  87. va_list args;
  88. va_start(args, fmt);
  89. char buf[1024] = {0};
  90. vsnprintf(buf, sizeof(buf), fmt, args);
  91. va_end(args);
  92. QString text(buf);
  93. QString info;
  94. info.append(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
  95. info.append(text);
  96. emit doinui_signal(QFunction([this, info]() {
  97. if (ui->rawDataPreview->document()->lineCount() > 1000) {
  98. ui->rawDataPreview->document()->clear();
  99. }
  100. ui->rawDataPreview->append(info);
  101. }));
  102. }
  103. // uploadDataPreview
  104. #pragma pack(push, 1)
  105. typedef struct {
  106. uint16_t header;
  107. int16_t wave1;
  108. int16_t wave2;
  109. int16_t wave3;
  110. int16_t wave4;
  111. int16_t wave5;
  112. uint8_t check;
  113. uint16_t tail;
  114. } Wave_t;
  115. #pragma pack(pop)
  116. void MainWindow::displayInfo(bool suc, QString info) {}
  117. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
  118. /*******************************************************************************
  119. * QT初始化 *
  120. *******************************************************************************/
  121. ui->setupUi(this);
  122. m_mainWindow = this;
  123. qRegisterMetaType<int32_t>("int32_t");
  124. qRegisterMetaType<uint32_t>("uint32_t");
  125. qRegisterMetaType<float>("float");
  126. qRegisterMetaType<function<void()>>("function<void()>");
  127. qRegisterMetaType<QFunction>("QFunction");
  128. connect(this, SIGNAL(doinui_signal(QFunction)), this, SLOT(doinui_slot(QFunction)));
  129. // qInstallMessageHandler(log_output);
  130. wp2d = new WidgetPlot2D();
  131. wp2d->initGraphName(QStringList() << "心电");
  132. /*******************************************************************************
  133. * *
  134. *******************************************************************************/
  135. constructUI();
  136. ui->TestCmd_writeSubICRegMask_p0->setPlaceholderText("寄存器地址");
  137. ui->TestCmd_writeSubICRegMask_p1->setPlaceholderText("偏移");
  138. ui->TestCmd_writeSubICRegMask_p2->setPlaceholderText("位数");
  139. ui->TestCmd_writeSubICRegMask_p3->setPlaceholderText("");
  140. ui->TestCmd_writeSubICReg_p0->setPlaceholderText("寄存器地址");
  141. ui->TestCmd_writeSubICReg_p1->setPlaceholderText("");
  142. /*******************************************************************************
  143. * *
  144. *******************************************************************************/
  145. G_QTDataChannel.init();
  146. ElectrocardiographTester::ins()->initialize(&G_QTDataChannel);
  147. }
  148. MainWindow::~MainWindow() { delete ui; }
  149. /*******************************************************************************
  150. * UI相关构造 *
  151. *******************************************************************************/
  152. void MainWindow::constructUI() {
  153. /*******************************************************************************
  154. * UI *
  155. *******************************************************************************/
  156. {
  157. const auto infos = QSerialPortInfo::availablePorts();
  158. for (const QSerialPortInfo &info : infos) {
  159. ui->serialPortCB->addItem(info.portName());
  160. }
  161. }
  162. ui->serialBaudrateCB->addItem("9600");
  163. ui->serialBaudrateCB->addItem("14400");
  164. ui->serialBaudrateCB->addItem("19200");
  165. ui->serialBaudrateCB->addItem("38400");
  166. ui->serialBaudrateCB->addItem("57600");
  167. ui->serialBaudrateCB->addItem("115200");
  168. ui->serialBaudrateCB->addItem("460800");
  169. ui->serialBaudrateCB->addItem("500000");
  170. ui->serialBaudrateCB->setCurrentIndex(6);
  171. connect(ui->serialPortRefreshKey, &QPushButton::clicked, this, [this](bool check) {
  172. ui->serialPortCB->clear();
  173. const auto infos = QSerialPortInfo::availablePorts();
  174. for (const QSerialPortInfo &info : infos) {
  175. ui->serialPortCB->addItem(info.portName());
  176. }
  177. });
  178. connect(ui->serialOpenKey, &QPushButton::clicked, this, [=](bool check) {
  179. // 打开串口
  180. if (ui->serialOpenKey->text() == "打开") {
  181. G_QTDataChannel.setPortName(ui->serialPortCB->currentText().toStdString());
  182. G_QTDataChannel.setBaudRate(ui->serialBaudrateCB->currentText().toInt());
  183. G_QTDataChannel.setDataBits(QSerialPort::Data8);
  184. G_QTDataChannel.setParity(QSerialPort::NoParity);
  185. G_QTDataChannel.setFlowControl(QSerialPort::NoFlowControl);
  186. G_QTDataChannel.setStopBits(QSerialPort::OneStop);
  187. if (!G_QTDataChannel.open()) {
  188. QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占??");
  189. return;
  190. }
  191. ui->serialOpenKey->setText("关闭");
  192. // 下拉菜单控件使能
  193. ui->serialBaudrateCB->setEnabled(false);
  194. ui->serialPortCB->setEnabled(false);
  195. ui->serialPortRefreshKey->setEnabled(false);
  196. } else {
  197. G_QTDataChannel.close();
  198. ui->serialOpenKey->setText("打开");
  199. ui->serialBaudrateCB->setEnabled(true);
  200. ui->serialPortCB->setEnabled(true);
  201. ui->serialPortRefreshKey->setEnabled(true);
  202. }
  203. });
  204. /*******************************************************************************
  205. * UI *
  206. *******************************************************************************/
  207. {
  208. ui->deviceType->addItem("单导联一代(M1001)");
  209. ui->deviceType->addItem("三导联一代(M1002)");
  210. ui->deviceType->addItem("单导联二代(M1003)");
  211. ui->deviceType->setCurrentIndex(0);
  212. connect(ui->deviceType, &QComboBox::currentTextChanged, this, [this](const QString &text) {
  213. if (text == "单导联一代(M1001)") {
  214. m_devicetype = kone_lead_ecg;
  215. } else if (text == "三导联一代(M1002)") {
  216. m_devicetype = kthree_lead_ecg;
  217. } else if (text == "单导联二代(M1003)") {
  218. m_devicetype = kone_lead_ecg_v2;
  219. }
  220. });
  221. }
  222. // 事件填充
  223. ElectrocardiographTester::ins()->regReportCB([this](bool checkok, ify_hrs_packet_t *report_packet, size_t len) {
  224. int reportType = report_packet->cmd;
  225. switch (reportType) {
  226. case ify_hrs_report_heartrate_data: {
  227. heartrate_report_packet_t *heartrate_report = (heartrate_report_packet_t *)report_packet;
  228. if (m_devicetype == kone_lead_ecg) {
  229. static uint32_t lastpacket_index = 0;
  230. static uint32_t lostpacket = 0;
  231. if ((lastpacket_index + 5) != (heartrate_report->sample_data_index)) {
  232. lostpacket++;
  233. }
  234. lastpacket_index = heartrate_report->sample_data_index;
  235. reportPreviewShow("[preview data ] lost:%d index %d", lostpacket, heartrate_report->sample_data_index);
  236. if (checkok) {
  237. uint16_t data0 = (uint16_t)(heartrate_report->data[0]) + ((uint16_t)heartrate_report->data[1] << 8);
  238. uint16_t data1 = (uint16_t)(heartrate_report->data[2]) + ((uint16_t)heartrate_report->data[3] << 8);
  239. uint16_t data2 = (uint16_t)(heartrate_report->data[4]) + ((uint16_t)heartrate_report->data[5] << 8);
  240. uint16_t data3 = (uint16_t)(heartrate_report->data[6]) + ((uint16_t)heartrate_report->data[7] << 8);
  241. uint16_t data4 = (uint16_t)(heartrate_report->data[8]) + ((uint16_t)heartrate_report->data[9] << 8);
  242. emit doinui_signal(QFunction([this, data0, data1, data2, data3, data4]() { //
  243. wp2d->addData("心电", data0, 0);
  244. wp2d->addData("心电", data1, 2);
  245. wp2d->addData("心电", data2, 4);
  246. wp2d->addData("心电", data3, 6);
  247. wp2d->addData("心电", data4, 8);
  248. // wp2d->addData("心电", data2);
  249. // wp2d->addData("心电", data3);
  250. // wp2d->addData("心电", data4);
  251. }));
  252. }
  253. } else if (m_devicetype == kthree_lead_ecg) {
  254. } else if (m_devicetype == kone_lead_ecg_v2) {
  255. if (checkok) {
  256. uint32_t packetlen = len - sizeof(heartrate_report_packet_t);
  257. static uint32_t lastpacket_index = 0;
  258. static uint32_t lostpacket = 0;
  259. if ((lastpacket_index + 50) != (heartrate_report->sample_data_index)) {
  260. lostpacket++;
  261. }
  262. lastpacket_index = heartrate_report->sample_data_index;
  263. uint32_t timestamp = *(uint32_t *)(&heartrate_report->data[50 * 4]);
  264. reportPreviewShow("[preview data ] timestamp:%10d lost:%d index %d packetlen %d", timestamp, lostpacket, heartrate_report->sample_data_index, packetlen);
  265. int32_t *frame = (int32_t *)heartrate_report->data;
  266. for (int i = 0; i < 50; i++) {
  267. int32_t data = frame[i];
  268. int32_t frameIndex = heartrate_report->sample_data_index + i;
  269. emit doinui_signal(QFunction([this, data, i]() { wp2d->addData("心电", data, i * 2); }));
  270. }
  271. }
  272. }
  273. break;
  274. }
  275. case ify_hrs_report_battery_level: {
  276. reportPreviewShow("[battery_level ]");
  277. break;
  278. }
  279. case ify_hrs_report_low_battey_level: {
  280. reportPreviewShow("[low_battey ]");
  281. break;
  282. }
  283. case ify_hrs_report_sample_finish_end: {
  284. reportPreviewShow("[sample_finish ]");
  285. break;
  286. }
  287. case ify_hrs_report_sensor_drop_detect: {
  288. sensor_drop_event_report_packet_t *sensor_drop_report = (sensor_drop_event_report_packet_t *)report_packet->data;
  289. reportPreviewShow("[sensor_drop ] %s %s", zhex2binary(sensor_drop_report->drop_state0).c_str(), zhex2binary(sensor_drop_report->drop_state1).c_str());
  290. break;
  291. }
  292. case ify_hrs_report_record_upload_end: {
  293. uint32_t checksum = *(uint32_t *)report_packet->data;
  294. reportPreviewShow("[upload end ] checksum: 0x%08x", checksum);
  295. break;
  296. }
  297. default:
  298. break;
  299. }
  300. });
  301. ElectrocardiographTester::ins()->regCh4CheckSumPacketReport([this](uint32_t rxcnt, uint32_t report_packet_checksum) { //
  302. blockDataUploadPreviewShow("RXCNT %d CHECKSUM 0x%08x", rxcnt, report_packet_checksum);
  303. });
  304. ElectrocardiographTester::ins()->regRawDataCB([this](raw_data_type_t type, uint8_t *hex, uint32_t hexlen) {
  305. if (type == kcmd_cmd) {
  306. rawDataPreviewShow("[CMD ] %s", zhex2str(hex, hexlen).c_str());
  307. } else if (type == kcmd_receipt) {
  308. rawDataPreviewShow("[RECEIPT] %s", zhex2str(hex, hexlen).c_str());
  309. } else if (type == kcmd_report) {
  310. rawDataPreviewShow("[REPORT ] %s", zhex2str(hex, hexlen).c_str());
  311. } else if (type == kcmd_ch4_data) {
  312. // rawDataPreviewShow("[CH4 ] %s", zhex2str(hex, hexlen).c_str());
  313. }
  314. });
  315. }
  316. void MainWindow::processException(zexception &e) { ishow("%s:%s", e.what(), ify_hrs_error_code_to_string((ify_hrs_error_code_t)e.ecode())); }
  317. void MainWindow::on_readDeviceVersion_clicked() {
  318. instructionPreviewClear();
  319. try {
  320. device_version_info_receipt_t version;
  321. ElectrocardiographTester::ins()->readDeviceVersion(&version);
  322. ishow("-------------- version ----------------");
  323. ishow(" blestack_version: %d", version.blestack_version);
  324. ishow(" bootloader_version: %d", version.bootloader_version);
  325. ishow(" firmware_version: %d", version.firmware_version);
  326. ishow(" hardware_version: %d", version.hardware_version);
  327. } catch (zexception &exception) {
  328. processException(exception);
  329. }
  330. }
  331. void MainWindow::on_readDeviceState_clicked() {
  332. instructionPreviewClear();
  333. try {
  334. device_state_receipt_t state;
  335. ElectrocardiographTester::ins()->readDeviceState(&state);
  336. ishow("-------------- state ----------------");
  337. ishow(" drop_state0: %s", zhex2binary(state.drop_state0).c_str());
  338. ishow(" drop_state1: %s", zhex2binary(state.drop_state1).c_str());
  339. ishow(" sampling_state: %d", state.device_state0.sampling_state);
  340. ishow(" report_state: %d", state.device_state0.report_state);
  341. ishow(" low_battery: %d", state.device_state0.low_battery);
  342. ishow(" full_storge: %d", state.device_state0.full_storge);
  343. ishow(" holder: %d", state.device_state0.holder);
  344. ishow(" powerlevel: %d", state.powerlevel);
  345. ishow(" storage_item_num: %d", state.storage_item_num);
  346. } catch (zexception &exception) {
  347. processException(exception);
  348. }
  349. }
  350. void MainWindow::on_readTime_clicked() {
  351. instructionPreviewClear();
  352. try {
  353. read_time_receipt_t time;
  354. ElectrocardiographTester::ins()->readTime(&time);
  355. ishow("-------------- time ----------------");
  356. ishow(" %d/%d/%d %d:%d:%d", time.year + 2000, time.month, time.day, time.hour, time.minute, time.second);
  357. } catch (zexception &exception) {
  358. processException(exception);
  359. }
  360. }
  361. void MainWindow::on_syncTime_clicked() {
  362. instructionPreviewClear();
  363. try {
  364. // 获取系统时间
  365. QDateTime now = QDateTime::currentDateTime();
  366. ElectrocardiographTester::ins()->syncTime(now.date().year() - 2000, now.date().month(), now.date().day(), now.time().hour(), now.time().minute(), now.time().second());
  367. ishow("sync time success!");
  368. } catch (zexception &exception) {
  369. processException(exception);
  370. }
  371. }
  372. std::string zhex2time(const uint8_t *hex, size_t len) {
  373. std::string str;
  374. if (len < 6) return str;
  375. str.append(fmt("%d/%d/%d %2d:%2d:%2d", hex[0] + 2000, hex[1], hex[2], hex[3], hex[4], hex[5]));
  376. return str;
  377. }
  378. void MainWindow::on_readAllRecords_clicked() {
  379. // 读取当前有多少条记录
  380. instructionPreviewClear();
  381. try {
  382. device_state_receipt_t state;
  383. ElectrocardiographTester::ins()->readDeviceState(&state);
  384. ishow("index recordid frameNum dataSize sensorNum captRate captPrec compAlgo checksum");
  385. for (int32_t i = 0; i < state.storage_item_num; i++) {
  386. read_record_info_receipt_t record;
  387. ElectrocardiographTester::ins()->readRecordsInfo(i, &record);
  388. ishow("%d %s %8d %8d %8d %8d %8d %8d 0x%08x", i, zhex2time(record.record_id, 6).c_str(), record.frameNum, record.dataSize, record.sensorNum, record.captureRate, record.capturePrecision, record.compressAlgorithm, record.checksum);
  389. }
  390. } catch (zexception &exception) {
  391. processException(exception);
  392. }
  393. }
  394. void MainWindow::on_startUploadRecord_clicked() {
  395. instructionPreviewClear();
  396. int reportIndex = ui->startUploadRecord_p0->toPlainText().toInt();
  397. try {
  398. read_record_info_receipt_t record;
  399. ElectrocardiographTester::ins()->readRecordsInfo(reportIndex, &record);
  400. ElectrocardiographTester::ins()->startUploadRecord(record.record_id);
  401. ishow("start upload record [%s] success", zhex2time(record.record_id, 6).c_str());
  402. } catch (zexception &exception) {
  403. processException(exception);
  404. }
  405. }
  406. void MainWindow::on_readSensorInfo_clicked() {
  407. instructionPreviewClear();
  408. try {
  409. sensor_info_receipt_t sensor;
  410. ElectrocardiographTester::ins()->readSensorInfo(&sensor);
  411. ishow("-------------- sensor ----------------");
  412. ishow(" sensor_num: %d", sensor.sensor_num);
  413. ishow(" sensor_precision: %d", sensor.sensor_precision);
  414. ishow(" sensor_sample_rate:%d", sensor.sensor_sample_rate);
  415. ishow(" sensor0_pos: %d", sensor.sensor0_pos);
  416. ishow(" sensor1_pos: %d", sensor.sensor1_pos);
  417. ishow(" sensor2_pos: %d", sensor.sensor2_pos);
  418. } catch (zexception &exception) {
  419. processException(exception);
  420. }
  421. }
  422. void MainWindow::on_readSN_clicked() {
  423. instructionPreviewClear();
  424. try {
  425. string sn;
  426. ElectrocardiographTester::ins()->readSn(sn);
  427. ishow("-------------- sn ----------------");
  428. ishow(" sn: %s", sn.c_str());
  429. } catch (zexception &exception) {
  430. processException(exception);
  431. }
  432. }
  433. void MainWindow::on_stopUploadRecord_clicked() {
  434. instructionPreviewClear();
  435. try {
  436. ElectrocardiographTester::ins()->stopUploadRecord();
  437. ishow("stop upload record success");
  438. } catch (zexception &exception) {
  439. processException(exception);
  440. }
  441. }
  442. void MainWindow::on_delRecord_clicked() {
  443. instructionPreviewClear();
  444. int reportIndex = ui->delRecord_p0->toPlainText().toInt();
  445. try {
  446. read_record_info_receipt_t record;
  447. ElectrocardiographTester::ins()->readRecordsInfo(reportIndex, &record);
  448. ElectrocardiographTester::ins()->delRecord(record.record_id);
  449. ishow("delete record [%s] success", zhex2time(record.record_id, 6).c_str());
  450. } catch (zexception &exception) {
  451. processException(exception);
  452. }
  453. }
  454. #if 0
  455. void MainWindow::on_startCapture_clicked() {
  456. instructionPreviewClear();
  457. try {
  458. ElectrocardiographTester::ins()->startCapture();
  459. ishow("start capture success");
  460. } catch (zexception &exception) {
  461. processException(exception);
  462. }
  463. }
  464. void MainWindow::on_stopCapture_clicked() {
  465. instructionPreviewClear();
  466. try {
  467. ElectrocardiographTester::ins()->stopCapture();
  468. ishow("stop capture success");
  469. } catch (zexception &exception) {
  470. processException(exception);
  471. }
  472. }
  473. #endif
  474. void MainWindow::on_startRealtimeReport_clicked() {
  475. instructionPreviewClear();
  476. try {
  477. ElectrocardiographTester::ins()->startRealtimeReport();
  478. ishow("start realtime report success");
  479. wp2d->show();
  480. } catch (zexception &exception) {
  481. processException(exception);
  482. }
  483. }
  484. void MainWindow::on_stopRealtimeReport_clicked() {
  485. instructionPreviewClear();
  486. try {
  487. ElectrocardiographTester::ins()->stopRealtimeReport();
  488. ishow("stop realtime report success");
  489. wp2d->hide();
  490. } catch (zexception &exception) {
  491. processException(exception);
  492. }
  493. }
  494. void MainWindow::on_clearPreview_clicked() {
  495. ui->reportPreview->document()->clear();
  496. ui->uploadDataPreview->document()->clear();
  497. ui->rawDataPreview->document()->clear();
  498. ui->instructionPreview->document()->clear();
  499. }
  500. void MainWindow::on_TestCmd_readSubIcRegs_clicked() {
  501. instructionPreviewClear();
  502. try {
  503. uint8_t data[12];
  504. data[ADS129X_REG_ID] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_ID);
  505. data[ADS129X_REG_CONFIG1] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CONFIG1);
  506. data[ADS129X_REG_CONFIG2] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CONFIG2);
  507. data[ADS129X_REG_LOFF] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_LOFF);
  508. data[ADS129X_REG_CH1SET] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CH1SET);
  509. data[ADS129X_REG_CH2SET] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CH2SET);
  510. data[ADS129X_REG_RLDSENS] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_RLDSENS);
  511. data[ADS129X_REG_LOFFSENS] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_LOFFSENS);
  512. data[ADS129X_REG_LOFFSTAT] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_LOFFSTAT);
  513. data[ADS129X_REG_RESP1] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_RESP1);
  514. data[ADS129X_REG_RESP2] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_RESP2);
  515. data[ADS129X_REG_GPIO] = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_GPIO);
  516. ishow("reg %10s %02d: 0x%02x", "ID", ADS129X_REG_ID, data[ADS129X_REG_ID]);
  517. ishow("reg %10s %02d: 0x%02x", "CONFIG1", ADS129X_REG_CONFIG1, data[ADS129X_REG_CONFIG1]);
  518. ishow("reg %10s %02d: 0x%02x", "CONFIG2", ADS129X_REG_CONFIG2, data[ADS129X_REG_CONFIG2]);
  519. ishow("reg %10s %02d: 0x%02x", "LOFF", ADS129X_REG_LOFF, data[ADS129X_REG_LOFF]);
  520. ishow("reg %10s %02d: 0x%02x", "CH1SET", ADS129X_REG_CH1SET, data[ADS129X_REG_CH1SET]);
  521. ishow("reg %10s %02d: 0x%02x", "CH2SET", ADS129X_REG_CH2SET, data[ADS129X_REG_CH2SET]);
  522. ishow("reg %10s %02d: 0x%02x", "RLDSENS", ADS129X_REG_RLDSENS, data[ADS129X_REG_RLDSENS]);
  523. ishow("reg %10s %02d: 0x%02x", "LOFFSENS", ADS129X_REG_LOFFSENS, data[ADS129X_REG_LOFFSENS]);
  524. ishow("reg %10s %02d: 0x%02x %s", "LOFFSTAT", ADS129X_REG_LOFFSTAT, data[ADS129X_REG_LOFFSTAT], zhex2binary(data[ADS129X_REG_LOFFSTAT]).c_str());
  525. ishow("reg %10s %02d: 0x%02x", "RESP1", ADS129X_REG_RESP1, data[ADS129X_REG_RESP1]);
  526. ishow("reg %10s %02d: 0x%02x", "RESP2", ADS129X_REG_RESP2, data[ADS129X_REG_RESP2]);
  527. ishow("reg %10s %02d: 0x%02x", "GPIO", ADS129X_REG_GPIO, data[ADS129X_REG_GPIO]);
  528. } catch (zexception &exception) {
  529. processException(exception);
  530. }
  531. }
  532. void MainWindow::on_TestCmd_writeSubICReg_clicked() {
  533. uint8_t add = ui->TestCmd_writeSubICReg_p0->toPlainText().toInt();
  534. uint8_t val = ui->TestCmd_writeSubICReg_p1->toPlainText().toInt();
  535. instructionPreviewClear();
  536. try {
  537. ElectrocardiographTester::ins()->testCmdWriteReg(add, val);
  538. ishow("write reg %d: 0x%02x success", add, val);
  539. } catch (zexception &exception) {
  540. processException(exception);
  541. }
  542. }
  543. void MainWindow::on_TestCmd_writeSubICRegMask_clicked() {
  544. uint8_t add = ui->TestCmd_writeSubICRegMask_p0->toPlainText().toInt();
  545. uint8_t off = ui->TestCmd_writeSubICRegMask_p1->toPlainText().toInt();
  546. uint8_t bitnum = ui->TestCmd_writeSubICRegMask_p2->toPlainText().toInt();
  547. uint8_t val = ui->TestCmd_writeSubICRegMask_p3->toPlainText().toInt();
  548. instructionPreviewClear();
  549. try {
  550. uint8_t regval = ElectrocardiographTester::ins()->testCmdReadReg(add);
  551. uint8_t oldval = regval;
  552. uint8_t mask = (1 << bitnum) - 1;
  553. mask = mask << off;
  554. regval = regval & (~mask);
  555. regval = regval | (val << off);
  556. ElectrocardiographTester::ins()->testCmdWriteReg(add, regval);
  557. ishow("write reg %d: 0x%02x -> 0x%02x success", add, oldval, regval);
  558. } catch (const std::exception &e) {
  559. std::cerr << e.what() << '\n';
  560. }
  561. }
  562. void MainWindow::on_TestCmd_startCapture_clicked() {
  563. instructionPreviewClear();
  564. try {
  565. ElectrocardiographTester::ins()->testCmdStartCapture();
  566. ishow("call start capture success");
  567. wp2d->show();
  568. } catch (zexception &exception) {
  569. processException(exception);
  570. }
  571. }
  572. void MainWindow::on_TestCmd_stopCapture_clicked() {
  573. instructionPreviewClear();
  574. try {
  575. ElectrocardiographTester::ins()->testCmdStopCapture();
  576. ishow("call stop capture success");
  577. } catch (zexception &exception) {
  578. processException(exception);
  579. }
  580. }
  581. void MainWindow::on_TestCmd_changeECGSrcToSquareWave_clicked() {
  582. instructionPreviewClear();
  583. try {
  584. uint8_t cfg2 = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CONFIG2);
  585. uint8_t ch1set = ElectrocardiographTester::ins()->testCmdReadReg(ADS129X_REG_CH1SET);
  586. cfg2 = ADS129X_SET_BITS(cfg2, ADS129X_INT_TEST, ADS129X_INT_TEST_ON);
  587. cfg2 = ADS129X_SET_BITS(cfg2, ADS129X_INT_FREQ, ADS129X_INT_FREQ_AC);
  588. ch1set = ADS129X_SET_BITS(ch1set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST);
  589. ElectrocardiographTester::ins()->testCmdWriteReg(ADS129X_REG_CONFIG2, cfg2);
  590. ElectrocardiographTester::ins()->testCmdWriteReg(ADS129X_REG_CH1SET, ch1set);
  591. ishow("call change ECG src to square wave success");
  592. } catch (zexception &exception) {
  593. processException(exception);
  594. }
  595. }
  596. void MainWindow::on_resetDevice_clicked() {
  597. instructionPreviewClear();
  598. try {
  599. ElectrocardiographTester::ins()->reset();
  600. } catch (zexception &exception) {
  601. // processException(exception);
  602. }
  603. ishow("call reset device success");
  604. }