From a83ad6de2331909914ea5d6c4bd88e16666c013e Mon Sep 17 00:00:00 2001
From: Przemyslaw Marczak
Date: Fri, 21 Mar 2014 16:15:50 +0100
Subject: [PATCH] samsung: misc: new feature: common interactive charger
This change adds common interactive charger feature with
display support.
New config: CONFIG_INTERACTIVE_CHARGER
New functions:
- battery() - which takes one of commands parameter:
BOOT_CHECK: check battery present, low power mode;
check battery charge level, draw battery screen
STATE: display battery screen with current state of charge
this is for command line use
CHARGE: start interactive charger for every battery charge level
this is also for command line use
- interactive_charger() - loop function for charge the battery and do:
- update of battery screen,
- update charge animation,
- check for exit condition (if charge level >= 20%)
- clear screen after 10 seconds animation
- draw battery on clean screen if any key pressed
There are few constants defined for this feature:
- CHARGE_TRESHOLD_BOOT: 20 (20 percent of charge)
- CHARGE_DISPLAY_TIMEOUT_SEC: 10 (time for animation display)
- CONNECT_CHARGER_TIMEOUT_SEC: 5 (time for connect charger animation)
- CHARGE_PWR_KEY_RESET_TIMEOUT: 3 (time for PWR key press to reset device)
Battery charge level cases:
- 0-20 % - don't allow to boot and then:
- enable charger if connected and start charge animation
or if no charger:
- display 5 sec charger animation and turn off the device
- > 20 % - don't display battery screen and boot device
Charge mode can be break by keys VOLUP + VOLDOWN. If charge level > 20%
then device can be enabled by pressing PWR key for a time defined in
CHARGE_PWR_KEY_RESET_TIMEOUT.
Change-Id: I15066a4b86c89f1f0124b072a0aeb7246b29b279
Signed-off-by: Przemyslaw Marczak
---
board/samsung/common/misc.c | 264 +++++++++++++++++++++++++++++++++++++++++++-
include/samsung/misc.h | 36 +++++-
2 files changed, 294 insertions(+), 6 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c
index 123f89d..86d234d 100644
--- a/board/samsung/common/misc.c
+++ b/board/samsung/common/misc.c
@@ -6,6 +6,7 @@
#include
#include
+#include
#include
#include
#include
@@ -110,7 +111,7 @@ void set_board_info(void)
}
#endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */
-#ifdef CONFIG_LCD_MENU
+#if defined(CONFIG_LCD_MENU) || defined(CONFIG_INTERACTIVE_CHARGER)
static int power_key_pressed(u32 reg)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
@@ -177,7 +178,11 @@ int check_keys(void)
return keys;
}
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_LCD_MENU || CONFIG_INTERACTIVE_CHARGER */
+#ifdef CONFIG_LCD_MENU
+#ifdef CONFIG_LCD
/*
* 0 BOOT_MODE_INFO
* 1 BOOT_MODE_THOR
@@ -421,10 +426,265 @@ static void download_menu(void)
#endif
}
+#ifdef CONFIG_INTERACTIVE_CHARGER
+static int interactive_charger(int command)
+{
+ int display_timeout_ms = 1000 * CHARGE_DISPLAY_TIMEOUT_SEC;
+ int display_time_ms = 0;
+ int animation_step_ms = 500;
+ int no_charger_anim_timeout_ms = NO_CHARGER_ANIM_TIMEOUT_SEC * 1000;
+ int power_key_timeout_ms = CHARGE_PWR_KEY_RESET_TIMEOUT * 1000;
+ int power_key_time_ms = 0;
+ int keys_exit_timeout_ms = CHARGE_KEYS_EXIT_TIMEOUT * 1000;
+ int keys_exit_time_ms = 0;
+ unsigned int soc_boot = CHARGE_TRESHOLD_BOOT;
+ unsigned int soc = 0;
+ int clear_screen = 0;
+ int chrg = 0;
+ int keys;
+ int i;
+
+ /* Enable charger */
+ if (charger_enable()) {
+ puts("Can't enable charger");
+ return CMD_RET_FAILURE;
+ }
+
+ draw_charge_screen();
+
+ /* Clear PWR button Rising edge interrupt status flag */
+ power_key_pressed(KEY_PWR_INTERRUPT_REG);
+
+ puts("Starting interactive charger (Ctrl+C to break).\n");
+ puts("This mode can be also finished by keys: VOLUP + VOLDOWN.\n");
+
+ while (1) {
+ /* Check state of charge */
+ if (battery_state(&soc)) {
+ puts("Fuel Gauge Error\n");
+ lcd_clear();
+ return CMD_RET_FAILURE;
+ }
+
+ if (display_time_ms <= display_timeout_ms) {
+ draw_battery_state(soc);
+ draw_charge_animation();
+
+ mdelay(animation_step_ms);
+ display_time_ms += animation_step_ms;
+ clear_screen = 1;
+ } else {
+ /* Clear screen only once */
+ if (clear_screen) {
+ lcd_clear();
+ clear_screen = 0;
+ }
+
+ /* Check key if lcd is clear */
+ keys = check_keys();
+ if (keys) {
+ display_time_ms = 0;
+ draw_battery_screen();
+ draw_battery_state(soc);
+ draw_charge_screen();
+ printf("Key pressed. Battery SOC: %.2d %%.\n",
+ soc);
+ }
+ }
+
+ /* Check exit conditions */
+ while (check_keys() == CHARGE_KEYS_EXIT) {
+ /* 50 ms delay in check_keys() */
+ keys_exit_time_ms += 50;
+ if (keys_exit_time_ms >= keys_exit_timeout_ms)
+ break;
+ }
+
+ if (ctrlc() || keys_exit_time_ms >= keys_exit_timeout_ms) {
+ puts("Charge mode: aborted by user.\n");
+ lcd_clear();
+ return CMD_RET_SUCCESS;
+ }
+
+ keys_exit_time_ms = 0;
+
+ /* Turn off if no charger */
+ chrg = charger_type();
+ if (!chrg) {
+ puts("Charger disconnected\n");
+ draw_battery_screen();
+ draw_battery_state(soc);
+
+ for (i = 0; i < no_charger_anim_timeout_ms; i += 600) {
+ mdelay(700);
+ draw_connect_charger_animation();
+
+ if (ctrlc())
+ return CMD_RET_SUCCESS;
+
+ chrg = charger_type();
+ if (chrg) {
+ display_time_ms = 0;
+ draw_battery_screen();
+ draw_battery_state(soc);
+ draw_charge_screen();
+ puts("Charger connected\n");
+ break;
+ }
+ }
+
+ if (!chrg) {
+ if (command == CMD_BATTERY_BOOT_CHECK) {
+ puts("Power OFF.");
+ board_poweroff();
+ } else {
+ puts("Please connect charger.\n");
+ return CMD_RET_SUCCESS;
+ }
+ }
+ }
+
+ /* Check boot ability with 5% of reserve */
+ if (soc >= soc_boot) {
+ while (power_key_pressed(KEY_PWR_STATUS_REG)) {
+ mdelay(100);
+ power_key_time_ms += 100;
+ /* Check for pwr key press */
+ if (power_key_time_ms >= power_key_timeout_ms)
+ run_command("reset", 0);
+ }
+ }
+
+ power_key_time_ms = 0;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int battery(int command)
+{
+ unsigned soc;
+ unsigned soc_boot = CHARGE_TRESHOLD_BOOT;
+ int no_charger_timeout = NO_CHARGER_TIMEOUT_SEC;
+ int no_charger_anim_timeout = NO_CHARGER_ANIM_TIMEOUT_SEC;
+ int chrg = 0;
+ int keys = 0;
+ char *pwr_mode_info = "Warning!\n"
+ "Battery charge level was too low and\n"
+ "device is now in LOW POWER mode.\n"
+ "This mode is not recommended for boot system!\n";
+
+ if (!battery_present()) {
+ puts("Battery not present.\n");
+ return CMD_RET_FAILURE;
+ }
+
+ if (battery_state(&soc)) {
+ puts("Fuel Gauge Error\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Battery SOC: %.2d %%.\n", soc);
+
+ switch (command) {
+ case CMD_BATTERY_BOOT_CHECK:
+ /*
+ * If (soc > soc_boot) then don't waste
+ * a time for draw battery screen.
+ */
+ if (soc >= soc_boot)
+ return CMD_RET_SUCCESS;
+
+ /* Set low power mode only if do boot check */
+ board_low_power_mode();
+ puts("Battery SOC (< 20%) is too low for boot.\n");
+ break;
+ case CMD_BATTERY_STATE:
+ lcd_clear();
+ draw_battery_screen();
+ draw_battery_state(soc);
+
+ /* Wait some time before clear battery screen */
+ mdelay(2000);
+ lcd_clear();
+ return CMD_RET_SUCCESS;
+ case CMD_BATTERY_CHARGE:
+ lcd_clear();
+ break;
+ default:
+ return CMD_RET_SUCCESS;
+ }
+
+ draw_battery_screen();
+ draw_battery_state(soc);
+
+ do {
+ /* Check charger */
+ chrg = charger_type();
+ if (chrg) {
+ printf("CHARGER TYPE: %d\n", chrg);
+ draw_battery_screen();
+ draw_battery_state(soc);
+ break;
+ }
+
+ if (no_charger_anim_timeout > 0)
+ draw_connect_charger_animation();
+
+ mdelay(800);
+
+ /* Check exit conditions */
+ keys = check_keys();
+ if (keys) {
+ no_charger_anim_timeout = NO_CHARGER_ANIM_TIMEOUT_SEC;
+ draw_battery_screen();
+ draw_battery_state(soc);
+ }
+
+ if (keys == CHARGE_KEYS_EXIT || ctrlc()) {
+ puts("Charge mode aborted by user.\n");
+ goto warning;
+ }
+
+ no_charger_anim_timeout--;
+ if (!no_charger_anim_timeout)
+ lcd_clear();
+
+ } while (no_charger_timeout--);
+
+ /* there is no charger and soc (%) is too low - POWER OFF */
+ if (!chrg) {
+ puts("No charger connected!\n");
+
+ if (command == CMD_BATTERY_BOOT_CHECK) {
+ puts("Power OFF.");
+ board_poweroff();
+ } else {
+ puts("Please connect charger.\n");
+ return CMD_RET_SUCCESS;
+ }
+ }
+
+ /* Charger connected - enable charge mode */
+ if (interactive_charger(command))
+ printf("Charge failed\n");
+
+warning:
+ /* Charge mode aborted or failed */
+ if (command == CMD_BATTERY_BOOT_CHECK)
+ puts(pwr_mode_info);
+
+ return CMD_RET_SUCCESS;
+}
+#endif
+
void check_boot_mode(void)
{
int pwr_key;
+#ifdef CONFIG_INTERACTIVE_CHARGER
+ battery(CMD_BATTERY_BOOT_CHECK);
+#endif
pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
if (!pwr_key)
return;
@@ -476,6 +736,8 @@ void draw_logo(void)
printf("Warning: image height is bigger than display height\n");
}
+ lcd_clear();
+
bmp_display(addr, x, y);
}
#endif /* CONFIG_CMD_BMP */
diff --git a/include/samsung/misc.h b/include/samsung/misc.h
index 61f7876..1ef9c9f 100644
--- a/include/samsung/misc.h
+++ b/include/samsung/misc.h
@@ -11,6 +11,13 @@ u32 get_board_rev(void);
void set_board_info(void);
#endif
+#if defined(CONFIG_LCD_MENU) || defined(CONFIG_INTERACTIVE_CHARGER)
+void keys_init(void);
+int check_keys(void);
+int key_pressed(int key);
+void check_boot_mode(void);
+#endif /* CONFIG_LCD_MENU || CONFIG_INTERACTIVE_CHARGER */
+
#ifdef CONFIG_LCD_MENU
enum {
BOOT_MODE_INFO,
@@ -21,13 +28,32 @@ enum {
BOOT_MODE_ENV,
BOOT_MODE_EXIT,
};
-
-void keys_init(void);
-int check_keys(void);
-int key_pressed(int key);
-void check_boot_mode(void);
#endif /* CONFIG_LCD_MENU */
+#ifdef CONFIG_INTERACTIVE_CHARGER
+enum {
+ CMD_BATTERY_BOOT_CHECK,
+ CMD_BATTERY_STATE,
+ CMD_BATTERY_CHARGE,
+};
+
+#define CHARGE_TRESHOLD_BOOT 20
+#define CHARGE_DISPLAY_TIMEOUT_SEC 10
+#define NO_CHARGER_ANIM_TIMEOUT_SEC 10
+#define NO_CHARGER_TIMEOUT_SEC 30
+#define CHARGE_PWR_KEY_RESET_TIMEOUT 3
+#define CHARGE_KEYS_EXIT_TIMEOUT 3
+
+#define CHARGE_KEYS_EXIT (KEY_VOLUMEDOWN + KEY_VOLUMEUP)
+
+/* Should be implemented by board */
+int charger_enable(void);
+int charger_type(void);
+int battery_present(void);
+int battery_state(unsigned int *soc);
+void board_low_power_mode(void);
+#endif /* CONFIG_INTERACTIVE_CHARGER */
+
#ifdef CONFIG_CMD_BMP
void draw_logo(void);
#endif
--
2.7.4