📄 pwr_cust.c
字号:
/*******************************************************************************
*
* pwr_cust.c
*
* Purpose: This file contains functions for battery management.
* These functions can be modified by the customer.
*
* Author Candice Bazanegue (c-brille@ti.com)
*
*
* (C) Texas Instruments 2001
*
******************************************************************************/
#include "rv_defined_swe.h" // for RVM_PWR_SWE
#ifdef RVM_PWR_SWE
#include "abb.h"
#include "rvm_use_id_list.h"
#include "pwr_messages.h"
#include "rvf_api.h"
#include "pwr_cust.h"
#include "pwr_env.h"
#include "pwr_analog_dev.h"
#include "spi_env.h"
#include "spi_task.h"
#include "pwr_liion_cha.h"
#include "pwr_disch.h"
/* Caution: keep ascending order in the temperature arrays !!! */
const INT16 BAT_Celsius_temp_10uA[4]=
{
-10, -5, 0, 5
};
const UINT16 BAT_MADC_temp_10uA[4]=
{
0x13F, 0x103, 0xCB, 0x9C
};
const INT16 BAT_Celsius_temp_50uA[13]=
{
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60
};
const UINT16 BAT_MADC_temp_50uA[13]=
{
0x351, 0x2AD, 0x22E, 0x1C4, 0x169, 0x128, 0xF9, 0xCB, 0x96, 0x83, 0x68, 0x58, 0x4A
};
/* Correpondence between the battery voltage and the remaining capacity in the battery */
/* The voltages have to be expressed in mV units */
/* The capacities are percentages of the total capacity */
/* Caution: keep this order in the array !!!! (in voltage (or capacity) descending order) */
const T_PWR_THRESHOLDS a_pwr_thresholds[NB_THRESHOLDS]=
{{4200,100}, {4000,75}, {3970,50}, {3950,25}, {3900,15}, {3870,10}};
/* Global variable */
extern T_SPI_GBL_INFO *SPI_GBL_INFO_PTR;
/*******************************************************************************
** Function pwr_adc_to_mvolt
**
** Description Converts the MADC voltage reading into voltage in mVolt
**
** Warning: The offsets are not taken into account !!!
**
*******************************************************************************/
UINT16 pwr_adc_to_mvolt(UINT16 voltage_madc)
{
UINT16 voltage_mvolt;
/* Note: /1000 because MADC_VOLTAGE_STEP is expressed in uV */
voltage_mvolt = (voltage_madc * MADC_VOLTAGE_STEP * 4) / 1000;
/* return voltage in mVolt */
return (voltage_mvolt);
}
/*******************************************************************************
** Function pwr_adc_to_mA
**
** Description Converts the MADC current reading into current in mA
**
** Warning: The offsets are not taken into account !!!
**
*******************************************************************************/
UINT16 pwr_adc_to_mA(UINT16 current_madc)
{
UINT16 current_mA;
/* Note: /1000 because MADC_VOLTAGE_STEP is expressed in uA */
current_mA = (current_madc * MADC_CURRENT_STEP) / 1000;
/* return current in mA */
return (current_mA);
}
/*******************************************************************************
** Function pwr_bat_temp_within_limits
**
** Description Check if the battery temperature is within limits
**
** Parameter battery_temperature : battery temperature un Celsius degrees
**
*******************************************************************************/
UINT8 pwr_bat_temp_within_limits(INT16 battery_temperature)
{
rvf_send_trace("Battery temperature (Celsius degrees) ", 38, battery_temperature, RV_TRACE_LEVEL_DEBUG_LOW, PWR_USE_ID);
if ((battery_temperature < BAT_TEMPERATURE_MAX) &&
(battery_temperature > BAT_TEMPERATURE_MIN))
{
rvf_send_trace("Battery temperature within limits",33, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, PWR_USE_ID);
return (TRUE);
}
rvf_send_trace("Battery temperature outside limits",34, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_MEDIUM, PWR_USE_ID);
return (FALSE);
}
/*******************************************************************************
** Function pwr_madc_to_Celius_conv
**
** Description Find the temperature in Celsius degrees corresponding
** to the value given by the MADC
**
*******************************************************************************/
UINT8 pwr_madc_to_Celsius_conv(UINT8 bias_current, UINT16 madc_temp, INT16 *celsius_temp)
{
UINT8 last_index, i;
const UINT16 *MADC_temp_array;
const INT16 *celsius_temp_array;
UINT16 madc_diff;
UINT16 madc_inc;
UINT16 celsius_inc;
/* choose the table */
switch(bias_current)
{
case THEN_10uA:
MADC_temp_array = BAT_MADC_temp_10uA;
celsius_temp_array = BAT_Celsius_temp_10uA;
/* get last index of the lookup table array(s) */
last_index = sizeof(BAT_MADC_temp_10uA)/sizeof(BAT_MADC_temp_10uA[0]);
break;
case THEN_50uA:
MADC_temp_array = BAT_MADC_temp_50uA;
celsius_temp_array = BAT_Celsius_temp_50uA;
/* get last index of the lookup table array(s) */
last_index = sizeof(BAT_MADC_temp_50uA)/sizeof(BAT_MADC_temp_50uA[0]);
break;
default: return (FALSE);
}
/* check the limits */
if((madc_temp > MADC_temp_array[0]) || (madc_temp < MADC_temp_array[last_index-1]))
{
return (FALSE);
}
/* find the two points between which the given point lies */
for(i=0; i<last_index; i++)
{
if(madc_temp >= MADC_temp_array[i])
{
if(i==0)
{
*celsius_temp = celsius_temp_array[0];
return (TRUE);
}
/* the value is between MADC_temp_array[i] and MADC_temp_array[i-1] */
/* interpolate to get a more precise value */
madc_inc = MADC_temp_array[i-1] - MADC_temp_array[i];
celsius_inc = celsius_temp_array[1] - celsius_temp_array[0]; /* positive value */
/* difference between the given point and the first madc value below this point */
madc_diff = madc_temp - MADC_temp_array[i];
*celsius_temp = celsius_temp_array[i] - (madc_diff*celsius_inc)/madc_inc;
return (TRUE);
}
/* else, try a smaller value */
}
return (FALSE);
}
/*******************************************************************************
** Function pwr_get_battery_temperature
**
** Description Start MADC temperature reading
**
** Note If the used battery does not allow to make a temperature
** measurement, the body of this function can be replaced
** by just a "return" with a temperature (in Celsius degrees)
** between BAT_TEMPERATURE_MIN and BAT_TEMPERATURE_MAX.
*******************************************************************************/
void pwr_get_battery_temperature(void)
{
/* set the bias current to 50uA */
ABB_Write_Register_on_page(PAGE0, BCICTL1, THEN_50uA);
rvf_delay(RVF_MS_TO_TICKS(5));
pwr_env_ctrl_blk->timer0_state = BATTERY_50UA_TEMP_TEST;
if (SPI_GBL_INFO_PTR->is_adc_on == FALSE)
{
/* start ADIN2REG channel conversion by writing in the result register */
ABB_Write_Register_on_page(PAGE0, ADIN2REG, 0x0000);
rvf_start_timer (SPI_TIMER0,
RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_1),
FALSE);
}
else /* The L1 asks for ADC conversions */
{
/* Let time for the L1 to ask for new AD conversions */
rvf_start_timer (SPI_TIMER0,
RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_2),
FALSE);
}
}
/*******************************************************************************
** Function pwr_bat_50uA_temp_test_timer_process
**
** Description
**
**
*******************************************************************************/
void pwr_bat_50uA_temp_test_timer_process(void)
{
UINT16 bat_madc_temp;
rvf_send_trace("TIMER0: Battery 50uA temp test",30, NULL_PARAM, RV_TRACE_LEVEL_WARNING, PWR_USE_ID);
pwr_env_ctrl_blk->bat_celsius_temp = (INT16)(0xFFFF);
/* Read ADC result */
bat_madc_temp = ABB_Read_Register_on_page(PAGE0, ADIN2REG);
/* MADC value to Celsius degrees conversion */
if (!pwr_madc_to_Celsius_conv(THEN_50uA, bat_madc_temp, &(pwr_env_ctrl_blk->bat_celsius_temp)))
{
/* outside the 50uA temp range */
/* set the bias current to 10uA */
pwr_env_ctrl_blk->timer0_state = BATTERY_10UA_TEMP_TEST;
ABB_Write_Register_on_page(PAGE0, BCICTL1, THEN_10uA);
rvf_delay(RVF_MS_TO_TICKS(5));
if (SPI_GBL_INFO_PTR->is_adc_on == FALSE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -