2016-10-31 04:44 AM
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 GCCUsing 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 linesextern ''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
2016-10-31 05:09 AM
Are you using filter settings suitable for CAN2?
2016-10-31 07:42 AM
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,
2016-10-31 07:09 PM
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.
2016-11-01 04:18 AM
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.
~Praseen2016-11-02 12:33 AM
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