cancel
Showing results for 
Search instead for 
Did you mean: 

CAN interrupt is not called

Kaveh
Associate III

Hello,

I am trying to set up a CAN interrupt base communication system and it seems that IRQ handler is never called.

Debugger goes through the CAN1_TX and then back to main function, so IRq is never called.

USART output:

[2020-12-08_21:19:01:191] AFTER  50.

[2020-12-08_21:19:01:191]SYSCLK : 100000000Hz

[2020-12-08_21:19:01:191]HCLK  : 50000000Hz

[2020-12-08_21:19:01:191]PCLK1 : 25000000Hz

[2020-12-08_21:19:01:191]PCLK2 : 50000000Hz

[2020-12-08_21:19:01:191] BEFORE TX CALL.

[2020-12-08_21:19:01:191] After TX call.

[2020-12-08_21:19:01:191] END of program.

Main:

#include "main.h"
#include <string.h>
#include <stdio.h>
 
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart2;
FDCAN_HandleTypeDef CAN1;
 
 void SystemClock_Config_HSE(uint16_t Clock_Freq);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM2_Init(void);
void GPIO_Init(void);
void CAN1_Init(void);
void CAN1_TX(void);
void CAN1_RX(void);
void CAN_Filter_Config(void);
void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes);
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs);
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan);
 
