cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 EVAL board CAN2 receive interrupt not working, but CAN2 transmit working

praseen
Associate II
Posted on October 31, 2016 at 12:44

Hardware: STM3240G-EVAL (STM32 20-21-45-46 G-EVAL) using STM32F407IGH6UHPAHP microcontroller

 

 

IDE: Eclipse IDE for C/C++ Luna Service Release 2 (4.4.2) Build: 20150219-0600

 

 

Toolchain: Ac6 STM32 MCU GCC

Using the above hardware and software I am unable to get CAN2 receive interrupt on the STM32 evaluation module mentioned above. However I am able 

to transmit without interrupt using CAN2. The CAN1 peripheral is working as expected and I am able to successfully transmit and get receive interrupts. 

Below is code I have written for configuring CAN2 for receive interrupt. The CAN2 transmit is working without interrupt using this configuration.

stm32f4xx_it.h - In this file added the lines

 

void CAN2_RX0_IRQHandler(void);

 

void CAN2_RX1_IRQHandler(void);

 

Can.cpp - In this file added the lines

extern ''C'' void CAN2_RX0_IRQHandler(void)

 

{

 

   canRxIsr(&canHandle);

 

}

 

 

__inline void canRxIsr(CAN_HandleTypeDef* canrxhandle)

 

{

 

   HAL_CAN_IRQHandler(canrxhandle);

 

   HAL_CAN_Receive_IT(canrxhandle, CAN_FIFO0);

 

 

   //changed for integration

 

   // Transmit below done to validate the receive that has happened

 

   canHandle.pTxMsg->StdId = 821;

 

   canHandle.pTxMsg->DLC = 8;

 

   canHandle.pTxMsg->Data[0] = 0xAA;

 

   canHandle.pTxMsg->Data[1] = 0xBB;

 

   canHandle.pTxMsg->Data[2] = 0xCC;

 

   canHandle.pTxMsg->Data[3] = 0xDD;

 

 

 

   canHandle.pTxMsg->Data[4] = 0xEE;

 

   canHandle.pTxMsg->Data[5] = 0xFF;

 

   canHandle.pTxMsg->Data[6] = 0xAA;

 

   canHandle.pTxMsg->Data[7] = 0xBB;

 

 

 

   HAL_CAN_Transmit(&canHandle, 10);

 

   //changed for integration

 

}

 

void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)

 

{

 

   //changed for CAN2 configuration

 

   GPIO_InitTypeDef   GPIO_InitStruct;

 

 

  /*♯♯-1- Enable peripherals and GPIO Clocks ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

 

  /* CAN2 Periph clock enable */

 

  CANx1_CLK_ENABLE(); //Both clocks are configured as per data sheet for CAN2 to work

 

  CANx_CLK_ENABLE();

 

 

  /* Enable GPIO clock ****************************************/

 

  CANx_GPIO_CLK_ENABLE();

 

 

  /*♯♯-2- Configure peripheral GPIO ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

 

  /* CAN2 TX GPIO pin configuration */

 

  GPIO_InitStruct.Pin = CANx_TX_PIN;

 

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

 

  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;

 

  GPIO_InitStruct.Pull = GPIO_PULLUP;

 

  GPIO_InitStruct.Alternate =  CANx_TX_AF;

 

 

  HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);

 

 

  /* CAN2 RX GPIO pin configuration */

 

  GPIO_InitStruct.Pin = CANx_RX_PIN;

 

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

 

  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;

 

  GPIO_InitStruct.Pull = GPIO_PULLUP;

 

  GPIO_InitStruct.Alternate =  CANx_RX_AF;

 

 

  HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);

 

 

  /*♯♯-3- Configure the NVIC ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

 

  /* NVIC configuration for CAN2 Reception complete interrupt */

 

  HAL_NVIC_SetPriority(CANx_RX_IRQn, 1, 0);

 

  HAL_NVIC_EnableIRQ(CANx_RX_IRQn);

 

}

 

/**

  * @brief CAN MSP De-Initialization

  *        This function frees the hardware resources used in this example:

  *          - Disable the Peripheral's clock

  *          - Revert GPIO to their default state

  * @param hcan: CAN handle pointer

  * @retval None

  */

void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)

 

