void BSP::InitCAN() { //set prescaler for 2MHz/500ns Frequency of Time qunata //STM32F0: 48MHz --> 24, STM32F1: 36MHz --> 18, STM32F4: 42MHz -->21 //Use 16 time quanta for one bit -->125kbit/sec hcan.Instance = CAN; hcan.Init.Prescaler = CAN_PRESCALER; //bei 36MHz -->2MHz Abtastrate hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SJW = CAN_SJW_2TQ; hcan.Init.BS1 = CAN_BS1_13TQ; hcan.Init.BS2 = CAN_BS2_2TQ; hcan.Init.TTCM = DISABLE; hcan.Init.ABOM = DISABLE; hcan.Init.AWUM = DISABLE; hcan.Init.NART = DISABLE; hcan.Init.RFLM = DISABLE; hcan.Init.TXFP = DISABLE; hcan.pRxMsg = &RxMessage; hcan.pTxMsg = &TxMessage; hcan.pTxMsg->IDE = CAN_ID_EXT; hcan.pTxMsg->RTR = CAN_RTR_DATA; hcan.pTxMsg->StdId = 0; HAL_StatusTypeDef status=HAL_CAN_Init(&hcan); if (status != HAL_OK) { LOGE(NOT_SUCCESSFUL_STRING, "CAN"); return; } LOGI(SUCCESSFUL_STRING, "CAN"); CAN_FilterConfTypeDef sFilterConfig; /*##-2- Configure the CAN Filter ###########################################*/ sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); sFilterConfig.FilterNumber = 14; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; status = HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); if (status != HAL_OK) { LOG->Error(NOT_SUCCESSFUL_STRING, "CAN filter"); return; } LOGI(SUCCESSFUL_STRING, "CAN filter"); }
/** * @brief This function initialize and configure CAN * @param hcan select can handle * @arg hcan_bsp1 * @arg hcan_bsp2 * @param can_mode Select the CAN mode * @arg CAN_MODE_LOOPBACK * @arg CAN_MODE_SILENT * @arg CAN_MODE_SILENT_LOOPBACK * @arg CAN_MODE_NORMAL * @param fifo_assignment select the fifo0 or fifo1 */ void BSP_CAN_Init(CAN_HandleTypeDef* hcan, uint32_t can_mode, Fifo_Assignment_Typedef fifo_assignment) { CAN_FilterConfTypeDef sFilterConfig; if(hcan == &hcan_bsp1) { hcan_bsp1.Instance = CAN1; hcan_bsp1.pTxMsg = &TxMsg1; hcan_bsp1.pRxMsg = &RxMsg1; sFilterConfig.FilterNumber = 0; } else if (hcan == &hcan_bsp2) { hcan_bsp2.Instance = CAN2; hcan_bsp2.pTxMsg = &TxMsg2; hcan_bsp2.pRxMsg = &RxMsg2; sFilterConfig.FilterNumber = 14; } hcan->Init.Prescaler = 16; hcan->Init.Mode = can_mode; hcan->Init.SJW = CAN_SJW_1TQ; hcan->Init.BS1 = CAN_BS1_6TQ; hcan->Init.BS2 = CAN_BS2_8TQ; hcan->Init.TTCM = DISABLE; hcan->Init.ABOM = DISABLE; hcan->Init.AWUM = DISABLE; hcan->Init.NART = DISABLE; hcan->Init.RFLM = DISABLE; hcan->Init.TXFP = DISABLE; BSP_CAN_MspInit(hcan); HAL_CAN_Init(hcan); if(hcan == &hcan_bsp1) { sFilterConfig.FilterNumber = 0; // 0-13 } else if (hcan == &hcan_bsp2) { sFilterConfig.FilterNumber = 14; // 14-27 } sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = fifo_assignment; sFilterConfig.FilterActivation = ENABLE; HAL_CAN_ConfigFilter(hcan, &sFilterConfig); }
void can_enable(void) { uint32_t status; if (bus_state == OFF_BUS) { hcan.Init.Mode = CAN_MODE_NORMAL; hcan.pTxMsg = NULL; status = HAL_CAN_Init(&hcan); status = HAL_CAN_ConfigFilter(&hcan, &filter); bus_state = ON_BUS; } }
/** * @brief Configures the CAN. * @param None * @retval None */ static void CAN_Config(void) { CAN_FilterConfTypeDef sFilterConfig; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage; /*##-1- Configure the CAN peripheral #######################################*/ CanHandle.Instance = CANx; CanHandle.pTxMsg = &TxMessage; CanHandle.pRxMsg = &RxMessage; CanHandle.Init.TTCM = DISABLE; CanHandle.Init.ABOM = DISABLE; CanHandle.Init.AWUM = DISABLE; CanHandle.Init.NART = DISABLE; CanHandle.Init.RFLM = DISABLE; CanHandle.Init.TXFP = DISABLE; CanHandle.Init.Mode = CAN_MODE_NORMAL; CanHandle.Init.SJW = CAN_SJW_1TQ; CanHandle.Init.BS1 = CAN_BS1_6TQ; CanHandle.Init.BS2 = CAN_BS2_8TQ; CanHandle.Init.Prescaler = 2; if (HAL_CAN_Init(&CanHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-2- Configure the CAN Filter ###########################################*/ sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; if (HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ Error_Handler(); } /*##-3- Configure Transmission process #####################################*/ CanHandle.pTxMsg->StdId = 0x321; CanHandle.pTxMsg->ExtId = 0x01; CanHandle.pTxMsg->RTR = CAN_RTR_DATA; CanHandle.pTxMsg->IDE = CAN_ID_STD; CanHandle.pTxMsg->DLC = 2; }
void setup_can_filter() { filter.FilterIdHigh = 0; filter.FilterIdLow = 0; filter.FilterMaskIdHigh = 0; filter.FilterMaskIdLow = 0; filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterScale = CAN_FILTERSCALE_32BIT; filter.FilterNumber = 0; filter.FilterFIFOAssignment = CAN_FIFO0; filter.BankNumber = 0; filter.FilterActivation = ENABLE; HAL_CAN_ConfigFilter(&hcan, &filter); }
/** * @brief Enables the CAN2 interface with the current settings * @param None * @retval None */ static ErrorStatus prvEnableCan2Interface() { /*##-1- Enable peripheral Clocks ###########################################*/ /* CAN2 Peripheral clock enable */ __CAN1_CLK_ENABLE(); /* IMPORTANT!!! As CAN2 is a slave device we need to enable the clock for CAN1 as well */ __CAN2_CLK_ENABLE(); /*##-2- Configure the NVIC #################################################*/ /* NVIC configuration for CAN2 Reception complete interrupt */ HAL_NVIC_SetPriority(CAN2_RX0_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY, 0); HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn); HAL_NVIC_SetPriority(CAN2_TX_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY, 0); HAL_NVIC_EnableIRQ(CAN2_TX_IRQn); /*##-3- Configure the CAN peripheral #######################################*/ if (HAL_CAN_Init(&CAN_Handle) != HAL_OK) { /* Initialization Error */ goto error; } /*##-4- Configure the CAN Filter ###########################################*/ if (HAL_CAN_ConfigFilter(&CAN_Handle, &CAN_Filter) != HAL_OK) { /* Filter configuration Error */ goto error; } /*##-5- Configure Transmission process #####################################*/ CAN_Handle.pTxMsg->StdId = 0x321; CAN_Handle.pTxMsg->ExtId = 0x01; CAN_Handle.pTxMsg->RTR = CAN_RTR_DATA; CAN_Handle.pTxMsg->IDE = CAN_ID_STD; CAN_Handle.pTxMsg->DLC = 2; /*##-6- Start the Reception process and enable reception interrupt #########*/ if (HAL_CAN_Receive_IT(&CAN_Handle, CAN_FIFO1) != HAL_OK) { /* Reception Error */ goto error; } return SUCCESS; error: /* Something went wrong so disable */ prvDisableCan2Interface(); return ERROR; }
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) { GPIO_InitTypeDef GPIO_InitStruct; if(hcan->Instance==CAN1) { /* USER CODE BEGIN CAN1_MspInit 0 */ /* USER CODE END CAN1_MspInit 0 */ /* Peripheral clock enable */ __CAN1_CLK_ENABLE(); /**CAN1 GPIO Configuration PB8 ------> CAN1_RX PB9 ------> CAN1_TX */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF9_CAN1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Peripheral interrupt init*/ HAL_NVIC_SetPriority(CAN1_TX_IRQn, 5, 0); HAL_NVIC_EnableIRQ(CAN1_TX_IRQn); HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 5, 0); HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn); /* USER CODE BEGIN CAN1_MspInit 1 */ CAN_FilterConfTypeDef CAN_FilterInitStructure; /* CAN filter init */ CAN_FilterInitStructure.FilterNumber = 0; CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK; CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT; CAN_FilterInitStructure.FilterIdHigh = 0x0000; CAN_FilterInitStructure.FilterIdLow = 0x0000; CAN_FilterInitStructure.FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.FilterFIFOAssignment = 0; CAN_FilterInitStructure.FilterActivation = ENABLE; HAL_CAN_ConfigFilter(hcan, &CAN_FilterInitStructure); /* USER CODE END CAN1_MspInit 1 */ } }
STATIC void can_clearfilter(uint32_t f) { CAN_FilterConfTypeDef filter; filter.FilterIdHigh = 0; filter.FilterIdLow = 0; filter.FilterMaskIdHigh = 0; filter.FilterMaskIdLow = 0; filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.FilterNumber = f; filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterScale = CAN_FILTERSCALE_16BIT; filter.FilterActivation = DISABLE; filter.BankNumber = can2_start_bank; HAL_CAN_ConfigFilter(NULL, &filter); }
/** * @brief Enables the CAN1 interface with the current settings * @param None * @retval None */ static ErrorStatus prvEnableCan1Interface() { /*##-1- Enable peripheral Clocks ###########################################*/ /* CAN1 Peripheral clock enable */ __CAN1_CLK_ENABLE(); /*##-2- Configure the NVIC #################################################*/ HAL_NVIC_SetPriority(CAN1_RX0_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY, 0); HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); HAL_NVIC_SetPriority(CAN1_TX_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY, 0); HAL_NVIC_EnableIRQ(CAN1_TX_IRQn); /*##-3- Configure the CAN peripheral #######################################*/ if (HAL_CAN_Init(&CAN_Handle) != HAL_OK) { /* Initialization Error */ goto error; } /*##-4- Configure the CAN Filter ###########################################*/ if (HAL_CAN_ConfigFilter(&CAN_Handle, &CAN_Filter) != HAL_OK) { /* Filter configuration Error */ goto error; } /*##-6- Start the Reception process and enable reception interrupt #########*/ if (HAL_CAN_Receive_IT(&CAN_Handle, CAN_FIFO0) != HAL_OK) { /* Reception Error */ goto error; } return SUCCESS; error: /* Something went wrong so disable */ prvDisableCan1Interface(); return ERROR; }
// Start the CAN peripheral void can_enable(void) { if (bus_state == OFF_BUS) { can_handle.Init.Prescaler = prescaler; can_handle.Init.Mode = CAN_MODE_NORMAL; can_handle.Init.SJW = CAN_SJW_1TQ; can_handle.Init.BS1 = CAN_BS1_4TQ; can_handle.Init.BS2 = CAN_BS2_3TQ; can_handle.Init.TTCM = DISABLE; can_handle.Init.ABOM = ENABLE; can_handle.Init.AWUM = DISABLE; can_handle.Init.NART = can_nart; can_handle.Init.RFLM = DISABLE; can_handle.Init.TXFP = DISABLE; can_handle.pTxMsg = NULL; HAL_CAN_Init(&can_handle); HAL_CAN_ConfigFilter(&can_handle, &filter); bus_state = ON_BUS; led_blue_on(); } }
int __start(void) { const volatile uint32_t *src; volatile uint32_t *dest; /* Set up BSS and copy data from flash */ for (src = &_eronly, dest = &_sdata; dest < &_edata;) { *dest++ = *src++; } for (dest = &_sbss; dest < &_ebss;) { *dest++ = 0; } SystemInit(); HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Make sure the flash option bytes are set such that we don't re-enter bootloader mode */ set_dfu_option_bytes(0u); MX_USB_DEVICE_Init(); /* Configure GPIO for the CAN_SILENT signal */ GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __CRS_CLK_ENABLE(); /*Configure GPIO pin : PB7 */ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /**CAN GPIO Configuration PB8 ------> CAN_RX PB9 ------> CAN_TX */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_CAN; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure the bxCAN transceiver */ CAN_HandleTypeDef hcan; __CAN_CLK_ENABLE(); hcan.Instance = CAN; hcan.Init.Mode = CAN_MODE_SILENT; hcan.Init.TTCM = DISABLE; hcan.Init.ABOM = ENABLE; hcan.Init.AWUM = ENABLE; hcan.Init.NART = DISABLE; hcan.Init.RFLM = DISABLE; hcan.Init.TXFP = DISABLE; /* Set the bitrate and init */ set_can_bitrate(&hcan, 1000000u); CanRxMsgTypeDef rx_msg; hcan.pRxMsg = &rx_msg; CanTxMsgTypeDef tx_msg; hcan.pTxMsg = &tx_msg; CAN_FilterConfTypeDef filter; filter.FilterNumber = 0; filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterScale = CAN_FILTERSCALE_32BIT; filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.FilterActivation = ENABLE; filter.BankNumber = 0; filter.FilterMaskIdLow = filter.FilterIdLow = filter.FilterMaskIdHigh = filter.FilterIdHigh = 0; HAL_CAN_ConfigFilter(&hcan, &filter); __HAL_UNLOCK(&hcan); /* Now that USB is active, we need to sync with the 1 kHz SOF packets to tune the HSI48 so it's accurate enough not to disrupt the CAN bus. */ RCC_CRSInitTypeDef crs_config; crs_config.Prescaler = RCC_CRS_SYNC_DIV1; crs_config.Source = RCC_CRS_SYNC_SOURCE_USB; crs_config.Polarity = RCC_CRS_SYNC_POLARITY_RISING; crs_config.ReloadValue = RCC_CRS_RELOADVALUE_DEFAULT; crs_config.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; crs_config.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; HAL_RCCEx_CRSConfig(&crs_config); /* Don't continue unless we're synced */ while (!(HAL_RCCEx_CRSWaitSynchronization(1000000u) & RCC_CRS_SYNCOK)); while (1) { /* Set up the command record */ size_t i; uint8_t current_cmd; uint8_t current_cmd_data[32]; uint8_t current_cmd_data_length; uint8_t channel_open; current_cmd = current_cmd_data_length = i = 0; channel_open = 0; rx_buffer_length = 0; while (hUsbDevice_0 && hUsbDevice_0->pClassData) { /* If the RX buffer is non-empty, process any commands/messages in it and then acknowledge the transfer to the USB stack */ if (rx_buffer_length) { /* Exit if we've read the entire buffer, or if transmit mailboxes are full and the current command is a transmit. */ for (; i < rx_buffer_length && ((current_cmd != 't' && current_cmd != 'T') || __HAL_CAN_GET_FLAG(&hcan, CAN_FLAG_TME0)); i++) { if (rx_buffer[i] == '\r') { uint8_t *buf = active_buffer ? tx_buffer_1 : tx_buffer_0; /* End of command -- process and reset state */ switch (current_cmd) { case 'S': /* Setup bitrate -- data should be a number from 0 to 8. */ if (current_cmd_data[0] < '0' || current_cmd_data[0] > '8') { buf[active_buffer_length++] = '\a'; } else if (set_can_bitrate( &hcan, bitrate_lookup[current_cmd_data[0] - '0'])) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'O': /* Open channel -- take CAN out of silent mode and start receiving. */ if (!channel_open) { channel_open = 1; set_can_silent(&hcan, 0); buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'L': /* Open in listen-only -- CAN should already be in silent mode but just make sure. */ if (!channel_open) { channel_open = 1; set_can_silent(&hcan, 1); buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'C': /* Close channel -- put CAN back in silent mode. */ if (channel_open) { channel_open = 0; set_can_silent(&hcan, 1); buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'V': /* Hardware version */ buf[active_buffer_length++] = 'V'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '1'; buf[active_buffer_length++] = '\r'; break; case 'v': /* Major/minor version */ buf[active_buffer_length++] = 'v'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '1'; buf[active_buffer_length++] = '\r'; break; case 'N': /* Serial number */ buf[active_buffer_length++] = 'N'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = '\r'; break; case 'T': /* Extended message */ if (read_ext_message(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 't': /* Standard message */ if (read_std_message(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'R': /* Extended RTR */ if (read_ext_rtr(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'r': /* Standard RTR */ if (read_std_rtr(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case '_': /* Bootloader request */ if (current_cmd_data[0] == '_' && current_cmd_data[1] == 'd' && current_cmd_data[2] == 'f' && current_cmd_data[3] == 'u') { /* Set option bytes to force bootloader entry */ set_dfu_option_bytes(1u); NVIC_SystemReset(); } else { buf[active_buffer_length++] = '\a'; } break; case 'F': /* Read status flags -- return 4 hex digits */ case 'Z': /* Timestamp on/off -- 0=off, 1=on */ case 'M': /* Acceptance mask -- 8 hex digits */ case 'm': /* Acceptance value -- 8 hex digits */ case 's': /* Set bitrate register -- 6 hex digits */ default: /* NACK */ buf[active_buffer_length++] = '\a'; break; } current_cmd = current_cmd_data_length = 0; } else if (current_cmd) { /* Command data -- save it */ current_cmd_data[current_cmd_data_length++] = rx_buffer[i]; /* Reset command state if the data is too long */ if (current_cmd_data_length == 32u) { current_cmd = current_cmd_data_length = 0; } } else { /* The first letter of a line is the command type -- don't bother validating as we can't NACK until the data has been received. */ current_cmd = rx_buffer[i]; } } if (i == rx_buffer_length) { /* Mark last packet as received */ rx_buffer_length = i = 0; USBD_CDC_ReceivePacket(hUsbDevice_0); } } /* Check the CAN controller for messages and process them if the channel is open */ if (HAL_CAN_Receive(&hcan, CAN_FIFO0, 0) == HAL_OK && hUsbDevice_0 && channel_open) { /* Format the message and send it to the host. The data format for a standard ID message is: tiiildddddddddddddddd\r The data format for a standard ID RTR is: riii\r The data format for an extended ID message is: Tiiiiiiiildddddddddddddddd\r The data format for an extended ID RTR is: Riiiiiiii\r */ uint8_t *write_location; if (active_buffer_length + EXT_MESSAGE_LEN > TX_BUFFER_SIZE) { /* Reset buffer if we're too far behind -- use worst-case message length for calculation */ active_buffer_length = 0; } write_location = &((active_buffer ? tx_buffer_1 : tx_buffer_0)[active_buffer_length]); if (rx_msg.IDE == CAN_ID_EXT && rx_msg.RTR) { active_buffer_length += write_ext_rtr( write_location, &rx_msg); } else if (rx_msg.IDE == CAN_ID_EXT && !rx_msg.RTR) { active_buffer_length += write_ext_message( write_location, &rx_msg); } else if (rx_msg.IDE == CAN_ID_STD && rx_msg.RTR) { active_buffer_length += write_std_rtr( write_location, &rx_msg); } else if (rx_msg.IDE == CAN_ID_STD && !rx_msg.RTR) { active_buffer_length += write_std_message( write_location, &rx_msg); } } if (!hUsbDevice_0 || !hUsbDevice_0->pClassData) { /* Reset TX buffer if USB is not connected */ active_buffer_length = 0; } else if (active_buffer_length && ((USBD_CDC_HandleTypeDef*)hUsbDevice_0->pClassData)->TxState == 0) { /* Transmit the next buffer if one is available */ CDC_Transmit_FS(active_buffer ? tx_buffer_1 : tx_buffer_0, active_buffer_length); active_buffer_length = 0; active_buffer = active_buffer ? 0 : 1; } } } }
/** * @brief Configures the CAN, transmit and receive by polling * @param None * @retval PASSED if the reception is well done, FAILED in other case */ HAL_StatusTypeDef CAN_Polling(void) { CAN_FilterConfTypeDef sFilterConfig; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage; /*##-1- Configure the CAN peripheral #######################################*/ CanHandle.Instance = CANx; CanHandle.pTxMsg = &TxMessage; CanHandle.pRxMsg = &RxMessage; CanHandle.Init.TTCM = DISABLE; CanHandle.Init.ABOM = DISABLE; CanHandle.Init.AWUM = DISABLE; CanHandle.Init.NART = DISABLE; CanHandle.Init.RFLM = DISABLE; CanHandle.Init.TXFP = DISABLE; CanHandle.Init.Mode = CAN_MODE_LOOPBACK; CanHandle.Init.SJW = CAN_SJW_1TQ; CanHandle.Init.BS1 = CAN_BS1_6TQ; CanHandle.Init.BS2 = CAN_BS2_8TQ; CanHandle.Init.Prescaler = 2; if(HAL_CAN_Init(&CanHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-2- Configure the CAN Filter ###########################################*/ sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; if(HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ Error_Handler(); } /*##-3- Start the Transmission process #####################################*/ CanHandle.pTxMsg->StdId = 0x11; CanHandle.pTxMsg->RTR = CAN_RTR_DATA; CanHandle.pTxMsg->IDE = CAN_ID_STD; CanHandle.pTxMsg->DLC = 2; CanHandle.pTxMsg->Data[0] = 0xCA; CanHandle.pTxMsg->Data[1] = 0xFE; if(HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK) { /* Transmition Error */ Error_Handler(); } if(HAL_CAN_GetState(&CanHandle) != HAL_CAN_STATE_READY) { return HAL_ERROR; } /*##-4- Start the Reception process ########################################*/ if(HAL_CAN_Receive(&CanHandle, CAN_FIFO0,10) != HAL_OK) { /* Reception Error */ Error_Handler(); } if(HAL_CAN_GetState(&CanHandle) != HAL_CAN_STATE_READY) { return HAL_ERROR; } if(CanHandle.pRxMsg->StdId != 0x11) { return HAL_ERROR; } if(CanHandle.pRxMsg->IDE != CAN_ID_STD) { return HAL_ERROR; } if(CanHandle.pRxMsg->DLC != 2) { return HAL_ERROR; } if((CanHandle.pRxMsg->Data[0]<<8|RxMessage.Data[1]) != 0xCAFE) { return HAL_ERROR; } return HAL_OK; /* Test Passed */ }
_Bool CAN_init(void *data) { CAN_HandleTypeDef *handle = data; HAL_StatusTypeDef result = HAL_ERROR; const uint32_t baudRate = 125000; CAN_InitTypeDef ifaceParams = { HAL_RCC_GetPCLK1Freq()/(baudRate*(1+4+3)), //(CAN_SJW + CAN_BS1 + CAN_BS2) CAN_MODE_NORMAL, CAN_SJW_1TQ, CAN_BS1_4TQ, CAN_BS2_3TQ, .TTCM = DISABLE, .ABOM = DISABLE, .AWUM = DISABLE, .NART = DISABLE, .RFLM = DISABLE, .TXFP = DISABLE, }; CAN_FilterConfTypeDef filter = { 0, 0, 0, 0, CAN_FIFO0, 0, CAN_FILTERMODE_IDMASK, CAN_FILTERSCALE_32BIT, ENABLE, 0 }; if (handle) { free(handle->pRxMsg); free(handle->pTxMsg); handle->pRxMsg = NULL; handle->pTxMsg = NULL; memset(handle, 0, sizeof(*handle)); handle->Instance = CAN1; handle->Init = ifaceParams; result = HAL_CAN_Init(handle); if (result == HAL_OK) { HAL_CAN_ConfigFilter(handle, &filter); HAL_NVIC_EnableIRQ(CAN1_TX_IRQn); HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn); // HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn); handle->pRxMsg = malloc(sizeof(*handle->pRxMsg)); result &= HAL_CAN_Receive_IT(handle, CAN_FIFO0); } s_can1Handle = handle; } return result == HAL_OK; } _Bool CAN_write(const CanMsg_t *data) { HAL_StatusTypeDef result = HAL_ERROR; static const size_t msgSize = sizeof(CanTxMsgTypeDef); if (!data) return false; CanTxMsgTypeDef txMsg = { data->id, data->id, data->isExtended ? CAN_ID_EXT : CAN_ID_STD, data->isRemoteFrame ? CAN_RTR_REMOTE : CAN_RTR_DATA, data->isRemoteFrame ? 0 : data->size > 8 ? 8 : data->size, }; do { if (!s_can1Handle) break; memcpy(txMsg.Data, data->buff, txMsg.DLC); free(s_can1Handle->pTxMsg); s_can1Handle->pTxMsg = malloc(msgSize); if (!s_can1Handle->pTxMsg) break; memcpy(s_can1Handle->pTxMsg, &txMsg, msgSize); result = HAL_CAN_Transmit_IT(s_can1Handle); } while (0); return result == HAL_OK; }
CAN_ERROR CAN_hw_rx_object (U32 ctrl, U32 ch, U32 id, U32 object_para, U32 mask) { static uint32_t sb = __FILTER_BANK_MAX; U8 filterIdx = 0; CAN_FilterConfTypeDef filter; filter.FilterActivation = ENABLE; filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterScale = CAN_FILTERSCALE_32BIT; filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.BankNumber = sb; //(CAN2_filterIdx == 0) ? __FILTER_BANK_MAX : __FILTER_BANK_MAX - CAN2_filterIdx - 1; /* find free filter */ switch (ctrl) { #if RTE_CAN1 == 1 case __CTRL1: /* for CTRL1 we check from 0 .. __FILTER_BANK_MAX - CAN2_filterIdx */ for (filter.FilterNumber = 0; filter.FilterNumber < __FILTER_BANK_MAX; filter.FilterNumber++) { filterIdx = CAN_hw_rx_object_chk (filter.FilterNumber, object_para); if (filterIdx != 0xff) { if (filter.FilterNumber==filter.BankNumber) sb = ++filter.BankNumber; if ((object_para & FORMAT_TYPE) == STANDARD_TYPE) { filter.FilterIdHigh = id<<5; filter.FilterIdLow = object_para & FRAME_TYPE; filter.FilterMaskIdHigh = mask<<5; filter.FilterMaskIdLow = object_para & FRAME_TYPE; } else { filter.FilterIdHigh = id>>13; filter.FilterIdLow = ((id & 0x1FFF)<<3) | (1<<2) | (object_para & FRAME_TYPE); filter.FilterMaskIdHigh = mask>>13; filter.FilterMaskIdLow = ((mask & 0x1FFF)<<3) | (1<<2) | (object_para & FRAME_TYPE); } HAL_CAN_ConfigFilter(&hCAN1, &filter); return CAN_OK; } else { if (filter.FilterNumber>=filter.BankNumber) return CAN_OBJECTS_FULL_ERROR; } } break; #endif #if RTE_CAN2 == 1 case __CTRL2: /* for CTRL2 we check from __FILTER_BANK_MAX .. [1 | CAN1_filterIdx] */ for (filter.FilterNumber = __FILTER_BANK_MAX; filter.FilterNumber >0; filter.FilterNumber--) { filterIdx = CAN_hw_rx_object_chk (filter.FilterNumber, object_para); if (filterIdx != 0xff) { if (filter.FilterNumber<filter.BankNumber) sb = --filter.BankNumber; if ((object_para & FORMAT_TYPE) == STANDARD_TYPE) { filter.FilterIdHigh = id<<5; filter.FilterIdLow = object_para & FRAME_TYPE; filter.FilterMaskIdHigh = mask<<5; filter.FilterMaskIdLow = object_para & FRAME_TYPE; } else { filter.FilterIdHigh = id>>13; filter.FilterIdLow = ((id & 0x1FFF)<<3) | (1<<2) | (object_para & FRAME_TYPE); filter.FilterMaskIdHigh = mask>>13; filter.FilterMaskIdLow = ((mask & 0x1FFF)<<3) | (1<<2) | (object_para & FRAME_TYPE); } HAL_CAN_ConfigFilter(&hCAN2, &filter); return CAN_OK; } else { if (filter.FilterNumber<filter.BankNumber) return CAN_OBJECTS_FULL_ERROR; } }