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.

387 lines
12 KiB

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 "zfpga_commander.hpp"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. //
  5. #include "zqui/base/logger.hpp"
  6. #include "zqui/base/zexception.hpp"
  7. #include "zqui/channelmgr/channelmgr.hpp"
  8. using namespace iflytop;
  9. #define TAG "ZFPGACommander"
  10. QTSerialChannel *serial_ch;
  11. #define DEBUG
  12. #define PACKET_LEN(__packet) (sizeof(zaf_packet_header_t) + (__packet->ndata) * sizeof(uint32_t) + 1 /*checksum*/ + 2 /*tail*/)
  13. #define DO_CMD(exptr) \
  14. { \
  15. zaf_error_code_t ecode = exptr; \
  16. if (ecode != kaf_ec_success) return ecode; \
  17. }
  18. static string hex2str(uint8_t *hex, size_t len) {
  19. string str;
  20. for (size_t i = 0; i < len; i++) {
  21. char buf[3];
  22. sprintf(buf, "%02X", hex[i]);
  23. str += buf;
  24. }
  25. return str;
  26. }
  27. void ZFPGACommander::initialize() {
  28. //
  29. serial_ch = &ChannelMgr::ins()->serialCh;
  30. serial_ch->regRxListener([this](uint8_t *data, size_t len) {
  31. {
  32. lock_guard<mutex> lock(lock_);
  33. if (len + m_rxlen > sizeof(m_rxcache)) {
  34. m_rxlen = 0;
  35. }
  36. memcpy(m_rxcache + m_rxlen, data, len);
  37. m_rxlen += len;
  38. }
  39. });
  40. m_thread.reset(new thread([this]() {
  41. uint32_t last_rx_cnt = 0;
  42. uint8_t rx_process_cache[1024];
  43. uint32_t rx_process_cache_len = 0;
  44. while (true) {
  45. this_thread::sleep_for(chrono::milliseconds(4));
  46. {
  47. lock_guard<mutex> lock(lock_);
  48. if (last_rx_cnt == m_rxlen && m_rxlen != 0) {
  49. memcpy(rx_process_cache, m_rxcache, m_rxlen);
  50. rx_process_cache_len = m_rxlen;
  51. m_rxlen = 0;
  52. last_rx_cnt = 0;
  53. }
  54. }
  55. if (rx_process_cache_len != 0) {
  56. processRxData(rx_process_cache, rx_process_cache_len);
  57. memset(rx_process_cache, 0, sizeof(rx_process_cache));
  58. rx_process_cache_len = 0;
  59. }
  60. last_rx_cnt = m_rxlen;
  61. }
  62. }));
  63. m_online_detect_thread.reset(new thread([this]() {
  64. while (true) {
  65. if (!isconnected) {
  66. this_thread::sleep_for(chrono::milliseconds(100));
  67. } else {
  68. this_thread::sleep_for(chrono::milliseconds(3000));
  69. }
  70. bool tostate = false;
  71. if (ping()) {
  72. tostate = true;
  73. } else {
  74. tostate = false;
  75. }
  76. if (tostate != isconnected) {
  77. if (tostate) {
  78. ZLOGI(TAG, "device connected.");
  79. } else {
  80. ZLOGI(TAG, "device disconnected.");
  81. RegInfo_Reset();
  82. }
  83. isconnected = tostate;
  84. if (m_stateCbFn) m_stateCbFn(isconnected);
  85. }
  86. }
  87. }));
  88. }
  89. void ZFPGACommander::regRawDataListener(binary_cb_t cb) { m_raw_data_cb = cb; }
  90. void ZFPGACommander::regStateCbFn(StateCbFn_t cbfn) { this->m_stateCbFn = cbfn; }
  91. bool ZFPGACommander::chIsOn() { return serial_ch->isOpen(); }
  92. void ZFPGACommander::processRxData(uint8_t *rx, uint32_t rxlen) {
  93. #ifdef DEBUG
  94. ZLOGI(TAG, "RX %s", hex2str((uint8_t *)rx, rxlen).c_str());
  95. #endif
  96. for (uint32_t i = 0; i < rxlen; i++) {
  97. zaf_packet_header_t *header = (zaf_packet_header_t *)(&rx[i]);
  98. uint8_t *packetu8 = &rx[i];
  99. if (header->packet_header == PACKET_HEADER) {
  100. uint8_t check = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 0];
  101. uint8_t tail0 = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 1];
  102. uint8_t tail1 = packetu8[header->ndata * 4 + sizeof(zaf_packet_header_t) + 2];
  103. uint16_t tail = (tail1 << 8) | tail0;
  104. uint8_t expectcheck = 0;
  105. for (uint32_t j = 2; j < header->ndata * 4 + sizeof(zaf_packet_header_t); j++) {
  106. expectcheck += packetu8[j];
  107. }
  108. if (tail == PACKET_TAIL) {
  109. if (expectcheck == check) {
  110. processRxPacket(header);
  111. } else {
  112. ZLOGE(TAG, "Rx packet check error %d != %d", expectcheck, check);
  113. }
  114. }
  115. }
  116. }
  117. }
  118. void ZFPGACommander::processRxPacket(zaf_packet_header_t *packet) {
  119. //
  120. // ZLOGI(TAG, "RX packet");
  121. // ZLOGI(TAG, " type :%d", packet->packet_type);
  122. // ZLOGI(TAG, " index :%d", packet->index);
  123. // ZLOGI(TAG, " cmd :%d", packet->cmd);
  124. // ZLOGI(TAG, " ndata :%d", packet->ndata);
  125. // for (uint32_t i = 0; i < packet->ndata; i++) {
  126. // ZLOGI(TAG, " data[%d]:%d", i, packet->data[i]);
  127. // }
  128. // ZLOGI(TAG, "Rx.....");
  129. uint32_t packetlen = sizeof(zaf_packet_header_t) + packet->ndata * 4 + 3;
  130. if (m_raw_data_cb) {
  131. m_raw_data_cb(kuart_raw_rx, (uint8_t *)packet, packetlen);
  132. }
  133. if (packet->packet_type == kzaf_packet_type_receipt) {
  134. lock_guard<mutex> lock(m_rxReceiptContext_lock);
  135. if (m_rxReceiptContext.waittingForReceipt) {
  136. if (m_rxReceiptContext.waittingIndex == packet->index) {
  137. m_rxReceiptContext.receiptIsReady = true;
  138. m_rxReceiptContext.receiptLen = PACKET_LEN(packet);
  139. memcpy(m_rxReceiptContext.receipt, packet, PACKET_LEN(packet));
  140. }
  141. m_rxReceiptContext.waittingForReceipt = false;
  142. }
  143. } else if (packet->packet_type == kzaf_packet_type_heart) {
  144. }
  145. }
  146. void ZFPGACommander::resetRxContext(int32_t cmdIndex) {
  147. lock_guard<mutex> lock(m_rxReceiptContext_lock);
  148. m_rxReceiptContext.waittingIndex = cmdIndex;
  149. m_rxReceiptContext.waittingForReceipt = true;
  150. m_rxReceiptContext.receiptIsReady = false;
  151. m_rxReceiptContext.receiptLen = 0;
  152. }
  153. shared_ptr<Receipt> ZFPGACommander::sendPacket(zaf_packet_header_t *packet, uint32_t len, uint32_t overtime) {
  154. lock_guard<recursive_mutex> lock(m_tx_lock);
  155. zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0];
  156. resetRxContext(packet->index);
  157. if (serial_ch->isOpen() == false) {
  158. throw zexception(ke_invalid_packet_format, "channel is not open");
  159. }
  160. if (m_raw_data_cb) {
  161. m_raw_data_cb(kuart_raw_tx, (uint8_t *)packet, PACKET_LEN(packet));
  162. }
  163. #ifdef DEBUG
  164. ZLOGI(TAG, "TX %s", hex2str((uint8_t *)packet, len).c_str());
  165. #endif
  166. serial_ch->send((uint8_t *)packet, len);
  167. for (size_t i = 0; i < overtime; i++) {
  168. {
  169. lock_guard<mutex> lock(m_rxReceiptContext_lock);
  170. if (m_rxReceiptContext.receiptIsReady) {
  171. break;
  172. }
  173. }
  174. this_thread::sleep_for(chrono::milliseconds(1));
  175. }
  176. if (m_rxReceiptContext.receiptIsReady) {
  177. if (rxpacket->data[0] != 0) {
  178. throw zexception(rxpacket->data[0], zaf_ecode_to_string((zaf_error_code_t)rxpacket->data[0]));
  179. } else {
  180. shared_ptr<Receipt> receipt;
  181. receipt.reset(new Receipt(m_rxReceiptContext.receipt, m_rxReceiptContext.receiptLen));
  182. return receipt;
  183. }
  184. } else {
  185. }
  186. throw zexception(ke_overtime, "overtime");
  187. }
  188. void ZFPGACommander::writeReg(uint32_t regadd, uint32_t regvalue) {
  189. uint32_t regbackvalue;
  190. writeReg(regadd, regvalue, regbackvalue, 50);
  191. }
  192. void ZFPGACommander::writeReg(uint32_t regadd, uint32_t regvalue, uint32_t &regbackvalue, int32_t overtime_ms) {
  193. lock_guard<recursive_mutex> lock(m_tx_lock);
  194. Reginfo *reg = GetRegInfo(regadd);
  195. if (reg->flag & kreg_flag_force_write) {
  196. _writeReg(regadd, regvalue, regbackvalue, overtime_ms);
  197. } else if (reg->dirty) {
  198. _writeReg(regadd, regvalue, regbackvalue, overtime_ms);
  199. } else if (reg->regshadow != regvalue) {
  200. _writeReg(regadd, regvalue, regbackvalue, overtime_ms);
  201. } else {
  202. regbackvalue = reg->regshadow;
  203. }
  204. reg->dirty = false;
  205. reg->regshadow = regvalue;
  206. return;
  207. }
  208. void ZFPGACommander::readReg(uint32_t regadd, uint32_t &regvalue, int32_t overtime_ms) {
  209. lock_guard<recursive_mutex> lock(m_tx_lock);
  210. Reginfo *reg = GetRegInfo(regadd);
  211. if ((reg->flag & kreg_flag_force_read)) {
  212. _readReg(regadd, regvalue, overtime_ms);
  213. } else if (reg->dirty) {
  214. _readReg(regadd, regvalue, overtime_ms);
  215. } else {
  216. regvalue = reg->regshadow;
  217. }
  218. reg->dirty = false;
  219. reg->regshadow = regvalue;
  220. }
  221. void ZFPGACommander::_writeReg(uint32_t regadd, uint32_t regvalue, uint32_t &regbackvalue, int32_t overtime_ms) {
  222. //
  223. uint8_t txdata[128] = {0};
  224. zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata;
  225. zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0];
  226. txpacket->packet_header = PACKET_HEADER;
  227. txpacket->packet_type = kzaf_packet_type_cmd;
  228. txpacket->index = ++txindex;
  229. txpacket->cmd = kzaf_cmd_reg_write;
  230. txpacket->ndata = 2;
  231. txpacket->data[0] = regadd;
  232. txpacket->data[1] = regvalue;
  233. uint32_t txpacklen = PACKET_LEN(txpacket);
  234. uint8_t checksum = 0;
  235. for (uint32_t i = 2; i < txpacklen - 3; i++) {
  236. checksum += txdata[i];
  237. }
  238. txdata[txpacklen - 3] = checksum;
  239. txdata[txpacklen - 2] = PACKET_TAIL & 0xFF;
  240. txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF;
  241. sendPacket(txpacket, txpacklen, overtime_ms);
  242. regbackvalue = rxpacket->data[1];
  243. }
  244. void ZFPGACommander::_readReg(uint32_t regadd, uint32_t &regvalue, int32_t overtime_ms) {
  245. uint8_t txdata[128] = {0};
  246. zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata;
  247. zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0];
  248. txpacket->packet_header = PACKET_HEADER;
  249. txpacket->packet_type = kzaf_packet_type_cmd;
  250. txpacket->index = ++txindex;
  251. txpacket->cmd = kzaf_cmd_reg_read;
  252. txpacket->ndata = 1;
  253. txpacket->data[0] = regadd;
  254. uint32_t txpacklen = PACKET_LEN(txpacket);
  255. uint8_t checksum = 0;
  256. for (uint32_t i = 2; i < txpacklen - 3; i++) {
  257. checksum += txdata[i];
  258. }
  259. txdata[txpacklen - 3] = checksum;
  260. txdata[txpacklen - 2] = PACKET_TAIL & 0xFF;
  261. txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF;
  262. sendPacket(txpacket, txpacklen, overtime_ms);
  263. regvalue = rxpacket->data[1];
  264. // ZLOGI(TAG, "RX packet");
  265. // ZLOGI(TAG, " type :%d", rxpacket->packet_type);
  266. // ZLOGI(TAG, " index :%d", rxpacket->index);
  267. // ZLOGI(TAG, " cmd :%d", rxpacket->cmd);
  268. // ZLOGI(TAG, " ndata :%d", rxpacket->ndata);
  269. // for (uint32_t i = 0; i < rxpacket->ndata; i++) {
  270. // ZLOGI(TAG, " data[%d]:%d", i, rxpacket->data[i]);
  271. // }
  272. // ZLOGI(TAG, "RX:%d", regvalue);
  273. }
  274. Reginfo *ZFPGACommander::GetRegInfo(uint32_t add) {
  275. auto it = m_reginfoMap.find(add);
  276. if (it != m_reginfoMap.end()) {
  277. return &it->second;
  278. }
  279. m_reginfoMap.insert(make_pair(add, Reginfo()));
  280. return &m_reginfoMap[add];
  281. }
  282. void ZFPGACommander::RegInfo_Reset() {
  283. for (auto &it : m_reginfoMap) {
  284. it.second.dirty = true;
  285. }
  286. }
  287. void ZFPGACommander::readFPGAVersion(Version &version) {
  288. uint32_t version32;
  289. readReg(kreg_fpga_version, version32, 100);
  290. version.main = VERSION_MAIN(version32);
  291. version.sub = VERSION_SUB(version32);
  292. version.fix = VERSION_FIX(version32);
  293. }
  294. void ZFPGACommander::readStm32Version(Version &version) {
  295. uint32_t version32;
  296. readReg(kreg_software_version, version32, 10);
  297. version.main = VERSION_MAIN(version32);
  298. version.sub = VERSION_SUB(version32);
  299. version.fix = VERSION_FIX(version32);
  300. }
  301. bool ZFPGACommander::ping() {
  302. try {
  303. callcmd(kzaf_cmd_ping, 10);
  304. } catch (const std::exception &e) {
  305. return false;
  306. }
  307. return true;
  308. }
  309. void ZFPGACommander::callcmd(uint32_t cmd, uint32_t delayms) {
  310. lock_guard<recursive_mutex> lock(m_tx_lock);
  311. uint8_t txdata[128] = {0};
  312. zaf_packet_header_t *txpacket = (zaf_packet_header_t *)txdata;
  313. // zaf_packet_header_t *rxpacket = (zaf_packet_header_t *)&m_rxReceiptContext.receipt[0];
  314. txpacket->packet_header = PACKET_HEADER;
  315. txpacket->packet_type = kzaf_packet_type_cmd;
  316. txpacket->index = ++txindex;
  317. txpacket->cmd = cmd;
  318. txpacket->ndata = 0;
  319. uint32_t txpacklen = PACKET_LEN(txpacket);
  320. uint8_t checksum = 0;
  321. for (uint32_t i = 2; i < txpacklen - 3; i++) {
  322. checksum += txdata[i];
  323. }
  324. txdata[txpacklen - 3] = checksum;
  325. txdata[txpacklen - 2] = PACKET_TAIL & 0xFF;
  326. txdata[txpacklen - 1] = (PACKET_TAIL >> 8) & 0xFF;
  327. sendPacket(txpacket, txpacklen, delayms);
  328. }
  329. void ZFPGACommander::factoryReset() { callcmd(kzaf_cmd_factory_reset, 1500); }
  330. void ZFPGACommander::reboot() { callcmd(kzaf_cmd_reboot, 100); }
  331. void ZFPGACommander::storageConfigs() { callcmd(kzaf_cmd_storage_cfg, 1500); }