External interrupts on KBI pins of MKE04Z

cancel
Showing results for 
Search instead for 
Did you mean: 

External interrupts on KBI pins of MKE04Z

Jump to solution
769 Views
shoaibshaikh
Contributor III

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

1 Solution
253 Views
Robin_Shen
NXP TechSupport
NXP TechSupport
Notice: After any edge is detected, all enabled keyboard interrupt input signals must return to the deasserted level before any new edge can be detected.
Edge-only sensitivity.png
 
before:
You have pull up these two KBI pins to high level and detected the rising edge.
Despite release one of the KBI pin but the other KBI pin is still in asserted level(high voltage). So new edge can not be detected.
 
now:
After making KBI1_ES = 0x00000000;
You have pull up these two KBI pins to high level and detected the falling edge.
So after release one of the KBI pin, these two KBI pins all return to the deasserted level(high voltage).  So new edge can be detected.

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

5 Replies
253 Views
mjbcswitzerland
Specialist V

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

253 Views
shoaibshaikh
Contributor III

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,

0 Kudos
253 Views
mjbcswitzerland
Specialist V

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

253 Views
shoaibshaikh
Contributor III

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!

254 Views
Robin_Shen
NXP TechSupport
NXP TechSupport
Notice: After any edge is detected, all enabled keyboard interrupt input signals must return to the deasserted level before any new edge can be detected.
Edge-only sensitivity.png
 
before:
You have pull up these two KBI pins to high level and detected the rising edge.
Despite release one of the KBI pin but the other KBI pin is still in asserted level(high voltage). So new edge can not be detected.
 
now:
After making KBI1_ES = 0x00000000;
You have pull up these two KBI pins to high level and detected the falling edge.
So after release one of the KBI pin, these two KBI pins all return to the deasserted level(high voltage).  So new edge can be detected.

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post