void BSP_BatterCheckInit (void) { unsigned short cal_var; SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; BAT_PORT->PCR[BAT_PORT_Pin] &= ~PORT_PCR_MUX_MASK; BAT_PORT->PCR[BAT_PORT_Pin] |= PORT_PCR_MUX(0); BAT_ADC->CFG1 &= ~(ADC_CFG1_MODE_MASK); BAT_ADC->CFG1 |= ADC_CFG1_MODE (3); // BAT_ADC->CFG1 &= ~(ADC_CFG1_ADICLK_MASK); BAT_ADC->CFG1 |= (ADC_CFG1_ADICLK (0)); // BAT_ADC->CFG1 &= ~(ADC_CFG1_ADLSMP_MASK); // BAT_ADC->CFG1 &= ~(ADC_CFG1_ADIV_MASK); BAT_ADC->CFG1 |= ADC_CFG1_ADIV (3); // BAT_ADC->CFG2 = 0; // BAT_ADC->CFG2 |= (ADACKEN_DISABLED|ADHSC_HISPEED |ADC_CFG2_ADLSTS(ADLSTS_20)); BAT_ADC->CV1 = 0x1234u; BAT_ADC->CV2 = 0x5678u; BAT_ADC->SC2 = (ACFE_DISABLED|ACFGT_GREATER |ACREN_ENABLED|DMAEN_DISABLED |ADC_SC2_REFSEL(REFSEL_EXT)); BAT_ADC->SC3 = (CAL_OFF|ADCO_SINGLE|AVGE_ENABLED |ADC_SC3_AVGS(AVGS_32)); BAT_ADC->PGA = (PGAEN_DISABLED|PGACHP_NOCHOP|PGALP_NORMAL |ADC_PGA_PGAG(PGAG_64)); BAT_ADC->SC1[0] &= ~ADC_SC1_DIFF_MASK;// BAT_ADC->SC2 &= ~ADC_SC2_ADTRG_MASK; BAT_ADC->SC3 &= ( ~ADC_SC3_ADCO_MASK & ~ADC_SC3_AVGS_MASK ); BAT_ADC->SC3 |= ( ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(AVGS_32) ); BAT_ADC->SC3 |= ADC_SC3_CAL_MASK ; while((BAT_ADC->SC1[0] & ADC_SC1_COCO_MASK) == 0); if((BAT_ADC->SC3 & ADC_SC3_CALF_MASK) == CALF_FAIL){ }else{ cal_var = 0x00; cal_var = BAT_ADC->CLP0; cal_var += BAT_ADC->CLP1; cal_var += BAT_ADC->CLP2; cal_var += BAT_ADC->CLP3; cal_var += BAT_ADC->CLP4; cal_var += BAT_ADC->CLPS; cal_var = cal_var/2; cal_var |= 0x8000; // Set MSB BAT_ADC->PG = ADC_PG_PG(cal_var); // Calculate minus-side calibration cal_var = 0x00; cal_var = BAT_ADC->CLM0; cal_var += BAT_ADC->CLM1; cal_var += BAT_ADC->CLM2; cal_var += BAT_ADC->CLM3; cal_var += BAT_ADC->CLM4; cal_var += BAT_ADC->CLMS; cal_var = cal_var/2; cal_var |= 0x8000; // Set MSB BAT_ADC->MG = ADC_MG_MG(cal_var); BAT_ADC->SC3 &= ~ADC_SC3_CAL_MASK; } }
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); }
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; }
//------------------------------------------------------------ // Calibration du convertisseur AD // Retour: true = OK, false = KO //------------------------------------------------------------ bool iAd_Cal(void) { UInt16 aCalVar=0; bool aRet; // Max ADC clock -> 4MHz ADC1_CFG1&=((~ADC_CFG1_ADIV_MASK)&(~ADC_CFG1_ADICLK_MASK)); ADC1_CFG1|=(ADC_CFG1_ADIV(3)|ADC_CFG1_MODE(1)|ADC_CFG1_ADICLK(1)|ADC_CFG1_ADLSMP_MASK); // Enable Software Conversion Trigger for Calibration Process ADC1_SC2&=(~ADC_SC2_ADTRG_MASK); // Set single conversion, clear avgs bitfield for next writing ADC1_SC3&= ((~ADC_SC3_ADCO_MASK) & (~ADC_SC3_AVGS_MASK)); // Turn averaging ON and set at max value ( 32 ) ADC1_SC3|= (ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(3) ); // Start CAL ADC1_SC3 |= ADC_SC3_CAL_MASK ; // Wait calibration end while ( (ADC1_SC1A & ADC_SC1_COCO_MASK ) == false ); // Check for Calibration fail error and return if ((ADC1_SC3&ADC_SC3_CALF_MASK) == ADC_SC3_CALF_MASK) { aRet=false; // Clear CAL bit ADC1_SC3&= (~ADC_SC3_CAL_MASK); } else { // Calculate plus-side calibration aCalVar = 0x00; aCalVar = ADC1_CLP0; aCalVar += ADC1_CLP1; aCalVar += ADC1_CLP2; aCalVar += ADC1_CLP3; aCalVar += ADC1_CLP4; aCalVar += ADC1_CLPS; aCalVar = aCalVar/2; aCalVar |= 0x8000; // Set MSB ADC1_PG= ADC_PG_PG(aCalVar); // Calculate minus-side calibration aCalVar = 0x00; aCalVar = ADC1_CLM0; aCalVar += ADC1_CLM1; aCalVar += ADC1_CLM2; aCalVar += ADC1_CLM3; aCalVar += ADC1_CLM4; aCalVar += ADC1_CLMS; aCalVar = aCalVar/2; aCalVar |= 0x8000; // Set MSB ADC1_MG = ADC_MG_MG(aCalVar); // Clear CAL bit ADC1_SC3&= (~ADC_SC3_CAL_MASK); // Return OK aRet=true; } return aRet; }