cancel
Showing results for 
Search instead for 
Did you mean: 

Two STM32F4-discovery boards unable to communicate over CAN

Rde K.1
Associate III

Hi,

I am new to HAL libraries and currently working on a small CAN bus consisting of two STM32F4-discovery boards connected to a CAN transceiver connected to the bus. Both transceivers are externally powered with 5V.

So far, I tried the existing CAN examples from the STM32CubeF4 github. The loopback example works fine, the normal mode example does not.

After a few transmissions the mailboxes are filled and the transmit function returns an error. And I can't figure out why it does not transmit the requests. Below you can find the code I on both discovery boards. It is basically the Networking example but with some light adjustments for LED output pins.

Any ideas on why this might not be working as expected?

#include "main.h"
 
#define KEY_PRESSED     0x00
#define KEY_NOT_PRESSED 0x01
 
uint8_t ubKeyNumber = 0x0;
CAN_HandleTypeDef     CanHandle;
CAN_TxHeaderTypeDef   TxHeader;
CAN_RxHeaderTypeDef   RxHeader;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
 
 
void SystemClock_Config(void);
void Error_Handler(void);
void CAN_Config(void);
void LED_Display(uint8_t LedStatus);
void Init_OnBoard_LEDs(void);
 
int main(void)
{
  HAL_Init();
 
  /* Configure the system clock to 168 MHz */
  SystemClock_Config();
 
  /* Configure LED1, LED2, LED3 and LED4 */
  Init_OnBoard_LEDs();
 
  LED_Display(ubKeyNumber);
 
  /* Configure the CAN peripheral */
  CAN_Config();
 
  /* Infinite loop */
  while (1)
  {
	  uint8_t state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
    if (state)
    {
      if (ubKeyNumber == 0x4)
      {
        ubKeyNumber = 0x00;
      }
      else
      {
        LED_Display(++ubKeyNumber);
 
        /* Set the data to be transmitted */
        TxData[0] = ubKeyNumber;
        TxData[1] = 0xAD;
 
        /* Start the Transmission process */
        if (HAL_CAN_AddTxMessage(&CanHandle, &TxHeader, TxData, &TxMailbox) != HAL_OK)
        {
          /* Transmission request Error */
          Error_Handler();
        }
        HAL_Delay(1000);
      }
    }
  }
}
 
void Init_OnBoard_LEDs(void){
	__HAL_RCC_GPIOD_CLK_ENABLE();
	GPIO_InitTypeDef BoardLEDs;
	BoardLEDs.Mode = GPIO_MODE_OUTPUT_PP;
	BoardLEDs.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
	HAL_GPIO_Init(GPIOD, &BoardLEDs);
 
 
	__HAL_RCC_GPIOA_CLK_ENABLE();
	GPIO_InitTypeDef BlueButton;
	BlueButton.Mode = GPIO_MODE_INPUT;
	BlueButton.Pin = GPIO_PIN_0;
	BlueButton.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOA, &BlueButton);
}
 
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
 
  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();
 
  /* The voltage scaling allows optimizing the power consumption when the device is
     clocked below the maximum system frequency, to update the voltage scaling value
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
 
  /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported  */
  if (HAL_GetREVID() == 0x1001)
  {
    /* Enable the Flash prefetch */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
  }
}
 
 
 
/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
  while (1)
  {
  }
}
 
/**
  * @brief  Configures the CAN.
  * @param  None
  * @retval None
  */
