nt9856x/rtos/code/driver/na51089/source/mcu/sf_battery.c

1281 lines
28 KiB
C

/**************************************************************************
*
* Copyright (c) 2009-2018 by SiFar Technology, Inc.
*
* This software is copyrighted by and is the property of SiFar
* Technology, Inc.. All rights are reserved by SiFar Technology, Inc..
* This software may only be used in accordance with the corresponding
* license agreement. Any unauthorized use, duplication, distribution,
* or disclosure of this software is expressly forbidden.
*
* This Copyright notice MUST not be removed or modified without prior
* written consent of SiFar Technology, Inc..
*
* SiFar Technology, Inc. reserves the right to modify this software without notice.
*
* Author: Payton
* Ver: 1.0.0 2023.02.14
* Description: mcu code
*
**************************************************************************/
#include <sf_battery.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sf_mcu.h>
#include <kwrap/util.h>
#include <sys/wait.h>
#include <errno.h>
#include <kwrap/debug.h>
#include "PrjInc.h"
#include "IOCfg.h"
#include "DxHunting.h"
#include "sf_led.h"
#include "flow_preview.h"
/*
#include "NvtUser/NvtUser.h"
#include "AppControl/AppControl.h"
#include "comm/hwclock.h"
#include <time.h>
#include <io/gpio.h>
#include <io/adc.h>
#include "UIInfo/UIInfo.h"
#include "IOCfg.h"
*/
#if HUNTING_CAMERA_MCU == ENABLE
UINT32 _DcVoltageVal = 0;
UINT32 _LiPolymerVoltageVal = 0; /*4.0P no use*/
UINT32 _BatVoltageVal = 45;
UINT8 IsNightLedOn = 0;
UINT32 IsPowerDcIn = 1;
UINT32 BatVoltageVal = 45;
SF_BatteryLevel_e sf_LatestBattLevel = SF_BATT_LEVEL_0;
UINT8 needCheckFirst = TRUE;
UINT32 DcVoltageVal = 0;
UINT32 LiPolymerVoltageVal = 0; /*4.0P no use*/
UINT32 batTempLevel = 0xff;
#define SF_READ_BAT_MAX 10
ID FLG_ID_SF_BSTTERY = 0;
#define SF_DC_IN_VOLATAGE 70
#define SF_LI_IN_VOLATAGE 99
/*************************************************
Function: sf_battery_voltage_convert
Description: battery voltage convert
Input: resistanceGnd:Grounding terminal resistance,resistanceVin:Input resistance,adcVal:adc val
Output: N/A
Return: Volt * 10
Others: N/A
*************************************************/
UINT32 sf_battery_voltage_convert(UINT32 resistanceGnd, UINT32 resistanceVin, UINT32 adcVal)
{
UINT32 volt = 0;
/*511 * (detected voltage) / (SARADC reference voltage)
DC input voltage x resistanceGnd/(resistanceGnd + resistanceVin) = detected voltage,
SARADC reference voltage:1.8V
*/
volt = 25 * adcVal * (resistanceGnd + resistanceVin) / resistanceGnd / 512;
return volt;
}
UINT32 sf_battery_convert_to_adc(UINT32 resistanceGnd, UINT32 resistanceVin, UINT32 volt)
{
UINT32 adcVal = 0;
adcVal = volt * resistanceGnd * 512 / 25 / (resistanceGnd + resistanceVin);
return adcVal;
}
UINT32 sf_get_max_value(UINT32 *_ValueList)
{
UINT8 readBatCnt = 0;
UINT32 MaxValue = 0;
for(readBatCnt = 0; readBatCnt < 5; readBatCnt++) /*get max value of 5 times.*/
{
MaxValue = (MaxValue > _ValueList[readBatCnt]? MaxValue : _ValueList[readBatCnt]);
}
return MaxValue;
}
void sf_adc_init(void)
{
if (adc_open(ADC_CH_VOLDET_BATTERY) != 0) {
printf("sf_adc_init Can't open ADC channel for battery voltage detection\r\n");
return;
}
//650 Range is 250K Hz ~ 2M Hz
adc_setConfig(ADC_CONFIG_ID_OCLK_FREQ, 250000); //250K Hz
//battery voltage detection
adc_setChConfig(ADC_CH_VOLDET_BATTERY, ADC_CH_CONFIG_ID_SAMPLE_FREQ, 10000); //10K Hz, sample once about 100 us for CONTINUOUS mode
adc_setChConfig(ADC_CH_VOLDET_BATTERY, ADC_CH_CONFIG_ID_SAMPLE_MODE, (VOLDET_ADC_MODE) ? ADC_CH_SAMPLEMODE_CONTINUOUS : ADC_CH_SAMPLEMODE_ONESHOT);
adc_setChConfig(ADC_CH_VOLDET_BATTERY, ADC_CH_CONFIG_ID_INTEN, FALSE);
// Enable adc control logic
adc_setEnable(TRUE);
}
/*************************************************
Function: sf_adc_value_get
Description: get battery adc
Input: N/A
Output: N/A
Return: SUCCESS/FAIL
Others: N/A
*************************************************/
UINT32 sf_adc_value_get(UINT32 mux, UINT32 *pval)
{
static UINT8 getAdcFlg = 0;
static UINT8 outputflag = 1;
*pval = 0;
if(getAdcFlg)
{
return FAIL;
}
getAdcFlg = 1;
if(outputflag)
{
outputflag = 0;
gpio_direction_output(P_GPIO_0,0);
gpio_direction_output(P_GPIO_1,0);
vos_util_delay_ms(1);
}
if(SF_ADC_BATT == mux)//bat_det
{
//B:0 A:0
gpio_set_value(P_GPIO_0, 0);//adc_muxa
gpio_set_value(P_GPIO_1, 0);//adc_muxb
}
else if(SF_ADC_LI == mux)//v-li_det
{
//B:0 A:1
gpio_set_value(P_GPIO_0, 1);//adc_muxa
gpio_set_value(P_GPIO_1, 0);//adc_muxb
}
else if(SF_ADC_DC == mux)//dc12_det
{
//B:1 A:0
gpio_set_value(P_GPIO_0, 0);//adc_muxa
gpio_set_value(P_GPIO_1, 1);//adc_muxb
}
else if(SF_ADC_TEMP == mux)//temp_det
{
//B:1 A:1
gpio_set_value(P_GPIO_0, 1);//adc_muxa
gpio_set_value(P_GPIO_1, 1);//adc_muxb
}
//vos_util_delay_us(500);
vos_util_delay_ms(1);
*pval = adc_readData(0);
//printf("[%s:%d] 1 *pval:%lu\n", __FUNCTION__, __LINE__,*pval);
getAdcFlg = 0;
return SUCCESS;
}
#if 0
/*************************************************
Function: sf_battery_adc_value_get_once
Description: get battery adc only once
Input: N/A
Output: N/A
Return: SUCCESS/FAIL
Others: N/A
*************************************************/
UINT32 sf_battery_adc_value_get_once(void)
{
UINT32 batAdc = 0;
static UINT8 getBatAdcFlg = 0;
if(getBatAdcFlg)
{
return SUCCESS;
}
getBatAdcFlg = 1;
if(sf_adc_value_get(SF_ADC_DC, &batAdc) == SUCCESS)
{
_DcVoltageVal = sf_battery_voltage_convert(10, 100, batAdc);
if(sf_adc_value_get(SF_ADC_LI, &batAdc) == SUCCESS)
{
_LiPolymerVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
if(_LiPolymerVoltageVal > SF_LI_IN_VOLATAGE)
{
getBatAdcFlg = 0;
return SUCCESS;
}
else
{
_LiPolymerVoltageVal = 0;
if(sf_adc_value_get(SF_ADC_BATT, &batAdc) == SUCCESS)
{
_BatVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
//_BatVoltageVal += 1;
getBatAdcFlg = 0;
return SUCCESS;
}
else
{
getBatAdcFlg = 0;
printf("%s:%d [ERR] failed !!!\n", __FUNCTION__, __LINE__);
return FAIL;
}
}
}
else
{
getBatAdcFlg = 0;
printf("%s:%d [ERR] failed !!!\n", __FUNCTION__, __LINE__);
return FAIL;
}
}
else
{
getBatAdcFlg = 0;
printf("%s:%d [ERR] failed !!!\n", __FUNCTION__, __LINE__);
return FAIL;
}
}
#else
/*************************************************
Function: sf_battery_adc_value_get_once
Description: get battery adc only once
Input: N/A
Output: N/A
Return: SUCCESS/FAIL
Others: N/A
*************************************************/
UINT32 sf_battery_adc_value_get_once(void)
{
UINT32 batAdc = 0;
UINT32 dcVoltageVal = 0;
UINT32 liPolymerVoltageVal = 0;
UINT32 batVoltageVal = 0;
static UINT8 getBatAdcFlg = 0;
if(getBatAdcFlg)
return SUCCESS;
getBatAdcFlg = 1;
if(sf_adc_value_get(SF_ADC_DC, &batAdc) == SUCCESS)
{
dcVoltageVal = sf_battery_voltage_convert(10, 100, batAdc);
}
if(sf_adc_value_get(SF_ADC_LI, &batAdc) == SUCCESS)
{
liPolymerVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
}
if(sf_adc_value_get(SF_ADC_BATT, &batAdc) == SUCCESS)
{
batVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
batVoltageVal += 3;
}
_DcVoltageVal = dcVoltageVal;
if ((liPolymerVoltageVal > batVoltageVal))
{
_LiPolymerVoltageVal = liPolymerVoltageVal;
_BatVoltageVal = 0;
}
else
{
_LiPolymerVoltageVal = 0;
_BatVoltageVal = batVoltageVal;
}
getBatAdcFlg = 0;
return SUCCESS;
}
#endif
#if HW_S530
/*************************************************
Function: sf_battery_level_update
Description: Get battery Voltage with Level.
Input: N/A
Output: N/A
Return: N/A
Others: N/A
*************************************************/
void sf_battery_level_update(void)
{
UINT8 batteryVal = 0;
UINT8 batteryLevel = SF_BATT_LEVEL_0;
batteryVal = sf_battery_value_get(sf_get_night_led_flag());
if(batteryVal >= 70)
{
batteryLevel = SF_BATT_LEVEL_4;
}
else if(batteryVal >= 40)
{
batteryLevel = SF_BATT_LEVEL_3;
}
else if(batteryVal >= 20)
{
batteryLevel = SF_BATT_LEVEL_2;
}
else if(batteryVal >= 1)
{
batteryLevel = SF_BATT_LEVEL_1;
}
else
{
batteryLevel = SF_BATT_LEVEL_0;
}
sf_LatestBattLevel = batteryLevel;
}
#else
/*************************************************
Function: sf_battery_level_update
Description: Get battery Voltage with Level.
Input: N/A
Output: N/A
Return: N/A
Others: N/A
*************************************************/
void sf_battery_level_update(void)
{
UINT8 batteryVal = 0;
UINT8 batteryLevel = SF_BATT_LEVEL_0;
if(sf_get_night_led_flag())
{
return;
}
if(IsPowerDcIn == 0)
{
batteryVal = BatVoltageVal;
if(SysGetFlag(BatteryType) == SF_BATT_ALKALINE)
{
if(batteryVal >= 106)
{
batteryLevel = SF_BATT_LEVEL_5;
}
else if(batteryVal >= 102)
{
batteryLevel = SF_BATT_LEVEL_4;
}
else if(batteryVal >= 97)
{
batteryLevel = SF_BATT_LEVEL_3;
}
else if(batteryVal >= 90)
{
batteryLevel = SF_BATT_LEVEL_2;
}
else if(batteryVal >= 75)
{
batteryLevel = SF_BATT_LEVEL_1;
}
else
{
batteryLevel = SF_BATT_LEVEL_0;
}
}
else if(SysGetFlag(BatteryType) == SF_BATT_NI_MH)
{
if(batteryVal >= 103)
{
batteryLevel = SF_BATT_LEVEL_5;
}
else if(batteryVal >= 101)
{
batteryLevel = SF_BATT_LEVEL_4;
}
else if(batteryVal >= 100)
{
batteryLevel = SF_BATT_LEVEL_3;
}
else if(batteryVal >= 97)
{
batteryLevel = SF_BATT_LEVEL_2;
}
else if(batteryVal >= 75)
{
batteryLevel = SF_BATT_LEVEL_1;
}
else
{
batteryLevel = SF_BATT_LEVEL_0;
}
}
else if(SysGetFlag(BatteryType) == SF_BATT_LI) //5.8CG Li Battery
{
if(batteryVal >= 122)
{
batteryLevel = SF_BATT_LEVEL_5;
}
else if(batteryVal >= 120)
{
batteryLevel = SF_BATT_LEVEL_4;
}
else if(batteryVal >= 117)
{
batteryLevel = SF_BATT_LEVEL_3;
}
else if(batteryVal >= 110)
{
batteryLevel = SF_BATT_LEVEL_2;
}
else if(batteryVal >= 80)
{
batteryLevel = SF_BATT_LEVEL_1;
}
else
{
batteryLevel = SF_BATT_LEVEL_0;
}
}
}
else
{
batteryLevel = SF_BATT_LEVEL_5;
}
sf_LatestBattLevel = batteryLevel;
if(SysGetFlag(BatteryLogSwitch))
{
printf("battery levle=%d\n", sf_LatestBattLevel);
}
}
#endif
/*************************************************
Function: sf_check_low_battery
Description: check is low battery in auto mode.
Output: N/A
Return: TRUE/FALSE
Others: N/A
*************************************************/
BOOL sf_check_low_battery(void)
{
UINT8 lowCompareVal = 0;
BOOL ret = FALSE;
UIMenuStoreInfo *puiPara = sf_ui_para_get();
if(sf_is_usb_flag())
{
return FALSE;
}
sf_battery_level_update();
if(sf_get_night_led_flag())
{
if(puiPara->BatteryType == SF_BATT_ALKALINE)
{
lowCompareVal = 69;
}
else if(puiPara->BatteryType == SF_BATT_NI_MH)
{
lowCompareVal = 71;
}
}
else
{
if(puiPara->BatteryType == SF_BATT_ALKALINE)
{
lowCompareVal = 80;
}
else if(puiPara->BatteryType == SF_BATT_NI_MH)
{
lowCompareVal = 80;
}
else
{
lowCompareVal = 80;
}
}
if((IsPowerDcIn == 0) && (BatVoltageVal < lowCompareVal))
{
ret = TRUE;
}
else
{
ret = FALSE;
}
return ret;
}
/******************************************************
Function: sf_battery_value_fast_get
Description: auto mode:take the maximum of 5 times;
manual mode:take the average of 10 times;
Input: N/A
Output: N/A
Return: SUCCESS/FAIL
Others: N/A
*******************************************************/
signed int sf_battery_value_fast_get(void)
{
UINT8 readBatCnt = 0;
UINT32 dcValueList[12] = { 0 };
UINT32 batValueList[12] = { 0 };
UIMenuStoreInfo *puiPara = sf_ui_para_get();
SINT32 ret = FAIL;
//if((sf_get_mode_flag() == 0) || (needCheckFirst == TRUE))
{
//printf("[%s:%d]ConfigureModeFlag=%d,needCheckFirst=%d\n",__FUNCTION__,__LINE__,sf_get_mode_flag(),needCheckFirst);
//needCheckFirst = FALSE;
for(readBatCnt = 0; readBatCnt < 5;) //get max value of 5 times.
{
if(sf_battery_adc_value_get_once() == SUCCESS)
{
dcValueList[readBatCnt] = _DcVoltageVal;
if(puiPara->BatteryLogSwitch)
{
printf("%s:%d [%d]DC ADC Value=%lu,After Convert:%lu(%lu.%luV)\n", __FUNCTION__, __LINE__, readBatCnt + 1, sf_battery_convert_to_adc(10, 100, dcValueList[readBatCnt]),
dcValueList[readBatCnt], dcValueList[readBatCnt] / 10, dcValueList[readBatCnt] % 10);
}
if(_LiPolymerVoltageVal)
{
batValueList[readBatCnt] = _LiPolymerVoltageVal;
if(puiPara->BatteryLogSwitch)
{
printf("%s:%d [%d]Li Battery ADC Value=%lu,After Convert:%lu(%lu.%luV)\n", __FUNCTION__, __LINE__, readBatCnt + 1, sf_battery_convert_to_adc(15, 100, batValueList[readBatCnt]),
batValueList[readBatCnt], batValueList[readBatCnt] / 10, batValueList[readBatCnt] % 10);
}
}
else
{
batValueList[readBatCnt] = _BatVoltageVal;
if(puiPara->BatteryLogSwitch)
{
printf("%s:%d [%d]Other Battery ADC Value=%lu,After Convert:%lu(%lu.%luV)\n", __FUNCTION__, __LINE__, readBatCnt + 1, sf_battery_convert_to_adc(15, 100, batValueList[readBatCnt]),
batValueList[readBatCnt], batValueList[readBatCnt] / 10, batValueList[readBatCnt] % 10);
}
}
//appTimeDelayMs(50);
readBatCnt++;
}
}
DcVoltageVal = sf_get_max_value(dcValueList);
if(_LiPolymerVoltageVal)
{
LiPolymerVoltageVal = sf_get_max_value(batValueList);
BatVoltageVal = 0;
}
else
{
BatVoltageVal = sf_get_max_value(batValueList);
LiPolymerVoltageVal = 0;
}
if((DcVoltageVal > LiPolymerVoltageVal) && (DcVoltageVal >= BatVoltageVal) && (DcVoltageVal >= SF_DC_IN_VOLATAGE))
{
IsPowerDcIn = 1;
}
else
{
IsPowerDcIn = 0;
}
if(puiPara->BatteryLogSwitch)
{
printf("\n[max]DC,After Convert:(%lu.%luV),Is Dc In=%s\n", DcVoltageVal / 10, DcVoltageVal % 10, IsPowerDcIn == 1? "Yes" : "No");
if(LiPolymerVoltageVal)
{
printf("[max]Li Battery,After Convert:(%lu.%luV)\n\n", LiPolymerVoltageVal / 10, LiPolymerVoltageVal % 10);
}
else
{
printf("[max]Other Battery,After Convert:(%lu.%luV)\n\n", BatVoltageVal / 10, BatVoltageVal % 10);
}
}
ret = SUCCESS;
}
return ret;
}
/*************************************************
Function: sf_battery_level_polling
Description: polling battery level
Input: N/A
Output: N/A
Return: N/A
Others: N/A
*************************************************/
void sf_battery_level_polling(void)
{
UINT16 readBatCnt = 0;
UINT32 dcTemp = 0;
UINT32 batTemp = 0;
UINT32 LibatTemp = 0;
UINT8 LibatCnt = 0;
UINT8 batCnt = 0;
UIMenuStoreInfo *puiPara = sf_ui_para_get();
static UINT32 prePowerDcStatus = 0;
//signed int ret = FALSE;
static UINT32 battEmpty = 0;
for(readBatCnt = 0; readBatCnt < 100;) //get average value of 100 times.
{
if(sf_battery_adc_value_get_once() == SUCCESS)
{
vos_util_delay_ms(100);
dcTemp += _DcVoltageVal;
if(_LiPolymerVoltageVal)
{
LibatTemp += _LiPolymerVoltageVal;
batCnt++;
}
else
{
batTemp += _BatVoltageVal;
LibatCnt++;
}
readBatCnt++;
if(readBatCnt >= 100)
{
_DcVoltageVal = dcTemp / 100;
if(LibatCnt)
_LiPolymerVoltageVal = LibatTemp / LibatCnt;
if(batCnt)
_BatVoltageVal = batTemp / batCnt;
if((_DcVoltageVal > _LiPolymerVoltageVal) && (_DcVoltageVal >= _BatVoltageVal) && (_DcVoltageVal >= SF_DC_IN_VOLATAGE))
{
IsPowerDcIn = 1;
}
else
{
IsPowerDcIn = 0;
}
if ((_LiPolymerVoltageVal > _BatVoltageVal))
{
_BatVoltageVal = 0;
}
else
{
_LiPolymerVoltageVal = 0;
}
DcVoltageVal = _DcVoltageVal;
LiPolymerVoltageVal = _LiPolymerVoltageVal;
BatVoltageVal = _BatVoltageVal;
if(puiPara->BatteryLogSwitch)
{
printf("\n[average]DC,After Convert:(%lu.%luV),Is Dc In=%s\n", DcVoltageVal / 10, DcVoltageVal % 10, IsPowerDcIn == 1? "Yes" : "No");
if(LiPolymerVoltageVal)
{
printf("[average]Li Battery,After Convert:(%lu.%luV)\n\n", LiPolymerVoltageVal / 10, LiPolymerVoltageVal % 10);
}
else
{
printf("[average]Other Battery,After Convert:(%lu.%luV)\n\n", BatVoltageVal / 10, BatVoltageVal % 10);
}
}
}
}
}
sf_battery_level_update();
//ret = sf_check_low_battery();
if(puiPara->BatteryLogSwitch)
{
printf("[%s:%d]batTempLevel=%lu,sf_LatestBattLevel=%d\n", __FUNCTION__, __LINE__, batTempLevel, sf_LatestBattLevel);
}
if((batTempLevel != sf_LatestBattLevel) || IsPowerDcIn != prePowerDcStatus)
{
prePowerDcStatus = IsPowerDcIn;
batTempLevel = sf_LatestBattLevel;
#if HW_S530
sf_view_osd_battery_draw(TRUE);
#endif
}
if(sf_LatestBattLevel == SF_BATT_LEVEL_0)
{
if(sf_get_night_led_flag())
{
sf_ir_led_set(0, 0, 0, 0);
//pwm_pwm_disable(IRLED_PWMID);
//printf("%s:%d \n", __FUNCTION__, __LINE__);
}
//the Module not need sleep.
//gModuleSleep = 0;
sf_set_module_sleep_flag(0);
if(battEmpty == 0)
{
battEmpty = 1;
printf("[%s:%d]power off because low battery\n", __FUNCTION__, __LINE__);
//Ux_PostEvent(NVTEVT_SYSTEM_SHUTDOWN, 1, APP_POWER_OFF_BATT_EMPTY); //shutdown start
#if SF_IQ_TEST != ENABLE
sf_set_power_off_flag(1);
flow_preview_set_stop_flag(TRUE);
#endif
}
}
else if(sf_LatestBattLevel == SF_BATT_LEVEL_1)
{
if((sf_battery_value_get(sf_get_night_led_flag()) < 10)/* && (sf_led_get(SF_LED_BAT1) != SF_LED_STATE_SLOW_FLASHING)*/)
{
printf("[%s:%d] SF_LED_BAT1 SF_LED_STATE_SLOW_FLASHING\n", __FUNCTION__, __LINE__);
//sf_led_set(SF_LED_BAT1, SF_LED_STATE_SLOW_FLASHING);
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_0_SLOW);
}
else if((sf_battery_value_get(sf_get_night_led_flag()) == 10) /*&& (sf_led_get(SF_LED_BAT1) != SF_LED_STATE_ON)*/)
{
printf("[%s:%d] SF_LED_BAT1 SF_LED_STATE_SLOW_FLASHING\n", __FUNCTION__, __LINE__);
//sf_led_set(SF_LED_BAT1, SF_LED_STATE_ON);
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_1);
}
}
else
{
}
}
THREAD_RETTYPE sf_battery_check_thread(void *arg)
{
THREAD_ENTRY();
printf("[%s:%d] s\n", __FUNCTION__, __LINE__);
if(sf_is_battery_low(1, 0) == TRUE)
{
printf("[%s:%d]power off because low battery\n", __FUNCTION__, __LINE__);
//Ux_PostEvent(NVTEVT_SYSTEM_SHUTDOWN, 1, APP_POWER_OFF_BATT_EMPTY); //shutdown start
#if SF_IQ_TEST != ENABLE
sf_set_power_off_flag(1);
flow_preview_set_stop_flag(TRUE);
#endif
}
else {
while(sf_while_flag())
{
sf_battery_level_polling();
}
}
printf("[%s:%d] e \n", __FUNCTION__, __LINE__);
THREAD_RETURN(0);
}
void sf_battery_thread_init(void)
{
static UINT8 dofirst = 1;
printf("[%s:%d] s\n", __FUNCTION__, __LINE__);
if(!dofirst)
return;
dofirst = 0;
sf_adc_init();
VK_TASK_HANDLE s_handle_batt = 0;
vos_flag_create(&FLG_ID_SF_BSTTERY, NULL, "FLG_ID_SF_BSTTERY");
/*thread creat*/
s_handle_batt = vos_task_create(sf_battery_check_thread, NULL, "sf_battery_check_thread", 25, 2048);
vos_task_resume(s_handle_batt);
printf("[%s:%d] e\n", __FUNCTION__, __LINE__);
}
UINT8 sf_get_night_led_flag(void)
{
return IsNightLedOn;
}
void sf_set_night_led_flag(UINT8 flag)
{
IsNightLedOn = flag;
}
/*************************************************
Function: sf_battery_level_get
Description: get battery level
Input: N/A
Output: N/A
Return: SUCCESS/FAIL
Others: N/A
*************************************************/
UINT32 sf_battery_level_get(void)
{
return (UINT32)sf_LatestBattLevel;
}
void sf_view_osd_battery_draw(UINT8 bShow)
{
printf("[%s:%d] s\n", __FUNCTION__, __LINE__);
#if HW_S530
if(!sf_get_mode_flag())
{
return;
}
if(bShow)
{
switch(sf_battery_level_get())
{
case SF_BATT_LEVEL_0:
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_0);
break;
case SF_BATT_LEVEL_1:
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_1);
break;
case SF_BATT_LEVEL_2:
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_2);
break;
case SF_BATT_LEVEL_3:
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_3);
break;
case SF_BATT_LEVEL_4:
sf_sys_status_led_set(SF_LED_SYS_STATE_BAT_4);
break;
default:
break;
}
}
#endif
printf("[%s:%d] e\n", __FUNCTION__, __LINE__);
}
/*************************************************
Function: sf_battery_value_get
Description: get battery value x%
Input: nightMode or no
Output: N/A
Return: battery value x%
Others: N/A
*************************************************/
UINT8 sf_battery_value_get(UINT8 nightMode)
{
UINT8 value = 0;
UINT8 batteryVal = 0;
UIMenuStoreInfo *puiPara = sf_ui_para_get();
if(IsPowerDcIn == 0)
{
//printf("BatMedian:%d\n", BatMedian);
if(LiPolymerVoltageVal)
{
batteryVal = LiPolymerVoltageVal;
if(batteryVal < 65)
{
if(nightMode && (batteryVal >= 43))
value = 1;
else
value = 0;
}
else if(batteryVal < 71)
{
value = 1;
}
else if(batteryVal < 72)
{
value = 10;
}
else if(batteryVal < 73)
{
value = 20;
}
else if(batteryVal < 74)
{
value = 30;
}
else if(batteryVal < 75)
{
value = 40;
}
else if(batteryVal < 76)
{
value = 50;
}
else if(batteryVal < 77)
{
value = 60;
}
else if(batteryVal < 78)
{
value = 70;
}
else if(batteryVal < 79)
{
value = 80;
}
else if(batteryVal < 81)
{
value = 90;
}
else
{
value = 100;
}
}
else
{
batteryVal = BatVoltageVal;
if(puiPara->BatteryType == SF_BATT_ALKALINE) //ALK
{
if(batteryVal < 62)
{
if(nightMode && (batteryVal >= 43))
value = 1;
else
value = 0;
}
else if(batteryVal < 65)
{
value = 1;
}
else if(batteryVal < 69)
{
value = 10;
}
else if(batteryVal < 71)
{
value = 20;
}
else if(batteryVal < 72)
{
value = 30;
}
else if(batteryVal < 73)
{
value = 40;
}
else if(batteryVal < 75)
{
value = 50;
}
else if(batteryVal < 76)
{
value = 60;
}
else if(batteryVal < 78)
{
value = 70;
}
else if(batteryVal < 80)
{
value = 80;
}
else if(batteryVal < 83)
{
value = 90;
}
else
{
value = 100;
}
}
else if(puiPara->BatteryType == SF_BATT_NI_MH) //NIH
{
if(batteryVal < 60)
{
if(nightMode && (batteryVal >= 43))
value = 1;
else
value = 0;
}
else if(batteryVal < 61)
{
value = 1;
}
else if(batteryVal < 62)
{
value = 10;
}
else if(batteryVal < 64)
{
value = 20;
}
else if(batteryVal < 65)
{
value = 30;
}
else if(batteryVal < 67)
{
value = 40;
}
else if(batteryVal < 68)
{
value = 50;
}
else if(batteryVal < 70)
{
value = 60;
}
else if(batteryVal < 71)
{
value = 70;
}
else if(batteryVal < 73)
{
value = 80;
}
else if(batteryVal < 75)
{
value = 90;
}
else
{
value = 100;
}
}
else
{
if(batteryVal < 62)
{
if(nightMode && (batteryVal >= 43))
value = 1;
else
value = 0;
}
else if(batteryVal < 75)
{
value = 1;
}
else if(batteryVal < 80)
{
value = 10;
}
else if(batteryVal < 82)
{
value = 20;
}
else if(batteryVal < 83)
{
value = 30;
}
else if(batteryVal < 84)
{
value = 40;
}
else if(batteryVal < 86)
{
value = 50;
}
else if(batteryVal < 91)
{
value = 60;
}
else if(batteryVal < 92)
{
value = 70;
}
else if(batteryVal < 93)
{
value = 80;
}
else if(batteryVal < 94)
{
value = 90;
}
else
{
value = 100;
}
}
}
}
else
{
value = 100;
}
return value;
}
/*************************************************
Function: sf_battery_type_get
Description: Get battery type.
Input: N/A
Output: N/A
Return: value: battery type, 0:normal 1:LiPolymer
Others: N/A
*************************************************/
UINT8 sf_battery_type_get(void)
{
if(IsPowerDcIn)
return SF_POWER_TYPE_DC;
else if(LiPolymerVoltageVal)
return SF_POWER_TYPE_LI_POLYER;
else
return SF_POWER_TYPE_AA;
}
/*************************************************
Function: sf_is_battery_low
Description: Judge whether the power is low
Input: refresh:refresh ADC acquisition or no,
nightMode:day or night
Output: N/A
Return: TRUE/FALSE
Others: N/A
*************************************************/
BOOL sf_is_battery_low(UINT8 refresh, UINT8 nightMode)
{
UINT8 batteryVal = 0;
UINT8 batteryLevel = 0;
if(refresh)
{
sf_battery_value_fast_get();
//printf("DC=%d Custom=%d bat=%d\n", dcValue, CustomValue, batli8v);
}
batteryVal = sf_battery_value_get(nightMode);
if(!sf_get_mode_flag())
{
if(batteryVal >= 70)
{
batteryLevel = SF_BATT_LEVEL_4;
}
else if(batteryVal >= 40)
{
batteryLevel = SF_BATT_LEVEL_3;
}
else if(batteryVal >= 20)
{
batteryLevel = SF_BATT_LEVEL_2;
}
else if(batteryVal >= 1)
{
batteryLevel = SF_BATT_LEVEL_1;
}
else
{
batteryLevel = SF_BATT_LEVEL_0;
}
sf_LatestBattLevel = batteryLevel;
}
if(batteryVal == 0)
return TRUE;
return FALSE;
}
/*************************************************
Function: sf_battery_check_init
Description: Perform a battery test in manual mode.
Input: N/A
Output: N/A
Return: value: TRUE ,FALSE
Others: N/A
*************************************************/
BOOL sf_battery_check_init(void)
{
if(sf_battery_value_fast_get() == SUCCESS)
{
if(sf_is_battery_low(0, 0) == TRUE)
{
printf("[%s:%d]power off because low battery\n", __FUNCTION__, __LINE__);
//Ux_PostEvent(NVTEVT_SYSTEM_SHUTDOWN, 1, APP_POWER_OFF_BATT_EMPTY); //shutdown start
sf_set_power_off_flag(1);
flow_preview_set_stop_flag(TRUE);
return FALSE;
}
}
else
{
return FALSE;
}
#if HW_S530
sf_view_osd_battery_draw(TRUE);
#endif
return TRUE;
}
void sf_set_need_check_first(void)
{
needCheckFirst = TRUE;
}
/*************************************************
Function: sf_is_enough_power_to_update
Description: whether or not enough power to update
Input: N/A
Output: N/A
Return: TRUE/FALSE
Others: N/A
*************************************************/
BOOL sf_is_enough_power_to_update(void)
{
//sf_set_need_check_first();
sf_battery_value_fast_get();
printf("update DC=%lu Li=%lu Bat=%lu\n", DcVoltageVal, LiPolymerVoltageVal, BatVoltageVal);
if(sf_battery_value_get(0) < 40)
{
printf("low battery, no update\n");
return FALSE;
}
return TRUE;
}
#endif