char *user_data = "Hello world, I made it using STM32 ARM Cortex M7!\r\n";
char msg[100];
 
 
int main(void)
{
  HAL_Init();
	SystemClock_Config_HSE(SYS_CLOCK_FREQ_50_MHZ);
	  MX_GPIO_Init();
	  GPIO_Init();
	  MX_USART2_UART_Init();
	  MX_TIM2_Init();
 
 user_data = "						AFTER    50.\r\n";
	if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
	{
		Error_Handler();
	}
	memset(msg,0,sizeof(msg));
	sprintf(msg,"SYSCLK : %ldHz\r\n",HAL_RCC_GetSysClockFreq());
	HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
 
	memset(msg,0,sizeof(msg));
	sprintf(msg,"HCLK   : %ldHz\r\n",HAL_RCC_GetHCLKFreq());
	HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
 
	memset(msg,0,sizeof(msg));
	sprintf(msg,"PCLK1  : %ldHz\r\n",HAL_RCC_GetPCLK1Freq());
	HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
 
	memset(msg,0,sizeof(msg));
	sprintf(msg,"PCLK2  : %ldHz\r\n",HAL_RCC_GetPCLK2Freq());
	HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
 
 CAN1_Init();
 
  CAN_Filter_Config();
 
  if (HAL_FDCAN_Start(&CAN1) != HAL_OK)
	{
	  Error_Handler();
	}
 
  if (HAL_FDCAN_ConfigInterruptLines(&CAN1, FDCAN_IT_TX_COMPLETE | FDCAN_IT_RX_BUFFER_NEW_MESSAGE, FDCAN_INTERRUPT_LINE0) != HAL_OK)
	{
	  Error_Handler();
	}
 
  if (HAL_FDCAN_ActivateNotification(&CAN1, FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY | FDCAN_IT_TX_EVT_FIFO_FULL | FDCAN_IT_TX_EVT_FIFO_NEW_DATA | FDCAN_IT_BUS_OFF | FDCAN_IT_RX_BUFFER_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO1_NEW_MESSAGE, FDCAN_TX_BUFFER0 | FDCAN_TX_BUFFER1) != HAL_OK)
	{
	  Error_Handler();
	}
 
	user_data = "						BEFORE TX CALL.\r\n";
	if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
	{
		Error_Handler();
	}
 
  CAN1_TX();
 
	user_data = "						After TX call.\r\n";
	if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
	{
		Error_Handler();
	}
 
  uint8_t Loop_Count = 0;
 
  while (Loop_Count < 5)
  { 
	  Loop_Count++;
  }
 
	user_data = "						END of program.\r\n";
	if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
	{
		Error_Handler();
	}
}
 
 
void SystemClock_Config_HSE(uint16_t Clock_Freq)
{
	RCC_OscInitTypeDef OSC_Init;
	RCC_ClkInitTypeDef clk_init;
	uint8_t FLatency = 0;
 
	  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
	  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
 
	  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
 
	OSC_Init.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	OSC_Init.HSEState = RCC_HSE_ON;
	OSC_Init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
	OSC_Init.PLL.PLLState = RCC_PLL_ON;
	OSC_Init.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 
	switch(Clock_Freq)
	{
	case SYS_CLOCK_FREQ_50_MHZ:
	{
		OSC_Init.PLL.PLLM = 1;
		OSC_Init.PLL.PLLN = 25;
		OSC_Init.PLL.PLLP = 2;
		OSC_Init.PLL.PLLQ = 3;
		OSC_Init.PLL.PLLR = 2;
 
	    clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK  | \
	    					RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
							RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
	    clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	    clk_init.SYSCLKDivider = RCC_SYSCLK_DIV2;
	    clk_init.AHBCLKDivider = RCC_HCLK_DIV1;
	    clk_init.APB3CLKDivider = RCC_APB3_DIV1;
	    clk_init.APB1CLKDivider = RCC_APB1_DIV2;
	    clk_init.APB2CLKDivider = RCC_APB2_DIV1;
	    clk_init.APB4CLKDivider = RCC_APB4_DIV1;
 
		FLatency = FLASH_ACR_LATENCY_0WS;
 
		break;
	}
 
	default:
		return;
	}
 
	if (HAL_RCC_OscConfig(&OSC_Init) != HAL_OK)
	  {
		Error_Handler();
	  }
 
	if(HAL_RCC_ClockConfig(&clk_init, FLatency) != HAL_OK)
	  {
		Error_Handler();
	  }
 
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
 
 
void CAN1_Init(void)
{
	CAN1.Instance = FDCAN1;
	CAN1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
	CAN1.Init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK;		// EXTERNAL Means FDCAN treats its own transmitted messages as received
															// messages
 
	CAN1.Init.AutoRetransmission = ENABLE;
	CAN1.Init.TransmitPause = DISABLE;
	CAN1.Init.ProtocolException = DISABLE;
			// Setting values for 500k bps
	CAN1.Init.NominalPrescaler = 3;
	CAN1.Init.NominalSyncJumpWidth = 1;
	CAN1.Init.NominalTimeSeg1 = 2;
	CAN1.Init.NominalTimeSeg2 = 2;
	CAN1.Init.DataPrescaler = 3;
	CAN1.Init.DataSyncJumpWidth = 1;
	CAN1.Init.DataTimeSeg1 = 2;
	CAN1.Init.DataTimeSeg2 = 2;
	CAN1.Init.MessageRAMOffset = 0;
	CAN1.Init.StdFiltersNbr = 10;
	CAN1.Init.ExtFiltersNbr = 0;
	CAN1.Init.RxBuffersNbr = 64;
	CAN1.Init.RxFifo0ElmtsNbr = 64;
	CAN1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_32;
	CAN1.Init.RxFifo1ElmtsNbr = 64;
	CAN1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_32;
	CAN1.Init.RxBuffersNbr = 64;
	CAN1.Init.RxBufferSize = FDCAN_DATA_BYTES_32;
	CAN1.Init.TxBuffersNbr = 32;
	CAN1.Init.TxEventsNbr = 32;
	CAN1.Init.TxFifoQueueElmtsNbr = 32;
	CAN1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
	CAN1.Init.TxElmtSize = FDCAN_DATA_BYTES_16;
 
	if (HAL_FDCAN_Init(&CAN1) != HAL_OK)
	  {
	    Error_Handler();
	  }
 }
 
void CAN1_TX(void)
{
	FDCAN_TxHeaderTypeDef TX_Header;
	uint8_t CAN_Msg_Ptr[5] = {'H', 'E', 'L', 'L', 'R'};
	TX_Header.DataLength = 1;
	TX_Header.Identifier = 0x7DF;
	TX_Header.IdType = FDCAN_STANDARD_ID;
	TX_Header.TxFrameType = FDCAN_DATA_FRAME;
	TX_Header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
	TX_Header.BitRateSwitch = FDCAN_BRS_OFF;
	TX_Header.FDFormat = FDCAN_CLASSIC_CAN;
	//TX_Header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
	TX_Header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
	TX_Header.MessageMarker = 0x00;
 
	///*
	if( HAL_FDCAN_AddMessageToTxBuffer(&CAN1, &TX_Header, CAN_Msg_Ptr, FDCAN_TX_BUFFER0) != HAL_OK)
	  {
	    Error_Handler();
	  }
	//while(HAL_FDCAN_IsTxBufferMessagePending(&CAN1, FDCAN_TX_BUFFER0));
	//*/
}
 
void CAN_Filter_Config(void)
{
	FDCAN_FilterTypeDef CAN1_Filter_Init;
 
	CAN1_Filter_Init.IdType = FDCAN_STANDARD_ID;
	CAN1_Filter_Init.FilterIndex = 0;
	CAN1_Filter_Init.FilterType = FDCAN_FILTER_MASK;
	CAN1_Filter_Init.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
	CAN1_Filter_Init.FilterID1 = 0x0000;
	CAN1_Filter_Init.FilterID2 = 0x0000;
	CAN1_Filter_Init.RxBufferIndex = 0;
	CAN1_Filter_Init.IsCalibrationMsg = 0;
 
	if (HAL_FDCAN_ConfigFilter(&CAN1, &CAN1_Filter_Init) != HAL_OK)
	{
		Error_Handler();
	}
}
 
void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
	user_data = "		FIFO			CAN Message transmitted.\r\n";
	if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
	{
		Error_Handler();
	}
}
 
