cancel
Showing results for 
Search instead for 
Did you mean: 

CAN receive interrupt issue - data lost!

Raider E
Associate III
Posted on December 12, 2016 at 06:30

The original post was too long to process during our migration. Please click on the attachment to read the original post.
4 REPLIES 4
Jeroen3
Senior
Posted on December 12, 2016 at 08:55

I think your interrupt is overrun. CAN does not have much hardware FIFO. You really need to only fetch the data from the CAN memory. If you want to put it on display, you might want to have a software fifo, or a lower message burst. (eg: a burst of 5 consecutive messages will overrun the 3 deep fifo on an F1.

void CAN1_RX0_IRQHandler(void)

{

/* USER CODE BEGIN CAN1_RX0_IRQn 0 */

HAL_CAN_IRQHandler(&hcan1);

sprintf(data, '%d', hcan1.pRxMsg->Data[0]);

Byte_num=hcan1.pRxMsg->Data[0];

ILI9325_TextFont(120,50,data,RED,BLACK,FONT8x8_table);

HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);

/* USER CODE BEGIN CAN1_RX0_IRQn 1 */

/* USER CODE END CAN1_RX0_IRQn 1 */

}

Try reading the FIFO Overrun bits, see what those say.

For comparison, on 125 Kbit, you can fill the buffers in just 1.1 milliseconds. (3 STD RTR frames)

Posted on December 12, 2016 at 22:41

Many thanks Jeroen3.  I have just removed everything from the can receiving handler and included the following in my main  (following an youtube tutorial) and everything is now working like a charm. I have also removed the writing to the LCD to the main while loop and in the

HAL_CAN_RxCpltCallback only reading the received  data.

However, not sure what was the problem with my first approach and why it is working now what was the problem??. I always thought that I need tread data from CAN as soon as my program senses an IRQ handler interrupt!. 

One more question on a seperate matter. I'd like to start  using FreeRTOS semaphores with interrupts and whenever I receive a message give a signal to one of the threads to do something for example read a certain ADC pin and display it on screen then sleep until a new message arrives. My question is, is this the right way to do stuff or any other suggestions?

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)

{

if ((CanHandle->pRxMsg->StdId == 0x321)&&(CanHandle->pRxMsg->IDE == CAN_ID_STD) && (CanHandle->pRxMsg->DLC == 1))

{

// HAL_CAN_IRQHandler(&hcan1);

// hcan1->pRxMsg->Data[0];

// sprintf(data, '%d', hcan1->pRxMsg->Data[0]);

// Byte_num=hcan1->pRxMsg->Data[0];

// ILI9325_TextFont(120,50,data,RED,BLACK,FONT8x8_table);

Byte_num=CanHandle->pRxMsg->Data[0];

// sprintf(data, '%d', hcan1.pRxMsg->Data[0]);

// ILI9325_TextFont(120,50,data,RED,BLACK,FONT8x8_table);

//HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);

}

RxIntEnable(CanHandle);

}

void RxIntEnable(CAN_HandleTypeDef *CanHandle) {

if(CanHandle->State == HAL_CAN_STATE_BUSY_TX)

CanHandle->State = HAL_CAN_STATE_BUSY_TX_RX;

else {

CanHandle->State = HAL_CAN_STATE_BUSY_RX;

/* Set CAN error code to none */

CanHandle->ErrorCode = HAL_CAN_ERROR_NONE;

/* Enable Error warning Interrupt */

__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_EWG);

/* Enable Error passive Interrupt */

__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_EPV);

/* Enable Bus-off Interrupt */

__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_BOF);

/* Enable Last error code Interrupt */

__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_LEC);

/* Enable Error Interrupt */

__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_ERR);

}

// Enable FIFO 0 message pending Interrupt

__HAL_CAN_ENABLE_IT(CanHandle, CAN_IT_FMP0);

}
Posted on December 13, 2016 at 07:26

Using events to signal a different thread from an interrupt is the way to do it. However, you can't rely on the hardware fifo. You must add some software fifo, otherwise you're still going to truncate data when a burst arrives.

Note that because of this, you can't possibly keep up with a saturated bus! Don't expect this either. It's part of CAN bus design to not have a saturated bus.

Posted on June 16, 2017 at 19:59

Hi Raider E,

I am also having the similar problem. I will try the solution proposed here and will try to update in case I will be successful or not. Meanwhile can you please provide me the link of the 'youtube tutorial' you have mentioned in your post. 

Thank you

Naqqash