int32_t adc_measure_pm2p5() { // uint16_t val = 0; if((ADC_SC2_REG(adc_ptr) & ADC_SC2_ADACT_MASK) == 0) { /* set once conversion mode */ ADC_SC3_REG(adc_ptr) = (ADC_SC3_REG(adc_ptr) & (~ADC_SC3_ADCO_MASK) | ADCO_SINGLE); /* set sw triger */ ADC_SC2_REG(adc_ptr) = (ADC_SC2_REG(adc_ptr) & (~ADC_SC2_ADTRG_MASK) | ADTRG_SW); ADC_SC1_REG(adc_ptr,0) = ADC_INPUT_CH; while(!(ADC_SC1_REG(adc_ptr,0) & ADC_SC1_COCO_MASK)){ //printf("adc calculating...\n"); //_time_delay(1); } val = (uint16_t) (ADC_R_REG(adc_ptr,0)); } else { printf("Conversion in progress...\n"); _time_delay(50); val = (uint16_t) (ADC_R_REG(adc_ptr,0)); } return val; }
void Io_Adc_Initialization(const Io_Adc_config_device *cnf_adc_ptr) { uint8 i; /* Copy the values from the channel configuration structure */ Io_Adc_ConfigPtr = cnf_adc_ptr; /* Initialize channels values */ Io_Adc_Data = &Io_Adc_Data_var; /* Current conversion channel set */ Io_Adc_Data->current_cnv_channel=0; /* Conversion ongoing set */ Io_Adc_Data->conversion_ongoing=0; /* Set buffer */ for (i=0; i< Io_Adc_ConfigPtr->adc_number_of_channels; i++) { Io_Adc_Data->adc_ch_data[i].adc_channel_value = 0; Io_Adc_Data->adc_ch_data[i].valid = INVALID; Io_Adc_Data->current_cnv_channel++; } /* Enable the Clock Gate Control for ADC */ SIM_SCGC6 |= SIM_SCGC6_ADC0(1); /* Status and control register2 contains the conversion active, hardware/software trigger select, compare function and voltage reference select of the ADC module * |-------|-------|-------|-------|-------|-------|-------| * | ADACT | ADTRG | ACFE | ACFGT | ACREN | DMAEN | REFSEL| * |_______|_______|_______|_______|_______|_______|_______| * Voltage reference. Possible values: * VREFH & VREFL->IO_ADC_SC2_VOLT_REFSEL_DEFAULT, * VALTH & VALTL->IO_ADC_SC2_VOLD_REFSEL_ALT * DMA. Possible values: * Disable->IO_ADC_SC2_DMA_DIS, * Enable->IO_ADC_SC2_DMA_EN * Compare function range. Possible values: * Range function disabled. Only CV1 is compared.->IO_ADC_SC2_RANGE_DIS, * Range function enabled. Both CV1 and CV2 are compared.->IO_ADC_SC2_RANGE_EN * Comp. func. greater than. Possible values: * Configures less than threshold, outside range not inclusive and inside range not inclusive; functionality based on the values placed in CV1 and CV2.->IO_ADC_SC2_COMP_FUNC_LES_THAN, * Configures greater than or equal to threshold, outside and inside ranges inclusive; functionality based on the values placed in CV1 and CV2.->IO_ADC_SC2_COMP_FUNC_GR_THAN, * Comp. func. Possible values: * Compare function disabled->IO_ADC_SC2_EN_COMP_FUNC, * Compare function enabled.->IO_ADC_SC2_DIS_COMP_FUNC * Conversion trigger. Possible values: * Software trigger selected.When software trigger is selected, a conversion is initiated following a write to SC1A.->IO_ADC_SC2_SOFT_TRIGGER, * Hardware trigger selected.->IO_ADC_SC2_HARD_TRIGGER * Conversion active. Possible values: * Conversion not in progress.->IO_ADC_SC2_CONV_NOT_PROGRESS, * Conversion in progress.->IO_ADC_SC2_CONV_IN_PROGRESS */ /* Select software trigger */ ADC_SC2_REG(ADC0) = IO_ADC_SC2_VOLT_REFSEL_DEFAULT | IO_ADC_SC2_DMA_DIS | IO_ADC_SC2_RANGE_DIS | IO_ADC_SC2_COMP_FUNC_LESS_THAN | IO_ADC_SC2_EN_COMP_FUNC | IO_ADC_SC2_SOFT_TRIGGER | IO_ADC_SC2_CONV_NOT_PROGRESS; }
uint8 ADC_Cal (ADC_MemMapPtr adcmap) { /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ unsigned short cal_var; /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~*/ ADC_SC2_REG(adcmap) &= ~ADC_SC2_ADTRG_MASK; // Enable Software Conversion Trigger for Calibration Process - ADC0_SC2 = ADC0_SC2 | ADC_SC2_ADTRGW(0); ADC_SC3_REG(adcmap) &= (~ADC_SC3_ADCO_MASK &~ADC_SC3_AVGS_MASK); // set single conversion, clear avgs bitfield for next writing ADC_SC3_REG(adcmap) |= (ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(AVGS_32)); // Turn averaging ON and set at max value ( 32 ) ADC_SC3_REG(adcmap) |= ADC_SC3_CAL_MASK; // Start CAL while((ADC_SC1_REG(adcmap, A) & ADC_SC1_COCO_MASK) == COCO_NOT); // Wait calibration end if((ADC_SC3_REG(adcmap) & ADC_SC3_CALF_MASK) == CALF_FAIL) { return(1); // Check for Calibration fail error and return } // Calculate plus-side calibration cal_var = 0x00; cal_var = ADC_CLP0_REG(adcmap); cal_var += ADC_CLP1_REG(adcmap); cal_var += ADC_CLP2_REG(adcmap); cal_var += ADC_CLP3_REG(adcmap); cal_var += ADC_CLP4_REG(adcmap); cal_var += ADC_CLPS_REG(adcmap); cal_var = cal_var / 2; cal_var |= 0x8000; // Set MSB ADC_PG_REG(adcmap) = ADC_PG_PG(cal_var); // Calculate minus-side calibration cal_var = 0x00; cal_var = ADC_CLM0_REG(adcmap); cal_var += ADC_CLM1_REG(adcmap); cal_var += ADC_CLM2_REG(adcmap); cal_var += ADC_CLM3_REG(adcmap); cal_var += ADC_CLM4_REG(adcmap); cal_var += ADC_CLMS_REG(adcmap); cal_var = cal_var / 2; cal_var |= 0x8000; // Set MSB ADC_MG_REG(adcmap) = ADC_MG_MG(cal_var); ADC_SC3_REG(adcmap) &= ~ADC_SC3_CAL_MASK; /* Clear CAL bit */ return(0); }
void ADC_Config_Alt(ADC_MemMapPtr adcmap, tADC_ConfigPtr ADC_CfgPtr) { ADC_CFG1_REG(adcmap) = ADC_CfgPtr->CONFIG1; ADC_CFG2_REG(adcmap) = ADC_CfgPtr->CONFIG2; ADC_CV1_REG(adcmap) = ADC_CfgPtr->COMPARE1; ADC_CV2_REG(adcmap) = ADC_CfgPtr->COMPARE2; ADC_SC2_REG(adcmap) = ADC_CfgPtr->STATUS2; ADC_SC3_REG(adcmap) = ADC_CfgPtr->STATUS3; //ADC_PGA_REG(adcmap) = ADC_CfgPtr->PGA; pbd ADC_SC1_REG(adcmap,A)= ADC_CfgPtr->STATUS1A; ADC_SC1_REG(adcmap,B)= ADC_CfgPtr->STATUS1B; }
/****************************************************************************** Function Name : ADC0__Config (from Inga Harris' Nucleus ADC0_ Validation) Engineer : r54940 Date : 04/08/08 Parameters : Returns : NONE Notes : Configures ADC0_ ******************************************************************************/ void ADC_Config(ADC_MemMapPtr adcmap, uint8_t CONFIG1, uint8_t CONFIG2, uint16_t COMPARE1, uint16_t COMPARE2, uint8_t STATUS2, uint8_t STATUS3, uint8_t STATUS1A, uint8_t STATUS1B, uint32_t PGA ) { ADC_CFG1_REG(adcmap) = CONFIG1; ADC_CFG2_REG(adcmap) = CONFIG2; ADC_CV1_REG(adcmap) = COMPARE1; ADC_CV2_REG(adcmap) = COMPARE2; ADC_SC2_REG(adcmap) = STATUS2; ADC_SC3_REG(adcmap) = STATUS3; ADC_SC1_REG(adcmap,A) = STATUS1A; ADC_SC1_REG(adcmap,B) = STATUS1B; ADC_PGA_REG(adcmap) = PGA; }
void main(void) { adc_init(); dma_init(); enter_thread_mode(); sema_wait(&adc_start_sema); struct dma_ctx *ctx; ctx = dma_setup(DMAMUX_ADC0, &ADC_R_REG(ADC0, 0), dstbuf, 2, sizeof(dstbuf)/2, DMA_SRC_STICKY | DMA_DOUBLEBUF | DMA_LOOP, dma_done, NULL); adc_sample_prepare(ADC_MODE_CONTINUOUS); bf_set_reg(ADC_SC2_REG(ADC0), ADC_SC2_DMAEN, 1); ADC_SC1_REG(ADC0, 0) = ADC_SC1_ADCH(0) | ADC_SC1_DIFF_MASK; wait(main); }
int adc_init() { adc_pixelIndex = 0; // disable ADC irq - not ready yet disable_irq(ADC_IRQ_NUM); // turn on clock to ADC0 SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK); // to setup SW trigger on FTM2 SIM_SOPT7 = SIM_SOPT7_ADC0TRGSEL(10); // to calibrate the ADC module unsigned short cal_var; cal_var = 0x0000; // add the plus-side calibration results cal_var += ADC_CLP0_REG(ADC0_BASE_PTR); cal_var += ADC_CLP1_REG(ADC0_BASE_PTR); cal_var += ADC_CLP2_REG(ADC0_BASE_PTR); cal_var += ADC_CLP3_REG(ADC0_BASE_PTR); cal_var += ADC_CLP4_REG(ADC0_BASE_PTR); cal_var += ADC_CLPS_REG(ADC0_BASE_PTR); cal_var /= 2; cal_var |= 0x8000; // store value in plus-side gain calibration register (PG) ADC_PG_REG(ADC0_BASE_PTR) = ADC_PG_PG(cal_var); cal_var = 0x0000; // add the minus-side calibration results cal_var += ADC_CLM0_REG(ADC0_BASE_PTR); cal_var += ADC_CLM1_REG(ADC0_BASE_PTR); cal_var += ADC_CLM2_REG(ADC0_BASE_PTR); cal_var += ADC_CLM3_REG(ADC0_BASE_PTR); cal_var += ADC_CLM4_REG(ADC0_BASE_PTR); cal_var += ADC_CLMS_REG(ADC0_BASE_PTR); cal_var /= 2; cal_var |= 0x8000; // store value in minus-side gain calibration register (MG) ADC_MG_REG(ADC0_BASE_PTR) = ADC_MG_MG(cal_var); ADC_SC3_REG(ADC0_BASE_PTR) &= ~ADC_SC3_CAL_MASK; // to set the configuration register 1 (CFG1) to select the mode of // operation, clock source, clock divide, and configuration for low // power or long sample time ADC_CFG1_REG(ADC0_BASE_PTR) = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_1) | ADLSMP_SHORT | ADC_CFG1_MODE(MODE_8) | ADC_CFG1_ADICLK(ADICLK_BUS); // to set the configuration register 2 (CFG2) to select the special // high-speed configuration for very high speed conversions and // select the long sample time duration during long sample mode ADC_CFG2_REG(ADC0_BASE_PTR) = MUXSEL_ADCA | ADACKEN_DISABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_2); // to configure the status and control register 2 (SC2) ADC_SC2_REG(ADC0_BASE_PTR) = ADTRG_SW | ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_DISABLED | ADC_SC2_REFSEL(REFSEL_EXT); // to configure the status and control register 3 (SC3) // enable hw averaging, 16 samples taken ADC_SC3_REG(ADC0_BASE_PTR) = CAL_OFF | ADCO_SINGLE | AVGE_ENABLED | ADC_SC3_AVGS(AVGS_16); // to configure the status and control register 1 (SC1) // enable the interrupt, single-ended conversion, on AD18 ADC_SC1_REG(ADC0_BASE_PTR, A)= AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(18); // to configure the PGA register ADC_PGA_REG(ADC0_BASE_PTR) = PGAEN_DISABLED | PGACHP_NOCHOP | PGALP_NORMAL | ADC_PGA_PGAG(PGAG_64); // enable ADC irq enable_irq(ADC_IRQ_NUM); return ADC_RET_SUCCESS; }
int adcc_init(int adc_num) { //PORT_MemMapPtr pctl = NULL; //uint8_t gpio_port; /* led pin init */ if(!lwgpio_init(&pm2p5_ledgpio, PM2P5_LED_PWREN, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE)) { printf("Initializing GPIO with associated pins failed.\n"); _time_delay (200L); _task_block(); } lwgpio_set_functionality(&pm2p5_ledgpio, PM2P5_LED_MUX_GPIO); //lwgpio_set_value(&pm2p5_ledgpio, LWGPIO_VALUE_LOW); lwgpio_set_value(&pm2p5_ledgpio, LWGPIO_VALUE_HIGH); if(adc_num == 0) { /* SIM_SCGC6: ADC0=1 */ adc_ptr = ADC0_BASE_PTR; SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK; } else { adc_ptr = ADC1_BASE_PTR; SIM_SCGC6 |= SIM_SCGC6_ADC1_MASK; } #ifdef ADC_HW_TRIGER SIM_SCGC6 |= SIM_SCGC6_PIT_MASK; /* enable PIT */ SIM_SOPT7 |= SIM_SOPT7_ADC1ALTTRGEN_MASK; SIM_SOPT7 |= (SIM_SOPT7_ADC1PRETRGSEL_MASK); /* Pre Trigger B */ SIM_SOPT7 &= ~(SIM_SOPT7_ADC1TRGSEL_MASK); SIM_SOPT7 |= SIM_SOPT7_ADC1TRGSEL(7); /* PIT trigger 3 */ PIT_MCR_REG(PIT_BASE_PTR) = 0; #endif // pin mux config : spec P216 ADC0_DP0/ADC1_DP3 is default /* set pin's multiplexer to analog gpio_port = ADC_SIG_PORTB | 4; pctl = (PORT_MemMapPtr) PORTB_BASE_PTR; pctl->PCR[gpio_port & 0x1F] &= ~PORT_PCR_MUX_MASK; */ // Initialize ADC0/1 ================================================================================= //averages (4 h/w) // bus 60M /8/2 = 3.75M ADC clock ADC_CFG1_REG(adc_ptr) = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_8) /*| ADLSMP_LONG*/ | ADC_CFG1_MODE(MODE_16) | ADC_CFG1_ADICLK(/*ADICLK_BUS_2*/ADICLK_BUS); // do calibration if(adc_calibrate(adc_ptr)) printf("adc-%x calibrate failed\n",(int)adc_ptr); /* channel A/B selected */ #ifdef ADC_HW_TRIGER ADC_CFG2_REG(adc_ptr) = MUXSEL_ADCB | ADACKEN_ENABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_20); #else ADC_CFG2_REG(adc_ptr) = MUXSEL_ADCA /*| ADACKEN_ENABLED */| ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_20); #endif //ADC_CV1_REG(adc_ptr) = 0x0; //ADC_CV2_REG(adc_ptr) = 0x0; //ADC_SC1_REG(adc_ptr,0) = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(ADC_INPUT_CH); /* SC1 A */ //ADC_SC1_REG(adc_ptr,1) = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(ADC_INPUT_CH); /* SC1 B */ #ifdef ADC_HW_TRIGER ADC_SC2_REG(adc_ptr) = ADTRG_HW /*ADTRG_SW*/ | ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_DISABLED /* DMAEN_ENABLED*/| ADC_SC2_REFSEL(REFSEL_EXT); #else ADC_SC2_REG(adc_ptr) = ADTRG_SW /*| ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_DISABLED*/ | ADC_SC2_REFSEL(REFSEL_EXT); #endif ADC_SC3_REG(adc_ptr) = /*ADC_SC3_CALF_MASK |*/ CAL_OFF | ADCO_SINGLE /*| AVGE_ENABLED | ADC_SC3_AVGS(AVGS_4)*/; /* averages 4 h/w */ }