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.

225 lines
7.2 KiB

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. bool ZCanReceiver::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  101. /**
  102. * @brief FIFO中缓存了多少帧的数据
  103. */
  104. uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum);
  105. if (level == 0) {
  106. return false;
  107. }
  108. HAL_StatusTypeDef HAL_RetVal;
  109. HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData);
  110. if (HAL_OK == HAL_RetVal) {
  111. // 处理接收到的can总线数据
  112. return true;
  113. }
  114. return false;
  115. }
  116. void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  117. /**
  118. * @brief
  119. */
  120. // ZLOG_INFO("%s\n", __FUNCTION__);
  121. // printf("------------------%s\n", __FUNCTION__);
  122. if (canHandle != m_config->canHandle) {
  123. return;
  124. }
  125. /**
  126. * @brief can接收到消息
  127. */
  128. CAN_RxHeaderTypeDef pHeader;
  129. uint8_t aData[8] /*8byte table*/;
  130. while (getRxMessage(&pHeader, aData)) {
  131. /**
  132. * @brief
  133. *
  134. * [2] [3bit] [8bit] [8bit] [8bit]
  135. * , from frameNum frameId
  136. */
  137. uint8_t from = (pHeader.ExtId >> 16 & 0xFF);
  138. uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8;
  139. uint8_t frameId = (pHeader.ExtId & 0x00FF);
  140. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  141. if (from != rxbuf->id) {
  142. // 目前只接收来自主机的消息
  143. continue;
  144. }
  145. if (rxbuf->dataIsReady) {
  146. // 上次接收到的消息还没有来的急处理
  147. continue;
  148. }
  149. /**
  150. * @TODO:
  151. */
  152. if (frameId == 0) {
  153. rxbuf->m_canPacketNum = 0;
  154. }
  155. if (rxbuf->m_canPacketNum < 255) {
  156. rxbuf->m_canPacket[rxbuf->m_canPacketNum].pHeader = pHeader;
  157. memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
  158. rxbuf->m_canPacketNum++;
  159. }
  160. if (nframe == frameId) {
  161. rxbuf->dataIsReady = true;
  162. }
  163. }
  164. // deactivateRxIT();
  165. }
  166. void ZCanReceiver::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
  167. if (canHandle != m_config->canHandle) {
  168. return;
  169. }
  170. ZLOGE(TAG, "onCAN_Error\r\n");
  171. }
  172. void ZCanReceiver::loop() {
  173. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  174. if (rxbuf->dataIsReady) {
  175. int dataoff = 0;
  176. for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
  177. memcpy(rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].pHeader.DLC);
  178. dataoff += rxbuf->m_canPacket[i].pHeader.DLC;
  179. }
  180. for (auto &var : m_listenerList) {
  181. var->onRceivePacket(rxbuf, rxdata, dataoff);
  182. }
  183. rxbuf->dataIsReady = false;
  184. }
  185. }
  186. HAL_StatusTypeDef ZCanReceiver::activateRxIT() {
  187. HAL_StatusTypeDef hal_status = HAL_ERROR;
  188. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  189. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  190. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  191. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  192. } else {
  193. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  194. return hal_status;
  195. }
  196. return hal_status;
  197. }
  198. HAL_StatusTypeDef ZCanReceiver::deactivateRxIT() {
  199. HAL_StatusTypeDef hal_status = HAL_ERROR;
  200. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  201. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  202. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  203. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  204. } else {
  205. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  206. return hal_status;
  207. }
  208. return hal_status;
  209. }
  210. #endif