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
12 KiB

1 year ago
5 months ago
1 year 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
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
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_canPacketRxBuffer[0].dataIsReady = false;
  42. m_canPacketRxBuffer[0].id = 0; // 只接收来自主机的消息
  43. m_canPacketRxBuffer[0].m_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. sFilterConfig.FilterBank = m_config->canFilterIndex0; //
  91. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  92. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  93. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  94. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  95. HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig);
  96. if (HAL_Status != HAL_OK) {
  97. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  98. return HAL_Status;
  99. }
  100. ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  101. return HAL_Status;
  102. }
  103. void ZCanReceiver::registerListener(IZCanReceiverListener *listener) { m_listenerList.push_back(listener); }
  104. // static inline const char *dumphex(uint8_t *packet, size_t len) {
  105. // static char buf[1024];
  106. // memset(buf, 0, sizeof(buf));
  107. // for (size_t i = 0; i < len; i++) {
  108. // sprintf(buf + i * 2, "%02x", packet[i]);
  109. // }
  110. // return buf;
  111. // }
  112. static const char* hex2str(const char* hex, size_t len) {
  113. static char buf[256];
  114. memset(buf, 0, sizeof(buf));
  115. for (size_t i = 0; i < len; i++) {
  116. sprintf(buf + i * 2, "%02X", hex[i]);
  117. }
  118. return buf;
  119. }
  120. void ZCanReceiver::sendPacket(uint8_t *packet, size_t len) {
  121. // ZLOGI(TAG, "tx %s(%d)", hex2str((const char *)packet, len), len);
  122. /**
  123. * @brief
  124. */
  125. int npacket = len / 7 + (len % 7 == 0 ? 0 : 1);
  126. if (npacket > 255) {
  127. ZLOGE(TAG, "sendPacket fail, len:%d", len);
  128. return;
  129. }
  130. int finalpacketlen = len % 7 == 0 ? 7 : len % 7;
  131. for (uint8_t i = 0; i < npacket; i++) {
  132. bool suc = false;
  133. if (i == npacket - 1) {
  134. suc = sendPacketSub(npacket, i, packet + i * 7, finalpacketlen, OVER_TIME_MS);
  135. } else {
  136. suc = sendPacketSub(npacket, i, packet + i * 7, 7, OVER_TIME_MS);
  137. }
  138. if (!suc) {
  139. ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
  140. return;
  141. }
  142. }
  143. }
  144. int32_t ZCanReceiver::sendBufAck(zcr_cmd_header_t *rx_cmd_header, uint8_t *data, int32_t len) {
  145. zlock_guard l(m_lock);
  146. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  147. int packetlen = sizeof(zcr_cmd_header_t) + len + 1;
  148. ZASSERT(sizeof(txbuff) > packetlen);
  149. memcpy(txheader, rx_cmd_header, sizeof(zcr_cmd_header_t));
  150. txheader->packetType = kptv2_ack;
  151. txheader->datalen = len;
  152. memcpy(txheader->data, data, len);
  153. assign_packet_checksum(txbuff, packetlen);
  154. sendPacket(txbuff, packetlen);
  155. return 0;
  156. }
  157. int32_t ZCanReceiver::triggerEvent(zcr_cmd_header_t *cmd_header, uint8_t *data, int32_t len) {
  158. zlock_guard l(m_lock);
  159. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  160. int packetlen = sizeof(zcr_cmd_header_t) + len + 1;
  161. ZASSERT(sizeof(txbuff) > packetlen);
  162. memcpy(txheader, cmd_header, sizeof(zcr_cmd_header_t));
  163. txheader->packetType = kptv2_event;
  164. txheader->index = m_reportIndex;
  165. txheader->datalen = len;
  166. memcpy(txheader->data, data, len);
  167. assign_packet_checksum(txbuff, packetlen);
  168. sendPacket(txbuff, packetlen);
  169. m_reportIndex++;
  170. return 0;
  171. }
  172. int32_t ZCanReceiver::sendAck(zcr_cmd_header_t *rx_cmd_header, int32_t *ackvar, int32_t nack) {
  173. zlock_guard l(m_lock);
  174. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  175. int packetlen = sizeof(zcr_cmd_header_t) + sizeof(int32_t) * nack + 1;
  176. memcpy(txheader, rx_cmd_header, sizeof(zcr_cmd_header_t));
  177. txheader->packetType = kptv2_ack;
  178. int32_t *txackcache = (int32_t *)txheader->data;
  179. txheader->datalen = nack * sizeof(int32_t);
  180. for (int i = 0; i < nack; i++) {
  181. txackcache[i] = ackvar[i];
  182. }
  183. assign_packet_checksum(txbuff, packetlen);
  184. sendPacket(txbuff, packetlen);
  185. return 0;
  186. }
  187. int32_t ZCanReceiver::sendErrorAck(zcr_cmd_header_t *rx_cmd_header, int32_t errorcode) {
  188. zlock_guard l(m_lock);
  189. zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
  190. int32_t *txackcache = (int32_t *)txheader->data;
  191. int packetlen = sizeof(zcr_cmd_header_t) + sizeof(int32_t) * 1 + 1;
  192. memcpy(txheader, rx_cmd_header, sizeof(zcr_cmd_header_t));
  193. txheader->packetType = kptv2_error_ack;
  194. txheader->datalen = sizeof(int32_t);
  195. txackcache[0] = errorcode;
  196. assign_packet_checksum(txbuff, packetlen);
  197. sendPacket(txbuff, packetlen);
  198. return 0;
  199. }
  200. bool ZCanReceiver::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  201. zlock_guard l(m_lock);
  202. // ZLOGI(TAG, "sendPacketSub(%d:%d)", npacket, packetIndex);
  203. CAN_TxHeaderTypeDef pHeader;
  204. uint8_t aData[8] /*8byte table*/;
  205. uint32_t txMailBox = 0;
  206. uint32_t enterticket = zos_get_tick();
  207. memset(&pHeader, 0, sizeof(pHeader));
  208. memset(aData, 0, sizeof(aData));
  209. pHeader.StdId = m_config->deviceId;
  210. pHeader.ExtId = 0;
  211. pHeader.IDE = CAN_ID_STD;
  212. pHeader.RTR = CAN_RTR_DATA;
  213. pHeader.DLC = len + 1;
  214. pHeader.TransmitGlobalTime = DISABLE;
  215. aData[0] = (npacket << 4) | packetIndex;
  216. memcpy(aData + 1, packet, len);
  217. m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox);
  218. if (m_lastTransmitStatus != HAL_OK) {
  219. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  220. return false;
  221. }
  222. while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) {
  223. if (zos_haspassedms(enterticket) > (uint32_t)overtimems) {
  224. m_lastTransmitStatus = HAL_TIMEOUT;
  225. HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox);
  226. return false;
  227. }
  228. // m_os->sleepMS(1);
  229. osDelay(1);
  230. }
  231. if (txPacketInterval_ms > 0) {
  232. osDelay(txPacketInterval_ms);
  233. }
  234. return true;
  235. }
  236. bool ZCanReceiver::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  237. /**
  238. * @brief FIFO中缓存了多少帧的数据
  239. */
  240. uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum);
  241. if (level == 0) {
  242. return false;
  243. }
  244. HAL_StatusTypeDef HAL_RetVal;
  245. HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData);
  246. if (HAL_OK == HAL_RetVal) {
  247. // 处理接收到的can总线数据
  248. return true;
  249. }
  250. return false;
  251. }
  252. void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  253. /**
  254. * @brief
  255. */
  256. // ZLOG_INFO("%s\n", __FUNCTION__);
  257. if (canHandle != m_config->canHandle) {
  258. return;
  259. }
  260. /**
  261. * @brief can接收到消息
  262. */
  263. CAN_RxHeaderTypeDef pHeader;
  264. uint8_t aData[8] = {0};
  265. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  266. while (getRxMessage(&pHeader, aData)) {
  267. // 过滤掉非标准帧和远程帧,和DLC为0的帧
  268. if (pHeader.RTR != CAN_RTR_DATA || pHeader.IDE != CAN_ID_STD) continue;
  269. if (pHeader.DLC == 0) continue;
  270. // 上次接收到的消息还没有来的急处理
  271. if (rxbuf->dataIsReady) continue;
  272. /**
  273. * @brief
  274. */
  275. uint8_t from = (pHeader.StdId & 0xFF);
  276. uint8_t nframe = (aData[0] & 0xF0) >> 4;
  277. uint8_t frameoff = (aData[0] & 0x0F);
  278. // 只接收来自主机的消息
  279. if (from != rxbuf->id) continue;
  280. // 当frameoff==0,重置接收缓存
  281. if (frameoff == 0) {
  282. rxbuf->m_canPacketNum = 0;
  283. }
  284. // 当接收到非期望frameoff的数据时,说明发生了丢包,重置接收缓存
  285. if (rxbuf->m_canPacketNum != frameoff) {
  286. rxbuf->m_canPacketNum = 0;
  287. continue;
  288. }
  289. // 接收到有效包
  290. if (rxbuf->m_canPacketNum < ZARRAY_SIZE(rxbuf->m_canPacket)) {
  291. rxbuf->m_canPacket[rxbuf->m_canPacketNum].dlc = pHeader.DLC;
  292. memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
  293. rxbuf->m_canPacketNum++;
  294. }
  295. if (nframe == frameoff + 1) {
  296. rxbuf->m_npacket = nframe;
  297. rxbuf->dataIsReady = true;
  298. }
  299. }
  300. // deactivateRxIT();
  301. }
  302. void ZCanReceiver::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
  303. if (canHandle != m_config->canHandle) {
  304. return;
  305. }
  306. ZLOGE(TAG, "onCAN_Error\r\n");
  307. }
  308. void ZCanReceiver::loop() {
  309. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  310. if (rxbuf->dataIsReady) {
  311. if (rxbuf->m_canPacketNum != rxbuf->m_npacket) {
  312. ZLOGE(TAG, "lost packet");
  313. } else {
  314. int dataoff = 0;
  315. for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
  316. if (rxbuf->m_canPacket[i].dlc == 0) continue;
  317. memcpy(rxbuf->rxdata + dataoff, rxbuf->m_canPacket[i].aData + 1, rxbuf->m_canPacket[i].dlc - 1);
  318. dataoff += rxbuf->m_canPacket[i].dlc - 1;
  319. }
  320. rxbuf->rxdataSize = dataoff;
  321. // ZLOGI(TAG,"rx packet");
  322. for (auto &var : m_listenerList) {
  323. if (var) var->onRceivePacket(rxbuf->get_cmdheader(), rxbuf->get_rx_raw_len());
  324. }
  325. }
  326. rxbuf->dataIsReady = false;
  327. }
  328. }
  329. HAL_StatusTypeDef ZCanReceiver::activateRxIT() {
  330. HAL_StatusTypeDef hal_status = HAL_ERROR;
  331. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  332. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  333. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  334. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  335. } else {
  336. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  337. return hal_status;
  338. }
  339. return hal_status;
  340. }
  341. HAL_StatusTypeDef ZCanReceiver::deactivateRxIT() {
  342. HAL_StatusTypeDef hal_status = HAL_ERROR;
  343. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  344. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  345. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  346. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  347. } else {
  348. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  349. return hal_status;
  350. }
  351. return hal_status;
  352. }
  353. #endif