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.

394 lines
12 KiB

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