LC60 -> KBI1 doesn't work!

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

LC60 -> KBI1 doesn't work!

3,941 Views
BasePointer
Contributor II
Hi,
 
I'm using MC9S08LC60. Its KBI1 module doesn't generate interrupt for me. All interrupts such as SCI, LCD, RTI work but KBI1 doesn't :smileysad: KBI1SC_KBF flag is never asserted.
 
Here is my KBI1 initialization:
Code:
  KBI1ES = 0b10000000;  // PWR_MON-RisingEgde, M_BTN-FallingEgde,
                        // D_BTN-FallingEgde, UST-FallingEdge, KLMS-FallingEdge
  KBI1PE = 0b11011000;  // PWR_MON, M_BTN, *D_BTN*, UST, KLMS
  KBI1SC = 0b00000100;  // Edge detect, KBIIE = 0
  KBI1SC_KBACK = 1;
  KBI1SC_KBIE = 1;

 

Can you check for me please KBI1 has a bug?

SDID of the LC60 that I use: Rev=1, ID=12

Thank you.


 
 
 
 
Labels (1)
0 Kudos
14 Replies

772 Views
BasePointer
Contributor II
Hi again,
 
My actual project work on PIC18LF4620. I want to port whole project to MC9S08LC60.
I have four port-on-change interrupt at pic side to wake up in sleep. 
At freescale side, I wanted to change them with KBI interrupt.
But as learned, they are not exactly same. For example, I have two buttons to wake up.
One of them is connected to KBI1PE2 and the other is to KBI1PE3. Both of them are pulled up to VDD via a external resistor 510K and pulled down to GND via a 100nF to prevent bouncing. KBI is configured to catch falling edge of the buttons.
 
If I press the first button (click event), KBI interrupt works well.
If I press the second button (click event), KBI interrupt works well.
If I press the first button but don't release it (onDownEvent), KBI interrupt works well.
At this state, If I press the second button (click event), KBI interrupt doesn't work!!
 
Namely, when KBI1PE2=0, KBI can't catch the falling edge of KBI1PE3 pin that is the second button. So, as a result, MCU can't wake up.
 
This is not a big problem for buttons. But in my application, I have also two switchs that indicate cover states of our product. Cover states can be any thing(first may be one [opened state], the other may be zero [closed state]) at any time. and the KBI doesn't work at that state.
 
How can I solve this problem?
 
Thank you.
0 Kudos

772 Views
bigmac
Specialist III
Hello BP,
 
To handle multiple, overlapping key presses using the KBI module might be possible with the following approach -
 
Whenever a key is pressed, it generates an interrupt that wakes up the MCU.
 
