Pin interrupt clear not clearing

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Pin interrupt clear not clearing

1,410 Views
perencia-wc
Contributor II

I have a routine to enable external interrupts and I want to discard any pending ones before enabling them again.

That's the code I use (MCUXpresso IDE v11.5.0 [Build 7232] [2022-01-11], LPC 4330 M4, O3 compilation):

 

Chip_PININT_ClearIntStatus(LPC_GPIO_PIN_INT, PININTCH(pinint_index));
NVIC_ClearPendingIRQ(nvic_name);
NVIC_EnableIRQ(nvic_name);

 

The problem is that pending interrupts keep triggering as soon as I enable the irq in the NVIC, even though I've cleared them.

Introducing a delay or a __DSB between Chip_PININT_ClearIntStatus and NVIC_ClearPendingIRQ solves the problem, but I'd like to understand what's going on here.

These are the assemblies produced without and with the DSB

With DSB

 

00000000 <xxx>:
   0:	4b0a      	ldr	r3, [pc, #40]	; (2c <xxx+0x2c>)
   2:	2201      	movs	r2, #1
   4:	fa02 f000 	lsl.w	r0, r2, r0
   8:	6258      	str	r0, [r3, #36]	; 0x24
   a:	f3bf 8f4f 	dsb	sy
   e:	094b      	lsrs	r3, r1, #5
  10:	009b      	lsls	r3, r3, #2
  12:	f103 4360 	add.w	r3, r3, #3758096384	; 0xe0000000
  16:	f503 4361 	add.w	r3, r3, #57600	; 0xe100
  1a:	f001 011f 	and.w	r1, r1, #31
  1e:	fa02 f101 	lsl.w	r1, r2, r1
  22:	f8c3 1180 	str.w	r1, [r3, #384]	; 0x180
  26:	6019      	str	r1, [r3, #0]
  28:	4770      	bx	lr
  2a:	bf00      	nop
  2c:	40087000 	.word	0x40087000

 

Without DSB

 

00000000 <xxx>:
   0:	094b      	lsrs	r3, r1, #5
   2:	009b      	lsls	r3, r3, #2
   4:	2201      	movs	r2, #1
   6:	f103 4360 	add.w	r3, r3, #3758096384	; 0xe0000000
   a:	f001 011f 	and.w	r1, r1, #31
   e:	fa02 f101 	lsl.w	r1, r2, r1
  12:	f503 4361 	add.w	r3, r3, #57600	; 0xe100
  16:	fa02 f000 	lsl.w	r0, r2, r0
  1a:	4a03      	ldr	r2, [pc, #12]	; (28 <xxx+0x28>)
  1c:	6250      	str	r0, [r2, #36]	; 0x24
  1e:	f8c3 1180 	str.w	r1, [r3, #384]	; 0x180
  22:	6019      	str	r1, [r3, #0]
  24:	4770      	bx	lr
  26:	bf00      	nop
  28:	40087000 	.word	0x40087000

 

As you can see, without __DSB the stores are all delayed until the end. That makes me think if there are some cycles we need to wait for the clearing of the interrupt to be effective. I've searched the user manual and the code examples with the IDE but couldn't find anything.

I understand it can also be some memory reordering in the micro, but I'm not sure. So, what I'm looking for here 1) an explanation for that behaviour and 2) if there's any recommended (or mandatory) way of clearing the interrupt flags to avoid the problem.

Thanks!

 

Tags (1)
0 Kudos
Reply
1 Reply

1,392 Views
ErichStyger
Specialist I

It is maybe related to this:

https://community.nxp.com/t5/Kinetis-Microcontrollers/ARM-errata-838869/m-p/1029107

point is that the M4 has a silicon bug, basically requiring a DSB at the end of the ISR.

So this might be what you need to do?