summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/powermgmt.h3
-rw-r--r--firmware/powermgmt.c21
-rw-r--r--firmware/usbstack/usb_hid.c86
3 files changed, 63 insertions, 47 deletions
diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h
index b7ca6772f3..235f5302f9 100644
--- a/firmware/export/powermgmt.h
+++ b/firmware/export/powermgmt.h
@@ -166,9 +166,6 @@ void set_poweroff_timeout(int timeout);
166void set_battery_capacity(int capacity); /* set local battery capacity value */ 166void set_battery_capacity(int capacity); /* set local battery capacity value */
167int get_battery_capacity(void); /* get local battery capacity value */ 167int get_battery_capacity(void); /* get local battery capacity value */
168void set_battery_type(int type); /* set local battery type */ 168void set_battery_type(int type); /* set local battery type */
169#ifdef USB_ENABLE_HID
170void set_battery_reporting(bool enable);
171#endif
172 169
173void set_sleeptimer_duration(int minutes); 170void set_sleeptimer_duration(int minutes);
174int get_sleep_timer(void); 171int get_sleep_timer(void);
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 969d6167da..6cac300cdf 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -48,9 +48,6 @@
48#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 48#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
49#include <time.h> 49#include <time.h>
50#endif 50#endif
51#ifdef USB_ENABLE_HID
52#include "usbstack/usb_hid.h"
53#endif
54 51
55#if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) \ 52#if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) \
56 && !defined (SIMULATOR) 53 && !defined (SIMULATOR)
@@ -640,17 +637,6 @@ static void collect_power_history(void)
640 power_history[0] = power_hist_item(); 637 power_history[0] = power_hist_item();
641} 638}
642 639
643#ifdef USB_ENABLE_HID
644static bool battery_reporting = false;
645static int battery_report_percent = -1;
646
647void set_battery_reporting(bool enable)
648{
649 battery_reporting = enable;
650 battery_report_percent = -1;
651}
652#endif
653
654/* 640/*
655 * Monitor the presence of a charger and perform critical frequent steps 641 * Monitor the presence of a charger and perform critical frequent steps
656 * such as running the battery voltage filter. 642 * such as running the battery voltage filter.
@@ -764,13 +750,6 @@ static void power_thread(void)
764 next_power_hist += HZ*60; 750 next_power_hist += HZ*60;
765 collect_power_history(); 751 collect_power_history();
766 } 752 }
767
768#ifdef USB_ENABLE_HID
769 if (battery_reporting && battery_report_percent != battery_percent) {
770 battery_report_percent = battery_percent;
771 usb_hid_send(HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS, battery_report_percent);
772 }
773#endif
774 } 753 }
775} /* power_thread */ 754} /* power_thread */
776 755
diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c
index 0b672e6452..5885b60e32 100644
--- a/firmware/usbstack/usb_hid.c
+++ b/firmware/usbstack/usb_hid.c
@@ -42,6 +42,7 @@
42/* HID main items (HID1_11.pdf, page 38) */ 42/* HID main items (HID1_11.pdf, page 38) */
43#define INPUT 0x80 43#define INPUT 0x80
44#define OUTPUT 0x90 44#define OUTPUT 0x90
45#define FEATURE 0xB0
45#define COLLECTION 0xA0 46#define COLLECTION 0xA0
46#define COLLECTION_PHYSICAL 0x00 47#define COLLECTION_PHYSICAL 0x00
47#define COLLECTION_APPLICATION 0x01 48#define COLLECTION_APPLICATION 0x01
@@ -90,6 +91,7 @@
90#define HID_BUF_SIZE_REPORT 160 91#define HID_BUF_SIZE_REPORT 160
91#define HID_NUM_BUFFERS 5 92#define HID_NUM_BUFFERS 5
92#define SET_REPORT_BUF_LEN 2 93#define SET_REPORT_BUF_LEN 2
94#define GET_REPORT_BUF_LEN 2
93 95
94#ifdef LOGF_ENABLE 96#ifdef LOGF_ENABLE
95 97
@@ -103,6 +105,8 @@
103#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0) 105#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0)
104#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff 106#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff
105 107
108#define REPORT_ID_BACKGROUND REPORT_ID_COUNT
109
106typedef enum 110typedef enum
107{ 111{
108 REPORT_ID_KEYBOARD = 1, 112 REPORT_ID_KEYBOARD = 1,
@@ -110,7 +114,6 @@ typedef enum
110#ifdef HAVE_USB_HID_MOUSE 114#ifdef HAVE_USB_HID_MOUSE
111 REPORT_ID_MOUSE, 115 REPORT_ID_MOUSE,
112#endif 116#endif
113 REPORT_ID_BACKGROUND,
114 REPORT_ID_COUNT, 117 REPORT_ID_COUNT,
115} report_id_t; 118} report_id_t;
116 119
@@ -452,15 +455,6 @@ static uint8_t buf_set_mouse(unsigned char *buf, int id)
452} 455}
453#endif /* HAVE_USB_HID_MOUSE */ 456#endif /* HAVE_USB_HID_MOUSE */
454 457
455#define BUF_LEN_BACKGROUND 1
456static uint8_t buf_set_background(unsigned char *buf, int id)
457{
458 memset(buf, 0, BUF_LEN_BACKGROUND);
459 buf[0] = (uint8_t)id;
460
461 return BUF_LEN_BACKGROUND;
462}
463
464static size_t descriptor_report_get(unsigned char *dest) 458static size_t descriptor_report_get(unsigned char *dest)
465{ 459{
466 unsigned char *report = dest; 460 unsigned char *report = dest;
@@ -562,22 +556,25 @@ static size_t descriptor_report_get(unsigned char *dest)
562 PACK_VAL(report, END_COLLECTION); 556 PACK_VAL(report, END_COLLECTION);
563#endif /* HAVE_USB_HID_MOUSE */ 557#endif /* HAVE_USB_HID_MOUSE */
564 558
565 /* Background controls */ 559 /* Background reports */
566 usb_hid_report = &usb_hid_reports[REPORT_ID_BACKGROUND];
567 usb_hid_report->usage_page = HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS;
568 usb_hid_report->buf_set = buf_set_background;
569 usb_hid_report->is_key_released = 0;
570
571 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS); 560 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS);
572 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BACKGROUND_CONTROLS); 561 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BACKGROUND_CONTROLS);
573 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION); 562 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
574 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_BACKGROUND); 563 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_BACKGROUND);
564 /* Padding */
565 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_UNDEFINED);
566 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0);
567 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 255);
568 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
569 pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
570 pack_parameter(&report, 0, 1, FEATURE, MAIN_ITEM_CONSTANT);
571 /* Battery percentage */
575 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BATTERY_STRENGTH); 572 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BATTERY_STRENGTH);
576 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0); 573 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0);
577 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 100); 574 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 100);
578 pack_parameter(&report, 0, 1, REPORT_SIZE, 8); 575 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
579 pack_parameter(&report, 0, 1, REPORT_COUNT, 1); 576 pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
580 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE); 577 pack_parameter(&report, 0, 1, FEATURE, MAIN_ITEM_VARIABLE);
581 PACK_VAL(report, END_COLLECTION); 578 PACK_VAL(report, END_COLLECTION);
582 579
583 return (size_t)(report - dest); 580 return (size_t)(report - dest);
@@ -622,7 +619,6 @@ void usb_hid_init_connection(void)
622 logf("hid: init connection"); 619 logf("hid: init connection");
623 active = true; 620 active = true;
624 currently_sending = false; 621 currently_sending = false;
625 set_battery_reporting(true);
626} 622}
627 623
628/* called by usb_core_init() */ 624/* called by usb_core_init() */
@@ -643,7 +639,6 @@ void usb_hid_init(void)
643void usb_hid_disconnect(void) 639void usb_hid_disconnect(void)
644{ 640{
645 logf("hid: disconnect"); 641 logf("hid: disconnect");
646 set_battery_reporting(false);
647 active = false; 642 active = false;
648 currently_sending = false; 643 currently_sending = false;
649} 644}
@@ -677,7 +672,7 @@ static int usb_hid_set_report(struct usb_ctrlrequest *req)
677 672
678 if ((req->wValue >> 8) != REPORT_TYPE_OUTPUT) 673 if ((req->wValue >> 8) != REPORT_TYPE_OUTPUT)
679 { 674 {
680 logf("Unsopported report type"); 675 logf("Unsupported report type");
681 return 1; 676 return 1;
682 } 677 }
683 if ((req->wValue & 0xff) != REPORT_ID_KEYBOARD) 678 if ((req->wValue & 0xff) != REPORT_ID_KEYBOARD)
@@ -718,14 +713,47 @@ static int usb_hid_set_report(struct usb_ctrlrequest *req)
718 return 0; 713 return 0;
719} 714}
720 715
716static int usb_hid_get_report(struct usb_ctrlrequest *req, unsigned char** dest)
717{
718 if ((req->wValue >> 8) != REPORT_TYPE_FEATURE)
719 {
720 logf("Unsupported report type");
721 return 1;
722 }
723
724 if ((req->wValue & 0xff) != REPORT_ID_BACKGROUND)
725 {
726 logf("Wrong report id");
727 return 2;
728 }
729
730 if (req->wIndex != (uint16_t)usb_interface)
731 {
732 logf("Wrong interface");
733 return 3;
734 }
735
736 if (req->wLength < GET_REPORT_BUF_LEN)
737 {
738 logf("Wrong length");
739 return 4;
740 }
741
742 (*dest)[0] = 0;
743 (*dest)[1] = battery_level();
744 *dest += GET_REPORT_BUF_LEN;
745
746 return 0;
747}
748
721/* called by usb_core_control_request() */ 749/* called by usb_core_control_request() */
722bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest) 750bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest)
723{ 751{
752 unsigned char *orig_dest = dest;
724 switch (req->bRequestType & USB_TYPE_MASK) 753 switch (req->bRequestType & USB_TYPE_MASK)
725 { 754 {
726 case USB_TYPE_STANDARD: 755 case USB_TYPE_STANDARD:
727 { 756 {
728 unsigned char *orig_dest = dest;
729 uint8_t type = req->wValue >> 8; 757 uint8_t type = req->wValue >> 8;
730 size_t len; 758 size_t len;
731 logf("hid: type %d %s", type, (type == USB_DT_HID) ? "hid" : 759 logf("hid: type %d %s", type, (type == USB_DT_HID) ? "hid" :
@@ -755,14 +783,26 @@ bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest)
755 { 783 {
756 logf("req %d %s", req->bRequest, 784 logf("req %d %s", req->bRequest,
757 (req->bRequest == USB_HID_SET_IDLE) ? "set idle" : 785 (req->bRequest == USB_HID_SET_IDLE) ? "set idle" :
758 ((req->bRequest == USB_HID_SET_REPORT) ? "set report" : "")); 786 ((req->bRequest == USB_HID_SET_REPORT) ? "set report" :
787 ((req->bRequest == USB_HID_GET_REPORT) ? "get report" : "")));
759 switch (req->bRequest) 788 switch (req->bRequest)
760 { 789 {
761 case USB_HID_SET_REPORT: 790 case USB_HID_SET_REPORT:
762 if (usb_hid_set_report(req)) 791 if (usb_hid_set_report(req))
763 break; 792 break;
793 case USB_HID_GET_REPORT:
794 if (usb_hid_get_report(req, &dest))
795 break;
764 case USB_HID_SET_IDLE: 796 case USB_HID_SET_IDLE:
765 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 797 if (dest != orig_dest)
798 {
799 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
800 usb_drv_send(EP_CONTROL, orig_dest, dest - orig_dest);
801 }
802 else
803 {
804 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
805 }
766 return true; 806 return true;
767 } 807 }
768 break; 808 break;