diff options
-rw-r--r-- | apps/lang/english.lang | 5 | ||||
-rw-r--r-- | apps/settings.c | 14 | ||||
-rw-r--r-- | apps/settings.h | 1 | ||||
-rw-r--r-- | apps/settings_menu.c | 10 | ||||
-rw-r--r-- | apps/status.c | 1 | ||||
-rw-r--r-- | apps/wps.c | 20 | ||||
-rw-r--r-- | firmware/export/powermgmt.h | 1 | ||||
-rw-r--r-- | firmware/powermgmt.c | 89 |
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 | |||
1757 | desc: in main_menu() | 1757 | desc: in main_menu() |
1758 | eng: "Plugins" | 1758 | eng: "Plugins" |
1759 | new: | 1759 | new: |
1760 | |||
1761 | id: LANG_CAR_ADAPTER_MODE | ||
1762 | desc: Displayed for setting car adapter mode to on/off | ||
1763 | eng: "Car Adapter Mode" | ||
1764 | new: | ||
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: | |||
133 | 0xAC Max number of files in dir (50-10000) | 133 | 0xAC Max number of files in dir (50-10000) |
134 | 0xAE fade on pause/unpause/stop setting (bit 0) | 134 | 0xAE fade on pause/unpause/stop setting (bit 0) |
135 | caption backlight (bit 1) | 135 | caption backlight (bit 1) |
136 | car adapter mode (bit 2) | ||
137 | 0xAF [available/unused] | ||
136 | 0xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7) | 138 | 0xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7) |
137 | 0xB1 peak meter release step size, peak_meter_dbfs (bit 7) | 139 | 0xB1 peak meter release step size, peak_meter_dbfs (bit 7) |
138 | 0xB2 peak meter min either in -db or in percent | 140 | 0xB2 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 | ||
47 | static 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 | |||
47 | static bool contrast(void) | 56 | static 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 | ||
97 | void set_sleep_timer(int seconds); | 97 | void set_sleep_timer(int seconds); |
98 | int get_sleep_timer(void); | 98 | int get_sleep_timer(void); |
99 | void 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 | |||
68 | void set_car_adapter_mode(bool setting) | ||
69 | { | ||
70 | (void)setting; | ||
71 | } | ||
72 | |||
67 | #else /* not SIMULATOR */ | 73 | #else /* not SIMULATOR */ |
68 | 74 | ||
69 | int battery_capacity = 1500; /* only a default value */ | 75 | int battery_capacity = 1500; /* only a default value */ |
70 | int battery_level_cached = -1; /* battery level of this minute, updated once | 76 | int battery_level_cached = -1; /* battery level of this minute, updated once |
71 | per minute */ | 77 | per minute */ |
78 | static bool car_adapter_mode_enabled = false; | ||
72 | 79 | ||
73 | static int poweroff_idle_timeout_value[15] = | 80 | static 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 | ||
356 | void set_car_adapter_mode(bool setting) | ||
357 | { | ||
358 | car_adapter_mode_enabled = setting; | ||
359 | } | ||
360 | |||
361 | static 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 | */ | ||
416 | static 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 | } |