FRDM-KE06Z Change KBI Example Port

cancel
Showing results for 
Search instead for 
Did you mean: 

FRDM-KE06Z Change KBI Example Port

368 Views
stevenlutz
Contributor I

I have loaded the KBI example in MCUXpresso 11 for the Freedom Board KE06Z. However, it doesn't seem to work with the onboard switches on PTH3 and PTH4, butmaybe actually connected to H0?

I need to switch this over to using PTC0-7 and am unsure how to do that. 

I've tried changing the port in #define EXAMPLE_KBI_SIGNAL_INPUT_REF_GPIO kGPIO_PORTH to
#define EXAMPLE_KBI_SIGNAL_INPUT_REF_GPIO kGPIO_PORTC but this doesn't work. 

How do I switch from using port H to using all ports on PTC?
I'll also need to check to see which port triggered the interrupt. 


Labels (1)
Tags (1)
0 Kudos
5 Replies

215 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Steven Lutz,

What you need to change is the definitions:

#define EXAMPLE_KBI KBI0
#define EXAMPLE_KBI_PINS (10)

This #define EXAMPLE_KBI_SIGNAL_INPUT_REF_GPIO kGPIO_PORTH is used to generate a signal trigger KBI0_P10.

KBI example.png

FRDM-KE06Z KBI example.png

If you want to use the PTC7 as KBI function, then please change:

#define EXAMPLE_KBI KBI0
#define EXAMPLE_KBI_PINS (23)

KBI0.png

Best Regards,

Robin

 

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

0 Kudos

215 Views
stevenlutz
Contributor I

I'm hoping for information directly regarding the example code. 

0 Kudos

215 Views
mjbcswitzerland
Specialist V

Steven

I am sorry but I don't know anything about the sample code and I only have proven working code.
You can look at that to maybe better understand the operation and then you will be in a position to either modify the sample of code or correct it accordingly.

Regards

Mark

0 Kudos

215 Views
mjbcswitzerland
Specialist V

Steven

Without looking at the example code I think that the main problem that you have is quite obvious due to the fact that the inputs on PTH and PTC are not controlled by the same KBI. If you just change the port reference you may be causing the code to configure the peripherals functions correctly on the ports but the original code will be configuring the wrong KBI (as noted above, PTH pins are controlled by KBI1 and PTC pins are controlled by KBI0, which means that you at least need also to change the KBI accessed in the example code - and probably also apply clocks correctly at different locations in the project code as well, plus configure and enter different interrupt vectors).

This would mean that the example code is not generic (only works for the example pins) and needs to be completely understood and modified accordingly to the exact pins used. This is why example code is often inflexible and can result in lots of additional development to make what should be trivial changes.

If you look at the uTasker KBI code, which is are real solution rather than just an example, you will find that it uses a look up table to map pins, KBI inputs and KBI controllers so that the user can work on delivering products rather than fighting with data sheets and slipping project schedules. [If you are a professional developer, how much has it cost your company so far to switch KBI pins from PTH to PTC?]. For the KE06:

