summaryrefslogtreecommitdiff
path: root/firmware/powermgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/powermgmt.c')
-rw-r--r--firmware/powermgmt.c89
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
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 }