both KBI buttons on KE06

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

both KBI buttons on KE06

Jump to solution
1,370 Views
william_putnam
Contributor I

I'm using the MCUXpresso (v10.2.1) IDE to make software for my FRDM-KE06Z board. (SDK v2.4.1)

I have an application where I need to use both SW2 and SW3 to control two different actions. I've initialized them both as such:

kbi_config_t sKBIConfig;

sKBIConfig.pinsEnabled = 18000000;       //both SW2 and SW3

sKBIConfig.pinsEdge = 0;                        //falling edge

sKBIConfig.mode = kKBI_EdgesDetect;   //just on edges

KBI_Init(KBI1, &sKBIConfig);

KBI_ClearInterruptFlag(KBI1);

KBI_EnableInterrupts(KBI1);

In order to differentiate between the two buttons, I was thinking on using

KBI_GetSourcePinStatus(KBI1)

to read the source pin value in order to determine which button is being pressed. I'm doing it like this in the handler function:

if (KBI_IsInterruptRequestDetected(KBI1)){

        KBI_DisableInterrupts(KBI1);
        KBI_ClearInterruptFlag(KBI1);

        if (KBI_GetSourcePinStatus(KBI1) == 134217728){   //SW3

               //function1()

        }

       else if (KBI_GetSourcePinStatus(KBI1) == 268435456){   //SW2

               //function2()

        }

      KBI_EnableInterrupts(KBI1);

}

What I've noticed in breakpoints is that when the application first loads, if I stick to pressing only one of the two buttons, I'll get the proper return value from the source pin status function. But if I then press the other button, that same function returns a value of 402653184 (the values of SW2 and SW3 combined). And if I go back to pressing the button that I was pressing before, I'll still get 402653184. That value will stay the same no matter which button until I reset the application.

I'm not sure whether it's a matter of a flag not getting cleared properly. According to fsl_kbi.h, the clear interrupt flag function modifies base->sc, while the source pin status function is reading from base->sp. In addition, I was unable to find any information on how to properly "reset" the pins, as I'm not modifying arrays directly the way I'm doing it here.

Is there something I'm overlooking?

0 Kudos
1 Solution
1,106 Views
mjbcswitzerland
Specialist V

William

You need to read the interrupt source 'before' you reset it!

See the uTasker code:

    unsigned long ulFlags = KBI0_SP;                                     // read enabled interrupt flags
    KBI0_SC |= (KBI_SC_RSTKBSP | KBI_SC_KBACK);                          // clear flags and pending interrupt (note that subsequent edge sensitive interrupts are only accepted by the KBI when all other inputs have returned to their original state)
...now handle the flags...

Regards

Mark

View solution in original post

0 Kudos
7 Replies
1,106 Views
mjbcswitzerland
Specialist V

Hi William

I don't know the routines that you are using but beware that generally the KBI controller is not suitable for detecting more than one input at the same time: When a first input is active it blocks other inputs so they will not be recognised until the first is released.

Regards

Mark

0 Kudos
1,106 Views
william_putnam
Contributor I

Mark-

I should clarify. I’m not pushing both buttons at the same time. I’m pushing and releasing one button, pausing momentarily, and then pushing and releasing the other button. I’m clearing the interrupt flag, but is there something else I should be clearing as well?

-wp

0 Kudos
1,106 Views
mjbcswitzerland
Specialist V

Hi William

This is the code that clears the interrupt in the uTasker project's KBI driver (attached as reference or complete project available on GitHub - with KE06 and KBI simulation):

KBI0_SC |= (KBI_SC_RSTKBSP | KBI_SC_KBACK);                          // clear flags and pending interrupt (note that subsequent edge sensitive interrupts are only accepted by the KBI when all other inputs have returned to their original state)

Note that both KBACK and RSTBSP need to be written to '1' - maybe that is your problem?

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

0 Kudos
1,106 Views
william_putnam
Contributor I

Mark-

I've attached the relevant SDK header/resource files I'm using as reference. In fsl_kbi.h, the KBI_ClearInterruptFlag() function is defined as a static inline with one command:

base->SC |= KBI_SC_KBACK_MASK;

Going by your earlier suggestion, modifying this line to:

base->SC |= (KBI_SC_RSTKBSP_MASK | KBI_SC_KBACK_MASK);

will cause KBI_GetSourcePinStatus() to return a value of 0 every time, regardless of which button is pressed.

Furthermore, KBI_SC_RSTKBSP_MASK and KBI_SC_KBACK_MASK evaluate respectively to 0x20U and 0x4U.

The former is also only used once in KBI_Init():

    /* Clear any false interrupts. */
    scReg = KBI_SC_KBACK_MASK;
#if defined(FSL_FEATURE_KBI_HAS_SOURCE_PIN) && FSL_FEATURE_KBI_HAS_SOURCE_PIN
    /* Reset kbi sp register. */
    scReg |= KBI_SC_RSTKBSP_MASK | KBI_SC_KBSPEN_MASK;
#endif
    base->SC = scReg;

-wp

0 Kudos
1,107 Views
mjbcswitzerland
Specialist V

William

You need to read the interrupt source 'before' you reset it!

See the uTasker code:

    unsigned long ulFlags = KBI0_SP;                                     // read enabled interrupt flags
    KBI0_SC |= (KBI_SC_RSTKBSP | KBI_SC_KBACK);                          // clear flags and pending interrupt (note that subsequent edge sensitive interrupts are only accepted by the KBI when all other inputs have returned to their original state)
...now handle the flags...

Regards

Mark

0 Kudos
1,106 Views
william_putnam
Contributor I

Mark-

I've tried clearing the flags after the read as you've said, and now it works. I did, however, have to edit the KBI_ClearInterruptFlag() function in fsl_kbi.h to

base->SC |= (KBI_SC_RSTKBSP_MASK | KBI_SC_KBACK_MASK);

in order to make it work. Thanks for your help!

-wp

0 Kudos
1,106 Views
mjbcswitzerland
Specialist V

William

It sound like you may be working with some code from a KE04 (or similar) since they have a slightly different keyboard controller that doesn't need the RST flag cleared. Or maybe there is another cover function to reset the other flag(?)

If in doubt just check the uTasker code since it is an encapsulated solution proven on all types.

Regards

Mark

0 Kudos