1327 lines
29 KiB
C
1327 lines
29 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
|
|
|
|
#if SF_BATTERY_TEST == ENABLE
|
|
UINT32 LiPolymerVoltageValTest = 0;
|
|
UINT32 BatVoltageValTest = 0;
|
|
#endif
|
|
/*************************************************
|
|
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 = 27 * adcVal * (resistanceGnd + resistanceVin) / resistanceGnd / 511;
|
|
|
|
return volt;
|
|
}
|
|
|
|
UINT32 sf_battery_convert_to_adc(UINT32 resistanceGnd, UINT32 resistanceVin, UINT32 volt)
|
|
{
|
|
UINT32 adcVal = 0;
|
|
|
|
adcVal = volt * resistanceGnd * 511 / 27 / (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);
|
|
|
|
gpio_direction_output(P_GPIO_0,0);
|
|
gpio_direction_output(P_GPIO_1,0);
|
|
}
|
|
/*************************************************
|
|
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(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(400);
|
|
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);
|
|
dcVoltageVal += 4;
|
|
}
|
|
|
|
if(sf_adc_value_get(SF_ADC_LI, &batAdc) == SUCCESS)
|
|
{
|
|
liPolymerVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
|
|
liPolymerVoltageVal += 4;
|
|
}
|
|
|
|
if(sf_adc_value_get(SF_ADC_BATT, &batAdc) == SUCCESS)
|
|
{
|
|
batVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
|
|
batVoltageVal += 4;
|
|
}
|
|
|
|
_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;
|
|
}
|
|
#if SF_BATTERY_TEST == ENABLE
|
|
LiPolymerVoltageValTest = LiPolymerVoltageVal;
|
|
BatVoltageValTest = BatVoltageVal;
|
|
#endif
|
|
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;
|
|
|
|
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)
|
|
{
|
|
sf_adc_init();
|
|
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
|
|
}
|
|
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;
|
|
}
|
|
|
|
#if SF_BATTERY_TEST == ENABLE
|
|
|
|
|
|
void sf_BatteryInfoSave(char *name)
|
|
{
|
|
char *tmpBuf = NULL;
|
|
UINT32 LibatAdc = 0;
|
|
UINT32 batAdc = 0;
|
|
|
|
//char fileName[64] = {0};
|
|
int fd = 0;
|
|
struct stat st;
|
|
|
|
tmpBuf = malloc(512);
|
|
|
|
if (tmpBuf == NULL) {
|
|
printf("%s:%d tmpBuf malloc err\n", __FUNCTION__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
//snprintf(fileName, sizeof(fileName), "%s", SF_BATTERY_TEST_FILE);
|
|
|
|
if(access(SF_BATTERY_TEST_FILE, F_OK) == 0)
|
|
{
|
|
printf("fileName:%s\n",SF_BATTERY_TEST_FILE);
|
|
fd = open(SF_BATTERY_TEST_FILE, O_APPEND | O_WRONLY);
|
|
}
|
|
else {
|
|
fd = open(SF_BATTERY_TEST_FILE, O_APPEND | O_WRONLY | O_CREAT);
|
|
}
|
|
|
|
LibatAdc = sf_battery_convert_to_adc(15, 100, LiPolymerVoltageValTest);
|
|
batAdc = sf_battery_convert_to_adc(15, 100, BatVoltageValTest);
|
|
|
|
|
|
sprintf(tmpBuf, "%s BatAdc=%lu BatVal=%lu LiBatAdc=%lu LiBatVal=%lu\r\n", name, batAdc, BatVoltageValTest, LibatAdc, LiPolymerVoltageValTest);
|
|
printf("%s\r", tmpBuf);
|
|
|
|
if(fd)
|
|
{
|
|
fstat(fd, &st);
|
|
lseek(fd, 0, SEEK_END);
|
|
write(fd, tmpBuf, strlen(tmpBuf));
|
|
close(fd);
|
|
printf("Add Success st_size:%ld\n", st.st_size);
|
|
}
|
|
free(tmpBuf);
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|