lpcware

ADC On Interrupt LPC1788

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by amlwwalker on Mon Dec 16 12:42:52 MST 2013
Hi
I am trying to get my ADC's for my touchscreen working on an interrupt. They worked when I was polling the channels, but I dont get anything on an interrupt.

My setup code for the two channels is:

void prepareTouchScreen() {
ADC_Init(LPC_ADC, 400000);
/* Configure X1: */LPC_IOCON ->P0_24 = PIN_GPIO; /* X1 is a GPIO pin */
LPC_GPIO0 ->DIR |= (1 << 24); /* it's output */
LPC_GPIO0 ->SET = (1 << 24); /* and is set high */

/* Configure Y1: */LPC_IOCON ->P0_23 = PIN_GPIO; /* Y1 is a GPIO pin */
LPC_GPIO0 ->DIR |= (1 << 23); /* it's output */
LPC_GPIO0 ->SET = (1 << 23); /* and is set high */

/* Configure X2: */LPC_IOCON ->P0_22 = PIN_OD; /* simulated open drain (high impedance) mode */
LPC_GPIO0 ->DIR |= (1 << 22); /* this pin is always output */
LPC_GPIO0 ->SET = (1 << 22); /* and is set high (not sinking current) */

/* Configure Y2: */LPC_IOCON ->P0_21 = PIN_OD; /* simulated open drain (high impedance) mode */
LPC_GPIO0 ->DIR |= (1 << 21); /* this pin is always output */
LPC_GPIO0 ->SET = (1 << 21); /* and is set high (not sinking current) */
LOG("Touch Screen Prepared");
}


My code to read a channel is:


inline uint16_t startTouchscreenADC(uint8_t aDirection) {
LOG(__PRETTY_FUNCTION__);

/* Prepare pins: */
if (aDirection) {
LPC_IOCON ->P0_24 = PIN_ADC; /* X1 = ADC */
LPC_IOCON ->P0_23 = PIN_GPIO; /* Y1 = GPIO pin */
LPC_GPIO0 ->CLR = (1 << 22); /* set X2 low (now sinking current) */
LPC_GPIO0 ->SET = (1 << 21); /* set Y2 high (now high impedance) */
LOG("direction = 1");
} else {
LPC_IOCON ->P0_24 = PIN_GPIO; /* X1 = GPIO pin */
LPC_IOCON ->P0_23 = PIN_ADC; /* Y1 = ADC */
LPC_GPIO0 ->SET = (1 << 22); /* set X2 high (now high impedance) */
LPC_GPIO0 ->CLR = (1 << 21); /* set Y2 low (now sinking current) */
LOG("direction = 0");
}
ADC_ChannelCmd(LPC_ADC, 1 - aDirection, DISABLE);
ADC_ChannelCmd(LPC_ADC, aDirection, ENABLE);
LOG("direction changed");
LPC_ADC ->INTEN = (LPC_ADC ->INTEN & ~0x03) | (1 << aDirection); /* enable interrupt for this direction */
LPC_ADC->CR = ADC_CR_START_MODE_SEL(ADC_CR_START_NOW) | ADC_CR_PDN | ADC_CR_CH_SEL(aDirection);
LOG("finished conversion");

      return (ADC_DR_RESULT(LPC_ADC->DR[aDirection]));
}


In main I am doing:


        prepareTouchScreen();
        /* preemption = 1, sub-priority = 1 */
        NVIC_SetPriority(ADC_IRQn, ((0x01<<3)|0x01));
        LPC_ADC->INTEN = 0;                                             /* disable ADC interrupts */
        NVIC_ClearPendingIRQ(ADC_IRQn);                 /* clear ADC_IRQ pending bit in the NVIC */
        NVIC_EnableIRQ(ADC_IRQn);                               /* enable ADC_IRQ in the NVIC */
        startTouchscreenADC(0);
while(1){
}

Finally my ADC handler is:

void ADC_IRQHandler(void)
{
        static uint8_t  valid = 0;
        static uint16_t valueX = 0x8000;
        static uint16_t valueY = 0x8000;
        uint16_t                value;

        NVIC_ClearPendingIRQ(ADC_IRQn);

        // the static local variables above are for temporary values, until we have both values as a complete set.

        // read ADC values and store into appropriate variables:
        // get ADC channel status for channel 0, if it's ready

        LOG("Handler accessed");
       if(value & ADC_DR_DONE_FLAG)                            // this might happen right now, it might not
        {
               valueX = ADC_DR_RESULT(value);                  // store value temporarily
                valid |= X_VALID;                                               // X position is now valid
                startTouchscreenADC(1);                                 // start conversion for channel 1.
        }
        // get ADC channel status for channel 1, if it's ready
       value = LPC_ADC->DR[1];
       if(value & ADC_DR_DONE_FLAG)                            // this might happen right now, it might not
        {
               valueY = ADC_DR_RESULT(value);                  // store value temporarily
                valid |= Y_VALID;                                               // Y position is now valid
                startTouchscreenADC(0);                                 // start conversion for channel 0.
        }
        if(BOTH_VALID == valid)
        {
                valid = 0;

                if(valueX >= TOUCH_X_MIN && valueX < TOUCH_X_MAX && valueY >= TOUCH_Y_MIN && valueY < TOUCH_Y_MAX)
                {
                        touchPos = (valueX << 16) | (valueY & 0xffff);
                        touchState = 1;
                }
                else
                {
                        touchState = 0;                                         // not touched.
                        touchPos = 0x80008000;                          // coordinates somewhere far away. :)
                }
        }
}

I am expecting to see:

LOG("Handler accessed");

If I touch the touchscreen and the Handler is called.
What I do see is on my terminal is:


Quote:

Touch Screen Prepared

startTouchscreenADC

direction = 0

direction changed

finished conversion



Can anyone see why Im not getting anything back when I touch the touchscreen? Im not sure why its not going into the handler. Im trying to setup JTAG debugging now to see if I can get anything but any help would be greatly appreciated.

Alex

Outcomes