diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/config/sansaconnect.h | 10 | ||||
-rw-r--r-- | firmware/powermgmt.c | 20 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c | 83 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h | 30 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c | 25 |
5 files changed, 153 insertions, 15 deletions
diff --git a/firmware/export/config/sansaconnect.h b/firmware/export/config/sansaconnect.h index 5668d579fc..fa929f3c10 100644 --- a/firmware/export/config/sansaconnect.h +++ b/firmware/export/config/sansaconnect.h | |||
@@ -152,7 +152,15 @@ | |||
152 | #define BATTERY_CAPACITY_INC 100 /* capacity increment */ | 152 | #define BATTERY_CAPACITY_INC 100 /* capacity increment */ |
153 | #define BATTERY_TYPES_COUNT 1 /* only one type */ | 153 | #define BATTERY_TYPES_COUNT 1 /* only one type */ |
154 | 154 | ||
155 | #define CONFIG_BATTERY_MEASURE PERCENTAGE_MEASURE | 155 | /* bq27000 provides voltage, percentage and time measure. |
156 | * Voltage reading is available every 2.56 seconds and does not need filtering. | ||
157 | * Read the measured voltage every 3 seconds so we are guaranteed to not read | ||
158 | * the same value twice (do not try to read every 2.56 seconds as clocks are | ||
159 | * not synchronized). | ||
160 | */ | ||
161 | #define CONFIG_BATTERY_MEASURE (VOLTAGE_MEASURE|PERCENTAGE_MEASURE|TIME_MEASURE) | ||
162 | #define BATT_AVE_SAMPLES 1 | ||
163 | #define POWER_THREAD_STEP_TICKS (3*HZ) | ||
156 | 164 | ||
157 | /* define current usage levels */ | 165 | /* define current usage levels */ |
158 | #if 0 | 166 | #if 0 |
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index a05e0aeb68..51ea99f6fa 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c | |||
@@ -88,16 +88,12 @@ static long last_event_tick = 0; | |||
88 | #if (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE | 88 | #if (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE |
89 | #ifdef SIMULATOR | 89 | #ifdef SIMULATOR |
90 | int _battery_level(void) { return -1; } | 90 | int _battery_level(void) { return -1; } |
91 | int _battery_voltage(void); | ||
92 | extern const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11]; | ||
93 | extern const unsigned short percent_to_volt_charge[11]; | ||
94 | #else | ||
95 | int _battery_voltage(void) { return -1; } | ||
96 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11]; | ||
97 | const unsigned short percent_to_volt_charge[11]; | ||
98 | #endif | 91 | #endif |
99 | #elif (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE | 92 | #else |
100 | int _battery_level(void) { return -1; } | 93 | int _battery_level(void) { return -1; } |
94 | #endif | ||
95 | |||
96 | #if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE | ||
101 | /* | 97 | /* |
102 | * Average battery voltage and charger voltage, filtered via a digital | 98 | * Average battery voltage and charger voltage, filtered via a digital |
103 | * exponential filter (aka. exponential moving average, scaled): | 99 | * exponential filter (aka. exponential moving average, scaled): |
@@ -106,10 +102,8 @@ int _battery_level(void) { return -1; } | |||
106 | static unsigned int avgbat; | 102 | static unsigned int avgbat; |
107 | /* filtered battery voltage, millivolts */ | 103 | /* filtered battery voltage, millivolts */ |
108 | static unsigned int battery_millivolts; | 104 | static unsigned int battery_millivolts; |
109 | #elif (CONFIG_BATTERY_MEASURE == 0) | 105 | #else |
110 | int _battery_voltage(void) { return -1; } | 106 | int _battery_voltage(void) { return -1; } |
111 | int _battery_level(void) { return -1; } | ||
112 | |||
113 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11]; | 107 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11]; |
114 | const unsigned short percent_to_volt_charge[11]; | 108 | const unsigned short percent_to_volt_charge[11]; |
115 | #endif | 109 | #endif |
@@ -156,9 +150,9 @@ void battery_read_info(int *voltage, int *level) | |||
156 | *voltage = millivolts; | 150 | *voltage = millivolts; |
157 | 151 | ||
158 | if (level) { | 152 | if (level) { |
159 | percent = voltage_to_battery_level(millivolts); | 153 | percent = _battery_level(); |
160 | if (percent < 0) | 154 | if (percent < 0) |
161 | percent = _battery_level(); | 155 | percent = voltage_to_battery_level(millivolts); |
162 | *level = percent; | 156 | *level = percent; |
163 | } | 157 | } |
164 | } | 158 | } |
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c index 8ebba3a8d5..ed7dab1572 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c | |||
@@ -104,8 +104,15 @@ | |||
104 | #define SYS_CTRL_EN_TS_THERM 0x06 | 104 | #define SYS_CTRL_EN_TS_THERM 0x06 |
105 | #define SYS_CTRL_FRESET 0x80 | 105 | #define SYS_CTRL_FRESET 0x80 |
106 | 106 | ||
107 | /* HDQ status codes */ | ||
108 | #define HDQ_STATUS_OK 0x00 | ||
109 | #define HDQ_STATUS_NOT_READY 0x01 | ||
110 | #define HDQ_STATUS_TIMEOUT 0x02 | ||
111 | |||
107 | /* protects spi avr commands from concurrent access */ | 112 | /* protects spi avr commands from concurrent access */ |
108 | static struct mutex avr_mtx; | 113 | static struct mutex avr_mtx; |
114 | /* serializes hdq read/write and status retrieval */ | ||
115 | static struct mutex hdq_mtx; | ||
109 | 116 | ||
110 | /* AVR thread events */ | 117 | /* AVR thread events */ |
111 | #define INPUT_INTERRUPT 1 | 118 | #define INPUT_INTERRUPT 1 |
@@ -498,6 +505,7 @@ void avr_hid_init(void) | |||
498 | IO_SERIAL1_MODE = 0x6DB; | 505 | IO_SERIAL1_MODE = 0x6DB; |
499 | 506 | ||
500 | mutex_init(&avr_mtx); | 507 | mutex_init(&avr_mtx); |
508 | mutex_init(&hdq_mtx); | ||
501 | } | 509 | } |
502 | 510 | ||
503 | int _battery_level(void) | 511 | int _battery_level(void) |
@@ -510,6 +518,17 @@ int _battery_level(void) | |||
510 | return avr_battery_level & BATTERY_LEVEL_PERCENTAGE_MASK; | 518 | return avr_battery_level & BATTERY_LEVEL_PERCENTAGE_MASK; |
511 | } | 519 | } |
512 | 520 | ||
521 | int _battery_voltage(void) | ||
522 | { | ||
523 | return avr_hid_hdq_read_short(HDQ_REG_VOLT); | ||
524 | } | ||
525 | |||
526 | int _battery_time(void) | ||
527 | { | ||
528 | /* HDQ_REG_TTE reads as 65535 when charging */ | ||
529 | return avr_hid_hdq_read_short(HDQ_REG_TTE); | ||
530 | } | ||
531 | |||
513 | unsigned int power_input_status(void) | 532 | unsigned int power_input_status(void) |
514 | { | 533 | { |
515 | if (avr_battery_status & BATTERY_STATUS_CHARGER_CONNECTED) | 534 | if (avr_battery_status & BATTERY_STATUS_CHARGER_CONNECTED) |
@@ -524,6 +543,70 @@ bool charging_state(void) | |||
524 | return (avr_battery_status & BATTERY_STATUS_CHARGING) != 0; | 543 | return (avr_battery_status & BATTERY_STATUS_CHARGING) != 0; |
525 | } | 544 | } |
526 | 545 | ||
546 | static int avr_hid_hdq_read_byte_internal(uint8_t address) | ||
547 | { | ||
548 | uint8_t result[2]; | ||
549 | |||
550 | if (!avr_execute_command(CMD_HDQ_READ, &address, sizeof(address))) | ||
551 | { | ||
552 | return -1; | ||
553 | } | ||
554 | |||
555 | do | ||
556 | { | ||
557 | mdelay(10); | ||
558 | if (!avr_execute_command(CMD_HDQ_STATUS, result, sizeof(result))) | ||
559 | { | ||
560 | return -1; | ||
561 | } | ||
562 | } | ||
563 | while (result[0] == HDQ_STATUS_NOT_READY); | ||
564 | |||
565 | if (result[0] != HDQ_STATUS_OK) | ||
566 | { | ||
567 | logf("HDQ read %d status %d", address, result[0]); | ||
568 | return -1; | ||
569 | } | ||
570 | |||
571 | return result[1]; | ||
572 | } | ||
573 | |||
574 | int avr_hid_hdq_read_byte(uint8_t address) | ||
575 | { | ||
576 | int retry; | ||
577 | int value = -1; | ||
578 | for (retry = 0; (retry < 3) && (value < 0); retry++) | ||
579 | { | ||
580 | mutex_lock(&hdq_mtx); | ||
581 | value = avr_hid_hdq_read_byte_internal(address); | ||
582 | mutex_unlock(&hdq_mtx); | ||
583 | } | ||
584 | return value; | ||
585 | } | ||
586 | |||
587 | int avr_hid_hdq_read_short(uint8_t address) | ||
588 | { | ||
589 | int old_hi = -1, old_lo = -1, hi = -2, lo = -2; | ||
590 | /* Keep reading until we read the same value twice. | ||
591 | * There's no atomic 16-bit value retrieval, so keep reading | ||
592 | * until we read the same value twice. HDQ registers update | ||
593 | * no more than once per 2.56 seconds so usually there will | ||
594 | * be 4 reads and sometimes 6 reads. | ||
595 | */ | ||
596 | while ((old_hi != hi) || (old_lo != lo)) | ||
597 | { | ||
598 | old_hi = hi; | ||
599 | old_lo = lo; | ||
600 | hi = avr_hid_hdq_read_byte(address + 1); | ||
601 | lo = avr_hid_hdq_read_byte(address); | ||
602 | } | ||
603 | if ((hi < 0) || (lo < 0)) | ||
604 | { | ||
605 | return -1; | ||
606 | } | ||
607 | return (hi << 8) | lo; | ||
608 | } | ||
609 | |||
527 | static void avr_hid_enable_wheel(void) | 610 | static void avr_hid_enable_wheel(void) |
528 | { | 611 | { |
529 | uint8_t enable = 0x01; | 612 | uint8_t enable = 0x01; |
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h index baa7083760..ed23e84936 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h +++ b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.h | |||
@@ -24,8 +24,38 @@ | |||
24 | 24 | ||
25 | #include "config.h" | 25 | #include "config.h" |
26 | 26 | ||
27 | /* HDQ (bq27000) RAM registers */ | ||
28 | #define HDQ_REG_CTRL 0x00 | ||
29 | #define HDQ_REG_MODE 0x01 | ||
30 | #define HDQ_REG_AR 0x02 | ||
31 | #define HDQ_REG_ARTTE 0x04 | ||
32 | #define HDQ_REG_TEMP 0x06 | ||
33 | #define HDQ_REG_VOLT 0x08 | ||
34 | #define HDQ_REG_FLAGS 0x0A | ||
35 | #define HDQ_REG_RSOC 0x0B | ||
36 | #define HDQ_REG_NAC 0x0C | ||
37 | #define HDQ_REG_CACD 0x0E | ||
38 | #define HDQ_REG_CACT 0x10 | ||
39 | #define HDQ_REG_LMD 0x12 | ||
40 | #define HDQ_REG_AI 0x14 | ||
41 | #define HDQ_REG_TTE 0x16 | ||
42 | #define HDQ_REG_TTF 0x18 | ||
43 | #define HDQ_REG_SI 0x1A | ||
44 | #define HDQ_REG_STTE 0x1C | ||
45 | #define HDQ_REG_MLI 0x1E | ||
46 | #define HDQ_REG_MLTTE 0x20 | ||
47 | #define HDQ_REG_SAE 0x22 | ||
48 | #define HDQ_REG_AP 0x24 | ||
49 | #define HDQ_REG_TTECP 0x26 | ||
50 | #define HDQ_REG_CYCL 0x28 | ||
51 | #define HDQ_REG_CYCT 0x2A | ||
52 | #define HDQ_REG_CSOC 0x2C | ||
53 | |||
27 | void avr_hid_init(void); | 54 | void avr_hid_init(void); |
28 | 55 | ||
56 | int avr_hid_hdq_read_byte(uint8_t address); | ||
57 | int avr_hid_hdq_read_short(uint8_t address); | ||
58 | |||
29 | void avr_hid_enable_charger(void); | 59 | void avr_hid_enable_charger(void); |
30 | 60 | ||
31 | void avr_hid_wifi_pd(int high); | 61 | void avr_hid_wifi_pd(int high); |
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c index ccd91c6d2f..597fb6b7e0 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/power-sansaconnect.c | |||
@@ -31,6 +31,29 @@ | |||
31 | #include "i2c-dm320.h" | 31 | #include "i2c-dm320.h" |
32 | #include "logf.h" | 32 | #include "logf.h" |
33 | 33 | ||
34 | |||
35 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
36 | { | ||
37 | 3450 | ||
38 | }; | ||
39 | |||
40 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
41 | { | ||
42 | 3400 | ||
43 | }; | ||
44 | |||
45 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
46 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
47 | { | ||
48 | { 3400, 3508, 3630, 3703, 3727, 3750, 3803, 3870, 3941, 4026, 4142 } | ||
49 | }; | ||
50 | |||
51 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
52 | const unsigned short percent_to_volt_charge[11] = | ||
53 | { | ||
54 | 3540, 3788, 3860, 3890, 3916, 3956, 4016, 4085, 4164, 4180, 4190 | ||
55 | }; | ||
56 | |||
34 | /* (7-bit) address is 0x48, the LSB is read/write flag */ | 57 | /* (7-bit) address is 0x48, the LSB is read/write flag */ |
35 | #define TPS65021_ADDR (0x48 << 1) | 58 | #define TPS65021_ADDR (0x48 << 1) |
36 | 59 | ||
@@ -54,7 +77,7 @@ void power_init(void) | |||
54 | 77 | ||
55 | /* PWM mode */ | 78 | /* PWM mode */ |
56 | tps65021_write_reg(0x04, 0xB2); | 79 | tps65021_write_reg(0x04, 0xB2); |
57 | 80 | ||
58 | /* Set core voltage to 1.5V */ | 81 | /* Set core voltage to 1.5V */ |
59 | tps65021_write_reg(0x06, 0x1C); | 82 | tps65021_write_reg(0x06, 0x1C); |
60 | 83 | ||