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.

420 lines
13 KiB

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