/************************************************************************** * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #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 #include #include #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,180,185,190,195,200,205,210,215,220,225,230,240,245,250,255,265,275,290,295, 300,310,320,330,340,350,371,380,385,400,410,425,435,450,465,470,490,500,510,520, 530,545,560,586,590,605,610,625,650,680,690,710,725,735,750,765,780,795,825,840, 865,883,890,910,930,950,970,990,1010,1030,1053,1070,1090,1110,1130,1150,1170,1190,1210,1230, 1250,1270,1290,1310,1330,1350,1370,1390,1410,1432,1450,1470,1490,1510,1530,1550,1570,1590,1620,1640, 1660,1680,1700,1720,1745,1770,1790,1810,1830,1850,1870,1890,1910,1930,1950,1965,1980,2000,2020,2040, 2060,2080,2100,2115,2125,2140,2150,2170,2190,2210,2225,2240,2255,2275,2290,2310,2325,2340,2355,2370, 2385,2400,2410,2425,2440,2455,2470,2485,2500,2510,2525,2535,2545,2550,2560,2570,2580,2600,2610,2620, 2635,2640,2650,2660,2670,2680,2690,2700,2710,2720,2730,2740,2750,2760,2770,2780 }; #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; if(adcVal) { volt = (27 * adcVal + 554) / 539; } return volt; } /************************************************* Function: sf_aa_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_aa_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; if(adcVal) { volt = (27 * adcVal + 3097) / 531; } 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); if(volt) { adcVal = (volt * 539 - 554) / 27; } return adcVal; } UINT32 sf_aa_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); if(volt) { adcVal = (volt * 531 - 3097) / 27; } 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(SF_ADC_MUXA,0); gpio_direction_output(SF_ADC_MUXB,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(SF_ADC_MUXA, 0);//adc_muxa gpio_set_value(SF_ADC_MUXB, 0);//adc_muxb } else if(SF_ADC_LI == mux)//v-li_det { //B:0 A:1 gpio_set_value(SF_ADC_MUXA, 1);//adc_muxa gpio_set_value(SF_ADC_MUXB, 0);//adc_muxb } else if(SF_ADC_DC == mux)//dc12_det { //B:1 A:0 gpio_set_value(SF_ADC_MUXA, 0);//adc_muxa gpio_set_value(SF_ADC_MUXB, 1);//adc_muxb } else if(SF_ADC_TEMP == mux)//temp_det { //B:1 A:1 gpio_set_value(SF_ADC_MUXA, 1);//adc_muxa gpio_set_value(SF_ADC_MUXB, 1);//adc_muxb } //vos_util_delay_ms(1); vos_util_delay_us(1500); *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; static int getBatFlg = 2; static int getLiBatFlg = 2; static int getDcFlg = 2; UIMenuStoreInfo *puiPara = sf_ui_para_get(); if(getBatAdcFlg) return SUCCESS; getBatAdcFlg = 1; if(getDcFlg) { if(sf_adc_value_get(SF_ADC_DC, &batAdc) == SUCCESS) { dcVoltageVal = sf_battery_voltage_convert(24, 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(batAdc <= 100) { getDcFlg--; } else { getDcFlg = 2; } } if(getLiBatFlg) { if(sf_adc_value_get(SF_ADC_LI, &batAdc) == SUCCESS) { liPolymerVoltageVal = sf_battery_voltage_convert(24, 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(batAdc <= 100) { getLiBatFlg--; } else { getLiBatFlg = 2; } } if(getBatFlg) { if(sf_adc_value_get(SF_ADC_BATT, &batAdc) == SUCCESS) { batVoltageVal = sf_aa_battery_voltage_convert(24, 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(batAdc <= 100) { getBatFlg--; } else { getBatFlg = 2; } } 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 (defined(_MODEL_565_HUNTING_EVB_LINUX_4G_S530_) || defined(_MODEL_565_HUNTING_EVB_LINUX_4G_S550_)) /************************************************* 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(24, 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(24, 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_aa_battery_convert_to_adc(24, 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_BATTERY_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; 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", 18, 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_type_get Description: Get battery type. Input: N/A Output: N/A Return: value: battery type, 0:normal 1:LiPolymer Others: N/A *************************************************/ UINT16 sf_battery_val_get(void) { if(IsPowerDcIn) return (UINT16)DcVoltageVal; else if(LiPolymerVoltageVal) return (UINT16)LiPolymerVoltageVal; else if(BatVoltageVal) return (UINT16)BatVoltageVal; else return 0; } UINT32 sf_get_battery_level(void) { UINT32 tmp = ((UINT32) (sf_battery_value_get(sf_get_night_led_flag()) << 18) | (((sf_battery_type_get()) << 16) | (sf_battery_val_get()))); // printf("[%s:%d] tmp:%ld\n", __FUNCTION__, __LINE__, tmp); return tmp; } /************************************************* 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 < 66) { if(nightMode && (batteryVal >= 45)) 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 < 63) { if(nightMode && (batteryVal >= 45)) 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 < 61) { if(nightMode && (batteryVal >= 45)) value = 1; else value = 0; } else if(batteryVal < 62) { value = 1; } else if(batteryVal < 63) { 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 < 63) { if(nightMode && (batteryVal >= 45)) 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 HW_S530 printf("batteryVal=%d sf_get_mode_flag()=%d \n", batteryVal, sf_get_mode_flag()); sf_view_osd_battery_draw(TRUE); #endif 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) { if(sf_is_usb_flag()){ printf("[%s:%d]usb power\n", __FUNCTION__, __LINE__); return 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); } unsigned long DayCode[12]= {0,31,59,90,120,151,181,212,243,273,304,334}; unsigned long DayCode_Leap[12]= {0,31,60,91,121,152,182,213,244,274,305,335}; UINT8 sf_solar_to_Lunar(UINT16 Year,UINT8 Month, UINT8 Day) { float temp = 0,Tempnum = 0; UINT8 tempn = 0,tempQ = 0,tempR = 0,LunarDay = 0; UINT8 LunarDaytemp = 0; if(Year>=2000) Year=Year-2000; if (Year<21) { UINT16 wMonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334}; UINT32 wNongliData[100] = { 2635,333387,1701,1748,267701,694,2391,133423,1175,396438 ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402 ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738 ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762 ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413 ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395 ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031 ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222 ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709 ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877 }; UINT16 wCurYear; UINT8 wCurMonth,wCurDay; int nIsEnd,m,k,n,i; UINT16 nTheDate,nBit; //static int wCurYear,wCurMonth,wCurDay; //static int nTheDate,nIsEnd,m,k,n,i,nBit; wCurYear = Year+2000; wCurMonth = Month; wCurDay = Day; nTheDate = (wCurYear - 1921) * 365 + (wCurYear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 38; if((!(wCurYear % 4)) && (wCurMonth > 2)) nTheDate = nTheDate + 1; nIsEnd = 0; m = 0; while(nIsEnd != 1) { if(wNongliData[m] < 4095) k = 11; else k = 12; n = k; while(n>=0) { nBit = wNongliData[m]; for(i=1; i=5) LunarDay=(Tempnum-tempn*29.5)+1; else if (LunarDaytemp%1000<10) LunarDay=30; else if (LunarDaytemp%1000>300) LunarDay=1; else LunarDay=Tempnum-tempn*29.5; // UI_PrintOSDNumber(LunarDay, 2, 6, 4); } return LunarDay; } #if SF_BATTERY_TEST == ENABLE void sf_BatteryInfoSave(char *name, FST_FILE fd) { char *tmpBuf = NULL; UINT32 LibatAdc = 0; UINT32 batAdc = 0; //char fileName[64] = {0}; //FST_FILE fd = 0; //struct stat st; UINT32 size = 0; INT32 ret_fs = 0; tmpBuf = malloc(100); 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); }*/ //printf("fileName:%s\n",SF_BATTERY_TEST_FILE); //fd = FileSys_OpenFile(SF_BATTERY_TEST_FILE, FST_OPEN_ALWAYS | FST_OPEN_WRITE); if(LiPolymerVoltageValTest) { LibatAdc = sf_battery_convert_to_adc(24, 100, LiPolymerVoltageValTest); } if(BatVoltageValTest) { batAdc = sf_aa_battery_convert_to_adc(24, 100, BatVoltageValTest); } sprintf(tmpBuf, "%s BatAdc=%lu BatVal=%lu LiBatAdc=%lu LiBatVal=%lu TemperAdc=%lu\r\n", name, batAdc, BatVoltageValTest, LibatAdc, LiPolymerVoltageValTest, TemperAdc); 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); */ size = strlen(tmpBuf); printf("%s:%d size:%lu\r\n", __FUNCTION__, __LINE__, size); ret_fs = FileSys_WriteFile(fd, (UINT8*)tmpBuf, &size, 0, NULL); if (ret_fs != FST_STA_OK) { printf("%s:%d FileSys_WriteFile failed\r\n", __FUNCTION__, __LINE__); } //FileSys_CloseFile((FST_FILE)fd); } free(tmpBuf); } #endif /****************************************************** Function: sf_get_temper_adc Description: Input: N/A Output: N/A Return: TemperAdc Others: N/A *******************************************************/ UINT32 sf_get_temper_adc(void) { return TemperAdc; } /************************************************* Function: sf_battery_print Description: printf battery Input: N/A Output: N/A Return: N/A Others: N/A *************************************************/ void sf_battery_print(void) { if(DcVoltageVal) { printf("DC ADC Value=%lu V:(%lu.%luV),Is Dc In=%s\n", sf_battery_convert_to_adc(24, 100, DcVoltageVal), DcVoltageVal / 10, DcVoltageVal % 10, IsPowerDcIn == 1? "Yes" : "No"); } if(LiPolymerVoltageVal) { printf("Li ADC Value=%lu V:(%lu.%luV)\n", sf_battery_convert_to_adc(24, 100, LiPolymerVoltageVal), LiPolymerVoltageVal / 10, LiPolymerVoltageVal % 10); } else { printf("Other ADC Value=%lu V:(%lu.%luV)\n", sf_aa_battery_convert_to_adc(24, 100, BatVoltageVal), BatVoltageVal / 10, BatVoltageVal % 10); } } #endif