summaryrefslogtreecommitdiff
path: root/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c')
-rwxr-xr-xdrivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c1196
1 files changed, 1196 insertions, 0 deletions
diff --git a/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c b/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c
new file mode 100755
index 00000000..e23f858e
--- /dev/null
+++ b/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c
@@ -0,0 +1,1196 @@
+/**
+ * @filename uG31xx_API_System.cpp
+ *
+ * uG31xx system control
+ *
+ * @author AllenTeng <allen_teng@upi-semi.com>
+ */
+
+#include "stdafx.h" //windows need this??
+#include "uG31xx_API.h"
+
+#if defined(uG31xx_OS_ANDROID)
+
+_upi_bool_ ReadGGBXFileToCellDataAndInitSetting(SystemDataType *obj)
+{
+ _sys_u8_ *p_start = _UPI_NULL_;
+ _sys_u8_ *p_end = _UPI_NULL_;
+ _sys_u16_ sum16=0;
+ _sys_s32_ i=0;
+
+ /*
+ * check GGBX_FILE tag
+ */
+ if(obj->ggbXBuf->ggb_tag != GGBX_FILE_TAG)
+ {
+ UG31_LOGE("[%s] GGBX file tag not correct. tag: %08X\n", __func__, obj->ggbXBuf->ggb_tag);
+ return (_UPI_FALSE_);
+ }
+
+ /*
+ * check GGBX_FILE checksum
+ */
+ p_start = (_sys_u8_ *)obj->ggbXBuf + sizeof(GGBX_FILE_HEADER);
+ p_end = p_start + obj->ggbXBuf->length - 1;
+ for (; p_start <= p_end; p_start++)
+ {
+ sum16 += *p_start;
+ }
+
+ /* check done. prepare copy data */
+ memset(obj->ggbCellTable, 0x00, sizeof(CELL_TABLE));
+ memset(obj->ggbParameter, 0x00, sizeof(CELL_PARAMETER));
+
+ p_start = (_sys_u8_ *)obj->ggbXBuf + sizeof(GGBX_FILE_HEADER);
+ for (i=0; i<obj->ggbXBuf->num_ggb; i++)
+ {
+ /* TODO: boundary checking */
+ /* TODO: select right ggb content by sku */
+ memcpy(obj->ggbParameter, p_start, sizeof(CELL_PARAMETER));
+ memcpy(obj->ggbCellTable, p_start + sizeof(CELL_PARAMETER), sizeof(CELL_TABLE));
+ p_start += (sizeof(CELL_PARAMETER) + sizeof(CELL_TABLE));
+ }
+ return (_UPI_TRUE_);
+}
+
+#else ///< else of defined(uG31xx_OS_ANDROID)
+
+ _upi_bool_ ReadGGBFileToCellDataAndInitSetting(SystemDataType *obj)
+{
+ FILE* stream;
+ _wfopen_s(&stream, obj->ggbFilename, _T("rb, ccs=UTF-8"));
+
+ memset(obj->ggbCellTable, 0x00, sizeof(CELL_TABLE));
+ memset(obj->ggbParameter, 0x00, sizeof(CELL_PARAMETER));
+
+ if(!stream)
+ {
+ return (_UPI_FALSE_);
+ }
+ if(fread(obj->ggbParameter, sizeof(char), sizeof(CELL_PARAMETER), stream) != sizeof(CELL_PARAMETER))
+ {
+ fclose(stream);
+ return (_UPI_FALSE_);
+ }
+ if(fread(obj->ggbCellTable, sizeof(char), sizeof(CELL_TABLE), stream) != sizeof(CELL_TABLE))
+ {
+ fclose(stream);
+ return (_UPI_FALSE_);
+ }
+
+ fclose(stream);
+
+ return (_UPI_TRUE_);
+}
+
+#endif ///< end of defined(uG31xx_OS_ANDROID)
+
+/**
+ * @brief GetCellNum
+ *
+ * Get cell number from ggbParameter->ICType
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void GetCellNum(SystemDataType *data)
+{
+ _sys_u8_ cellNum[6] = {1, 1, 2, 0, 2, 3};
+
+ data->cellNum = cellNum[data->ggbParameter->ICType];
+}
+
+/**
+ * @brief SetupAdcChopFunction
+ *
+ * Setup ADC chop function
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void SetupAdcChopFunction(SystemDataType *data)
+{
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_FW_CTRL,
+ data->ggbParameter->chopCtrl);
+}
+
+/**
+ * @brief SetupAdc1Queue
+ *
+ * Setup ADC1 conversion queue
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void SetupAdc1Queue(SystemDataType *data)
+{
+ _cap_u8_ adcQueue[4];
+
+ adcQueue[0] = SET_A_IT | SET_B_IT | SET_C_CURRENT | SET_D_CURRENT;
+ adcQueue[1] = SET_E_CURRENT | SET_F_CURRENT | SET_G_CURRENT | SET_H_CURRENT;
+ adcQueue[2] = SET_I_ET | SET_J_ET | SET_K_CURRENT | SET_L_CURRENT;
+ adcQueue[3] = SET_M_CURRENT | SET_N_CURRENT | SET_O_CURRENT | SET_P_CURRENT;
+
+ API_I2C_Write(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_ADC_CTR_A,
+ 4,
+ &adcQueue[0]);
+}
+
+/**
+ * @brief SetupAdc2Queue
+ *
+ * Set ADC2 conversion queue
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void SetupAdc2Quene(SystemDataType *data)
+{
+ _sys_u8_ adc2Queue[3];
+
+ /// [AT-PM] : Set sell type ; 01/31/2013
+ if(data->cellNum == 1)
+ {
+ adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT1 | SET_V4_VBAT1;
+ adc2Queue[1] = SET_V5_VBAT1 | SET_V6_VBAT1 | SET_V7_VBAT1 | SET_V8_VBAT1;
+ adc2Queue[2] = SET_V9_VBAT1 | SET_V10_VBAT1 | SET_V11_VBAT1 | SET_V12_VBAT1;
+ }
+ else if(data->cellNum == 2)
+ {
+ adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT2 | SET_V4_VBAT2;
+ adc2Queue[1] = SET_V5_VBAT1 | SET_V6_VBAT1 | SET_V7_VBAT2 | SET_V8_VBAT2;
+ adc2Queue[2] = SET_V9_VBAT1 | SET_V10_VBAT1 | SET_V11_VBAT2 | SET_V12_VBAT2;
+ }
+ else if(data->cellNum == 3)
+ {
+ adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT2 | SET_V4_VBAT2;
+ adc2Queue[1] = SET_V5_VBAT3 | SET_V6_VBAT3 | SET_V7_VBAT1 | SET_V8_VBAT1;
+ adc2Queue[2] = SET_V9_VBAT2 | SET_V10_VBAT2 | SET_V11_VBAT3 | SET_V12_VBAT3;
+ }
+ else
+ {
+ /// [AT-PM] : 1-cell ; 01/31/2013
+ adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT1 | SET_V4_VBAT1;
+ adc2Queue[1] = SET_V5_VBAT1 | SET_V6_VBAT1 | SET_V7_VBAT1 | SET_V8_VBAT1;
+ adc2Queue[2] = SET_V9_VBAT1 | SET_V10_VBAT1 | SET_V11_VBAT1 | SET_V12_VBAT1;
+ }
+ API_I2C_Write(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ADC_V1, 3, &adc2Queue[0]);
+}
+
+/**
+ * @brief EnableCbc
+ *
+ * Enable CBC function
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void EnableCbc(SystemDataType *data)
+{
+ _sys_u8_ tmp8;
+
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_B, &tmp8);
+ tmp8 = tmp8 & (~(INTR_CTRL_B_CBC_32_EN | INTR_CTRL_B_CBC_21_EN));
+ tmp8 = tmp8 | (INTR_CTRL_B_ET_EN | INTR_CTRL_B_IT_EN | INTR_CTRL_B_RID_EN);
+ tmp8 = tmp8 | (data->ggbParameter->cbcEnable << 4);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_B, tmp8);
+}
+
+/**
+ * @brief EnableICType
+ *
+ * Enable IC type
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void EnableICType(SystemDataType *data)
+{
+ _sys_u8_ tmp8;
+
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, &tmp8);
+ tmp8 = tmp8 & (~CELL_EN_APPLICATION);
+ tmp8 = tmp8 | (data->ggbParameter->ICType << 2);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, tmp8);
+}
+
+/**
+ * @brief ConfigGpioFunction
+ *
+ * Configure GPIO1/2 function
+ *
+ * @para setting GPIO1/2 setting
+ * @return register value
+ */
+_sys_u8_ ConfigGpioFunction(_sys_u8_ setting)
+{
+ _sys_u8_ gpioSelData = 0;
+
+ if(setting & FUN_GPIO)
+ {
+ gpioSelData = 0;
+ }
+ if(setting & FUN_ALARM) //select Alarm function
+ {
+ gpioSelData = 1;
+ }
+ if(setting & FUN_CBC_EN21) //cbc21 enable
+ {
+ gpioSelData = 2;
+ }if(setting & FUN_CBC_EN32) //cbc32 Enable
+ {
+ gpioSelData = 3;
+ }
+ if(setting & FUN_PWM) //PWM function, set PWM cycle
+ {
+ gpioSelData = 4;
+ }
+ return (gpioSelData);
+}
+
+/**
+ * @brief ConfigureGpio
+ *
+ * Configure GPIO function
+ *
+ * @para data SystemDataType
+ * @return _UPI_NULL_
+ */
+void ConfigureGpio(SystemDataType *data)
+{
+ _sys_u8_ tmp8;
+
+ API_I2C_SingleRead(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_INTR_CTRL_A,
+ &tmp8);
+ tmp8 = tmp8 | (ConfigGpioFunction(data->ggbParameter->gpio1) << 2);
+ tmp8 = tmp8 | (ConfigGpioFunction(data->ggbParameter->gpio2) << 5);
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_INTR_CTRL_A,
+ tmp8);
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_INTR_CTRL_D,
+ data->ggbParameter->gpio34);
+}
+
+#define ADC_FAIL_CRITERIA (10)
+
+/**
+ * @brief CheckAdcStatusFail
+ *
+ * Check ADC status is fail or not
+ *
+ * @para pUg31xx address of SystemDataType
+ * @return _UPI_TRUE_ if fail
+ */
+_upi_bool_ CheckAdcStatusFail(SystemDataType *data)
+{
+ API_I2C_Read(NORMAL,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_COUNTER_LOW,
+ REG_COUNTER_HIGH - REG_COUNTER_LOW + 1,
+ (unsigned char *)&data->adcCheckData.regCounter);
+
+ API_I2C_Read(NORMAL,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_AVE_VBAT1_LOW,
+ REG_AVE_VBAT1_HIGH - REG_AVE_VBAT1_LOW + 1,
+ (unsigned char *)&data->adcCheckData.regVbat1Ave);
+
+ /// [AT-PM] : Compare counter register ; 01/27/2013
+ if(data->adcCheckData.regCounter == data->adcCheckData.lastCounter)
+ {
+ data->adcCheckData.failCounterCurrent = data->adcCheckData.failCounterCurrent + 1;
+ UG31_LOGI("[%s]: Counter fixed (%d) ... %d\n", __func__,
+ data->adcCheckData.regCounter, data->adcCheckData.failCounterCurrent);
+ }
+ else
+ {
+ data->adcCheckData.failCounterCurrent = 0;
+ }
+ data->adcCheckData.lastCounter = data->adcCheckData.regCounter;
+
+ /// [AT-PM] : Compre VBat1 register ; 01/27/2013
+ if(data->adcCheckData.regVbat1Ave == data->adcCheckData.lastVBat1Ave)
+ {
+ data->adcCheckData.failCounterVoltage = data->adcCheckData.failCounterVoltage + 1;
+ UG31_LOGI("[%s]: VBat1 fixed (%d) ... %d\n", __func__,
+ data->adcCheckData.regVbat1Ave, data->adcCheckData.failCounterVoltage);
+ }
+ else
+ {
+ data->adcCheckData.failCounterVoltage = 0;
+ }
+ data->adcCheckData.lastVBat1Ave = data->adcCheckData.regVbat1Ave;
+
+ /// [AT-PM] : Check ADC fail criteria ; 01/27/2013
+ if(data->adcCheckData.failCounterCurrent > ADC_FAIL_CRITERIA)
+ {
+ data->adcCheckData.failCounterCurrent = 0;
+ return (_UPI_TRUE_);
+ }
+ if(data->adcCheckData.failCounterVoltage > ADC_FAIL_CRITERIA)
+ {
+ data->adcCheckData.failCounterVoltage = 0;
+ return (_UPI_TRUE_);
+ }
+ return (_UPI_FALSE_);
+}
+
+/**
+ * @brief DecimateRst
+ *
+ * Decimate reset filter of ADC
+ *
+ * @return _UPI_NULL_
+ */
+void DecimateRst(void)
+{
+ _sys_u8_ tmp8;
+
+ tmp8 = 0x00;
+ API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+ tmp8 = tmp8 & (~ALARM_EN_DECIMATE_RST);
+ API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+ tmp8 = tmp8 | ALARM_EN_DECIMATE_RST;
+ API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+ UG31_LOGI("[%s]: DECIMATE_RST\n", __func__);
+}
+
+/**
+ * @brief AlarmEnable
+ *
+ * Enable alarm
+ *
+ * @para alarm REG_ALARM_EN bits
+ * @return NULL
+ */
+void AlarmEnable(_sys_u8_ alarm)
+{
+ _sys_u8_ tmp8;
+
+ API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+ tmp8 = tmp8 | alarm;
+ API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+}
+
+/**
+ * @brief AlarmDisable
+ *
+ * Disable alarm
+ *
+ * @para alarm REG_ALARM_EN bits
+ * @return NULL
+ */
+void AlarmDisable(_sys_u8_ alarm)
+{
+ _sys_u8_ tmp8;
+
+ API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+ tmp8 = tmp8 & (~alarm);
+ API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8);
+}
+
+#define SYS_ALARM_STS_UV1 (ALARM2_STATUS_UV1_ALARM)
+#define SYS_ALARM_STS_OV1 (ALARM2_STATUS_OV1_ALARM)
+#define SYS_ALARM_STS_UV2 (ALARM2_STATUS_UV2_ALARM)
+#define SYS_ALARM_STS_OV2 (ALARM2_STATUS_OV2_ALARM)
+#define SYS_ALARM_STS_UV3 (ALARM2_STATUS_UV3_ALARM)
+#define SYS_ALARM_STS_OV3 (ALARM2_STATUS_OV3_ALARM)
+#define SYS_ALARM_STS_UET (ALARM1_STATUS_UET_ALARM<<8)
+#define SYS_ALARM_STS_OET (ALARM1_STATUS_OET_ALARM<<8)
+#define SYS_ALARM_STS_UIT (ALARM1_STATUS_UIT_ALARM<<8)
+#define SYS_ALARM_STS_OIT (ALARM1_STATUS_OIT_ALARM<<8)
+#define SYS_ALARM_STS_DOC (ALARM1_STATUS_DOC_ALARM<<8)
+#define SYS_ALARM_STS_COC (ALARM1_STATUS_COC_ALARM<<8)
+
+/**
+ * @brief ProcUVAlarm
+ *
+ * UV alarm function
+ *
+ * @para data address of SystemDataType
+ * @return NULL
+ */
+void ProcUVAlarm(SystemDataType *data)
+{
+ _sys_u8_ tmp8[4];
+
+ /// [AT-PM] : Check alarm is enable or not ; 04/08/2013
+ if(!(data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_UV))
+ {
+ /// [AT-PM] : Disable UV and OV alarm ; 04/08/2013
+ AlarmDisable(ALARM_EN_V1_ALARM_EN);
+ return;
+ }
+
+ if(data->uvAlarm.state == _UPI_TRUE_)
+ {
+ /// [AT-PM] : UV alarm has been set -> Wait for OV alarm ; 04/08/2013
+ if(data->alarmSts & SYS_ALARM_STS_OV1)
+ {
+ data->uvAlarm.state = _UPI_FALSE_;
+
+ /// [AT-PM] : Release UV alarm by disable ; 04/08/2013
+ AlarmDisable(ALARM_EN_V1_ALARM_EN);
+
+ /// [AT-PM] : UV release threshold reached -> set alarm threshold ; 04/08/2013
+ tmp8[0] = 0xff;
+ tmp8[1] = 0x7f;
+ tmp8[2] = (_sys_u8_)(data->uvAlarm.alarmThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->uvAlarm.alarmThrd >> 8);
+ }
+ else
+ {
+ /// [AT-PM] : UV state -> set release threshold ; 04/08/2013
+ tmp8[0] = (_sys_u8_)(data->uvAlarm.releaseThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->uvAlarm.releaseThrd >> 8);
+ tmp8[2] = 0x00;
+ tmp8[3] = 0x00;
+ }
+ }
+ else
+ {
+ /// [AT-PM] : Normal state ; 04/08/2013
+ if(data->alarmSts & SYS_ALARM_STS_UV1)
+ {
+ data->uvAlarm.state = _UPI_TRUE_;
+
+ /// [AT-PM] : Release UV alarm by disable ; 04/08/2013
+ AlarmDisable(ALARM_EN_V1_ALARM_EN);
+
+ /// [AT-PM] : UV alarm reached -> set release threshold ; 04/08/2013
+ tmp8[0] = (_sys_u8_)(data->uvAlarm.releaseThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->uvAlarm.releaseThrd >> 8);
+ tmp8[2] = 0x00;
+ tmp8[3] = 0x00;
+ }
+ else
+ {
+ /// [AT-PM] : Normal state -> set alarm threshold ; 04/08/2013
+ tmp8[0] = 0xff;
+ tmp8[1] = 0x7f;
+ tmp8[2] = (_sys_u8_)(data->uvAlarm.alarmThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->uvAlarm.alarmThrd >> 8);
+ }
+ }
+
+ /// [AT-PM] : Set alarm threshold ; 04/08/2013
+ API_I2C_Write(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_OV1_LOW, 4, &tmp8[0]);
+
+ /// [AT-PM] : Enable UV and OV alarm ; 04/08/2013
+ AlarmEnable(ALARM_EN_V1_ALARM_EN);
+}
+
+/**
+ * @brief ProcETAlarm
+ *
+ * UET and OET alarm function
+ *
+ * @para data address of SystemDataType
+ * @return NULL
+ */
+void ProcETAlarm(SystemDataType *data)
+{
+ _sys_u8_ tmp8[4];
+
+ /// [AT-PM] : Check alarm is enable or not ; 04/08/2013
+ if(!(data->ggbParameter->alarmEnable & (CELL_PARAMETER_ALARM_EN_UET | CELL_PARAMETER_ALARM_EN_OET)))
+ {
+ /// [AT-PM] : Disable UV and OV alarm ; 04/08/2013
+ AlarmDisable(ALARM_EN_ET_ALARM_EN);
+ return;
+ }
+
+ if(data->uetAlarm.state == _UPI_TRUE_)
+ {
+ /// [AT-PM] : UET alarm state -> wait for OET alarm ; 04/08/2013
+ if(data->alarmSts & SYS_ALARM_STS_OET)
+ {
+ data->uetAlarm.state = _UPI_FALSE_;
+
+ /// [AT-PM] : Release by disable ; 04/08/2013
+ AlarmDisable(ALARM_EN_ET_ALARM_EN);
+
+ /// [AT-PM] : UET release met -> set UET and OET alarm ; 04/08/2013
+ tmp8[0] = (_sys_u8_)(data->oetAlarm.alarmThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->oetAlarm.alarmThrd >> 8);
+ tmp8[2] = (_sys_u8_)(data->uetAlarm.alarmThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->uetAlarm.alarmThrd >> 8);
+ }
+ else
+ {
+ /// [AT-PM] : Wait OET alarm ; 04/08/2013
+ tmp8[0] = (_sys_u8_)(data->uetAlarm.releaseThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->uetAlarm.releaseThrd >> 8);
+ tmp8[2] = 0x00;
+ tmp8[3] = 0x00;
+ }
+ }
+ else if(data->oetAlarm.state == _UPI_TRUE_)
+ {
+ /// [AT-PM] : OET alarm state -> wait for UET alarm ; 04/08/2013
+ if(data->alarmSts & SYS_ALARM_STS_UET)
+ {
+ data->oetAlarm.state = _UPI_FALSE_;
+
+ /// [AT-PM] : Release by disable ; 04/08/2013
+ AlarmDisable(ALARM_EN_ET_ALARM_EN);
+
+ /// [AT-PM] : OET release met -> set UET and OET alarm ; 04/08/2013
+ tmp8[0] = (_sys_u8_)(data->oetAlarm.alarmThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->oetAlarm.alarmThrd >> 8);
+ tmp8[2] = (_sys_u8_)(data->uetAlarm.alarmThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->uetAlarm.alarmThrd >> 8);
+ }
+ else
+ {
+ /// [AT-PM] : Wait UET alarm ; 04/08/2013
+ tmp8[0] = 0xff;
+ tmp8[1] = 0x7f;
+ tmp8[2] = (_sys_u8_)(data->oetAlarm.releaseThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->oetAlarm.releaseThrd >> 8);
+ }
+ }
+ else
+ {
+ /// [AT-PM] : Normal state ; 04/08/2013
+ if((data->alarmSts & SYS_ALARM_STS_UET) &&
+ (data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_UET))
+ {
+ data->uetAlarm.state = _UPI_TRUE_;
+
+ /// [AT-PM] : Release by disable ; 04/08/2013
+ AlarmDisable(ALARM_EN_ET_ALARM_EN);
+
+ /// [AT-PM] : UET is set -> set UET release threshold ; 04/08/2013
+ tmp8[0] = (_sys_u8_)(data->uetAlarm.releaseThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->uetAlarm.releaseThrd >> 8);
+ tmp8[2] = 0x00;
+ tmp8[3] = 0x00;
+ }
+ else if((data->alarmSts & SYS_ALARM_STS_OET) &&
+ (data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_OET))
+ {
+ data->oetAlarm.state = _UPI_TRUE_;
+
+ /// [AT-PM] : Release by disable ; 04/08/2013
+ AlarmDisable(ALARM_EN_ET_ALARM_EN);
+
+ /// [AT-PM] : OET is set -> set OET release threshold ; 04/08/2013
+ tmp8[0] = 0xff;
+ tmp8[1] = 0x7f;
+ tmp8[2] = (_sys_u8_)(data->oetAlarm.releaseThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->oetAlarm.releaseThrd >> 8);
+ }
+ else
+ {
+ /// [AT-PM] : Set OET alarm threshold ; 04/08/2013
+ if(data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_OET)
+ {
+ tmp8[0] = (_sys_u8_)(data->oetAlarm.alarmThrd & 0x00ff);
+ tmp8[1] = (_sys_u8_)(data->oetAlarm.alarmThrd >> 8);
+ }
+ else
+ {
+ tmp8[0] = 0xff;
+ tmp8[1] = 0x7f;
+ }
+ /// [AT-PM] : Set UET alarm threshold ; 04/11/2013
+ if(data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_UET)
+ {
+ tmp8[2] = (_sys_u8_)(data->uetAlarm.alarmThrd & 0x00ff);
+ tmp8[3] = (_sys_u8_)(data->uetAlarm.alarmThrd >> 8);
+ }
+ else
+ {
+ tmp8[2] = 0x00;
+ tmp8[3] = 0x00;
+ }
+ }
+ }
+
+ /// [AT-PM] : Set alarm threshold ; 04/08/2013
+ API_I2C_Write(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_EXTR_OVER_TEMP_LOW, 4, &tmp8[0]);
+
+ /// [AT-PM] : Enable UV and OV alarm ; 04/08/2013
+ AlarmEnable(ALARM_EN_ET_ALARM_EN);
+}
+
+/**
+ * @brief EnableAlarm
+ *
+ * Set UV, UET, and OET alarm functions
+ *
+ * @para data address of SystemDataType
+ * @return NULL
+ */
+void EnableAlarm(SystemDataType *data)
+{
+ /// [AT-PM] : UV alarm ; 04/08/2013
+ ProcUVAlarm(data);
+
+ /// [AT-PM] : UET and OET alarm ; 04/08/2013
+ ProcETAlarm(data);
+}
+
+/// =============================================
+/// [AT-PM] : Extern function region
+/// =============================================
+
+/**
+ * @brief UpiInitSystemData
+ *
+ * Initialize system variables
+ *
+ * @para data address of SystemDataType
+ * @return SYSTEM_RTN_CODE
+ */
+SYSTEM_RTN_CODE UpiInitSystemData(SystemDataType *data)
+{
+ /// [AT-PM] : Initialize variables ; 01/30/2013
+ data->preITAve = 0;
+ data->cellNum = 0;
+
+ /// [AT-PM] : Load GGB file ; 01/30/2013
+ UG31_LOGI("[%s]: Read GGB\n", __func__);
+ #if defined(uG31xx_OS_ANDROID)
+ if(!ReadGGBXFileToCellDataAndInitSetting(data))
+ #else
+ if(!ReadGGBFileToCellDataAndInitSetting(data))
+ #endif
+ {
+ return (SYSTEM_RTN_READ_GGB_FAIL);
+ }
+
+ /// [AT-PM] : Set cell number ; 01/31/2013
+ GetCellNum(data);
+ return (SYSTEM_RTN_PASS);
+}
+
+/**
+ * @brief UpiCheckICActive
+ *
+ * Check IC is actived or not
+ *
+ * @return _UPI_TRUE_ if uG31xx is not actived
+ */
+_upi_bool_ UpiCheckICActive(void)
+{
+ _upi_u8_ tmp;
+
+ if(!API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_MODE, 1, &tmp))
+ {
+ UG31_LOGI("[%s]: Get GG_RUN fail.\n", __func__);
+ return (_UPI_TRUE_);
+ }
+
+ if((tmp & MODE_GG_RUN) == GG_RUN_OPERATION_MODE)
+ {
+ UG31_LOGI("[%s]: uG31xx is actived.\n", __func__);
+ return (_UPI_FALSE_);
+ }
+ UG31_LOGI("[%s]: uG31xx is NOT actived.\n", __func__);
+ return (_UPI_TRUE_);
+}
+
+/**
+ * @brief UpiActiveUg31xx
+ *
+ * Active uG31xx
+ *
+ * @return SYSTEM_RTN_CODE
+ */
+SYSTEM_RTN_CODE UpiActiveUg31xx(void)
+{
+ _sys_u8_ tmp8;
+
+ /// [AT-PM] : Reset uG31xx ; 01/31/2013
+ tmp8 = PORDET_W_SOFTRESET | IO1DATA_W_HIGH;
+ if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CTRL1, 1, &tmp8))
+ {
+ return (SYSTEM_RTN_I2C_FAIL);
+ }
+ tmp8 = IO1DATA_W_HIGH;
+ if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CTRL1, 1, &tmp8))
+ {
+ return (SYSTEM_RTN_I2C_FAIL);
+ }
+
+ /// [AT-PM] : Active uG31xx ; 01/31/2013
+ tmp8 = CTRL1_GG_RST | IO1DATA_W_HIGH;
+ if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CTRL1, 1, &tmp8))
+ {
+ return (SYSTEM_RTN_I2C_FAIL);
+ }
+ tmp8 = GG_RUN_OPERATION_MODE;
+ if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_MODE, 1, &tmp8))
+ {
+ return (SYSTEM_RTN_I2C_FAIL);
+ }
+
+ /// [AT-PM] : Delay 255mS for system stable ; 01/31/2013
+ SleepMiniSecond(255); //2012/08/29/Jacky, need wait 255 ms
+ return (SYSTEM_RTN_PASS);
+}
+
+/**
+ * @brief UpiSetupAdc
+ *
+ * Setup ADC configurations
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void UpiSetupAdc(SystemDataType *data)
+{
+ _sys_u8_ tmp8;
+
+ /// [AT-PM] : Set ADC chop function ; 01/31/2013
+ SetupAdcChopFunction(data);
+
+ /// [AT-PM] : Set ADC1 queue ; 01/31/2013
+ SetupAdc1Queue(data);
+
+ /// [AT-PM] : Set ADC2 queue ; 01/31/2013
+ SetupAdc2Quene(data);
+
+ /// [AT-PM] : Enable ADC ; 01/31/2013
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_A, &tmp8);
+ tmp8 = tmp8 | (INTR_CTRL_A_ADC2_EN | INTR_CTRL_A_ADC1_EN);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_A, tmp8);
+
+ /// [AT-PM] : Decimate reset ; 01/31/2013
+ DecimateRst();
+
+ /// [AT-PM] : Enable CBC function ; 01/31/2013
+ EnableCbc(data);
+}
+
+/**
+ * @brief UpiSetupSystem
+ *
+ * Setup uG31xx system
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void UpiSetupSystem(SystemDataType *data)
+{
+ _sys_u8_ tmp8;
+
+ /// [AT-PM] : Enable IC type ; 01/31/2013
+ EnableICType(data);
+
+ /// [AT-PM] : Configure GPIO ; 01/31/2013
+ ConfigureGpio(data);
+
+ /// [AT-PM] : Enable cell ; 01/31/2013
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, &tmp8);
+ tmp8 = tmp8 | (CELL_EN1 | CELL_EN0);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, tmp8);
+}
+
+#define OSC_CNT_TARG 512 //oscCntTarg[9:0]
+
+/**
+ * @brief UpiCalibrationOsc
+ *
+ * OSC calibration
+ * oscCnt25[9:0] = oscCntTarg[9:0] + oscDeltaCode25[7:0]
+ * oscCnt80[9:0] = oscCntTarg[9:0] + oscDeltaCode80[7:0]
+ * oscCnt[9:0] = m*ITcode[15:8] + C[9:0]
+ * m = (oscCnt80[9:0]-oscCnt25[9:0])/(iTcode80[7:0]-iTcode25[7:0])
+ * c = oscCnt25[9:0] - m*ITcode25[7:0]
+ * write oscCnt[9:0] to register 0x97-98
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void UpiCalibrationOsc(SystemDataType *data)
+{
+ _sys_u16_ u16Temp;
+
+ _sys_u16_ oscCnt25;
+ _sys_u16_ oscCnt80; //10 bits
+ _sys_u16_ oscDeltaCode25;
+ _sys_u16_ oscDeltaCode80; //
+ _sys_u16_ targetOscCnt; //target osc
+
+ _sys_u16_ varM;
+ _sys_u16_ varC;
+
+ _sys_u16_ aveIT;
+
+ /// [AT-PM] : Calculate m & C ; 01/25/2013
+ oscDeltaCode25 = (_sys_u16_)data->otpData->oscDeltaCode25;
+ oscDeltaCode80 = (_sys_u16_)data->otpData->oscDeltaCode80;
+
+ oscCnt25 = OSC_CNT_TARG + oscDeltaCode25;
+ oscCnt80 = OSC_CNT_TARG + oscDeltaCode80;
+
+ varM = (oscCnt80 - oscCnt25)/(data->otpData->aveIT80 - data->otpData->aveIT25);
+ varC = oscCnt25 - varM*(data->otpData->aveIT25);
+
+ /// [AT-PM] : Read ITAve ; 01/27/2013
+ API_I2C_Read(NORMAL,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_AVE_IT_LOW,
+ REG_AVE_IT_HIGH - REG_AVE_IT_LOW + 1,
+ (_sys_u8_ *)&aveIT);
+
+ /// [AT-PM] : Calculate target OSC cnt ; 01/25/2013
+ targetOscCnt = varM*(aveIT/256) + varC;
+ if(targetOscCnt & 0x8000) //check +/-
+ {
+ u16Temp = (_sys_u16_)(targetOscCnt & 0x1fff);
+ u16Temp |= 0x0200; // minus
+ } else{
+ u16Temp = (_sys_u16_)targetOscCnt; //positive data
+ }
+
+ /// [AT-PM] : Write to register 0x97-98 ; 01/25/2013
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ OSCTUNE_CNTB,
+ (_sys_u8_)(u16Temp >> 8));
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ OSCTUNE_CNTA,
+ (_sys_u8_)u16Temp );
+}
+
+/**
+ * @brief UpiAdcStatus
+ *
+ * Check ADC status
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void UpiAdcStatus(SystemDataType *data)
+{
+ if(CheckAdcStatusFail(data) == _UPI_TRUE_) //check ADC Code frozen
+ {
+ DecimateRst();
+ }
+}
+
+#define BACKUP_TIME_BYTE3 (REG_COC_LOW)
+#define BACKUP_TIME_BYTE2 (REG_OTP_CTRL)
+#define BACKUP_NAC_HIGH (REG_CBC21_LOW)
+#define BACKUP_NAC_LOW (REG_CBC21_HIGH)
+#define BACKUP_LMD_HIGH (REG_CBC32_LOW)
+#define BACKUP_LMD_LOW (REG_CBC32_HIGH)
+#define BACKUP_TABLE_UPDATE_IDX (REG_COC_HIGH)
+#define BACKUP_DELTA_CAP_HIGH (REG_DOC_LOW)
+#define BACKUP_DELTA_CAP_LOW (REG_DOC_HIGH)
+#define BACKUP_ADC1_CONV_TIME (REG_COC_HIGH)
+
+/**
+ * @brief UpiLoadBatInfoFromIC
+ *
+ * Load battery information from uG31xx
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void UpiLoadBatInfoFromIC(SystemDataType *data)
+{
+ _sys_u8_ *u8Ptr;
+ _sys_u8_ u8Temp;
+ _sys_u8_ u8TempHigh;
+ _sys_u16_ u16Temp;
+
+ //Load the time tag
+ u8Ptr = (_sys_u8_ *)&data->timeTagFromIC;
+ *u8Ptr = 0;
+ *(u8Ptr + 1) = 0;
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE2, &u8Temp);
+ *(u8Ptr + 2) = u8Temp;
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE3, &u8Temp);
+ *(u8Ptr + 3) = u8Temp;
+
+ //Load the NAC
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_HIGH, &u8TempHigh);
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_LOW, &u8Temp);
+ data->rmFromIC = (_sys_u16_)u8TempHigh;
+ data->rmFromIC = data->rmFromIC*256 + u8Temp;
+
+ // Load LMD
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_HIGH, &u8TempHigh);
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_LOW, &u8Temp);
+ data->fccFromIC = (_sys_u16_)u8TempHigh;
+ data->fccFromIC = data->fccFromIC*256 + u8Temp;
+ UG31_LOGE("[%s]:timeTag =%u/%x ms,NAC = %d mAh,LMD = %dmAh\n",
+ __func__,
+ data->timeTagFromIC,
+ data->timeTagFromIC,
+ data->rmFromIC,
+ data->fccFromIC);
+
+ /// [AT-PM] : Load table update index ; 02/10/2013
+ API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TABLE_UPDATE_IDX, &u8Temp);
+ data->tableUpdateIdxFromIC = u8Temp & 0x07;
+ UG31_LOGI("[%s]: Table Update Index From IC = %d (0x%02x)\n", __func__, data->tableUpdateIdxFromIC, u8Temp);
+
+ /// [AT-PM] : Load delta capacity ; 02/10/2013
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_HIGH, &u8TempHigh);
+ API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_LOW, &u8Temp);
+ data->deltaCapFromIC = (_sys_u16_)u8TempHigh;
+ data->deltaCapFromIC = data->deltaCapFromIC*256 + u8Temp;
+ UG31_LOGI("[%s]: Delta Capacity From IC = %d (0x%02x%02x)\n", __func__, data->deltaCapFromIC, u8TempHigh, u8Temp);
+
+ /// [AT-PM] : Load ADC1 conversion time ; 02/10/2013
+ API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_ADC1_CONV_TIME, &u8Temp);
+ u16Temp = (_sys_u16_)(u8Temp & 0xf8);
+ data->adc1ConvTime = u16Temp*TIME_CONVERT_TIME_TO_MSEC;
+ UG31_LOGI("[%s]: ADC1 Conversion Time From IC = %d (0x%02x)\n", __func__, data->adc1ConvTime, u8Temp);
+
+ /// [AT-PM] : Get RSOC ; 01/31/2013
+ if(data->fccFromIC == 0)
+ {
+ data->rsocFromIC = 0;
+ }
+ else
+ {
+ data->rsocFromIC = CalculateRsoc(data->rmFromIC, data->fccFromIC);
+ }
+
+ data->rmFromICBackup = data->rmFromIC;
+ data->fccFromICBackup = data->fccFromIC;
+ data->rsocFromICBackup = data->rsocFromIC;
+}
+
+/**
+ * @brief UpiUpdateBatInfoFromIC
+ *
+ * Update battery information from uG31xx
+ *
+ * @para data address of SystemDataType
+ * @para deltaQ delta capacity from coulomb counter
+ * @return _UPI_NULL_
+ */
+void UpiUpdateBatInfoFromIC(SystemDataType *data, _sys_s16_ deltaQ)
+{
+ _sys_s32_ tmp32;
+ _sys_u16_ oldRM;
+
+ oldRM = data->rmFromIC;
+
+ tmp32 = (_sys_s32_)data->rmFromIC;
+ tmp32 = tmp32 + deltaQ;
+ if(tmp32 < 0)
+ {
+ tmp32 = 0;
+ }
+ if(tmp32 > data->fccFromIC)
+ {
+ tmp32 = (_sys_s32_)data->fccFromIC;
+ }
+ UG31_LOGI("[%s]: RM = %d + %d = %d\n", __func__,
+ data->rmFromIC, deltaQ, tmp32);
+ data->rmFromIC = (_sys_u16_)tmp32;
+
+ if(data->fccFromIC == 0)
+ {
+ data->rsocFromIC = 0;
+ }
+ else
+ {
+ data->rsocFromIC = CalculateRsoc(data->rmFromIC, data->fccFromIC);
+
+ if(oldRM != 0)
+ {
+ /// [AT-PM] : EDVF is not reached in last log data ; 02/13/2013
+ if(data->rsocFromIC == 0)
+ {
+ /// [AT-PM] : Check EDVF threshold ; 02/13/2013
+ if(data->voltage < data->ggbParameter->edv1Voltage)
+ {
+ /// [AT-PM] : Set capacity to 0 when EDVF reached ; 02/13/2013
+ data->rmFromIC = 0;
+ data->rsocFromIC = 0;
+ }
+ else
+ {
+ /// [AT-PM] : Capacity should not be 0 before EDVF ; 02/13/2013
+ tmp32 = (_sys_s32_)data->fccFromIC;
+ tmp32 = tmp32/CONST_PERCENTAGE;
+ data->rmFromIC = (_sys_u16_)tmp32;
+ data->rsocFromIC = 1;
+ }
+ }
+ else
+ {
+ /// [AT-PM] : Check EDVF threshold ; 02/13/2013
+ if(data->voltage < data->ggbParameter->edv1Voltage)
+ {
+ /// [AT-PM] : Set capacity to 1% when EDVF reached in initialization ; 02/13/2013
+ tmp32 = (_sys_s32_)data->fccFromIC;
+ tmp32 = tmp32/CONST_PERCENTAGE;
+ data->rmFromIC = (_sys_u16_)tmp32;
+ data->rsocFromIC = 1;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief UpiSaveBatInfoTOIC
+ *
+ * Save battery information from uG31xx
+ *
+ * @para data address of SystemDataType
+ * @return _UPI_NULL_
+ */
+void UpiSaveBatInfoTOIC(SystemDataType *data)
+{
+ _sys_u8_ *u8Ptr;
+ _sys_u8_ u8Temp;
+ _sys_u8_ u8Temp1;
+ _sys_u16_ u16Temp;
+
+ #if defined(uG31xx_OS_ANDROID)
+ data->timeTagFromIC = GetSysTickCount();
+ #else ///< else of defined(uG31xx_OS_ANDROID)
+ data->timeTagFromIC = GetTickCount();
+ #endif ///< end of defined(uG31xx_OS_ANDROID)
+ UG31_LOGE("[%s]:timeTag =%u/%x ms,NAC = %d maH,LMD = %d maH\n",
+ __func__,
+ data->timeTagFromIC,
+ data->timeTagFromIC,
+ data->rmFromIC,
+ data->fccFromIC);
+
+ //save the time tag
+ u8Ptr = (_sys_u8_ *)&data->timeTagFromIC;
+ u8Temp = (*(u8Ptr + 2)) & 0xf8;
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE2, u8Temp);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE3, *(u8Ptr + 3));
+
+ //save the NAC
+ u8Temp = (_sys_u8_)((data->rmFromIC & 0xff00)/256);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_HIGH, u8Temp);
+ u8Temp = (_sys_u8_)(data->rmFromIC & 0x00ff);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_LOW, u8Temp);
+
+ // save LMD
+ u8Temp = (_sys_u8_)((data->fccFromIC & 0xff00)/256);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_HIGH, u8Temp);
+ u8Temp = (_sys_u8_)(data->fccFromIC & 0x00ff);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_LOW, u8Temp);
+
+ /// [AT-PM] : Save table update index ; 02/10/2013
+ API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TABLE_UPDATE_IDX, &u8Temp);
+ u8Temp = u8Temp & 0xf8;
+ u8Temp = u8Temp | (data->tableUpdateIdxFromIC & 0x07);
+ API_I2C_SingleWrite(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TABLE_UPDATE_IDX, u8Temp);
+ UG31_LOGI("[%s]: Save Table Update Index = %d - 0x%02x\n", __func__, data->tableUpdateIdxFromIC, u8Temp);
+
+ /// [AT-PM] : Save delta capacity ; 02/10/2013
+ u16Temp = (_sys_u16_)data->deltaCapFromIC;
+ u8Temp = (_sys_u8_)(u16Temp >> 8);
+ API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_HIGH, u8Temp);
+ u8Temp1 = (_sys_u8_)(u16Temp & 0x00ff);
+ API_I2C_SingleWrite(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_LOW, u8Temp1);
+ UG31_LOGI("[%s]: Save Delta Capacity = %d - 0x%02x%02x\n", __func__, data->deltaCapFromIC, u8Temp, u8Temp1);
+
+ /// [AT-PM] : Save adc1 conversion time ; 02/10/2013
+ u16Temp = data->adc1ConvTime/TIME_CONVERT_TIME_TO_MSEC;
+ API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_ADC1_CONV_TIME, &u8Temp);
+ u8Temp = u8Temp & 0x07;
+ u8Temp = u8Temp | (u16Temp & 0xf8);
+ API_I2C_SingleWrite(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_ADC1_CONV_TIME, u8Temp);
+ UG31_LOGI("[%s]: Save ADC1 Conversion Time = %d - 0x%02x\n", __func__, data->adc1ConvTime, u8Temp);
+}
+
+/**
+ * @brief UpiInitAlarm
+ *
+ * Initialize alarm function of uG3105
+ *
+ * @para data address of SystemDataType
+ * @return NULL
+ */
+void UpiInitAlarm(SystemDataType *data)
+{
+ /// [AT-PM] : Set GPIO as alarm pin ; 04/08/2013
+ ConfigureGpio(data);
+
+ /// [AT-PM] : Set delay time ; 04/08/2013
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_TIMER,
+ data->ggbParameter->alarm_timer);
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_CLK_DIVA,
+ data->ggbParameter->clkDivA);
+ API_I2C_SingleWrite(SECURITY,
+ UG31XX_I2C_HIGH_SPEED_MODE,
+ UG31XX_I2C_TEM_BITS_MODE,
+ REG_CLK_DIVB,
+ data->ggbParameter->clkDivB);
+
+ /// [AT-PM] : Enable alarm ; 04/08/2013
+ data->alarmSts = 0;
+ data->uvAlarm.state = _UPI_FALSE_;
+ data->uetAlarm.state = _UPI_FALSE_;
+ data->oetAlarm.state = _UPI_FALSE_;
+ EnableAlarm(data);
+}
+
+/**
+ * @brief UpiAlarmStatus
+ *
+ * Get alarm status
+ *
+ * @para data address of SystemDataType
+ * @return NULL
+ */
+_sys_u8_ UpiAlarmStatus(SystemDataType *data)
+{
+ _sys_u8_ sts;
+ _sys_u8_ tmp8[2];
+
+ sts = 0;
+
+ /// [AT-PM] : Read alarm status from uG3105 ; 04/08/2013
+ API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM1_STATUS, 2, &tmp8[0]);
+ data->alarmSts = (_sys_u16_)tmp8[0];
+ data->alarmSts = data->alarmSts*256 + tmp8[1];
+
+ /// [AT-PM] : Enable alarm ; 04/08/2013
+ EnableAlarm(data);
+
+ /// [AT-PM] : Update current alarm status ; 04/08/2013
+ tmp8[0] = data->uvAlarm.state == _UPI_TRUE_ ? ALARM_STATUS_UV : 0;
+ sts = sts | tmp8[0];
+ tmp8[0] = data->uetAlarm.state == _UPI_TRUE_ ? ALARM_STATUS_UET : 0;
+ sts = sts | tmp8[0];
+ tmp8[0] = data->oetAlarm.state == _UPI_TRUE_ ? ALARM_STATUS_OET : 0;
+ sts = sts | tmp8[0];
+ return (sts);
+}
+