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.

455 lines
16 KiB

12 months ago
12 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
  1. #include "zcanreceiver.hpp"
  2. #include "stm32basic/mutex.hpp"
  3. #include "stm32halport/stm32halport.hpp"
  4. #define TAG "zcan"
  5. #define CANHANDLER &hcan1
  6. #define CAN_FILTER_INDEX 0
  7. #define CAN_MAX_FILTER_NUM 7
  8. #define CAN_FIFO_NUM CAN_RX_FIFO0
  9. #define OVER_TIME_MS 30
  10. #define HEART_OVERTIME (30 * 1000)
  11. using namespace iflytop;
  12. static uint8_t m_deviceId;
  13. static zcanbus_on_rx_t m_rxlistener[30];
  14. static uint32_t m_numListener = 0;
  15. static zcanbus_on_connected_t m_connectedlistener;
  16. static canrxbuffer_t m_rxbufcache;
  17. static uint16_t reportIndex;
  18. static uint16_t eventId;
  19. static uint16_t rxConfirmEventId;
  20. static uint8_t rxdata[200];
  21. static uint8_t txbuff[200];
  22. static uint32_t lastpacket_ticket;
  23. static bool m_is_connected;
  24. static uint8_t m_priority;
  25. zmutex m_lock = {"ZCANReceiver"};
  26. static void _oncanpacket(CAN_HandleTypeDef *hcan);
  27. static void _processOneCanPacket(CAN_RxHeaderTypeDef *pHeader, uint8_t *aData);
  28. static bool _getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/);
  29. extern "C" {
  30. void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox0CompleteCallback"); }
  31. void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox1CompleteCallback"); }
  32. void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox2CompleteCallback"); }
  33. void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox0AbortCallback"); }
  34. void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox1AbortCallback"); }
  35. void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox2AbortCallback"); }
  36. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { _oncanpacket(hcan); }
  37. void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo0FullCallback"); }
  38. void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo1MsgPendingCallback"); }
  39. void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo1FullCallback"); }
  40. void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_SleepCallback"); }
  41. void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_WakeUpFromRxMsgCallback"); }
  42. void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_ErrorCallback"); }
  43. }
  44. /***********************************************************************************************************************
  45. * ?? *
  46. ***********************************************************************************************************************/
  47. static void _oncanpacket(CAN_HandleTypeDef *hcan) {
  48. if (CANHANDLER != hcan) return;
  49. CAN_RxHeaderTypeDef pHeader;
  50. uint8_t aData[8] /*8byte table*/;
  51. while (_getRxMessage(&pHeader, aData)) {
  52. _processOneCanPacket(&pHeader, aData);
  53. }
  54. }
  55. static bool _getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  56. /**
  57. * @brief FIFO??
  58. */
  59. uint32_t level = HAL_CAN_GetRxFifoFillLevel(CANHANDLER, CAN_FIFO_NUM);
  60. if (level == 0) {
  61. return false;
  62. }
  63. HAL_StatusTypeDef HAL_RetVal;
  64. HAL_RetVal = HAL_CAN_GetRxMessage(CANHANDLER, CAN_FIFO_NUM, pHeader, aData);
  65. if (HAL_OK == HAL_RetVal) {
  66. // 处理接收到的can总线数据
  67. return true;
  68. }
  69. return false;
  70. }
  71. static void _processOneCanPacket(CAN_RxHeaderTypeDef *pHeader, uint8_t *aData) {
  72. /**
  73. * @brief 12bit from,1bit emergency
  74. *
  75. * [1] [4bit] [8bit] [8bit] [4bit/4bit]
  76. * , from to frameNum/frameId
  77. */
  78. uint8_t from = (pHeader->ExtId & 0x00FF0000) >> 16;
  79. uint8_t to = (pHeader->ExtId & 0x0000FF00) >> 8;
  80. uint8_t nframe = (pHeader->ExtId & 0x000000F0) >> 4;
  81. uint8_t frameId = (pHeader->ExtId & 0x0000000F);
  82. // ZLOGI(TAG, "from:%d to:%d nframe:%d frameId:%d", from, to, nframe, frameId);
  83. if (pHeader->IDE == CAN_ID_STD) {
  84. return;
  85. }
  86. // �?接收主机消息
  87. if (from != 1) {
  88. return;
  89. }
  90. if (to != m_deviceId && to != 0xff) {
  91. return;
  92. }
  93. // 上�?�接收到的消�?还没有来的急�?�理
  94. if (m_rxbufcache.dataIsReady) {
  95. ZLOGI(TAG, "discard rx packet ,last packet not processed");
  96. return;
  97. }
  98. if (frameId == 0) {
  99. m_rxbufcache.canPacketNum = 0;
  100. }
  101. if (frameId != m_rxbufcache.canPacketNum) {
  102. m_rxbufcache.canPacketNum = 0;
  103. ZLOGI(TAG, "discard rx packet ,due to lost packet");
  104. return;
  105. }
  106. if (m_rxbufcache.canPacketNum < ZARRAY_SIZE(m_rxbufcache.canPacket)) {
  107. if (m_rxbufcache.canPacketNum == 0) {
  108. m_rxbufcache.header = *pHeader;
  109. m_rxbufcache.from = from;
  110. m_rxbufcache.to = to;
  111. }
  112. m_rxbufcache.canPacket[m_rxbufcache.canPacketNum].datalen = pHeader->DLC;
  113. memcpy(m_rxbufcache.canPacket[m_rxbufcache.canPacketNum].aData, aData, 8);
  114. m_rxbufcache.canPacketNum++;
  115. } else {
  116. ZLOGI(TAG, "discard rx packet ,due to buffer full");
  117. m_rxbufcache.canPacketNum = 0;
  118. return;
  119. }
  120. if (nframe == frameId + 1) {
  121. if (m_rxbufcache.canPacketNum != nframe) {
  122. m_rxbufcache.canPacketNum = 0;
  123. ZLOGI(TAG, "discard rx packet ,due to lost packet");
  124. return;
  125. } else {
  126. m_rxbufcache.dataIsReady = true;
  127. }
  128. }
  129. }
  130. /***********************************************************************************************************************
  131. * FUNC *
  132. ***********************************************************************************************************************/
  133. static HAL_StatusTypeDef activateRxIT() {
  134. HAL_StatusTypeDef hal_status = HAL_ERROR;
  135. if (CAN_FIFO_NUM == CAN_RX_FIFO0) {
  136. hal_status = HAL_CAN_ActivateNotification(CANHANDLER, CAN_IT_RX_FIFO0_MSG_PENDING);
  137. } else if (CAN_FIFO_NUM == CAN_RX_FIFO1) {
  138. hal_status = HAL_CAN_ActivateNotification(CANHANDLER, CAN_IT_RX_FIFO1_MSG_PENDING);
  139. } else {
  140. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  141. return hal_status;
  142. }
  143. return hal_status;
  144. }
  145. // static HAL_StatusTypeDef deactivateRxIT() {
  146. // HAL_StatusTypeDef hal_status = HAL_ERROR;
  147. // if (CAN_FIFO_NUM == CAN_RX_FIFO0) {
  148. // hal_status = HAL_CAN_DeactivateNotification(CANHANDLER, CAN_IT_RX_FIFO0_MSG_PENDING);
  149. // } else if (CAN_FIFO_NUM == CAN_RX_FIFO1) {
  150. // hal_status = HAL_CAN_DeactivateNotification(CANHANDLER, CAN_IT_RX_FIFO1_MSG_PENDING);
  151. // } else {
  152. // ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  153. // return hal_status;
  154. // }
  155. // return hal_status;
  156. // }
  157. HAL_StatusTypeDef initializeFilter() {
  158. HAL_StatusTypeDef HAL_Status;
  159. CAN_FilterTypeDef sFilterConfig;
  160. uint32_t filterId;
  161. uint32_t mask;
  162. memset(&sFilterConfig, 0, sizeof(sFilterConfig));
  163. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 设为MASK模式
  164. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
  165. sFilterConfig.FilterFIFOAssignment = CAN_FIFO_NUM; // 关联过滤器到rxfifoNum
  166. sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
  167. sFilterConfig.SlaveStartFilterBank = CAN_MAX_FILTER_NUM; // slave filter start index
  168. /*******************************************************************************
  169. * ? *
  170. *******************************************************************************/
  171. filterId = (0); //
  172. mask = (0); //
  173. sFilterConfig.FilterBank = CAN_FILTER_INDEX; //
  174. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  175. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  176. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  177. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  178. HAL_Status = HAL_CAN_ConfigFilter(CANHANDLER, &sFilterConfig);
  179. if (HAL_Status != HAL_OK) {
  180. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  181. return HAL_Status;
  182. }
  183. // ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  184. return HAL_Status;
  185. }
  186. void zcanbus_init(uint8_t deviceId) {
  187. m_deviceId = deviceId;
  188. HAL_StatusTypeDef hal_status;
  189. m_rxbufcache.dataIsReady = false;
  190. m_rxbufcache.id = 0; // �?接收来自主机的消�?
  191. m_rxbufcache.canPacketNum = 0;
  192. hal_status = initializeFilter();
  193. if (hal_status != HAL_OK) {
  194. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  195. return;
  196. }
  197. hal_status = HAL_CAN_Start(CANHANDLER); // 开启CAN
  198. if (hal_status != HAL_OK) {
  199. ZLOGE(TAG, "start can fail\r\n");
  200. return;
  201. }
  202. m_lock.init();
  203. HAL_StatusTypeDef status = activateRxIT();
  204. if (status != HAL_OK) {
  205. ZLOGE(TAG, "activateRxIT fail\r\n");
  206. ZASSERT(0);
  207. return;
  208. }
  209. ZLOGI(TAG, "zcanbus init done");
  210. }
  211. void zcanbus_reglistener(zcanbus_on_rx_t rxlistener) {
  212. ZASSERT(m_numListener < ZARRAY_SIZE(m_rxlistener));
  213. m_rxlistener[m_numListener++] = rxlistener;
  214. }
  215. void zcanbus_reg_on_connected_listener(zcanbus_on_connected_t connectedlistener) { m_connectedlistener = connectedlistener; }
  216. bool zcanbus_send_packet(uint8_t to, uint8_t *packet, size_t len) { return zcanbus_send_packet(to, packet, len, OVER_TIME_MS); }
  217. // static char *hex2str(uint8_t *data, size_t len) {
  218. // static char buf[200];
  219. // memset(buf, 0, sizeof(buf));
  220. // for (size_t i = 0; i < len; i++) {
  221. // sprintf(buf + i * 2, "%02x", data[i]);
  222. // }
  223. // return buf;
  224. // }
  225. bool zcanbus_send_packet(uint8_t to, uint8_t *packet, size_t len, int overtimems) {
  226. // ZLOGI(TAG, "sendPacket to:%d, %s(%d)", to, hex2str(packet, len), len);
  227. int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
  228. if (npacket > 255) {
  229. ZLOGE(TAG, "sendPacket fail, len:%d", len);
  230. return false;
  231. }
  232. int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
  233. for (uint8_t i = 0; i < npacket; i++) {
  234. bool suc = false;
  235. if (i == npacket - 1) {
  236. suc = zcanbus_send_sub_packet(to, npacket, i, packet + i * 8, finalpacketlen, overtimems);
  237. } else {
  238. suc = zcanbus_send_sub_packet(to, npacket, i, packet + i * 8, 8, overtimems);
  239. }
  240. if (!suc) {
  241. // ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
  242. return false;
  243. }
  244. }
  245. return true;
  246. }
  247. // static const char *canpacket_dump(uint8_t *data, int size) {
  248. // static char buf[20];
  249. // memset(buf, 0, sizeof(buf));
  250. // for (int i = 0; i < size; i++) {
  251. // sprintf(buf + i * 2, "%02x", data[i]);
  252. // }
  253. // return buf;
  254. // }
  255. bool zcanbus_send_sub_packet(uint8_t to, int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  256. CAN_TxHeaderTypeDef pHeader;
  257. uint8_t aData[8] /*8byte table*/;
  258. uint32_t txMailBox = 0;
  259. uint32_t enterticket = zget_ticket();
  260. memset(&pHeader, 0, sizeof(pHeader));
  261. memset(aData, 0, sizeof(aData));
  262. pHeader.StdId = 0x00;
  263. pHeader.ExtId = (m_deviceId << 16) | (to << 8) | (npacket << 4) | (packetIndex);
  264. pHeader.ExtId |= (m_priority & 0x0f) << 24;
  265. pHeader.ExtId |= (0x01 << 28);
  266. pHeader.IDE = CAN_ID_EXT;
  267. pHeader.RTR = CAN_RTR_DATA;
  268. pHeader.DLC = len;
  269. pHeader.TransmitGlobalTime = DISABLE;
  270. memcpy(aData, packet, len);
  271. // ZLOGI(TAG, "tx %s", canpacket_dump(aData, len));
  272. HAL_StatusTypeDef lastTransmitStatus = HAL_CAN_AddTxMessage(CANHANDLER, &pHeader, aData, &txMailBox);
  273. if (lastTransmitStatus != HAL_OK) {
  274. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  275. return false;
  276. }
  277. while (HAL_CAN_IsTxMessagePending(CANHANDLER, txMailBox)) {
  278. if (zhas_passedms(enterticket) > (uint32_t)overtimems) {
  279. lastTransmitStatus = HAL_TIMEOUT;
  280. HAL_CAN_AbortTxRequest(CANHANDLER, txMailBox);
  281. return false;
  282. }
  283. zos_delay_ms(1);
  284. }
  285. zos_delay_ms(1);
  286. return true;
  287. }
  288. bool zcanbus_send_ack(zcanbus_packet_t *rxpacket, uint8_t *param, size_t len) {
  289. zlock_guard l(m_lock);
  290. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  291. txpacket->index = rxpacket->index;
  292. txpacket->function_id = rxpacket->function_id;
  293. txpacket->ptype = kreceipt;
  294. if (param) memcpy(txpacket->params, param, len);
  295. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len);
  296. }
  297. bool zcanbus_send_ack(zcanbus_packet_t *rxpacket, int32_t val) { return zcanbus_send_ack(rxpacket, (uint8_t *)&val, sizeof(val)); }
  298. bool zcanbus_send_ack(zcanbus_packet_t *rxpacket, bool _val) {
  299. int32_t val = _val ? 1 : 0;
  300. return zcanbus_send_ack(rxpacket, (uint8_t *)&val, sizeof(val));
  301. }
  302. bool zcanbus_send_errorack(zcanbus_packet_t *rxpacket, int32_t errcode) {
  303. zlock_guard l(m_lock);
  304. m_priority = kpriority_receipt;
  305. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  306. txpacket->index = rxpacket->index;
  307. txpacket->function_id = rxpacket->function_id;
  308. txpacket->ptype = kerror_receipt;
  309. memcpy(txpacket->params, &errcode, sizeof(errcode));
  310. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + 4);
  311. }
  312. bool zcanbus_send_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
  313. zlock_guard l(m_lock);
  314. m_priority = kpriority_report;
  315. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  316. txpacket->index = reportIndex++;
  317. txpacket->function_id = function_id;
  318. txpacket->ptype = kreport;
  319. memcpy(txpacket->params, param, len);
  320. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, overtime);
  321. }
  322. bool zcanbus_send_event(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
  323. zlock_guard l(m_lock);
  324. m_priority = kpriority_emergency_report;
  325. eventId++;
  326. rxConfirmEventId = 0;
  327. for (size_t i = 0; i < 5; i++) {
  328. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  329. txpacket->index = eventId;
  330. txpacket->function_id = function_id;
  331. txpacket->ptype = kevent;
  332. memcpy(txpacket->params, param, len);
  333. zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, 10);
  334. for (size_t i = 0; i < 100; i++) {
  335. if (rxConfirmEventId == eventId) break;
  336. zos_delay_ms(1);
  337. }
  338. }
  339. return true;
  340. }
  341. bool zcanbus_send_emergency_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
  342. zlock_guard l(m_lock);
  343. m_priority = kpriority_emergency_report;
  344. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  345. txpacket->index = reportIndex++;
  346. txpacket->function_id = function_id;
  347. txpacket->ptype = kreport;
  348. memcpy(txpacket->params, param, len);
  349. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, overtime);
  350. }
  351. static void process_rx_packet(canrxbuffer_t *canrxbuf, uint8_t *rx, size_t len) {
  352. zcanbus_packet_t *packet = (zcanbus_packet_t *)rx;
  353. lastpacket_ticket = zget_ticket();
  354. if (!m_is_connected) {
  355. m_is_connected = true;
  356. if (m_connectedlistener) m_connectedlistener(true);
  357. }
  358. if (packet->ptype == kcmd) {
  359. for (size_t i = 0; i < m_numListener; i++) {
  360. m_rxlistener[i](canrxbuf->from, canrxbuf->to, rxdata, len);
  361. }
  362. }
  363. if (packet->ptype == kevent_confirm) {
  364. rxConfirmEventId = packet->index;
  365. }
  366. }
  367. void zcanbus_schedule() {
  368. canrxbuffer_t *rxbuf = &m_rxbufcache;
  369. uint16_t fromId = 0;
  370. uint16_t toId = 0;
  371. if (rxbuf->dataIsReady) {
  372. int dataoff = 0;
  373. // rxdata[0] = rxbuf->from;
  374. // rxdata[1] = rxbuf->to;
  375. for (size_t i = 0; i < rxbuf->canPacketNum; i++) {
  376. memcpy(rxdata + dataoff, rxbuf->canPacket[i].aData, rxbuf->canPacket[i].datalen);
  377. dataoff += rxbuf->canPacket[i].datalen;
  378. ZASSERT(dataoff < ZARRAY_SIZE(rxdata));
  379. }
  380. process_rx_packet(rxbuf, rxdata, dataoff);
  381. rxbuf->dataIsReady = false;
  382. }
  383. if (m_is_connected && zhas_passedms(lastpacket_ticket) > HEART_OVERTIME) {
  384. m_is_connected = false;
  385. if (m_connectedlistener) m_connectedlistener(false);
  386. }
  387. }
  388. bool zcanbus_is_connected() { return m_is_connected; }