static const unsigned char _KBI[PORTS_AVAILABLE][32] = {
    {(_KBI_0 | 0),  (_KBI_0 | 1),  (_KBI_0 | 2),  (_KBI_0 | 3),  (_KBI_0 | 4),  (_KBI_0 | 5),  (_KBI_0 | 6),  (_KBI_0 | 7), // PTA0..PTA7
     (_KBI_0 | 8),  (_KBI_0 | 9),  (_KBI_0 | 10), (_KBI_0 | 11), (_KBI_0 | 12), (_KBI_0 | 29), (_KBI_0 | 30), (_KBI_0 | 15), // PTB0..PTB7
     (_KBI_0 | 16), (_KBI_0 | 17), (_KBI_0 | 18), (_KBI_0 | 19), (_KBI_0 | 20), (_KBI_0 | 21), (_KBI_0 | 22), (_KBI_0 | 23), // PTC0..PTC7
     (_KBI_1 | 24), (_KBI_1 | 25), (_KBI_0 | 26), (_KBI_0 | 27), (_KBI_0 | 28), (_KBI_0 | 29), (_KBI_0 | 30), (_KBI_0 | 31)}, // PTD0..PTD7

    {(_KBI_1 | 0),  (_KBI_1 | 1),  (_KBI_1 | 2),  (_KBI_1 | 3),  (_KBI_1 | 4),  (_KBI_1 | 5),  (_KBI_1 | 6),  (_KBI_1 | 7), // PTE0..PTE7
     (_KBI_1 | 8),  (_KBI_1 | 9),  (_KBI_1 | 10), (_KBI_1 | 11), (_KBI_1 | 12), (_KBI_1 | 13), (_KBI_1 | 14), (_KBI_1 | 15), // PTF0..PTF7
     (_KBI_1 | 16), (_KBI_1 | 17), (_KBI_1 | 18), (_KBI_1 | 19), (_KBI_1 | 20), (_KBI_1 | 21), (_KBI_1 | 22), (_KBI_1 | 23), // PTG0..PTG7
     (_KBI_1 | 24), (_KBI_1 | 25), (_KBI_1 | 26), (_KBI_1 | 27), (_KBI_1 | 28), (_KBI_1 | 29), (_KBI_1 | 30), (_KBI_1 | 31)}, // PTH0..PTH7
};
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This shows clearly that PTH are connected to KBI1 and PTC to KBI0.
Potentially more complicated are PTD pins since most are connected to KBI0 but two of them are connected to KBI1, making for potentially days of development and debugging when trying to edit examples to get them all working if the details are not initially well understood.

A good generic driver will allow the user to state what he/she wants to connect - eg.  PTD0, PTD7, PTC4 and PTH2 to an interrupt callback - and it sorts out the nitty-gritty so that the development is successfully completed within a few minutes instead.

Regards

Mark

0 Kudos

215 Views
mjbcswitzerland
Specialist V

Hi

Compare with the KBI solution in the uTasker project (free open source below) which also simulates the KBI so that there are no secrets or problems when developing.

    INTERRUPT_SETUP interrupt_setup;                                     // interrupt configuration parameters
    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 inputs connected
    interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON);     // interrupt is to be falling edge sensitive
    interrupt_setup.int_handler    = kbi_interrupt;                      // handling function
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt

This will generate the interrupt on any falling edge on PTH3, PTH4, PTH5, PTH6 or PTH7 [note that these are on KBI1]

The source causing the interrupt is visible in KBI1_SP.

To add PTC inputs the following can be called as well (or in place of)

    interrupt_setup.int_port = KE_PORTC;                                 // 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_PORTC_BIT0 | KE_PORTC_BIT1 | KE_PORTC_BIT5 | KE_PORTC_BIT6 | KE_PORTC_BIT7); // the IRQs inputs connected
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt

These PTCx inputs happen to be on KBI0 but the HAL automates all the internal details.

By doing

    interrupt_setup.int_port = KE_PORTC;                                 // 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_PORTC_BIT0);                     // the IRQs input connected
    interrupt_setup.int_handler    = kbi_PTC0_interrupt;                 // handling function
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt
    interrupt_setup.int_port_bits = (KE_PORTC_BIT3);                     // the IRQs input connected
    interrupt_setup.int_handler    = kbi_PTC3_interrupt;                 // handling function
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt
    interrupt_setup.int_port_bits = (KE_PORTC_BIT7);                     // the IRQs input connected
    interrupt_setup.int_handler    = kbi_PTC7_interrupt;                 // handling function
    fnConfigureInterrupt((void *)&interrupt_setup);                      // configure interrupt

Each of the possible interrupts then has its own interrupt callback so that each input can directly have its own unique code.

Beware that the KBI controller only allows one interrupt to be recognised at a time. A second will only be recognised when the first has been removed - that means that it can't be used when more that one interrupt is in the triggering state (this is a potential restriction in using the KBI for some practical applications).

Regards

Mark

Complete Kinetis solutions for professional needs, training and support: http://www.utasker.com/kinetis.html
i.MX RT project compatibility: http://www.utasker.com/iMX.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


uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market

Request Free emergency remote desk-top consulting at http://www.utasker.com/services.html

Open Source version at https://github.com/uTasker/uTasker-Kinetis

https://community.nxp.com/thread/512558
https://community.nxp.com/thread/352862
https://community.nxp.com/thread/498809

0 Kudos