diff -ru /home/rockbox/code_base/rockbox-daily-20030811/apps/lang/english.lang apps/lang/english.lang --- /home/rockbox/code_base/rockbox-daily-20030811/apps/lang/english.lang 2003-08-05 21:00:28.000000000 -0700 +++ apps/lang/english.lang 2003-08-11 17:21:40.000000000 -0700 @@ -1727,3 +1727,8 @@ desc: Asked from onplay screen eng: "Recursively?" new: + +id: LANG_CAR_ADAPTER_MODE +desc: Displayed for setting car adapter mode to on/off +eng: "Car Adapter Mode" +new: diff -ru /home/rockbox/code_base/rockbox-daily-20030811/apps/settings.c apps/settings.c --- /home/rockbox/code_base/rockbox-daily-20030811/apps/settings.c 2003-08-09 21:00:26.000000000 -0700 +++ apps/settings.c 2003-08-11 17:21:40.000000000 -0700 @@ -133,6 +133,8 @@ 0xAC Max number of files in dir (50-10000) 0xAE fade on pause/unpause/stop setting (bit 0) caption backlight (bit 1) + car adapter mode (bit 2) +0xAF [available/unused] 0xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7) 0xB1 peak meter release step size, peak_meter_dbfs (bit 7) 0xB2 peak meter min either in -db or in percent @@ -402,7 +404,8 @@ (global_settings.max_files_in_dir >> 8) & 0xff; config_block[0xae] = (unsigned char) ((global_settings.fade_on_stop & 1) | - ((global_settings.caption_backlight & 1) << 1)); + ((global_settings.caption_backlight & 1) << 1) | + ((global_settings.car_adapter_mode & 1) << 2)); config_block[0xb0] = (unsigned char)global_settings.peak_meter_clip_hold | (global_settings.peak_meter_performance ? 0x80 : 0); config_block[0xb1] = global_settings.peak_meter_release | @@ -540,6 +543,8 @@ global_settings.lang_file); lang_load(buf); } + + set_car_adapter_mode(global_settings.car_adapter_mode); } /* @@ -682,6 +687,7 @@ if (config_block[0xae] != 0xff) { global_settings.fade_on_stop = config_block[0xae] & 1; global_settings.caption_backlight = (config_block[0xae] >> 1) & 1; + global_settings.car_adapter_mode = (config_block[0xae] >> 2) & 1; } if(config_block[0xb0] != 0xff) { @@ -1068,6 +1074,8 @@ else if (!strcasecmp(name, "max files in playlist")) set_cfg_int(&global_settings.max_files_in_playlist, value, 1000, 20000); + else if (!strcasecmp(name, "car adapter mode")) + set_cfg_bool(&global_settings.car_adapter_mode, value); else if (!strcasecmp(name, "recursive directory insert")) { static char* options[] = {"off", "on", "ask"}; set_cfg_option(&global_settings.recursive_dir_insert, value, @@ -1328,6 +1336,12 @@ options[global_settings.poweroff]); } + { + static char* options[] = {"off","on"}; + fprintf(fd, "car adapter mode: %s\r\n", + options[global_settings.car_adapter_mode]); + } + #ifdef HAVE_MAS3587F fprintf(fd, "#\r\n# Recording\r\n#\r\n"); fprintf(fd, "rec quality: %d\r\n", global_settings.rec_quality); @@ -1454,6 +1468,7 @@ global_settings.topruntime = 0; global_settings.fade_on_stop = true; global_settings.caption_backlight = false; + global_settings.car_adapter_mode = false; global_settings.max_files_in_dir = 400; global_settings.max_files_in_playlist = 10000; global_settings.show_icons = true; diff -ru /home/rockbox/code_base/rockbox-daily-20030811/apps/settings.h apps/settings.h --- /home/rockbox/code_base/rockbox-daily-20030811/apps/settings.h 2003-07-15 03:04:20.000000000 -0700 +++ apps/settings.h 2003-08-11 17:21:40.000000000 -0700 @@ -133,6 +133,7 @@ bool peak_meter_performance; /* true: high performance, else save energy*/ int peak_meter_min; /* range minimum */ int peak_meter_max; /* range maximum */ + bool car_adapter_mode; /* 0=off 1=on */ /* show status bar */ bool statusbar; /* 0=hide, 1=show */ diff -ru /home/rockbox/code_base/rockbox-daily-20030811/apps/settings_menu.c apps/settings_menu.c --- /home/rockbox/code_base/rockbox-daily-20030811/apps/settings_menu.c 2003-07-20 21:00:26.000000000 -0700 +++ apps/settings_menu.c 2003-08-11 17:21:40.000000000 -0700 @@ -43,6 +43,19 @@ #endif #include "lang.h" +static bool car_adapter_mode(void) +{ + bool rc; + char* options[] = { str(LANG_OFF), str(LANG_ON) }; + + rc = set_option( str(LANG_CAR_ADAPTER_MODE), + &global_settings.car_adapter_mode, BOOL, + options, 2, + set_car_adapter_mode); + + return rc; +} + static bool contrast(void) { return set_int( str(LANG_CONTRAST), "", &global_settings.contrast, @@ -878,6 +891,7 @@ { str(LANG_TIMEFORMAT), timeformat_set }, #endif { str(LANG_POWEROFF_IDLE), poweroff_idle_timer }, + { str(LANG_CAR_ADAPTER_MODE), car_adapter_mode }, { str(LANG_RESET), reset_settings }, }; diff -ru /home/rockbox/code_base/rockbox-daily-20030811/apps/status.c apps/status.c --- /home/rockbox/code_base/rockbox-daily-20030811/apps/status.c 2003-06-04 21:00:22.000000000 -0700 +++ apps/status.c 2003-08-11 17:21:40.000000000 -0700 @@ -119,6 +119,7 @@ info.shuffle = global_settings.playlist_shuffle; info.keylock = keys_locked; info.repeat = global_settings.repeat_mode; + info.playmode = current_mode; /* only redraw if forced to, or info has changed */ if (force_redraw || diff -ru /home/rockbox/code_base/rockbox-daily-20030811/apps/wps.c apps/wps.c --- /home/rockbox/code_base/rockbox-daily-20030811/apps/wps.c 2003-07-01 21:00:30.000000000 -0700 +++ apps/wps.c 2003-08-11 17:21:40.000000000 -0700 @@ -655,8 +655,10 @@ if (mpeg_status() & MPEG_STATUS_PAUSE) { paused = true; + status_set_playmode(STATUS_PAUSE); } else { paused = false; + status_set_playmode(STATUS_PLAY); } while ( 1 ) @@ -713,6 +715,27 @@ button = button_get_w_tmo(HZ/5); #endif + /* update local pause flag if another thread changed the mpeg status */ + if (paused) { + if (!(mpeg_status() & MPEG_STATUS_PAUSE)) { + paused = false; + status_set_playmode(STATUS_PLAY); + } + } + else { + if (mpeg_status() & MPEG_STATUS_PAUSE) { + paused = true; + status_set_playmode(STATUS_PAUSE); + + if (global_settings.resume) { + settings_save(); +#ifndef HAVE_RTC + ata_flush(); +#endif + } + } + } + /* discard first event if it's a button release */ if (button && ignore_keyup) { diff -ru /home/rockbox/code_base/rockbox-daily-20030811/firmware/export/powermgmt.h firmware/export/powermgmt.h --- /home/rockbox/code_base/rockbox-daily-20030811/firmware/export/powermgmt.h 2003-02-14 21:00:18.000000000 -0800 +++ firmware/export/powermgmt.h 2003-08-11 17:21:40.000000000 -0700 @@ -96,5 +96,6 @@ void set_sleep_timer(int seconds); int get_sleep_timer(void); +void set_car_adapter_mode(int setting); #endif diff -ru /home/rockbox/code_base/rockbox-daily-20030811/firmware/powermgmt.c firmware/powermgmt.c --- /home/rockbox/code_base/rockbox-daily-20030811/firmware/powermgmt.c 2003-06-09 21:00:30.000000000 -0700 +++ firmware/powermgmt.c 2003-08-11 17:21:40.000000000 -0700 @@ -64,11 +64,18 @@ { (void)capacity; } + +void set_car_adapter_mode(int setting) +{ + (void)setting; +} + #else /* not SIMULATOR */ int battery_capacity = 1500; /* only a default value */ int battery_level_cached = -1; /* battery level of this minute, updated once per minute */ +bool car_adapter_mode_enabled = false; static int poweroff_idle_timeout_value[15] = { @@ -341,6 +348,82 @@ } } +void set_car_adapter_mode(int setting) +{ + if (setting == 1) + car_adapter_mode_enabled = true; + else + car_adapter_mode_enabled = false; +} + +static void car_adapter_mode_processing(void) +{ + static bool charger_power_is_on = false; + static bool waiting_to_resume_play = false; + static long play_resume_time; + + if (car_adapter_mode_enabled) { + + if (waiting_to_resume_play) { + if (TIME_AFTER(current_tick, play_resume_time)) { + if (mpeg_status() & MPEG_STATUS_PAUSE) { + mpeg_resume(); + } + waiting_to_resume_play = false; + } + } + else { + if (charger_power_is_on) { + + /* if external power was turned off */ + if (!charger_inserted()) { + + charger_power_is_on = false; + + /* if playing */ + if ((mpeg_status() & MPEG_STATUS_PLAY) && + !(mpeg_status() & MPEG_STATUS_PAUSE)) { + mpeg_pause(); + } + } + } + else { + /* if external power was turned on */ + if (charger_inserted()) { + + charger_power_is_on = true; + + /* if paused */ + if (mpeg_status() & MPEG_STATUS_PAUSE) { + /* delay resume a bit while the engine is cranking */ + play_resume_time = current_tick + HZ*5; + waiting_to_resume_play = true; + } + } + } + } + } +} + +/* + * This function is called to do the relativly long sleep waits from within the + * main power_thread loop while at the same time servicing any other periodic + * functions in the power thread which need to be called at a faster periodic + * rate than the slow periodic rate of the main power_thread loop + */ +static void power_thread_sleep(int ticks) +{ + int small_ticks; + while (ticks > 0) { + small_ticks = MIN(HZ/2, ticks); + sleep(small_ticks); + ticks -= small_ticks; + + car_adapter_mode_processing(); + } +} + + /* * This power thread maintains a history of battery voltage * and implements a charging algorithm. @@ -384,7 +467,7 @@ avg += adc_read(ADC_UNREG_POWER); ok_samples++; } - sleep(HZ*POWER_AVG_SLEEP); + power_thread_sleep(HZ*POWER_AVG_SLEEP); } avg = avg / ((ok_samples) ? ok_samples : spin_samples); @@ -575,7 +658,7 @@ /* charge the calculated amount of seconds */ charger_enable(true); - sleep(HZ * trickle_sec); + power_thread_sleep(HZ * trickle_sec); charger_enable(false); /* trickle charging long enough? */ @@ -681,7 +764,7 @@ i = 60 - POWER_AVG_N * POWER_AVG_SLEEP; #endif if (i > 0) - sleep(HZ*(i)); + power_thread_sleep(HZ*(i)); handle_auto_poweroff(); }