Merge branch 'master' into master
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Low-battery LED indicator. See battery_led.h.
|
||||
//
|
||||
|
||||
#include "battery_led.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "config.h"
|
||||
#include "pico/cyw43_arch.h"
|
||||
#include "pico/time.h"
|
||||
|
||||
extern uint8_t interrupt_in_data[63];
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr uint64_t REPORT_STALE_US = 2'000'000; // assume disconnected if no report for 2 s
|
||||
constexpr uint64_t BLINK_PERIOD_US = 500'000; // 1 Hz, 50% duty
|
||||
constexpr uint8_t THRESHOLD_LEVEL = 1; // PowerPercent <= 1 (i.e. <= 10%)
|
||||
constexpr uint8_t POWER_STATE_DISCHARGING = 0x0;
|
||||
|
||||
uint64_t last_report_us = 0;
|
||||
uint64_t last_toggle_us = 0;
|
||||
bool blinking = false;
|
||||
bool led_state = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
void battery_led_init(void) {
|
||||
last_report_us = 0;
|
||||
last_toggle_us = 0;
|
||||
blinking = false;
|
||||
led_state = false;
|
||||
}
|
||||
|
||||
void battery_led_note_report(void) {
|
||||
last_report_us = time_us_64();
|
||||
}
|
||||
|
||||
void battery_led_tick(void) {
|
||||
const uint64_t now = time_us_64();
|
||||
if (last_report_us == 0 || (now - last_report_us) >= REPORT_STALE_US) {
|
||||
// No fresh data — bt.cpp owns the LED while disconnected.
|
||||
blinking = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t b = interrupt_in_data[52];
|
||||
const uint8_t pct = b & 0x0F;
|
||||
const uint8_t st = (b >> 4) & 0x0F;
|
||||
const bool low = (st == POWER_STATE_DISCHARGING) && (pct <= THRESHOLD_LEVEL);
|
||||
|
||||
if (low) {
|
||||
// Critical warning: override disable_pico_led so the user always sees it.
|
||||
if (!blinking) {
|
||||
blinking = true;
|
||||
led_state = true;
|
||||
last_toggle_us = now;
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true);
|
||||
return;
|
||||
}
|
||||
if ((now - last_toggle_us) >= BLINK_PERIOD_US) {
|
||||
led_state = !led_state;
|
||||
last_toggle_us = now;
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state);
|
||||
}
|
||||
} else if (blinking) {
|
||||
blinking = false;
|
||||
// Battery recovered or now charging — restore steady-state LED per the user
|
||||
// preference flag (LED off when disabled, otherwise the bt.cpp connected = on state).
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, !get_config().disable_pico_led);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Low-battery LED indicator for the Pico onboard LED.
|
||||
// Reads PowerPercent / PowerState from interrupt_in_data[52]
|
||||
// (DualSense BT 0x31 report, see USBGetStateData in utils.h).
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
void battery_led_init(void);
|
||||
|
||||
// Call once per main-loop iteration. Drives the LED blink while the
|
||||
// battery is low and the controller is connected; otherwise no-op.
|
||||
void battery_led_tick(void);
|
||||
|
||||
// Call from the BT input-report callback whenever a fresh 0x31 report
|
||||
// has been copied into interrupt_in_data. Used to detect disconnection
|
||||
// via stale-report timeout.
|
||||
void battery_led_note_report(void);
|
||||
+8
-2
@@ -17,8 +17,8 @@
|
||||
#include "config.h"
|
||||
#include "pico/util/queue.h"
|
||||
|
||||
#define MTU_CONTROL 256
|
||||
#define MTU_INTERRUPT 1691
|
||||
#define MTU_CONTROL 672
|
||||
#define MTU_INTERRUPT 672
|
||||
|
||||
using std::unordered_map;
|
||||
using std::vector;
|
||||
@@ -395,6 +395,9 @@ static void l2cap_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
if (psm == PSM_HID_CONTROL) {
|
||||
printf("[L2CAP] HID Control opened cid=0x%04X\n", local_cid);
|
||||
hid_control_cid = local_cid;
|
||||
|
||||
const auto mtu = l2cap_get_remote_mtu_for_local_cid(hid_control_cid);
|
||||
printf("[L2CAP] Remote Control MTU: %d\n",mtu);
|
||||
} else if (psm == PSM_HID_INTERRUPT) {
|
||||
printf("[L2CAP] HID Interrupt opened cid=0x%04X\n", local_cid);
|
||||
hid_interrupt_cid = local_cid;
|
||||
@@ -429,6 +432,9 @@ static void l2cap_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
memcpy(report32 + 2, packet_0x10, sizeof(packet_0x10));
|
||||
bt_write(report32, sizeof(report32));
|
||||
|
||||
const auto mtu = l2cap_get_remote_mtu_for_local_cid(hid_interrupt_cid);
|
||||
printf("[L2CAP] Remote Interrupt MTU: %d\n",mtu);
|
||||
|
||||
// tud_connect();
|
||||
} else {
|
||||
printf("[L2CAP] Unknown Channel psm: 0x%02X", psm);
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#endif
|
||||
#include "config.h"
|
||||
#include "cmd.h"
|
||||
#if ENABLE_BATT_LED
|
||||
#include "battery_led.h"
|
||||
#endif
|
||||
|
||||
// Pico SDK speciifically for waiting on conditions
|
||||
#include "pico/critical_section.h"
|
||||
@@ -85,6 +88,9 @@ void on_bt_data(CHANNEL_TYPE channel, uint8_t *data, uint16_t len) {
|
||||
|
||||
if (get_config().polling_rate_mode != 2) {
|
||||
memcpy(interrupt_in_data, data + 3, 63);
|
||||
#if ENABLE_BATT_LED
|
||||
battery_led_note_report();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,6 +104,9 @@ void on_bt_data(CHANNEL_TYPE channel, uint8_t *data, uint16_t len) {
|
||||
memcpy(interrupt_in_data, data + 3, 63);
|
||||
report_dirty = true;
|
||||
critical_section_exit(&report_cs);
|
||||
#if ENABLE_BATT_LED
|
||||
battery_led_note_report();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +213,10 @@ int main() {
|
||||
}
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, false);
|
||||
|
||||
#if ENABLE_BATT_LED
|
||||
battery_led_init();
|
||||
#endif
|
||||
|
||||
#if !ENABLE_SERIAL
|
||||
if (watchdog_caused_reboot()) {
|
||||
printf("Rebooted by Watchdog!\n");
|
||||
@@ -243,5 +256,8 @@ int main() {
|
||||
tud_task();
|
||||
audio_loop();
|
||||
interrupt_loop();
|
||||
#if ENABLE_BATT_LED
|
||||
battery_led_tick();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user