Skip to main content
mh_stm
Associate II
February 27, 2019
Question

stm32l476 CAN functions only in loopback mode

  • February 27, 2019
  • 0 replies
  • 556 views

Hi all,

I have two stm32l476RG nucleo boards connected via transceivers. Each of them works fine in loopback mode. however none receives messages of the other in CAN_MODE_NORMAL.

I'm using a simplistic code ported from STM32L476G-EVAL HAL examples. Both boards have same configuration: clock 16MHz for all buses, same pins,... all CAN IDs are accepted. Both MCUs have CAN1_RX0_IRQn enabled but never triggered.

Here is the configuration:

/*
 * @name com_gpio_config.
 * @brief sets up CAN GPIO pins.
 * @param none.
 * @retval none.
 */
static void
com_gpio_config (void)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 
 /* Enable GPIO clock */
 __HAL_RCC_GPIOA_CLK_ENABLE ();
 
 /* Configure peripheral GPIO */
 GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 return;
}
 
/*
 * @name com_can_config.
 * @brief configures CAN peripheral.
 * @param none
 * @retval none
 */
static void
com_can_config (void)
{
 CAN_FilterTypeDef sFilterConfig;
 
 /* peripheral clock enable */
 __HAL_RCC_CAN1_CLK_ENABLE();
 
 /* configure the CAN peripheral */
 can_handle.Instance = CAN1;
 can_handle.Init.TimeTriggeredMode = DISABLE;
 can_handle.Init.AutoBusOff = DISABLE;
 can_handle.Init.AutoWakeUp = DISABLE;
 can_handle.Init.AutoRetransmission = ENABLE;
 can_handle.Init.ReceiveFifoLocked = DISABLE;
 can_handle.Init.TransmitFifoPriority = DISABLE;
 can_handle.Init.Mode = CAN_MODE_NORMAL;//CAN_MODE_LOOPBACK;//
 can_handle.Init.SyncJumpWidth = CAN_SJW_1TQ;
 can_handle.Init.TimeSeg1 = CAN_BS1_16TQ;
 can_handle.Init.TimeSeg2 = CAN_BS2_2TQ;
 can_handle.Init.Prescaler = 32;
 if (HAL_CAN_Init(&can_handle) != HAL_OK)
 {
 /* halt process */
 while (1);
 }
 
 /* configure the CAN Filter */
 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 = 0; // unique CAN instance
 if (HAL_CAN_ConfigFilter(&can_handle, &sFilterConfig) != HAL_OK)
 {
 /* halt process */
 while (1);
 }
 
 /* start the CAN peripheral */
 if (HAL_CAN_Start(&can_handle) != HAL_OK)
 {
 /* halt process */
 while (1);
 }
 
 /* activate CAN Rx IRQ */
 if (HAL_CAN_ActivateNotification(&can_handle, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO0_FULL) != HAL_OK)
 {
 /* halt process */
 while (1);
 }
 
 /* configure transmission process */
 tx_header.StdId = 0x321;
 tx_header.ExtId = 0x01;
 tx_header.RTR = CAN_RTR_DATA;
 tx_header.IDE = CAN_ID_STD;
 tx_header.DLC = 2;
 tx_header.TransmitGlobalTime = DISABLE;
 
 HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 2, 0);
 HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
 
 return;
}

and here is the sending loop:

 if (HAL_CAN_AddTxMessage(&can_handle, &tx_header, (uint8_t*)&msg, &tx_mailbox) != HAL_OK)
 {
 /* Transmission request Error */
 cli_error ("CAN Tx failed");
 retval =(-1);
 }
 else
 {
 cli_notice ("command sent!");
 }
 simple _delay (some_time);

This topic has been closed for replies.