#include "hal_can.h" #include "usart.h" #include "delay.h" #include "board.h" #include "sys_log.h" #include "sys_common.h" #include "string.h" #define CAN_RX_IRQn CAN1_RX0_IRQn #define CAN_TX_IRQn CAN1_TX_IRQn #define FIX_TIME_SEG 1 #define CAN_TX_RETRY_CNT 2 static can_rcv_cb_def g_s_can_rcv_cb = NULL; static can_send_suc_cb_def g_s_can_send_suc_cb = NULL; static can_err_cb_def g_s_can_err_cb = NULL; static uint32_t g_s_tx_mailbox; static uint8_t g_s_can_tx_payload[8]; static uint8_t g_s_can_tx_cnt; CAN_HandleTypeDef g_s_can1_handler; CAN_TxHeaderTypeDef g_s_can_tx_header; CAN_RxHeaderTypeDef g_s_can_rx_header; int HAL_CanInit(void) { int err_code; g_s_can1_handler.Instance = CAN1; g_s_can1_handler.Init.TimeTriggeredMode = DISABLE; g_s_can1_handler.Init.AutoBusOff = DISABLE; g_s_can1_handler.Init.AutoWakeUp = DISABLE; g_s_can1_handler.Init.AutoRetransmission = DISABLE; g_s_can1_handler.Init.ReceiveFifoLocked = DISABLE; g_s_can1_handler.Init.TransmitFifoPriority = DISABLE; g_s_can1_handler.Init.Mode = CAN_MODE_NORMAL; g_s_can1_handler.Init.SyncJumpWidth = CAN_SJW_1TQ; g_s_can1_handler.Init.Prescaler = 4; g_s_can1_handler.Init.TimeSeg1 = CAN_BS1_9TQ; g_s_can1_handler.Init.TimeSeg2 = CAN_BS2_8TQ; err_code = HAL_CAN_Init(&g_s_can1_handler); if (err_code != HAL_OK) // { return -1; } err_code = HAL_CanFilterConfig(); if (err_code != HAL_OK) // { return -2; } /*##-4- Activate CAN RX notification #######################################*/ if (HAL_CAN_ActivateNotification(&g_s_can1_handler, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK){ /* Initialization Error */ return -3; } if (HAL_CAN_ActivateNotification(&g_s_can1_handler, CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK){ /* Initialization Error */ return -3; } if (HAL_CAN_ActivateNotification(&g_s_can1_handler, CAN_IT_BUSOFF) != HAL_OK){ /* Initialization Error */ return -3; } if (HAL_CAN_ActivateNotification(&g_s_can1_handler, CAN_IT_ERROR_WARNING) != HAL_OK){ /* Initialization Error */ return -3; } if (HAL_CAN_ActivateNotification(&g_s_can1_handler, CAN_IT_ERROR_PASSIVE) != HAL_OK){ /* Initialization Error */ return -3; } if (HAL_CAN_ActivateNotification(&g_s_can1_handler, CAN_IT_ERROR) != HAL_OK){ /* Initialization Error */ return -3; } return 0; } void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_CAN1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_Initure.Pin = CAN_H_PIN; GPIO_Initure.Mode = GPIO_MODE_AF_PP; GPIO_Initure.Pull = GPIO_PULLUP; GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(CAN_GPIO, &GPIO_Initure); GPIO_Initure.Pin = CAN_L_PIN; GPIO_Initure.Mode = GPIO_MODE_AF_INPUT; GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(CAN_GPIO, &GPIO_Initure); /*##-2- Configure the NVIC*/ /* NVIC configuration for CAN1 Reception complete interrupt */ HAL_NVIC_SetPriority(CAN_RX_IRQn, 8, 0); HAL_NVIC_EnableIRQ(CAN_RX_IRQn); HAL_NVIC_SetPriority(CAN_TX_IRQn, 8, 0); HAL_NVIC_EnableIRQ(CAN_TX_IRQn); } static int HAL_CanFilterConfig(void) { CAN_FilterTypeDef sFilterConfig; int err_code; sFilterConfig.FilterBank = 0; // sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; //32λID sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; //32λMASK sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;// sFilterConfig.FilterActivation = ENABLE; // sFilterConfig.SlaveStartFilterBank = 14; err_code = HAL_CAN_ConfigFilter(&g_s_can1_handler, &sFilterConfig); if (err_code != HAL_OK) { return -1; } return 0; } int HAL_CanStart(void) { if (HAL_CAN_Start(&g_s_can1_handler) != HAL_OK) { return -1; } return 0; } static int HAL_CanTx(CAN_TxHeaderTypeDef *pHeader, uint8_t* can_data) { if (HAL_CAN_AddTxMessage(&g_s_can1_handler, pHeader, can_data, &g_s_tx_mailbox) != HAL_OK) //���� { return -1; } return 0; } int8_t HAL_CanTxData(uint8_t can_id_type, uint32_t can_id, uint8_t *data, uint8_t data_len) { uint8_t payload_len; if(NULL == data) { return -1; } g_s_can_tx_cnt = 0; DLOG_I("tx can_id_type:%d,can_id,0x%x,payload_len:%d,payload:%s", can_id_type, can_id, data_len, SYS_Hex2str(data,data_len)); if(0x00 == can_id_type) { g_s_can_tx_header.IDE = CAN_ID_STD; g_s_can_tx_header.StdId = can_id; g_s_can_tx_header.ExtId = 0; } else if (0x04 == can_id_type) { g_s_can_tx_header.IDE = CAN_ID_EXT; g_s_can_tx_header.StdId = 0; g_s_can_tx_header.ExtId = can_id; } else { return -2; } payload_len = data_len>8?8:data_len; g_s_can_tx_header.RTR = CAN_RTR_DATA; g_s_can_tx_header.DLC = payload_len; g_s_can_tx_header.TransmitGlobalTime = DISABLE; memset(g_s_can_tx_payload, 0, 8); memcpy(g_s_can_tx_payload, data, payload_len); if(0 != HAL_CanTx(&g_s_can_tx_header, g_s_can_tx_payload)) { DLOG_E("HAL_CanTx error"); return -3; } return 0; } void CAN1_RX0_IRQHandler(void) { HAL_CAN_IRQHandler(&g_s_can1_handler); } void CAN1_TX_IRQHandler(void) { HAL_CAN_IRQHandler(&g_s_can1_handler); } void HAL_CanCallbackRegister(can_rcv_cb_def rcv_cb, can_send_suc_cb_def send_cb, can_err_cb_def err_cb) { if((NULL == rcv_cb) || (NULL == send_cb) || (NULL == err_cb)) { return; } g_s_can_rcv_cb = rcv_cb; g_s_can_send_suc_cb = send_cb; g_s_can_err_cb = err_cb; } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef rx_msg_header = {0}; uint8_t rx_buf[8] = {0}; if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_msg_header, rx_buf) == HAL_OK) { if(g_s_can_rcv_cb != NULL) { if(CAN_ID_STD == rx_msg_header.IDE) { g_s_can_rcv_cb(rx_msg_header.IDE, rx_msg_header.StdId, rx_buf, rx_msg_header.DLC); } else if(CAN_ID_EXT == rx_msg_header.IDE) { g_s_can_rcv_cb(rx_msg_header.IDE, rx_msg_header.ExtId, rx_buf, rx_msg_header.DLC); } } } else { /* Reception Error */ DLOG_E("Get Rx Msg ERR"); } } void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { if(NULL != g_s_can_send_suc_cb) { g_s_can_send_suc_cb(); } } void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { if(NULL != g_s_can_send_suc_cb) { g_s_can_send_suc_cb(); } } void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { if(NULL != g_s_can_send_suc_cb) { g_s_can_send_suc_cb(); } } void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { char REC = hcan->Instance->ESR >> 24; char TEC = (hcan->Instance->ESR >> 16); char LEC = (hcan->Instance->ESR >> 4) & 0x07; char EWGF = hcan->Instance->ESR & 0x01; char EPVF = (hcan->Instance->ESR & 0x02) >> 1; char BOFF = (hcan->Instance->ESR & 0x04) >> 2; DLOG_E("can_error,code:0x%x, REC:%d, TEC:%d, LEC:0x%x, EWGF:%d, EPVF:%d, BOFF:%d", hcan->ErrorCode,REC,TEC,LEC,EWGF,EPVF,BOFF); g_s_can_tx_cnt += 1; if(g_s_can_tx_cnt < CAN_TX_RETRY_CNT) { HAL_CanTx(&g_s_can_tx_header, g_s_can_tx_payload); } if(NULL != g_s_can_err_cb) { g_s_can_err_cb(hcan->ErrorCode); } }