AnsweredAssumed Answered

LPC54101 ADC

Question asked by carl engelmann on Oct 31, 2016
Latest reply on Nov 3, 2016 by carl engelmann

I am trying to get the ADC working on the LPC54101 using LPCopen. I have not successfully managed to get the ADC_SEQA_IRQHandler() interrupt to trigger. I can't seem to find where I am going wrong. I have followed all the steps that are required in the user manual and used steps similar to those in the lpcxpresso54102 ADC example.

 

Here is my code so far (i have not edited any of the LPCopen files from v3.03.000):

/*
* @brief LPC5410x ADC example
*
* @note
* Copyright(C) NXP Semiconductors, 2015
* All rights reserved.
*
* /

#include "chip.h"

/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/

static volatile int ticks;
static bool sequenceComplete, thresholdCrossed;

#define TICKRATE_HZ (100) /* 100 ticks per second */


#define BOARD_ADC_CH 0

/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/

/*****************************************************************************
* Private functions
****************************************************************************/

/*****************************************************************************
* Public functions
****************************************************************************/

/**
* @brief Handle interrupt from SysTick timer
* @return Nothing
*/
void SysTick_Handler(void)
{
static uint32_t count;

/* Every 1/2 second */
count++;
if (count >= (TICKRATE_HZ / 2)) {
count = 0;

/* Manual start for ADC conversion sequence A */
Chip_ADC_StartSequencer(LPC_ADC, ADC_SEQA_IDX);
Chip_GPIO_SetPinToggle(LPC_GPIO, 0, 11);
}
}

/* SEQ-A interrupt handler */
void ADC_SEQA_IRQHandler(void)
{
uint32_t pending;

/* Get pending interrupts */
pending = Chip_ADC_GetFlags(LPC_ADC);

/* Sequence A completion interrupt */
if (pending & ADC_FLAGS_SEQA_INT_MASK) {
sequenceComplete = true;
}

/* Clear any pending interrupts */
Chip_ADC_ClearFlags(LPC_ADC, ADC_FLAGS_SEQA_INT_MASK);
}

/* ADC threashold interrupt handler */
void ADC_THCMP_IRQHandler(void)
{
uint32_t pending;

/* Get pending interrupts */
pending = Chip_ADC_GetFlags(LPC_ADC);

/* Threshold crossing interrupt on ADC input channel */
if (pending & ADC_FLAGS_THCMP_MASK(BOARD_ADC_CH)) {
thresholdCrossed = true;
}

/* Clear any pending interrupts */
Chip_ADC_ClearFlags(LPC_ADC, ADC_FLAGS_THCMP_MASK(BOARD_ADC_CH));
}

/* main function (C entry point) */
int main(void)
{
int loop = 1; /* Prevents unreachable statement warning */
uint32_t rawSample;

SystemCoreClockUpdate();
Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_INPUTMUX);
Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON);
Chip_GPIO_Init(LPC_GPIO);

//LED init
Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 11);
Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 0);

/* Setup ADC for 12-bit mode and normal power */
Chip_ADC_Init(LPC_ADC, (ADC_CR_RESOL(3) | ADC_CR_TSAMP(ADC_TSAMP_7CLK5)));

uint32_t i;
for( i=0; i<10000000; i++);

/* FIXME: Enable ADC, should be at least 10mS after ADC is powered up */
LPC_ADC->STARTUP = 0x1;
LPC_ADC->STARTUP = 0x3; /* Dummy calibration */

/* Need to do a calibration after initialization and trim */
Chip_ADC_Calibration(LPC_ADC);

/* Setup for maximum ADC clock rate using synchronous clocking */
Chip_ADC_SetClockRate(LPC_ADC, ADC_MAX_SAMPLE_RATE);


/* Setup sequencer A for ADC channel 0, EOS interrupt */
/* Setup a sequencer to do the following:
Perform ADC conversion of ADC channels 0 */
Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, (ADC_SEQ_CTRL_CHANSEL(BOARD_ADC_CH)| ADC_SEQ_CTRL_MODE_EOS));

/* ADC input 0 is on PIO0_29 mapped to FUNC0 */
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 29, (IOCON_FUNC0 | IOCON_MODE_INACT |
IOCON_ANALOG_EN));

/* Setup threshold 0 low and high values to about 25% and 75% of max */
Chip_ADC_SetThrLowValue(LPC_ADC, 0, 0xf50); // ((1 * 0xFFF) / 4));
Chip_ADC_SetThrHighValue(LPC_ADC, 0, 0xf70);// ((3 * 0xFFF) / 4));

/* Clear all pending interrupts */
Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));

/* Enable ADC overrun and sequence A completion interrupts */
Chip_ADC_EnableInt(LPC_ADC, (ADC_INTEN_SEQA_ENABLE | ADC_INTEN_OVRRUN_ENABLE));

/* Use threshold 0 for ADC channel and enable threshold interrupt mode for
channel as crossing */
Chip_ADC_SelectTH0Channels(LPC_ADC, ADC_THRSEL_CHAN_SEL_THR1(BOARD_ADC_CH));
Chip_ADC_SetThresholdInt(LPC_ADC, BOARD_ADC_CH, ADC_INTEN_THCMP_CROSSING);

/* Enable ADC NVIC interrupt */
NVIC_EnableIRQ(ADC_SEQA_IRQn);
NVIC_EnableIRQ(ADC_THCMP_IRQn);

/* Enable sequencer */
Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX);

/* This example uses the periodic sysTick to manually trigger the ADC,
but a periodic timer can be used in a match configuration to start
an ADC sequence without software intervention. */
SysTick_Config(SystemCoreClock / TICKRATE_HZ);

/* Endless loop */
while (loop) {
/* Sleep until something happens */
__WFI();

if (thresholdCrossed) {
thresholdCrossed = false;
}

/* Is a conversion sequence complete? */
if (sequenceComplete) {
sequenceComplete = false;

rawSample = Chip_ADC_GetDataReg(LPC_ADC, 0);

}
}

/* Should not run to here */
return 0;
}

Thanks

Outcomes