524 lines
15 KiB
C
524 lines
15 KiB
C
/*================================================================
|
||
Copyright (c) 2019 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||
Quectel Wireless Solution Proprietary and Confidential.
|
||
=================================================================*/
|
||
|
||
/*=================================================================
|
||
|
||
EDIT HISTORY FOR MODULE
|
||
|
||
This section contains comments describing changes made to the module.
|
||
Notice that changes are listed in reverse chronological order.
|
||
|
||
WHEN WHO WHAT, WHERE, WHY
|
||
------------ ------- -------------------------------------------------------------------------------
|
||
06/05/2019 Fitz Init version
|
||
=================================================================*/
|
||
#include <stdio.h>
|
||
#include "quec_adc.h"
|
||
#include "quec_include.h"
|
||
#include "quec_debug.h"
|
||
//#include "quec_urc.h"
|
||
#include "guilin.h"
|
||
#include "UART.h"
|
||
#include "MRD.h"
|
||
|
||
extern BOOL PMIC_IS_PM803(void);
|
||
extern BOOL PMIC_IS_PM802(void);
|
||
extern BOOL PMIC_IS_PM803L(void);
|
||
extern BOOL PMIC_IS_PM807(void);
|
||
|
||
|
||
extern UINT32 get_cranel_adc0(void);
|
||
extern UINT32 get_cranel_adc1(void);
|
||
extern UINT16 get_cranel_vbat(void);
|
||
|
||
|
||
#ifndef MIN_SYS
|
||
|
||
#if defined QUEC_ADC_SUPPORT
|
||
|
||
/*========================================================================
|
||
* Macro Definition
|
||
*========================================================================*/
|
||
#ifdef QUEC_ATCMD_LOG
|
||
#define quec_adc_log(msg, ...) custom_log("QUEC_ADC", msg, ##__VA_ARGS__)
|
||
#else
|
||
#define quec_adc_log(msg, ...)
|
||
#endif
|
||
|
||
/*===========================================================================
|
||
|
||
FUNCTION quec_adc_init
|
||
|
||
DESCRIPTION
|
||
ADC driver init.
|
||
|
||
DEPENDENCIES
|
||
None
|
||
|
||
RETURN VALUE
|
||
None
|
||
|
||
SIDE EFFECTS
|
||
None
|
||
===========================================================================*/
|
||
static unsigned char adc_init_flg = 0;//标记adc 是否被初始化
|
||
int quec_adc_init(void)
|
||
{
|
||
int ret = -1;
|
||
if(0 == adc_init_flg)
|
||
{
|
||
#ifndef NOT_SUPPORT_PM802
|
||
if(PMIC_IS_PM802())
|
||
{
|
||
UINT8 val = 0;
|
||
UINT16 vbat_mv = 0;
|
||
|
||
/* GPADC VINLDO channel enable */
|
||
val = GUILIN_VINLDO_MEAS_EN;
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG2, val );
|
||
|
||
/* GPADC ADCo,ADC1 channel enable*/
|
||
val = GUILIN_GPADC0_MEAS_EN | GUILIN_GPADC1_MEAS_EN;
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG1, val );
|
||
|
||
/* GPADC mode control */
|
||
GuilinRead( GUILIN_GPADC_Reg, GUILIN_GPADC_MISC_CONFIG_REG2, &val );
|
||
val |= GUILIN_NON_STOP | GUILIN_GPADC_EN;
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MISC_CONFIG_REG2, val );
|
||
|
||
/* GPADC bais config */
|
||
//val = (0x3 << 4);
|
||
//GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_BIAS_REG, val );
|
||
|
||
//val = GUILIN_GPADC0_BIAS_OUT | GUILIN_GPADC1_BIAS_OUT ;
|
||
//GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_BIAS_ENABLE, val );
|
||
adc_init_flg =1;
|
||
ret = 0;
|
||
}
|
||
else
|
||
#endif
|
||
#ifndef NOT_SUPPORT_PM813
|
||
if (PMIC_IS_PM813())
|
||
{
|
||
unsigned char val = 0;
|
||
unsigned char gpadc_en = 0;
|
||
unsigned char gpadc_control = 0;
|
||
|
||
/* ADC BAT_ID and BAT_TEMP channel enable */
|
||
val = NINGBO_RTC_ALARM_STATUS_BIT | NINGBO_VBUS_STATUS_BIT;
|
||
NingboWrite( NINGBO_GPADC_Reg, NINGBO_GPADC_MEAS_EN_REG1, val);
|
||
NingboRead( NINGBO_GPADC_Reg, NINGBO_GPADC_MEAS_EN_REG1, &gpadc_en);
|
||
if(val != gpadc_en)
|
||
{
|
||
quec_adc_log("Set BAT_ID & BAT_TEMP reg failed.\n");
|
||
ret = -1;
|
||
}
|
||
|
||
/* GPADC mode control */
|
||
//NingboRead( NINGBO_GPADC_Reg, NINGBO_GPADC_MODE_CONTROL_REG, &val );
|
||
//val = NINGBO_RTC_ALARM_STATUS_BIT;
|
||
val =NINGBO_GPADC_EN;
|
||
NingboWrite( NINGBO_GPADC_Reg, NINGBO_GPADC_MODE_CONTROL_REG, val);
|
||
NingboRead( NINGBO_GPADC_Reg, NINGBO_GPADC_MODE_CONTROL_REG, &gpadc_control);
|
||
if(val != gpadc_control)
|
||
{
|
||
quec_adc_log("Set GPADC mode control reg failed.\n");
|
||
ret= -1;
|
||
}
|
||
|
||
quec_adc_log("Init GPADC register SUCCESS!!!\n");
|
||
adc_init_flg = 1;
|
||
ret = 0;
|
||
}
|
||
else
|
||
#endif
|
||
ret = 0;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
#if !defined(NOT_SUPPORT_PM802)
|
||
void quec_adc_onff(bool status)
|
||
{
|
||
UINT8 val = 0;
|
||
if(PMIC_IS_PM802())//ASR 1601 平台,采用PM802 移远ECxxxS系列
|
||
{
|
||
if(TRUE == status)
|
||
{
|
||
/* GPADC VINLDO channel enable */
|
||
// val = GUILIN_VINLDO_MEAS_EN;
|
||
// GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG2, val );
|
||
|
||
/* GPADC ADCo,ADC1 channel enable*/
|
||
val = GUILIN_GPADC0_MEAS_EN | GUILIN_GPADC1_MEAS_EN;
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG1, val );
|
||
|
||
/* GPADC mode control */
|
||
GuilinRead( GUILIN_GPADC_Reg, GUILIN_GPADC_MISC_CONFIG_REG2, &val );
|
||
val |= GUILIN_NON_STOP | GUILIN_GPADC_EN;
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MISC_CONFIG_REG2, val );
|
||
}
|
||
else
|
||
{
|
||
/* GPADC VINLDO channel disable */
|
||
// GuilinRead( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG2, &val );
|
||
// val &= ~GUILIN_VINLDO_MEAS_EN;
|
||
// GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG2, val );
|
||
|
||
/* GPADC ADCo,ADC1 channel disable*/
|
||
GuilinRead( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG1, &val );
|
||
val &= ~(GUILIN_GPADC0_MEAS_EN | GUILIN_GPADC1_MEAS_EN);
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MEAS_EN_REG1, val );
|
||
|
||
/* GPADC mode control */
|
||
GuilinRead( GUILIN_GPADC_Reg, GUILIN_GPADC_MISC_CONFIG_REG2, &val );
|
||
val &= ~(GUILIN_NON_STOP | GUILIN_GPADC_EN);
|
||
GuilinWrite( GUILIN_GPADC_Reg, GUILIN_GPADC_MISC_CONFIG_REG2, val );
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/*===========================================================================
|
||
|
||
FUNCTION quec_vbat_adc_read
|
||
|
||
DESCRIPTION
|
||
Read vbat ADC channel voltage.
|
||
|
||
DEPENDENCIES
|
||
None
|
||
|
||
RETURN VALUE
|
||
None
|
||
|
||
SIDE EFFECTS
|
||
None
|
||
===========================================================================*/
|
||
|
||
int quec_vbat_adc_read(uint16 *p_batvol)
|
||
{
|
||
uint16 meas_val;
|
||
uint16 vol_GPADC;
|
||
|
||
#if !defined(NOT_SUPPORT_PM802)
|
||
if(PMIC_IS_PM802())//ASR 1601 平台,采用PM802 移远ECxxxS系列
|
||
{
|
||
meas_val = guilin_read_volt_meas_val(0x62);
|
||
vol_GPADC = (uint16) ((meas_val * 1300 * 5) / 4096);
|
||
*p_batvol = vol_GPADC;
|
||
}
|
||
else
|
||
#endif
|
||
#if !defined(NOT_SUPPORT_PM813)
|
||
if(PMIC_IS_PM813())//EC100Y
|
||
{
|
||
*p_batvol = (unsigned short)pm813_get_battery_voltage_withoutCharger();
|
||
}
|
||
else
|
||
#endif
|
||
|
||
if(PMIC_IS_PM803() || PMIC_IS_PM803L() || PMIC_IS_PM807())//EC600N
|
||
{
|
||
// ASR 1603 平台使用 PM803 ADC需要采用板级校准,并且仅支持通道0 ECxxxN系列
|
||
#ifdef ASR_PLATFORM_CRANEM
|
||
extern INT16 GetPm803VbatAdc(ADC_TEMP_t tempType);
|
||
*p_batvol = GetPm803VbatAdc(TEMP_NORMAL); // 获取vbat实际电压值
|
||
#else
|
||
*p_batvol = (UINT16)get_cranel_vbat();
|
||
|
||
#endif
|
||
}
|
||
|
||
quec_adc_log("Get vbat batvol=%d",vol_GPADC);
|
||
return 0;
|
||
}
|
||
|
||
/*===========================================================================
|
||
|
||
FUNCTION quec_adc_read
|
||
|
||
DESCRIPTION
|
||
Read ADC channel voltage.
|
||
|
||
DEPENDENCIES
|
||
None
|
||
|
||
RETURN VALUE
|
||
None
|
||
|
||
SIDE EFFECTS
|
||
None
|
||
===========================================================================*/
|
||
/************************************************************
|
||
Due to the voltage drop of ADC port during voltage acquisition,
|
||
the acquisition voltage is not accurate,
|
||
so the ADC acquisition function is turned off after collecting voltage,
|
||
and then the value is read and the average value is offset
|
||
*************************************************************/
|
||
|
||
#define QUEC_ADC_SAMPLE_MAX 10
|
||
|
||
|
||
int quec_adc_read(uint8 adc_channel, uint16 *p_batvol)
|
||
{
|
||
uint16 meas_val;
|
||
uint16 vol_GPADC, vol_cali;
|
||
uint16 vbat_base;
|
||
uint16 i=0,j=0,min=0,max=0,val_all=0,times = QUEC_ADC_SAMPLE_MAX;
|
||
uint16 batvol_sample[QUEC_ADC_SAMPLE_MAX]={0};
|
||
|
||
if (p_batvol == NULL)
|
||
{
|
||
quec_adc_log("p_batvol == NULL", adc_channel);
|
||
return ADC_READ_FAIL;
|
||
}
|
||
#if !defined(NOT_SUPPORT_PM802)
|
||
if(PMIC_IS_PM802())//ASR 1601 平台,采用PM802 移远ECxxxS系列
|
||
{
|
||
while(times--)
|
||
{
|
||
quec_adc_onff(TRUE);
|
||
quec_rtos_task_sleep_ms(5);
|
||
quec_adc_onff(FALSE);
|
||
if (adc_channel == ADC_CHANNEL_ADC0)
|
||
{
|
||
meas_val = guilin_read_volt_meas_val(GUILIN_VGPADC0);
|
||
}
|
||
else if (adc_channel == ADC_CHANNEL_ADC1)
|
||
{
|
||
meas_val = guilin_read_volt_meas_val(GUILIN_VGPADC1);
|
||
}
|
||
else
|
||
{
|
||
quec_adc_log("channel=%d err", adc_channel);
|
||
return ADC_READ_FAIL;
|
||
}
|
||
|
||
vol_GPADC = (uint16) ((meas_val * 1300) / 4096);
|
||
|
||
#if defined (__QUECTEL_PROJECT_EC600SCN_AA__) || defined (__QUECTEL_PROJECT_EC600SCN_LA__) || defined (__QUECTEL_PROJECT_EC600SCN_LB__) || defined (__QUECTEL_PROJECT_EC600SCN_AC__) \
|
||
|| defined (__QUECTEL_PROJECT_EC600SCN_LC__) || defined (__QUECTEL_PROJECT_EC600SCN_LD__)
|
||
|
||
|
||
batvol_sample[i]=vol_GPADC;
|
||
|
||
#else
|
||
vbat_base = 1300;
|
||
if (vol_GPADC >= vbat_base)
|
||
{
|
||
vol_cali = (uint16)(1300 + (vol_GPADC-vbat_base));
|
||
}
|
||
else
|
||
{
|
||
vol_cali = (uint16)(1300 - (vbat_base-vol_GPADC));
|
||
}
|
||
|
||
/* (1) 100K, 47K resistance position is wrong.
|
||
before modify the circuit: *p_batvol = vol_cali*147/100;
|
||
after modify the circuit: *p_batvol = vol_cali*147/47;
|
||
|
||
(2) HW change 100K,47K to 100K,39K
|
||
100K,47K can detect 0-4.0V
|
||
100K,39K can detect 0-4.6V
|
||
|
||
(3) HW change 100K,39K to 1000K,390K
|
||
100K,39K can detect 0-4.6V
|
||
1000K,390K can detect 0-4.6V
|
||
*/
|
||
batvol_sample[i]=vol_cali*139/39;
|
||
|
||
#endif
|
||
|
||
quec_adc_log("time=%d, channel=%d, meas_val=%d, vbat_base=%d, vol_cali=%d, batvol=%d", i, adc_channel, meas_val, vbat_base, vol_cali, batvol_sample[i]);
|
||
i++;
|
||
}
|
||
{
|
||
uint16 temp=0;
|
||
uint16 batvol_sample_temp[QUEC_ADC_SAMPLE_MAX]={0};
|
||
memcpy(batvol_sample_temp,batvol_sample,sizeof(batvol_sample_temp));
|
||
for(i=0;i<QUEC_ADC_SAMPLE_MAX-1;i++)
|
||
{
|
||
for(j=i+1;j<QUEC_ADC_SAMPLE_MAX;j++)
|
||
{
|
||
if(batvol_sample_temp[i]>batvol_sample_temp[j])
|
||
{
|
||
temp=batvol_sample_temp[i];
|
||
batvol_sample_temp[i]=batvol_sample_temp[j];
|
||
batvol_sample_temp[j]=temp;
|
||
}
|
||
}
|
||
}
|
||
for(i=0;i<QUEC_ADC_SAMPLE_MAX;i++)
|
||
{
|
||
quec_adc_log("adc_val_all=%d",batvol_sample_temp[i]);
|
||
}
|
||
for(i=1;i<9;i++)
|
||
{
|
||
val_all += batvol_sample_temp[i];
|
||
}
|
||
*p_batvol =val_all/8;
|
||
|
||
if(PMIC_IS_PM802())
|
||
{
|
||
if((*p_batvol >= 1000)&&(*p_batvol <= 2000))
|
||
{
|
||
*p_batvol -= 10;
|
||
}
|
||
else if((*p_batvol > 2000)&&(*p_batvol <= 3000))
|
||
{
|
||
*p_batvol -= 15;
|
||
}
|
||
else if((*p_batvol > 3000)&&(*p_batvol <= 4000))
|
||
{
|
||
*p_batvol -= 25;
|
||
}
|
||
else if(*p_batvol > 4000)
|
||
{
|
||
*p_batvol -= 30;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
#endif
|
||
|
||
if (PMIC_IS_PM803() || PMIC_IS_PM803L() || PMIC_IS_PM807())//ASR 1603、1606平台,移远ECxxxN/M系列采用PM803
|
||
{
|
||
// ASR 1603 平台使用 PM803 ADC需要采用板级校准,并且仅支持通道0 ECxxxN系列
|
||
#ifdef ASR_PLATFORM_CRANEM
|
||
extern INT16 GetPm803VrtpAdc(void);
|
||
if (adc_channel == ADC_CHANNEL_ADC0)
|
||
{
|
||
*p_batvol = GetPm803VrtpAdc();
|
||
return ADC_READ_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
*p_batvol = 0;
|
||
quec_adc_log("PM803 only support adc0\n");
|
||
return ADC_READ_FAIL;
|
||
}
|
||
#else
|
||
// ASR 1606 平台采用高精度ADC,ECxxxM系列
|
||
/* ADC分压电路:Vin经过R1和R2电阻分压,得到Vadc
|
||
* Vin -------| R2 |-------| R1 |---------| GND
|
||
* |
|
||
* |
|
||
* Vadc
|
||
*
|
||
* 计算公式 Vin = Vadc * (R1+R2)/R1
|
||
*
|
||
* 其中
|
||
* Vin:待测量的输入电压
|
||
* Vadc:adc测量到的电压
|
||
*/
|
||
uint16 a = 0;
|
||
if(adc_channel == 0)
|
||
{
|
||
#if defined (__QUECTEL_PROJECT_EC200MCN_LA__) || defined (__QUECTEL_PROJECT_EC200MCN_GB__) || defined (__QUECTEL_PROJECT_EC200MCN_LE__)|| defined (__QUECTEL_PROJECT_EC200MCN_LF__)\
|
||
|| defined (__QUECTEL_PROJECT_EG915KEU_LG__) || defined (__QUECTEL_PROJECT_EG915KLA_LG__)
|
||
a = (uint16)get_cranel_adc0();
|
||
//add by tomas 20240812,fix STASR1606-3540,EC200MCN_LF分压电路:R1 = 120K,R2 = 390K
|
||
*p_batvol = a+(a*390/120);
|
||
#else
|
||
*p_batvol = (uint16)get_cranel_adc0();
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#if defined (__QUECTEL_PROJECT_EC200MCN_LA__) || defined (__QUECTEL_PROJECT_EC200MCN_GB__) || defined (__QUECTEL_PROJECT_EC200MCN_LE__)|| defined (__QUECTEL_PROJECT_EC200MCN_LF__)\
|
||
|| defined (__QUECTEL_PROJECT_EG915KEU_LG__) || defined (__QUECTEL_PROJECT_EG915KLA_LG__)
|
||
a = (uint16)get_cranel_adc1();
|
||
//add by tomas 20240812,fix STASR1606-3540,EC200MCN_LF分压电路:R1 = 120K,R2 = 390K
|
||
*p_batvol = a+(a*390/120);
|
||
#else
|
||
*p_batvol = (uint16)get_cranel_adc1();
|
||
#endif
|
||
}
|
||
#endif
|
||
}
|
||
#ifndef NOT_SUPPORT_PM813 //ASR 3601 平台,移远ECxxxY系列采用PM813
|
||
else if (PMIC_IS_PM813()) //pm813 adc0、adc1
|
||
{
|
||
unsigned short meas_val;
|
||
unsigned short vol_GPADC, vol_cali;
|
||
unsigned short vbat_base;
|
||
unsigned char val = 0;
|
||
unsigned char gpadc_en = 0;
|
||
unsigned char gpadc_control = 0;
|
||
val = NINGBO_RTC_ALARM_STATUS_BIT | NINGBO_VBUS_STATUS_BIT;
|
||
|
||
NingboRead( NINGBO_GPADC_Reg, NINGBO_GPADC_MEAS_EN_REG1, &gpadc_en);
|
||
if(val != gpadc_en)
|
||
{
|
||
NingboWrite( NINGBO_GPADC_Reg, NINGBO_GPADC_MEAS_EN_REG1, val);
|
||
//ql_adc_log("Get BAT_ID & BAT_TEMP reg FAILED reset BAT_ID & BAT_TEMP.\n");
|
||
|
||
}
|
||
|
||
val =NINGBO_GPADC_EN;
|
||
NingboRead( NINGBO_GPADC_Reg, NINGBO_GPADC_MODE_CONTROL_REG, &gpadc_control);
|
||
if(val != gpadc_control)
|
||
{
|
||
NingboWrite( NINGBO_GPADC_Reg, NINGBO_GPADC_MODE_CONTROL_REG, val);
|
||
//ql_adc_log("Get GPADC mode control reg FAILED reset NINGBO_GPADC_EN.\n");
|
||
|
||
}
|
||
|
||
if (p_batvol == NULL)
|
||
{
|
||
quec_adc_log("p_batvol == NULL\n");
|
||
return ADC_READ_FAIL;
|
||
}
|
||
|
||
if (adc_channel == ADC_CHANNEL_ADC0)
|
||
{
|
||
meas_val = ningbo_read_volt_meas_val(NINGBO_GPADC_MEAS_VBATID_1_REG);
|
||
|
||
}
|
||
else if (adc_channel == ADC_CHANNEL_ADC1)
|
||
{
|
||
meas_val = ningbo_read_volt_meas_val(NINGBO_GPADC_MEAS_VBATTEMP_1_REG);
|
||
}
|
||
else
|
||
{
|
||
quec_adc_log("channel=%d err", adc_channel);
|
||
}
|
||
|
||
vol_GPADC = (uint16) ((meas_val * 1300) / 4096);
|
||
|
||
vbat_base = 1300;
|
||
if (vol_GPADC >= vbat_base)
|
||
{
|
||
vol_cali = (uint16)(1300 + (vol_GPADC-vbat_base));
|
||
}
|
||
else
|
||
{
|
||
vol_cali = (uint16)(1300 - (vbat_base-vol_GPADC));
|
||
}
|
||
|
||
|
||
/* (1) 100K, 47K resistance position is wrong.
|
||
before modify the circuit: *p_batvol = vol_cali*147/100;
|
||
after modify the circuit: *p_batvol = vol_cali*147/47;
|
||
|
||
(2) HW change 100K,47K to 100K,39K
|
||
100K,47K can detect 0-4.0V
|
||
100K,39K can detect 0-4.6V
|
||
*/
|
||
*p_batvol = vol_cali*139/39;
|
||
|
||
//ql_adc_log("channel=%d, meas_val=%d, vbat_base=%d, vol_cali=%d, batvol=%d\n", adc_channel, meas_val, vbat_base, vol_cali, *p_batvol);
|
||
|
||
}
|
||
#endif
|
||
return ADC_READ_SUCCESS;
|
||
}
|
||
#endif
|
||
|
||
#endif /*MIN_SYS*/
|
||
|