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.

403 lines
13 KiB

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