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.

270 lines
8.4 KiB

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