/*********************************************************************//** * @brief Get ADC result * @param[in] channel channel number * @return Data conversion * ************************************************************************/ uint16_t ADC_ChannelGetData(uint8_t channel) { uint32_t adc_value; CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel)); adc_value = *(uint32_t *) ((&LPC_ADC->DR[0]) + channel); return ADC_DR_RESULT(adc_value); }
/** * @brief Get ADC result * @param[in] ADCx pointer to ADC * @param[in] channel channel number * @return Data conversion * *********************************************************************/ uint16_t ADC_ChannelGetData(ADC_TypeDef *ADCx, uint8_t channel) { uint32_t adc_value; CHECK_PARAM(PARAM_ADCx(ADCx)); CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel)); adc_value = *(uint32_t *) ((&ADCx->ADDR0) + channel); return ADC_DR_RESULT(adc_value); }
/* Get the ADC value */ LPC_Status readAdcVal(LPC_ADC_T *pADC, uint8_t channel, uint16_t *data) { uint32_t temp; temp = pADC->DR[channel]; if (!ADC_DR_DONE(temp)) { return ERROR; } /* if(ADC_DR_OVERRUN(temp) && (pADC->CR & ADC_CR_BURST)) */ /* return ERROR; */ *data = (uint16_t) ADC_DR_RESULT(temp); return SUCCESS; }
/** * @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); } } }
/* DMA routine for ADC example */ static void App_DMA_Test(void) { uint16_t dataADC; /* Initialize GPDMA controller */ Chip_GPDMA_Init(LPC_GPDMA); /* Setting GPDMA interrupt */ NVIC_DisableIRQ(DMA_IRQn); NVIC_SetPriority(DMA_IRQn, ((0x01 << 3) | 0x01)); NVIC_EnableIRQ(DMA_IRQn); /* Setting ADC interrupt, ADC Interrupt must be disable in DMA mode */ NVIC_DisableIRQ(_LPC_ADC_IRQ); Chip_ADC_Int_SetChannelCmd(_LPC_ADC_ID, _ADC_CHANNLE, ENABLE); /* Get the free channel for DMA transfer */ dmaChannelNum = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, _GPDMA_CONN_ADC); /* Enable burst mode if any, the AD converter does repeated conversions at the rate selected by the CLKS field in burst mode automatically */ if (Burst_Mode_Flag) { Chip_ADC_SetBurstCmd(_LPC_ADC_ID, ENABLE); } /* Get adc value until get 'x' character */ while (DEBUGIN() != 'x') { /* Start A/D conversion if not using burst mode */ if (!Burst_Mode_Flag) { Chip_ADC_SetStartMode(_LPC_ADC_ID, ADC_START_NOW, ADC_TRIGGERMODE_RISING); } channelTC = 0; Chip_GPDMA_Transfer(LPC_GPDMA, dmaChannelNum, _GPDMA_CONN_ADC, (uint32_t) &DMAbuffer, GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, 1); /* Waiting for reading ADC value completed */ while (channelTC == 0) {} /* Get the ADC value fron Data register*/ dataADC = ADC_DR_RESULT(DMAbuffer); App_print_ADC_value(dataADC); } /* Disable interrupts, release DMA channel */ Chip_GPDMA_Stop(LPC_GPDMA, dmaChannelNum); NVIC_DisableIRQ(DMA_IRQn); /* Disable burst mode if any */ if (Burst_Mode_Flag) { Chip_ADC_SetBurstCmd(_LPC_ADC_ID, DISABLE); } }
int main(void) { boardInit(); SysTick_Config(SystemCoreClock / TICKRATE_HZ); dsPuts(&streamUart, strHello); while (1) { promptProcess(&adcEvalPromptData, &streamUart); /* Is a conversion sequence complete? */ if(sequenceComplete) { sequenceComplete = false; /* Get raw sample data for channels 0-11 */ for (uint16_t i = 0; i < 12; i++) { uint32_t rawSample = Chip_ADC_GetDataReg(LPC_ADC, i); /* Show some ADC data */ if (rawSample & (ADC_DR_OVERRUN | ADC_SEQ_GDAT_DATAVALID)) { printDecNzU16(&streamUart, i); dsPuts(&streamUart, strIs); printDecU16(&streamUart, ADC_DR_RESULT(rawSample)); dsPuts(&streamUart, strSep); } } dsPuts(&streamUart, strCrLf); } } return 0 ; }
/** * @brief Main program body */ int c_entry(void) { PINSEL_CFG_Type PinCfg; GPDMA_Channel_CFG_Type GPDMACfg; uint32_t adc_value, tmp; // DeInit NVIC and SCBNVIC NVIC_DeInit(); NVIC_SCBDeInit(); /* Configure the NVIC Preemption Priority Bits: * two (2) bits of preemption priority, six (6) bits of sub-priority. * Since the Number of Bits used for Priority Levels is five (5), so the * actual bit number of sub-priority is three (3) */ NVIC_SetPriorityGrouping(0x05); // Set Vector table offset value #if (__RAM_MODE__==1) NVIC_SetVTOR(0x10000000); #else NVIC_SetVTOR(0x00000000); #endif /* * Initialize debug via UART */ debug_frmwrk_init(); // print welcome screen print_menu(); /* GPDMA block section -------------------------------------------- */ /* Disable GPDMA interrupt */ NVIC_DisableIRQ(DMA_IRQn); /* preemption = 1, sub-priority = 1 */ NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01)); /* * Init LPC_ADC pin connect * AD0.2 on P0.25 */ PinCfg.Funcnum = 1; PinCfg.OpenDrain = 0; PinCfg.Pinmode = 0; PinCfg.Pinnum = 25; PinCfg.Portnum = 0; PINSEL_ConfigPin(&PinCfg); /* Configuration for ADC : * Frequency at 1Mhz * ADC channel 2, generate interrupt to make a request for DMA source */ ADC_Init(LPC_ADC, 1000000); ADC_IntConfig(LPC_ADC,ADC_ADINTEN2,SET); ADC_ChannelCmd(LPC_ADC,ADC_CHANNEL_2,SET); /* Initialize GPDMA controller */ GPDMA_Init(); // Setup GPDMA channel -------------------------------- // channel 0 GPDMACfg.ChannelNum = 0; // Source memory - unused GPDMACfg.SrcMemAddr = 0; // Destination memory GPDMACfg.DstMemAddr = (uint32_t) &adc_value; // Transfer size GPDMACfg.TransferSize = DMA_SIZE; // Transfer width - unused GPDMACfg.TransferWidth = 0; // Transfer type GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M; // Source connection GPDMACfg.SrcConn = GPDMA_CONN_ADC; // Destination connection - unused GPDMACfg.DstConn = 0; // Linker List Item - unused GPDMACfg.DMALLI = 0; // Setup channel with given parameter GPDMA_Setup(&GPDMACfg, GPDMA_Callback); /* Reset terminal counter */ Channel0_TC = 0; /* Reset Error counter */ Channel0_Err = 0; /* Enable GPDMA interrupt */ NVIC_EnableIRQ(DMA_IRQn); while (1) { // Enable GPDMA channel 0 GPDMA_ChannelCmd(0, ENABLE); ADC_StartCmd(LPC_ADC,ADC_START_NOW); /* Wait for GPDMA processing complete */; while ((Channel0_TC == 0) ); // Disable GPDMA channel 0 GPDMA_ChannelCmd(0, DISABLE); //Display the result of conversion on the UART0 _DBG("ADC value on channel 2: "); _DBD32(ADC_DR_RESULT(adc_value)); _DBG_(""); // Wait for a while for(tmp = 0; tmp < 1000000; tmp++); // Re-setup channel GPDMA_Setup(&GPDMACfg, GPDMA_Callback); /* Reset terminal counter */ Channel0_TC = 0; /* Reset Error counter */ Channel0_Err = 0; } ADC_DeInit(LPC_ADC); return 1; }
/*********************************************************************//** * @brief Get ADC result * @param[in] ADCx pointer to LPC_ADC_TypeDef, should be: LPC_ADC * @param[in] channel: channel number, should be 0...7 * @return Data conversion **********************************************************************/ uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel) { uint32_t adc_value; adc_value = *(uint32_t *) ((&ADCx->DR[0]) + channel); return ADC_DR_RESULT(adc_value); }
/** * @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; }
/** * @brief Handler for the systick timer; increments counters, etc. */ void SysTick_Handler(void) { //static uint32_t blink_counter = 0; static uint32_t sample_counter_temp = 0; static uint32_t sample_counter_rh = 10; static uint32_t sample_counter_mag = 20; static int_fp mag_x=0, mag_y=0, mag_z=0; static uint32_t sample_counter_range = 30; static uint32_t left_sw_hold_counter = 0; static uint8_t left_sw_engaged = 0; static uint32_t right_sw_hold_counter = 0; static uint8_t right_sw_engaged = 0; g_delayms_counter += MS_PER_TICK; sample_counter_temp++; if (sample_counter_temp > SAMPLE_PERIOD_TEMP) { Plot_AddSample(&g_plot_temp, HTU21D_GetTemp(&g_HTU21D)); sample_counter_temp = 0; } sample_counter_rh++; if (sample_counter_rh > SAMPLE_PERIOD_RH) { Plot_AddSample(&g_plot_rh, HTU21D_GetRH(&g_HTU21D)); sample_counter_rh = 0; } sample_counter_mag++; if (sample_counter_mag > SAMPLE_PERIOD_MAG) { HMC5883L_GetXYZ(&g_HMC5883L, &mag_x, &mag_y, &mag_z); Plot_AddSample(&g_plot_mag, mag_z); Compass_UpdateXY(&g_compass, mag_x, -mag_y); sample_counter_mag = 0; } sample_counter_range++; if (sample_counter_range > SAMPLE_PERIOD_RANGE) { if (g_adc_sample_ready) { g_adc_sample_ready = 0; sample_counter_range = 0; g_range_raw = ADC_DR_RESULT(Chip_ADC_GetDataReg(LPC_ADC, MoonLander_IO8_ADC)); Chip_ADC_StartSequencer(LPC_ADC, ADC_SEQA_IDX); } } if (left_sw_engaged) { if (Chip_GPIO_GetPinState(LPC_GPIO_PORT, 0, SW_LEFT)) { left_sw_engaged = 0; left_sw_hold_counter = 0; } else { left_sw_hold_counter += MS_PER_TICK; if (left_sw_hold_counter >= SW_OFF_HOLD_TIME_MS) { g_go_to_sleep = 1; left_sw_hold_counter = 0; left_sw_engaged = 0; } } } if (right_sw_engaged) { if (Chip_GPIO_GetPinState(LPC_GPIO_PORT, 0, SW_RIGHT)) { right_sw_engaged = 0; right_sw_hold_counter = 0; } else { right_sw_hold_counter += MS_PER_TICK; if (right_sw_hold_counter >= SW_OFF_HOLD_TIME_MS) { g_go_to_sleep = 1; right_sw_hold_counter = 0; right_sw_engaged = 0; } } } if (g_sw_left_debouncing) { left_sw_engaged = 1; g_sw_left_debounce_counter += MS_PER_TICK; if (g_sw_left_debounce_counter >= SW_DEBOUNCE_MS) { g_sw_left_debouncing = 0; g_sw_left_debounce_counter = 0; } } if (g_sw_right_debouncing) { right_sw_engaged = 1; g_sw_right_debounce_counter += MS_PER_TICK; if (g_sw_right_debounce_counter >= SW_DEBOUNCE_MS) { g_sw_right_debouncing = 0; g_sw_right_debounce_counter = 0; } } g_millis_counter += MS_PER_TICK; }
/*********************************************************************//** * @brief c_entry: Main ADC program body * @param[in] None * @return None **********************************************************************/ void c_entry(void) { GPDMA_Channel_CFG_Type GPDMACfg; volatile uint32_t adc_value, tmp; uint8_t quit; /* Initialize debug via UART0 * ?115200bps * ?8 data bit * ?No parity * ?1 stop bit * ?No flow control */ debug_frmwrk_init(); // print welcome screen print_menu(); /* Initialize ADC ----------------------------------------------------*/ /* Settings for AD input pin */ PINSEL_ConfigPin (BRD_ADC_PREPARED_CH_PORT, BRD_ADC_PREPARED_CH_PIN, BRD_ADC_PREPARED_CH_FUNC_NO); PINSEL_SetAnalogPinMode(BRD_ADC_PREPARED_CH_PORT,BRD_ADC_PREPARED_CH_PIN,ENABLE); /* Configuration for ADC : * ADC conversion rate = 400KHz */ ADC_Init(LPC_ADC, 400000); ADC_IntConfig(LPC_ADC, BRD_ADC_PREPARED_INTR, ENABLE); ADC_ChannelCmd(LPC_ADC, BRD_ADC_PREPARED_CHANNEL, ENABLE); /* GPDMA block section -------------------------------------------- */ /* Disable GPDMA interrupt */ NVIC_DisableIRQ(DMA_IRQn); /* preemption = 1, sub-priority = 1 */ NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01)); /* Initialize GPDMA controller */ GPDMA_Init(); // Setup GPDMA channel -------------------------------- // channel 0 GPDMACfg.ChannelNum = 0; // Source memory - unused GPDMACfg.SrcMemAddr = 0; // Destination memory GPDMACfg.DstMemAddr = (uint32_t) &adc_value; // Transfer size GPDMACfg.TransferSize = DMA_SIZE; // Transfer width - unused GPDMACfg.TransferWidth = 0; // Transfer type GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M; // Source connection GPDMACfg.SrcConn = GPDMA_CONN_ADC; // Destination connection - unused GPDMACfg.DstConn = 0; // Linker List Item - unused GPDMACfg.DMALLI = 0; GPDMA_Setup(&GPDMACfg); /* Reset terminal counter */ Channel0_TC = 0; /* Reset Error counter */ Channel0_Err = 0; /* Enable GPDMA interrupt */ NVIC_EnableIRQ(DMA_IRQn); while (1) { // Enable GPDMA channel 0 GPDMA_ChannelCmd(0, ENABLE); ADC_StartCmd(LPC_ADC, ADC_START_NOW); /* Wait for GPDMA processing complete */ while ((Channel0_TC == 0)); // Disable GPDMA channel 0 GPDMA_ChannelCmd(0, DISABLE); //Display the result of conversion on the UART _DBG("ADC value on channel "); _DBD(BRD_ADC_PREPARED_CHANNEL); _DBG(" is: "); _DBD32(ADC_DR_RESULT(adc_value)); _DBG_(""); // Wait for a while for(tmp = 0; tmp < 1000000; tmp++); /* GPDMA Re-setup */ GPDMA_Setup(&GPDMACfg); /* Reset terminal counter */ Channel0_TC = 0; /* Reset Error counter */ Channel0_Err = 0; if(_DG_NONBLOCK(&quit) && (quit == 'Q' || quit == 'q')) break; } _DBG_("Demo termination!!!"); ADC_DeInit(LPC_ADC); }