Index: sdk/yc_adc.h
===================================================================
--- /YC3121_SDK/fw/sdk/yc_adc.h	(revision 823)
+++ /YC3121_SDK/fw/sdk/yc_adc.h	(working copy)
@@ -1,8 +1,10 @@
 /*
 File Name    : yc_adc.h
 Author       : Yichip
-Version      : V1.1
-Date         : 2020/07/14
+Version      : V1.2
+Notes        :  1. add ADC_Calibration_Para function
+                2. calculate_voltage absolute value return it
+Date         : 2021/08/02
 Description  : ADC encapsulation.
 */
 

Index: sdk/yc_adc.c
===================================================================
--- /YC3121_SDK/fw/sdk/yc_adc.c	(revision 823)
+++ /YC3121_SDK/fw/sdk/yc_adc.c	(working copy)
@@ -1,17 +1,77 @@
 /*
 File Name    : yc_adc.c
 Author       : Yichip
-Version      : V1.1
-Date         : 2020/07/14
+Version      : V1.2
+Notes        :  1. add ADC_Calibration_Para function
+                2. calculate_voltage absolute value return it
+Date         : 2021/08/02
 Description  : ADC encapsulation.
 */
+
+
 #include "yc_adc.h"
 
 #define ADC_RESULT (0x7FE&ADC_RDATA)
 
+
+/*@Note        ：Otp parameter calibration channel select the channel in use.
+                By default, GPIO40 and ADC_CHANNEL_3 are used as the calibration channels.*/
+#define ADC_CALIBR_OPEN
+#define ADC_1V_DIFF_VALUE       (0x20)
+#define ADC_CALIB_0V_GPIO       (40)
+#define ADC_CALIB_0V_CHANNEL    (ADC_CHANNEL_3)
+
 extern Boolean ipc_inited;
 static int calculate_voltage(int result, int vol_high_ref, int vol_low_ref, int vol_high, int vol_low);
 uint8_t r_otp_ref_para[16];
+static int io_vol_low_ref = 0;
+static int io_vol_high_ref = 0;
+
+static void ADC_Calibration_Para(void)
+{
+    int adc_0v_value = 0;
+    int adc_1v_value = 0;
+    uint8_t cnt = 5;
+    
+    /*get 0v ad value*/
+    
+    uint8_t gpio_func = GPIO_CONFIG(ADC_CALIB_0V_GPIO);
+    GPIO_CONFIG(ADC_CALIB_0V_GPIO) = OUTPUT_LOW ;
+    delay_ms(5);
+    while(cnt -- )
+    {
+        adc_0v_value = ADC_GetResult(ADC_CALIB_0V_CHANNEL);
+        MyPrintf("adc_0v_value = 0x%x\n");
+        if(adc_0v_value > 0x3e0 && adc_0v_value < 0x420)
+        {
+            break;
+        }
+        delay_ms(100);
+    }
+    GPIO_CONFIG(ADC_CALIB_0V_GPIO) = gpio_func;
+    
+    /*Calibration 1v para*/
+    
+    int k = ((((r_otp_ref_para[3] << 8) | r_otp_ref_para[2]) -  adc_0v_value)*1000)/ IO_LOW_VOLTAGE_REF;
+    adc_1v_value =  (IO_LOW_VOLTAGE_REF * k + (((r_otp_ref_para[3] << 8) | r_otp_ref_para[2])*1000))/1000;
+    
+    int diff = adc_1v_value > ((r_otp_ref_para[9] << 8) | r_otp_ref_para[8])? adc_1v_value -  ((r_otp_ref_para[9] << 8) | r_otp_ref_para[8]): ((r_otp_ref_para[9] << 8) | r_otp_ref_para[8]) - adc_1v_value;
+    if(diff > ADC_1V_DIFF_VALUE)
+    {
+        r_otp_ref_para[9] = r_otp_ref_para[3];
+        r_otp_ref_para[8] = r_otp_ref_para[2];
+        r_otp_ref_para[2] = adc_0v_value & 0xff;
+        r_otp_ref_para[3] = adc_0v_value >> 8 & 0xff;
+        io_vol_low_ref = 0;
+        io_vol_high_ref = IO_LOW_VOLTAGE_REF;
+    }
+    else
+    {
+        io_vol_low_ref = IO_LOW_VOLTAGE_REF;
+        io_vol_high_ref = IO_HIHG_VOLTAGE_REF;
+    }
+    return ;
+}
 
 void ADC_Init(ADC_InitTypeDef *ADC_InitStruct)
 {
@@ -35,6 +95,17 @@
     
     //read otp reference
     read_otp(ADC_REF_OTP_ADDR, r_otp_ref_para, 16);
+    
+    delay_ms(100);
+    
+#ifdef  ADC_CALIBR_OPEN
+    /*adc calibration*/
+    ADC_Calibration_Para();
+#else
+    io_vol_low_ref = IO_LOW_VOLTAGE_REF;
+    io_vol_high_ref = IO_HIHG_VOLTAGE_REF;
+#endif
+    
 }
 
 uint16_t  ADC_GetResult(ADC_ChxTypeDef ADC_Channel)
@@ -103,6 +174,7 @@
 
 int ADC_GetVoltage(ADC_ChxTypeDef ADC_Channel)
 {
+    int v_rang = 0;
     int result = 0;
     int i = 0, j = 0;
     int voltage_low  = 2800;
@@ -120,8 +192,9 @@
     case ADC_GPIO:
         reg_voltage_low  = ((r_otp_ref_para[3] << 8) | r_otp_ref_para[2]) * 1000;
         ref_voltage_high = ((r_otp_ref_para[9] << 8) | r_otp_ref_para[8]) * 1000;
-        voltage_low = IO_LOW_VOLTAGE_REF;
-        voltage_high = IO_HIHG_VOLTAGE_REF;
+        voltage_low = io_vol_low_ref;
+        voltage_high = io_vol_high_ref;
+        v_rang = 1200;
         break;
 
     case ADC_HVIN:
@@ -129,6 +202,7 @@
         ref_voltage_high = ((r_otp_ref_para[11] << 8) | r_otp_ref_para[10]) * 1000; //OTP中5.0V校准值
         voltage_low = HVIN_LOW_VOLTAGE_REF;
         voltage_high = HVIN_HIHG_VOLTAGE_REF;
+        v_rang = 5500;
         break;
 
     case ADC_VINLPM:
@@ -136,6 +210,7 @@
         ref_voltage_high = ((r_otp_ref_para[11] << 8) | r_otp_ref_para[10]) * 1000;
         voltage_low = VINLPM_LOW_VOLTAGE_REF;
         voltage_high = VINLPM_HIHG_VOLTAGE_REF;
+        v_rang = 1200;
         break;
     default:
         return -1;
@@ -171,7 +246,8 @@
     {
         result += adc_result_buf[i];
     }
-    return result / (FILT_NUM - 2 * REMOVE_NUM);
+    result /=  (FILT_NUM - 2 * REMOVE_NUM);
+    return result > v_rang ? v_rang : result;
 }
 
 /**
@@ -189,5 +265,5 @@
     int regb = vol_high_ref - vol_low_ref;
     int regc = vol_high - vol_low;
     int temp = (rega * regc) / regb + vol_low;
-    return temp;
+    return temp > 0 ? temp : (0 - temp);
 }
