#include "Drv_adc.h" #include "system.h" //#define DEBUG_ADC /** * @brief calculate voltage ,acording reference value and reference voltage * @param result : adc result * vol_high_ref : high voltage reference value * vol_low_ref : low voltage reference value * vol_high : high reference voltage (mV) * vol_low : low reference voltage * @retval voltage (mV) */ static int calculate_voltage(int result, int vol_high_ref,int vol_low_ref , int vol_high, int vol_low) { int64_t rega = result*1000 - vol_low_ref; int regb = vol_high_ref - vol_low_ref; int regc = vol_high - vol_low; int temp = (rega *regc)/regb +vol_low; #ifdef DEBUG_ADC MyPrintf("rega*regc=%d\r\n",(rega*regc)); MyPrintf("rega=%x\r\n",rega); MyPrintf("regb=%d\r\n",regb); MyPrintf("regc=%d\r\n",regc); MyPrintf("temp=%d\r\n",temp); #endif return temp; } void ADC_Init(ADC_InitTypeDef *ADC_InitStruct) { _ASSERT(IS_ADC_CHANNEL(ADC_InitStruct->ADC_Channel)); _ASSERT(IS_ADC_MODE(ADC_InitStruct->ADC_Mode)); HWRITE(RF_ADC_MODE , 0x8f|(ADC_InitStruct->ADC_Mode)<<4); HWRITE(RFEN_ADC,0x7c);// adc_enable HWRITE(RF_ADC_GC, 0xaa); HWRITE(RF_ADC_CH, 0x30|ADC_InitStruct->ADC_Channel); HWRITE(CORE_SUM_EN,0x80);// ADC_SUM_EN } uint16_t ADC_GetResult(ADC_ChxTypeDef ADC_Channel) { int nop=WAIT_TIME; HWRITE(RFEN_ADC,0x7c);// adc_enable HWRITE(RF_ADC_GC, 0xaa); HWRITE(RF_ADC_CH, 0x30|ADC_Channel); HWRITE(CORE_SUM_EN,0x80);// ADC_SUM_EN while(nop--); return HREADW(CORE_SUMDATA); } int ADC_GetVoltage(ADC_ChxTypeDef ADC_Channel) { int result = 0; int i = 0,j = 0; int voltage_low = 500; int voltage_high = 1000; int reg_voltage_low = 0; int ref_voltage_high = 0; uint8_t getmode = ( HREAD(RF_ADC_MODE) & 0x70) >> 4; uint8_t data[14]={0}; read_otp_data(OTP_ADC_IO_0_5V_ADDR,data,14); // if((HREADW(OTP_ADC_FLAG_REG))!=OTP_ADC_FLAG) return -1; if (((data[13]<<8) |data[12])!= OTP_ADC_FLAG) return -1; switch(getmode) { case ADC_GPIO: // reg_voltage_low=(HREADW(GPIO_LOW_REF_REG))*1000; // ref_voltage_high=(HREADW(GPIO_HIGH_REF_REG))*1000; reg_voltage_low=((data[1]<<8) | data[0])*1000; ref_voltage_high=((data[7]<<8) | data[6])*1000; voltage_low = GPIO_LOW_VOLTAGE_REF; voltage_high = GPIO_HIGH_VOLTAGE_REF; break; case ADC_HVIN: // reg_voltage_low=(HREADW(HVIN_LOW_REF_REG))*1000; // ref_voltage_high=(HREADW(HVIN_HIGH_REF_REG))*1000; reg_voltage_low=((data[3]<<8) | data[2])*1000; ref_voltage_high=((data[9]<<8) | data[8])*1000; voltage_low = HVIN_LOW_VOLTAGE_REF; voltage_high = HVIN_HIGH_VOLTAGE_REF; break; case ADC_VINLPM: // reg_voltage_low=(HREADW(VINLPM_LOW_REF_REG))*1000; // ref_voltage_high=(HREADW(VINLPM_HIGH_REF_REG))*1000; reg_voltage_low=((data[5]<<8) | data[4])*1000; ref_voltage_high=((data[11]<<8) | data[10])*1000; voltage_low = VINLPM_LOW_VOLTAGE_REF; voltage_high = VINLPM_HIGH_VOLTAGE_REF; break; default: return -1; } if (reg_voltage_low == 0 || ref_voltage_high == 0) return -1; result = ADC_GetResult(ADC_Channel); #ifdef DEBUG_ADC MyPrintf("result=%x\r\n",result); #endif return calculate_voltage(result, ref_voltage_high, reg_voltage_low, voltage_high, voltage_low); }