/** * @brief ADC initialization. * * Enables ADC and sets up the sequencer for single sample on the range * finder ADC input. */ void adcInit(void) { /* Setup ADC for 12-bit mode and normal power */ Chip_ADC_Init(LPC_ADC, 0); /* Need to do a calibration after initialization and trim */ Chip_ADC_StartCalibration(LPC_ADC); while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {} /* Setup for maximum ADC clock rate using sycnchronous clocking */ Chip_ADC_SetClockRate(LPC_ADC, 500000); Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, (ADC_SEQ_CTRL_CHANSEL(MoonLander_IO8_ADC) | ADC_SEQ_CTRL_MODE_EOS)); /* Setup threshold 0 low and high values to about 25% and 75% of max */ Chip_ADC_SetThrLowValue(LPC_ADC, 0, ((1 * 0xFFF) / 4)); Chip_ADC_SetThrHighValue(LPC_ADC, 0, ((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(MoonLander_IO8_ADC)); Chip_ADC_SetThresholdInt(LPC_ADC, MoonLander_IO8_ADC, ADC_INTEN_THCMP_CROSSING); /* Enable ADC NVIC interrupt */ NVIC_EnableIRQ(ADC_SEQA_IRQn); /* Enable sequencer */ Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX); }
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) { g_adc_sample_ready = 1; } /* Clear any pending interrupts */ Chip_ADC_ClearFlags(LPC_ADC, pending); }
/** * @brief Handle interrupt from ADC sequencer A * @return Nothing */ void ADCA_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; } /* Threshold crossing interrupt on channel 1? */ if (pending & ADC_FLAGS_THCMP_MASK(1)) { thresholdCrossed = true; } /* Clear any pending interrupts */ Chip_ADC_ClearFlags(LPC_ADC, pending); }
/** * @brief Handle interrupt from ADC sequencer A * @return Nothing */ void ADC0A_IRQHandler(void) { uint32_t i, pending; uint32_t gdata_value, data_value, seq_ctrl_value, ch_offset; /* Get pending interrupts */ pending = Chip_ADC_GetFlags(LPC_ADC); /* Sequence A completion interrupt */ if (pending & ADC_FLAGS_SEQA_INT_MASK) { seq_ctrl_value = Chip_ADC_GetSequencerCtrl(LPC_ADC, ADC_SEQA_IDX); if ( seq_ctrl_value & ADC_SEQ_CTRL_MODE_EOS ) { /* End of sequence, get raw sample data for channels 0-11 */ for (i = 0; i < BOARD_ADC_CH; i++) { if ( seq_ctrl_value & (0x1<<i) ) { if ( (data_value = Chip_ADC_GetDataReg(LPC_ADC, i)) & ADC_DR_DATAVALID ) { ADC_Data_Buffer[i] = ADC_DR_RESULT(data_value); channel_completion |= ( 0x1 << i ); } } } } else { /* End of conversion, get raw sample data for channels 0-11 */ gdata_value = Chip_ADC_GetGlobalDataReg(LPC_ADC, ADC_SEQA_IDX); if ( gdata_value & ADC_SEQ_GDAT_DATAVALID ) { ch_offset = (gdata_value & ADC_SEQ_GDAT_CHAN_MASK) >> ADC_SEQ_GDAT_CHAN_BITPOS; ADC_Data_Buffer[ch_offset] = ADC_DR_RESULT(gdata_value); channel_completion |= (0x1<<ch_offset); } if ( channel_completion != (seq_ctrl_value & 0xFFF) ) { /* Not all channels are completed. */ if ( (seq_ctrl_value & ADC_SEQ_CTRL_SINGLESTEP) && !(seq_ctrl_value & ADC_SEQ_CTRL_BURST) ) { /* If SINGLE_STEP is set and BURST is not, this sequence needs to be restarted. */ Chip_ADC_StartSequencer(LPC_ADC, ADC_SEQA_IDX); } } }
/** * @brief main routine for ADC example * @return Function should not exit */ int main(void) { uint32_t rawSample; int j; SystemCoreClockUpdate(); Board_Init(); DEBUGSTR("ADC Demo\r\n"); /* Setup ADC for 12-bit mode and normal power */ Chip_ADC_Init(LPC_ADC, 0); /* Setup for maximum ADC clock rate */ Chip_ADC_SetClockRate(LPC_ADC, ADC_MAX_SAMPLE_RATE); /* Setup sequencer A for ADC channel 1, EOS interrupt */ #if defined(BOARD_MCORE48_1125) /* Setup a sequencer to do the following: Perform ADC conversion of ADC channel 1 only Trigger on low edge of PIO0_7 */ Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, (ADC_SEQ_CTRL_CHANSEL(1) | ADC_SEQ_CTRL_MODE_EOS | ADC_SEQ_CTRL_HWTRIG_PIO0_7)); /* Select ADC_1 mux for PIO1_11 */ Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO1_11, (IOCON_FUNC1 | IOCON_ADMODE_EN)); /* Setup GPIO PIO0_7 as an input (will kill LED out) */ Chip_GPIO_WriteDirBit(LPC_GPIO, 0, 7, false); /* Use higher voltage trim for MCore48 board */ Chip_ADC_SetTrim(LPC_ADC, ADC_TRIM_VRANGE_HIGHV); #endif /* Need to do a calibration after initialization and trim */ Chip_ADC_StartCalibration(LPC_ADC); while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {} /* Setup threshold 0 low and high values to about 25% and 75% of max */ Chip_ADC_SetThrLowValue(LPC_ADC, 0, ((1 * 0xFFF) / 4)); Chip_ADC_SetThrHighValue(LPC_ADC, 0, ((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 channel 1 and enable threshold interrupt mode for channel as crossing */ Chip_ADC_SelectTH0Channels(LPC_ADC, ADC_THRSEL_CHAN_SEL_THR1(1)); Chip_ADC_SetThresholdInt(LPC_ADC, 1, ADC_INTEN_THCMP_CROSSING); /* Enable ADC NVIC interrupt */ NVIC_EnableIRQ(ADC_A_IRQn); /* Enable sequencer */ Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX); /* Setup SyTick for a periodic rate */ SysTick_Config(SystemCoreClock / TICKRATE_HZ); /* Endless loop */ while (1) { /* Sleep until something happens */ __WFI(); if (thresholdCrossed) { thresholdCrossed = false; DEBUGSTR("********ADC threshold event********\r\n"); } /* Is a conversion sequence complete? */ if (sequenceComplete) { sequenceComplete = false; /* Get raw sample data for channels 1-8 */ for (j = 1; j <= 1; j++) { rawSample = Chip_ADC_GetDataReg(LPC_ADC, j); /* Show some ADC data */ DEBUGOUT("Sample value = 0x%x\r\n", ADC_DR_RESULT(rawSample)); DEBUGOUT("Threshold range = 0x%x\r\n", ADC_DR_THCMPRANGE(rawSample)); DEBUGOUT("Threshold cross = 0x%x\r\n", ADC_DR_THCMPCROSS(rawSample)); DEBUGOUT("Overrun = %d\r\n", ((rawSample & ADC_DR_OVERRUN) != 0)); DEBUGOUT("Data valid = %d\r\n", ((rawSample & ADC_SEQ_GDAT_DATAVALID) != 0)); DEBUGSTR("\r\n"); } } } /* Should not run to here */ return 0; }