cancel
Showing results for 
Search instead for 
Did you mean: 

CanRx no callback

bartocham
Associate II
Posted on March 14, 2016 at 11:26

Hi,

I wrote about in other topic but it was not clear so I took decision to start other topic. I'm working with CAN of F103 with CubeMX configuration. Transmiting works fine but I have problem with receive. Before while loop in user code I copied part from CubeF1 example package:

/*##-2- Start the Reception process and enable reception interrupt #########*/
if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}

It shall enable interrupt but I'm not getting any callback... I have to call it manualy like this:

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_CAN_Transmit(&hcan, 10);
if(HAL_CAN_Receive(&hcan, CAN_FIFO0,10) == HAL_OK)
{
HAL_CAN_RxCpltCallback(&hcan);
}
HAL_Delay(10);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

In that way it's working on loopback mode. Any idea why do I have to do it that way?
10 REPLIES 10
Nesrine M_O
Lead II
Posted on March 15, 2016 at 12:06

Hi bartocha.mateusz.001,

Could you please check error flags in CAN_ESR register? Maybe there is an error that happens and blocks the Receive complete callback.

Also you can have a look to the CAN_LoopBack example under the STM32F4 cube firmware package it may be helpful. 

The example is tested using STM324x9I_EVAL evaluation board, but it can be adapted to any other supported device.

STM32Cube_FW_F4_V1.11.0\Projects\STM324x9I_EVAL\Examples\CAN\CAN_LoopBack

-Syrine-

bartocham
Associate II
Posted on March 16, 2016 at 19:19

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6Wa&d=%2Fa%2F0X0000000bpw%2FhyD7Gj.JkX9pyoN3zq4gzB2hzLyjkOOtVdoHwDg44XQ&asPdf=false
bartocham
Associate II
Posted on March 16, 2016 at 20:35

Ok found solution.

From stm32f1xx_hal_can.c

*** Interrupt mode IO operation ***

===================================

[..]

(+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()

(+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()

(+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine

(+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can

add his own code by customization of function pointer HAL_CAN_TxCpltCallback

(+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can

add his own code by customization of function pointer HAL_CAN_ErrorCallback

If I change my subroutine in main function to look like this:

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();

/* Configure the system clock */

SystemClock_Config();

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_CAN_Init();

/* USER CODE BEGIN 2 */

/* struct ID to repetitive asks to ECU */

uint8_t PIDcnt=0;

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

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

{

/* Reception Error */

Error_Handler();

}

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

/* Fill frame to ask ECU for basic data */

OBD_FillFrame(PIDcnt);

/* cycle PID id */

if(PIDcnt<4)

{

PIDcnt++;

}

else

{

PIDcnt=0;

}

HAL_CAN_Transmit(&hcan, 10);

HAL_Delay(10);

HAL_CAN_IRQHandler(&hcan);

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

It is working.

Amel NASRI
ST Employee
Posted on March 17, 2016 at 10:57

Hibartocha.mateusz.001,

HAL_CAN_IRQHandler should be added in the file stm32f1xx_it.c as already done in the example:

void CANx_RX_IRQHandler(void)
{
HAL_CAN_IRQHandler(&CanHandle);
}

-Mayla-

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.

bartocham
Associate II
Posted on March 18, 2016 at 10:31 Hi Mayla, Now I understand flow a little bit more. In example I see something like this in main.h

/* Definition for USARTx's NVIC */
#define CANx_RX_IRQn USB_LP_CAN1_RX0_IRQn
#define CANx_RX_IRQHandler USB_LP_CAN1_RX0_IRQHandler

Could you explain it to me ? I don't understand what actually those defines are for. Shall I add something like this into my code?
Posted on March 18, 2016 at 12:46

One is the NVIC interrupt index number, and the other is the vector table name of the function being called.

The macro substitution changes your generalized function name, to the one explicitly associated with the specific CAN interface you are actually using.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bartocham
Associate II
Posted on March 18, 2016 at 13:33

Ok. It's clear now.

This weekend I'll try to make my code work.

Thanks for help.

bartocham
Associate II
Posted on March 22, 2016 at 21:17

Hi,

I've looked into example from cube package. After that I found my mistakes but problems continue. Right now in while loop in main.c I simply call can_transmit function withHAL_CAN_Transmit(&hcan,10) and useHAL_Delay(10); After that my callback function code is executed. According to example at the end of it I'm rearming receive.

/* Rearm Receive */
if (HAL_CAN_Receive_IT(hcan, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}

And here's the problem - receive_it does not return HAL_OK. During debug I saw that it return HAL_BUSY state. I saw that in receive_it hcan state is READY - 0x01 however after entering to first IF, locking CAN it unconditionally jumps to ELSE statement and return busy. Do you have any clue on that ?
bartocham
Associate II
Posted on March 26, 2016 at 13:44

No one have similar problem ?

I found out that first time after reset I am able to finalize receive_it function correctly, but next times it enters busy state and I'm not able to rearm the interrupt ;/