{

 

  /*♯♯-1- Reset peripherals ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

 

  CANx_FORCE_RESET();

 

  CANx_RELEASE_RESET();

 

 

  /*♯♯-2- Disable peripherals and GPIO Clocks ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

 

  /* De-initialize the CAN2 TX GPIO pin */

 

  HAL_GPIO_DeInit(CANx_TX_GPIO_PORT, CANx_TX_PIN);

 

  /* De-initialize the CAN2 RX GPIO pin */

 

  HAL_GPIO_DeInit(CANx_RX_GPIO_PORT, CANx_RX_PIN);

 

 

  /*♯♯-4- Disable the NVIC for CAN reception ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

 

  HAL_NVIC_DisableIRQ(CANx_RX_IRQn);

 

}

 

Since the EVK is being used the PORTB PIN 13 is used for CAN2 Tx and PORTB PIN 8 is used for CAN2 Rx

 

The values of the config macros used above is as below

 &sharpdefine CANx                            CAN2

 

 &sharpdefine CANx_CLK_ENABLE()               __HAL_RCC_CAN2_CLK_ENABLE()

 

 &sharpdefine CANx1_CLK_ENABLE()              __HAL_RCC_CAN1_CLK_ENABLE()

 

 &sharpdefine CANx_GPIO_CLK_ENABLE()          __HAL_RCC_GPIOB_CLK_ENABLE()

 

 

 &sharpdefine CANx_FORCE_RESET()              __HAL_RCC_CAN2_FORCE_RESET()

 

 &sharpdefine CANx_RELEASE_RESET()            __HAL_RCC_CAN2_RELEASE_RESET()

 

 

 /* Definition for CANx Pins */

 

 &sharpdefine CANx_TX_PIN                    GPIO_PIN_13

 

 &sharpdefine CANx_TX_GPIO_PORT              GPIOB

 

 &sharpdefine CANx_TX_AF                     GPIO_AF9_CAN2

 

 &sharpdefine CANx_RX_PIN                    GPIO_PIN_5

 

 &sharpdefine CANx_RX_GPIO_PORT              GPIOB

 

 &sharpdefine CANx_RX_AF                     GPIO_AF9_CAN2

 

 

 /* Definition for CANx's NVIC */

 

 &sharpdefine CANx_RX_IRQn                   CAN2_RX0_IRQn

 

 &sharpdefine CANx_RX_IRQHandler             CAN2_RX0_IRQHandler

 

 

 I have also made the jumper changes to the JP3, JP10, JP7 and JP9 on the evaluation module for enabling CAN2 in high speed.

 

 Please have a look and let me know what I missed in the configuration, to get CAN2 receive interrupt working.

#receive #can2-configuration
5 REPLIES 5
Posted on October 31, 2016 at 13:09

Are you using filter settings suitable for CAN2?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
praseen
Associate II
Posted on October 31, 2016 at 15:42

Hi Clive,

This is my filter configuration below, its marked in blue, in the middle of the complete CAN configuration. Please let me know, what change I need to make for CAN2 receive interrupt to work.

 

CANConfig(void)

 

{

 

  CAN_FilterConfTypeDef  sFilterConfig;

 

  static CanTxMsgTypeDef        TxMessage;

 

  static CanRxMsgTypeDef        RxMessage;

 

 

  /*##-1- Configure the CAN peripheral #######################################*/

 

  canHandle.Instance = CAN2; 

 

  canHandle.pTxMsg = &TxMessage;

 

  canHandle.pRxMsg = &RxMessage;

 

 

  canHandle.Init.TTCM = DISABLE;

 

  canHandle.Init.ABOM = DISABLE; //DISABLE; praseen

 

  canHandle.Init.AWUM = DISABLE; //DISABLE;

 

  canHandle.Init.NART = DISABLE;

 

  canHandle.Init.RFLM = DISABLE;

 

  canHandle.Init.TXFP = DISABLE;

 

  canHandle.Init.Mode = CAN_MODE_NORMAL;

 

 

  canHandle.Init.SJW = CAN_SJW_2TQ;

 

  canHandle.Init.BS1 = CAN_BS1_16TQ;

 

  canHandle.Init.BS2 = CAN_BS2_4TQ;

 

  canHandle.Init.Prescaler = 2;

 

 

  if(HAL_CAN_Init(&canHandle) != HAL_OK)

 

  {

 

    /* Initialization Error */

 

    ErrorHandler();

 

  }

 

 

  /*##-2- Configure the CAN Filter ###########################################*/

 

  sFilterConfig.FilterNumber = 14;

 

  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

 

  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

 

  sFilterConfig.FilterIdHigh = 0x0000;

 

  sFilterConfig.FilterIdLow = 0x0000;

 

  sFilterConfig.FilterMaskIdHigh = 0x0000;

 

  sFilterConfig.FilterMaskIdLow = 0x0000;

 

  sFilterConfig.FilterFIFOAssignment = 0;

 

  sFilterConfig.FilterActivation = ENABLE; //ENABLE; changed to test

 

  sFilterConfig.BankNumber = 14;

  if(HAL_CAN_ConfigFilter(&canHandle, &sFilterConfig) != HAL_OK)

 

  {

 

    /* Filter configuration Error */

 

    ErrorHandler();

 

  }

 

 

  /*##-3- Configure Transmission process #####################################*/

 

  canHandle.pTxMsg->StdId = 0x00;

 

  canHandle.pTxMsg->ExtId = 0x01;

 

  canHandle.pTxMsg->RTR = CAN_RTR_DATA;

 

  canHandle.pTxMsg->IDE = CAN_ID_STD;

 

  canHandle.pTxMsg->DLC = 0;

 

 

  /*##-2- Start the Reception process and enable reception interrupt #########*/

 

  if(HAL_CAN_Receive_IT(&canHandle, CAN_FIFO0) != HAL_OK)

 

  {

 

    /* Reception Error */

 

    ErrorHandler();

 

  }

 

}

 

Thanks and Regards,

jpeacock23
Associate II
Posted on November 01, 2016 at 03:09

For dual CAN you have to specify where the filter bank split occurs between CAN1 and CAN2.  I don't use HAL, is this done automatically or do you have to explicitly configure it?  It may be you are configuring the filter for the wrong interface.

praseen
Associate II
Posted on November 01, 2016 at 12:18

As part of the configuration I have specified it. For CAN1 the filter bank is between 0-13 and for CAN2 its between 14-27. So I have chosen filter bank as 14 in the above post.

~Praseen 

ST Renegade
Senior
Posted on November 02, 2016 at 08:33

Hello preman.praseen,

Why are you putting so much effort to configure the peripheral manually? For a starter I would recommend to use the STM32CubeMX to configure the CAN2 peripheral and try to make it run. After it's working, try to compare it to your code.

Btw. a silly thing, to receive the first message, you need to call the HAL_CAN_ReceiveIT function already in the main function and after that call this function over and over again in your ISR (but you made this call in your ISR).

Have a nice day,

Renegade