2021-08-02 11:15:24 +00:00
|
|
|
#include <furi.h>
|
2022-01-05 16:10:18 +00:00
|
|
|
#include <furi_hal.h>
|
|
|
|
#include <notification/notification_messages.h>
|
2021-08-02 11:15:24 +00:00
|
|
|
|
2022-01-21 16:55:44 +00:00
|
|
|
typedef struct {
|
|
|
|
osThreadId_t thread;
|
|
|
|
|
|
|
|
} PowerObserverSrv;
|
|
|
|
|
2021-08-02 11:15:24 +00:00
|
|
|
const NotificationMessage message_green_110 = {
|
|
|
|
.type = NotificationMessageTypeLedGreen,
|
|
|
|
.data.led.value = 110,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const NotificationSequence sequence_overconsumption = {
|
|
|
|
&message_green_110,
|
|
|
|
&message_red_255,
|
|
|
|
&message_delay_100,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2022-01-21 16:55:44 +00:00
|
|
|
typedef enum {
|
|
|
|
EventReset = (1 << 0),
|
|
|
|
EventRequest = (1 << 1),
|
|
|
|
} UsbEvent;
|
|
|
|
|
|
|
|
static void usb_state_callback(FuriHalUsbStateEvent state, void* context) {
|
|
|
|
PowerObserverSrv* srv = (PowerObserverSrv*)(context);
|
|
|
|
if(state == FuriHalUsbStateEventReset) {
|
|
|
|
osThreadFlagsSet(srv->thread, EventReset);
|
|
|
|
} else if(state == FuriHalUsbStateEventDescriptorRequest) {
|
|
|
|
osThreadFlagsSet(srv->thread, EventRequest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-07 16:54:42 +00:00
|
|
|
int32_t power_observer_srv(void* p) {
|
2021-08-02 11:15:24 +00:00
|
|
|
NotificationApp* notifications = furi_record_open("notification");
|
2022-01-21 16:55:44 +00:00
|
|
|
PowerObserverSrv* srv = furi_alloc(sizeof(PowerObserverSrv));
|
|
|
|
srv->thread = osThreadGetId();
|
2021-08-02 11:15:24 +00:00
|
|
|
|
|
|
|
const float overconsumption_limit = 0.03f;
|
2022-01-21 16:55:44 +00:00
|
|
|
bool usb_request_pending = false;
|
|
|
|
uint8_t usb_wait_time = 0;
|
|
|
|
|
|
|
|
furi_hal_usb_set_state_callback(usb_state_callback, srv);
|
2021-08-02 11:15:24 +00:00
|
|
|
|
|
|
|
while(true) {
|
2022-01-21 16:55:44 +00:00
|
|
|
uint32_t flags = osThreadFlagsWait(EventReset | EventRequest, osFlagsWaitAny, 500);
|
|
|
|
if((flags & osFlagsError) == 0) {
|
|
|
|
if(flags & EventReset) {
|
|
|
|
usb_request_pending = true;
|
|
|
|
usb_wait_time = 0;
|
|
|
|
}
|
|
|
|
if(flags & EventRequest) {
|
|
|
|
usb_request_pending = false;
|
|
|
|
}
|
|
|
|
} else if(usb_request_pending) {
|
|
|
|
usb_wait_time++;
|
|
|
|
if(usb_wait_time > 4) {
|
|
|
|
furi_hal_usb_reinit();
|
|
|
|
usb_request_pending = false;
|
|
|
|
}
|
|
|
|
}
|
2021-08-02 11:15:24 +00:00
|
|
|
|
2022-01-21 16:55:44 +00:00
|
|
|
float current = -furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge);
|
|
|
|
if(current > overconsumption_limit) {
|
2021-08-02 11:15:24 +00:00
|
|
|
notification_message_block(notifications, &sequence_overconsumption);
|
|
|
|
}
|
2022-01-21 16:55:44 +00:00
|
|
|
if(furi_hal_power_is_otg_enabled()) {
|
|
|
|
furi_hal_power_check_otg_status();
|
|
|
|
}
|
2021-08-02 11:15:24 +00:00
|
|
|
}
|
|
|
|
|
2022-01-21 16:55:44 +00:00
|
|
|
free(srv);
|
2021-08-02 11:15:24 +00:00
|
|
|
return 0;
|
2022-01-21 16:55:44 +00:00
|
|
|
}
|