2018-06-21 03:29 PM
I have struggled over the last couple of weeks to implement an interrupt-driven CAN system on a STM32F042K6 using CubeMX v4.26.0 and FW_F0 V1.9.0.
Now that I finally have it working, I found what I believe is a bug in HAL_CAN_IRQHandler() - and thought others might be interested.
At line 1384 in stm32f0xx_hal_can.c, there is a call to __HAL_CAN_DISABLE_IT() to disable a bunch of interrupts when an error is detected. Included in these are CAN_IT_FMP0 and _FMP1 - which are required to receive messages.
HAL_CAN_Receive_IT() properly enables the relevant FMPx interrupt. But then if there's some kind of glitch on the bus and ANY error interrupt occurs, FMPx will be cleared. A message that arrives after this glitch will not generate an interrupt and will be ignored.
While I've used a variety of STM32 chips in various projects, this is my first foray into CAN on the STM32, so feel free to correct me if I'm wrong!
Workaround: Enable HAL_CAN_ErrorCallback() as follows:
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *canp) {
// Re-enable receive interrupts! // (The error handling code in HAL_CAN_IRQHandler() disables this for some reason!) __HAL_CAN_ENABLE_IT(canp, CAN_IT_FMP0 |CAN_IT_FMP1);
// (or only re-enable the one you are using)
}Alternate (uglier) workaround: Use a polled system for CAN receives.
Real fix: In stm32f0xx_hal_can.c, do not disable ALL the interrupts when an error is detected. It seems like it should only disable the error interrupts - as follows:
/* Disable interrupts: */
/* - Disable Error warning Interrupt */ /* - Disable Error passive Interrupt */ /* - Disable Bus-off Interrupt */ /* - Disable Last error code Interrupt */ /* - Disable Error Interrupt */__HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC | CAN_IT_ERR);Thanks.
2018-06-22 02:14 AM
Hello
Seymour.Jim
,I will raise this issue internally for check.
With Regards,
Imen.