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.

330 lines
10 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
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. using namespace zcr;
  8. #define TAG "ZCanCmder"
  9. #define OVER_TIME_MS 5
  10. ZCanCmder::CFG *ZCanCmder::createCFG(uint8_t deviceId) {
  11. CFG *cfg = new CFG();
  12. ZASSERT(cfg != NULL);
  13. cfg->deviceId = deviceId;
  14. #ifdef STM32F103xB
  15. cfg->canHandle = &hcan;
  16. #else
  17. cfg->canHandle = &hcan1;
  18. #endif
  19. cfg->canFilterIndex0 = 0;
  20. cfg->maxFilterNum = 7;
  21. cfg->rxfifoNum = CAN_RX_FIFO0;
  22. return cfg;
  23. }
  24. void ZCanCmder::init(CFG *cfg) {
  25. HAL_StatusTypeDef hal_status;
  26. m_config = cfg;
  27. /**
  28. * @brief ʼCAN
  29. */
  30. /**
  31. * @brief ʼϢbuf
  32. */
  33. m_canPacketRxBuffer[0].dataIsReady = false;
  34. m_canPacketRxBuffer[0].id = 1; // ֻ����������������Ϣ
  35. m_canPacketRxBuffer[0].m_canPacketNum = 0;
  36. /**
  37. * @brief ʼ
  38. */
  39. hal_status = initializeFilter();
  40. if (hal_status != HAL_OK) {
  41. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  42. return;
  43. }
  44. /**
  45. * @brief CAN
  46. */
  47. hal_status = HAL_CAN_Start(m_config->canHandle); // ����CAN
  48. if (hal_status != HAL_OK) {
  49. ZLOGE(TAG, "start can fail\r\n");
  50. return;
  51. }
  52. /**
  53. * @brief ص
  54. */
  55. ZCanIRQDispatcher::instance().regListener(this);
  56. HAL_StatusTypeDef status = activateRxIT();
  57. if (status != HAL_OK) {
  58. ZLOGE(TAG, "activateRxIT fail\r\n");
  59. return;
  60. }
  61. // ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { loop(); }, 0);
  62. }
  63. HAL_StatusTypeDef ZCanCmder::initializeFilter() {
  64. /**
  65. * @brief ID֡ʽ
  66. * [ 27:0 ]
  67. * [ STDID ] [ EXTID ]
  68. * [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0]
  69. * ȼ ֡ ĿID ԴID
  70. */
  71. HAL_StatusTypeDef HAL_Status;
  72. CAN_FilterTypeDef sFilterConfig;
  73. uint32_t filterId;
  74. uint32_t mask;
  75. memset(&sFilterConfig, 0, sizeof(sFilterConfig));
  76. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // ��ΪMASKģʽ
  77. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
  78. sFilterConfig.FilterFIFOAssignment = m_config->rxfifoNum; // ������������rxfifoNum
  79. sFilterConfig.FilterActivation = ENABLE; // ����������
  80. sFilterConfig.SlaveStartFilterBank = m_config->maxFilterNum; // slave filter start index
  81. /*******************************************************************************
  82. * Ϣ *
  83. *******************************************************************************/
  84. filterId = (0); //
  85. mask = (0); //
  86. sFilterConfig.FilterBank = m_config->canFilterIndex0; //
  87. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  88. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  89. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  90. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  91. HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig);
  92. if (HAL_Status != HAL_OK) {
  93. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  94. return HAL_Status;
  95. }
  96. ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  97. return HAL_Status;
  98. }
  99. void ZCanCmder::registerListener(ZCanCmderListener *listener) { m_listenerList.push_back(listener); }
  100. void ZCanCmder::regListener(zcan_cmder_listener_t listener) { m_listenerList2.push_back(listener); }
  101. void ZCanCmder::sendPacket(uint8_t *packet, size_t len) {
  102. /**
  103. * @brief
  104. */
  105. int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
  106. if (npacket > 255) {
  107. ZLOGE(TAG, "sendPacket fail, len:%d", len);
  108. return;
  109. }
  110. int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
  111. for (uint8_t i = 0; i < npacket; i++) {
  112. bool suc = false;
  113. if (i == npacket - 1) {
  114. suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS);
  115. } else {
  116. suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS);
  117. }
  118. if (!suc) {
  119. ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
  120. return;
  121. }
  122. }
  123. }
  124. void ZCanCmder::sendAck(Cmdheader_t *cmdheader, uint8_t *data, size_t len) {
  125. Cmdheader_t *txheader = (Cmdheader_t *)txbuff;
  126. memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
  127. txheader->packetType = kpt_ack;
  128. memcpy(txheader->data, data, len);
  129. sendPacket(txbuff, sizeof(Cmdheader_t) + len);
  130. }
  131. void ZCanCmder::sendExecStatusReport(Cmdheader_t *rxcmdheader, uint8_t *data, size_t len) {
  132. Cmdheader_t *txheader = (Cmdheader_t *)txbuff;
  133. memcpy(txheader, rxcmdheader, sizeof(Cmdheader_t));
  134. txheader->packetType = kpt_cmd_exec_status_report;
  135. memcpy(txheader->data, data, len);
  136. sendPacket(txbuff, sizeof(Cmdheader_t) + len);
  137. }
  138. void ZCanCmder::sendStatusReport(Cmdheader_t *rxcmdheader, uint8_t *data, size_t len) {
  139. Cmdheader_t *txheader = (Cmdheader_t *)txbuff;
  140. memcpy(txheader, rxcmdheader, sizeof(Cmdheader_t));
  141. txheader->packetType = kpt_report;
  142. memcpy(txheader->data, data, len);
  143. sendPacket(txbuff, sizeof(Cmdheader_t) + len);
  144. }
  145. void ZCanCmder::sendErrorAck(Cmdheader_t *cmdheader, uint16_t id, uint32_t errcode) {
  146. Cmdheader_t *txheader = (Cmdheader_t *)txbuff;
  147. memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
  148. txheader->packetType = kpt_error_ack;
  149. zcan_cmder_error_ack_t *error_ack = (zcan_cmder_error_ack_t *)txheader->data;
  150. error_ack->id = id;
  151. error_ack->errorcode = errcode;
  152. sendPacket(txbuff, sizeof(Cmdheader_t) + sizeof(zcan_cmder_error_ack_t));
  153. }
  154. bool ZCanCmder::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
  155. // ZLOGI(TAG, "sendPacketSub(%d:%d)", npacket, packetIndex);
  156. CAN_TxHeaderTypeDef pHeader;
  157. uint8_t aData[8] /*8byte table*/;
  158. uint32_t txMailBox = 0;
  159. uint32_t enterticket = zos_get_tick();
  160. memset(&pHeader, 0, sizeof(pHeader));
  161. memset(aData, 0, sizeof(aData));
  162. pHeader.StdId = 0x00;
  163. pHeader.ExtId = (m_config->deviceId << 16) | (npacket << 8) | packetIndex;
  164. pHeader.IDE = CAN_ID_EXT;
  165. pHeader.RTR = CAN_RTR_DATA;
  166. pHeader.DLC = len;
  167. pHeader.TransmitGlobalTime = DISABLE;
  168. memcpy(aData, packet, len);
  169. m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox);
  170. if (m_lastTransmitStatus != HAL_OK) {
  171. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  172. return false;
  173. }
  174. while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) {
  175. if (zos_haspassedms(enterticket) > (uint32_t)overtimems) {
  176. m_lastTransmitStatus = HAL_TIMEOUT;
  177. HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox);
  178. return false;
  179. }
  180. // m_os->sleepMS(1);
  181. }
  182. if (txPacketInterval_ms > 0) {
  183. osDelay(txPacketInterval_ms);
  184. }
  185. return true;
  186. }
  187. bool ZCanCmder::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
  188. /**
  189. * @brief ȡǰFIFOл˶֡
  190. */
  191. uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum);
  192. if (level == 0) {
  193. return false;
  194. }
  195. HAL_StatusTypeDef HAL_RetVal;
  196. HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData);
  197. if (HAL_OK == HAL_RetVal) {
  198. // �������յ���can��������
  199. return true;
  200. }
  201. return false;
  202. }
  203. void ZCanCmder::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  204. /**
  205. * @brief ж
  206. */
  207. // ZLOG_INFO("%s\n", __FUNCTION__);
  208. // printf("------------------%s\n", __FUNCTION__);
  209. if (canHandle != m_config->canHandle) {
  210. return;
  211. }
  212. /**
  213. * @brief canյϢ
  214. */
  215. CAN_RxHeaderTypeDef pHeader;
  216. uint8_t aData[8] /*8byte table*/;
  217. while (getRxMessage(&pHeader, aData)) {
  218. /**
  219. * @brief Ϣʽ
  220. *
  221. * [2] [3bit] [8bit] [8bit] [8bit]
  222. * , from frameNum frameId
  223. */
  224. uint8_t from = (pHeader.ExtId >> 16 & 0xFF);
  225. uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8;
  226. uint8_t frameId = (pHeader.ExtId & 0x00FF);
  227. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  228. if (from != rxbuf->id) {
  229. // Ŀǰֻ����������������Ϣ
  230. continue;
  231. }
  232. if (rxbuf->dataIsReady) {
  233. // �ϴν��յ�����Ϣ��û�����ļ�����
  234. continue;
  235. }
  236. /**
  237. * @TODO:жǷ񶪰
  238. */
  239. if (frameId == 0) {
  240. rxbuf->m_canPacketNum = 0;
  241. }
  242. if (rxbuf->m_canPacketNum < 255) {
  243. rxbuf->m_canPacket[rxbuf->m_canPacketNum].pHeader = pHeader;
  244. memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
  245. rxbuf->m_canPacketNum++;
  246. }
  247. if (nframe == frameId + 1) {
  248. rxbuf->dataIsReady = true;
  249. }
  250. }
  251. // deactivateRxIT();
  252. }
  253. void ZCanCmder::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
  254. if (canHandle != m_config->canHandle) {
  255. return;
  256. }
  257. ZLOGE(TAG, "onCAN_Error\r\n");
  258. }
  259. void ZCanCmder::loop() {
  260. CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
  261. if (rxbuf->dataIsReady) {
  262. int dataoff = 0;
  263. for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
  264. memcpy(rxbuf->rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].pHeader.DLC);
  265. dataoff += rxbuf->m_canPacket[i].pHeader.DLC;
  266. }
  267. rxbuf->rxdataSize = dataoff;
  268. for (auto &var : m_listenerList) {
  269. var->onRceivePacket(rxbuf);
  270. }
  271. for (auto &var : m_listenerList2) {
  272. var(rxbuf);
  273. }
  274. rxbuf->dataIsReady = false;
  275. }
  276. }
  277. HAL_StatusTypeDef ZCanCmder::activateRxIT() {
  278. HAL_StatusTypeDef hal_status = HAL_ERROR;
  279. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  280. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  281. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  282. hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  283. } else {
  284. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  285. return hal_status;
  286. }
  287. return hal_status;
  288. }
  289. HAL_StatusTypeDef ZCanCmder::deactivateRxIT() {
  290. HAL_StatusTypeDef hal_status = HAL_ERROR;
  291. if (m_config->rxfifoNum == CAN_RX_FIFO0) {
  292. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
  293. } else if (m_config->rxfifoNum == CAN_RX_FIFO1) {
  294. hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
  295. } else {
  296. ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n");
  297. return hal_status;
  298. }
  299. return hal_status;
  300. }
  301. #endif