Hello guys and girls
I'm starting into ARM Cortex M4 (Freescale Kinetis). My past experience im uC are all about PIC. I'm facing some difficults into setting/handling an Interruption. A simple one, since it's GPIO related.
I'm working on a Freescale TRW-K60N512 module with MK60N512VMD100 processor and Keil u-Vision. This board has 4 LED-TouchElectrode pairs. I'm trying to toggle 2 LEDs by pressing the touch electrodes.
So far, my code is bellow. However, it doesn't work (I get no response from pressing the electrodes).
Could anyone help please with some more details? For a first, I could not understand how PORTA_IRQHandler could be right handled by the compiler and I could not find any vector address for it. Do I need to declare an address myself?
What are the Interrupt usage basic? Setting up (Registers) and then Handling (registers). If anyone has a document about it, or even better, some usage example (using Keil) I would appreciate it a lot.
#include "MK60N512MD100.h"#include "delay.h" #define nLED_E1 11#define nLED_E2 28#define nLED_E3 29#define nLED_E4 10#define nTouch_E1 4#define nTouch_E2 3#define nTouch_E3 2#define nTouch_E4 16#define nSW1_IRQ0 19#define nSW2_IRQ1 26#define LED_E1 (1<<nLED_E1)#define LED_E2 (1<<nLED_E2)#define LED_E3 (1<<nLED_E3)#define LED_E4 (1<<nLED_E4)#define Touch_E1 (1<<nTouch_E1)#define Touch_E2 (1<<nTouch_E2)#define Touch_E3 (1<<nTouch_E3)#define Touch_E4 (1<<nTouch_E4)#define SW1_IRQ0 (1<<nSW1_IRQ0)#define SW2_IRQ1 (1<<nSW2_IRQ1)int main (void) { SIM->SCGC5 = SIM->SCGC5 | SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTE_MASK ; PORTA->PCR[nLED_E1] = PORT_PCR_MUX(1); PORTA->PCR[nLED_E2] = PORT_PCR_MUX(1); PORTA->PCR[nLED_E3] = PORT_PCR_MUX(1); PORTA->PCR[nLED_E4] = PORT_PCR_MUX(1); PORTA->PCR[nTouch_E1] = PORT_PCR_MUX(1) | PORT_PCR_PE_MASK; PORTB->PCR[nTouch_E2] = PORT_PCR_MUX(1) | PORT_PCR_PE_MASK; PORTB->PCR[nTouch_E3] = PORT_PCR_MUX(1) | PORT_PCR_PE_MASK; PORTB->PCR[nTouch_E4] = PORT_PCR_MUX(1) | PORT_PCR_PE_MASK; PORTA->PCR[nSW1_IRQ0] = PORT_PCR_MUX(1) | PORT_PCR_PE_MASK ; PORTE->PCR[nSW2_IRQ1] = PORT_PCR_MUX(1) | PORT_PCR_PE_MASK ; PTA->PDDR = ~GPIO_PDDR_PDD_MASK; PTB->PDDR = ~GPIO_PDDR_PDD_MASK; PTE->PDDR = ~GPIO_PDDR_PDD_MASK; PTA->PDDR = PTA->PDDR | LED_E1; PTA->PDDR = PTA->PDDR | LED_E2; PTA->PDDR = PTA->PDDR | LED_E3; PTA->PDDR = PTA->PDDR | LED_E4; /*-------------------------------------------------------------------------- Enable interruptions: Falling edge --------------------------------------------------------------------------*/ PORTA->PCR[nTouch_E1] |= PORT_PCR_IRQC(10); PORTB->PCR[nTouch_E2] |= PORT_PCR_IRQC(10); PORTB->PCR[nTouch_E3] |= PORT_PCR_IRQC(10); PORTB->PCR[nTouch_E4] |= PORT_PCR_IRQC(10); PORTA->PCR[nSW1_IRQ0] |= PORT_PCR_IRQC(10); PORTE->PCR[nSW2_IRQ1] |= PORT_PCR_IRQC(10); NVIC_EnableIRQ(PORTA_IRQn); NVIC_EnableIRQ(PORTB_IRQn); NVIC_EnableIRQ(PORTE_IRQn); NVIC_SetPriority(PORTA_IRQn,1); NVIC_SetPriority(PORTB_IRQn,1); NVIC_SetPriority(PORTE_IRQn,1); /*-------------------------------------------------------------------------- Turn off LEDs --------------------------------------------------------------------------*/ PTA->PSOR = LED_E1 ; PTA->PSOR = LED_E2 ; PTA->PSOR = LED_E3 ; PTA->PSOR = LED_E4 ; /*-------------------------------------------------------------------------- Main loop --------------------------------------------------------------------------*/ while (1) { Delay_ms (50); PTA->PSOR = LED_E2 ; Delay_ms (50); PTA->PCOR = LED_E2 ; }}void PORTA_IRQHandler(void) { PORTA->ISFR = PORT_ISFR_ISF_MASK; PTA->PTOR = LED_E3 ; Delay_ms (500);}void PORTB_IRQHandler(void) { PORTB->ISFR = PORT_ISFR_ISF_MASK; PTA->PTOR = LED_E4 ; Delay_ms (500);}
Thanks in advance!
Best regards
Fabio de Luca
Hi Fabio
The 4 electrode sensors need to be used in touch sensor mode (either together with a Freescale software library or as touch sensor pins) and so are probably not suitable for GPIO interrupts. I would recommend using the push buttons for developing GPIO interrupt operation instead.
I think that your code is missing entering the interrupt handlers (PORTA_IRQHandler and PORTB_IRQHandler). There is probabably a function that can be called to associate these with the interrupt vectors. There is in fact one interrupt vector for a port (with up to 32 GPIOs on it) so it may be necessary for it to also filter the GPIOs that have actually changed too.
See page 35 ("Port Interrupts") of
http://www.utasker.com/docs/KINETIS/uTaskerV1.4_Kinetis_demo.pdf
for the user interface in the uTasker project which allows assigning an interrupt handler to each GPIO rather than just to each port.
Regards
Mark