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.

418 lines
14 KiB

1 year ago
  1. #include "zcanreceiver.hpp"
  2. #ifdef HAL_CAN_MODULE_ENABLED
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. using namespace iflytop;
  7. using namespace zcr;
  8. #define TAG "ZCanCmder"
  9. #define OVER_TIME_MS 5
  10. ZCanReceiver *g_receiver;
  11. extern "C" {
  12. void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) {}
  13. void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) {}
  14. void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) {}
  15. void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) {}
  16. void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) {}
  17. void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) {}
  18. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
  19. if (g_receiver) g_receiver->STM32_HAL_onCAN_RxFifo0MsgPending(hcan);
  20. }
  21. void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {}
  22. void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {}
  23. void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) {}
  24. void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) {}
  25. void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) {}
  26. void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {}
  27. }
  28. ZCanReceiver::CFG *ZCanReceiver::createCFG(uint8_t deviceId) {
  29. CFG *cfg = new CFG();
  30. ZASSERT(cfg != NULL);
  31. cfg->deviceId = deviceId;
  32. #ifdef STM32F103xB
  33. cfg->canHandle = &hcan;
  34. #else
  35. cfg->canHandle = &hcan1;
  36. #endif
  37. cfg->canFilterIndex0 = 0;
  38. cfg->maxFilterNum = 7;
  39. cfg->rxfifoNum = CAN_RX_FIFO0;
  40. return cfg;
  41. }
  42. void ZCanReceiver::initialize(CFG *cfg) {
  43. HAL_StatusTypeDef hal_status;
  44. m_config = cfg;
  45. m_lock.init();
  46. /**
  47. * @brief CAN
  48. */
  49. /**
  50. * @brief buf
  51. */
  52. m_canPacketRxBuffer[0].dataIsReady = false;
  53. m_canPacketRxBuffer[0].id = 0; // 只接收来自主机的消息
  54. m_canPacketRxBuffer[0].m_canPacketNum = 0;
  55. /**
  56. * @brief
  57. */
  58. hal_status = initializeFilter();
  59. if (hal_status != HAL_OK) {
  60. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  61. return;
  62. }
  63. /**
  64. * @brief CAN
  65. */
  66. hal_status = HAL_CAN_Start(m_config->canHandle); // 开启CAN
  67. if (hal_status != HAL_OK) {
  68. ZLOGE(TAG, "start can fail\r\n");
  69. return;
  70. }
  71. /**
  72. * @brief
  73. */
  74. HAL_StatusTypeDef status = activateRxIT();
  75. if (status != HAL_OK) {
  76. ZLOGE(TAG, "activateRxIT fail\r\n");
  77. return;
  78. }
  79. g_receiver = this;
  80. // ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { loop(); }, 0);
  81. }
  82. HAL_StatusTypeDef ZCanReceiver::initializeFilter() {
  83. /**
  84. * @brief ID区帧格式
  85. * [ 27:0 ]
  86. * [ STDID ] [ EXTID ]
  87. * [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0]
  88. * ID ID
  89. */
  90. HAL_StatusTypeDef HAL_Status;
  91. CAN_FilterTypeDef sFilterConfig;
  92. uint32_t filterId;
  93. uint32_t mask;
  94. memset(&sFilterConfig, 0, sizeof(sFilterConfig));
  95. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 设为MASK模式
  96. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
  97. sFilterConfig.FilterFIFOAssignment = m_config->rxfifoNum; // 关联过滤器到rxfifoNum
  98. sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
  99. sFilterConfig.SlaveStartFilterBank = m_config->maxFilterNum; // slave filter start index
  100. /*******************************************************************************
  101. * *
  102. *******************************************************************************/
  103. filterId = (0); //
  104. mask = (0); //
  105. sFilterConfig.FilterBank = m_config->canFilterIndex0; //
  106. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  107. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  108. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  109. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  110. HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig);
  111. if (HAL_Status != HAL_OK) {
  112. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  113. return HAL_Status;
  114. }
  115. ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  116. return HAL_Status;
  117. }
  118. void ZCanReceiver::registerListener(IZCanReceiverListener *listener) { m_listenerList.push_back(listener); }
  119. // static inline const char *dumphex(uint8_t *packet, size_t len) {
  120. // static char buf[1024];
  121. // memset(buf, 0, sizeof(buf));
  122. // for (size_t i = 0; i < len; i++) {
  123. // sprintf(buf + i * 2, "%02x", packet[i]);
  124. // }
  125. // return buf;
  126. // }
  127. void ZCanReceiver::sendPacket(uint8_t *packet, size_t len) {
  128. /**
  129. * @brief
  130. */
  131. int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
  132. if (npacket > 255) {
  133. ZLOGE(TAG, "sendPacket fail, len:%d", len);
  134. return;
  135. }
  136. int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
  137. for (uint8_t i = 0; i < npacket; i++) {
  138. bool suc = false;
  139. if (i == npacket - 1) {
  140. suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS);
  141. } else {
  142. suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS);
  143. }
  144. if (!suc) {
  145. ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
  146. return;
  147. }
  148. }
  149. }
  150. #if 0
  151. void ZCanReceiver::sendAck(zcr_cmd_header_t *cmdheader, uint8_t *data, size_t len) {
  152. zlock_guard l(m_lock);
  153. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  154. memcpy(txheader, cmdheader, sizeof(zcr_cmd_header_t));
  155. txheader->packetType = kptv2_ack;
  156. memcpy(txheader->data, data, len);
  157. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + len);
  158. }
  159. void ZCanReceiver::sendErrorAck(zcr_cmd_header_t *cmdheader, uint16_t id, uint32_t errcode) {
  160. zlock_guard l(m_lock);
  161. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  162. memcpy(txheader, cmdheader, sizeof(zcr_cmd_header_t));
  163. txheader->packetType = kptv2_error_ack;
  164. zcanreceiver_error_ack_t *error_ack = (zcanreceiver_error_ack_t *)txheader->data;
  165. error_ack->id = id;
  166. error_ack->errorcode = errcode;
  167. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + sizeof(zcanreceiver_error_ack_t));
  168. }
  169. void ZCanReceiver::sendExecStatusReport(zcr_cmd_header_t *rxcmdheader, uint8_t *data, size_t len) {
  170. zlock_guard l(m_lock);
  171. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  172. memcpy(txheader, rxcmdheader, sizeof(zcr_cmd_header_t));
  173. txheader->packetType = kptv2_cmd_exec_status_report;
  174. memcpy(txheader->data, data, len);
  175. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + len);
  176. }
  177. void ZCanReceiver::sendStatusReport(zcr_cmd_header_t *rxcmdheader, uint8_t *data, size_t len) {
  178. zlock_guard l(m_lock);
  179. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  180. memcpy(txheader, rxcmdheader, sizeof(zcr_cmd_header_t));
  181. txheader->packetType = kptv2_report;
  182. memcpy(txheader->data, data, len);
  183. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + len);
  184. }
  185. #endif
  186. int32_t ZCanReceiver::sendBufAck(zcr_cmd_header_t *rx_cmd_header, uint8_t *data, int32_t len) {
  187. zlock_guard l(m_lock);
  188. ZASSERT(sizeof(txbuff) > sizeof(zcr_cmd_header_t) + len);
  189. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  190. memcpy(txheader, rx_cmd_header, sizeof(zcr_cmd_header_t));
  191. txheader->packetType = kptv2_ack;
  192. memcpy(txheader->data, data, len);
  193. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + len);
  194. return 0;
  195. }
  196. int32_t ZCanReceiver::triggerEvent(zcr_cmd_header_t *cmd_header, uint8_t *data, int32_t len) {
  197. zlock_guard l(m_lock);
  198. m_reportIndex++;
  199. ZASSERT(sizeof(txbuff) > sizeof(zcr_cmd_header_t) + len);
  200. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  201. memcpy(txheader, cmd_header, sizeof(zcr_cmd_header_t));
  202. txheader->packetType = kptv2_event;
  203. txheader->packetindex = m_reportIndex;
  204. memcpy(txheader->data, data, len);
  205. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + len);
  206. return 0;
  207. }
  208. int32_t ZCanReceiver::sendAck(zcr_cmd_header_t *rx_cmd_header, int32_t *ackvar, int32_t nack) {
  209. zlock_guard l(m_lock);
  210. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  211. memcpy(txheader, rx_cmd_header, sizeof(zcr_cmd_header_t));
  212. txheader->packetType = kptv2_ack;
  213. int32_t *txackcache = (int32_t *)txheader->data;
  214. for (int i = 0; i < nack; i++) {
  215. txackcache[i] = ackvar[i];
  216. }
  217. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + sizeof(int32_t) * nack);
  218. return 0;
  219. }
  220. int32_t ZCanReceiver::sendErrorAck(zcr_cmd_header_t *rx_cmd_header, int32_t errorcode) {
  221. zlock_guard l(m_lock);
  222. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  223. memcpy(txheader, rx_cmd_header, sizeof(zcr_cmd_header_t));
  224. txheader->packetType = kptv2_error_ack;
  225. int32_t *txackcache = (int32_t *)txheader->data;
  226. txackcache[0] = errorcode;
  227. sendPacket(txbuff, sizeof(zcr_cmd_header_t) + sizeof(int32_t));
  228. return 0;
  229. }
  230. bool ZCanReceiver::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  231. zlock_guard l(m_lock);
  232. // ZLOGI(TAG, "sendPacketSub(%d:%d)", npacket, packetIndex);
  233. CAN_TxHeaderTypeDef pHeader;
  234. uint8_t aData[8] /*8byte table*/;
  235. uint32_t txMailBox = 0;
  236. uint32_t enterticket = zos_get_tick();
  237. memset(&pHeader, 0, sizeof(pHeader));
  238. memset(aData, 0, sizeof(aData));
  239. pHeader.StdId = 0x00;
  240. pHeader.ExtId = (m_config->deviceId << 16) | (npacket << 8) | packetIndex;
  241. pHeader.IDE = CAN_ID_EXT;
  242. pHeader.RTR = CAN_RTR_DATA;
  243. pHeader.DLC = len;
  244. pHeader.TransmitGlobalTime = DISABLE;
  245. memcpy(aData, packet, len);
  246. m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox);
  247. if (m_lastTransmitStatus != HAL_OK) {
  248. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  249. return false;
  250. }
  251. while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) {
  252. if (zos_haspassedms(enterticket) > (uint32_t)overtimems) {
  253. m_lastTransmitStatus = HAL_TIMEOUT;
  254. HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox);
  255. return false;
  256. }
  257. // m_os->sleepMS(1);
  258. }
  259. if (txPacketInterval_ms > 0) {
  260. osDelay(txPacketInterval_ms);
  261. }
  262. return true;
  263. }
  264. bool ZCanReceiver::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  265. /**
  266. * @brief FIFO中缓存了多少帧的数据
  267. */
  268. uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum);
  269. if (level == 0) {
  270. return false;
  271. }
  272. HAL_StatusTypeDef HAL_RetVal;
  273. HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData);
  274. if (HAL_OK == HAL_RetVal) {
  275. // 处理接收到的can总线数据
  276. return true;
  277. }
  278. return false;
  279. }
  280. void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  281. /**
  282. * @brief
  283. */
  284. // ZLOG_INFO("%s\n", __FUNCTION__);
  285. // printf("------------------%s\n", __FUNCTION__);
  286. if (canHandle != m_config->canHandle) {
  287. return;
  288. }
  289. /**
  290. * @brief can接收到消息
  291. */
  292. CAN_RxHeaderTypeDef pHeader;
  293. uint8_t aData[8] /*8byte table*/;
  294. while (getRxMessage(&pHeader, aData)) {
  295. /**
  296. * @brief
  297. *
  298. * [2] [3bit] [8bit] [8bit] [8bit]
  299. * , from frameNum frameId
  300. */
  301. uint8_t from = (pHeader.ExtId >> 16 & 0xFF);
  302. uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8;
  303. uint8_t frameId = (pHeader.ExtId & 0x00FF);
  304. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  305. if (from != rxbuf->id) {
  306. // 目前只接收来自主机的消息
  307. continue;
  308. }
  309. if (rxbuf->dataIsReady) {
  310. // 上次接收到的消息还没有来的急处理
  311. continue;
  312. }
  313. /**
  314. * @TODO:
  315. */
  316. if (frameId == 0) {
  317. rxbuf->m_canPacketNum = 0;
  318. }
  319. if (rxbuf->m_canPacketNum != frameId) {
  320. rxbuf->m_canPacketNum = 0;
  321. continue;
  322. }
  323. if (rxbuf->m_canPacketNum < ZARRAY_SIZE(rxbuf->m_canPacket)) {
  324. rxbuf->m_canPacket[rxbuf->m_canPacketNum].dlc = pHeader.DLC;
  325. memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
  326. rxbuf->m_canPacketNum++;
  327. }
  328. if (nframe == frameId + 1) {
  329. rxbuf->dataIsReady = true;
  330. }
  331. }
  332. // deactivateRxIT();
  333. }
  334. void ZCanReceiver::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
  335. if (canHandle != m_config->canHandle) {
  336. return;
  337. }
  338. ZLOGE(TAG, "onCAN_Error\r\n");
  339. }
  340. void ZCanReceiver::loop() {
  341. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  342. if (rxbuf->dataIsReady) {
  343. int dataoff = 0;
  344. for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
  345. memcpy(rxbuf->rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].dlc);
  346. dataoff += rxbuf->m_canPacket[i].dlc;
  347. }
  348. rxbuf->rxdataSize = dataoff;
  349. // ZLOGI(TAG,"rx packet");
  350. for (auto &var : m_listenerList) {
  351. if (var) var->onRceivePacket(rxbuf->get_cmdheader(), rxbuf->get_params(), rxbuf->get_params_len());
  352. }
  353. rxbuf->dataIsReady = false;
  354. }
  355. }
  356. HAL_StatusTypeDef ZCanReceiver::activateRxIT() {
  357. HAL_StatusTypeDef hal_status = HAL_ERROR;
  358. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  359. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  360. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  361. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  362. } else {
  363. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  364. return hal_status;
  365. }
  366. return hal_status;
  367. }
  368. HAL_StatusTypeDef ZCanReceiver::deactivateRxIT() {
  369. HAL_StatusTypeDef hal_status = HAL_ERROR;
  370. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  371. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  372. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  373. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  374. } else {
  375. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  376. return hal_status;
  377. }
  378. return hal_status;
  379. }
  380. #endif