Add checkBatteryState functions

Added _checkBatteryState()_ and _checkBatteryStateLED()_ functions
This commit is contained in:
Mr.Blinky 2018-11-24 15:46:27 +01:00 committed by GitHub
parent 974f5298ee
commit 97dbd076f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 156 additions and 0 deletions

View File

@ -32,6 +32,8 @@ bootLogoSpritesOverwrite KEYWORD2
bootLogoSpritesSelfMasked KEYWORD2 bootLogoSpritesSelfMasked KEYWORD2
bootLogoText KEYWORD2 bootLogoText KEYWORD2
buttonsState KEYWORD2 buttonsState KEYWORD2
checkBatteryState KEYWORD2
checkBatteryStateLED KEYWORD2
clear KEYWORD2 clear KEYWORD2
collide KEYWORD2 collide KEYWORD2
cpuLoad KEYWORD2 cpuLoad KEYWORD2
@ -165,3 +167,7 @@ RGB_ON LITERAL1
ARDUBOY_NO_USB LITERAL1 ARDUBOY_NO_USB LITERAL1
BATTERY_STATE_LOW LITERAL1
BATTERY_STATE_NORMAL LITERAL1
BATTERY_STATE_INVALID LITERAL1
FLASH_LED LITERAL1

View File

@ -32,6 +32,8 @@ Point::Point(int16_t x, int16_t y)
uint8_t Arduboy2Base::sBuffer[]; uint8_t Arduboy2Base::sBuffer[];
uint8_t Arduboy2Base::batteryLow = EEPROM.read(EEPROM_BATTERY_LOW); //Low battery bandgap value - 192
Arduboy2Base::Arduboy2Base() Arduboy2Base::Arduboy2Base()
{ {
currentButtonState = 0; currentButtonState = 0;
@ -1176,6 +1178,92 @@ void Arduboy2Base::swap(int16_t& a, int16_t& b)
b = temp; b = temp;
} }
uint8_t Arduboy2Base::checkBatteryState()
{
uint8_t state = BATTERY_STATE_INVALID;
asm volatile (
" ldi r30, lo8(%[prr0]) \n" // if (bit_is_set(PRR0,PRADC)) //ADC power off
" ldi r31, hi8(%[prr0]) \n" // {
" ld r24, z \n"
" lds r25, %[adcsra] \n"
" sbrs r24, %[pradc] \n"
" rjmp 1f \n"
" \n"
" andi r24, ~(1<<%[pradc]) \n" // PRR0 &= ~_BV(PRADC); // ADC power on
" st z, r24 \n"
" ldi r24, %[admuxval] \n" // ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1)
" sts %[admux], r24 \n"
" ori r25, 1<<%[adsc] \n" // ADCSRA |= _BV(ADSC) //start conversion
" sts %[adcsra], r25 \n" // }
" ;rjmp 2f \n" // bit is set so continue below to jump to 2f
"1: \n"
" sbrc r25, %[adsc] \n" // else if (!(ADCSRA & _BV(ADSC)) //ADC conversion ready
" rjmp 2f \n" // {
" \n"
" ori r24, 1<<%[pradc] \n" // PRR0 |= _BV(PRADC); // ADC power off
" st z, r24 \n"
" ldi r30, %[adcl] \n" // uint16_t bandgap = ADCL | (ADCH << 8);
" ld r24, z+ \n"
" ld r25, z \n"
" subi r24, 192 \n" // bandgap -= 192;
" sbci r25, 0 \n"
" and r25, r25 \n" // if (bandgap < 256)
" brne 2f \n" // {
" \n"
" ldi %[state],%[normal] \n" // state = BATTERY_STATE_NORMAL;
" lds r25, %[battlow] \n"
" cp r25, r24 \n"
" brcc 2f \n" // if (batteryLow < bandgap) state = BATTERY_STATE_LOW;
" ldi %[state],%[low] \n" // }
"2: \n" // }
:[state] "+d"(state)
:[prr0] "M" (_SFR_MEM_ADDR(PRR0)),
[adcsra] "M" (_SFR_MEM_ADDR(ADCSRA)),
[pradc] "I" (PRADC),
[admuxval] "M" (_BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1)),
[admux] "M" (_SFR_MEM_ADDR(ADMUX)),
[adsc] "I" (ADSC),
[adcl] "M" (_SFR_MEM_ADDR(ADCL)),
[battlow] "" (&batteryLow),
[normal] "I" (BATTERY_STATE_NORMAL),
[low] "I" (BATTERY_STATE_LOW)
: "r24", "r25", "r30", "r31"
);
return state;
}
#if 0
// For reference, this is the C++ equivalent
uint8_t Arduboy2Base::checkBatteryState();
{
uint8_t state = BATTERY_STATE_UNDEFINED;
if (bit_is_set(PRR0,PRADC)) //only enable when ADC power is disabled
{
PRR0 &= ~_BV(PRADC); // ADC power on
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); //meassure 1.1V bandgap against AVcc
ADCSRA |= _BV(ADSC); //start conversion
}
else if (!(ADCSRA & _BV(ADSC)))
{
PRR0 |= _BV(PRADC); // ADC power off
uint16_t bandgap = ADCL | (ADCH << 8);
bandgap -= 192;
if (bandgap < 256)
{
state = BATTERY_STATE_NORMAL;
if (batteryLow < (uint8_t)bandgap) state = BATTERY_STATE_LOW;
}
}
return state;
}
#endif
uint8_t Arduboy2Base::checkBatteryStateLED(bool flash)
{
uint8_t state = checkBatteryState();
if (state == BATTERY_STATE_NORMAL | flash) TXLED0;
if (state == BATTERY_STATE_LOW) TXLED1;
return state;
}
//==================================== //====================================
//========== class Arduboy2 ========== //========== class Arduboy2 ==========

