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.

1 REPLY 1
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.