Correct me if I'm wrong but this is what I have understood so far:
If KBIE is set and pin for pushbutton is set as input, then KBF flag will be set to 1 on switch press, hence performing interrupt request.
My question is, how do I, or rather, what is the correct way to execute the ISR only once, and not like it's in an infinite loop once KBF is set?
For example I want to switch to toggle the LED. Currently it toggles very fast once switch is pressed, and doesn't stop doing so once the switch is released. Although I can think of a workaround of executing the ISR only once using if(once == true) or a loop that runs only once, but is that how people usually go about doing this? Plus if I do it this way how do I know how long switch is pressed or what if I want to execute ISR only on switch release?
The other question is, what is Rising and Falling-edge? Please explain keeping in mind I'm very new to embedded & hardware programming.
When the pin us used as a KBI, an interrupt will be generated when the input to the pin has changed (depending on setup). In the interrupt, all you need to do is dis-able the interrupt and it won't happen again.
Keep in mind it won't ever happen again if you don't enable it again somewhere else in the code.
Rising edge -> the input goes from low to high falling edge -> the input goes from high to low rising and falling is the combination of both.
When you operate a mechanical switch into the input of something like a microcontroller that can read the input quite fast, it will see the input go on and off perhaps many times instead of just one off to on transition. This is called switch bounce. We use a technique called switch debounce to combat this. Basically switch debounce is detecting the first transition then deliberately ignoring the input for a period of time. This time should be long enough that the worst case bounce is already over and the input has settled to the "on" state. When using the KBI the easiest thing is just to disable KBI interrupts on the first interrupt and only re-enable them after this time has expired.
On the subject of debounce, use the forum search engine below - I recall this has been discussed on previous occasions. As Witztronics has suggested, within the interrupt service routine (ISR), disable further KBI interrupts for that pin, carry out the action associated with the keypress, and clear the interrupt flag. If the required action is too lengthy, it is probably better to set a user flag within the ISR, and to poll for the flag within the main loop.
Now the debounce part. Typically, you will now need to wait 10 - 50 milliseconds before re-enabling the KBI interrupt, ready for the next keypress. While you could enter a simple software timing loop, this would prevent anything else from occurring during the wait period (unless you were to poll for specific events during this period).
Probably a better way is to setup a TPM module so that overflow interrupts will periodically occur. You can then configure your debounce delay to be an integral number of overflow periods. You will need a byte size counter (global) variable for each switch contact, to handle the debounce timing. Within the KBI ISR, set the counter to the required delay value. Then, within the TPM overflow ISR do the following:
Test whether the counter is non-zero.
If so, decrement the counter.
Now, again test whether the counter has reached zero.
If so, re-enable the KBI interrupt.
Using this method, the debounce will be transparent to the main loop.
Whether you need to interrupt on a rising or a falling edge will be determined by the connection configuration for the pushbutton. Assuming that the contact closes when the button is pressed, if the switch is connected between the input pin and ground, you will require falling edge setup. If the switch is returned to Vdd instead of ground, the rising edge would be applicable.
What about the fact that within the KBI ISR, other interrupts will be disabled including the TPM interrupts used for debounce - or does one re-enable them within the KBI ISR (isn't this a bit risky though?)
Be aware that it may also be necessary to allow for contact bounce on switch release. If you simply debounce the closure you can run the risk of the release being counted as an additional press. Confirming the switch state, by a poll, at the end of the debounce time can help mitigate against this. Also be wary of using a full debounce on release that may allow the switch to get "stuck" on.