From: Przemyslaw Marczak Date: Fri, 21 Mar 2014 15:15:50 +0000 (+0100) Subject: samsung: misc: new feature: common interactive charger X-Git-Tag: accepted/tizen/unified/20191107.062134~238 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a83ad6de2331909914ea5d6c4bd88e16666c013e;p=platform%2Fkernel%2Fu-boot.git 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 --- 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