I have tested success of Functions KBI & GPIO with EVM KIT TRK-KEA8
I want to ports change
I had tried code to change of Initial port
But what cannot enter to KB0_IRQ Handler() and can't read port state..
Can you please advice below my code
* Port changes
----------------------------------------------------
** Input
KBI SW1 : PORTC4 --> PORTB0
KBI SW2 : PORTC5 --> PORTB1
** Output
PORTC0 --> PORTB5
PORTC1 --> PORTB6
PORTC2 --> PORTB7
Origin code
void GPIO_Init()
{
CONFIG_PIN_AS_GPIO(PORT_C,16,OUTPUT); /* Configure LED 0 (PTC0) as an output */
CONFIG_PIN_AS_GPIO(PORT_C,17,OUTPUT); /* Configure LED 1 (PTC1) as an output */
CONFIG_PIN_AS_GPIO(PORT_C,18,OUTPUT); /* Configure LED 2 (PTC2) as an output */
CONFIG_PIN_AS_GPIO(PORT_C,19,OUTPUT); /* Configure LED 3 (PTC3) as an output */
CONFIG_PIN_AS_GPIO(PORT_A,6,OUTPUT);
CONFIG_PIN_AS_GPIO(PORT_C,20,INPUT); /* Configure SW1 (PTC4) as an input */
CONFIG_PIN_AS_GPIO(PORT_C,21,INPUT); /* Configure SW2 (PTC5) as an input */
ENABLE_INPUT(PORT_C,20); /* Enable input SW1*/
ENABLE_INPUT(PORT_C,21); /* Enable input SW2*/
}
void KBI_Init()
{
SIM_SCGC |= SIM_SCGC_KBI1_MASK; /* Enable bus clock on KBI1 */
KBI1_SC = 0; /* Clearing mechanism */
KBI1_ES |= KBI_ES_KBEDG(1);/* Polarity setting, falling edge low level ,SW1 */
KBI1_ES |= KBI_ES_KBEDG(2);/* Polarity setting, falling edge low level ,SW1 */
PORT_PUEL=0; /* No internal pullup*/
KBI1_PE |= KBI_PE_KBIPE(1); /* Enable KBI1 channel 0 , SW1 */
KBI1_PE |= KBI_PE_KBIPE(2); /* Enable KBI1 channel 1 , SW2 */
KBI1_SC = 0; /* Clearing flags and RSTKBSP bit */
KBI1_SC |= KBI_SC_KBIE_MASK; /* Enable KBI1 Interrupts */
//** Change to setup NEW port
SIM_SCGC |= SIM_SCGC_KBI0_MASK; /* Enable bus clock on KBI1 */
KBI0_SC = 0; /* Clearing mechanism */
KBI0_ES |= KBI_ES_KBEDG(4);/* Polarity setting, falling edge low level ,SW1 */
KBI0_ES |= KBI_ES_KBEDG(5);/* Polarity setting, falling edge low level ,SW1 */
PORT_PUEL=0; /* No internal pullup*/
KBI0_PE |= KBI_PE_KBIPE(4); /* Enable KBI4 channel 4 , SW1 */
KBI0_PE |= KBI_PE_KBIPE(5); /* Enable KBI5 channel 5 , SW2 */
KBI0_SC = 0; /* Clearing flags and RSTKBSP bit */
KBI0_SC |= KBI_SC_KBIE_MASK; /* Enable KBI1 Interrupts */
}
void KBI1_IRQHandler()
{
KBI1_SC |= KBI_SC_KBACK_MASK; /*Clear flag*/
if((GPIOA_PDIR & GPIO_PDIR_PDI(0x100000))>>20) /* If SW1 has been pressed */
{
LED0_TOGGLE;
PIT_Config0.bTimerEn = TRUE;
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
}
else if((GPIOA_PDIR & GPIO_PDIR_PDI(0x200000))>>21) /* If SW2 has been pressed *
{
__asm("nop");
Flag_sleep=1;
__asm("nop");
}
}
//** To setup NEW port IRQ Handler
void KBI0_IRQHandler()
{
KBI1_SC |= KBI_SC_KBACK_MASK; /*Clear flag*/
if((GPIOA_PDIR & GPIO_PDIR_PDI(0x100))>>8) /* If Folding_SW1(PTB0) has been pressed */
//if(GPIOA_PDIR == 0x101020) /* If SW1 has been pressed */
//0x101020
{
//GPIOA_PTOR |=1<<16; /* LED Toggle at port C0*/
LED0_TOGGLE;
PIT_Config0.bTimerEn = TRUE;
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
//LED1_TOGGLE;
}
else if((GPIOA_PDIR & GPIO_PDIR_PDI(0x200))>>9) /* If Walk_IN_SW2(PTB1) has been pressed *
//else if(GPIOA_PDIR == 0x201020) /* If SW2 has been pressed */
{
//GPIOA_PTOR |=1<<16; /* LED Toggle at port C0*/
__asm("nop");
//LED1_TOGGLE;
Flag_sleep=1;
//__asm__("wfi");
__asm("nop");
//reset;
}
}
Thank you so much !
But I use IDE that is KDS 3.2.0
So I can`t apply your code
Hi
I use the code with KDS3.2.0, S32 Design Studio, CodeWarrior, IAR, Keil, Rowley, Green Hills, CooCox, GCC, VisualStdio and Atollic.
There is no restrictions to a certain IDE. Only basic libraries will be restricted to a certain environment.
As I mention, if you are looking just for a quick fix and not a powerful complete solution you just need to write the 3 lines of code shown to do it correctly.
Regards
Mark
Hi
It looks a bit suspect that you reference the original KBI inputs as 1 and 2 for channels 0 and 1, and the new ones as 4 and 5 for channels 4 and 5 (and not as 5 and 6). I would check that first.
I put a quick video for you on Youtube showing how to do this in the uTasker project [ https://youtu.be/UU69QHUbVb0 ] and test the operation in its simulator. It shows also that there are in fact only three registers to be set as follows:
PORT_PUEL |= 0x300;
KBI0_SC = 0x02;
KBI0_PE = 0x30;
This is the code:
static void test_kb(void)
{
// User interrupt call-back handler
// - arrives here when either of the two inputs detects a falling edge
//
}
extern void fnConfigureTwoKBI_Interrupts(void)
{
INTERRUPT_SETUP interrupt_setup; // interrupt configuration parameters
interrupt_setup.int_type = KEYBOARD_INTERRUPT; // define keyboard interrupt rather than IRQ
interrupt_setup.int_handler = test_kb; // handling function
interrupt_setup.int_priority = PRIORITY_KEYBOARD_INT; // interrupt priority level
interrupt_setup.int_port = KE_PORTB; // the port that the interrupt input is on (KE_PORTA, KE_PORTB, KE_PORTC and KE_PORTD are the same)
interrupt_setup.int_port_bits = (KE_PORTB_BIT0 | KE_PORTB_BIT1); // the IRQs input connected
interrupt_setup.int_port_sense = (IRQ_FALLING_EDGE | PULLUP_ON); // interrupt is to be falling edge sensitive with pull-up enabled on inputs
fnConfigureInterrupt((void *)&interrupt_setup); // configure interrupt
}
The method also allows assigning each KBI to a different interrupt call-back too, to simplify the interrupt handling.
If you watch the video and check the register being written against yours you should also be able to solve the issue.
To save time in the future consider using the uTasker project and its simulator - it is open source at the links below, will improve your code and slash development times needed.
Beware however that the KBI will lose interrupts if two occur together. This is a characteristic of its design (or a bug (?)) that needs to be considered....
Regards
Mark
http://www.utasker.com/kinetis.html
http://www.utasker.com/kinetis/TRK-KEA8.html