Ruth Hendrix

KBI on GT60

Discussion created by Ruth Hendrix Employee on Jan 24, 2006
This message contains an entire topic ported from a separate forum. The original message and all replies are in this single message. We have seeded this new forum with selected information that we expect will be of value to you as you search for answers to your questions.
Posted: Thu Oct 13, 2005 10:37 pm    
I'm a complete newbie to embedded programming so please excuse me.

I want to interface the GT60 to a chip via SPI, unfortunately I'm going to use a module that contains both the GT60 and the MC13192, and that module does not expose the MCU's h/w SPI pins. So I will have to resort to using a software SPI using the IO pins.
The problem is I also want to listen for a couple of buttons and external events on the other KBI pins.
I'm figuring I'll listen for any interrupt generated on KBI, but can't figure out if it infact has some mask I can use to distinguish which pin generated the irq.
Can any one give me an idea of how to figure out which I/O pin generates an event?
Posted: Fri Oct 14, 2005 6:34 am    
If the external chip can operate as a SPI slave device, the software SPI routines will be simpler, and you will usually not need an interrupt for SPI operation. In this event, the interrupt would only be needed for the buttons and external events.

Setting appropriate bits within the KBI1PE register would determine the keyboard interrupt inputs, so you can restrict interrupts to the buttons, etc. To determine the button that caused a particular interrupt, you can simply read and test the state of the relevant Port A bits from within the keyboard ISR. The data direction for these bits would need to be configured as inputs.

Posted: Fri Oct 14, 2005 4:53 pm    
So I was finally able to get a KBI interrupt, but needed to clarify a couple of things.

Firstly here's my setup :

On app startup I do the following:

// enable interrupts on KBI1SC

// this happens to be on the MC13192Sard board, hence these pins are tied to the pushbuttons (PB0 and PB1)

// enable pullup on pin

//enable direction = input

I added a vector to service the isr, and the isr looks like this
interrupt void kbd_isr (void)
KBI1SC_KBACK = 1; // Disable kbdinterrupt

if (PTAD_PTAD2 = 0) // Push button 1 was pressed
{ LED1 ^= 1;}
if (PTAD_PTAD3 = 0) // push button 2 was pressed
{ LED2 ^= 1;}


When i hit either of the buttons, the KBI does get called however the weird thing that happens is it also fires irq_isr() the handler for the IRQ pin. (i'm quite sure no other irq fires exactly at the same time - the MC13192 controls this pin and at those times I don't think it fires an interrupt)
Any idea whats happening?
Posted: Sat Oct 15, 2005 12:04 pm    

I am not sure why pressing a buttons should also cause entry to irq_isr() since there are separate interrupt vectors for the device you are using. Does the irq flag become set? How often does the MC13192 normally cause an interrupt? I might expect that irq_isr() would ignore a spurious interrupt by first testing that the interrupt flag is set, and immediately exiting if not.

It appears that your kb_isr() may not operate in the manner you intend because no allowance is made for "bounce" of the mechanical key switches. Assuming the interrupt is edge-sensitive only, as required in this case, kb_isr() may be entered multiple times for a single keypress. Additionally, there is no test to verify that flag KBF is actually set - to filter possible spurious interrupts.

You will need to disable keyboard interrupts for at least a typical de-bounce period of 20-50 milliseconds. You will also need to take into account further key bounce on release of the key switch.

With the presence of the MC13192, you will most likely need to exit the ISR as quickly as possible. This will require that de-bounce delay be within the main program loop, rather than the ISR. One way to handle this is to set a flag within the ISR, and test the flag, and eventually clear it, within the main program loop.
A modified ISR might be:

interrupt void kbd_isr (void)
if (KBI1SC_KBF) {
   KBI1SC_KBIE = 0;  // Disable further keyboard interrupt
   KBI1SC_KBACK = 1; // Clear interrupt flag
   kb_flag = 1;      // Flag keypress pending

Then within the main program loop the sequence might be:
1. Only if kb_flag is non-zero, do the following operations.
2. Wait de-bounce delay period.
3. Test for keyswitch #1 pressed - if so toggle LED1.
4. Test for keyswitch #2 pressed - if so toggle LED2.
5. Clear kb_flag and re-enable keyboard interrupt.