From 3c3f462bbcd062eeddb5e1cc6210b5649a9345c6 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Mon, 5 Aug 2024 10:41:32 +0800 Subject: [PATCH] update --- src/app/main.cpp | 46 ---- src/app/syncbox16ch/syncbox16ch_sdk.cpp | 6 + src/app/syncbox16ch/syncbox16ch_sdk.hpp | 34 +++ src/app/zfpga_commander/zfpga_commander.cpp | 276 ------------------- src/app/zfpga_commander/zfpga_commander.hpp | 110 -------- src/main.cpp | 46 ++++ src/protocol/zfpga_commander/zfpga_commander.cpp | 325 +++++++++++++++++++++++ src/protocol/zfpga_commander/zfpga_commander.hpp | 127 +++++++++ zfpga_basic_protocol | 2 +- 9 files changed, 539 insertions(+), 433 deletions(-) delete mode 100644 src/app/main.cpp create mode 100644 src/app/syncbox16ch/syncbox16ch_sdk.cpp create mode 100644 src/app/syncbox16ch/syncbox16ch_sdk.hpp delete mode 100644 src/app/zfpga_commander/zfpga_commander.cpp delete mode 100644 src/app/zfpga_commander/zfpga_commander.hpp create mode 100644 src/main.cpp create mode 100644 src/protocol/zfpga_commander/zfpga_commander.cpp create mode 100644 src/protocol/zfpga_commander/zfpga_commander.hpp diff --git a/src/app/main.cpp b/src/app/main.cpp deleted file mode 100644 index c8f2bb6..0000000 --- a/src/app/main.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -// #include -#include -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zqui/zqui/mainwindow.h" -#include "zqui/zqui/zqui.hpp" -// -#include "app/syncbox16ch/syncbox16ch.h" -// -#include -// -#include -// -#define TAG "Main" -using namespace std; -QT_CHARTS_USE_NAMESPACE - -int main(int argc, char* argv[]) { - WSADATA wsaData; - WSAStartup(MAKEWORD(2, 2), &wsaData); - - QApplication a(argc, argv); - - ZQUI::ins()->regAppBuilder([](QWidget* p) { return new SyncBox16CH(p); }); - ZQUI::ins()->initialize(); - - // DOINUI([]() { ZQUI::ins()->mainW()->setVersionInfo(1, "APP_VERSION", "1.0.0"); }); - - return a.exec(); -} diff --git a/src/app/syncbox16ch/syncbox16ch_sdk.cpp b/src/app/syncbox16ch/syncbox16ch_sdk.cpp new file mode 100644 index 0000000..043b47e --- /dev/null +++ b/src/app/syncbox16ch/syncbox16ch_sdk.cpp @@ -0,0 +1,6 @@ +#include "syncbox16ch_sdk.hpp" +using namespace iflytop; + +void SyncBox16ChSDK::initialize() { + +} diff --git a/src/app/syncbox16ch/syncbox16ch_sdk.hpp b/src/app/syncbox16ch/syncbox16ch_sdk.hpp new file mode 100644 index 0000000..06e9e55 --- /dev/null +++ b/src/app/syncbox16ch/syncbox16ch_sdk.hpp @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "protocol/zfpga_commander/zfpga_commander.hpp" +#include "zfpga_basic_protocol/zaf_protocol.h" +#include "zfpga_basic_protocol/zaf_regs.hpp" + +namespace iflytop { + +using namespace std; + +class SyncBox16ChSDK { + + public: + static SyncBox16ChSDK *ins() { + static SyncBox16ChSDK cmder; + return &cmder; + } + + void initialize(); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/src/app/zfpga_commander/zfpga_commander.cpp b/src/app/zfpga_commander/zfpga_commander.cpp deleted file mode 100644 index c6aadf8..0000000 --- a/src/app/zfpga_commander/zfpga_commander.cpp +++ /dev/null @@ -1,276 +0,0 @@ -#include "zfpga_commander.hpp" - -#include -#include - -// -#include "zqui/base/logger.hpp" -#include "zqui/base/zexception.hpp" -#include "zqui/channelmgr/channelmgr.hpp" - -using namespace iflytop; - -#define TAG "Syncbox16ch" - -QTSerialChannel *serial_ch; - -#define PACKET_LEN(__packet) (sizeof(zaf_packet_header_t) + (__packet->ndata) * sizeof(uint32_t) + 1 /*checksum*/ + 2 /*tail*/) -#define DO_CMD(exptr) \ - { \ - zaf_error_code_t ecode = exptr; \ - if (ecode != kaf_ec_success) return ecode; \ - } - -void ZFPGACommander::initialize() { - // - serial_ch = &ChannelMgr::ins()->serialCh; - serial_ch->regRxListener([this](uint8_t *data, size_t len) { - { - lock_guard lock(lock_); - if (len + m_rxlen > sizeof(m_rxcache)) { - m_rxlen = 0; - } - memcpy(m_rxcache + m_rxlen, data, len); - m_rxlen += len; - } - }); - - m_thread.reset(new thread([this]() { - uint32_t last_rx_cnt = 0; - uint8_t rx_process_cache[1024]; - uint32_t rx_process_cache_len; - while (true) { - this_thread::sleep_for(chrono::milliseconds(4)); - - { - lock_guard lock(lock_); - if (last_rx_cnt == m_rxlen && m_rxlen != 0) { - memcpy(rx_process_cache, m_rxcache, m_rxlen); - rx_process_cache_len = m_rxlen; - - m_rxlen = 0; - last_rx_cnt = 0; - } - } - - if (rx_process_cache_len != 0) { - processRxData(rx_process_cache, rx_process_cache_len); - memset(rx_process_cache, 0, sizeof(rx_process_cache)); - rx_process_cache_len = 0; - } - - last_rx_cnt = m_rxlen; - } - })); -} -void ZFPGACommander::regRawDataListener(binary_cb_t cb) {} - -void ZFPGACommander::processRxData(uint8_t *rx, uint32_t rxlen) { - for (uint32_t i = 0; i < rxlen; i++) { - zaf_packet_header_t *header = (zaf_packet_header_t *)(&rx[i]); - uint8_t *packetu8 = &rx[i]; - - if (header->packet_header == PACKET_HEADER) { - uint8_t check = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 0]; - uint8_t tail0 = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 1]; - uint8_t tail1 = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 2]; - - uint16_t tail = (tail1 << 8) | tail0; - - uint8_t expectcheck = 0; - for (uint32_t j = 2; j < header->ndata * 4 + sizeof(zaf_packet_header_t); j++) { - expectcheck += packetu8[j]; - } - - if (tail == PACKET_TAIL) { - if (expectcheck == check) { - processRxPacket(header); - } else { - ZLOGE(TAG, "Rx packet check error %d != %d", expectcheck, check); - } - } - } - } -} -void ZFPGACommander::processRxPacket(zaf_packet_header_t *packet) { - // - // ZLOGI(TAG, "RX packet"); - // ZLOGI(TAG, " type :%d", packet->packet_type); - // ZLOGI(TAG, " index :%d", packet->index); - // ZLOGI(TAG, " cmd :%d", packet->cmd); - // ZLOGI(TAG, " ndata :%d", packet->ndata); - // for (uint32_t i = 0; i < packet->ndata; i++) { - // ZLOGI(TAG, " data[%d]:%d", i, packet->data[i]); - // } - // ZLOGI(TAG, "Rx....."); - uint32_t packetlen = sizeof(zaf_packet_header_t) + packet->ndata * 4 + 3; - - if (m_raw_data_cb) { - m_raw_data_cb(kuart_raw_rx, (uint8_t *)packet, packetlen); - } - if (packet->packet_type == kzaf_packet_type_receipt) { - lock_guard lock(m_rxReceiptContext_lock); - if (m_rxReceiptContext.waittingForReceipt) { - if (m_rxReceiptContext.waittingIndex == packet->index) { - m_rxReceiptContext.receiptIsReady = true; - m_rxReceiptContext.receiptLen = PACKET_LEN(packet); - memcpy(m_rxReceiptContext.receipt, packet, PACKET_LEN(packet)); - } - m_rxReceiptContext.waittingForReceipt = false; - } - } else if (packet->packet_type == kzaf_packet_type_heart) { - } -} - -void ZFPGACommander::resetRxContext(int32_t cmdIndex) { - lock_guard lock(m_rxReceiptContext_lock); - m_rxReceiptContext.waittingIndex = cmdIndex; - m_rxReceiptContext.waittingForReceipt = true; - m_rxReceiptContext.receiptIsReady = false; - m_rxReceiptContext.receiptLen = 0; -} - -void ZFPGACommander::sendPacket(zaf_packet_header_t *packet, uint32_t len, uint32_t overtime) { - zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; - - resetRxContext(packet->index); - - if (serial_ch->isOpen() == false) { - throw zexception(ke_invalid_packet_format, "channel is not open"); - } - if (m_raw_data_cb) { - m_raw_data_cb(kuart_raw_tx, (uint8_t *)packet, PACKET_LEN(packet)); - } - serial_ch->send((uint8_t *)packet, len); - for (size_t i = 0; i < overtime; i++) { - { - lock_guard lock(m_rxReceiptContext_lock); - if (m_rxReceiptContext.receiptIsReady) { - break; - } - } - this_thread::sleep_for(chrono::milliseconds(1)); - } - - if (m_rxReceiptContext.receiptIsReady) { - if (rxpacket->data[0] != 0) { - throw zexception(rxpacket->data[0], zaf_ecode_to_string((zaf_error_code_t)rxpacket->data[0])); - } else { - return; - } - } else { - } - - throw zexception(ke_overtime, "overtime"); -} - -zaf_packet_header_t *ZFPGACommander::getReceipt() { return (zaf_packet_header_t *)&(m_rxReceiptContext.receipt[0]); } - -void ZFPGACommander::writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms) { - Reginfo *reg = GetRegInfo(regadd); - - if (reg->flag & kreg_flag_force_write) { - _writeReg(regadd, regvalue, regbackvalue, overtime_ms); - } else if (reg->dirty) { - _writeReg(regadd, regvalue, regbackvalue, overtime_ms); - } else { - regbackvalue = reg->regshadow; - } - reg->dirty = false; - reg->regshadow = regvalue; - return; -} -void ZFPGACommander::readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms) { - Reginfo *reg = GetRegInfo(regadd); - - if ((reg->flag & kreg_flag_force_read)) { - _readReg(regadd, regvalue, overtime_ms); - } else if (reg->dirty) { - _readReg(regadd, regvalue, overtime_ms); - } else { - regvalue = reg->regshadow; - } - reg->dirty = false; - reg->regshadow = regvalue; -} - -void ZFPGACommander::_writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms) { - // - lock_guard lock(m_tx_lock); - - uint8_t txdata[128] = {0}; - - zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata; - zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; - - txpacket->packet_header = PACKET_HEADER; - txpacket->packet_type = kzaf_packet_type_cmd; - txpacket->index = ++txindex; - txpacket->cmd = kzaf_cmd_reg_write; - txpacket->ndata = 2; - txpacket->data[0] = regadd; - txpacket->data[1] = regvalue; - - uint32_t txpacklen = PACKET_LEN(txpacket); - uint8_t checksum = 0; - for (uint32_t i = 2; i < txpacklen - 3; i++) { - checksum += txdata[i]; - } - txdata[txpacklen - 3] = checksum; - txdata[txpacklen - 2] = PACKET_TAIL & 0xFF; - txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF; - - sendPacket(txpacket, txpacklen, overtime_ms); - regbackvalue = rxpacket->data[1]; -} -void ZFPGACommander::_readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms) { - lock_guard lock(m_tx_lock); - - uint8_t txdata[128] = {0}; - - zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata; - zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; - - txpacket->packet_header = PACKET_HEADER; - txpacket->packet_type = kzaf_packet_type_cmd; - txpacket->index = ++txindex; - txpacket->cmd = kzaf_cmd_reg_read; - txpacket->ndata = 1; - txpacket->data[0] = regadd; - - uint32_t txpacklen = PACKET_LEN(txpacket); - uint8_t checksum = 0; - for (uint32_t i = 2; i < txpacklen - 3; i++) { - checksum += txdata[i]; - } - txdata[txpacklen - 3] = checksum; - txdata[txpacklen - 2] = PACKET_TAIL & 0xFF; - txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF; - - sendPacket(txpacket, txpacklen, overtime_ms); - regvalue = rxpacket->data[1]; - - // ZLOGI(TAG, "RX packet"); - // ZLOGI(TAG, " type :%d", rxpacket->packet_type); - // ZLOGI(TAG, " index :%d", rxpacket->index); - // ZLOGI(TAG, " cmd :%d", rxpacket->cmd); - // ZLOGI(TAG, " ndata :%d", rxpacket->ndata); - // for (uint32_t i = 0; i < rxpacket->ndata; i++) { - // ZLOGI(TAG, " data[%d]:%d", i, rxpacket->data[i]); - // } - // ZLOGI(TAG, "RX:%d", regvalue); -} - -Reginfo *ZFPGACommander::GetRegInfo(uint32_t add) { - auto it = m_reginfoMap.find(add); - if (it != m_reginfoMap.end()) { - return &it->second; - } - m_reginfoMap.insert(make_pair(add, Reginfo())); - return &m_reginfoMap[add]; -} -void ZFPGACommander::RegInfo_Reset() { - for (auto &it : m_reginfoMap) { - it.second.dirty = true; - } -} \ No newline at end of file diff --git a/src/app/zfpga_commander/zfpga_commander.hpp b/src/app/zfpga_commander/zfpga_commander.hpp deleted file mode 100644 index 853215c..0000000 --- a/src/app/zfpga_commander/zfpga_commander.hpp +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zfpga_basic_protocol\zaf_protocol.h" -#include "zfpga_basic_protocol\zaf_regs.hpp" - -namespace iflytop { - -using namespace std; - -typedef enum { - kuart_raw_tx, - kuart_raw_rx, -} uart_message_type_t; - -typedef function device_state_cb_t; - -typedef function binary_cb_t; - -class ZFPGARxReceiptContext { - public: - bool waittingForReceipt; - bool receiptIsReady; - uint16_t waittingIndex; - uint8_t receipt[1024]; - size_t receiptLen; -}; - -typedef enum { - - kreg_flag_r = 0x01, // 可读 - kreg_flag_w = 0x01 << 1, // 可写 - kreg_flag_force_read = 0x01 << 2, // 易变寄存器 - kreg_flag_force_write = 0x01 << 3, // 易变寄存器 - - kreg_flag_rw = kreg_flag_r | kreg_flag_w, -} reg_flag_t; - -class Reginfo { - public: - uint32_t regadd = 0; - uint32_t flag = kreg_flag_rw; - uint32_t regshadow = 0; - bool dirty = true; - - public: -}; - -class ZFPGACommander { - ZFPGACommander() {} - - uint8_t m_rxcache[1024]; - size_t m_rxlen = 0; - - mutex lock_; - - unique_ptr m_thread; - - ZFPGARxReceiptContext m_rxReceiptContext; - mutex m_rxReceiptContext_lock; - mutex m_tx_lock; - - binary_cb_t m_raw_data_cb; - uint16_t txindex = 0; - - map m_reginfoMap; - - public: - static ZFPGACommander *ins() { - static ZFPGACommander cmder; - return &cmder; - } - - void initialize(); - void regRawDataListener(binary_cb_t cb); - - public: - void writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms); - void readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms); - void sendPacket(zaf_packet_header_t *packet, uint32_t len, uint32_t overtime); - - zaf_packet_header_t *getReceipt(); - - private: - void _writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms); - void _readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms); - - private: - void resetRxContext(int32_t cmdIndex); - void processRxData(uint8_t *rx, uint32_t rxlen); - void processRxPacket(zaf_packet_header_t *packet); - void setRxContext(int32_t cmdIndex); - - private: - Reginfo *GetRegInfo(uint32_t add); - void RegInfo_Reset(); -}; - -} // namespace iflytop \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c8f2bb6 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,46 @@ +#include +#include +// #include +#include +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zqui/zqui/mainwindow.h" +#include "zqui/zqui/zqui.hpp" +// +#include "app/syncbox16ch/syncbox16ch.h" +// +#include +// +#include +// +#define TAG "Main" +using namespace std; +QT_CHARTS_USE_NAMESPACE + +int main(int argc, char* argv[]) { + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); + + QApplication a(argc, argv); + + ZQUI::ins()->regAppBuilder([](QWidget* p) { return new SyncBox16CH(p); }); + ZQUI::ins()->initialize(); + + // DOINUI([]() { ZQUI::ins()->mainW()->setVersionInfo(1, "APP_VERSION", "1.0.0"); }); + + return a.exec(); +} diff --git a/src/protocol/zfpga_commander/zfpga_commander.cpp b/src/protocol/zfpga_commander/zfpga_commander.cpp new file mode 100644 index 0000000..5bdd60b --- /dev/null +++ b/src/protocol/zfpga_commander/zfpga_commander.cpp @@ -0,0 +1,325 @@ +#include "zfpga_commander.hpp" + +#include +#include + +// +#include "zqui/base/logger.hpp" +#include "zqui/base/zexception.hpp" +#include "zqui/channelmgr/channelmgr.hpp" + +using namespace iflytop; + +#define TAG "Syncbox16ch" + +QTSerialChannel *serial_ch; + +#define PACKET_LEN(__packet) (sizeof(zaf_packet_header_t) + (__packet->ndata) * sizeof(uint32_t) + 1 /*checksum*/ + 2 /*tail*/) +#define DO_CMD(exptr) \ + { \ + zaf_error_code_t ecode = exptr; \ + if (ecode != kaf_ec_success) return ecode; \ + } + +void ZFPGACommander::initialize() { + // + serial_ch = &ChannelMgr::ins()->serialCh; + serial_ch->regRxListener([this](uint8_t *data, size_t len) { + { + lock_guard lock(lock_); + if (len + m_rxlen > sizeof(m_rxcache)) { + m_rxlen = 0; + } + memcpy(m_rxcache + m_rxlen, data, len); + m_rxlen += len; + } + }); + + m_thread.reset(new thread([this]() { + uint32_t last_rx_cnt = 0; + uint8_t rx_process_cache[1024]; + uint32_t rx_process_cache_len; + while (true) { + this_thread::sleep_for(chrono::milliseconds(4)); + + { + lock_guard lock(lock_); + if (last_rx_cnt == m_rxlen && m_rxlen != 0) { + memcpy(rx_process_cache, m_rxcache, m_rxlen); + rx_process_cache_len = m_rxlen; + + m_rxlen = 0; + last_rx_cnt = 0; + } + } + + if (rx_process_cache_len != 0) { + processRxData(rx_process_cache, rx_process_cache_len); + memset(rx_process_cache, 0, sizeof(rx_process_cache)); + rx_process_cache_len = 0; + } + + last_rx_cnt = m_rxlen; + } + })); +} +void ZFPGACommander::regRawDataListener(binary_cb_t cb) {} + +void ZFPGACommander::processRxData(uint8_t *rx, uint32_t rxlen) { + for (uint32_t i = 0; i < rxlen; i++) { + zaf_packet_header_t *header = (zaf_packet_header_t *)(&rx[i]); + uint8_t *packetu8 = &rx[i]; + + if (header->packet_header == PACKET_HEADER) { + uint8_t check = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 0]; + uint8_t tail0 = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 1]; + uint8_t tail1 = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 2]; + + uint16_t tail = (tail1 << 8) | tail0; + + uint8_t expectcheck = 0; + for (uint32_t j = 2; j < header->ndata * 4 + sizeof(zaf_packet_header_t); j++) { + expectcheck += packetu8[j]; + } + + if (tail == PACKET_TAIL) { + if (expectcheck == check) { + processRxPacket(header); + } else { + ZLOGE(TAG, "Rx packet check error %d != %d", expectcheck, check); + } + } + } + } +} +void ZFPGACommander::processRxPacket(zaf_packet_header_t *packet) { + // + // ZLOGI(TAG, "RX packet"); + // ZLOGI(TAG, " type :%d", packet->packet_type); + // ZLOGI(TAG, " index :%d", packet->index); + // ZLOGI(TAG, " cmd :%d", packet->cmd); + // ZLOGI(TAG, " ndata :%d", packet->ndata); + // for (uint32_t i = 0; i < packet->ndata; i++) { + // ZLOGI(TAG, " data[%d]:%d", i, packet->data[i]); + // } + // ZLOGI(TAG, "Rx....."); + uint32_t packetlen = sizeof(zaf_packet_header_t) + packet->ndata * 4 + 3; + + if (m_raw_data_cb) { + m_raw_data_cb(kuart_raw_rx, (uint8_t *)packet, packetlen); + } + if (packet->packet_type == kzaf_packet_type_receipt) { + lock_guard lock(m_rxReceiptContext_lock); + if (m_rxReceiptContext.waittingForReceipt) { + if (m_rxReceiptContext.waittingIndex == packet->index) { + m_rxReceiptContext.receiptIsReady = true; + m_rxReceiptContext.receiptLen = PACKET_LEN(packet); + memcpy(m_rxReceiptContext.receipt, packet, PACKET_LEN(packet)); + } + m_rxReceiptContext.waittingForReceipt = false; + } + } else if (packet->packet_type == kzaf_packet_type_heart) { + } +} + +void ZFPGACommander::resetRxContext(int32_t cmdIndex) { + lock_guard lock(m_rxReceiptContext_lock); + m_rxReceiptContext.waittingIndex = cmdIndex; + m_rxReceiptContext.waittingForReceipt = true; + m_rxReceiptContext.receiptIsReady = false; + m_rxReceiptContext.receiptLen = 0; +} + +void ZFPGACommander::sendPacket(zaf_packet_header_t *packet, uint32_t len, uint32_t overtime) { + zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; + + resetRxContext(packet->index); + + if (serial_ch->isOpen() == false) { + throw zexception(ke_invalid_packet_format, "channel is not open"); + } + if (m_raw_data_cb) { + m_raw_data_cb(kuart_raw_tx, (uint8_t *)packet, PACKET_LEN(packet)); + } + serial_ch->send((uint8_t *)packet, len); + for (size_t i = 0; i < overtime; i++) { + { + lock_guard lock(m_rxReceiptContext_lock); + if (m_rxReceiptContext.receiptIsReady) { + break; + } + } + this_thread::sleep_for(chrono::milliseconds(1)); + } + + if (m_rxReceiptContext.receiptIsReady) { + if (rxpacket->data[0] != 0) { + throw zexception(rxpacket->data[0], zaf_ecode_to_string((zaf_error_code_t)rxpacket->data[0])); + } else { + return; + } + } else { + } + + throw zexception(ke_overtime, "overtime"); +} + +zaf_packet_header_t *ZFPGACommander::getReceipt() { return (zaf_packet_header_t *)&(m_rxReceiptContext.receipt[0]); } + +void ZFPGACommander::writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms) { + Reginfo *reg = GetRegInfo(regadd); + + if (reg->flag & kreg_flag_force_write) { + _writeReg(regadd, regvalue, regbackvalue, overtime_ms); + } else if (reg->dirty) { + _writeReg(regadd, regvalue, regbackvalue, overtime_ms); + } else { + regbackvalue = reg->regshadow; + } + reg->dirty = false; + reg->regshadow = regvalue; + return; +} +void ZFPGACommander::readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms) { + Reginfo *reg = GetRegInfo(regadd); + + if ((reg->flag & kreg_flag_force_read)) { + _readReg(regadd, regvalue, overtime_ms); + } else if (reg->dirty) { + _readReg(regadd, regvalue, overtime_ms); + } else { + regvalue = reg->regshadow; + } + reg->dirty = false; + reg->regshadow = regvalue; +} + +void ZFPGACommander::_writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms) { + // + lock_guard lock(m_tx_lock); + + uint8_t txdata[128] = {0}; + + zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata; + zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; + + txpacket->packet_header = PACKET_HEADER; + txpacket->packet_type = kzaf_packet_type_cmd; + txpacket->index = ++txindex; + txpacket->cmd = kzaf_cmd_reg_write; + txpacket->ndata = 2; + txpacket->data[0] = regadd; + txpacket->data[1] = regvalue; + + uint32_t txpacklen = PACKET_LEN(txpacket); + uint8_t checksum = 0; + for (uint32_t i = 2; i < txpacklen - 3; i++) { + checksum += txdata[i]; + } + txdata[txpacklen - 3] = checksum; + txdata[txpacklen - 2] = PACKET_TAIL & 0xFF; + txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF; + + sendPacket(txpacket, txpacklen, overtime_ms); + regbackvalue = rxpacket->data[1]; +} +void ZFPGACommander::_readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms) { + lock_guard lock(m_tx_lock); + + uint8_t txdata[128] = {0}; + + zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata; + zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; + + txpacket->packet_header = PACKET_HEADER; + txpacket->packet_type = kzaf_packet_type_cmd; + txpacket->index = ++txindex; + txpacket->cmd = kzaf_cmd_reg_read; + txpacket->ndata = 1; + txpacket->data[0] = regadd; + + uint32_t txpacklen = PACKET_LEN(txpacket); + uint8_t checksum = 0; + for (uint32_t i = 2; i < txpacklen - 3; i++) { + checksum += txdata[i]; + } + txdata[txpacklen - 3] = checksum; + txdata[txpacklen - 2] = PACKET_TAIL & 0xFF; + txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF; + + sendPacket(txpacket, txpacklen, overtime_ms); + regvalue = rxpacket->data[1]; + + // ZLOGI(TAG, "RX packet"); + // ZLOGI(TAG, " type :%d", rxpacket->packet_type); + // ZLOGI(TAG, " index :%d", rxpacket->index); + // ZLOGI(TAG, " cmd :%d", rxpacket->cmd); + // ZLOGI(TAG, " ndata :%d", rxpacket->ndata); + // for (uint32_t i = 0; i < rxpacket->ndata; i++) { + // ZLOGI(TAG, " data[%d]:%d", i, rxpacket->data[i]); + // } + // ZLOGI(TAG, "RX:%d", regvalue); +} + +Reginfo *ZFPGACommander::GetRegInfo(uint32_t add) { + auto it = m_reginfoMap.find(add); + if (it != m_reginfoMap.end()) { + return &it->second; + } + m_reginfoMap.insert(make_pair(add, Reginfo())); + return &m_reginfoMap[add]; +} +void ZFPGACommander::RegInfo_Reset() { + for (auto &it : m_reginfoMap) { + it.second.dirty = true; + } +} + +void ZFPGACommander::readFPGAVersion(Version &version) { + uint32_t version32; + readReg(kreg_fpga_version, version32, 100); +} +void ZFPGACommander::readStm32Version(Version &version) { + uint32_t version32; + readReg(kreg_software_version, version32, 100); +} + +bool ZFPGACommander::ping() { + try { + Version version; + readStm32Version(version); + } catch (const std::exception &e) { + return false; + } + return true; +} + +void ZFPGACommander::callcmd(uint32_t cmd, uint32_t delayms) { + lock_guard lock(m_tx_lock); + + uint8_t txdata[128] = {0}; + + zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata; + // zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0]; + + txpacket->packet_header = PACKET_HEADER; + txpacket->packet_type = kzaf_packet_type_cmd; + txpacket->index = ++txindex; + txpacket->cmd = cmd; + txpacket->ndata = 0; + + uint32_t txpacklen = PACKET_LEN(txpacket); + uint8_t checksum = 0; + for (uint32_t i = 2; i < txpacklen - 3; i++) { + checksum += txdata[i]; + } + txdata[txpacklen - 3] = checksum; + txdata[txpacklen - 2] = PACKET_TAIL & 0xFF; + txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF; + + sendPacket(txpacket, txpacklen, delayms); +} + +void ZFPGACommander::factoryReset() { callcmd(kzaf_cmd_factory_reset, 1500); } +void ZFPGACommander::reboot() { callcmd(kzaf_cmd_reboot, 100); } +void ZFPGACommander::storageConfigs() { callcmd(kzaf_cmd_storage_cfg, 1500); } \ No newline at end of file diff --git a/src/protocol/zfpga_commander/zfpga_commander.hpp b/src/protocol/zfpga_commander/zfpga_commander.hpp new file mode 100644 index 0000000..5005ba8 --- /dev/null +++ b/src/protocol/zfpga_commander/zfpga_commander.hpp @@ -0,0 +1,127 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zfpga_basic_protocol\zaf_protocol.h" +#include "zfpga_basic_protocol\zaf_regs.hpp" + +namespace iflytop { + +using namespace std; + +typedef enum { + kuart_raw_tx, + kuart_raw_rx, +} uart_message_type_t; + +typedef function device_state_cb_t; + +typedef function binary_cb_t; + +class ZFPGARxReceiptContext { + public: + bool waittingForReceipt; + bool receiptIsReady; + uint16_t waittingIndex; + uint8_t receipt[1024]; + size_t receiptLen; +}; + +typedef enum { + + kreg_flag_r = 0x01, // 可读 + kreg_flag_w = 0x01 << 1, // 可写 + kreg_flag_force_read = 0x01 << 2, // 易变寄存器 + kreg_flag_force_write = 0x01 << 3, // 易变寄存器 + + kreg_flag_rw = kreg_flag_r | kreg_flag_w, +} reg_flag_t; + +class Reginfo { + public: + uint32_t regadd = 0; + uint32_t flag = kreg_flag_rw; + uint32_t regshadow = 0; + bool dirty = true; + + public: +}; + +class Version { + public: + uint32_t main; + uint32_t sub; + uint32_t fix; +}; + +class ZFPGACommander { + ZFPGACommander() {} + + uint8_t m_rxcache[1024]; + size_t m_rxlen = 0; + + mutex lock_; + + unique_ptr m_thread; + + ZFPGARxReceiptContext m_rxReceiptContext; + mutex m_rxReceiptContext_lock; + mutex m_tx_lock; + + binary_cb_t m_raw_data_cb; + uint16_t txindex = 0; + + map m_reginfoMap; + + public: + static ZFPGACommander *ins() { + static ZFPGACommander cmder; + return &cmder; + } + + void initialize(); + void regRawDataListener(binary_cb_t cb); + + public: + void writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms); + void readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms); + void sendPacket(zaf_packet_header_t *packet, uint32_t len, uint32_t overtime); + + zaf_packet_header_t *getReceipt(); + + public: + void readFPGAVersion(Version &version); + void readStm32Version(Version &version); + + bool ping(); + void factoryReset(); + void reboot(); + void storageConfigs(); + + private: + void _writeReg(uint32_t regadd, uint32_t regvalue, uint32_t ®backvalue, int32_t overtime_ms); + void _readReg(uint32_t regadd, uint32_t ®value, int32_t overtime_ms); + void callcmd(uint32_t cmd, uint32_t delayms); + + private: + void resetRxContext(int32_t cmdIndex); + void processRxData(uint8_t *rx, uint32_t rxlen); + void processRxPacket(zaf_packet_header_t *packet); + void setRxContext(int32_t cmdIndex); + + private: + Reginfo *GetRegInfo(uint32_t add); + void RegInfo_Reset(); +}; + +} // namespace iflytop \ No newline at end of file diff --git a/zfpga_basic_protocol b/zfpga_basic_protocol index 9429095..9e7042b 160000 --- a/zfpga_basic_protocol +++ b/zfpga_basic_protocol @@ -1 +1 @@ -Subproject commit 94290950d567241d8b82ba8b8ae5ea5a55cc9634 +Subproject commit 9e7042b03742e5d8985b977f4457cbaf2b04c909