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.

282 lines
8.9 KiB

11 months ago
9 months ago
11 months ago
9 months ago
11 months ago
9 months ago
11 months ago
9 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. #include "zcan.hpp"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "stm32halport\halport\gins.h"
  6. using namespace iflytop;
  7. #define TAG "ZCanCmder"
  8. #define OVER_TIME_MS 5
  9. #define FIFO_NUM CAN_RX_FIFO0
  10. extern "C" {
  11. ZCAN1 *zcan1;
  12. void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) {}
  13. void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) {}
  14. void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) {}
  15. void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) {}
  16. void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) {}
  17. void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) {}
  18. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
  19. if (zcan1) zcan1->STM32_HAL_onCAN_RxFifo0MsgPending(hcan);
  20. }
  21. void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {}
  22. void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {}
  23. void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) {}
  24. void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) {}
  25. void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) {}
  26. void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {}
  27. }
  28. static void can1_init(Pin_t tx, Pin_t rx) {
  29. __HAL_RCC_CAN1_CLK_ENABLE();
  30. GPIO_InitTypeDef GPIO_InitStruct = {0};
  31. if (tx == PA12 && rx == PA11) {
  32. __HAL_RCC_GPIOA_CLK_ENABLE();
  33. GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
  34. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  35. GPIO_InitStruct.Pull = GPIO_NOPULL;
  36. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  37. GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
  38. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  39. } else if (tx == PD1 && rx == PD0) {
  40. __HAL_RCC_GPIOD_CLK_ENABLE();
  41. GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_0;
  42. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  43. GPIO_InitStruct.Pull = GPIO_NOPULL;
  44. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  45. GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
  46. HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  47. } else {
  48. ZASSERT(false);
  49. }
  50. // M1_CAN_RX
  51. // M1_CAN_TX
  52. // static_assert(M1_CAN_RX == PA11);
  53. // static_assert(M1_CAN_TX == PA12);
  54. /* CAN1 interrupt Init */
  55. HAL_NVIC_SetPriority(CAN1_TX_IRQn, 5, 0);
  56. HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
  57. HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0);
  58. HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
  59. HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 5, 0);
  60. HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
  61. HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 5, 0);
  62. HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  63. hcan1.Instance = CAN1;
  64. hcan1.Init.Prescaler = 4;
  65. hcan1.Init.Mode = CAN_MODE_NORMAL;
  66. hcan1.Init.SyncJumpWidth = CAN_SJW_3TQ;
  67. hcan1.Init.TimeSeg1 = CAN_BS1_14TQ;
  68. hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
  69. hcan1.Init.TimeTriggeredMode = ENABLE;
  70. hcan1.Init.AutoBusOff = ENABLE;
  71. hcan1.Init.AutoWakeUp = DISABLE;
  72. hcan1.Init.AutoRetransmission = ENABLE;
  73. hcan1.Init.ReceiveFifoLocked = ENABLE;
  74. hcan1.Init.TransmitFifoPriority = DISABLE;
  75. if (HAL_CAN_Init(&hcan1) != HAL_OK) {
  76. Error_Handler();
  77. }
  78. }
  79. HAL_StatusTypeDef ZCAN1::initializeFilter() {
  80. /**
  81. * @brief ID֡ʽ
  82. * [ 27:0 ]
  83. * [ STDID ] [ EXTID ]
  84. * [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0]
  85. * ȼ ֡ ĿID ԴID
  86. */
  87. HAL_StatusTypeDef HAL_Status;
  88. CAN_FilterTypeDef sFilterConfig;
  89. uint32_t filterId;
  90. uint32_t mask;
  91. memset(&sFilterConfig, 0, sizeof(sFilterConfig));
  92. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // ��ΪMASKģʽ
  93. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
  94. sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // ������������rxfifoNum
  95. sFilterConfig.FilterActivation = ENABLE; // ����������
  96. sFilterConfig.SlaveStartFilterBank = 7; // slave filter start index
  97. /*******************************************************************************
  98. * Ϣ *
  99. *******************************************************************************/
  100. filterId = (0); //
  101. mask = (0); //
  102. sFilterConfig.FilterBank = 0; //
  103. sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
  104. sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
  105. sFilterConfig.FilterIdLow = filterId & 0xffff; //
  106. sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
  107. HAL_Status = HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
  108. if (HAL_Status != HAL_OK) {
  109. ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail");
  110. return HAL_Status;
  111. }
  112. ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3);
  113. return HAL_Status;
  114. }
  115. HAL_StatusTypeDef ZCAN1::activateRxIT() {
  116. HAL_StatusTypeDef hal_status = HAL_ERROR;
  117. hal_status = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
  118. return hal_status;
  119. }
  120. void ZCAN1::zcaninit(Pin_t tx, Pin_t rx) {
  121. if (inited) return;
  122. inited = true;
  123. can1_init(tx, rx);
  124. HAL_StatusTypeDef hal_status;
  125. m_lock.init();
  126. /**
  127. * @brief ʼ
  128. */
  129. hal_status = initializeFilter();
  130. if (hal_status != HAL_OK) {
  131. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  132. return;
  133. }
  134. /**
  135. * @brief CAN
  136. */
  137. hal_status = HAL_CAN_Start(&hcan1); // ����CAN
  138. if (hal_status != HAL_OK) {
  139. ZLOGE(TAG, "start can fail\r\n");
  140. return;
  141. }
  142. /**
  143. * @brief ص
  144. */
  145. HAL_StatusTypeDef status = activateRxIT();
  146. if (status != HAL_OK) {
  147. ZLOGE(TAG, "activateRxIT fail\r\n");
  148. return;
  149. }
  150. zcan1 = this;
  151. // ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { loop(); }, 0);
  152. rxQueue.initialize(5, sizeof(zcanrx_t));
  153. canListener.init("canListener");
  154. canListener.start([this]() {
  155. while (1) {
  156. zcanrx_t rx;
  157. if (rxQueue.receive(&rx, 1000)) {
  158. // ZLOGI(TAG, "zcanrx 0x%08x:%s", rx.extid, zhex2str(rx.rxpacket, rx.rkpacketlen));
  159. if (onZcanRx) onZcanRx(&rx);
  160. }
  161. }
  162. });
  163. }
  164. bool ZCAN1::_txMsg(const uint32_t extid, const uint8_t txdata[], uint32_t txdatalen, int32_t overtime) {
  165. zlock_guard l(m_lock);
  166. CAN_TxHeaderTypeDef pHeader;
  167. uint8_t aData[8] /*8byte table*/;
  168. uint32_t txMailBox = 0;
  169. uint32_t enterticket = zos_get_tick();
  170. memset(&pHeader, 0, sizeof(pHeader));
  171. memset(aData, 0, sizeof(aData));
  172. pHeader.StdId = 0x00;
  173. pHeader.ExtId = extid;
  174. pHeader.IDE = CAN_ID_EXT;
  175. pHeader.RTR = CAN_RTR_DATA;
  176. pHeader.DLC = txdatalen;
  177. pHeader.TransmitGlobalTime = DISABLE;
  178. memcpy(aData, txdata, txdatalen);
  179. HAL_StatusTypeDef txsuc = HAL_CAN_AddTxMessage(&hcan1, &pHeader, aData, &txMailBox);
  180. if (txsuc != HAL_OK) {
  181. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  182. return false;
  183. }
  184. int i = 1;
  185. while (HAL_CAN_IsTxMessagePending(&hcan1, txMailBox)) {
  186. if (zos_haspassedms(enterticket) > (uint32_t)overtime) {
  187. if (!txNoError) ZLOGE(TAG, "HAL_CAN_IsTxMessagePending overtime");
  188. HAL_CAN_AbortTxRequest(&hcan1, txMailBox);
  189. return false;
  190. }
  191. osDelay(i);
  192. i++;
  193. }
  194. return true;
  195. }
  196. bool ZCAN1::txMsgNoError(const uint32_t extid, const uint8_t txdata[], uint32_t txdatalen, int32_t overtime) {
  197. zlock_guard l(m_lock);
  198. txNoError = true;
  199. bool suc = _txMsg(extid, txdata, txdatalen, overtime);
  200. txNoError = false;
  201. return suc;
  202. }
  203. bool ZCAN1::txMsg(const uint32_t extid, const uint8_t txdata[], uint32_t txdatalen, int32_t overtime) {
  204. zlock_guard l(m_lock);
  205. return _txMsg(extid, txdata, txdatalen, overtime);
  206. }
  207. void ZCAN1::regOnCanMessage(function<void(zcanrx_t *rx)> onmessage) { onZcanRx = onmessage; }
  208. bool ZCAN1::getRxMsg(zcanrx_t *rx) {
  209. /**
  210. * @brief ȡǰFIFOл˶֡
  211. */
  212. CAN_RxHeaderTypeDef pHeader;
  213. uint32_t level = HAL_CAN_GetRxFifoFillLevel(&hcan1, FIFO_NUM);
  214. if (level == 0) {
  215. return false;
  216. }
  217. HAL_StatusTypeDef HAL_RetVal;
  218. HAL_RetVal = HAL_CAN_GetRxMessage(&hcan1, FIFO_NUM, &pHeader, rx->rxpacket);
  219. rx->extid = pHeader.ExtId;
  220. rx->rkpacketlen = pHeader.DLC;
  221. if (HAL_OK == HAL_RetVal) {
  222. // �������յ���can��������
  223. return true;
  224. }
  225. return false;
  226. }
  227. static inline const char *zhex2str(uint8_t *data, uint32_t len) {
  228. static char str[256];
  229. for (uint32_t i = 0; i < len; i++) {
  230. sprintf(str + i * 2, "%02X", data[i]);
  231. }
  232. return str;
  233. }
  234. void ZCAN1::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  235. if (canHandle != &hcan1) {
  236. return;
  237. }
  238. /**
  239. * @brief TODO:ʱԴ
  240. */
  241. while (true) {
  242. zcanrx_t rx;
  243. bool rxmsg = getRxMsg(&rx);
  244. if (rxmsg) {
  245. rxQueue.send(&rx, 0);
  246. } else {
  247. break;
  248. }
  249. }
  250. }
  251. void ZCAN1::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) { ZLOGE(TAG, "onCAN_Error\r\n"); }