cancel
Showing results for 
Search instead for 
Did you mean: 

Accidental EXTI-Interrupts on STM32H735

AZorn.1
Associate III

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, ...)

30 REPLIES 30
FBL
ST Employee

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.

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.

AZorn.1
Associate III

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.

TDK
Guru

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?

If you feel a post has answered your question, please click "Accept as Solution".
AZorn.1
Associate III

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.

 

Bob S
Principal

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.

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.

Bob S,

sorry, i think speeding up the ramp will just reduce the vulnerable time window and lower the probability of the issue, but not solve it in the root case, this is not the solution i prefer.

In my case, as you can see in the screen shot above, every power line is C-coupled properly, alone in the showed area around the mcu, there are about 15 pcs. 100nF Caps on 3V3. And if the issues are mcu internal and can not be solved by better filtering of the 3V3 (or by other solutions, of course), the STM32H7 is not usable in my application.

Yes, i can generate a square wave, but as mentioned above, i want to solve/identify the problem, not only make an workaround. That is essential for me in this phase of evaluating different mcu vendors.

Using the EXTI for the buttons now, is just for evaluation purpose, in future it should be used to synchronize an other FPGA, so a perfectly working EXTI is highest priority in this application.

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.1
Associate III

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?