diff options
Diffstat (limited to 'firmware/powermgmt.c')
-rw-r--r-- | firmware/powermgmt.c | 89 |
1 files changed, 84 insertions, 5 deletions
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 | } |