AnsweredAssumed Answered

STM32F413 dual CAN receive on slave CAN issue

Question asked by Ed Maynard on Jul 11, 2017
Latest reply on Jul 12, 2017 by Valentin

I am using the STM32F413 and am trying to use CAN1 and CAN2 in a ring topology (CAN1 sends and if CAN2 doesn't get the message then I know I have a network connectivity failure). I use the latest CubeMX to generate the configuration code and CAN1 appears to send messages just fine and CAN2 asserts the ACK bit just fine. CAN1 in loopback mode receives its own message but CAN2 using the same filter configuration as CAN1 in loopback mode always returns HAL_TIMEOUT. When I look at the hardware registers for CAN2, the flags for the receive FIFOs show that no message has been recorded. Here's the filter configuration for CAN2:

 

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(&hcan2, &sFilterConfig);

 

Here are the initialization code for the two CAN:

/* CAN1 init function */
void MX_CAN1_Init(void)
{

hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 5;
hcan1.Init.Mode = CAN_MODE_LOOPBACK;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_6TQ;
hcan1.Init.BS2 = CAN_BS2_3TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

}
/* CAN2 init function */
void MX_CAN2_Init(void)
{

hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 5;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SJW = CAN_SJW_1TQ;
hcan2.Init.BS1 = CAN_BS1_6TQ;
hcan2.Init.BS2 = CAN_BS2_3TQ;
hcan2.Init.TTCM = DISABLE;
hcan2.Init.ABOM = DISABLE;
hcan2.Init.AWUM = DISABLE;
hcan2.Init.NART = DISABLE;
hcan2.Init.RFLM = DISABLE;
hcan2.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

GPIO_InitTypeDef GPIO_InitStruct;
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */

/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();

/**CAN1 GPIO Configuration
PG0 ------> CAN1_RX
PG1 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

/* USER CODE BEGIN CAN1_MspInit 1 */
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET); // Set CAN1 transceiver to high speed
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET); // This puts CAN2 transceiver in 'silent' mode

/* USER CODE END CAN1_MspInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */

/* USER CODE END CAN2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN2_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_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* USER CODE BEGIN CAN2_MspInit 1 */
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);

/* USER CODE END CAN2_MspInit 1 */
}
}

sorry for the paragraph spacing - can't seem to change it.

I am basically cribbing the F4xG EVAL CAN Networking example.

 

I figure that this has something to do with the shared hardware resourcing of CAN1/CAN2 but I cannot find a relevant example in the ST examples. Any pointers would be greatly appreciated. I realize that this is probably a simple oversight /misunderstanding on my part but I have tried a number of things and the messages just aren't getting in. Even though the SRAM is shared, there is nothing to indicate that the bxCAN cannot send on CAN1 and simultaneously receive on CAN2.

 

** Update **

Running Loopback mode on CAN2 has the CAN frame coming out just fine, the ACK asserted by CAN1, but NO message received on CAN2. This worked flawless on CAN1. Now I firmly suspect that I have configured something wrong for CAN2 to be able to receive.

Outcomes