Hello everyone,
I am not able to use the KBI pins available on MKE04Z128VLK4 as external interrupts. Only one pin at a time is working but if I try to use two of them together, the interrupt does not occur.
#define EXAMPLE_KBI KBI1
#define EXAMPLE_KBI_PIN1 30
#define EXAMPLE_KBI_PIN2 31
volatile bool g_keypress = false;
void delay(void)
{
volatile uint32_t i = 0;
for (i = 0; i < 800000; ++i)
{
__asm("NOP"); // delay
}
}
void KBI1_IRQHandler(void)
{
if (KBI_IsInterruptRequestDetected(EXAMPLE_KBI))
{
/* Disable interrupts. */
KBI_DisableInterrupts(EXAMPLE_KBI);
/* Clear status. */
KBI_ClearInterruptFlag(EXAMPLE_KBI);
g_keypress = true;
KBI_EnableInterrupts(EXAMPLE_KBI);
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
int main(void) {
/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
kbi_config_t kbiConfig;
PORT_SetFilterSelect(PORT, kPORT_FilterKBI1, kPORT_BUSCLK_OR_NOFILTER); /* Filter Selection for Input from KBI0: 0x01u */
gpio_pin_config_t config = {
kGPIO_DigitalOutput, 0,
};
GPIO_PinInit(kGPIO_PORTD, 1U, &config);
PORT_SetPinPullUpEnable(PORT, kGPIO_PORTH, 7, 1); //Pull up pin 7
PORT_SetPinPullUpEnable(PORT, kGPIO_PORTH, 6, 1);//Pull up pin 6
kbiConfig.mode = kKBI_EdgesDetect;
kbiConfig.pinsEnabled = (1 << EXAMPLE_KBI_PIN1) | (1 << EXAMPLE_KBI_PIN2);
kbiConfig.pinsEdge = (1 << EXAMPLE_KBI_PIN1) | (1 << EXAMPLE_KBI_PIN2); // Rising edge.
// kbiConfig.pinsEnabled = (0xC0000000) ;
// kbiConfig.pinsEdge = (0xC0000000) ; // Rising edge.
KBI_Init(EXAMPLE_KBI, &kbiConfig);
while(1) {
if (g_keypress)
{
g_keypress = false;
delay();
GPIO_PortToggle(kGPIO_PORTD, 1u << 1u);
}
}
return 0 ;
}
I also attached the complete project as well.
I am using KBI1 but the same is happening if I use KBI0 as well.
I want to use atleast 5 buttons for this chip as external interrupts. Could you let me know it can be done for this chip.
Thanks
Solved! Go to Solution.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi
The KBI allows multiple interrupts to be configured and as long as only one is detected at a time all works. However, if one input is detected all others are blocked, meaning that ONLY ONE can be detected at a time. This is the way that the key board controller operates, which makes it unusable in some applications needing multiple external interrupts to be recognised together.
If you can get one interrupt at a time but not a second when the first is still active it is thus 'normal'. If you can't get any when configuring more that one it is a coding error.
Try the key board interface in the uTasker project for operational multiple inputs if in doubt (it also simulates the KE04 and KBI - and is available as free open source on Git Hub)
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
Kinetis KE:
- http://www.utasker.com/kinetis/FRDM-KE02Z.html
- http://www.utasker.com/kinetis/FRDM-KE02Z40M.html
- http://www.utasker.com/kinetis/FRDM-KE04Z.html
- http://www.utasker.com/kinetis/FRDM-KE06Z.html
- http://www.utasker.com/kinetis/FRDM-KE15Z.html
For less questions and faster, cheaper developments: try uTasker for Kinetis
Hi Mark,
Thanks for the reply!
I found this link and will go through in detail. (uTasker-Kinetis/kinetis_KBI.h at master · uTasker/uTasker-Kinetis · GitHub )
I was trying to configure 5 push buttons as KBI interrupts. All of them will be connected to one KBI (0 or 1) but at one time only one button will be pressed.
In my codeI I initiazlized pin 7 of port H as interrupt and it worked properly then I changed the pin to 6, connected necessary hardware and it also worked.
But when I initialized both the pins the code never reaches the ISR. Could you kindly check my code where I might be going wrong in the initialization of the pins.
Thanks,
Hi
I configured 5 x KBI interrupts in the uTasker project using the following code and found them all to work.
INTERRUPT_SETUP interrupt_setup; // interrupt configuration parameters
// Keyboard
//
interrupt_setup.int_type = KEYBOARD_INTERRUPT; // define keyboard interrupt rather than IRQ
interrupt_setup.int_priority = PRIORITY_KEYBOARD_INT; // interrupt priority level
interrupt_setup.int_port = KE_PORTH; // the port that the interrupt input is on (KE_PORTE, KE_PORTF, KE_PORTG and KE_PORTH are the same)
interrupt_setup.int_port_bits = (KE_PORTH_BIT3 | KE_PORTH_BIT4 | KE_PORTH_BIT5 | KE_PORTH_BIT6 | KE_PORTH_BIT7); // the IRQs input connected (to same irq)
interrupt_setup.int_handler = test_irq; // handling function
interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON); // interrupt is to be falling edge sensitive
fnConfigureInterrupt((void *)&interrupt_setup); // configure interrupt
I then checked the register setup in the KBI1 (the one used for the 5 inputs defined)
#md 4007a000 l 4
Memory Display
0x4007a000 f8000000 00000000 00000012 00000000 ................
That is
KBI1_PE = 0xf8000000;
KBI1_ES = 0x00000000;
KBI1_SC = 0x00000012;
KBI1_SP = 0x00000000; {this is read-only}
If you check the values that you are actually writing to the registers involved (there are only two registers involved) you can possibly see your error. If there is no error it may be that there is an issue with entering the interrupt in the NVIC (but this is less likely if you have it working on single inputs).
One thing that you could check is that just after enabling each KBI interrupt it is necessary to clear any false interrupts, that I do with (ptrKBI points to the KBI controller in question):
ptrKBI->KBI_SC |= (KBI_SC_RSTKBSP | KBI_SC_KBACK | KBI_SC_KBSPEN); // clear any false interrupts and clear flagged interrupts - real KBI_SP register enable
Regards
Mark
The code worked after making KBI1_ES = 0x00000000;
Earlier I was entering the same values for KBI1_PE and KBI1_ES ( i.e. 0xC0000000 ), to detect a rising edge. But falling edge is also alright for me.
Thank you so much!
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------