void CAN_Config(void)
{
	//Tx: PB12
	//Rx: PB13
  CAN_FilterTypeDef  sFilterConfig;
 
  /*##-1- Configure the CAN peripheral #######################################*/
  CanHandle.Instance = CAN2;
 
  CanHandle.Init.TimeTriggeredMode = DISABLE;
  CanHandle.Init.AutoBusOff = DISABLE;
  CanHandle.Init.AutoWakeUp = DISABLE;
  CanHandle.Init.AutoRetransmission = ENABLE;
  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_4TQ;
  CanHandle.Init.TimeSeg2 = CAN_BS2_2TQ;
  CanHandle.Init.Prescaler = 6;
 
  if (HAL_CAN_Init(&CanHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
 
  /*##-2- 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 = 14;
 
  if (HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
    Error_Handler();
  }
 
  /*##-3- Start the CAN peripheral ###########################################*/
  if (HAL_CAN_Start(&CanHandle) != HAL_OK)
  {
    /* Start Error */
    Error_Handler();
  }
 
  /*##-4- Activate CAN RX notification #######################################*/
  if (HAL_CAN_ActivateNotification(&CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }
 
  /*##-5- Configure Transmission process #####################################*/
  TxHeader.StdId = 0x321;
  TxHeader.ExtId = 0x01;
  TxHeader.RTR = CAN_RTR_DATA;
  TxHeader.IDE = CAN_ID_STD;
  TxHeader.DLC = 2;
  TxHeader.TransmitGlobalTime = DISABLE;
}
 
/**
  * @brief  Rx Fifo 0 message pending callback
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  *         the configuration information for the specified CAN.
  * @retval None
  */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
  /* Get RX message */
  if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
  {
    /* Reception Error */
    Error_Handler();
  }
 
  /* Display LEDx */
  if ((RxHeader.StdId == 0x321) && (RxHeader.IDE == CAN_ID_STD) && (RxHeader.DLC == 2))
  {
    LED_Display(RxData[0]);
    ubKeyNumber = RxData[0];
  }
}
 
/**
  * @brief  Turns ON/OFF the dedicated LED.
  * @param  LedStatus: LED number from 0 to 3
  * @retval None
  */
void LED_Display(uint8_t LedStatus)
{
  /* Turn OFF all LEDs */
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
 
	switch(LedStatus){
	case(0x0):
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
		break;
	case(0x1):
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
		break;
	case(0x2):
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
		break;
	case(0x3):
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
		break;
	default:
		break;
	}
}

35 REPLIES 35

I connected each VIO pin to the 3V pin on the discovery board connected to it, but the situation remains the same.

Check all the connections by continuity test: from STM32 to the other STM32: Tx/Rx/ Tranceivers/ CANH/CANL ..

Check the voltage levels on the transceivers pins (power supply+VIO)

It's not obvious to provide a direct answer ..

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.

All pins are connected properly from discovery board to discovery board and tested with the multimeter. The voltage on the power and VIO are 4.84V and 2.96V respectively.

Therefore, I have a feeling it's a software issue. But I don't see where the problem is on the receiving end.

If you have used the same software on both disco board it's OK. Check the GPIOs used for CAN2 + GPIO APB clock .Check your bitrates according to the APB clock . I don't see how I can help more..

You can also use CubeMx to configure the system clock and your CAN interface + the bitrate.

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.

You're very welcome! Something bugged me when you said the CAN transceivers were externally powered with 5v. So I had to ask how they were connected. Glad you took your time to draw it out. I immediately could see the issue with the Dev boards not grounded to the CAN transceiver reference ground.

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.

@Rde K.1​ You're not filtering on any ID's so you're receiving all CAN message so the filter bank doesn't matter. Below configuration is what I use for both CAN1 and CAN2

0693W00000Y6k5KQAR.png

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.

@Rde K.1​ Offhand the Auto Transmission signal doesn't look right but I'm not sure since the timebase is too fast. Can you change the timebase to closer to 1ms or so we can see as much of the signal as possible? The signal should look similar to this where you can distinguish the bits

0693W00000Y6kDdQAJ.png

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.

No. Even he's not filtering on any ID's it will never work because the filtering bank config is not set correctly for CAN2. The messages are passing through the filters, so if they are not well configured he will never get any message.

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.

@Community member​ What do mean by not well configured? I changed the .FilterBank to 14, like you mentioned in the explanation.

It was a reply to Karl regarding "receiving all CAN message so the filter bank doesn't matter". The message is not for you ;)

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.