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.

515 lines
17 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "zcanreceiver_master.hpp"
  2. #include "project_configs.h"
  3. #include "sdk\components\zprotocols\errorcode\errorcode.hpp"
  4. #ifdef HAL_CAN_MODULE_ENABLED
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. using namespace iflytop;
  9. using namespace zcr;
  10. #define TAG "ZCanCommnaderMaster"
  11. #define OVER_TIME_MS 5
  12. #define MASK_32BIT(off) (0x01 << (off))
  13. ZCanCommnaderMaster::CFG *ZCanCommnaderMaster::createCFG() {
  14. CFG *cfg = new CFG();
  15. ZASSERT(cfg != NULL);
  16. cfg->deviceId = 1;
  17. #ifdef STM32F103xB
  18. cfg->canHandle = &hcan;
  19. #else
  20. cfg->canHandle = &hcan1;
  21. #endif
  22. cfg->canFilterIndex0 = 0;
  23. cfg->maxFilterNum = 7;
  24. cfg->rxfifoNum = CAN_RX_FIFO0;
  25. return cfg;
  26. }
  27. void ZCanCommnaderMaster::init(CFG *cfg) {
  28. HAL_StatusTypeDef hal_status;
  29. m_config = cfg;
  30. m_on_packet_map_lock.init();
  31. /**
  32. * @brief ʼCAN
  33. */
  34. /**
  35. * @brief ʼϢbuf
  36. */
  37. m_canPacketRxBuffer[0].dataIsReady = false;
  38. m_canPacketRxBuffer[0].id = 1; // ֻ����������������Ϣ
  39. m_canPacketRxBuffer[0].m_canPacketNum = 0;
  40. /**
  41. * @brief ʼ
  42. */
  43. hal_status = initializeFilter();
  44. if (hal_status != HAL_OK) {
  45. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  46. return;
  47. }
  48. /**
  49. * @brief CAN
  50. */
  51. hal_status = HAL_CAN_Start(m_config->canHandle); // ����CAN
  52. if (hal_status != HAL_OK) {
  53. ZLOGE(TAG, "start can fail\r\n");
  54. return;
  55. }
  56. /**
  57. * @brief ص
  58. */
  59. ZCanIRQDispatcher::instance().regListener(this);
  60. HAL_StatusTypeDef status = activateRxIT();
  61. if (status != HAL_OK) {
  62. ZLOGE(TAG, "activateRxIT fail\r\n");
  63. return;
  64. }
  65. m_loopThread.init("ZCanCommnaderMaster", 1024, osPriorityAboveNormal);
  66. m_loopThread.start([this]() {
  67. while (true) {
  68. loop();
  69. osDelay(1);
  70. }
  71. });
  72. }
  73. HAL_StatusTypeDef ZCanCommnaderMaster::initializeFilter() {
  74. /**
  75. * @brief ID֡ʽ
  76. * [ 27:0 ]
  77. * [ STDID ] [ EXTID ]
  78. * [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0]
  79. * ȼ ֡ ĿID ԴID
  80. */
  81. HAL_StatusTypeDef HAL_Status;
  82. CAN_FilterTypeDef sFilterConfig;
  83. uint32_t filterId;
  84. uint32_t mask;
  85. memset(&sFilterConfig, 0, sizeof(sFilterConfig));
  86. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // ��ΪMASKģʽ
  87. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
  88. sFilterConfig.FilterFIFOAssignment = m_config->rxfifoNum; // ������������rxfifoNum
  89. sFilterConfig.FilterActivation = ENABLE; // ����������
  90. sFilterConfig.SlaveStartFilterBank = m_config->maxFilterNum; // slave filter start index
  91. /*******************************************************************************
  92. * Ϣ *
  93. *******************************************************************************/
  94. filterId = (0); //
  95. mask = (0); //
  96. sFilterConfig.FilterBank = m_config->canFilterIndex0; //
  97. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  98. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  99. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  100. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  101. HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig);
  102. if (HAL_Status != HAL_OK) {
  103. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  104. return HAL_Status;
  105. }
  106. ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  107. return HAL_Status;
  108. }
  109. int32_t ZCanCommnaderMaster::sendCmdWithStatusCb(uint8_t *packet, size_t len, uint16_t &packetindex, int overtime_ms, action_cb_status_t status_cb) {
  110. return sendPacketBlock(packet, len, packetindex, NULL, 0, overtime_ms, [status_cb](CanPacketRxBuffer *rxreport) {
  111. if (status_cb) status_cb(rxreport->get_data_as<kcmd_xy_robot_ctrl_move_to_report_t>()->exec_status);
  112. });
  113. }
  114. int32_t ZCanCommnaderMaster::sendCmd(uint8_t *packet, size_t len, uint8_t *rxbuf, size_t rxbuflen, int overtime_ms) {
  115. uint16_t packetindex = 0;
  116. return sendPacketBlock(packet, len, packetindex, rxbuf, rxbuflen, overtime_ms, NULL);
  117. }
  118. int32_t ZCanCommnaderMaster::sendCmdNoAck(uint8_t *packet, size_t len, int overtime_ms) {
  119. uint16_t packetindex = 0;
  120. return sendPacketBlock(packet, len, packetindex, NULL, 0, overtime_ms, NULL);
  121. }
  122. int32_t ZCanCommnaderMaster::sendPacketBlock(uint8_t *packet,
  123. size_t len, //
  124. uint16_t &packetindex, //
  125. uint8_t *rxbuf, //
  126. size_t rxbuflen, //
  127. int overtime_ms, //
  128. zcan_commnader_master_onpacket_t onReport) {
  129. Cmdheader_t *cmdheader = (Cmdheader_t *)packet;
  130. if (packetindex != 0) {
  131. unregListener(packetindex);
  132. packetindex = 0;
  133. }
  134. cmdheader->packetindex = generateFreeIndex();
  135. /**
  136. * @brief ע
  137. */
  138. bool rxdataIsReady = false;
  139. int32_t errocode = 0;
  140. regListener(
  141. cmdheader->packetindex,
  142. [this, &rxdataIsReady, &rxbuf, &rxbuflen, &errocode](CanPacketRxBuffer *report) {
  143. if (report->get_cmdheader()->packetType == kpt_error_ack) {
  144. auto *error_ack = report->get_data_as<zcan_cmder_error_ack_t>();
  145. errocode = error_ack->errorcode;
  146. } else {
  147. if (rxbuf) {
  148. // ZLOGI(TAG, "rxbuf:%d", report->get_datalen());
  149. safe_memcpy(rxbuf, rxbuflen, report->get_data(), report->get_datalen());
  150. }
  151. }
  152. rxdataIsReady = true;
  153. },
  154. onReport, nullptr);
  155. /**
  156. * @brief Ϣ
  157. */
  158. sendPacket(packet, len);
  159. /**
  160. * @brief ȴִ
  161. */
  162. uint32_t enterticket = zos_get_tick();
  163. while (!rxdataIsReady) {
  164. if (zos_haspassedms(enterticket) > (uint32_t)overtime_ms) {
  165. ZLOGE(TAG, "sendPacketBlock timeout");
  166. unregListener(cmdheader->packetindex);
  167. return err::kce_overtime;
  168. }
  169. osDelay(1);
  170. }
  171. if (errocode != 0) {
  172. unregListener(cmdheader->packetindex);
  173. return errocode;
  174. }
  175. packetindex = cmdheader->packetindex;
  176. if (!onReport) {
  177. unregListener(cmdheader->packetindex);
  178. } else {
  179. unregListenerAckCB(cmdheader->packetindex);
  180. }
  181. return 0;
  182. }
  183. void ZCanCommnaderMaster::regListener(uint16_t index, //
  184. zcan_commnader_master_onpacket_t onack, //
  185. zcan_commnader_master_onpacket_t on_cmd_exec_status_report, //
  186. zcan_commnader_master_onpacket_t on_report) {
  187. zlock_guard l(m_on_packet_map_lock);
  188. if (m_on_packet_map.size() > 10000) {
  189. ZLOGW(TAG, "m_on_packet_map.size() = %d>10000", m_on_packet_map.size());
  190. }
  191. ZCanCommnaderMasterListener listener;
  192. listener.on_ack = onack;
  193. listener.on_cmd_exec_status_report = on_cmd_exec_status_report;
  194. listener.on_report = on_report;
  195. m_on_packet_map[index] = listener;
  196. }
  197. void ZCanCommnaderMaster::unregListener(uint16_t index) {
  198. zlock_guard l(m_on_packet_map_lock);
  199. auto it = m_on_packet_map.find(index);
  200. if (it != m_on_packet_map.end()) {
  201. m_on_packet_map.erase(it);
  202. }
  203. }
  204. void ZCanCommnaderMaster::unregListenerAckCB(uint16_t index) {
  205. zlock_guard l(m_on_packet_map_lock);
  206. auto it = m_on_packet_map.find(index);
  207. if (it != m_on_packet_map.end()) {
  208. it->second.on_ack = nullptr;
  209. }
  210. }
  211. int ZCanCommnaderMaster::getListenerNum() {
  212. zlock_guard l(m_on_packet_map_lock);
  213. return m_on_packet_map.size();
  214. }
  215. bool ZCanCommnaderMaster::isListenerReg(uint16_t index) {
  216. zlock_guard l(m_on_packet_map_lock);
  217. auto it = m_on_packet_map.find(index);
  218. if (it != m_on_packet_map.end()) {
  219. return true;
  220. }
  221. return false;
  222. }
  223. void ZCanCommnaderMaster::callListener(CanPacketRxBuffer *report) {
  224. uint16_t index = report->get_cmdheader()->packetindex;
  225. {
  226. zlock_guard l(m_on_packet_map_lock);
  227. auto it = m_on_packet_map.find(index);
  228. if (it != m_on_packet_map.end()) {
  229. if (report->get_cmdheader()->packetType == kpt_ack || report->get_cmdheader()->packetType == kpt_error_ack) {
  230. if (it->second.on_ack) it->second.on_ack(report);
  231. } else if (report->get_cmdheader()->packetType == kpt_cmd_exec_status_report) {
  232. if (it->second.on_cmd_exec_status_report) it->second.on_cmd_exec_status_report(report);
  233. } else if (report->get_cmdheader()->packetType == kpt_report) {
  234. if (it->second.on_report) it->second.on_report(report);
  235. }
  236. }
  237. }
  238. }
  239. uint16_t ZCanCommnaderMaster::generateFreeIndex() {
  240. m_index_off++;
  241. uint16_t count = 0;
  242. if (m_index_off == 0) m_index_off = 1;
  243. while (isListenerReg(m_index_off)) {
  244. m_index_off++;
  245. if (m_index_off == 0) m_index_off = 1;
  246. count++;
  247. if (count == 0) {
  248. ZLOGE(TAG, "generateFreeIndex fail");
  249. NVIC_SystemReset();
  250. }
  251. }
  252. return m_index_off;
  253. }
  254. void ZCanCommnaderMaster::sendPacket(uint8_t *packet, size_t len) {
  255. /**
  256. * @brief
  257. */
  258. int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
  259. if (npacket > 255) {
  260. ZLOGE(TAG, "sendPacket fail, len:%d", len);
  261. return;
  262. }
  263. int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
  264. for (uint8_t i = 0; i < npacket; i++) {
  265. bool suc = false;
  266. if (i == npacket - 1) {
  267. suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS);
  268. } else {
  269. suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS);
  270. }
  271. if (!suc) {
  272. ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
  273. return;
  274. }
  275. }
  276. }
  277. bool ZCanCommnaderMaster::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  278. // ZLOGI(TAG, "sendPacketSub(%d:%d)", npacket, packetIndex);
  279. CAN_TxHeaderTypeDef pHeader;
  280. uint8_t aData[8] /*8byte table*/;
  281. uint32_t txMailBox = 0;
  282. uint32_t enterticket = zos_get_tick();
  283. memset(&pHeader, 0, sizeof(pHeader));
  284. memset(aData, 0, sizeof(aData));
  285. pHeader.StdId = 0x00;
  286. pHeader.ExtId = (m_config->deviceId << 16) | (npacket << 8) | packetIndex;
  287. pHeader.IDE = CAN_ID_EXT;
  288. pHeader.RTR = CAN_RTR_DATA;
  289. pHeader.DLC = len;
  290. pHeader.TransmitGlobalTime = DISABLE;
  291. memcpy(aData, packet, len);
  292. m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox);
  293. if (m_lastTransmitStatus != HAL_OK) {
  294. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  295. return false;
  296. }
  297. while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) {
  298. if (zos_haspassedms(enterticket) > (uint32_t)overtimems) {
  299. m_lastTransmitStatus = HAL_TIMEOUT;
  300. HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox);
  301. return false;
  302. }
  303. // m_os->sleepMS(1);
  304. }
  305. if (txPacketInterval_ms > 0) {
  306. osDelay(txPacketInterval_ms);
  307. }
  308. return true;
  309. }
  310. bool ZCanCommnaderMaster::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  311. /**
  312. * @brief ȡǰFIFOл˶֡
  313. */
  314. uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum);
  315. if (level == 0) {
  316. return false;
  317. }
  318. HAL_StatusTypeDef HAL_RetVal;
  319. HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData);
  320. if (HAL_OK == HAL_RetVal) {
  321. // �������յ���can��������
  322. return true;
  323. }
  324. return false;
  325. }
  326. void ZCanCommnaderMaster::initCanPacketRxBuffer(CanPacketRxBuffer *buf, uint16_t id) {
  327. memset(buf, 0, sizeof(CanPacketRxBuffer));
  328. buf->id = id;
  329. }
  330. CanPacketRxBuffer *ZCanCommnaderMaster::allocCanPacketRxBufferInIRQ(uint16_t id) {
  331. for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) {
  332. if (m_canPacketRxBuffer[i].isUsed && m_canPacketRxBuffer[i].id == id) {
  333. // ˵����ǰid�Ļ����Ѿ����ڣ������ڶ������������ռ���
  334. if (!m_canPacketRxBuffer[i].dataIsReady) {
  335. initCanPacketRxBuffer(&m_canPacketRxBuffer[i], id);
  336. m_canPacketRxBuffer[i].isUsed = true;
  337. return &m_canPacketRxBuffer[i];
  338. }
  339. }
  340. }
  341. for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) {
  342. if (!m_canPacketRxBuffer[i].isUsed) {
  343. initCanPacketRxBuffer(&m_canPacketRxBuffer[i], id);
  344. m_canPacketRxBuffer[i].isUsed = true;
  345. return &m_canPacketRxBuffer[i];
  346. }
  347. }
  348. return nullptr;
  349. }
  350. CanPacketRxBuffer *ZCanCommnaderMaster::findCanPacketRxBufferInIRQ(uint16_t id) {
  351. for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) {
  352. if (!m_canPacketRxBuffer[i].dataIsReady && m_canPacketRxBuffer[i].isUsed && m_canPacketRxBuffer[i].id == id) {
  353. return &m_canPacketRxBuffer[i];
  354. }
  355. }
  356. return nullptr;
  357. }
  358. void ZCanCommnaderMaster::freeCanPacketRxBuffer(uint16_t id) {
  359. for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) {
  360. if (m_canPacketRxBuffer[i].isUsed && m_canPacketRxBuffer[i].id == id) {
  361. m_canPacketRxBuffer[i].isUsed = false;
  362. return;
  363. }
  364. }
  365. }
  366. void ZCanCommnaderMaster::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  367. /**
  368. * @brief ж
  369. */
  370. // ZLOG_INFO("%s\n", __FUNCTION__);
  371. // printf("------------------%s\n", __FUNCTION__);
  372. if (canHandle != m_config->canHandle) {
  373. return;
  374. }
  375. /**
  376. * @brief canյϢ
  377. */
  378. CAN_RxHeaderTypeDef pHeader;
  379. uint8_t aData[8] /*8byte table*/;
  380. while (getRxMessage(&pHeader, aData)) {
  381. /**
  382. * @brief Ϣʽ
  383. *
  384. * [2] [3bit] [8bit] [8bit] [8bit]
  385. * , from frameNum frameId
  386. */
  387. uint8_t from = (pHeader.ExtId >> 16 & 0xFF);
  388. uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8;
  389. uint8_t frameId = (pHeader.ExtId & 0x00FF);
  390. CanPacketRxBuffer *rxbuf = nullptr;
  391. if (frameId == 0) {
  392. rxbuf = allocCanPacketRxBufferInIRQ(from);
  393. rxbuf->m_npacket = nframe;
  394. } else {
  395. rxbuf = findCanPacketRxBufferInIRQ(from);
  396. }
  397. if (!rxbuf) return;
  398. if (rxbuf->m_canPacketNum < ZARRAY_SIZE(rxbuf->m_canPacket)) {
  399. rxbuf->m_canPacket[rxbuf->m_canPacketNum].pHeader = pHeader;
  400. memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
  401. rxbuf->m_canPacketNum++;
  402. }
  403. /**
  404. * @brief
  405. */
  406. if (nframe == frameId + 1) {
  407. rxbuf->dataIsReady = true;
  408. if ((rxbuf->m_canPacketNum) != rxbuf->m_npacket) rxbuf->lostpacket = true;
  409. }
  410. }
  411. // deactivateRxIT();
  412. }
  413. void ZCanCommnaderMaster::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
  414. if (canHandle != m_config->canHandle) {
  415. return;
  416. }
  417. ZLOGE(TAG, "onCAN_Error\r\n");
  418. }
  419. void ZCanCommnaderMaster::processReadyPacket(CanPacketRxBuffer *rxbuf) {
  420. int dataoff = 0;
  421. for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
  422. memcpy(rxbuf->rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].pHeader.DLC);
  423. dataoff += rxbuf->m_canPacket[i].pHeader.DLC;
  424. rxbuf->rxdataSize = dataoff;
  425. }
  426. if (rxbuf->lostpacket) {
  427. ZLOGE(TAG, "lostpacket %d %d", rxbuf->m_canPacketNum, rxbuf->m_npacket);
  428. } else {
  429. callListener(rxbuf);
  430. }
  431. rxbuf->dataIsReady = false;
  432. }
  433. void ZCanCommnaderMaster::loop() {
  434. /**
  435. * @brief MainLoop
  436. */
  437. for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) {
  438. if (m_canPacketRxBuffer[i].isUsed && m_canPacketRxBuffer[i].dataIsReady) {
  439. processReadyPacket(&m_canPacketRxBuffer[i]);
  440. }
  441. }
  442. }
  443. HAL_StatusTypeDef ZCanCommnaderMaster::activateRxIT() {
  444. HAL_StatusTypeDef hal_status = HAL_ERROR;
  445. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  446. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  447. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  448. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  449. } else {
  450. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  451. return hal_status;
  452. }
  453. return hal_status;
  454. }
  455. HAL_StatusTypeDef ZCanCommnaderMaster::deactivateRxIT() {
  456. HAL_StatusTypeDef hal_status = HAL_ERROR;
  457. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  458. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  459. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  460. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  461. } else {
  462. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  463. return hal_status;
  464. }
  465. return hal_status;
  466. }
  467. size_t ZCanCommnaderMaster::safe_memcpy(void *dst, size_t dst_max_size, void *src, size_t src_len) { //
  468. size_t cpysize = dst_max_size < src_len ? dst_max_size : src_len;
  469. memcpy(dst, src, cpysize);
  470. return cpysize;
  471. }
  472. #endif