2024-05-04 04:08 AM
I have customized hardware based on STM32F407 controller.
I want to communicate on both CAN 1 and CAN 2. Both on 250 kbps baud rate but on different CAN bus due to some design requirement.
tx = Transmit, rx = Receive
I am able to tx and rx on CAN1 but on CAN2 I am only able to tx. Rx does not work on CAN2.
I have tried to connect CAN1 on separate CAN bus and CAN2 on separate CAN bus. I have also tried to connect both on same CAN bus. But I am still not able to get CAN2 rx working.
Below is my code for CAN1 and CAN2 configuration.
int main() {
...
CAN_Config();
CAN_Config_2();
...
}
static uint32_t HAL_RCC_CAN1_CLK_ENABLED = 0;
void HAL_CAN_MspInit(CAN_HandleTypeDef *canHandle) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
if (canHandle->Instance == CAN1) {
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if (HAL_RCC_CAN1_CLK_ENABLED == 1) {
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA12 ------> CAN1_TX
PA11 ------> CAN1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
} else if (canHandle->Instance == CAN2) {
/* USER CODE BEGIN CAN2_MspInit 0 */
/* USER CODE END CAN2_MspInit 0 */
/* CAN2 clock enable */
__HAL_RCC_CAN2_CLK_ENABLE();
HAL_RCC_CAN1_CLK_ENABLED++;
if (HAL_RCC_CAN1_CLK_ENABLED == 1) {
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */
/* USER CODE END CAN2_MspInit 1 */
}
}
static void CAN_Config(void) {
CAN_FilterTypeDef sFilterConfig;
CanHandle.Instance = CAN1;
CanHandle.Init.TimeTriggeredMode = DISABLE;
CanHandle.Init.AutoBusOff = DISABLE;
CanHandle.Init.AutoWakeUp = DISABLE;
CanHandle.Init.AutoRetransmission = DISABLE;
CanHandle.Init.ReceiveFifoLocked = DISABLE;
CanHandle.Init.TransmitFifoPriority = DISABLE;
CanHandle.Init.Mode = CAN_MODE_NORMAL;
CanHandle.Init.SyncJumpWidth = CAN_SJW_1TQ;
CanHandle.Init.TimeSeg1 = CAN_BS1_16TQ;
CanHandle.Init.TimeSeg2 = CAN_BS2_4TQ;
CanHandle.Init.Prescaler = 8;
if (HAL_CAN_Init(&CanHandle) != HAL_OK) {
/* Initialization Error */
CAN_Error_Handler();
}
sFilterConfig.FilterBank = 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 = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK) {
/* Filter configuration Error */
CAN_Error_Handler();
}
if (HAL_CAN_Start(&CanHandle) != HAL_OK) {
/* Start Error */
CAN_Error_Handler();
}
if (HAL_CAN_ActivateNotification(&CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING)
!= HAL_OK) {
/* Notification Error */
CAN_Error_Handler();
}
}
static void CAN_Config_2(void) {
CAN_FilterTypeDef sFilterConfig;
// PB12 CAN2_RX n/a Alternate Function Push Pull No pull-up and no pull-down Very High true
// PB13 CAN2_TX n/a Alternate Function Push Pull No pull-up and no pull-down Very High true
CanHandle2.Instance = CAN2;
CanHandle2.Init.TimeTriggeredMode = DISABLE;
CanHandle2.Init.AutoBusOff = DISABLE;
CanHandle2.Init.AutoWakeUp = DISABLE;
CanHandle2.Init.AutoRetransmission = DISABLE;
CanHandle2.Init.ReceiveFifoLocked = DISABLE;
CanHandle2.Init.TransmitFifoPriority = DISABLE;
CanHandle2.Init.Mode = CAN_MODE_NORMAL;
CanHandle2.Init.SyncJumpWidth = CAN_SJW_1TQ;
CanHandle2.Init.TimeSeg1 = CAN_BS1_16TQ;
CanHandle2.Init.TimeSeg2 = CAN_BS2_4TQ;
CanHandle2.Init.Prescaler = 8;
if (HAL_CAN_Init(&CanHandle2) != HAL_OK) {
/* Initialization Error */
CAN_Error_Handler();
}
sFilterConfig.FilterBank = 14;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&CanHandle2, &sFilterConfig) != HAL_OK) {
/* Filter configuration Error */
CAN_Error_Handler();
}
if (HAL_CAN_Start(&CanHandle2) != HAL_OK) {
/* Start Error */
CAN_Error_Handler();
}
if (HAL_CAN_ActivateNotification(&CanHandle2, CAN_IT_RX_FIFO1_MSG_PENDING)
!= HAL_OK) {
/* Notification Error */
CAN_Error_Handler();
}
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
int ret = 0;
/* Get RX message */
if ((ret = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader2, RxData2))
!= HAL_OK) {
/* Reception Error */
CAN_Error_Handler();
printf("CAN 1 HAL_CAN_GetRxMessage err:%d", ret);
return;
} else{
printf("CAN 1 received %d %d", RxData2[0], RxData2[7]);
}
}
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {
int ret = 0;
/* Get RX message */
if ((ret = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &RxHeader2, RxData2))
!= HAL_OK) {
/* Reception Error */
CAN_Error_Handler();
printf("CAN 2 HAL_CAN_GetRxMessage err:%d", ret);
return;
} else{
printf("CAN 2 received %d %d", RxData2[0], RxData2[7]);
}
}
I have skipped some variable declaration, GIPI , System clock and HAL init functions.
2024-05-04 07:36 AM
Hello,
Could you please share your project (remove unnecessary code and keep only the communication between CAN1 and CAN2?
Also what is your system clock source ? HSI/HSE?
2024-08-01 11:14 PM
Hello SamptelTech,
your CAN configuration code part seems ok. but still you are not able to receive data from CAN 2 so you need to check /* NVIC configuration for CAN2 Reception complete interrupt */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
in func
HAL_CAN_MspInit(CAN_HandleTypeDef *canHandle)
check the both NVIC func argument config by you. also try to config as below and test
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);