From 0f834e0ce227812499f28be36b93b07a0414ad98 Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Mon, 28 Dec 2020 19:28:35 -0500 Subject: [PATCH] add battery status --- apple/appleui.cpp | 7 +++--- teensy/teensy.ino | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/apple/appleui.cpp b/apple/appleui.cpp index 238065b..040f2e1 100644 --- a/apple/appleui.cpp +++ b/apple/appleui.cpp @@ -54,9 +54,9 @@ void AppleUI::drawPercentageUIElement(uint8_t element, uint8_t percent) void AppleUI::drawBatteryStatus(uint8_t percent) { - uint16_t xoff = 301*2; + uint16_t xoff = 301; uint16_t yoff = 222; - + // the area around the apple is 12 wide; it's exactly 11 high the // color is 210/202/159 @@ -93,7 +93,8 @@ void AppleUI::drawBatteryStatus(uint8_t percent) g = (float)g * alpha + (bgg * (1.0 - alpha)); b = (float)b * alpha + (bgb * (1.0 - alpha)); - g_display->drawPixel(x+xoff, y+yoff, r, g, b); + uint16_t color16 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3); + g_display->drawUIPixel(x+xoff, y+yoff, color16); } } } diff --git a/teensy/teensy.ino b/teensy/teensy.ino index 18e3ab8..9212fda 100644 --- a/teensy/teensy.ino +++ b/teensy/teensy.ino @@ -26,6 +26,8 @@ #define RESETPIN 38 #define DEBUGPIN 23 +#define BATTERYLEVEL 20 // analog reading of battery voltage (scaled to half) +#define BATTERYSELECT 21 // digital select that turns on the power reading ckt #include "globals.h" #include "teensy-crash.h" @@ -43,6 +45,23 @@ Bounce resetButtonDebouncer = Bounce(); volatile bool cpuClockInitialized = false; +// The battery voltage measurement comes through a 50% ratio voltage +// divider; and the analog resolution is set to 8 bits (so a max of +// 256); with a fixed voltage reference of 3.3v (standard in the +// Teensy 4.1). Since the voltage of a 16550 battery is 4.2v (at +// 100%) to 2.5v (at 0%), that means we should expect the +// currentBatteryReading to be about 97 - 163. Since this is +// imperfect due to tolerance in the resistors and whatnot, we might +// as well call that 100 - 160. +volatile uint16_t currentBatteryReading = 0; +volatile uint16_t currentBatteryCount = 0; +volatile uint16_t currentBatterySum = 0; + +#define BATTERYMIN 100 +#define BATTERYMAX 160 +// how often should we read the battery level? +#define BATTERYPERIOD (60 * 100000) + void onKeypress(int unicode) { /* @@ -80,6 +99,9 @@ void setup() delay(120); // let the power settle pinMode(DEBUGPIN, OUTPUT); // for debugging + pinMode(BATTERYSELECT, OUTPUT); + digitalWrite(BATTERYSELECT, false); // leave it off by default + pinMode(BATTERYLEVEL, INPUT); // enableFaultHandler(); // SCB_SHCSR |= SCB_SHCSR_BUSFAULTENA | SCB_SHCSR_USGFAULTENA | SCB_SHCSR_MEMFAULTENA; @@ -344,8 +366,40 @@ void runCPU(uint32_t now) void loop() { + static uint32_t readingBattery = 0; // set to millis() + a settle time constant when we start reading + static uint32_t nextReadBattery = micros() + BATTERYPERIOD; + uint32_t now = micros(); + if (readingBattery && now >= readingBattery) { + // Take 10 readings over a second and average them + currentBatterySum += analogRead(BATTERYLEVEL); + readingBattery = now + 100000; // 100 ms + if (++currentBatteryCount >= 10) { + currentBatteryReading = currentBatterySum / currentBatteryCount; + readingBattery = 0; + digitalWrite(BATTERYSELECT, false); + nextReadBattery = now + BATTERYPERIOD; + + // Set up the displayed battery level + if (currentBatteryReading < BATTERYMIN) + currentBatteryReading = BATTERYMIN; + if (currentBatteryReading > BATTERYMAX) + currentBatteryReading = BATTERYMAX; + + ((AppleUI *)g_ui)->drawBatteryStatus(map(currentBatteryReading, + BATTERYMIN, BATTERYMAX, + 0, 100)); + } + } + else if (!readingBattery && now >= nextReadBattery) { + // start reading the battery + readingBattery = now + 1 * 1000000; // let it settle for 1 second + currentBatterySum = 0; + currentBatteryCount = 0; + digitalWrite(BATTERYSELECT, true); + } + static bool wasBios = false; // so we can tell when it's done if (g_biosInterrupt) { runBIOS(now);