diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index 235f5302f9..b7ca6772f3 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -166,6 +166,9 @@ void set_poweroff_timeout(int timeout); void set_battery_capacity(int capacity); /* set local battery capacity value */ int get_battery_capacity(void); /* get local battery capacity value */ void set_battery_type(int type); /* set local battery type */ +#ifdef USB_ENABLE_HID +void set_battery_reporting(bool enable); +#endif void set_sleeptimer_duration(int minutes); int get_sleep_timer(void); diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 6cac300cdf..969d6167da 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -48,6 +48,9 @@ #if (CONFIG_PLATFORM & PLATFORM_HOSTED) #include #endif +#ifdef USB_ENABLE_HID +#include "usbstack/usb_hid.h" +#endif #if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) \ && !defined (SIMULATOR) @@ -637,6 +640,17 @@ static void collect_power_history(void) power_history[0] = power_hist_item(); } +#ifdef USB_ENABLE_HID +static bool battery_reporting = false; +static int battery_report_percent = -1; + +void set_battery_reporting(bool enable) +{ + battery_reporting = enable; + battery_report_percent = -1; +} +#endif + /* * Monitor the presence of a charger and perform critical frequent steps * such as running the battery voltage filter. @@ -750,6 +764,13 @@ static void power_thread(void) next_power_hist += HZ*60; collect_power_history(); } + +#ifdef USB_ENABLE_HID + if (battery_reporting && battery_report_percent != battery_percent) { + battery_report_percent = battery_percent; + usb_hid_send(HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS, battery_report_percent); + } +#endif } } /* power_thread */ diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c index ed0816395a..0b672e6452 100644 --- a/firmware/usbstack/usb_hid.c +++ b/firmware/usbstack/usb_hid.c @@ -23,6 +23,7 @@ #include "usb_core.h" #include "usb_drv.h" #include "kernel.h" +#include "powermgmt.h" #include "usb_hid.h" #include "usb_class_driver.h" /*#define LOGF_ENABLE*/ @@ -109,6 +110,7 @@ typedef enum #ifdef HAVE_USB_HID_MOUSE REPORT_ID_MOUSE, #endif + REPORT_ID_BACKGROUND, REPORT_ID_COUNT, } report_id_t; @@ -450,6 +452,15 @@ static uint8_t buf_set_mouse(unsigned char *buf, int id) } #endif /* HAVE_USB_HID_MOUSE */ +#define BUF_LEN_BACKGROUND 1 +static uint8_t buf_set_background(unsigned char *buf, int id) +{ + memset(buf, 0, BUF_LEN_BACKGROUND); + buf[0] = (uint8_t)id; + + return BUF_LEN_BACKGROUND; +} + static size_t descriptor_report_get(unsigned char *dest) { unsigned char *report = dest; @@ -551,6 +562,24 @@ static size_t descriptor_report_get(unsigned char *dest) PACK_VAL(report, END_COLLECTION); #endif /* HAVE_USB_HID_MOUSE */ + /* Background controls */ + usb_hid_report = &usb_hid_reports[REPORT_ID_BACKGROUND]; + usb_hid_report->usage_page = HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS; + usb_hid_report->buf_set = buf_set_background; + usb_hid_report->is_key_released = 0; + + pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS); + pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BACKGROUND_CONTROLS); + pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION); + pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_BACKGROUND); + pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BATTERY_STRENGTH); + pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0); + pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 100); + pack_parameter(&report, 0, 1, REPORT_SIZE, 8); + pack_parameter(&report, 0, 1, REPORT_COUNT, 1); + pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE); + PACK_VAL(report, END_COLLECTION); + return (size_t)(report - dest); } @@ -591,9 +620,9 @@ int usb_hid_get_config_descriptor(unsigned char *dest, int max_packet_size) void usb_hid_init_connection(void) { logf("hid: init connection"); - active = true; currently_sending = false; + set_battery_reporting(true); } /* called by usb_core_init() */ @@ -614,6 +643,7 @@ void usb_hid_init(void) void usb_hid_disconnect(void) { logf("hid: disconnect"); + set_battery_reporting(false); active = false; currently_sending = false; } diff --git a/firmware/usbstack/usb_hid_usage_tables.h b/firmware/usbstack/usb_hid_usage_tables.h index d23c704eae..538463e5a3 100644 --- a/firmware/usbstack/usb_hid_usage_tables.h +++ b/firmware/usbstack/usb_hid_usage_tables.h @@ -120,6 +120,33 @@ typedef enum usage_page #define HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY 0xB6 #define HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE 0xB7 +/* Generic Device Controls Page (0x06) */ +#define HID_GENERIC_DEVICE_UNDEFINED 0x00 +#define HID_GENERIC_DEVICE_BACKGROUND_CONTROLS 0x01 +#define HID_GENERIC_DEVICE_BATTERY_STRENGTH 0x20 +#define HID_GENERIC_DEVICE_WIRELESS_CHANNEL 0x21 +#define HID_GENERIC_DEVICE_WIRELESS_ID 0x22 +#define HID_GENERIC_DEVICE_DISCOVER_WIRELESS_CHANNEL 0x23 +#define HID_GENERIC_DEVICE_SECURITY_CODE_CHARACTER_ENTERED 0x24 +#define HID_GENERIC_DEVICE_SECURITY_CODE_CHARACTER_ERASED 0x25 +#define HID_GENERIC_DEVICE_SECURITY_CODE_CLEARED 0x26 +#define HID_GENERIC_DEVICE_SEQUENCE_ID 0x27 +#define HID_GENERIC_DEVICE_SEQUENCE_ID_RESET 0x28 +#define HID_GENERIC_DEVICE_RF_SIGNAL_STRENGTH 0x29 +#define HID_GENERIC_DEVICE_SOFTWARE_VERSION 0x2A +#define HID_GENERIC_DEVICE_PROTOCOL_VERSION 0x2B +#define HID_GENERIC_DEVICE_HARDWARE_VERSION 0x2C +#define HID_GENERIC_DEVICE_MAJOR 0x2D +#define HID_GENERIC_DEVICE_MINOR 0x2E +#define HID_GENERIC_DEVICE_REVISION 0x2F +#define HID_GENERIC_DEVICE_HANDEDNESS 0x30 +#define HID_GENERIC_DEVICE_EITHER_HAND 0x31 +#define HID_GENERIC_DEVICE_LEFT_HAND 0x32 +#define HID_GENERIC_DEVICE_RIGHT_HAND 0x33 +#define HID_GENERIC_DEVICE_BOTH_HANDS 0x34 +#define HID_GENERIC_DEVICE_GRIP_POSE_OFFSET 0x40 +#define HID_GENERIC_DEVICE_POINTER_POSE_OFFSET 0x41 + /* Keyboard/Keypad Page (0x07) */ #define HID_KEYBOARD_RESERVED 0x00 #define HID_KEYBOARD_ERROR_ROLLOVER 0x01