diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-05-25 01:38:08 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-05-25 01:38:08 +0000 |
commit | d892214d88ed00344516a9b2f1a127c033d4618f (patch) | |
tree | 6558e0e53d770a5984f7b775945a09ff948c1c7d | |
parent | 11a667b6ca68e9e9e1025319cd5bdffd02e3a841 (diff) | |
download | rockbox-d892214d88ed00344516a9b2f1a127c033d4618f.tar.gz rockbox-d892214d88ed00344516a9b2f1a127c033d4618f.zip |
Gigabeat S: Add charge current and battery temp readout in power management and display in the battery screen. Thermistor data was obtained experimentally from one pulled off a dead board and appears basically correct when read back on a working device (which requires letting it settle to ambient temperature - a long wait so not easy to do). Sending me more thermistors would help improve accuracy *fingers crossed that it's close enough*. :-) This commit does NOT add charging but is a step towards implementing it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17626 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/debug_menu.c | 14 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/adc-target.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c | 67 |
3 files changed, 82 insertions, 1 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 313a2aacac..22b1777a68 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -18,6 +18,7 @@ | |||
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | #include "config.h" | 20 | #include "config.h" |
21 | #include <stdlib.h> | ||
21 | #include <stdio.h> | 22 | #include <stdio.h> |
22 | #include <stdbool.h> | 23 | #include <stdbool.h> |
23 | #include <string.h> | 24 | #include <string.h> |
@@ -1649,7 +1650,18 @@ static bool view_battery(void) | |||
1649 | snprintf(buf, 30, "Charger: %s", | 1650 | snprintf(buf, 30, "Charger: %s", |
1650 | charger_inserted() ? "present" : "absent"); | 1651 | charger_inserted() ? "present" : "absent"); |
1651 | lcd_puts(0, 3, buf); | 1652 | lcd_puts(0, 3, buf); |
1652 | #endif | 1653 | #if defined TOSHIBA_GIGABEAT_S |
1654 | y = battery_adc_charge_current(); | ||
1655 | x = y < 0 ? '-' : ' '; | ||
1656 | y = abs(y); | ||
1657 | snprintf(buf, 30, "I Charge:%c%d.%03d A", (char)x, y / 1000, y % 1000); | ||
1658 | lcd_puts(0, 4, buf); | ||
1659 | |||
1660 | y = battery_adc_temp(); | ||
1661 | snprintf(buf, 30, "T Battery: %dC (%dF)", y, (9*y + 160) / 5); | ||
1662 | lcd_puts(0, 5, buf); | ||
1663 | #endif /* defined TOSHIBA_GIGABEAT_S */ | ||
1664 | #endif /* defined IPOD_NANO || defined IPOD_VIDEO */ | ||
1653 | #endif /* CONFIG_CHARGING != CHARGING_CONTROL */ | 1665 | #endif /* CONFIG_CHARGING != CHARGING_CONTROL */ |
1654 | #endif /* CONFIG_CHARGING */ | 1666 | #endif /* CONFIG_CHARGING */ |
1655 | break; | 1667 | break; |
diff --git a/firmware/target/arm/imx31/gigabeat-s/adc-target.h b/firmware/target/arm/imx31/gigabeat-s/adc-target.h index 0b74ad84eb..d5f60de3db 100644 --- a/firmware/target/arm/imx31/gigabeat-s/adc-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/adc-target.h | |||
@@ -45,5 +45,7 @@ | |||
45 | #define ADC_READ_ERROR 0xFFFF | 45 | #define ADC_READ_ERROR 0xFFFF |
46 | 46 | ||
47 | void adc_done(void); | 47 | void adc_done(void); |
48 | int battery_adc_charge_current(void); | ||
49 | unsigned int battery_adc_temp(void); | ||
48 | 50 | ||
49 | #endif | 51 | #endif |
diff --git a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c index 53996f8cd7..711bc0dc58 100644 --- a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c | |||
@@ -24,6 +24,37 @@ | |||
24 | #include "adc.h" | 24 | #include "adc.h" |
25 | #include "powermgmt.h" | 25 | #include "powermgmt.h" |
26 | 26 | ||
27 | /** | ||
28 | * Fixed-point natural log | ||
29 | * taken from http://www.quinapalus.com/efunc.html | ||
30 | * "The code assumes integers are at least 32 bits long. The (positive) | ||
31 | * argument and the result of the function are both expressed as fixed-point | ||
32 | * values with 16 fractional bits, although intermediates are kept with 28 | ||
33 | * bits of precision to avoid loss of accuracy during shifts." | ||
34 | */ | ||
35 | static long flog(int x) | ||
36 | { | ||
37 | long t,y; | ||
38 | |||
39 | y=0xa65af; | ||
40 | if(x<0x00008000) x<<=16, y-=0xb1721; | ||
41 | if(x<0x00800000) x<<= 8, y-=0x58b91; | ||
42 | if(x<0x08000000) x<<= 4, y-=0x2c5c8; | ||
43 | if(x<0x20000000) x<<= 2, y-=0x162e4; | ||
44 | if(x<0x40000000) x<<= 1, y-=0x0b172; | ||
45 | t=x+(x>>1); if((t&0x80000000)==0) x=t,y-=0x067cd; | ||
46 | t=x+(x>>2); if((t&0x80000000)==0) x=t,y-=0x03920; | ||
47 | t=x+(x>>3); if((t&0x80000000)==0) x=t,y-=0x01e27; | ||
48 | t=x+(x>>4); if((t&0x80000000)==0) x=t,y-=0x00f85; | ||
49 | t=x+(x>>5); if((t&0x80000000)==0) x=t,y-=0x007e1; | ||
50 | t=x+(x>>6); if((t&0x80000000)==0) x=t,y-=0x003f8; | ||
51 | t=x+(x>>7); if((t&0x80000000)==0) x=t,y-=0x001fe; | ||
52 | x=0x80000000-x; | ||
53 | y-=x>>15; | ||
54 | return y; | ||
55 | } | ||
56 | |||
57 | |||
27 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | 58 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = |
28 | { | 59 | { |
29 | 3450 | 60 | 3450 |
@@ -55,3 +86,39 @@ unsigned int battery_adc_voltage(void) | |||
55 | return ((adc_read(ADC_BATTERY) * 2303) >> 10) + 2400; | 86 | return ((adc_read(ADC_BATTERY) * 2303) >> 10) + 2400; |
56 | } | 87 | } |
57 | 88 | ||
89 | /* Returns battery charge current from ADC [milliamps] */ | ||
90 | int battery_adc_charge_current(void) | ||
91 | { | ||
92 | /* Positive reading = charger to battery | ||
93 | * Negative reading = battery to charger terminal | ||
94 | * ADC reading -512-511 = -2875mA-2875mA */ | ||
95 | unsigned int value = adc_read(ADC_CHARGER_CURRENT); | ||
96 | return (((int)value << 22) >> 22) * 2881 >> 9; | ||
97 | } | ||
98 | |||
99 | /* Returns battery temperature from ADC [deg-C] */ | ||
100 | unsigned int battery_adc_temp(void) | ||
101 | { | ||
102 | unsigned int value = adc_read(ADC_BATTERY_TEMP); | ||
103 | /* E[volts] = value * 2.3V / 1023 | ||
104 | * R[ohms] = E/I = E[volts] / 0.00002[A] (Thermistor bias current source) | ||
105 | * | ||
106 | * Steinhart-Hart thermistor equation (sans "C*ln^2(R)" term because it | ||
107 | * has negligible effect): | ||
108 | * [A + B*ln(R) + D*ln^3(R)] - 273.15 = 1 / T[°K] | ||
109 | * | ||
110 | * Coeffients that fit experimental data (one thermistor so far, one run): | ||
111 | * A = 0.0013002631685462800 | ||
112 | * B = 0.0002000841932612330 | ||
113 | * D = 0.0000000640446750919 | ||
114 | * | ||
115 | * Fixed-point output matches the floating-point version for each ADC | ||
116 | * value. | ||
117 | */ | ||
118 | int R = 2070000 * value; | ||
119 | long long ln = flog(R) + 83196; | ||
120 | long long t0 = 425890304133ll; | ||
121 | long long t1 = 1000000*ln; | ||
122 | long long t3 = ln*ln*ln / 13418057; | ||
123 | return ((32754211579494400ll / (t0 + t1 + t3)) - 27315) / 100; | ||
124 | } | ||