Write battery values to LPC mapped memory

Update the mapped memory inside charge state machine.

BUG=chrome-os-partner:8184
TEST=none

Change-Id: I84f6079fff9683b6a7a96e3bb066e0e043c0db28
This commit is contained in:
Rong Chang
2012-03-01 22:11:38 +08:00
parent acfbecebe4
commit 051b5f6dd3
2 changed files with 89 additions and 7 deletions

View File

@@ -11,6 +11,8 @@
#include "console.h"
#include "charger.h"
#include "gpio.h"
#include "lpc.h"
#include "lpc_commands.h"
#include "smart_battery.h"
#include "timer.h"
#include "uart.h"
@@ -18,6 +20,8 @@
/* Stop charge when state of charge reaches this percentage */
#define STOP_CHARGE_THRESHOLD 100
/* Critical level of when discharging reaches this percentage */
#define BATT_CRITICAL_LEVEL 10
/* power state task polling period in usec */
#define POLL_PERIOD_LONG 500000
@@ -59,25 +63,55 @@ static inline int get_ac(void)
*/
static int battery_params(struct batt_params *batt)
{
int rv;
int rv, d;
/* Direct mem mapped EC data */
uint32_t *memmap_batt_volt = (uint32_t*)(lpc_get_memmap_range() +
EC_LPC_MEMMAP_BATT_VOLT);
uint32_t *memmap_batt_rate = (uint32_t*)(lpc_get_memmap_range() +
EC_LPC_MEMMAP_BATT_RATE);
uint32_t *memmap_batt_cap = (uint32_t*)(lpc_get_memmap_range() +
EC_LPC_MEMMAP_BATT_CAP);
rv = battery_temperature(&batt->temperature);
if (rv)
return rv;
rv = battery_voltage(&batt->voltage);
if (rv)
return rv;
*memmap_batt_volt = batt->voltage;
rv = battery_current(&batt->current);
if (rv)
return rv;
*memmap_batt_rate = batt->current < 0 ? -batt->current : 0;
rv = battery_desired_voltage(&batt->desired_voltage);
if (rv)
return rv;
rv = battery_desired_current(&batt->desired_current);
if (rv)
return rv;
battery_vendor_params(batt);
rv = battery_get_battery_mode(&d);
if (rv)
return rv;
if (d & MODE_CAPACITY) {
/* Battery capacity mode was set to mW, set it back to mAh */
d &= ~MODE_CAPACITY;
rv = battery_set_battery_mode(d);
if (rv)
return rv;
}
rv = battery_remaining_capacity(&d);
if (rv)
return rv;
*memmap_batt_cap = d;
return EC_SUCCESS;
}
@@ -171,8 +205,10 @@ static enum power_state state_charge(void)
if (charger_get_voltage(&chg_voltage))
return PWR_STATE_ERROR;
if (charger_get_current(&chg_current))
return PWR_STATE_ERROR;
/* Check charger reset */
if (chg_voltage == 0 || chg_current == 0)
return PWR_STATE_INIT;
@@ -205,9 +241,18 @@ static enum power_state state_charge(void)
*/
static enum power_state state_discharge(void)
{
struct batt_params batt;
uint8_t *memmap_batt_flags = (uint8_t*)(lpc_get_memmap_range() +
EC_LPC_MEMMAP_BATT_FLAG);
if (get_ac())
return PWR_STATE_INIT;
if (battery_params(&batt))
return PWR_STATE_ERROR;
if (batt.state_of_charge <= BATT_CRITICAL_LEVEL)
*memmap_batt_flags |= EC_BATT_FLAG_LEVEL_CRITICAL;
/* TODO: handle overtemp in discharge mode */
return PWR_STATE_UNCHANGE;
@@ -227,14 +272,19 @@ static enum power_state state_error(void)
int ac = 0;
int bat_v = -1, bat_i = -1, bat_temp = -1;
int desired_v = -1, desired_i = -1;
uint8_t batt_flags = 0;
uint8_t *memmap_batt_flags = (uint8_t*)(lpc_get_memmap_range() +
EC_LPC_MEMMAP_BATT_FLAG);
ac = get_ac();
if (ac) {
batt_flags = EC_BATT_FLAG_AC_PRESENT;
if (charger_set_voltage(0))
error_flags |= (1 << F_CHG_V);
if (charger_set_current(0))
error_flags |= (1 << F_CHG_I);
}
} else
batt_flags = EC_BATT_FLAG_DISCHARGING;
if (battery_voltage(&bat_v))
error_flags |= (1 << F_BAT_V);
@@ -252,6 +302,11 @@ static enum power_state state_error(void)
return PWR_STATE_INIT;
}
/* Check if all battery operation returned success */
if (!(error_flags & (F_BAT_V | F_BAT_I | F_DES_V | F_DES_I | F_BAT_T)))
batt_flags |= EC_BATT_FLAG_BATT_PRESENT;
/* Debug output */
if (error_flags != last_error_flags) {
uart_printf("errors : %02x\n", error_flags);
uart_printf("previous : %02x\n", last_error_flags);
@@ -267,13 +322,15 @@ static enum power_state state_error(void)
uart_puts(" offline\n");
uart_puts("battery\n");
uart_printf(" voltage: %d\n", bat_v);
uart_printf(" current: %d\n", bat_i);
uart_printf(" temp : %d\n", bat_temp);
uart_printf(" des_vol: %d\n", desired_v);
uart_printf(" des_cur: %d\n", desired_i);
uart_printf(" voltage: %5d\n", bat_v);
uart_printf(" current: %5d\n", bat_i);
uart_printf(" temp : %5d\n", (bat_temp - 2731) / 10);
uart_printf(" des_vol: %5d\n", desired_v);
uart_printf(" des_cur: %5d\n", desired_i);
}
*memmap_batt_flags = batt_flags;
return PWR_STATE_UNCHANGE;
}
@@ -304,6 +361,9 @@ void charge_state_machine_task(void)
timestamp_t prev_ts, ts;
int sleep_usec, diff_usec;
enum power_state current_state, new_state;
uint8_t *memmap_batt_flags = (uint8_t*)(lpc_get_memmap_range() +
EC_LPC_MEMMAP_BATT_FLAG);
uint8_t batt_flags;
prev_ts.val = 0;
current_state = PWR_STATE_INIT;
@@ -338,12 +398,27 @@ void charge_state_machine_task(void)
switch (new_state) {
case PWR_STATE_IDLE:
*memmap_batt_flags = EC_BATT_FLAG_AC_PRESENT |
EC_BATT_FLAG_BATT_PRESENT;
sleep_usec = POLL_PERIOD_LONG;
break;
case PWR_STATE_DISCHARGE:
batt_flags = *memmap_batt_flags;
*memmap_batt_flags = EC_BATT_FLAG_AC_PRESENT |
EC_BATT_FLAG_BATT_PRESENT |
EC_BATT_FLAG_DISCHARGING |
(batt_flags & EC_BATT_FLAG_LEVEL_CRITICAL);
sleep_usec = POLL_PERIOD_LONG;
break;
case PWR_STATE_CHARGE:
*memmap_batt_flags = EC_BATT_FLAG_AC_PRESENT |
EC_BATT_FLAG_BATT_PRESENT |
EC_BATT_FLAG_CHARGING;
sleep_usec = POLL_PERIOD_CHARGE;
break;
case PWR_STATE_ERROR:
sleep_usec = POLL_PERIOD_SHORT;
break;
default:
sleep_usec = POLL_PERIOD_SHORT;
}

View File

@@ -39,6 +39,13 @@
#define EC_LPC_MEMMAP_BATT_FLAG 0x2c
#define EC_LPC_MEMMAP_LID 0x30
/* The battery bit flags. */
#define EC_BATT_FLAG_AC_PRESENT 0x01
#define EC_BATT_FLAG_BATT_PRESENT 0x02
#define EC_BATT_FLAG_DISCHARGING 0x04
#define EC_BATT_FLAG_CHARGING 0x08
#define EC_BATT_FLAG_LEVEL_CRITICAL 0x10
/* The offset of temperature value stored in mapped memory.
* This allows reporting a temperature range of
* 200K to 454K = -73C to 181C.