hand_acid_mainboard
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.

253 lines
7.9 KiB

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. can1_init();
  110. HAL_StatusTypeDef hal_status;
  111. m_lock.init();
  112. /**
  113. * @brief ʼ
  114. */
  115. hal_status = initializeFilter();
  116. if (hal_status != HAL_OK) {
  117. ZLOGE(TAG, "start can initializeFilter fail\r\n");
  118. return;
  119. }
  120. /**
  121. * @brief CAN
  122. */
  123. hal_status = HAL_CAN_Start(&hcan1); // ����CAN
  124. if (hal_status != HAL_OK) {
  125. ZLOGE(TAG, "start can fail\r\n");
  126. return;
  127. }
  128. /**
  129. * @brief ص
  130. */
  131. HAL_StatusTypeDef status = activateRxIT();
  132. if (status != HAL_OK) {
  133. ZLOGE(TAG, "activateRxIT fail\r\n");
  134. return;
  135. }
  136. zcan1 = this;
  137. // ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { loop(); }, 0);
  138. rxQueue.initialize(5, sizeof(zcanrx_t));
  139. canListener.init("canListener");
  140. canListener.start([this]() {
  141. while (1) {
  142. zcanrx_t rx;
  143. if (rxQueue.receive(&rx, 1000)) {
  144. // ZLOGI(TAG, "zcanrx 0x%08x:%s", rx.extid, zhex2str(rx.rxpacket, rx.rkpacketlen));
  145. if (onZcanRx) onZcanRx(&rx);
  146. }
  147. }
  148. });
  149. }
  150. bool ZCAN1::txMsg(const uint32_t extid, const uint8_t txdata[], uint32_t txdatalen, int32_t overtime) {
  151. zlock_guard l(m_lock);
  152. CAN_TxHeaderTypeDef pHeader;
  153. uint8_t aData[8] /*8byte table*/;
  154. uint32_t txMailBox = 0;
  155. uint32_t enterticket = zos_get_tick();
  156. memset(&pHeader, 0, sizeof(pHeader));
  157. memset(aData, 0, sizeof(aData));
  158. pHeader.StdId = 0x00;
  159. pHeader.ExtId = extid;
  160. pHeader.IDE = CAN_ID_EXT;
  161. pHeader.RTR = CAN_RTR_DATA;
  162. pHeader.DLC = txdatalen;
  163. pHeader.TransmitGlobalTime = DISABLE;
  164. memcpy(aData, txdata, txdatalen);
  165. HAL_StatusTypeDef txsuc = HAL_CAN_AddTxMessage(&hcan1, &pHeader, aData, &txMailBox);
  166. if (txsuc != HAL_OK) {
  167. ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
  168. return false;
  169. }
  170. while (HAL_CAN_IsTxMessagePending(&hcan1, txMailBox)) {
  171. if (zos_haspassedms(enterticket) > (uint32_t)overtime) {
  172. ZLOGE(TAG, "HAL_CAN_IsTxMessagePending overtime");
  173. HAL_CAN_AbortTxRequest(&hcan1, txMailBox);
  174. return false;
  175. }
  176. }
  177. return true;
  178. }
  179. void ZCAN1::regOnCanMessage(function<void(zcanrx_t *rx)> onmessage) { onZcanRx = onmessage; }
  180. bool ZCAN1::getRxMsg(zcanrx_t *rx) {
  181. /**
  182. * @brief ȡǰFIFOл˶֡
  183. */
  184. CAN_RxHeaderTypeDef pHeader;
  185. uint32_t level = HAL_CAN_GetRxFifoFillLevel(&hcan1, FIFO_NUM);
  186. if (level == 0) {
  187. return false;
  188. }
  189. HAL_StatusTypeDef HAL_RetVal;
  190. HAL_RetVal = HAL_CAN_GetRxMessage(&hcan1, FIFO_NUM, &pHeader, rx->rxpacket);
  191. rx->extid = pHeader.ExtId;
  192. rx->rkpacketlen = pHeader.DLC;
  193. if (HAL_OK == HAL_RetVal) {
  194. // �������յ���can��������
  195. return true;
  196. }
  197. return false;
  198. }
  199. static inline const char *zhex2str(uint8_t *data, uint32_t len) {
  200. static char str[256];
  201. for (uint32_t i = 0; i < len; i++) {
  202. sprintf(str + i * 2, "%02X", data[i]);
  203. }
  204. return str;
  205. }
  206. void ZCAN1::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) {
  207. if (canHandle != &hcan1) {
  208. return;
  209. }
  210. /**
  211. * @brief TODO:ʱԴ
  212. */
  213. while (true) {
  214. zcanrx_t rx;
  215. bool rxmsg = getRxMsg(&rx);
  216. if (rxmsg) {
  217. rxQueue.send(&rx, 0);
  218. } else {
  219. break;
  220. }
  221. }
  222. }
  223. void ZCAN1::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) { ZLOGE(TAG, "onCAN_Error\r\n"); }