Within the ISR code, the pressed key would be ascertained and action taken to flag the event.  Interrupts would then be disabled for that key only, before exiting the ISR.  You might also start a debounce delay period within the ISR, in lieu of your CR input filter, (but don't wait until timeout occurs before exiting the ISR).
 
With each interrupt disabled while the key remains pressed, this should allow other keys to be sensed, and to generate new interrupts.
 
From within main(), or an associated function,  you might then periodically test, firstly for completion of the debounce timeout period, and after this has occurred, for the key being in a released state.  Only after the key has been released would the interrupt be re-enabled for that particular keyswitch.
 
You should not re-enter stop mode until all keyswitches have been released (and the KBI interrupt has been re-enabled for all keyswitches).
 
Regards,
Mac
 
0 Kudos

772 Views
peg
Senior Contributor IV
Hi,
 
The method proposed by Mac above does indeed work! I use a similar method in a real world application. It has some limitations though which are application dependant. In my application none of these cause any problem, as for this one I don't know.
 
0 Kudos

772 Views
BasePointer
Contributor II
Hi again to all,
 
Such as peg mentioned previously, unfortunately this is normal activity of the KBI module :smileysad:
We can see it on Figure 7-2. Keyboard Interrupt (KBI) Block Diagram in the LC60 Datasheet.
I have changed KBI module to detect "level" and reconfigure KBI1ES register in interrupt routine.
Now, the code exactly works like PIC's on-change interrupt and all pins are independent.
 
Code:
  PTADD = 0;  KBI1SC = 0b00000100;  // level detect, KBIIE = 0  KBI1PE = 0b11011000;  // PWR_MON, M_BTN, *D_BTN*, UST, KLMS  KBI1ES = ~PTAD;  KBI1SC_KBIE = 1;  EnableInterrupts;      while(1)  {    __asm stop;    PTCD_PTCD2 = !PTCD_PTCD2;  // toogle BACKLIGHT to debug  }interrupt vNum_Vkeyboard1 void intKBI1(void){  unsigned char dummy;    dummy = PTAD;  KBI1ES = ~dummy; // change level to detect    KBI1SC_KBACK = 1;}

 
 
Thank you su much for your helps.
0 Kudos

772 Views
bigmac
Specialist III
Hello BP,
 
Your choice to change the edge select bit (instead of the pin enable bit), once a keypress has been detected, may have an unintended side effect.  This is because the internal pull-up resistor for a negative edge, will automatically become a pull-down resistor when a positive edge is selected.
 
The value of this internal resistor will lie somewhere between 17.5k and 52.5k, and will swamp your external pull-up resistor of 510k.  This will also affect the time delay for your debounce arrangement.
 
When the the internal pull-down occurs, you won't be able to sense the release of the keyswitch (assuming the switch is returned to ground), because there will be insufficient external pull-up to over-ride the internal pull-down - this would require a resistor value in the region of 2k2.
 
Regards,
Mac
 
0 Kudos

772 Views
BasePointer
Contributor II
Hi bigmac,
 
I don't use internal pull up/down resistors at all (PTAPE = 0). When I enabled the KBI module, are internal pull up/down resistors automatically activated? We can't use them because of power consumption.
 
To prevent unwanted interrupts during changing KBI Edge Select (KBI1ES) register, I acknowledge the KBI interrupt after changing KBIES register. That seems enough for my application.
 
Thank you,
BasePointer.
0 Kudos

772 Views
bigmac
Specialist III
Hello BP,
 
It appears that the LC60 device permits the pullups to be enabled or disabled when the KBI function is active.  However, this is not true for all MCU types.  For some, the pullups are automatically enabled whenever the KBI function is enabled.  You don't get to choose.
 
Regards,
Mac
 
0 Kudos

772 Views
BasePointer
Contributor II
Thank you for the information Mac!
I hope LC60 doesn't do it so.
0 Kudos

772 Views
peg
Senior Contributor IV
Hi,
If you are not using pullup/pulldowns then how does the input pin change to the opposite state when the switch opens?
 
0 Kudos

772 Views
BasePointer
Contributor II
Hi peg,
 
I'm using pullups. But they are external. I don't use internal pullups of the MCU due to power consumption.
See attached Sw.gif file.
 
Regards,
BP.
0 Kudos

772 Views
philip_drake
NXP Employee
NXP Employee
I have just verified that there is a unintended operation of the KBI as it relates to the port control registers.
 
This might account for the reported error you are seeing.
 
I found that the DDR of the port must be set to 0 (function as an input) for the port pull up/down enable function to work.
If the DDR = 1, setting the pin to an output the pull up/down function is disabled.
I suggest we make the following changes to the LC60 KBI chapter
 
We will be adding the following note to the introduction section of the KBI section.
 
"To use the input pins associated with the KBI the data direction register (PTxDD)  and the pull up enable register (PTxPE) for the corresponding KBI inputs must be set to inputs data direction (PTxDDn =0) and pull enable set (PTxPEn = 1)."  If the DDR is set for output then the pullup/pulldown is disabled.
 
Does this answer the issue your are having?
 
P. Drake
8- bit Applications Engineer
0 Kudos

772 Views
peg
Senior Contributor IV
Hi,
 
Is this really an "unintended operation" or just the way it normally is?
 
The pullup register is actually part of the GPIO and in that section it explicitly states that they will only function when the DDR is set for input.
 
Of course a further note in the KBI section would be welcomed.
 
Perhaps in the list of initialisation steps at 7.4.4
 
0 Kudos

772 Views
peg
Senior Contributor IV
Hi Base Pointer,
 
This is unfortunately how the KBI works. All enabled KBI pins must be at the unasserted level to detect an event on one of the pins. This is because although the level/edge selection is per pin the actual edge level detection is done after all the pins are OR'd together. Take a look at the block Diagram and the Functional Description.
This is perhaps why it is called a Keyboard Interrupt Module as it is of very limited use for much else. Once you use more than one pin they have to be coordinated.
 
0 Kudos

772 Views
freegeek
Contributor III
I have asked someone to have a look at this.
0 Kudos