Skip to main content
Graduate
February 8, 2024
Question

Accidental EXTI-Interrupts on STM32H735

  • February 8, 2024
  • 9 replies
  • 8443 views

Hello,

maybe someone has an idea or can share an similar experience. Since I'm currently in the evaluation phase for selecting an MCU for our new industrial embedded project. I want to inspect and analyze this problem, to be sure the used MCU is working fine and i can use it (STM32H735IGK6).

Issue:
Pushbuttons on different EXTI-Interrupt  randomly fires twice or more times. Some GPIOs are effected, but not all, i have tested.

Setup:
Own PCB-Layout, 6 Pushbuttons, every one is debounced with 10kOhm and 10nF. Signal looks fine on scope, no bouncing can be seen with scope, absolutely clean signal.

Test 1:
apply a 200mHz sine-wave directly to the button pin. Expected behavior is: one interrupt on rising one interrupt on falling signal (due to the 200mV hysteresis on every input pin, as mentioned in datasheet). Behavior in RealLife: as soon as the voltage level on the pin reaches the switching thresholds of the input pin, i get lots of Interrupts (Rising and falling edge).
BUT now its getting freaky: if i turn off the running FMC access to an external RAM, instantly everything works as expected - only one single interrupt per transition.

Test 2:
same as above, but the FMC-access only bursts data every few seconds for approx. 250ms. Result: only, during FMC-access i get this accidential interrupts. (just to be sure: i checked the signal with the scope again: the waveform looks perfectly clean, without any noise, glitches, or something else)