void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
	user_data = "		Buffer			CAN Message transmitted.\r\n";
	if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
	{
		Error_Handler();
	}
}
 
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
		FDCAN_RxHeaderTypeDef RX_Header;
		uint8_t Rcvd_msg[5];
 
		if( HAL_FDCAN_GetRxMessage(&CAN1, FDCAN_RX_FIFO0, &RX_Header, Rcvd_msg) != HAL_OK)
		{
			Error_Handler();
		}
 
		memset(msg,0,sizeof(msg));
		sprintf(msg,"Message received  : %s\r\n",Rcvd_msg);
		HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
}
 
void HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef *hfdcan)
{
	FDCAN_RxHeaderTypeDef RX_Header;
	uint8_t Rcvd_msg[5];
 
	if( HAL_FDCAN_GetRxMessage(&CAN1, FDCAN_RX_BUFFER0, &RX_Header, Rcvd_msg) != HAL_OK)
	{
		Error_Handler();
	}
 
	memset(msg,0,sizeof(msg));
	sprintf(msg,"Message received  : %s\r\n",Rcvd_msg);
	HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
}
 
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{
	user_data = "CAN BUS ERROR\r\n";
	HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY);
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
		HAL_Delay(500);
	}
}

1 ACCEPTED SOLUTION

Accepted Solutions
Kaveh
Associate III

After days of troubleshooting I discovered that not all system clocks work with CAN, SYSCLK 24 MHz and HCLK 12 MHZ worked for me, but 100 MHz did not. Is there a section in user manual or datasheet to find out these details instead of trial and error?

Also bellow lines have to be included in the systemclock function.

RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    /** Initializes the peripherals clocks
    */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
    PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }

View solution in original post

1 REPLY 1
Kaveh
Associate III

After days of troubleshooting I discovered that not all system clocks work with CAN, SYSCLK 24 MHz and HCLK 12 MHZ worked for me, but 100 MHz did not. Is there a section in user manual or datasheet to find out these details instead of trial and error?

Also bellow lines have to be included in the systemclock function.

RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    /** Initializes the peripherals clocks
    */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
    PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }