AnsweredAssumed Answered

LPC1788 GPIO Interrupts Slow

Question asked by James Kent on Jun 20, 2019
Latest reply on Jun 28, 2019 by jeremyzhou

I've asked this question on the Keil forums which have directed me to ask here, but i'm having some issues with interrupts on an embedded artists development board and LPC1788. I have a 1200 Hz clock coming in on a pin and I need to be able to trigger an interrupt on every falling edge, my understanding is that external interrupts should fire withing 12-16ish clock cycles, and normal GPIO interrupts may be a little bit slower. My core clock is configured to 120MHz and my peripheral clock is 60MHz, so this should be a very very small delay (~0.13 us). instead i'm seeing delays of more like 650 us and the point at which my interrupt triggers shifts relative to my input signal which it also shouldn't do.

i have tried this on both a general GPIO pin (on bank 0 or 2 as there are the supported interrupt pins) and on the EINT3 pin, with the same results.

simple example for GPIO:

#include "cmsis_os2.h"
#include "LPC177x_8x.h"
#include "GPIO_LPC17xx.h"
#include <stdio.h>

uint8_t clock_port = 0;
uint8_t clock_num = 9;
uint8_t twiddle_port = 1;
uint8_t twiddle_num = 28;

void GPIO_IRQHandler(void) {
        LPC_GPIOINT->IO0IntClr |= 1<<9;
        GPIO_PinWrite(twiddle_port, twiddle_num, 1);
        GPIO_PinWrite(twiddle_port, twiddle_num, 0);
}

int main() {
        osKernelInitialize();   // initialize CMSIS-RTOS
        SystemCoreClockUpdate();
        GPIO_PortClock(1);
        GPIO_SetDir(clock_port, clock_num, GPIO_DIR_INPUT);
        GPIO_SetDir(twiddle_port, twiddle_num, GPIO_DIR_OUTPUT);
        LPC_GPIOINT->IO0IntEnF |= 0x01 << 9; // trigger on falling edge
        NVIC_SetPriority(GPIO_IRQn, 0);         NVIC_EnableIRQ(GPIO_IRQn);
        osKernelStart ();               // start thread execution
        for (;;) { }
        return 0;
}

and for EINT3:

#include "cmsis_os2.h"
#include "LPC177x_8x.h"
#include "GPIO_LPC17xx.h"
#include <stdio.h>

uint8_t clock_port = 2;
uint8_t clock_num = 13;
uint8_t twiddle_port = 1;
uint8_t twiddle_num = 28;

void EINT3_IRQHandler(void) {
         LPC_SC->EXTINT |= 1<<3;
         GPIO_PinWrite(twiddle_port, twiddle_num, 1);
         GPIO_PinWrite(twiddle_port, twiddle_num, 0);
}

int main() {
        osKernelInitialize();   // initialize CMSIS-RTOS
        SystemCoreClockUpdate();
        GPIO_PortClock(1);
        GPIO_SetDir(clock_port, clock_num, GPIO_DIR_INPUT);
        GPIO_SetDir(twiddle_port, twiddle_num, GPIO_DIR_OUTPUT);
        LPC_SC->EXTINT = (1<<3);           /* Clear Pending interrupts */
        LPC_IOCON->P2_13 = 1;
        LPC_SC->EXTMODE = (1<<3);  /* Configure EINTx as Edge Triggered*/
        LPC_SC->EXTPOLAR = (1<<3); /* Configure EINTx as Falling Edge */
        NVIC_SetPriority(EINT3_IRQn, 0);
        NVIC_EnableIRQ(EINT3_IRQn);
        osKernelStart ();               // start thread execution 
        for (;;) { }
        return 0;
}

the GPIO pinwrite function is:

void GPIO_PinWrite (uint32_t port_num, uint32_t pin_num, uint32_t val) {
    val ? (LPC_GPIO(port_num)->SET = (1UL << pin_num)) : \
          (LPC_GPIO(port_num)->CLR = (1UL << pin_num));
}

and I have also tried with a toggle logic in the interrupt with the same results.

 

I'm using keil uvision 5.28a, with cmsis V2 using RTX5 as the underlying RTOS

 

Am I missing something in the setup?

Attachments

Outcomes