forked from qmk/qmk_firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
165 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#include <avr/io.h> | ||
#include <util/delay.h> | ||
#include "battery.h" | ||
|
||
|
||
/* | ||
* Battery | ||
*/ | ||
void battery_init(void) | ||
{ | ||
// blink | ||
battery_led(LED_ON); _delay_ms(500); | ||
battery_led(LED_OFF); _delay_ms(500); | ||
battery_led(LED_ON); _delay_ms(500); | ||
battery_led(LED_OFF); _delay_ms(500); | ||
// LED indicates charger status | ||
battery_led(LED_CHARGER); | ||
|
||
// ADC setting for voltage monitor | ||
// Ref:2.56V band-gap, Input:ADC0(PF0), Prescale:128(16MHz/128=125KHz) | ||
ADMUX = (1<<REFS1) | (1<<REFS0); | ||
ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); | ||
ADCSRA |= (1<<ADEN); | ||
} | ||
|
||
// Indicator for battery | ||
void battery_led(battery_led_t val) | ||
{ | ||
if (val == LED_TOGGLE) { | ||
// Toggle LED | ||
DDRF |= (1<<5); | ||
PINF |= (1<<5); | ||
} else if (val == LED_ON) { | ||
// On overriding charger status | ||
DDRF |= (1<<5); | ||
PORTF &= ~(1<<5); | ||
} else if (val == LED_OFF) { | ||
// Off overriding charger status | ||
DDRF |= (1<<5); | ||
PORTF |= (1<<5); | ||
} else { | ||
// Display charger status | ||
DDRF &= ~(1<<5); | ||
PORTF &= ~(1<<5); | ||
} | ||
} | ||
|
||
bool battery_charging(void) | ||
{ | ||
if (!(USBSTA&(1<<VBUS))) return false; | ||
|
||
// MCP73831:STAT | ||
// HiZ: Shutdown/No Battery | ||
// Low: Charging | ||
// Hi: Charged | ||
|
||
// preserve last register status | ||
uint8_t ddrf_prev = DDRF; | ||
uint8_t portf_prev = PORTF; | ||
|
||
// Input with pullup | ||
DDRF &= ~(1<<5); | ||
PORTF |= (1<<5); | ||
_delay_ms(1); | ||
bool charging = PINF&(1<<5) ? false : true; | ||
|
||
// restore last register status | ||
DDRF = (DDRF&~(1<<5)) | (ddrf_prev&(1<<5)); | ||
PORTF = (PORTF&~(1<<5)) | (portf_prev&(1<<5)); | ||
|
||
return charging; | ||
} | ||
|
||
// Returns voltage in mV | ||
uint16_t battery_voltage(void) | ||
{ | ||
volatile uint16_t bat; | ||
//ADCSRA |= (1<<ADEN); | ||
|
||
// discard first result | ||
ADCSRA |= (1<<ADSC); | ||
while (ADCSRA & (1<<ADSC)) ; | ||
bat = ADC; | ||
|
||
// discard second result | ||
ADCSRA |= (1<<ADSC); | ||
while (ADCSRA & (1<<ADSC)) ; | ||
bat = ADC; | ||
|
||
ADCSRA |= (1<<ADSC); | ||
while (ADCSRA & (1<<ADSC)) ; | ||
bat = ADC; | ||
|
||
//ADCSRA &= ~(1<<ADEN); | ||
|
||
return (bat - BATTERY_ADC_OFFSET) * BATTERY_ADC_RESOLUTION; | ||
} | ||
|
||
static bool low_voltage(void) { | ||
static bool low = false; | ||
uint16_t v = battery_voltage(); | ||
if (v < BATTERY_VOLTAGE_LOW_LIMIT) { | ||
low = true; | ||
} else if (v > BATTERY_VOLTAGE_LOW_RECOVERY) { | ||
low = false; | ||
} | ||
return low; | ||
} | ||
|
||
battery_status_t battery_status(void) | ||
{ | ||
if (USBSTA&(1<<VBUS)) { | ||
/* powered */ | ||
return battery_charging() ? CHARGING : FULL_CHARGED; | ||
} else { | ||
/* not powered */ | ||
return low_voltage() ? LOW_VOLTAGE : DISCHARGING; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef POWER_H | ||
#define POWER_H | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
typedef enum { | ||
FULL_CHARGED, | ||
CHARGING, | ||
DISCHARGING, | ||
LOW_VOLTAGE, | ||
} battery_status_t; | ||
|
||
typedef enum { | ||
LED_CHARGER = 0, | ||
LED_ON, | ||
LED_OFF, | ||
LED_TOGGLE, | ||
} battery_led_t; | ||
|
||
/* Battery API */ | ||
void battery_init(void); | ||
void battery_led(battery_led_t val); | ||
bool battery_charging(void); | ||
uint16_t battery_voltage(void); | ||
battery_status_t battery_status(void); | ||
|
||
#define BATTERY_VOLTAGE_LOW_LIMIT 3500 | ||
#define BATTERY_VOLTAGE_LOW_RECOVERY 3700 | ||
// ADC offset:16, resolution:5mV | ||
#define BATTERY_ADC_OFFSET 16 | ||
#define BATTERY_ADC_RESOLUTION 5 | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters