Преглед изворни кода

add control set boot protocol support and keyboard idle rate

- tud_hid_keyboard_is_boot_protocol()
- tud_hid_mouse_is_boot_protocol()
hathach пре 7 година
родитељ
комит
1982886f87
3 измењених фајлова са 51 додато и 26 уклоњено
  1. 6 4
      examples/device/nrf52840/src/main.c
  2. 35 17
      src/class/hid/hid_device.c
  3. 10 5
      src/class/hid/hid_device.h

+ 6 - 4
examples/device/nrf52840/src/main.c

@@ -134,10 +134,12 @@ void usb_hid_task(void)
   /*------------- Mouse -------------*/
   if ( tud_hid_mouse_ready() )
   {
-    if     ( btn & 0x01 ) tud_hid_mouse_move(-10, 0  ); // left
-    else if( btn & 0x02 ) tud_hid_mouse_move( 10, 0  ); // right
-    else if( btn & 0x04 ) tud_hid_mouse_move(  0, -10); // up
-    else if( btn & 0x08 ) tud_hid_mouse_move(  0,  10); // down
+    enum { DELTA  = 5 };
+
+    if ( btn & 0x01 ) tud_hid_mouse_move(-DELTA,      0); // left
+    if ( btn & 0x02 ) tud_hid_mouse_move( DELTA,      0); // right
+    if ( btn & 0x04 ) tud_hid_mouse_move(  0   , -DELTA); // up
+    if ( btn & 0x08 ) tud_hid_mouse_move(  0   ,  DELTA); // down
   }
 }
 

+ 35 - 17
src/class/hid/hid_device.c

@@ -58,7 +58,9 @@
 typedef struct {
   uint8_t itf_num;
   uint8_t ep_in;
-  uint8_t idle_rate;
+
+  uint8_t idle_rate; // in unit of 4 ms
+  bool    boot_protocol;
 
   uint8_t  report_id;
   uint16_t report_len;
@@ -92,24 +94,30 @@ bool tud_hid_keyboard_ready(void)
   return !dcd_edpt_busy(TUD_OPT_RHPORT, _kbd_itf.ep_in);
 }
 
+bool tud_hid_keyboard_is_boot_protocol(void)
+{
+  return _kbd_itf.boot_protocol;
+}
+
 static bool hidd_kbd_report(hid_keyboard_report_t const *p_report)
 {
   VERIFY( tud_hid_keyboard_ready() );
 
   hidd_interface_t * p_hid = &_kbd_itf;
 
-  if ( p_report )
-  {
-    memcpy(p_hid->report_buf, p_report, sizeof(hid_keyboard_report_t));
-  }else
-  {
-    // only send empty report if previous report is not empty
-    // TODO idle rate
-    if ( mem_all_zero(p_hid->report_buf, sizeof(hid_keyboard_report_t)) ) return true;
+  // Idle Rate = 0 : only send report if there is changes, i.e skip duplication
+  // Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
+  //                 If idle time is less than interrupt polling then use the polling.
+  static tu_timeout_t idle_tm = { 0, 0 };
 
-    arrclr_(p_hid->report_buf);
+  if ( (p_hid->idle_rate == 0) || !tu_timeout_expired(&idle_tm) )
+  {
+    if ( 0 == memcmp(p_hid->report_buf, p_report, sizeof(hid_keyboard_report_t)) ) return true;
   }
 
+  tu_timeout_restart(&idle_tm);
+
+  memcpy(p_hid->report_buf, p_report, sizeof(hid_keyboard_report_t));
   return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, sizeof(hid_keyboard_report_t));
 }
 
@@ -173,12 +181,18 @@ bool tud_hid_keyboard_key_sequence(const char* str, uint32_t interval_ms)
 // MOUSE APPLICATION API
 //--------------------------------------------------------------------+
 #if CFG_TUD_HID_MOUSE
+
 bool tud_hid_mouse_ready(void)
 {
   VERIFY( _mse_itf.ep_in != 0 );
   return !dcd_edpt_busy(TUD_OPT_RHPORT, _mse_itf.ep_in);
 }
 
+bool tud_hid_mouse_is_boot_protocol(void)
+{
+  return _mse_itf.boot_protocol;
+}
+
 static bool hidd_mouse_report(hid_mouse_report_t const *p_report)
 {
   VERIFY( tud_hid_mouse_ready() );
@@ -302,10 +316,11 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
 
       TU_ASSERT( dcd_edpt_open(rhport, desc_edpt), TUSB_ERROR_DCD_FAILED );
 
-      p_hid->report_len = desc_hid->wReportLength;
-      p_hid->itf_num    = desc_itf->bInterfaceNumber;
-      p_hid->ep_in      = desc_edpt->bEndpointAddress;
-      p_hid->report_id  = 0;
+      p_hid->boot_protocol = true; // default to boot mode when mounted
+      p_hid->report_len    = desc_hid->wReportLength;
+      p_hid->itf_num       = desc_itf->bInterfaceNumber;
+      p_hid->ep_in         = desc_edpt->bEndpointAddress;
+      p_hid->report_id     = 0;
 
       *p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t);
     }
@@ -402,12 +417,15 @@ tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t cons
     }
     else if (HID_REQ_CONTROL_GET_PROTOCOL == p_request->bRequest )
     {
-      _usbd_ctrl_buf[0] = 1 - CFG_TUD_HID_BOOT_PROTOCOL; // 0 is Boot, 1 is Report protocol
+      _usbd_ctrl_buf[0] = 1-p_hid->boot_protocol;   // 0 is Boot, 1 is Report protocol
       usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, 1);
     }
-    else
+    else if (HID_REQ_CONTROL_SET_PROTOCOL == p_request->bRequest )
+    {
+      p_hid->boot_protocol = 1 - p_request->wValue; // 0 is Boot, 1 is Report protocol
+      dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+    }else
     {
-//      HID_REQ_CONTROL_SET_PROTOCOL:
       dcd_control_stall(rhport);
     }
   }else

+ 10 - 5
src/class/hid/hid_device.h

@@ -61,6 +61,7 @@
  * \note    Application must not perform any action if the interface is not ready
  */
 bool tud_hid_keyboard_ready(void);
+bool tud_hid_keyboard_is_boot_protocol(void);
 
 bool tud_hid_keyboard_keycode(uint8_t modifier, uint8_t keycode[6]);
 
@@ -77,10 +78,9 @@ typedef struct{
 extern const hid_ascii_to_keycode_entry_t HID_ASCII_TO_KEYCODE[128];
 #endif
 
-/*------------- Callbacks -------------*/
+/*------------- Callbacks, ATTR_WEAK means optional -------------*/
 
-/** \brief      Callback function that is invoked when USB host request \ref HID_REQUEST_CONTROL_GET_REPORT
- *              via control endpoint.
+/** Callback invoked when USB host request \ref HID_REQ_CONTROL_GET_REPORT.
  * \param[in]   report_type specify which report (INPUT, OUTPUT, FEATURE) that host requests
  * \param[out]  buffer data that application need to update, value must be accessible by USB controller (see \ref CFG_TUSB_ATTR_USBRAM)
  * \param[in]   reqlen  number of bytes that host requested
@@ -93,8 +93,7 @@ extern const hid_ascii_to_keycode_entry_t HID_ASCII_TO_KEYCODE[128];
  */
 ATTR_WEAK uint16_t tud_hid_keyboard_get_report_cb(hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
 
-/** \brief      Callback function that is invoked when USB host request \ref HID_REQUEST_CONTROL_SET_REPORT
- *              via control endpoint.
+/** Callback invoked when USB host request \ref HID_REQ_CONTROL_SET_REPORT.
  * \param[in]   report_type specify which report (INPUT, OUTPUT, FEATURE) that host requests
  * \param[in]   buffer  containing the report's data
  * \param[in]   bufsize  number of bytes in the \a buffer
@@ -103,6 +102,9 @@ ATTR_WEAK uint16_t tud_hid_keyboard_get_report_cb(hid_report_type_t report_type,
  */
 ATTR_WEAK void tud_hid_keyboard_set_report_cb(hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
 
+
+//ATTR_WEAK void tud_hid_keyboard_set_protocol_cb(bool boot_protocol);
+
 /** @} */
 /** @} */
 
@@ -120,6 +122,7 @@ ATTR_WEAK void tud_hid_keyboard_set_report_cb(hid_report_type_t report_type, uin
  * \note        This function is primarily used for polling/waiting result after \ref tusbd_hid_mouse_send.
  */
 bool tud_hid_mouse_ready(void);
+bool tud_hid_mouse_is_boot_protocol(void);
 
 bool tud_hid_mouse_data(uint8_t buttons, int8_t x, int8_t y, int8_t scroll, int8_t pan);
 
@@ -161,6 +164,8 @@ ATTR_WEAK uint16_t tud_hid_mouse_get_report_cb(hid_report_type_t report_type, ui
  */
 ATTR_WEAK void tud_hid_mouse_set_report_cb(hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
 
+//ATTR_WEAK void tud_hid_mouse_set_protocol_cb(bool boot_protocol);
+
 /** @} */
 /** @} */