I don't know if this can be an mcu-internal emc-issue or something like that, but fact is, if i enable the data transfer to the external RAM, the EXTI-Peripheral (or the schmitt trigger inside) gets extremely disturbed.
Of course, in this use case with buttons, a simple workaround is possible, but i also need a solution for other, more complex applications with combinations of FMC and EXTI (e.g. FPGA Communications, ...)

    This topic has been closed for replies.

    9 replies

    Technical Moderator
    February 8, 2024

    Hello @AZorn.1 

    Could you reproduce the issue on a reference board H735 Disco? Otherwise, could you set flags in the EXTI interrupt handlers and then check these flags in your main loop when performing the necessary FMC operations only when no EXTI interrupts are pending? To make sure the issue comes from overlapping operations and to follow-up this investigation by elimination.

    AZorn.1Author
    Graduate
    February 8, 2024

    Hello F.Belaid,

    thank you for your reply.
    To reproduce on an Disco Board is one of my next steps.

    Meanwhile i did one test with polling the pin, to figure out if it is an issue on NVIC, EXTI or GPIO itself.

    Setup:

    Two parallel threads, described below.

    Signal generator to trigger the (slow) pin changes. Setting 0,5Hz -> should trigger pin change every second.

    Expected behaviour cause of Schmitt Trigger to only trigger once during a high-low or low-high transition.

    First Thread:

    RAM Access for a few seconds, 10 seconds break, and again ...

     

     

     

    void WorkerThread::run(const Systick & now)
    {
     extern uint32_t _sdramExt_start;
     uint32_t i = 0;
    
     this->sleep(10000);
     HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
    
     (*Logger::getInstance()) .log(Systick(), __PRETTY_FUNCTION__, __LINE__, __FILE__, Logger::info, "RAM-Access start");
     for (i=0; i < 25; ++i) {
     memTestDevice(&_sdramExt_start, MT48LC4M16A2_RAMSIZE);
     this->sleep(1);
     }
     (*Logger::getInstance()) .log(Systick(), __PRETTY_FUNCTION__, __LINE__, __FILE__, Logger::info, "RAM-Access end");
    
     HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
    
    }

     

     

     

     

    second Thread with higher priority:

    poll pin change events and log when pin has changed

     

     

     

    void PinPollingThread::run(const Systick &now)
    {
     uint32_t i = 0;
    
     do {
     static GPIO_PinState oldState = GPIO_PIN_SET;
     GPIO_PinState state = GPIO_PIN_SET;
     if (oldState != (state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12))) {
     (*Logger::getInstance()) .log(Systick(), __PRETTY_FUNCTION__, __LINE__, __FILE__, Logger::info, "pin changed");
     oldState = state;
     }
     //exit loop, every n times, to allow the other system to do it's stuff
     }while(++i < 500);
    
     // sleep 1ms
     this->sleep(1);
    }

     

     

     

     

    Trigger the pin with an function generator, sine wave from 0.0V to 3.3V with 0.5Hz. Produces:

     

    [ 4800] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 5774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 6800] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 7774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 8800] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 9774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 10000] INFO [virtual void WorkerThread::run(const Systick&)@29] RAM-Access start
    [ 10761] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 10762] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 10766] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 10768] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 10769] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 11741] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 11742] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 11743] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12755] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12759] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12760] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12762] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12764] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12767] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 12768] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 13738] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 13740] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 13744] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 13745] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 13746] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 14758] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 14763] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 14764] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 15731] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 15732] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 15733] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 15734] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 15736] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 16537] INFO [virtual void WorkerThread::run(const Systick&)@34] RAM-Access end
    [ 16801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 17774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 18801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 19774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 20801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 21775] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 22801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 23774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 24801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 25774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 26537] INFO [virtual void WorkerThread::run(const Systick&)@29] RAM-Access start
    [ 26769] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 26770] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 26771] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27739] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27740] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27742] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27744] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27745] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27746] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 27747] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 28756] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 28759] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 28760] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 28762] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 28763] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 29743] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 29744] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 29745] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 30757] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 30762] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 30763] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 30765] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 30766] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 31730] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 31732] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 31733] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32765] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32766] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32767] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32768] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32770] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32773] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32775] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 32776] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 33088] INFO [virtual void WorkerThread::run(const Systick&)@34] RAM-Access end
    [ 33774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 34801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 35774] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed
    [ 36801] INFO [virtual void PinPollingThread::run(const Systick&)@27] pin changed

    So as you can see, in the phase without FMC-RAM-Access the pin changes approx. every second, as expected, but if there are FMC-RAM Accesses the pin do whatever it wants. And there are unwanted pin changes.

    Super User
    February 8, 2024

    Are all of the power pins decoupled with a 0.1 uF close to the chip? Can you share a photo or schematic?

    Are the misbehaving EXTI traces in close proximity to FMC traces?

    AZorn.1Author
    Graduate
    February 8, 2024

    Hello TDK,
    thank you for your reply, yes, power pins are decoupled with capacitors.

    AZorn1_0-1707402634763.png

    the white one is one of the affected EXTI-Pins. The other chip on the right side, is the RAM. In my opinion there cannot be lot of interference by the FMC-Traces.

    I checked the trace with my scope, measured the testpoint directly near at the STM.

    scope_4.pngfor sure, this picture is very low horizontal resolution, but also in other resolution, there are no glitches or noise present on this trace.

     

    Super User
    February 8, 2024

    Your sine wave has a VERY SLOW rise time compared to what digital inputs normally expect. Schmitt trigger inputs (what gives you the hysteresis) has a feed-back effect on the input signal as it crosses the rising/falling threshold.  Your 10K series resistor (I presume the RC filter is series-R, C to GND) gives a fairly high impedance going into the CPU pin.  These combined with possible power rail glitches from FMC activity could be causing the multiple IRQs you are seeing.

    Power supply decoupling might require multiple values in parallel, not just 0.1uF.

    Can you generate a square wave instead of sine wave?

    And finally, for detecting button presses, EXTI is not usually the best choice for exactly these reasons.  It SOUNDS good, but often doesn't work as well in real life.

    Graduate
    February 8, 2024

    One comment I would like to add is that Ground is not ground. You might have a bench power supply, your sine-wave generator and oscilloscope all firmly grounded together.

    But then you have your stm32 board hanging off your power-supply. It is taking gulps of current, particularly when it has to drive all those lines to the external memory.

    The inductance in the 0V wire means that there will be significant voltage difference (at the speed of external memory accesses) between all your bench test-equipment’s ground and the stm32’s ground. Perhaps tens of millivolts - not so much as will be noticed for logic signals, but slow-moving analog ramps can be seen as logic high one moment and low the next.

    AZorn.1Author
    Graduate
    February 9, 2024

    Thank you Danish1,
    i have already considered that this is a problem and did some tests to contradict this theory.

    also without all this equipment, the problem occurred (otherwise i wouldn't have inspected this in that detail grade), so we can be sure, this issue is not caused by different ground levels, voltage drop on different grounds or floating grounds or similar.


    To clarify:

    I don't need an workaround or a solution for the button issue.

    I need to figure out, if the STM32H7 (and its peripherals) are stable and robust enough to fulfill my automotive graded very harsh industrial environment requirements. And if it is that easy to disturb the Schmitt-Triggers inside, in this laboratory conditions, i do not want to find out, what other *** will happen in real life at our countless customers.

    I am still hoping that there is something i am just missing so far.

    AZorn.1Author
    Graduate
    February 9, 2024

    Question to ST:

    is there a chance, that i figured out a bug in silicone, so that the integrated Schmitt Triggers on some pins getting deactivated, by doing data transfer on FMC?

     

    Technical Moderator
    February 9, 2024

    Hello @AZorn.1 

    Did you succeed to reproduce on discovery board. If so, please don't hesitate to share with us here in public or in private message your software and your hardware setup preferably on our reference board. This would be helpful to investigate further this issue. For now, unfortunately, we cannot confirm an issue linked to the chip.

    AZorn.1Author
    Graduate
    February 9, 2024

    Hello F.Belaid,

    thank you.

    I had a look on the H735-disco schematics and found out, that on this board there is no external SD-RAM or something else connected to the FMC Interface. So i can't easily port my software to this hardware.

    Maybe i can figure out other issue-triggers, which i can activate also on the Disco board.

     

    By now, i can run my/this software in the discoBoard, but without the FMC-Access. And of course EXTI on other pins, because only a few pins are unused at this board.

     

    Graduate II
    February 9, 2024

    Your PCB screenshot looks quite good and professional, but there are many close copper traces, so I can imagine there could be some crosstalk. Especially if the debouncing Rs & Cs are close to the buttons (where they should be), but the deciding factor might be what's happening at the MCU pin (maybe try some stronger / weaker external pull-ups).
    Just to make sure, every pcb signal layer has a neighbouring low impedance plane layer connected to ground or VCC? No gaps in the planes?

    Until now I have used quite a few ST test boards, incl. Nucleo-H723 and H735-disco, I never had these problems, and some of the boards have a terrible layout (due to the fact that a Nucleo's pins have many options), and my firmware did quite some stuff (ETH, OSPI HyperRam, SAI, I2S).

    Have you checked that you are not double-using some EXTI / FMC pins?

    I cannot imagine that this is a STM32 problem. But who knows...

    AZorn.1Author
    Graduate
    February 9, 2024

    Hello LCE,

    thank you for your valuable input. Crosstalk from other pins was also one of my attempts so i used my (of course not the fastest one) to inspect the problem-trace.

    Coupling was AC to filter the DC-part and to bring the signal down to GND, for better scoping. GND-Spring to have lowest possible GND-Loop (only few mm) to reduce extra noise due to the scope probe. And i scoped the via, directly near to the BGA, not to miss anything.

     

    first one is without FMC-communication

    scope_3.png

    second one with running FMC-communication (Be careful, it looks worse than it is due to the "Persistance-overlay" view of the scope.)

    scope_2.png

    so, of course the noise level rises, but all within +/-20mV compared to the 200mV pin-hysteresis, i would say, this can not be the cause. It should be an easy one for the Schmitt trigger to filter this small noise.

    Since the processor isn't the latest, I would be surprised if there was a defect in the silicon. And above all, no one has had similar problems with it before, so far google knows it ;-).

     

    I'm sure this use case is very contrived and not a real problem, but I don't know what to do now. If I design another evaluation board, I have no idea what to change to prevent such problems, or how to ensure that no more/other pin sampling problems occur, since any input pin/peripheral can be affected.

     

     

    Super User
    February 9, 2024

    Looks like some combination of cross-talk and internal noise to me.

    Would be interesting to see if you can change the EXTI pins to ADC at very high sample rate and see if their input also varies considerably more when FMC is going. Probably they will.

    Layout is good, perhaps decoupling caps could be closer.

    What are your RC values? If you use a lower-pass filter, do these jumps disappear?

    > I have no idea what to change to prevent such problems, or how to ensure that no more/other pin sampling problems occur, since any input pin/peripheral can be affected.

    Keep in mind input pins have a relatively large uncertainty zone (from 30% to 70% of VDD), way more than 200 mV. 40% of 3.3 V is 1.32 V. Might not be that big of a problem. Taking digital inputs on slow moving analog signals is not a very common use scenario.

    Technical Moderator
    February 12, 2024

    Hello @AZorn.1 

    Try to monitor the VDD supply during FMC to check for noise due to simultaneous switching noise (SSN).

    Graduate II
    February 13, 2024

    Just to make sure:

    scope measurements are done without the ~10cm GND clip, but with the ground / spring / tip directly besides the "hot" contact?

    AZorn.1Author
    Graduate
    February 13, 2024

    @LCEyes, with the spring-tip, to have GND loop as small as possible.
    :thumbs_up:

    Graduate II
    February 13, 2024

    Ah, spring-tip is the official name? Never used that in english... :grinning_face_with_sweat: