cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 CAN transmit bug?

SBaye
Associate

Hello to all from Germany,

I try to set up a CAN communication between the STM32F105RB and PCAN-Ethernet-Gateway. I have configured all my peripherals with STM32CubeMX (Version 5.3.0) and generated the code for Keil uVision (V5 28.0.0) and Atollic TrueSTUDIO (Version 9.3.0).

I know that the hardware of the CAN bus is perfectly working (because of an other project) so the problem has to be either in my code or in the HAL library. So, my problem is:

I have made a CAN frame with header and payload and I tried to transmit it with the CAN1 peripheral. I activated all interrupt sources by means of the function HAL_CAN_ActivateNotification(...). I also activated the CAN peripheral using HAL_CAN_Start(&hcan1). 

I am trying to transmit the CAN frame when an interrupt occurs because of an empty transmit buffer. I have noticed that this kind of interrupt never occurs. But why?

The flags BOFF, EPVF, EWGF are toggling between 1 and 0 all the time without a recognisable pattern. I try to set a breakpoint in the callback functions HAL_CAN_TxMailbox1CompleteCallback, HAL_CAN_TxMailbox2CompleteCallback and HAL_CAN_TxMailbox3CompleteCallback.

Is there anything wrong with the code that was generated by STM32CubeMX or is it my code? Is it necessary to configure a filter for CAN?

Please see my code below. Thank you for helping.

0690X00000AARBeQAP.png0690X00000AARBZQA5.png

int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
  
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN1_Init();
  MX_TIM6_Init();
  MX_UART4_Init();
  MX_USART1_UART_Init();
  MX_SPI1_Init();
  MX_SPI3_Init();
  MX_CRC_Init();
 
  /* Initialize interrupts */
  MX_NVIC_Init();
  /* USER CODE BEGIN 2 */
 
  /* Filter configuration */
  CAN_FilterTypeDef sFilterConfig;
  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterFIFOAssignment = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.FilterIdHigh = 0x000 << 5;
  sFilterConfig.FilterIdLow = 0;
  sFilterConfig.FilterMaskIdHigh = 0x000 << 5;
  sFilterConfig.FilterMaskIdLow = 0;
  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
 
  HAL_TIM_Base_Start_IT(&htim6);
  HAL_CAN_Start(&hcan1);
 
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_FULL);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_OVERRUN);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_FULL);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_OVERRUN);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_WAKEUP);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_SLEEP_ACK);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR_WARNING);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR_PASSIVE);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_BUSOFF);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_LAST_ERROR_CODE);
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR);
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

2 REPLIES 2

Hello Stephan,

I can confirm your trouble because I have the same problem, the IRQ for CAN_IT_TX_MAILBOX_EMPTY never happens.

I am suspicious about the shared IRQs with the USB controller but did not find an answer jet.

Best regards,

Markus.

Johi
Senior III

Hello Markus & Stephan,

Last week I explored my STM32F407VET6 industrial communications board that has 2 CAN bus connection both leading to the MCU. I was able to send with CAN 1 to CAN 2 by ISR and by POLLING. Without configuring filters is mandatory for details see RM (RM0090 for the STM32F407VET6). I added a detailed document with the settings and code for both experiments (see attachment).

In other experiments I observerd that I needed to give the HAL a first kick and then the cycle of ISR's started, the reason why I have not figured out yet.

	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
	{
		printf("Failed activating notification.\n");
		Error_Handler();
	}
	else
		HAL_CAN_TxMailbox0CompleteCallback(&hcan1);

Best regards,

John.