Skip to content

Commit

Permalink
SFT-1071: Port FE battery ADC code to Gen 2 repo
Browse files Browse the repository at this point in the history
FE battery icon was not updating as battery drained
  • Loading branch information
FoundationKen committed Aug 25, 2023
1 parent 94cc878 commit 81898ca
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 6 deletions.
1 change: 1 addition & 0 deletions ports/stm32/boards/Passport/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@
('tasks/__init__.py',
'tasks/apply_passphrase_task.py',
'tasks/auto_shutdown_task.py',
'tasks/battery_adc_task.py',
'tasks/bip85_seed_task.py',
'tasks/calculate_file_sha256_task.py',
'tasks/card_task.py',
Expand Down
2 changes: 2 additions & 0 deletions ports/stm32/boards/Passport/modules/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ def go():

if passport.HAS_FUEL_GAUGE:
common.loop.create_task(tasks.fuelgauge_task())
else:
common.loop.create_task(tasks.battery_adc_task())

# Setup the main task
common.loop.create_task(tasks.main_task())
Expand Down
4 changes: 2 additions & 2 deletions ports/stm32/boards/Passport/modules/screens/main_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def update_background(self):
idx = NUM_ACCOUNT_TEXTURES

overlay_name = 'IMAGE_SCREEN_OVERLAY_{}'.format(idx)
print('overlay_name={}'.format(overlay_name))
# print('overlay_name={}'.format(overlay_name))
with LocalStyle(self.overlay) as default:
default.bg_img(getattr(lv, overlay_name))
default.radius(8)
Expand All @@ -110,7 +110,7 @@ def update_background(self):
idx = NUM_ACCOUNT_TEXTURES

overlay_name = 'IMAGE_SCREEN_OVERLAY_{}'.format(idx)
print('overlay_name={}'.format(overlay_name))
# print('overlay_name={}'.format(overlay_name))
with LocalStyle(self.overlay) as default:
default.bg_img(getattr(lv, overlay_name))
default.radius(8)
Expand Down
3 changes: 3 additions & 0 deletions ports/stm32/boards/Passport/modules/styles/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
DIGIT_BORDER_COLOR_FOCUSED_HEX = FD_BLUE_HEX
PIN_ENTRY_MESSAGE_COLOR_HEX = FD_BLUE_HEX
BATTERY_FILL_COLOR_HEX = FD_BLUE_HEX
BATTERY_FILL_BG_COLOR_HEX = TEXT_GREY
SCROLLBAR_BG_COLOR_HEX = BLACK_HEX
else:
# On monochrome, white is white, and everything else is black
Expand Down Expand Up @@ -122,6 +123,7 @@
DIGIT_BORDER_COLOR_UNFOCUSED_HEX = BLACK_HEX
PIN_ENTRY_MESSAGE_COLOR_HEX = BLACK_HEX
BATTERY_FILL_COLOR_HEX = BLACK_HEX
BATTERY_FILL_BG_COLOR_HEX = WHITE_HEX
SCROLLBAR_BG_COLOR_HEX = BLACK_HEX

WHITE = lv.color_hex(WHITE_HEX)
Expand Down Expand Up @@ -178,6 +180,7 @@
DIGIT_BORDER_COLOR_UNFOCUSED = lv.color_hex(DIGIT_BORDER_COLOR_UNFOCUSED_HEX)
PIN_ENTRY_MESSAGE_COLOR = lv.color_hex(PIN_ENTRY_MESSAGE_COLOR_HEX)
BATTERY_FILL_COLOR = lv.color_hex(BATTERY_FILL_COLOR_HEX)
BATTERY_FILL_BG_COLOR = lv.color_hex(BATTERY_FILL_BG_COLOR_HEX)
SCROLLBAR_BG_COLOR = lv.color_hex(SCROLLBAR_BG_COLOR_HEX)

# Account Colors
Expand Down
2 changes: 2 additions & 0 deletions ports/stm32/boards/Passport/modules/tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

if passport.HAS_FUEL_GAUGE:
from .fuelgauge_task import fuelgauge_task
else:
from .battery_adc_task import battery_adc_task

from .apply_passphrase_task import apply_passphrase_task
from .auto_shutdown_task import auto_shutdown_task
Expand Down
89 changes: 89 additions & 0 deletions ports/stm32/boards/Passport/modules/tasks/battery_adc_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <hello@foundationdevices.com>
# SPDX-License-Identifier: GPL-3.0-or-later
#
# battery_adc_task.py - Task for updating the battery level in the UI by reading the battery ADC
# (Founder's Edition only).


from micropython import const
from uasyncio import sleep_ms
import common

NUM_SAMPLES = const(2)

battery_segments = [
{'v': 3100, 'p': 100},
{'v': 3100, 'p': 100},
{'v': 3025, 'p': 75},
{'v': 2975, 'p': 50},
{'v': 2800, 'p': 25},
{'v': 2400, 'p': 0},
]


def calc_battery_percent(current, voltage):
# print('calc_battery_percent(): voltage={}'.format(voltage))
if voltage > 3100:
voltage = 3100
elif voltage < 2400:
voltage = 2400

# First find the segment we fit in
for i in range(1, len(battery_segments)):
curr = battery_segments[i]
prev = battery_segments[i - 1]
if voltage >= curr['v']:
# print('curr[{}]={}'.format(i, curr))

rise = curr['v'] - prev['v']
# print('rise={}'.format(rise))

run = curr['p'] - prev['p']
# print('run={}'.format(run))

if run == 0:
# print('zero run, so return value directly: {}'.format(curr['p']))
return curr['p']

# Slope
m = rise / run
# print('m={}'.format(m))

# y = mx + b => x = (y - b) / m => b = y - mx

# Calculate y intercept for this segment
b = curr['v'] - (m * curr['p'])
# print('b={}'.format(b))

percent = int((voltage - b) / m)
# print('Returning percent={}'.format(percent))
return percent

return 0


async def battery_adc_task():
while True:
# Read the current values -- repeat this a number of times and average for better results
total_current = 0
total_voltage = 0
for i in range(NUM_SAMPLES):
(current, voltage) = common.powermon.read()
voltage = round(voltage * (44.7 + 22.1) / 44.7)
total_current += current
total_voltage += voltage
await sleep_ms(1) # Wait a bit before next sample
current = total_current / NUM_SAMPLES
voltage = total_voltage / NUM_SAMPLES

# Update the actual battery level in the UI
level = calc_battery_percent(current, voltage)
# print('New battery level = {}'.format(level))

common.ui.set_battery_level(level)

# If battery is too low, try to avoid the doom loop of reboots by shutting down automatically
if level <= 2:
common.system.shutdown()

await sleep_ms(60000)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import lvgl as lv
from micropython import const
from views import View, Icon
from styles.colors import BATTERY_FILL_COLOR, WHITE, TEXT_GREY
from styles.colors import BATTERY_FILL_COLOR, BATTERY_FILL_BG_COLOR, WHITE
from styles import Stylize, LocalStyle

_LEFT_MARGIN = const(2)
Expand All @@ -32,7 +32,7 @@ def __init__(self, outline_color=WHITE):
self.bg_fill.set_size(_FILL_MAX_WIDTH, _FILL_HEIGHT)
self.bg_fill.set_pos(_LEFT_MARGIN, _TOP_MARGIN)
with Stylize(self.bg_fill) as default:
default.bg_color(TEXT_GREY)
default.bg_color(BATTERY_FILL_BG_COLOR)

self.fill = View()
self.fill.set_height(_FILL_HEIGHT)
Expand Down
10 changes: 8 additions & 2 deletions simulator/sim_modules/passport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ def random_bytes(self, buf, _source):

class Powermon:
def __init__(self):
pass
self.level = 2350
self.increment = -25

def read(self):
return (0, 3500)
result = (0, self.level)
self.level += self.increment
if self.level <= 1750 or self.level >= 2350:
self.increment = -self.increment
# print('Powermon simulator: {}'.format(result))
return result


class System:
Expand Down

0 comments on commit 81898ca

Please sign in to comment.