cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 Dual CAN - CAN1 both tx rx works, on CAN2 only tx works, receive does not

SamptelTech
Associate

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.

2 REPLIES 2
SofLit
ST Employee

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?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Denish23
Associate

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);