nt9856x/rtos/code/driver/na51089/source/mcu/sf_battery.c
payton a9db3fb395 1.模块启动时无需读光敏
2.调整如果第一次为0那么再次可读光敏
3.rtos下增加低电写mcu
4.同步Linux下ui参数修改
2023-07-21 10:52:24 +08:00

1477 lines
34 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 _TemperAdc = 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;
static UINT32 TemperAdc = 0;
static INT16 fTemper = 0;
static INT16 cTemper = 0;
#define SF_READ_BAT_MAX 10
ID FLG_ID_SF_BSTTERY = 0;
#define SF_DC_IN_VOLATAGE 70
#define SF_LI_IN_VOLATAGE 99
const UINT16 Adc2TempTable[]=
{
0,1648,1721,1794,1867,1940,2013,2086,2159, 2232,2305, 2378,2451,2524,2597,2670,2743, 2816, 2889, 2968,
3047,3126,3205,3284,3363,3442,3521,3600/*-15*/,3679,3758,3837,3916,3995,4074,4153,4232,4321/*-10*/, 4427,4533,4639,
4745,4851,4957,5063,5169,5275,5381,5487,5593,5699,5805,5911,6017,6123,6238/*0*/,6334,6430,6526,6622,6718,
6814,6910,7006,7102,7198,7294,7390,7486,7582,7678,7774,7870,7996,8063/*10*/,8182,8301,8420,8539,8658,8777,
8896,9015,9134,9253,9372,9491,9610,9729,9848,9967,10128/*20*/,10221,10314,10407,10500,10593,10686,10779,10872,10965,
11058,11151,11244,11337,11430,11480,11530,11580,11630/*30*/,11680,11730,11780,11830,11880,11930,11980,12032,12097,12162,12232,
12302,12372,12442,12512,12582,12652,12722/*40*/,12769,12816,12863,12910,12957,13004,13051,13098,13145,13192,13239,13286,13333,
13380,13427,13474,13521/*50*/,13591,13661,13731,13801,13871,13941,14011,14081,14151,14221,14291,14361,14431,14501,14571,14641,
14711,14781,14851/*60*/,14941,15031,15111,15181,15251,15321,15391,15461,15531,15601,15671,15741,15811
};
#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;
volt = 27 * adcVal * (resistanceGnd + resistanceVin) / resistanceGnd / 2696;
return volt;
}
UINT32 sf_battery_convert_to_adc(UINT32 resistanceGnd, UINT32 resistanceVin, UINT32 volt)
{
UINT32 adcVal = 0;
//adcVal = volt * resistanceGnd * 511 / 27 / (resistanceGnd + resistanceVin);
adcVal = volt * resistanceGnd * 2696 / 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_ms(1);
*pval = adc_readVoltage(0);
//*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;
UIMenuStoreInfo *puiPara = sf_ui_para_get();
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(puiPara->BatteryLogSwitch)
printf("DC ADC Value:%lu After Convert:%lu(%lu.%luV)\n",batAdc,dcVoltageVal,dcVoltageVal/10,dcVoltageVal%10);
}
if(sf_adc_value_get(SF_ADC_LI, &batAdc) == SUCCESS)
{
liPolymerVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
liPolymerVoltageVal += 4;
if(puiPara->BatteryLogSwitch)
printf("Li ADC Value:%lu After Convert:%lu(%lu.%luV)\n",batAdc,liPolymerVoltageVal,liPolymerVoltageVal/10,liPolymerVoltageVal%10);
}
if(sf_adc_value_get(SF_ADC_BATT, &batAdc) == SUCCESS)
{
batVoltageVal = sf_battery_voltage_convert(15, 100, batAdc);
batVoltageVal += 4;
if(puiPara->BatteryLogSwitch)
printf("Bat ADC Value:%lu After Convert:%lu(%lu.%luV)\n",batAdc,batVoltageVal,batVoltageVal/10,batVoltageVal%10);
}
if(sf_adc_value_get(SF_ADC_TEMP, &batAdc) == SUCCESS)
{
_TemperAdc = batAdc;
if(puiPara->BatteryLogSwitch)
printf("_TemperAdc:%lu \n",batAdc);
}
_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 };
UINT32 temperValueList[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;
temperValueList[readBatCnt] = _TemperAdc;
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);
TemperAdc = sf_get_max_value(temperValueList);
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;
}
cTemper = sf_adc2Temperature((UINT16)TemperAdc, 1);
fTemper = sf_celsius_change_to_fahrenheit(cTemper);
#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;
UINT32 temperValue = 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;
temperValue += _TemperAdc;
if(_LiPolymerVoltageVal)
{
LibatTemp += _LiPolymerVoltageVal;
batCnt++;
}
else
{
batTemp += _BatVoltageVal;
LibatCnt++;
}
readBatCnt++;
if(readBatCnt >= 100)
{
_DcVoltageVal = dcTemp / 100;
_TemperAdc = temperValue/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, TemperAdc:%lu\n", DcVoltageVal / 10, DcVoltageVal % 10, IsPowerDcIn == 1? "Yes" : "No", TemperAdc);
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();
sf_temper_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(APP_POWER_OFF_BATT_EMPTY);
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(APP_POWER_OFF_BATT_EMPTY);
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(APP_POWER_OFF_BATT_EMPTY);
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;
}
INT16 sf_celsius_change_to_fahrenheit(INT16 cTemper)
{
INT16 fTemper = 0;
fTemper = cTemper*9/5 + 32;
printf("fTemper=%d%s\n",fTemper,"`F");
return fTemper;
}
void sf_stamp_temperature_get(INT16 *fTem,INT16 *cTem) /*0:F 1:C*/
{
*fTem = fTemper;
*cTem = cTemper;
}
INT16 sf_adc2Temperature(UINT16 adcValue, UINT8 type)/*type: 0:F 1:C*/
{
UINT16 lowIndex = 0, highIndex = 175, keyIndex = 77, midIndex = 0;
UINT16 tmp = 0;
INT16 Temper = 0;
while(lowIndex < highIndex)
{
if((lowIndex == highIndex) || (lowIndex == (highIndex - 1)))
{
keyIndex = lowIndex;
break;
}
else if( (adcValue < Adc2TempTable[lowIndex]) || (adcValue > Adc2TempTable[highIndex]))
{
keyIndex = 255;
break;
}
else
{
midIndex = (lowIndex + highIndex) / 2;
if(adcValue < Adc2TempTable[midIndex])
highIndex = midIndex;
else
lowIndex = midIndex;
}
//printf("low=%bx,high=%bx\r",lowIndex,highIndex);
}
if(keyIndex == 255)
tmp = 176;
else
tmp = keyIndex;
if(tmp > 176)
tmp = 176;
if(type == 1)
{
if(tmp >= 22)
{
tmp = tmp-22;
if( tmp >= 32)
{
tmp = (tmp - 32) * 5 / 9;
Temper = (INT16)tmp;
}
else
{
tmp = (32 - tmp) * 5 / 9;
Temper = -(INT16)tmp;
}
}
else
{
tmp = 22 - tmp;
tmp = (32 + tmp) * 5 / 9;
Temper = -(INT16)tmp;
}
}
else
{
if (tmp > 22)
{
Temper = tmp - 22;
}
else
{
Temper = 22 - tmp;
Temper = -Temper;
}
}
printf("Temper = %d%s\n", Temper, (type ? "`C" : "`F"));
return Temper;
}
/*************************************************
Function: sf_temper_update
Description: Get temper Voltage.
Input: N/A
Output: N/A
Return: N/A
Others: N/A
*************************************************/
void sf_temper_update(void)
{
cTemper = sf_adc2Temperature((UINT16)TemperAdc, 1);
fTemper = sf_celsius_change_to_fahrenheit(cTemper);
}
#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