summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/config-iaudiox5.h13
-rw-r--r--firmware/export/config.h1
-rw-r--r--firmware/export/powermgmt.h5
-rw-r--r--firmware/powermgmt.c54
-rw-r--r--firmware/target/coldfire/iaudio/x5/adc-target.h5
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/adc-x5.c48
-rw-r--r--firmware/target/coldfire/iaudio/x5/pcf50606-x5.c4
7 files changed, 84 insertions, 46 deletions
diff --git a/firmware/export/config-iaudiox5.h b/firmware/export/config-iaudiox5.h
index df24850892..3e835605da 100644
--- a/firmware/export/config-iaudiox5.h
+++ b/firmware/export/config-iaudiox5.h
@@ -113,12 +113,13 @@
113#define CPU_FREQ 11289600 113#define CPU_FREQ 11289600
114 114
115/* Type of mobile power */ 115/* Type of mobile power */
116#define CONFIG_BATTERY BATT_LIPOL1300 116#define X5_BATT_CONFIG 2
117#define BATTERY_CAPACITY_MIN 950 /* min. capacity selectable */ 117#define CONFIG_BATTERY BATT_IAUDIO_X5
118#define BATTERY_CAPACITY_MAX 2250 /* max. capacity selectable */ 118#define BATTERY_CAPACITY_MIN 950 /* min. capacity selectable */
119#define BATTERY_CAPACITY_INC 50 /* capacity increment */ 119#define BATTERY_CAPACITY_MAX 2250 /* max. capacity selectable */
120#define BATTERY_TYPES_COUNT 1 /* only one type */ 120#define BATTERY_CAPACITY_INC 50 /* capacity increment */
121#define BATTERY_SCALE_FACTOR 23437 /* FIX: this value is picked at random */ 121#define BATTERY_TYPES_COUNT 1 /* only one type */
122#define BATTERY_SCALE_FACTOR 5859 /* (420703125 + 35900) / 71800 */
122 123
123/* define this if you have a real-time clock */ 124/* define this if you have a real-time clock */
124#define CONFIG_RTC RTC_PCF50606 125#define CONFIG_RTC RTC_PCF50606
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 6f6d253fe9..765bcfdb07 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -70,6 +70,7 @@
70#define BATT_LIION2200 2200 /* FM/V2 recorder type */ 70#define BATT_LIION2200 2200 /* FM/V2 recorder type */
71#define BATT_4AA_NIMH 1500 71#define BATT_4AA_NIMH 1500
72#define BATT_3AAA 1000 /* Ondio */ 72#define BATT_3AAA 1000 /* Ondio */
73#define BATT_IAUDIO_X5 950
73#define BATT_LIPOL1300 1300 /* the type used in iRiver h1x0 models */ 74#define BATT_LIPOL1300 1300 /* the type used in iRiver h1x0 models */
74#define BATT_LPCS355385 1550 /* iriver h10 20Gb - SKC LPCS355385 */ 75#define BATT_LPCS355385 1550 /* iriver h10 20Gb - SKC LPCS355385 */
75#define BATT_BP009 820 /* iriver H10 5/6Gb - iriver BP009 */ 76#define BATT_BP009 820 /* iriver H10 5/6Gb - iriver BP009 */
diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h
index 30fe60c293..ba2cc02318 100644
--- a/firmware/export/powermgmt.h
+++ b/firmware/export/powermgmt.h
@@ -63,7 +63,7 @@ extern int trickle_sec; /* trickle charge: How many seconds per minute
63 63
64#if CONFIG_CHARGING >= CHARGING_MONITOR 64#if CONFIG_CHARGING >= CHARGING_MONITOR
65typedef enum { /* sorted by increasing charging current */ 65typedef enum { /* sorted by increasing charging current */
66 DISCHARGING = 0, 66 DISCHARGING = 0,
67 TRICKLE, /* Can occur for CONFIG_CHARGING >= CHARGING_MONITOR */ 67 TRICKLE, /* Can occur for CONFIG_CHARGING >= CHARGING_MONITOR */
68 TOPOFF, /* Can occur for CONFIG_CHARGING == CHARGING_CONTROL */ 68 TOPOFF, /* Can occur for CONFIG_CHARGING == CHARGING_CONTROL */
69 CHARGING /* Can occur for all CONFIG_CHARGING options */ 69 CHARGING /* Can occur for all CONFIG_CHARGING options */
@@ -126,6 +126,9 @@ int battery_time(void); /* minutes */
126 126
127unsigned int battery_voltage(void); /* filtered batt. voltage in centivolts */ 127unsigned int battery_voltage(void); /* filtered batt. voltage in centivolts */
128 128
129/* read unfiltered battery info */
130void battery_read_info(int *adc, int *voltage, int *level);
131
129/* Tells if the battery level is safe for disk writes */ 132/* Tells if the battery level is safe for disk writes */
130bool battery_level_safe(void); 133bool battery_level_safe(void);
131 134
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 50b734bbbd..f18ea3c636 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -112,6 +112,20 @@ static void battery_status_update(void)
112 } 112 }
113} 113}
114 114
115void battery_read_info(int *adc, int *voltage, int *level)
116{
117 battery_status_update();
118
119 if (adc)
120 *adc = batt_centivolts*10000 / BATTERY_SCALE_FACTOR;
121
122 if (voltage)
123 *voltage = batt_centivolts;
124
125 if (level)
126 *level = batt_level;
127}
128
115unsigned int battery_voltage(void) 129unsigned int battery_voltage(void)
116{ 130{
117 battery_status_update(); 131 battery_status_update();
@@ -167,6 +181,8 @@ static const unsigned int battery_level_dangerous[BATTERY_TYPES_COUNT] =
167 105, 115 /* alkaline, NiHM */ 181 105, 115 /* alkaline, NiHM */
168#elif CONFIG_BATTERY == BATT_LIPOL1300 /* iRiver H1x0 */ 182#elif CONFIG_BATTERY == BATT_LIPOL1300 /* iRiver H1x0 */
169 339 183 339
184#elif CONFIG_BATTERY == BATT_IAUDIO_X5
185 354
170#elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB */ 186#elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB */
171 376 187 376
172#elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB */ 188#elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB */
@@ -192,6 +208,13 @@ static const short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
192 * for the 1300 mAh stock battery. */ 208 * for the 1300 mAh stock battery. */
193// { 337, 358, 365, 369, 372, 377, 383, 389, 397, 406, 413 } 209// { 337, 358, 365, 369, 372, 377, 383, 389, 397, 406, 413 }
194 { 337, 366, 372, 374, 378, 381, 385, 392, 399, 408, 417 } 210 { 337, 366, 372, 374, 378, 381, 385, 392, 399, 408, 417 }
211#elif CONFIG_BATTERY == BATT_IAUDIO_X5
212 /* iAudio x5 series - still experimenting with best curve */
213// Lithium ion discharge curve
214 { 355, 356, 357, 359, 362, 365, 369, 374, 380, 387, 395 }
215// Linear
216// { 355, 360, 364, 369, 373, 378, 382, 387, 391, 390, 400 }
217// { 355, 359, 363, 367, 371, 375, 379, 383, 387, 391, 395 }
195#elif CONFIG_BATTERY == BATT_LPCS355385 218#elif CONFIG_BATTERY == BATT_LPCS355385
196 /* iriver H10 20GB */ 219 /* iriver H10 20GB */
197 { 376, 380, 385, 387, 390, 395, 402, 407, 411, 418, 424 } 220 { 376, 380, 385, 387, 390, 395, 402, 407, 411, 418, 424 }
@@ -289,9 +312,25 @@ static long sleeptimer_endtick;
289 312
290static long last_event_tick; 313static long last_event_tick;
291 314
315static int voltage_to_battery_level(int battery_centivolts);
292static void battery_status_update(void); 316static void battery_status_update(void);
293static int runcurrent(void); 317static int runcurrent(void);
294 318
319void battery_read_info(int *adc, int *voltage, int *level)
320{
321 int adc_battery = adc_read(ADC_UNREG_POWER);
322 int centivolts = adc_battery*BATTERY_SCALE_FACTOR / 10000;
323
324 if (adc)
325 *adc = adc_battery;
326
327 if (voltage)
328 *voltage = centivolts;
329
330 if (level)
331 *level = voltage_to_battery_level(centivolts);
332}
333
295unsigned int battery_voltage(void) 334unsigned int battery_voltage(void)
296{ 335{
297 return battery_centivolts; 336 return battery_centivolts;
@@ -387,14 +426,14 @@ static int voltage_to_percent(int voltage, const short* table)
387 426
388/* update battery level and estimated runtime, called once per minute or 427/* update battery level and estimated runtime, called once per minute or
389 * when battery capacity / type settings are changed */ 428 * when battery capacity / type settings are changed */
390static void battery_status_update(void) 429static int voltage_to_battery_level(int battery_centivolts)
391{ 430{
392 int level; 431 int level;
393 432
394#if CONFIG_CHARGING >= CHARGING_MONITOR 433#if CONFIG_CHARGING >= CHARGING_MONITOR
395 if (charge_state == DISCHARGING) { 434 if (charge_state == DISCHARGING) {
396 level = voltage_to_percent(battery_centivolts, 435 level = voltage_to_percent(battery_centivolts,
397 percent_to_volt_discharge[battery_type]); 436 percent_to_volt_discharge[battery_type]);
398 } 437 }
399 else if (charge_state == CHARGING) { 438 else if (charge_state == CHARGING) {
400 /* battery level is defined to be < 100% until charging is finished */ 439 /* battery level is defined to be < 100% until charging is finished */
@@ -407,9 +446,16 @@ static void battery_status_update(void)
407#else 446#else
408 /* always use the discharge table */ 447 /* always use the discharge table */
409 level = voltage_to_percent(battery_centivolts, 448 level = voltage_to_percent(battery_centivolts,
410 percent_to_volt_discharge[battery_type]); 449 percent_to_volt_discharge[battery_type]);
411#endif 450#endif
412 451
452 return level;
453}
454
455static void battery_status_update(void)
456{
457 int level = voltage_to_battery_level(battery_centivolts);
458
413#ifndef HAVE_MMC /* this adjustment is only needed for HD based */ 459#ifndef HAVE_MMC /* this adjustment is only needed for HD based */
414 if (battery_percent == -1) { /* first run of this procedure */ 460 if (battery_percent == -1) { /* first run of this procedure */
415 /* The battery voltage is usually a little lower directly after 461 /* The battery voltage is usually a little lower directly after
@@ -699,7 +745,6 @@ static void power_thread(void)
699#endif 745#endif
700 746
701 /* initialize the voltages for the exponential filter */ 747 /* initialize the voltages for the exponential filter */
702
703 avgbat = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR * 748 avgbat = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR *
704 BATT_AVE_SAMPLES; 749 BATT_AVE_SAMPLES;
705 battery_centivolts = avgbat / BATT_AVE_SAMPLES / 10000; 750 battery_centivolts = avgbat / BATT_AVE_SAMPLES / 10000;
@@ -1010,7 +1055,6 @@ void powermgmt_init(void)
1010{ 1055{
1011 /* init history to 0 */ 1056 /* init history to 0 */
1012 memset(power_history, 0x00, sizeof(power_history)); 1057 memset(power_history, 0x00, sizeof(power_history));
1013
1014 create_thread(power_thread, power_stack, sizeof(power_stack), 1058 create_thread(power_thread, power_stack, sizeof(power_stack),
1015 power_thread_name IF_PRIO(, PRIORITY_SYSTEM)); 1059 power_thread_name IF_PRIO(, PRIORITY_SYSTEM));
1016} 1060}
diff --git a/firmware/target/coldfire/iaudio/x5/adc-target.h b/firmware/target/coldfire/iaudio/x5/adc-target.h
index 4081562fe5..28ba6225d1 100644
--- a/firmware/target/coldfire/iaudio/x5/adc-target.h
+++ b/firmware/target/coldfire/iaudio/x5/adc-target.h
@@ -28,5 +28,8 @@
28 28
29/* Force a scan now */ 29/* Force a scan now */
30unsigned short adc_scan(int channel); 30unsigned short adc_scan(int channel);
31 31static inline unsigned short adc_read(int channel)
32 { return adc_scan(channel); }
33static inline void adc_init(void)
34 {}
32#endif /* _ADC_TARGET_H_ */ 35#endif /* _ADC_TARGET_H_ */
diff --git a/firmware/target/coldfire/iaudio/x5/adc-x5.c b/firmware/target/coldfire/iaudio/x5/adc-x5.c
index 72aec7d547..1895cacfe9 100755
--- a/firmware/target/coldfire/iaudio/x5/adc-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/adc-x5.c
@@ -24,49 +24,35 @@
24#include "adc.h" 24#include "adc.h"
25#include "pcf50606.h" 25#include "pcf50606.h"
26 26
27static unsigned short adcdata[NUM_ADC_CHANNELS]; 27/* get remaining 2 bits and return 10 bit value */
28 28static int get_10bit_voltage(int msbdata)
29static const int adcc2_parms[] =
30{ 29{
31 [ADC_BUTTONS] = 0x80 | (5 << 1) | 1, /* ADCIN2 */ 30 int data = msbdata << 2;
32 [ADC_REMOTE] = 0x80 | (6 << 1) | 1, /* ADCIN3 */ 31 data |= pcf50606_read(0x31) & 0x3;
33 [ADC_BATTERY] = 0x80 | (0 << 1) | 1, /* BATVOLT, resistive divider */ 32 return data;
34}; 33}
35 34
36unsigned short adc_scan(int channel) 35unsigned short adc_scan(int channel)
37{ 36{
37 static const int adcc2_parms[] =
38 {
39 [ADC_BUTTONS] = 0x81 | (5 << 1), /* 8b - ADCIN2 */
40 [ADC_REMOTE] = 0x81 | (6 << 1), /* 8b - ADCIN3 */
41 [ADC_BATTERY] = 0x01 | (0 << 1), /* 10b - BATVOLT, resistive divider */
42 };
43
38 int level; 44 int level;
39 unsigned char data; 45 int data;
40 46
41 level = set_irq_level(HIGHEST_IRQ_LEVEL); 47 level = set_irq_level(HIGHEST_IRQ_LEVEL);
42 48
43 pcf50606_write(0x2f, adcc2_parms[channel]); 49 pcf50606_write(0x2f, adcc2_parms[channel]);
44 data = pcf50606_read(0x30); 50 data = pcf50606_read(0x30);
45 51
46 adcdata[channel] = data; 52 if (channel == ADC_BATTERY)
53 data = get_10bit_voltage(data);
47 54
48 set_irq_level(level); 55 set_irq_level(level);
49 return data;
50}
51
52unsigned short adc_read(int channel)
53{
54 return adcdata[channel];
55}
56
57static int adc_counter;
58
59static void adc_tick(void)
60{
61 if (++adc_counter == HZ)
62 {
63 adc_counter = 0;
64 adc_scan(ADC_BATTERY);
65 }
66}
67 56
68void adc_init(void) 57 return (unsigned short)data;
69{
70 adc_scan(ADC_BATTERY);
71 tick_add_task(adc_tick);
72} 58}
diff --git a/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c b/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c
index 3443d1e567..59140667ef 100644
--- a/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c
@@ -128,8 +128,8 @@ void GPI0(void)
128 if (data[2] & 0x06) 128 if (data[2] & 0x06)
129 { 129 {
130 /* ACDINS/ACDREM */ 130 /* ACDINS/ACDREM */
131 /* Check if adc_scan should actually scan main buttons or not - 131 /* Check if main buttons should be actually be scanned or not
132 bias towards "yes" out of paranoia. */ 132 - bias towards "yes" out of paranoia. */
133 button_enable_scan((data[2] & 0x02) != 0 || 133 button_enable_scan((data[2] & 0x02) != 0 ||
134 (pcf50606_read(0x33) & 0x01) != 0); 134 (pcf50606_read(0x33) & 0x01) != 0);
135 } 135 }