cancel
Showing results for 
Search instead for 
Did you mean: 

stm32l476 CAN functions only in loopback mode

mh_stm
Associate II

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

0 REPLIES 0