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.

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