View File

@ -41,6 +41,8 @@
#define EEPROM_VERSION 0 #define EEPROM_VERSION 0
#define EEPROM_SYS_FLAGS 1 #define EEPROM_SYS_FLAGS 1
#define EEPROM_AUDIO_ON_OFF 2 #define EEPROM_AUDIO_ON_OFF 2
#define EEPROM_BANDGAP_CAL 6 //Bandgap calibration value
#define EEPROM_BATTERY_LOW 7 //Battery low threshold
#define EEPROM_UNIT_ID 8 // A uint16_t binary unit ID #define EEPROM_UNIT_ID 8 // A uint16_t binary unit ID
#define EEPROM_UNIT_NAME 10 // An up to 6 character unit name. Cannot contain #define EEPROM_UNIT_NAME 10 // An up to 6 character unit name. Cannot contain
// 0x00 or 0xFF. Lengths less than 6 are padded // 0x00 or 0xFF. Lengths less than 6 are padded
@ -87,6 +89,10 @@
#define CLEAR_BUFFER true /**< Value to be passed to `display()` to clear the screen buffer. */ #define CLEAR_BUFFER true /**< Value to be passed to `display()` to clear the screen buffer. */
#define BATTERY_STATE_LOW 0
#define BATTERY_STATE_NORMAL 1
#define BATTERY_STATE_INVALID 0xFF
#define FLASH_LED true
//============================================= //=============================================
//========== Rect (rectangle) object ========== //========== Rect (rectangle) object ==========
@ -1260,6 +1266,60 @@ class Arduboy2Base : public Arduboy2Core
*/ */
void writeShowBootLogoLEDsFlag(bool val); void writeShowBootLogoLEDsFlag(bool val);
/** \brief
* Returns the battery state.
* \details
* This function is intended as a method to determine a low battery state
*
* Returns the following states:
* - BATTERY_STATE_LOW The battery low threshold has been reached.
* - BATTERY_STATE_NORMAL The battery is considered normal.
* - BATTERY_STATE_INVALID The ADC conversion is not ready yet or the
* result is out of range.
*
* This fucntion depends on the EEPROM_BATTERY_LOW value been set to the
* low batterly bandgap voltage value. The default value (0xFF) will
* disable the EEPROM_BATTERY_LOW state.
*
* example:
* \code{.cpp}
* void loop() {
* if (!arduboy.nextFrame()) return;
* if (arduboy.everyXFrames(FRAMERATE) && arduboy.checkBatteryState() == BATTERY_STATE_LOW)
* {
* batteryLowWarning = true;
* }
* \endcode
*
* \see everyXFrames()
*/
uint8_t checkBatteryState();
/** \brief
* Returns battery state and sets TXLED as a low battery indicator
* \param flash defaults to 'false' for no flashing. use 'FLASH_LED' or
* `true` for flashing.
* \details
* This function is intended as a method to determine a low battery state.
* The TXLED is used as a battery low indicator. The TXLED will light up
* continiously by default when the battery state is low. The optional
* FLASH_LED parameter can be passed to make the LED toggle on or off on low
* battery state.
*
* This function is a quick way of adding a low battery indicator to a sketch.
*
* example:
* \code{.cpp}
* void loop() {
* if (!arduboy.nextFrame()) return;
* //turn TXLED alternately on 1 second and off 1 second when battery is low
* if (arduboy.everyXFrames(FRAMERATE)) checkBatteryStateLED(FLASH_LED);
* \endcode
*
* \see checkBatteryState() everyXFrames()
*/
uint8_t checkBatteryStateLED(bool flash = false);
/** \brief /** \brief
* A counter which is incremented once per frame. * A counter which is incremented once per frame.
* *
@ -1309,6 +1369,8 @@ class Arduboy2Base : public Arduboy2Core
*/ */
static uint8_t sBuffer[(HEIGHT*WIDTH)/8]; static uint8_t sBuffer[(HEIGHT*WIDTH)/8];
static uint8_t batteryLow;
protected: protected:
// helper function for sound enable/disable system control // helper function for sound enable/disable system control
void sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal); void sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal);