Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NUCLEO_H743ZI2 CAN-FD Rx Interrupt not triggering but polling via thread works #15144

Closed
mynameismichael opened this issue Oct 18, 2021 · 14 comments · Fixed by #15398
Closed

Comments

@mynameismichael
Copy link

mynameismichael commented Oct 18, 2021

Description of defect

STM32H7 / NUCLEO_H743ZI2 CAN-FD rx interrupt is never triggered, despite using same code base as STM32 F7 target, which does trigger. Target has been changed and project setup (i.e. Makefile) to use H7 libraries.

Target(s) affected by this defect ?

STM32H7 variants with CAN-FD.

Toolchain(s) (name and version) displaying this defect ?

GNU MCU Eclipse Windows Build Tools 2.12.1-1
GNU Arm Embedded Toolchain 9 2020 Q2 Update but also 2019 Q4 Major

What version of Mbed-os are you using (tag or sha) ?

mbed-os-6.15.0, but also: 6.10.0 and 6.13.0

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

mbed-cli (purely for exporting projects, this works fine on F7 variants)
Eclipse IDE (probably not relevant)
OpenOCD for debugging (also probably irrelevant)

How is this defect reproduced ?

I can attempt to light an LED (which otherwise works in standard blinky program) upon CAN message rx interrupt. This does not work. However, when using threads, the CAN rx and constantly polling for a message, we will receive the message, and the LED will light.

@mbedmain
Copy link

@mynameismichael thank you for raising this issue.Please take a look at the following comments:

Could you add some more detail to the description? A good description should be at least 25 words.

NOTE: If there are fields which are not applicable then please just add 'n/a' or 'None'. This indicates to us that at least all the fields have been considered.
Please update the issue header with the missing information.

@jeromecoutant
Copy link
Collaborator

jeromecoutant commented Oct 19, 2021

Hi

STM32F7 is using CAN, so is using code from
https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/can_api.c#L682

STM32H7 is the first STM32 family with FDCAN, so with code before previous line.
I don't have a CAN setup with me, but with a quick review, code in can_irq_set seems strange as all IRQ are enabled without any check...
https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/can_api.c#L622

@mynameismichael
Copy link
Author

mynameismichael commented Oct 19, 2021

Indeed, I had glanced over this module, but it would appear now that the master has changed, and I should update mbed-os, perhaps.

I think, based on a quick glance of some commit history of that file, that somebody is working on a fix, but I cannot be sure if this includes H7.

What is in the file you linked:

case IRQ_RX:
#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)
            interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE;
#else

What I have:

case IRQ_RX:
#ifndef TARGET_STM32G4
            interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE;
#else

I will be going through the commit history. It is strange that all IRQ's are enabled.

@pmancele
Copy link
Contributor

Any update on this issue ? I can reproduce the behavior (No CAN Rx Irq)

@veppikeppi
Copy link

Any updates on this? Same problem still with NUCLEO_H743ZI2

@pmancele
Copy link
Contributor

Hello,

Yes we found that it works with the following modification in the can_api.c file. It seems that there are modification for STM32G4 that should also be done for STM32H7 :

diff --git a/targets/TARGET_STM/can_api.c b/targets/TARGET_STM/can_api.c
index e1468abfd8..65b1342204 100644
--- a/targets/TARGET_STM/can_api.c
+++ b/targets/TARGET_STM/can_api.c
@@ -520,17 +520,17 @@ static void can_irq(CANName name, int id)
             irq_handler(can_irq_ids[id], IRQ_TX);
         }
     }
-#ifndef TARGET_STM32G4
-    if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
-        if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
-            __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE);
+#if defined(TARGET_STM32G4) || defined(TARGET_STM32H7)
+    if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) {
+        if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) {
+            __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE);
             irq_handler(can_irq_ids[id], IRQ_RX);
         }
     }
 #else
-    if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) {
-        if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) {
-            __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE);
+    if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
+        if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
+            __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE);
             irq_handler(can_irq_ids[id], IRQ_RX);
         }
     }
@@ -602,10 +602,10 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
             interrupts = FDCAN_IT_TX_COMPLETE;
             break;
         case IRQ_RX:
-#ifndef TARGET_STM32G4
-            interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE;
-#else
+#if defined(TARGET_STM32G4) || defined(TARGET_STM32H7)
             interrupts = FDCAN_IT_RX_FIFO0_NEW_MESSAGE;
+#else
+            interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE;
 #endif
             break;
         case IRQ_ERROR:
 

@jeromecoutant
Copy link
Collaborator

Hi

So in current can_irq function, we have:

#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)
  xxx GET/CLEAR FDCAN_IT_RX_BUFFER_NEW_MESSAGE
#else
  xxx GET/CLEAR FDCAN_IT_RX_FIFO0_NEW_MESSAGE

which is currently equivalent to:
#if TARGET_STM32H7

So you mean this has to be corrected ?

@pmancele
Copy link
Contributor

Hello @jeromecoutant,

The master has been modified since our last message. I don't know how to patch it properly but yes, it seems that when using the STM32H7, the FDCAN_IT_RX_FIFO0_NEW_MESSAGE variable should be used, not the FDCAN_IT_RX_BUFFER_NEW_MESSAGE

@veppikeppi
Copy link

Thanks pmancele! After taking the FIFO in use (instead of BUFFER) H7 CAN interrupt started to work. So please fix this in the official mbed release.

@jeromecoutant
Copy link
Collaborator

Hi @veppikeppi
Will you be able to propose a patch ?
Thx

@AilWe
Copy link

AilWe commented Jun 27, 2022

Any update on this issue? After I change all FDCAN_IT_RX_BUFFER_NEW_MESSAGE to FDCAN_IT_RX_FIFO0_NEW_MESSAGE. CAN interrupt works. But it can only receive signal for 4 times.

@AilWe
Copy link

AilWe commented Jun 27, 2022

Thanks pmancele! After taking the FIFO in use (instead of BUFFER) H7 CAN interrupt started to work. So please fix this in the official mbed release.

Could you please propose a patch?

@AilWe
Copy link

AilWe commented Jun 27, 2022

Hi

So in current can_irq function, we have:

#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)
  xxx GET/CLEAR FDCAN_IT_RX_BUFFER_NEW_MESSAGE
#else
  xxx GET/CLEAR FDCAN_IT_RX_FIFO0_NEW_MESSAGE

which is currently equivalent to: #if TARGET_STM32H7

So you mean this has to be corrected ?

Hi

So in current can_irq function, we have:

#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)
  xxx GET/CLEAR FDCAN_IT_RX_BUFFER_NEW_MESSAGE
#else
  xxx GET/CLEAR FDCAN_IT_RX_FIFO0_NEW_MESSAGE

which is currently equivalent to: #if TARGET_STM32H7

So you mean this has to be corrected ?
I am new to mbed-os.
My current can_irq function is same as yours, have you modify code to make it work? I changed all FDCAN_IT_RX_BUFFER_NEW_MESSAGE to FDCAN_IT_RX_FIFO0_NEW_MESSAGE, but the interrupt can only work for 4 times, then never response again.

@jtmyz9
Copy link

jtmyz9 commented Apr 4, 2023

It looks like what is happening is that the can filters are being configured to load new messages into the FIFO https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/can_api.c#L375

if (format == CANStandard) {
        sFilterConfig.IdType = FDCAN_STANDARD_ID;
        sFilterConfig.FilterIndex = handle;
        sFilterConfig.FilterType = FDCAN_FILTER_MASK;
        sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;

Such that messages aren't loaded into the buffer but the RX Fifo so only the FDCAN_IT_RX_FIFO0_NEW_MESSAGE interrupt would trigger like this and not the FDCAN_IT_RX_BUFFER_NEW_MESSAGE changing can_irq in can_api.c to following sets IRQ_RX to the interrupt that is actually getting triggered

#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)  && !defined(TARGET_STM32H7)
    if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
        if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
            __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE);
            irq_handler(can_irq_contexts[id], IRQ_RX);
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants