/** * @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); }
/* PRIVATE: Reads data from the GDAT or DAT register based on mode of operation */ static ErrorCode_t _ADC_ReadData(ADC_DRIVER_T *pADC, ADC_SEQ_INDEX_T seqIndex) { ADC_REGS_T *pREGS = pADC->pREGS; int i; /* Check if this is End-of-Seq or End-of-SingleConversion */ if (!(pADC->valSeq[seqIndex] & ADC_SEQ_CTRL_MODE_EOS)) { return _ADC_GetData(pADC, seqIndex, pREGS->SEQ_GDAT[seqIndex]); } /* Read channels having conversion data */ for (i = 0; i < sizeof(pREGS->DAT) / sizeof(pREGS->DAT[0]); i++) { if (pADC->valSeq[seqIndex] & ADC_SEQ_CTRL_CHANSEL(i)) { if (_ADC_GetData(pADC, seqIndex, pREGS->DAT[i]) != LPC_OK) { return ERR_FAILED; } } } return LPC_OK; }
/** * @brief main routine for ADC example * @return Function should not exit */ int main(void) { SystemCoreClockUpdate(); Board_Init(); DEBUGSTR("ADC ROM sequencer demo\r\n"); /* Power up, enable clock and reset ADC0 */ Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC0_PD); Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC0); Chip_SYSCTL_PeriphReset(RESET_ADC0); /* Power up, enable clock and reset ADC1 */ Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_ADC1_PD); Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC1); Chip_SYSCTL_PeriphReset(RESET_ADC1); /* Power up the internal temperature sensor */ Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_TS_PD); #if defined(BOARD_NXP_LPCXPRESSO_1549) /* Disables pullups/pulldowns and disable digital mode */ Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 9, (IOCON_MODE_INACT | IOCON_ADMODE_EN)); /* Assign ADC1_1 to PIO0_9 via SWM (fixed pin) */ Chip_SWM_EnableFixedPin(SWM_FIXED_ADC1_1); #else #warning "No ADC setup for this example" #endif /* Initialize ROM API base address for ADC */ pAdcApi = LPC_ADCD_API; size_in_bytes = pAdcApi->adc_get_mem_size(); if (size_in_bytes / 4 > RAMBLOCK_H) { /* Adjust RAMBLOCK size in this case */ return 1; } /* ADC Handle Setup*/ adc_handle[0] = pAdcApi->adc_setup(LPC_ADC0_BASE, (uint8_t *) start_of_ram_block[0]); adc_handle[1] = pAdcApi->adc_setup(LPC_ADC1_BASE, (uint8_t *) start_of_ram_block[1]); /* ADC0 Config */ adc_cfg[0].system_clock = SystemCoreClock; /* System clock */ adc_cfg[0].adc_clock = 500000; /* ADC clock set to 500KHz for calibration*/ /* ADC1 Config */ adc_cfg[1].system_clock = SystemCoreClock; /* System clock */ adc_cfg[1].adc_clock = 500000; /* ADC clock set to 500KHz for calibration*/ pAdcApi->adc_calibration(adc_handle[0], &adc_cfg[0]); pAdcApi->adc_calibration(adc_handle[1], &adc_cfg[1]); /* ADC0 Config for Init */ adc_cfg[0].system_clock = SystemCoreClock; /* System clock */ adc_cfg[0].adc_clock = ADC_CLOCK_RATE; /* ADC clock */ adc_cfg[0].async_mode = 0; /* Synchronous mode */ adc_cfg[0].tenbit_mode = 0; /* 12 Bit ADC mode */ adc_cfg[0].lpwr_mode = 0; /* Disable low power mode */ adc_cfg[0].input_sel = ADC_INSEL_TS; adc_cfg[0].seqa_ctrl = (ADC_SEQ_CTRL_CHANSEL(0) | ADC_SEQ_CTRL_MODE_EOS); adc_cfg[0].channel_num = 1; /* Channel number is one higher than the maximum channel number used */ /* ADC1 Config for Init */ adc_cfg[1].system_clock = SystemCoreClock; /* System clock */ adc_cfg[1].adc_clock = ADC_CLOCK_RATE; /* ADC clock */ adc_cfg[1].async_mode = 0; /* Synchronous mode */ adc_cfg[1].tenbit_mode = 0; /* 12 Bit ADC mode */ adc_cfg[1].lpwr_mode = 0; /* Disable low power mode */ adc_cfg[1].seqa_ctrl = (ADC_SEQ_CTRL_CHANSEL(BOARD_ADC_CH) | ADC_SEQ_CTRL_MODE_EOS); adc_cfg[1].thrsel = 0; adc_cfg[1].thr0_low = ((1 * 0xFFF) / 4) << 4; adc_cfg[1].thr0_high = ((3 * 0xFFF) / 4) << 4; adc_cfg[1].thcmp_en = ADC_INTEN_CMP_ENABLE(ADC_INTEN_CMP_CROSSTH, BOARD_ADC_CH); adc_cfg[1].channel_num = BOARD_ADC_CH + 1; /* Channel number is one higher than the maximum channel number used */ pAdcApi->adc_init(adc_handle[0], &adc_cfg[0]); pAdcApi->adc_init(adc_handle[1], &adc_cfg[1]); /* When using ADC ROM API's lower the priority of ADC Sequence completion interrupt when compared to the threshold interrupt*/ NVIC_SetPriority(ADC1_SEQA_IRQn, 1); /* Enable related ADC NVIC interrupts */ NVIC_EnableIRQ(ADC0_SEQA_IRQn); NVIC_EnableIRQ(ADC1_SEQA_IRQn); NVIC_EnableIRQ(ADC1_THCMP); /* 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(Chip_Clock_GetSysTickClockRate() / TICKRATE_HZ); /* Endless loop */ while (1) { /* Sleep until something happens */ __WFI(); if (threshold1Crossed) { threshold1Crossed = false; DEBUGSTR("********ADC1 threshold event********\r\n"); } /* Is a conversion sequence complete? */ if (sequence0Complete) { sequence0Complete = false; showValudeADC(LPC_ADC0); } if (sequence1Complete) { sequence1Complete = false; showValudeADC(LPC_ADC1); } } /* Should not run to here */ return 0; }
/** * @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; }