summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/lang/english.lang5
-rw-r--r--apps/settings.c14
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_menu.c10
-rw-r--r--apps/status.c1
-rw-r--r--apps/wps.c20
-rw-r--r--firmware/export/powermgmt.h1
-rw-r--r--firmware/powermgmt.c89
8 files changed, 129 insertions, 12 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 3bf3c39fea..813955d3b0 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -1757,3 +1757,8 @@ id: LANG_PLUGINS
1757desc: in main_menu() 1757desc: in main_menu()
1758eng: "Plugins" 1758eng: "Plugins"
1759new: 1759new:
1760
1761id: LANG_CAR_ADAPTER_MODE
1762desc: Displayed for setting car adapter mode to on/off
1763eng: "Car Adapter Mode"
1764new:
diff --git a/apps/settings.c b/apps/settings.c
index e31a2d47d3..9b8f1b35e1 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -133,6 +133,8 @@ Rest of config block, only saved to disk:
1330xAC Max number of files in dir (50-10000) 1330xAC Max number of files in dir (50-10000)
1340xAE fade on pause/unpause/stop setting (bit 0) 1340xAE fade on pause/unpause/stop setting (bit 0)
135 caption backlight (bit 1) 135 caption backlight (bit 1)
136 car adapter mode (bit 2)
1370xAF [available/unused]
1360xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7) 1380xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7)
1370xB1 peak meter release step size, peak_meter_dbfs (bit 7) 1390xB1 peak meter release step size, peak_meter_dbfs (bit 7)
1380xB2 peak meter min either in -db or in percent 1400xB2 peak meter min either in -db or in percent
@@ -402,7 +404,8 @@ int settings_save( void )
402 (global_settings.max_files_in_dir >> 8) & 0xff; 404 (global_settings.max_files_in_dir >> 8) & 0xff;
403 config_block[0xae] = (unsigned char) 405 config_block[0xae] = (unsigned char)
404 ((global_settings.fade_on_stop & 1) | 406 ((global_settings.fade_on_stop & 1) |
405 ((global_settings.caption_backlight & 1) << 1)); 407 ((global_settings.caption_backlight & 1) << 1) |
408 ((global_settings.car_adapter_mode & 1) << 2));
406 config_block[0xb0] = (unsigned char)global_settings.peak_meter_clip_hold | 409 config_block[0xb0] = (unsigned char)global_settings.peak_meter_clip_hold |
407 (global_settings.peak_meter_performance ? 0x80 : 0); 410 (global_settings.peak_meter_performance ? 0x80 : 0);
408 config_block[0xb1] = global_settings.peak_meter_release | 411 config_block[0xb1] = global_settings.peak_meter_release |
@@ -542,6 +545,8 @@ void settings_apply(void)
542 global_settings.lang_file); 545 global_settings.lang_file);
543 lang_load(buf); 546 lang_load(buf);
544 } 547 }
548
549 set_car_adapter_mode(global_settings.car_adapter_mode);
545} 550}
546 551
547/* 552/*
@@ -684,6 +689,7 @@ void settings_load(void)
684 if (config_block[0xae] != 0xff) { 689 if (config_block[0xae] != 0xff) {
685 global_settings.fade_on_stop = config_block[0xae] & 1; 690 global_settings.fade_on_stop = config_block[0xae] & 1;
686 global_settings.caption_backlight = (config_block[0xae] >> 1) & 1; 691 global_settings.caption_backlight = (config_block[0xae] >> 1) & 1;
692 global_settings.car_adapter_mode = (config_block[0xae] >> 2) & 1;
687 } 693 }
688 694
689 if(config_block[0xb0] != 0xff) { 695 if(config_block[0xb0] != 0xff) {
@@ -1070,6 +1076,8 @@ bool settings_load_config(char* file)
1070 else if (!strcasecmp(name, "max files in playlist")) 1076 else if (!strcasecmp(name, "max files in playlist"))
1071 set_cfg_int(&global_settings.max_files_in_playlist, value, 1077 set_cfg_int(&global_settings.max_files_in_playlist, value,
1072 1000, 20000); 1078 1000, 20000);
1079 else if (!strcasecmp(name, "car adapter mode"))
1080 set_cfg_bool(&global_settings.car_adapter_mode, value);
1073 else if (!strcasecmp(name, "recursive directory insert")) { 1081 else if (!strcasecmp(name, "recursive directory insert")) {
1074 static char* options[] = {"off", "on", "ask"}; 1082 static char* options[] = {"off", "on", "ask"};
1075 set_cfg_option(&global_settings.recursive_dir_insert, value, 1083 set_cfg_option(&global_settings.recursive_dir_insert, value,
@@ -1330,6 +1338,9 @@ bool settings_save_config(void)
1330 options[global_settings.poweroff]); 1338 options[global_settings.poweroff]);
1331 } 1339 }
1332 1340
1341 fprintf(fd, "car adapter mode: %s\r\n",
1342 boolopt[global_settings.car_adapter_mode]);
1343
1333#ifdef HAVE_MAS3587F 1344#ifdef HAVE_MAS3587F
1334 fprintf(fd, "#\r\n# Recording\r\n#\r\n"); 1345 fprintf(fd, "#\r\n# Recording\r\n#\r\n");
1335 fprintf(fd, "rec quality: %d\r\n", global_settings.rec_quality); 1346 fprintf(fd, "rec quality: %d\r\n", global_settings.rec_quality);
@@ -1456,6 +1467,7 @@ void settings_reset(void) {
1456 global_settings.topruntime = 0; 1467 global_settings.topruntime = 0;
1457 global_settings.fade_on_stop = true; 1468 global_settings.fade_on_stop = true;
1458 global_settings.caption_backlight = false; 1469 global_settings.caption_backlight = false;
1470 global_settings.car_adapter_mode = false;
1459 global_settings.max_files_in_dir = 400; 1471 global_settings.max_files_in_dir = 400;
1460 global_settings.max_files_in_playlist = 10000; 1472 global_settings.max_files_in_playlist = 10000;
1461 global_settings.show_icons = true; 1473 global_settings.show_icons = true;
diff --git a/apps/settings.h b/apps/settings.h
index c3772ad7ff..635834cac0 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -135,6 +135,7 @@ struct user_settings
135 bool peak_meter_performance; /* true: high performance, else save energy*/ 135 bool peak_meter_performance; /* true: high performance, else save energy*/
136 int peak_meter_min; /* range minimum */ 136 int peak_meter_min; /* range minimum */
137 int peak_meter_max; /* range maximum */ 137 int peak_meter_max; /* range maximum */
138 bool car_adapter_mode; /* 0=off 1=on */
138 139
139 /* show status bar */ 140 /* show status bar */
140 bool statusbar; /* 0=hide, 1=show */ 141 bool statusbar; /* 0=hide, 1=show */
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index f12000c1ef..7af267389a 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -44,6 +44,15 @@
44#endif 44#endif
45#include "lang.h" 45#include "lang.h"
46 46
47static bool car_adapter_mode(void)
48{
49 return set_bool_options( str(LANG_CAR_ADAPTER_MODE),
50 &global_settings.car_adapter_mode,
51 str(LANG_SET_BOOL_YES),
52 str(LANG_SET_BOOL_NO),
53 set_car_adapter_mode);
54}
55
47static bool contrast(void) 56static bool contrast(void)
48{ 57{
49 return set_int( str(LANG_CONTRAST), "", &global_settings.contrast, 58 return set_int( str(LANG_CONTRAST), "", &global_settings.contrast,
@@ -901,6 +910,7 @@ static bool system_settings_menu(void)
901 { str(LANG_TIMEFORMAT), timeformat_set }, 910 { str(LANG_TIMEFORMAT), timeformat_set },
902#endif 911#endif
903 { str(LANG_POWEROFF_IDLE), poweroff_idle_timer }, 912 { str(LANG_POWEROFF_IDLE), poweroff_idle_timer },
913 { str(LANG_CAR_ADAPTER_MODE), car_adapter_mode },
904 { str(LANG_RESET), reset_settings }, 914 { str(LANG_RESET), reset_settings },
905 }; 915 };
906 916
diff --git a/apps/status.c b/apps/status.c
index 6f412d81b1..f0445c3901 100644
--- a/apps/status.c
+++ b/apps/status.c
@@ -119,6 +119,7 @@ void status_draw(bool force_redraw)
119 info.shuffle = global_settings.playlist_shuffle; 119 info.shuffle = global_settings.playlist_shuffle;
120 info.keylock = keys_locked; 120 info.keylock = keys_locked;
121 info.repeat = global_settings.repeat_mode; 121 info.repeat = global_settings.repeat_mode;
122 info.playmode = current_mode;
122 123
123 /* only redraw if forced to, or info has changed */ 124 /* only redraw if forced to, or info has changed */
124 if (force_redraw || 125 if (force_redraw ||
diff --git a/apps/wps.c b/apps/wps.c
index f34ec81d9c..c76d7ade26 100644
--- a/apps/wps.c
+++ b/apps/wps.c
@@ -653,14 +653,22 @@ int wps_show(void)
653 restore = true; 653 restore = true;
654 } 654 }
655 655
656 if (mpeg_status() & MPEG_STATUS_PAUSE) {
657 paused = true;
658 } else {
659 paused = false;
660 }
661
662 while ( 1 ) 656 while ( 1 )
663 { 657 {
658 /* did someone else (i.e power thread) change mpeg pause mode? */
659 if (paused != (mpeg_status() & MPEG_STATUS_PAUSE)) {
660 paused = mpeg_status() & MPEG_STATUS_PAUSE;
661 status_set_playmode(paused ? STATUS_PAUSE : STATUS_PLAY);
662
663 /* if another thread paused mpeg, we are probably in car mode,
664 about to shut down. lets save the settings. */
665 if (paused && global_settings.resume) {
666 settings_save();
667#ifndef HAVE_RTC
668 ata_flush();
669#endif
670 }
671 }
664 672
665#ifdef HAVE_LCD_BITMAP 673#ifdef HAVE_LCD_BITMAP
666 /* when the peak meter is enabled we want to have a 674 /* when the peak meter is enabled we want to have a
diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h
index 4b4d040dcd..f6b1a64b68 100644
--- a/firmware/export/powermgmt.h
+++ b/firmware/export/powermgmt.h
@@ -96,5 +96,6 @@ void set_battery_capacity(int capacity); /* set local battery capacity value */
96 96
97void set_sleep_timer(int seconds); 97void set_sleep_timer(int seconds);
98int get_sleep_timer(void); 98int get_sleep_timer(void);
99void set_car_adapter_mode(bool setting);
99 100
100#endif 101#endif
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 21ccddf301..cca44e01bd 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -64,11 +64,18 @@ void set_battery_capacity(int capacity)
64{ 64{
65 (void)capacity; 65 (void)capacity;
66} 66}
67
68void set_car_adapter_mode(bool setting)
69{
70 (void)setting;
71}
72
67#else /* not SIMULATOR */ 73#else /* not SIMULATOR */
68 74
69int battery_capacity = 1500; /* only a default value */ 75int battery_capacity = 1500; /* only a default value */
70int battery_level_cached = -1; /* battery level of this minute, updated once 76int battery_level_cached = -1; /* battery level of this minute, updated once
71 per minute */ 77 per minute */
78static bool car_adapter_mode_enabled = false;
72 79
73static int poweroff_idle_timeout_value[15] = 80static int poweroff_idle_timeout_value[15] =
74{ 81{
@@ -306,8 +313,8 @@ static void handle_auto_poweroff(void)
306#endif 313#endif
307 !usb_inserted() && 314 !usb_inserted() &&
308 (mpeg_stat == 0 || 315 (mpeg_stat == 0 ||
309 (mpeg_stat == (MPEG_STATUS_PLAY | MPEG_STATUS_PAUSE)) && 316 ((mpeg_stat == (MPEG_STATUS_PLAY | MPEG_STATUS_PAUSE)) &&
310 !sleeptimer_active)) 317 !sleeptimer_active)))
311 { 318 {
312 if(TIME_AFTER(current_tick, last_keypress + timeout) && 319 if(TIME_AFTER(current_tick, last_keypress + timeout) &&
313 TIME_AFTER(current_tick, last_disk_activity + timeout)) 320 TIME_AFTER(current_tick, last_disk_activity + timeout))
@@ -346,6 +353,78 @@ static void handle_auto_poweroff(void)
346 } 353 }
347} 354}
348 355
356void set_car_adapter_mode(bool setting)
357{
358 car_adapter_mode_enabled = setting;
359}
360
361static void car_adapter_mode_processing(void)
362{
363 static bool charger_power_is_on = false;
364 static bool waiting_to_resume_play = false;
365 static long play_resume_time;
366
367 if (car_adapter_mode_enabled) {
368
369 if (waiting_to_resume_play) {
370 if (TIME_AFTER(current_tick, play_resume_time)) {
371 if (mpeg_status() & MPEG_STATUS_PAUSE) {
372 mpeg_resume();
373 }
374 waiting_to_resume_play = false;
375 }
376 }
377 else {
378 if (charger_power_is_on) {
379
380 /* if external power was turned off */
381 if (!charger_inserted()) {
382
383 charger_power_is_on = false;
384
385 /* if playing */
386 if ((mpeg_status() & MPEG_STATUS_PLAY) &&
387 !(mpeg_status() & MPEG_STATUS_PAUSE)) {
388 mpeg_pause();
389 }
390 }
391 }
392 else {
393 /* if external power was turned on */
394 if (charger_inserted()) {
395
396 charger_power_is_on = true;
397
398 /* if paused */
399 if (mpeg_status() & MPEG_STATUS_PAUSE) {
400 /* delay resume a bit while the engine is cranking */
401 play_resume_time = current_tick + HZ*5;
402 waiting_to_resume_play = true;
403 }
404 }
405 }
406 }
407 }
408}
409
410/*
411 * This function is called to do the relativly long sleep waits from within the
412 * main power_thread loop while at the same time servicing any other periodic
413 * functions in the power thread which need to be called at a faster periodic
414 * rate than the slow periodic rate of the main power_thread loop
415 */
416static void power_thread_sleep(int ticks)
417{
418 while (ticks > 0) {
419 int small_ticks = MIN(HZ/2, ticks);
420 sleep(small_ticks);
421 ticks -= small_ticks;
422
423 car_adapter_mode_processing();
424 }
425}
426
427
349/* 428/*
350 * This power thread maintains a history of battery voltage 429 * This power thread maintains a history of battery voltage
351 * and implements a charging algorithm. 430 * and implements a charging algorithm.
@@ -389,7 +468,7 @@ static void power_thread(void)
389 avg += adc_read(ADC_UNREG_POWER); 468 avg += adc_read(ADC_UNREG_POWER);
390 ok_samples++; 469 ok_samples++;
391 } 470 }
392 sleep(HZ*POWER_AVG_SLEEP); 471 power_thread_sleep(HZ*POWER_AVG_SLEEP);
393 } 472 }
394 avg = avg / ((ok_samples) ? ok_samples : spin_samples); 473 avg = avg / ((ok_samples) ? ok_samples : spin_samples);
395 474
@@ -580,7 +659,7 @@ static void power_thread(void)
580 659
581 /* charge the calculated amount of seconds */ 660 /* charge the calculated amount of seconds */
582 charger_enable(true); 661 charger_enable(true);
583 sleep(HZ * trickle_sec); 662 power_thread_sleep(HZ * trickle_sec);
584 charger_enable(false); 663 charger_enable(false);
585 664
586 /* trickle charging long enough? */ 665 /* trickle charging long enough? */
@@ -686,7 +765,7 @@ static void power_thread(void)
686 i = 60 - POWER_AVG_N * POWER_AVG_SLEEP; 765 i = 60 - POWER_AVG_N * POWER_AVG_SLEEP;
687#endif 766#endif
688 if (i > 0) 767 if (i > 0)
689 sleep(HZ*(i)); 768 power_thread_sleep(HZ*(i));
690 769
691 handle_auto_poweroff(); 770 handle_auto_poweroff();
692 } 771 }