2 #include <util/delay.h>
9 void battery_init(void)
12 battery_led(LED_ON
); _delay_ms(500);
13 battery_led(LED_OFF
); _delay_ms(500);
14 battery_led(LED_ON
); _delay_ms(500);
15 battery_led(LED_OFF
); _delay_ms(500);
16 // LED indicates charger status
17 battery_led(LED_CHARGER
);
19 // ADC setting for voltage monitor
20 // Ref:2.56V band-gap, Input:ADC0(PF0), Prescale:128(16MHz/128=125KHz)
21 ADMUX
= (1<<REFS1
) | (1<<REFS0
);
22 ADCSRA
= (1<<ADPS2
) | (1<<ADPS1
) | (1<<ADPS0
);
24 // digital input buffer disable(24.9.5)
25 DIDR0
= (1<<ADC0D
) | (1<<ADC4D
) | (1<<ADC5D
) | (1<<ADC7D
);
27 DIDR2
= (1<<ADC8D
) | (1<<ADC9D
) | (1<<ADC11D
) | (1<<ADC12D
) | (1<<ADC13D
);
29 // ADC disable voltate divider(PF4)
34 // Indicator for battery
35 void battery_led(battery_led_t val
)
37 if (val
== LED_TOGGLE
) {
41 } else if (val
== LED_ON
) {
42 // On overriding charger status
45 } else if (val
== LED_OFF
) {
46 // Off overriding charger status
50 // Display charger status
56 bool battery_charging(void)
58 if (!(USBSTA
&(1<<VBUS
))) return false;
61 // MCP73831 MCP73832 LTC4054 Status
62 // Hi-Z Hi-Z Hi-Z Shutdown/No Battery
63 // Low Low Low Charging
64 // Hi Hi-Z Hi-Z Charged
66 // preserve last register status
67 uint8_t ddrf_prev
= DDRF
;
68 uint8_t portf_prev
= PORTF
;
74 bool charging
= PINF
&(1<<5) ? false : true;
76 // restore last register status
77 DDRF
= (DDRF
&~(1<<5)) | (ddrf_prev
&(1<<5));
78 PORTF
= (PORTF
&~(1<<5)) | (portf_prev
&(1<<5));
80 // TODO: With MCP73831 this can not get stable status when charging.
81 // LED is powered from PSEL line(USB or Lipo)
82 // due to weak low output of STAT pin?
83 // due to pull-up'd via resitor and LED?
87 // Returns voltage in mV
88 uint16_t battery_voltage(void)
90 // ADC disable voltate divider(PF4)
94 volatile uint16_t bat
;
95 //ADCSRA |= (1<<ADEN);
97 // discard first result
99 while (ADCSRA
& (1<<ADSC
)) ;
102 // discard second result
104 while (ADCSRA
& (1<<ADSC
)) ;
108 while (ADCSRA
& (1<<ADSC
)) ;
111 //ADCSRA &= ~(1<<ADEN);
113 // ADC disable voltate divider(PF4)
117 return (bat
- BATTERY_ADC_OFFSET
) * BATTERY_ADC_RESOLUTION
;
120 static bool low_voltage(void) {
121 static bool low
= false;
122 uint16_t v
= battery_voltage();
123 if (v
< BATTERY_VOLTAGE_LOW_LIMIT
) {
125 } else if (v
> BATTERY_VOLTAGE_LOW_RECOVERY
) {
131 battery_status_t
battery_status(void)
133 if (USBSTA
&(1<<VBUS
)) {
135 return battery_charging() ? CHARGING
: FULL_CHARGED
;
138 return low_voltage() ? LOW_VOLTAGE
: DISCHARGING
;