summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/powermgmt.c57
-rw-r--r--firmware/powermgmt.h16
2 files changed, 70 insertions, 3 deletions
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 602819f443..3f919fa177 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -29,7 +29,19 @@
29#include "power.h" 29#include "power.h"
30#include "powermgmt.h" 30#include "powermgmt.h"
31 31
32#ifndef SIMULATOR 32#ifdef SIMULATOR
33
34int battery_level(void)
35{
36 return 100;
37}
38
39bool battery_level_safe(void)
40{
41 return true;
42}
43
44#else /* not SIMULATOR */
33 45
34static char power_stack[DEFAULT_STACK_SIZE]; 46static char power_stack[DEFAULT_STACK_SIZE];
35static char power_thread_name[] = "power"; 47static char power_thread_name[] = "power";
@@ -40,6 +52,46 @@ char power_message[POWER_MESSAGE_LEN] = "";
40char charge_restart_level = CHARGE_RESTART_HI; 52char charge_restart_level = CHARGE_RESTART_HI;
41#endif 53#endif
42 54
55/* Returns battery level in percent */
56int battery_level(void)
57{
58 int level = 0;
59 int c = 0;
60 int i;
61
62 /* calculate average over last 3 minutes (skip empty samples) */
63 for (i = 0; i < 3; i++)
64 if (power_history[POWER_HISTORY_LEN-1-i]) {
65 level += power_history[POWER_HISTORY_LEN-1-i];
66 c++;
67 }
68
69 if (c)
70 level = level / c; /* avg */
71 else /* history was empty, get a fresh sample */
72 level = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
73
74#ifdef HAVE_CHARGE_CTRL
75 if (charger_enabled)
76 level -= 10; /* the charger raises the voltage 0.05-0.2v */
77#endif
78
79 if(level > BATTERY_LEVEL_FULL)
80 level = BATTERY_LEVEL_FULL;
81
82 if(level < BATTERY_LEVEL_EMPTY)
83 level = BATTERY_LEVEL_EMPTY;
84
85 return ((level-BATTERY_LEVEL_EMPTY) * 100) / BATTERY_RANGE;
86}
87
88/* Tells if the battery level is safe for disk writes */
89bool battery_level_safe(void)
90{
91 /* I'm pretty sure we don't want an average over a long time here */
92 return adc_read(ADC_UNREG_POWER) > (BATTERY_LEVEL_DANGEROUS * 10000) / BATTERY_SCALE_FACTOR;
93}
94
43/* 95/*
44 * This power thread maintains a history of battery voltage 96 * This power thread maintains a history of battery voltage
45 * and should, in the future, enable charging when it's needed 97 * and should, in the future, enable charging when it's needed
@@ -175,4 +227,5 @@ void power_init(void)
175 create_thread(power_thread, power_stack, sizeof(power_stack), power_thread_name); 227 create_thread(power_thread, power_stack, sizeof(power_stack), power_thread_name);
176} 228}
177 229
178#endif 230#endif /* SIMULATOR */
231
diff --git a/firmware/powermgmt.h b/firmware/powermgmt.h
index 751409b803..bfee5bf4a3 100644
--- a/firmware/powermgmt.h
+++ b/firmware/powermgmt.h
@@ -21,6 +21,13 @@
21 21
22#ifndef SIMULATOR 22#ifndef SIMULATOR
23 23
24#define BATTERY_LEVEL_SHUTDOWN 450 /* 4.5V */
25#define BATTERY_LEVEL_EMPTY 465 /* 4.65V */
26#define BATTERY_LEVEL_DANGEROUS 475 /* 4.75V */
27#define BATTERY_LEVEL_FULL 520 /* 5.2V */
28
29#define BATTERY_RANGE (BATTERY_LEVEL_FULL - BATTERY_LEVEL_EMPTY)
30
24#define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */ 31#define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */
25#define POWER_AVG 3 /* how many samples to take for each measurement */ 32#define POWER_AVG 3 /* how many samples to take for each measurement */
26 33
@@ -42,8 +49,15 @@ extern char charge_restart_level;
42 49
43extern unsigned short power_history[POWER_HISTORY_LEN]; 50extern unsigned short power_history[POWER_HISTORY_LEN];
44 51
52/* Start up power management thread */
45void power_init(void); 53void power_init(void);
46 54
47#endif 55#endif /* SIMULATOR */
56
57/* Returns battery level in percent */
58int battery_level(void);
59
60/* Tells if the battery level is safe for disk writes */
61bool battery_level_safe(void);
48 62
49#endif 63#endif