mirror of
https://github.com/bettse/seader.git
synced 2026-03-29 10:10:04 +00:00
power: convert board voltage handling to millivolts
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "board_power_lifecycle.h"
|
||||
|
||||
#define SEADER_BOARD_POWER_AVAILABLE_MV 4500U
|
||||
|
||||
SeaderBoardPowerAcquirePlan seader_board_power_plan_acquire(bool otg_already_enabled) {
|
||||
SeaderBoardPowerAcquirePlan plan = {
|
||||
.should_enable_otg = !otg_already_enabled,
|
||||
@@ -9,23 +11,23 @@ SeaderBoardPowerAcquirePlan seader_board_power_plan_acquire(bool otg_already_ena
|
||||
return plan;
|
||||
}
|
||||
|
||||
bool seader_board_power_is_available(bool otg_enabled, float vbus_voltage) {
|
||||
return otg_enabled || vbus_voltage >= 4.5f;
|
||||
bool seader_board_power_is_available(bool otg_enabled, uint16_t vbus_mv) {
|
||||
return otg_enabled || vbus_mv >= SEADER_BOARD_POWER_AVAILABLE_MV;
|
||||
}
|
||||
|
||||
SeaderBoardRuntimePowerState seader_board_runtime_power_state(
|
||||
bool otg_requested,
|
||||
bool otg_enabled,
|
||||
float vbus_voltage,
|
||||
uint16_t vbus_mv,
|
||||
bool otg_fault,
|
||||
bool grace_active,
|
||||
uint32_t grace_elapsed_ms,
|
||||
uint32_t grace_window_ms) {
|
||||
if(seader_board_power_is_available(otg_enabled, vbus_voltage)) {
|
||||
if(seader_board_power_is_available(otg_enabled, vbus_mv)) {
|
||||
return SeaderBoardRuntimePowerStateHealthy;
|
||||
}
|
||||
|
||||
if(otg_fault && vbus_voltage < 4.5f) {
|
||||
if(otg_fault && vbus_mv < SEADER_BOARD_POWER_AVAILABLE_MV) {
|
||||
return SeaderBoardRuntimePowerStateLost;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ typedef struct {
|
||||
} SeaderBoardPowerAcquirePlan;
|
||||
|
||||
SeaderBoardPowerAcquirePlan seader_board_power_plan_acquire(bool otg_already_enabled);
|
||||
bool seader_board_power_is_available(bool otg_enabled, float vbus_voltage);
|
||||
bool seader_board_power_is_available(bool otg_enabled, uint16_t vbus_mv);
|
||||
SeaderBoardRuntimePowerState seader_board_runtime_power_state(
|
||||
bool otg_requested,
|
||||
bool otg_enabled,
|
||||
float vbus_voltage,
|
||||
uint16_t vbus_mv,
|
||||
bool otg_fault,
|
||||
bool grace_active,
|
||||
uint32_t grace_elapsed_ms,
|
||||
|
||||
@@ -44,9 +44,9 @@ static MunitResult test_power_available_when_usb_vbus_is_already_present(
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
|
||||
munit_assert_true(seader_board_power_is_available(false, 5.0f));
|
||||
munit_assert_true(seader_board_power_is_available(true, 0.0f));
|
||||
munit_assert_false(seader_board_power_is_available(false, 4.4f));
|
||||
munit_assert_true(seader_board_power_is_available(false, 5000U));
|
||||
munit_assert_true(seader_board_power_is_available(true, 0U));
|
||||
munit_assert_false(seader_board_power_is_available(false, 4400U));
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ static MunitResult test_power_unavailable_when_neither_otg_nor_vbus_is_present(
|
||||
(void)params;
|
||||
(void)fixture;
|
||||
|
||||
munit_assert_false(seader_board_power_is_available(false, 0.0f));
|
||||
munit_assert_false(seader_board_power_is_available(false, 0U));
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
@@ -67,23 +67,23 @@ static MunitResult test_runtime_power_state_uses_handoff_grace(
|
||||
(void)fixture;
|
||||
|
||||
munit_assert_int(
|
||||
seader_board_runtime_power_state(false, false, 5.0f, false, false, 0U, 2000U),
|
||||
seader_board_runtime_power_state(false, false, 5000U, false, false, 0U, 2000U),
|
||||
==,
|
||||
SeaderBoardRuntimePowerStateHealthy);
|
||||
munit_assert_int(
|
||||
seader_board_runtime_power_state(true, false, 0.0f, false, false, 0U, 2000U),
|
||||
seader_board_runtime_power_state(true, false, 0U, false, false, 0U, 2000U),
|
||||
==,
|
||||
SeaderBoardRuntimePowerStateGracePending);
|
||||
munit_assert_int(
|
||||
seader_board_runtime_power_state(true, false, 0.0f, false, true, 1500U, 2000U),
|
||||
seader_board_runtime_power_state(true, false, 0U, false, true, 1500U, 2000U),
|
||||
==,
|
||||
SeaderBoardRuntimePowerStateGracePending);
|
||||
munit_assert_int(
|
||||
seader_board_runtime_power_state(true, false, 0.0f, false, true, 2000U, 2000U),
|
||||
seader_board_runtime_power_state(true, false, 0U, false, true, 2000U, 2000U),
|
||||
==,
|
||||
SeaderBoardRuntimePowerStateLost);
|
||||
munit_assert_int(
|
||||
seader_board_runtime_power_state(true, true, 0.0f, false, true, 2000U, 2000U),
|
||||
seader_board_runtime_power_state(true, true, 0U, false, true, 2000U, 2000U),
|
||||
==,
|
||||
SeaderBoardRuntimePowerStateHealthy);
|
||||
return MUNIT_OK;
|
||||
@@ -96,7 +96,7 @@ static MunitResult test_runtime_power_state_fault_is_immediate(
|
||||
(void)fixture;
|
||||
|
||||
munit_assert_int(
|
||||
seader_board_runtime_power_state(true, false, 0.0f, true, false, 0U, 2000U),
|
||||
seader_board_runtime_power_state(true, false, 0U, true, false, 0U, 2000U),
|
||||
==,
|
||||
SeaderBoardRuntimePowerStateLost);
|
||||
return MUNIT_OK;
|
||||
|
||||
30
seader.c
30
seader.c
@@ -260,6 +260,19 @@ static void seader_hf_read_fail(Seader* seader, SeaderHfReadFailureReason reason
|
||||
sizeof(seader->read_error));
|
||||
}
|
||||
|
||||
static uint16_t seader_board_vbus_mv_from_volts(float vbus_voltage) {
|
||||
if(vbus_voltage <= 0.0f) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
const float scaled_mv = (vbus_voltage * 1000.0f) + 0.5f;
|
||||
if(scaled_mv >= 65535.0f) {
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
return (uint16_t)scaled_mv;
|
||||
}
|
||||
|
||||
static void seader_board_runtime_monitor_tick(Seader* seader) {
|
||||
if(!seader || !seader->power || !seader->board_power_enabled ||
|
||||
seader->board_status == SeaderBoardStatusPowerLost) {
|
||||
@@ -274,17 +287,18 @@ static void seader_board_runtime_monitor_tick(Seader* seader) {
|
||||
|
||||
PowerInfo info;
|
||||
power_get_info(seader->power, &info);
|
||||
const uint16_t vbus_mv = seader_board_vbus_mv_from_volts(info.voltage_vbus);
|
||||
|
||||
const bool otg_requested = power_is_otg_enabled(seader->power);
|
||||
const uint32_t now = furi_get_tick();
|
||||
const uint32_t elapsed =
|
||||
seader->board_power_loss_pending ? (now - seader->board_power_loss_started_at) : 0U;
|
||||
const bool otg_fault = furi_hal_power_check_otg_fault() && info.voltage_vbus < 4.5f;
|
||||
const bool otg_fault = furi_hal_power_check_otg_fault() && vbus_mv < 4500U;
|
||||
|
||||
const SeaderBoardRuntimePowerState runtime_state = seader_board_runtime_power_state(
|
||||
otg_requested,
|
||||
info.is_otg_enabled,
|
||||
info.voltage_vbus,
|
||||
vbus_mv,
|
||||
otg_fault,
|
||||
seader->board_power_loss_pending,
|
||||
elapsed,
|
||||
@@ -399,21 +413,21 @@ static bool seader_board_power_on(Seader* seader) {
|
||||
|
||||
furi_delay_ms(SEADER_BOARD_POWER_SETTLE_MS);
|
||||
const bool otg_enabled = furi_hal_power_is_otg_enabled();
|
||||
const float vbus_voltage = furi_hal_power_get_usb_voltage();
|
||||
const uint16_t vbus_mv = seader_board_vbus_mv_from_volts(furi_hal_power_get_usb_voltage());
|
||||
seader->board_power_owned = plan.owns_otg && otg_enabled;
|
||||
|
||||
if(!seader_board_power_is_available(otg_enabled, vbus_voltage)) {
|
||||
if(!seader_board_power_is_available(otg_enabled, vbus_mv)) {
|
||||
FURI_LOG_W(
|
||||
TAG,
|
||||
"Board power unavailable after OTG request: otg=%d vbus=%.1fV",
|
||||
"Board power unavailable after OTG request: otg=%d vbus=%umV",
|
||||
otg_enabled,
|
||||
(double)vbus_voltage);
|
||||
vbus_mv);
|
||||
seader_board_power_fail(seader, SeaderBoardStatusFaultPreEnable);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!otg_enabled && vbus_voltage >= 4.5f) {
|
||||
FURI_LOG_I(TAG, "Using external VBUS power at %.1fV", (double)vbus_voltage);
|
||||
if(!otg_enabled && vbus_mv >= 4500U) {
|
||||
FURI_LOG_I(TAG, "Using external VBUS power at %umV", vbus_mv);
|
||||
}
|
||||
|
||||
if(furi_hal_power_check_otg_fault()) {
|
||||
|
||||
Reference in New Issue
Block a user