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.

428 lines
15 KiB

12 months ago
12 months ago
12 months ago
  1. #include "zcanreceiver.hpp"
  2. #include "../mutex.hpp"
  3. #include "stm32halport/stm32halport.hpp"
  4. #define TAG "zcan"
  5. #ifndef ENABLE_OLD_CAN_PROTOCOL
  6. #define CANHANDLER &hcan1
  7. #define CAN_FILTER_INDEX 0
  8. #define CAN_MAX_FILTER_NUM 7
  9. #define CAN_FIFO_NUM CAN_RX_FIFO0
  10. #define OVER_TIME_MS 30
  11. using namespace iflytop;
  12. using namespace zscanprotocol;
  13. using namespace transmit_disfection_protocol;
  14. static uint8_t m_deviceId;
  15. static zcanbus_on_rx_t m_rxlistener[30];
  16. static uint32_t m_numListener = 0;
  17. static zcanbus_on_connected_t m_connectedlistener;
  18. static canrxbuffer_t m_rxbufcache;
  19. static uint16_t reportIndex;
  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;
  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. return true;
  286. }
  287. bool zcanbus_send_ack(zcanbus_packet_t *rxpacket, uint8_t *param, size_t len) {
  288. zlock_guard l(m_lock);
  289. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  290. txpacket->index = rxpacket->index;
  291. txpacket->function_id = rxpacket->function_id;
  292. txpacket->ptype = kreceipt;
  293. if (param) memcpy(txpacket->params, param, len);
  294. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len);
  295. }
  296. bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, int32_t val) { return zcanbus_send_ack(rxpacket, (uint8_t *)&val, sizeof(val)); }
  297. bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, bool _val) {
  298. int32_t val = _val ? 1 : 0;
  299. return zcanbus_send_ack(rxpacket, (uint8_t *)&val, sizeof(val));
  300. }
  301. bool zcanbus_send_errorack(zcanbus_packet_t *rxpacket, int32_t errcode) {
  302. zlock_guard l(m_lock);
  303. m_priority = kpriority_receipt;
  304. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  305. txpacket->index = rxpacket->index;
  306. txpacket->function_id = rxpacket->function_id;
  307. txpacket->ptype = kerror_receipt;
  308. memcpy(txpacket->params, &errcode, sizeof(errcode));
  309. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + 4);
  310. }
  311. bool zcanbus_send_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
  312. zlock_guard l(m_lock);
  313. m_priority = kpriority_report;
  314. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  315. txpacket->index = reportIndex++;
  316. txpacket->function_id = function_id;
  317. txpacket->ptype = kreport;
  318. memcpy(txpacket->params, param, len);
  319. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, overtime);
  320. }
  321. bool zcanbus_send_emergency_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
  322. zlock_guard l(m_lock);
  323. m_priority = kpriority_emergency_report;
  324. zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
  325. txpacket->index = reportIndex++;
  326. txpacket->function_id = function_id;
  327. txpacket->ptype = kreport;
  328. memcpy(txpacket->params, param, len);
  329. return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, overtime);
  330. }
  331. static void process_rx_packet(canrxbuffer_t *canrxbuf, uint8_t *rx, size_t len) {
  332. zcanbus_packet_t *packet = (zcanbus_packet_t *)rx;
  333. lastpacket_ticket = zget_ticket();
  334. if (!m_is_connected) {
  335. m_is_connected = true;
  336. if (m_connectedlistener) m_connectedlistener(true);
  337. }
  338. if (packet->ptype == kcmd) {
  339. for (size_t i = 0; i < m_numListener; i++) {
  340. m_rxlistener[i](canrxbuf->from, canrxbuf->to, rxdata, len);
  341. }
  342. }
  343. }
  344. void zcanbus_schedule() {
  345. canrxbuffer_t *rxbuf = &m_rxbufcache;
  346. uint16_t fromId = 0;
  347. uint16_t toId = 0;
  348. if (rxbuf->dataIsReady) {
  349. int dataoff = 0;
  350. // rxdata[0] = rxbuf->from;
  351. // rxdata[1] = rxbuf->to;
  352. for (size_t i = 0; i < rxbuf->canPacketNum; i++) {
  353. memcpy(rxdata + dataoff, rxbuf->canPacket[i].aData, rxbuf->canPacket[i].datalen);
  354. dataoff += rxbuf->canPacket[i].datalen;
  355. ZASSERT(dataoff < ZARRAY_SIZE(rxdata));
  356. }
  357. process_rx_packet(rxbuf, rxdata, dataoff);
  358. rxbuf->dataIsReady = false;
  359. }
  360. if (m_is_connected && zhas_passedms(lastpacket_ticket) > HEART_OVERTIME) {
  361. m_is_connected = false;
  362. if (m_connectedlistener) m_connectedlistener(false);
  363. }
  364. }
  365. bool zcanbus_is_connected() { return m_is_connected; }
  366. #endif