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.

299 lines
9.5 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years 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. #define TAG "ZCanReceiver"
  8. #define OVER_TIME_MS 5
  9. ZCanReceiver::CFG *ZCanReceiver::createCFG(uint8_t deviceId) {
  10. CFG *cfg = new CFG();
  11. ZASSERT(cfg != NULL);
  12. cfg->deviceId = deviceId;
  13. #ifdef STM32F103xB
  14. cfg->canHandle = &hcan;
  15. #else
  16. cfg->canHandle = &hcan1;
  17. #endif
  18. cfg->canFilterIndex0 = 0;
  19. cfg->maxFilterNum = 7;
  20. cfg->rxfifoNum = CAN_RX_FIFO0;
  21. return cfg;
  22. }
  23. void ZCanReceiver::init(CFG *cfg) {
  24. HAL_StatusTypeDef hal_status;
  25. m_config = cfg;
  26. /**
  27. * @brief CAN
  28. */
  29. /**
  30. * @brief buf
  31. */
  32. m_canPacketRxBuffer[0].dataIsReady = false;
  33. m_canPacketRxBuffer[0].id = 1; // 只接收来自主机的消息
  34. m_canPacketRxBuffer[0].m_canPacketNum = 0;
  35. /**
  36. * @brief
  37. */
  38. hal_status = initializeFilter();
  39. if (hal_status != HAL_OK) {
  40. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  41. return;
  42. }
  43. /**
  44. * @brief CAN
  45. */
  46. hal_status = HAL_CAN_Start(m_config->canHandle); // 开启CAN
  47. if (hal_status != HAL_OK) {
  48. ZLOGE(TAG, "start can fail\r\n");
  49. return;
  50. }
  51. /**
  52. * @brief
  53. */
  54. ZCanIRQDispatcher::instance().regListener(this);
  55. HAL_StatusTypeDef status = activateRxIT();
  56. if (status != HAL_OK) {
  57. ZLOGE(TAG, "activateRxIT fail\r\n");
  58. return;
  59. }
  60. ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { loop(); }, 0);
  61. }
  62. HAL_StatusTypeDef ZCanReceiver::initializeFilter() {
  63. /**
  64. * @brief ID区帧格式
  65. * [ 27:0 ]
  66. * [ STDID ] [ EXTID ]
  67. * [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0]
  68. * ID ID
  69. */
  70. HAL_StatusTypeDef HAL_Status;
  71. CAN_FilterTypeDef sFilterConfig;
  72. uint32_t filterId;
  73. uint32_t mask;
  74. memset(&sFilterConfig, 0, sizeof(sFilterConfig));
  75. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 设为MASK模式
  76. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
  77. sFilterConfig.FilterFIFOAssignment = m_config->rxfifoNum; // 关联过滤器到rxfifoNum
  78. sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
  79. sFilterConfig.SlaveStartFilterBank = m_config->maxFilterNum; // slave filter start index
  80. /*******************************************************************************
  81. * *
  82. *******************************************************************************/
  83. filterId = (0); //
  84. mask = (0); //
  85. sFilterConfig.FilterBank = m_config->canFilterIndex0; //
  86. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  87. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  88. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  89. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  90. HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig);
  91. if (HAL_Status != HAL_OK) {
  92. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  93. return HAL_Status;
  94. }
  95. ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  96. return HAL_Status;
  97. }
  98. void ZCanReceiver::registerListener(ZCanRceiverListener *listener) { m_listenerList.push_back(listener); }
  99. void ZCanReceiver::sendPacket(uint8_t *packet, size_t len) {
  100. /**
  101. * @brief
  102. */
  103. int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
  104. if (npacket > 255) {
  105. ZLOGE(TAG, "sendPacket fail, len:%d", len);
  106. return;
  107. }
  108. int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
  109. for (uint8_t i = 0; i < npacket; i++) {
  110. bool suc = false;
  111. if (i == npacket - 1) {
  112. suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS);
  113. } else {
  114. suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS);
  115. }
  116. if (!suc) {
  117. ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
  118. return;
  119. }
  120. }
  121. }
  122. void ZCanReceiver::sendAck(Cmdheader_t *cmdheader, uint8_t *data, size_t len) {
  123. Cmdheader_t *txheader = (Cmdheader_t *)txbuff;
  124. memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
  125. txheader->packetType = kpt_ack;
  126. memcpy(txheader->data, data, len);
  127. sendPacket(txbuff, sizeof(Cmdheader_t) + len);
  128. }
  129. void ZCanReceiver::sendErrorAck(Cmdheader_t *cmdheader, int16_t errcode) {
  130. Cmdheader_t *txheader = (Cmdheader_t *)txbuff;
  131. memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
  132. txheader->packetType = kpt_error_ack;
  133. sendPacket(txbuff, sizeof(Cmdheader_t) + 2);
  134. }
  135. bool ZCanReceiver::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  136. CAN_TxHeaderTypeDef pHeader;
  137. uint8_t aData[8] /*8byte table*/;
  138. uint32_t txMailBox = 0;
  139. uint32_t enterticket = chip_get_ticket();
  140. memset(&pHeader, 0, sizeof(pHeader));
  141. memset(aData, 0, sizeof(aData));
  142. pHeader.StdId = 0x00;
  143. pHeader.ExtId = (m_config->deviceId << 16) | (npacket << 8) | packetIndex;
  144. pHeader.IDE = CAN_ID_EXT;
  145. pHeader.RTR = CAN_RTR_DATA;
  146. pHeader.DLC = len;
  147. pHeader.TransmitGlobalTime = DISABLE;
  148. memcpy(aData, packet, len);
  149. m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox);
  150. if (m_lastTransmitStatus != HAL_OK) {
  151. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  152. return false;
  153. }
  154. while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) {
  155. if (haspassedms(enterticket) > (uint32_t)overtimems) {
  156. m_lastTransmitStatus = HAL_TIMEOUT;
  157. HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox);
  158. return false;
  159. }
  160. // m_os->sleepMS(1);
  161. }
  162. return true;
  163. }
  164. bool ZCanReceiver::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  165. /**
  166. * @brief FIFO中缓存了多少帧的数据
  167. */
  168. uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum);
  169. if (level == 0) {
  170. return false;
  171. }
  172. HAL_StatusTypeDef HAL_RetVal;
  173. HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData);
  174. if (HAL_OK == HAL_RetVal) {
  175. // 处理接收到的can总线数据
  176. return true;
  177. }
  178. return false;
  179. }
  180. void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  181. /**
  182. * @brief
  183. */
  184. // ZLOG_INFO("%s\n", __FUNCTION__);
  185. // printf("------------------%s\n", __FUNCTION__);
  186. if (canHandle != m_config->canHandle) {
  187. return;
  188. }
  189. /**
  190. * @brief can接收到消息
  191. */
  192. CAN_RxHeaderTypeDef pHeader;
  193. uint8_t aData[8] /*8byte table*/;
  194. while (getRxMessage(&pHeader, aData)) {
  195. /**
  196. * @brief
  197. *
  198. * [2] [3bit] [8bit] [8bit] [8bit]
  199. * , from frameNum frameId
  200. */
  201. uint8_t from = (pHeader.ExtId >> 16 & 0xFF);
  202. uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8;
  203. uint8_t frameId = (pHeader.ExtId & 0x00FF);
  204. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  205. if (from != rxbuf->id) {
  206. // 目前只接收来自主机的消息
  207. continue;
  208. }
  209. if (rxbuf->dataIsReady) {
  210. // 上次接收到的消息还没有来的急处理
  211. continue;
  212. }
  213. /**
  214. * @TODO:
  215. */
  216. if (frameId == 0) {
  217. rxbuf->m_canPacketNum = 0;
  218. }
  219. if (rxbuf->m_canPacketNum < 255) {
  220. rxbuf->m_canPacket[rxbuf->m_canPacketNum].pHeader = pHeader;
  221. memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
  222. rxbuf->m_canPacketNum++;
  223. }
  224. if (nframe == frameId + 1) {
  225. rxbuf->dataIsReady = true;
  226. }
  227. }
  228. // deactivateRxIT();
  229. }
  230. void ZCanReceiver::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
  231. if (canHandle != m_config->canHandle) {
  232. return;
  233. }
  234. ZLOGE(TAG, "onCAN_Error\r\n");
  235. }
  236. void ZCanReceiver::loop() {
  237. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  238. if (rxbuf->dataIsReady) {
  239. int dataoff = 0;
  240. for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
  241. memcpy(rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].pHeader.DLC);
  242. dataoff += rxbuf->m_canPacket[i].pHeader.DLC;
  243. }
  244. for (auto &var : m_listenerList) {
  245. var->onRceivePacket(rxbuf, rxdata, dataoff);
  246. }
  247. rxbuf->dataIsReady = false;
  248. }
  249. }
  250. HAL_StatusTypeDef ZCanReceiver::activateRxIT() {
  251. HAL_StatusTypeDef hal_status = HAL_ERROR;
  252. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  253. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  254. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  255. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  256. } else {
  257. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  258. return hal_status;
  259. }
  260. return hal_status;
  261. }
  262. HAL_StatusTypeDef ZCanReceiver::deactivateRxIT() {
  263. HAL_StatusTypeDef hal_status = HAL_ERROR;
  264. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  265. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  266. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  267. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  268. } else {
  269. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  270. return hal_status;
  271. }
  272. return hal_status;
  273. }
  274. #endif