Page 1 of 1

Multiple interrupts when pressing a button.

Posted: Fri Nov 13, 2015 11:25 am
by mindentropy
Hi,

I am getting multiple interrupts when I press a button. I don't have de-bouncing implemented. Is this usually a problem if I don't have de-bouncing logic?

I am using an ARM9TDMI S3C2440 Samsung IC. My interrupt handling mechanism is as follows:

Code: Select all

.globl do_handle_irq
do_handle_irq:
	sub lr,lr,#4 
	stmfd sp!, {r0-r12,lr} @Save r0-r12 and lr. 
	bl handle_irq	
	ldmfd sp!, {r0-r12,pc}^ 
	
The handle_irq is a 'C' function. In it I have the following steps.

Code: Select all

	offset = readreg32(INTOFFSET_REG(INT_BA));
	mask_interrupt(INT_BA,BIT(offset));
	interrupt_handler_jmp_table[offset]();
	clear_interrupt_source_pending(INT_BA,BIT(offset));
	clear_interrupt_pending(INT_BA,BIT(offset));
	unmask_interrupt(INT_BA,BIT(offset));
The above code first masks the interrupt. Then it jumps to the particular interrupt handler. Next it clears the source pending interrupt and clears the interrupt pending flag. After this it unmasks the particular interrupt.

Am I on the right track?

Re: Multiple interrupts when pressing a button.

Posted: Fri Nov 13, 2015 1:13 pm
by BASICFreak
Do you send an acknowledge to the interrupt controller?

It also could be a press then a release INT.

What scancode(s) does each of the INTs have?

Re: Multiple interrupts when pressing a button.

Posted: Fri Nov 13, 2015 1:48 pm
by Brendan
Hi,
mindentropy wrote: I am getting multiple interrupts when I press a button. I don't have de-bouncing implemented. Is this usually a problem if I don't have de-bouncing logic?
I'm not sure what you're doing or how; but...

If you have a button without any de-bouncing you should expect "bounces" (multiple interrupts), especially with a cheaper button/switch. As far as I can tell this is "safe" (electrically), and you could do de-bounce in software (e.g. when the first interrupt occurs set a timer, and don't allow that IRQ to happen again until the timer expires).

However it could also be completely unrelated to de-bounce (e.g. for all I know you could have a button connected to an external interrupt and the "external interrupt control register" is configured for level trigger and not edge trigger).

I don't know enough about ARM to guess if masking and unmasking the IRQ in the interrupt controller makes sense; but I'd be tempted to assume that (if the IRQ priority arbiters are configured properly) you might only need to clear the source pending flag then interrupt pending flag. If you are using a timer to do "software de-bounce" you would want to mask, then clear the pending flags, then unmask later on when the timer expires.


Cheers,

Brendan

Re: Multiple interrupts when pressing a button.

Posted: Sat Nov 14, 2015 2:59 am
by mindentropy
@BASICFreak

Do you send an acknowledge to the interrupt controller?
No I don't ack the interrupt controller. I don't think there is a ACK in the interrupt controller except clearing all the masking and pending interrupts.
It also could be a press then a release INT.
I have kept the interrupt trigger to only falling edge. The pins are pulled up.
What scancode(s) does each of the INTs have?
I am not sure what you mean by scan codes but the right interrupt flags are set in the interrupt pending, source pending and GPIO external interrupt.

@Brendan,
If you have a button without any de-bouncing you should expect "bounces" (multiple interrupts), especially with a cheaper button/switch. As far as I can tell this is "safe" (electrically), and you could do de-bounce in software (e.g. when the first interrupt occurs set a timer, and don't allow that IRQ to happen again until the timer expires).
The buttons are cheap alright. I tried some experiments i.e. I pressed the button and released it after certain seconds and I don't get multiple interrupts. The multiple interrupts are happening when I press and release in an instant. Looks more like de-bouncing but want to be sure about this. There is a filter in the GPIO which seems to trigger an interrupt only after 90ns but I feel it is useless.
However it could also be completely unrelated to de-bounce (e.g. for all I know you could have a button connected to an external interrupt and the "external interrupt control register" is configured for level trigger and not edge trigger).
I have configured it to falling edge. The buttons are pulled up.
I don't know enough about ARM to guess if masking and unmasking the IRQ in the interrupt controller makes sense; but I'd be tempted to assume that (if the IRQ priority arbiters are configured properly) you might only need to clear the source pending flag then interrupt pending flag.
Could you please explain why masking,unmasking the IRQ in the interrupt controller does not make sense?

Possible bug fix and solution
In the external interrupt handler I was clearing the "external interrupt pending" before my interrupt logic. I have rearranged such that the clearing of "external interrupt pending" is done after I finish my logic. Testing this does not give me multiple interrupts. I removed the interrupt masking as you suggested and found that the masking is pointless with the current changes.

Re: Multiple interrupts when pressing a button.

Posted: Tue Nov 17, 2015 10:09 am
by intx13
mindentropy wrote: Possible bug fix and solution
In the external interrupt handler I was clearing the "external interrupt pending" before my interrupt logic. I have rearranged such that the clearing of "external interrupt pending" is done after I finish my logic. Testing this does not give me multiple interrupts. I removed the interrupt masking as you suggested and found that the masking is pointless with the current changes.
That indicates that what you're seeing is probably bounce. By clearing the interrupt at the end of the handler, any bouncing that occurs while the handler executes is ignored (because the interrupt flag is already set). When you clear the flag at the top of the handler, any bounce that occurs while the handler executes causes the interrupt flag to be set again, and when the handler returns, it immediately gets called again.

If the duration-of-execution of the handler is sufficient to debounce the switch, your fix might be sufficient. A more robust solution would use a timer, like Brendan suggested.