Просмотр исходного кода

update device freeRTOS exmaple

hathach 7 лет назад
Родитель
Сommit
3e4bb141ce

+ 17 - 11
examples/device/cdc_msc_hid/src/main.c

@@ -40,12 +40,18 @@
  * - 1000 ms : device mounted
  * - 2500 ms : device is suspended
  */
-static uint32_t blink_interval_ms = 250;
+enum  {
+  BLINK_NOT_MOUNTED = 250,
+  BLINK_MOUNTED = 1000,
+  BLINK_SUSPENDED = 2500,
+};
+
+static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
 
 void led_blinking_task(void);
 
-extern void virtual_com_task(void);
-extern void usb_hid_task(void);
+extern void cdc_task(void);
+extern void hid_task(void);
 
 /*------------- MAIN -------------*/
 int main(void)
@@ -62,11 +68,11 @@ int main(void)
     led_blinking_task();
 
 #if CFG_TUD_CDC
-    virtual_com_task();
+    cdc_task();
 #endif
 
 #if CFG_TUD_HID
-    usb_hid_task();
+    hid_task();
 #endif
   }
 
@@ -77,7 +83,7 @@ int main(void)
 // USB CDC
 //--------------------------------------------------------------------+
 #if CFG_TUD_CDC
-void virtual_com_task(void)
+void cdc_task(void)
 {
   if ( tud_cdc_connected() )
   {
@@ -134,7 +140,7 @@ enum
   REPORT_ID_MOUSE
 };
 
-void usb_hid_task(void)
+void hid_task(void)
 {
   // Poll every 10ms
   const uint32_t interval_ms = 10;
@@ -218,13 +224,13 @@ void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uin
 // Invoked when device is mounted
 void tud_mount_cb(void)
 {
-  blink_interval_ms = 1000;
+  blink_interval_ms = BLINK_MOUNTED;
 }
 
 // Invoked when device is unmounted
 void tud_umount_cb(void)
 {
-  blink_interval_ms = 250;
+  blink_interval_ms = BLINK_NOT_MOUNTED;
 }
 
 // Invoked when usb bus is suspended
@@ -233,13 +239,13 @@ void tud_umount_cb(void)
 void tud_suspend_cb(bool remote_wakeup_en)
 {
   (void) remote_wakeup_en;
-  blink_interval_ms = 2500;
+  blink_interval_ms = BLINK_SUSPENDED;
 }
 
 // Invoked when usb bus is resumed
 void tud_resume_cb(void)
 {
-  blink_interval_ms = 1000;
+  blink_interval_ms = BLINK_MOUNTED;
 }
 
 //--------------------------------------------------------------------+

+ 3 - 2
examples/device/cdc_msc_hid/src/tusb_config.h

@@ -46,8 +46,8 @@
 #define CFG_TUSB_RHPORT0_MODE       OPT_MODE_DEVICE
 #endif
 
-#define CFG_TUSB_DEBUG              2
 #define CFG_TUSB_OS                 OPT_OS_NONE
+#define CFG_TUSB_DEBUG              2
 
 /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
  * Tinyusb use follows macros to declare transferring memory so that they can be put
@@ -67,6 +67,7 @@
 //--------------------------------------------------------------------
 // DEVICE CONFIGURATION
 //--------------------------------------------------------------------
+
 #define CFG_TUD_ENDOINT0_SIZE       64
 
 //------------- CLASS -------------//
@@ -88,6 +89,7 @@
 //--------------------------------------------------------------------
 // MSC
 //--------------------------------------------------------------------
+
 // Number of supported Logical Unit Number (At least 1)
 #define CFG_TUD_MSC_MAXLUN          1
 
@@ -113,7 +115,6 @@
  */
 #define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 1
 
-
 #ifdef __cplusplus
  }
 #endif

+ 1 - 1
examples/device/cdc_msc_hid_freertos/ses/nrf5x/nrf5x.emProject

@@ -20,7 +20,7 @@
       arm_target_interface_type="SWD"
       build_treat_warnings_as_errors="No"
       c_preprocessor_definitions="NRF52840_XXAA;__nRF_FAMILY;ARM_MATH_CM4;FLASH_PLACEMENT=1;CFG_TUSB_MCU=OPT_MCU_NRF5X"
-      c_user_include_directories="./;../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(nrfxDir)/..;$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include;$(freertosDir)/Source/include;$(freertosDir)/Source/portable/GCC/ARM_CM4F"
+      c_user_include_directories="./;../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(nrfxDir)/..;$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include;$(nrfxDir)/drivers/src;$(freertosDir)/Source/include;$(freertosDir)/Source/portable/GCC/ARM_CM4F"
       debug_register_definition_file="nrf52840_Registers.xml"
       debug_target_connection="J-Link"
       gcc_enable_all_warnings="Yes"

+ 101 - 43
examples/device/cdc_msc_hid_freertos/src/main.c

@@ -24,9 +24,6 @@
  * This file is part of the TinyUSB stack.
  */
 
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -41,12 +38,22 @@
 #include "tusb.h"
 
 //--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
+// MACRO CONSTANT TYPEDEF PROTYPES
 //--------------------------------------------------------------------+
 
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
+/* Blink pattern
+ * - 250 ms  : device not mounted
+ * - 1000 ms : device mounted
+ * - 2500 ms : device is suspended
+ */
+enum  {
+  BLINK_NOT_MOUNTED = 250,
+  BLINK_MOUNTED = 1000,
+  BLINK_SUSPENDED = 2500,
+};
+
+TimerHandle_t blink_tm;
+
 void led_blinky_cb(TimerHandle_t xTimer);
 void usb_device_task(void* param);
 
@@ -56,8 +63,8 @@ int main(void)
   board_init();
 
   // soft timer for blinky
-  TimerHandle_t tm_hdl = xTimerCreate(NULL, pdMS_TO_TICKS(1000), true, NULL, led_blinky_cb);
-  xTimerStart(tm_hdl, 0);
+  blink_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
+  xTimerStart(blink_tm, 0);
 
   tusb_init();
 
@@ -71,7 +78,8 @@ int main(void)
 #endif
 
 #if CFG_TUD_HID
-  extern void usb_hid_task(void* params);
+  extern void hid_task(void* params);
+  xTaskCreate( hid_task, "hid", 256, NULL, configMAX_PRIORITIES-2, NULL);
 #endif
 
   vTaskStartScheduler();
@@ -130,6 +138,7 @@ void cdc_task(void* params)
   }
 }
 
+// Invoked when cdc when line state changed e.g connected/disconnected
 void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
 {
   (void) itf;
@@ -141,85 +150,134 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
     tud_cdc_write_str("\r\nTinyUSB CDC MSC HID device with FreeRTOS example\r\n");
   }
 }
+
+// Invoked when CDC interface received data from host
+void tud_cdc_rx_cb(uint8_t itf)
+{
+  (void) itf;
+}
+
 #endif
 
 //--------------------------------------------------------------------+
 // USB HID
 //--------------------------------------------------------------------+
 #if CFG_TUD_HID
-void usb_hid_task(void* params)
+
+// Must match with ID declared by HID Report Descriptor, better to be in header file
+enum
 {
-  (void) params;
+  REPORT_ID_KEYBOARD = 1,
+  REPORT_ID_MOUSE
+};
 
-  // Poll every 10ms
-  const uint32_t interval_ms = 10;
-  static uint32_t start_ms = 0;
+void hid_task(void* params)
+{
+  (void) params;
 
-  if ( board_millis() < start_ms + interval_ms) return; // not enough time
-  start_ms += interval_ms;
+  while (1)
+  {
+    // Poll every 10ms
+    vTaskDelay(pdMS_TO_TICKS(10));
 
-  uint32_t const btn = board_button_read();
+    uint32_t const btn = board_button_read();
 
-  /*------------- Keyboard -------------*/
-  if ( tud_hid_keyboard_ready() )
-  {
-    if ( btn )
+    // Remote wakeup
+    if ( tud_suspended() && btn )
     {
-      uint8_t keycode[6] = { 0 };
+      // Wake up host if we are in suspend mode
+      // and REMOTE_WAKEUP feature is enabled by host
+      tud_remote_wakeup();
+    }
 
-      for(uint8_t i=0; i < 6; i++)
+    /*------------- Mouse -------------*/
+    if ( tud_hid_ready() )
+    {
+      if ( btn )
       {
-        if ( btn & (1 << i) ) keycode[i] = HID_KEY_A + i;
+        int8_t const delta = 5;
+        tud_hid_mouse_move(REPORT_ID_MOUSE, delta, delta); // right + down
+
+        // delay a bit before attempt to send keyboard report
+        vTaskDelay(pdMS_TO_TICKS(2));
       }
+    }
 
-      tud_hid_keyboard_report(0, keycode);
-    }else
+    /*------------- Keyboard -------------*/
+    if ( tud_hid_ready() )
     {
-      // Null means all zeroes keycodes
-      tud_hid_keyboard_report(0, NULL);
-    }
-  }
+      // use to avoid send multiple consecutive zero report for keyboard
+      static bool has_key = false;
 
+      if ( btn )
+      {
+        uint8_t keycode[6] = { 0 };
+        keycode[0] = HID_KEY_A;
 
-  /*------------- Mouse -------------*/
-  if ( tud_hid_mouse_ready() )
-  {
-    enum { DELTA  = 5 };
+        tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
 
-    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
+        has_key = true;
+      }else
+      {
+        // send empty key report if previously has key pressed
+        if (has_key) tud_hid_keyboard_key_release(REPORT_ID_KEYBOARD);
+        has_key = false;
+      }
+    }
   }
 }
 
 uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
 {
   // TODO not Implemented
+  (void) report_id;
+  (void) report_type;
+  (void) buffer;
+  (void) reqlen;
+
   return 0;
 }
 
 void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
 {
   // TODO not Implemented
+  (void) report_id;
+  (void) report_type;
+  (void) buffer;
+  (void) bufsize;
 }
+
 #endif
 
 //--------------------------------------------------------------------+
-// tinyusb callbacks
+// Device callbacks
 //--------------------------------------------------------------------+
+
+// Invoked when device is mounted
 void tud_mount_cb(void)
 {
-
+  xTimerChangePeriod(blink_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
 }
 
+// Invoked when device is unmounted
 void tud_umount_cb(void)
 {
+  xTimerChangePeriod(blink_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0);
 }
 
-void tud_cdc_rx_cb(uint8_t itf)
+// Invoked when usb bus is suspended
+// remote_wakeup_en : if host allow us  to perform remote wakeup
+// Within 7ms, device must draw an average of current less than 2.5 mA from bus
+void tud_suspend_cb(bool remote_wakeup_en)
 {
-  (void) itf;
+  (void) remote_wakeup_en;
+  xTimerChangePeriod(blink_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0);
+}
+
+// Invoked when usb bus is resumed
+void tud_resume_cb(void)
+{
+  xTimerChangePeriod(blink_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
 }
 
 //--------------------------------------------------------------------+

+ 0 - 104
examples/device/cdc_msc_hid_freertos/src/msc_app.c

@@ -1,104 +0,0 @@
-/* 
- * The MIT License (MIT)
- *
- * Copyright (c) 2018, hathach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * This file is part of the TinyUSB stack.
- */
-
-#include "bsp/board.h"
-#include "tusb.h"
-
-#if CFG_TUD_MSC
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-
-//--------------------------------------------------------------------+
-// tinyusb callbacks
-//--------------------------------------------------------------------+
-
-// Callback invoked when received an SCSI command not in built-in list below
-// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
-// - READ10 and WRITE10 has their own callbacks
-int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
-{
-  // read10 & write10 has their own callback and MUST not be handled here
-
-  void const* response = NULL;
-  uint16_t resplen = 0;
-
-  // most scsi handled is input
-  bool in_xfer = true;
-
-  switch (scsi_cmd[0])
-  {
-    case SCSI_CMD_TEST_UNIT_READY:
-      // Command that host uses to check our readiness before sending other commands
-      resplen = 0;
-    break;
-
-    case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
-      // Host is about to read/write etc ... better not to disconnect disk
-      resplen = 0;
-    break;
-
-    case SCSI_CMD_START_STOP_UNIT:
-      // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
-      /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
-        // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
-        // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
-        start_stop->start;
-        start_stop->load_eject;
-       */
-       resplen = 0;
-    break;
-
-
-    default:
-      // Set Sense = Invalid Command Operation
-      tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
-
-      // negative means error -> tinyusb could stall and/or response with failed status
-      resplen = -1;
-    break;
-  }
-
-  // return resplen must not larger than bufsize
-  if ( resplen > bufsize ) resplen = bufsize;
-
-  if ( response && (resplen > 0) )
-  {
-    if(in_xfer)
-    {
-      memcpy(buffer, response, resplen);
-    }else
-    {
-      // SCSI output
-    }
-  }
-
-  return resplen;
-}
-
-
-#endif

+ 68 - 3
examples/device/cdc_msc_hid_freertos/src/msc_disk_ram.c → examples/device/cdc_msc_hid_freertos/src/msc_disk.c

@@ -49,7 +49,7 @@ enum
 #ifdef DISK_READONLY
 const
 #endif
-static uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
+uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
 {
   //------------- Boot Sector -------------//
   // byte_per_sector    = DISK_BLOCK_SIZE; fat12_sector_num_16  = DISK_BLOCK_NUM;
@@ -82,7 +82,7 @@ static uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
       // second entry is readme file
       'R' , 'E' , 'A' , 'D' , 'M' , 'E' , ' ' , ' ' , 'T' , 'X' , 'T' , 0x20, 0x00, 0xC6, 0x52, 0x6D,
       0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00,
-      sizeof(README_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's filesize (4 Bytes)
+      sizeof(README_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's files ize (4 Bytes)
   },
 
   //------------- Readme Content -------------//
@@ -96,7 +96,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff
 {
   (void) lun;
 
-  uint8_t* addr = msc_disk[lba] + offset;
+  uint8_t const* addr = msc_disk[lba] + offset;
   memcpy(buffer, addr, bufsize);
 
   return bufsize;
@@ -111,6 +111,8 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
 #ifndef DISK_READONLY
   uint8_t* addr = msc_disk[lba] + offset;
   memcpy(addr, buffer, bufsize);
+#else
+  (void) lba; (void) offset; (void) buffer;
 #endif
 
   return bufsize;
@@ -124,4 +126,67 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz
   *block_size  = DISK_BLOCK_SIZE;
 }
 
+// Callback invoked when received an SCSI command not in built-in list below
+// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
+// - READ10 and WRITE10 has their own callbacks
+int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
+{
+  // read10 & write10 has their own callback and MUST not be handled here
+
+  void const* response = NULL;
+  uint16_t resplen = 0;
+
+  // most scsi handled is input
+  bool in_xfer = true;
+
+  switch (scsi_cmd[0])
+  {
+    case SCSI_CMD_TEST_UNIT_READY:
+      // Command that host uses to check our readiness before sending other commands
+      resplen = 0;
+    break;
+
+    case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
+      // Host is about to read/write etc ... better not to disconnect disk
+      resplen = 0;
+    break;
+
+    case SCSI_CMD_START_STOP_UNIT:
+      // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
+      /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
+        // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
+        // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
+        start_stop->start;
+        start_stop->load_eject;
+       */
+       resplen = 0;
+    break;
+
+
+    default:
+      // Set Sense = Invalid Command Operation
+      tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
+
+      // negative means error -> tinyusb could stall and/or response with failed status
+      resplen = -1;
+    break;
+  }
+
+  // return resplen must not larger than bufsize
+  if ( resplen > bufsize ) resplen = bufsize;
+
+  if ( response && (resplen > 0) )
+  {
+    if(in_xfer)
+    {
+      memcpy(buffer, response, resplen);
+    }else
+    {
+      // SCSI output
+    }
+  }
+
+  return resplen;
+}
+
 #endif

+ 10 - 33
examples/device/cdc_msc_hid_freertos/src/tusb_config.h

@@ -40,7 +40,12 @@
   #error CFG_TUSB_MCU must be defined
 #endif
 
+#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX
+#define CFG_TUSB_RHPORT0_MODE       (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
+#else
 #define CFG_TUSB_RHPORT0_MODE       OPT_MODE_DEVICE
+#endif
+
 #define CFG_TUSB_OS                 OPT_OS_FREERTOS
 #define CFG_TUSB_DEBUG              2
 
@@ -65,40 +70,13 @@
 
 #define CFG_TUD_ENDOINT0_SIZE       64
 
-/*------------- Descriptors -------------*/
-
-/* Enable auto generated descriptor, tinyusb will try its best to create
- * descriptor ( device, configuration, hid ) that matches enabled CFG_* in this file
- *
- * Note: All CFG_TUD_DESC_* are relevant only if CFG_TUD_DESC_AUTO is enabled
- */
-#define CFG_TUD_DESC_AUTO           1
-
-// LPC175x_6x's endpoint type (bulk/interrupt/iso) are fixed by its number
-// Therefore we need to force endpoint number to correct type on lpc17xx
-#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X
-#define CFG_TUD_DESC_CDC_EPNUM_NOTIF      1
-#define CFG_TUD_DESC_CDC_EPNUM            2
-#define CFG_TUD_DESC_MSC_EPNUM            5
-#define CFG_TUD_DESC_HID_KEYBOARD_EPNUM   4
-#define CFG_TUD_DESC_HID_MOUSE_EPNUM      7
-#endif
-
-
 //------------- CLASS -------------//
 #define CFG_TUD_CDC                 1
 #define CFG_TUD_MSC                 1
+#define CFG_TUD_HID                 1
 
-#define CFG_TUD_HID                 0
-#define CFG_TUD_HID_KEYBOARD        0
-#define CFG_TUD_HID_MOUSE           0
-
-/* Use Boot Protocol for Keyboard, Mouse. Enable this will create separated HID interface
- * require more IN endpoints. If disabled, they they are all packed into a single
- * multiple report interface called "Generic". */
-#define CFG_TUD_HID_KEYBOARD_BOOT   1
-#define CFG_TUD_HID_MOUSE_BOOT      1
-
+#define CFG_TUD_MIDI                0
+#define CFG_TUD_CUSTOM_CLASS        0
 
 //--------------------------------------------------------------------
 // CDC
@@ -131,10 +109,9 @@
 // HID
 //--------------------------------------------------------------------
 
-/* Use the HID_ASCII_TO_KEYCODE lookup if CFG_TUD_HID_KEYBOARD is enabled.
- * This will occupies 256 bytes of ROM. It will also enable the use of 2 extra APIs
+/* Use the HID_ASCII_TO_KEYCODE lookup
+ * This will occupies 256 bytes of ROM. It will also enable the use of extra APIs
  * - tud_hid_keyboard_send_char()
- * - tud_hid_keyboard_send_string()
  */
 #define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 1
 

+ 81 - 40
examples/device/cdc_msc_hid_freertos/src/tusb_descriptors.c → examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c

@@ -26,19 +26,14 @@
 
 #include "tusb.h"
 
-// If HID Generic interface is generated
-#define AUTO_DESC_HID_GENERIC    (CFG_TUD_HID && ((CFG_TUD_HID_KEYBOARD && !CFG_TUD_HID_KEYBOARD_BOOT) || \
-                                                (CFG_TUD_HID_MOUSE && !CFG_TUD_HID_MOUSE_BOOT)) )
-
 /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
  * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
  *
  * Auto ProductID layout's Bitmap:
- *   [MSB]         HID Generic | Boot Mouse | Boot Keyboard | MSC | CDC          [LSB]
+ *   [MSB]         HID | MSC | CDC          [LSB]
  */
-#define _PID_MAP(itf, n)      ( (CFG_TUD_##itf) << (n) )
-#define CFG_TUD_DESC_PID      (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | \
-                               _PID_MAP(HID_KEYBOARD, 2) | _PID_MAP(HID_MOUSE, 3) | (AUTO_DESC_HID_GENERIC << 4) )
+#define _PID_MAP(itf, n)  ( (CFG_TUD_##itf) << (n) )
+#define USB_PID           (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) )
 
 //------------- Device Descriptors -------------//
 tusb_desc_device_t const desc_device =
@@ -62,7 +57,7 @@ tusb_desc_device_t const desc_device =
     .bMaxPacketSize0    = CFG_TUD_ENDOINT0_SIZE,
 
     .idVendor           = 0xCafe,
-    .idProduct          = CFG_TUD_DESC_PID,
+    .idProduct          = USB_PID,
     .bcdDevice          = 0x0100,
 
     .iManufacturer      = 0x01,
@@ -72,59 +67,105 @@ tusb_desc_device_t const desc_device =
     .bNumConfigurations = 0x01
 };
 
-//------------- String Descriptors -------------//
-// array of pointer to string descriptors
-uint16_t const * const string_desc_arr [] =
+//------------- HID Report Descriptor -------------//
+enum
 {
-    // 0: is supported language = English
-    TUD_DESC_STRCONV(0x0409),
+  REPORT_ID_KEYBOARD = 1,
+  REPORT_ID_MOUSE
+};
+
+uint8_t const desc_hid_report[] =
+{
+  HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ),
+  HID_REPORT_DESC_MOUSE   ( HID_REPORT_ID(REPORT_ID_MOUSE), )
+};
+
+//------------- Configuration Descriptor -------------//
+enum
+{
+  #if CFG_TUD_CDC
+    ITF_NUM_CDC = 0,
+    ITF_NUM_CDC_DATA,
+  #endif
+
+  #if CFG_TUD_MSC
+    ITF_NUM_MSC,
+  #endif
+
+  #if CFG_TUD_HID
+    ITF_NUM_HID,
+  #endif
+
+    ITF_NUM_TOTAL
+};
 
-    // 1: Manufacturer
-    TUD_DESC_STRCONV('t', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g'),
+enum
+{
+  CONFIG_DESC_LEN = sizeof(tusb_desc_configuration_t) + CFG_TUD_CDC*TUD_CDC_DESC_LEN + CFG_TUD_MSC*TUD_MSC_DESC_LEN + CFG_TUD_HID*TUD_HID_DESC_LEN
+};
 
-    // 2: Product
-    TUD_DESC_STRCONV('t', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'd', 'e', 'v', 'i', 'c', 'e'),
+#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
+  // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
+  // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
+  // Note: since CDC EP ( 1 & 2), HID (4) are spot-on, thus we only need to force
+  // endpoint number for MSC to 5
+  #define EPNUM_MSC   0x05
+#else
+  #define EPNUM_MSC   0x03
+#endif
 
-    // 3: Serials, should use chip ID
-    TUD_DESC_STRCONV('1', '2', '3', '4', '5', '6'),
+uint8_t const desc_configuration[] =
+{
+  // Config: self-powered with remote wakeup support, max power up to 100 mA
+  TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
 
 #if CFG_TUD_CDC
-    // 4: CDC Interface
-    TUD_DESC_STRCONV('t','u','s','b',' ','c','d','c'),
+  TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64),
 #endif
 
 #if CFG_TUD_MSC
-    // 5: MSC Interface
-    TUD_DESC_STRCONV('t','u','s','b',' ','m','s','c'),
+  TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512
 #endif
 
-#if CFG_TUD_HID_KEYBOARD
-    // 6: Keyboard
-    TUD_DESC_STRCONV('t','u','s','b',' ','k','e','y','b','o','a','r','d'),
+#if CFG_TUD_HID
+  TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), 0x84, 16, 10)
 #endif
+};
 
-#if CFG_TUD_HID_MOUSE
-    // 7: Mouse
-    TUD_DESC_STRCONV('t','u','s','b',' ','m', 'o','u','s','e'),
-#endif
+//------------- String Descriptors -------------//
+// array of pointer to string descriptors
+uint16_t const * const string_desc_arr [] =
+{
+  // 0: is supported language = English
+  TUD_DESC_STRCONV(0x0409),
+
+  // 1: Manufacturer
+  TUD_DESC_STRCONV('t', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g'),
+
+  // 2: Product
+  TUD_DESC_STRCONV('t', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'd', 'e', 'v', 'i', 'c', 'e'),
 
+  // 3: Serials, should use chip ID
+  TUD_DESC_STRCONV('1', '2', '3', '4', '5', '6'),
+
+  // 4: CDC Interface
+  TUD_DESC_STRCONV('t','u','s','b',' ','c','d','c'),
+
+  // 5: MSC Interface
+  TUD_DESC_STRCONV('t','u','s','b',' ','m','s','c'),
+
+  // 6: HID
+  TUD_DESC_STRCONV('t','u','s','b',' ','h','i','d')
 };
 
 // tud_desc_set is required by tinyusb stack
-// since CFG_TUD_DESC_AUTO is enabled, we only need to set string_arr 
 tud_desc_set_t tud_desc_set =
 {
     .device     = &desc_device,
-    .config     = NULL,
+    .config     = desc_configuration,
 
     .string_arr   = (uint8_t const **) string_desc_arr,
     .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]),
 
-    .hid_report =
-    {
-        .generic       = NULL,
-        .boot_keyboard = NULL,
-        .boot_mouse    = NULL
-    }
+    .hid_report = desc_hid_report,
 };
-

+ 6 - 6
examples/host/cdc_msc_hid/src/main.c

@@ -37,8 +37,8 @@
 void print_greeting(void);
 void led_blinking_task(void);
 
-extern void virtual_com_task(void);
-extern void usb_hid_task(void);
+extern void cdc_task(void);
+extern void hid_task(void);
 
 /*------------- MAIN -------------*/
 int main(void)
@@ -56,11 +56,11 @@ int main(void)
     led_blinking_task();
 
 #if CFG_TUH_CDC
-    virtual_com_task();
+    cdc_task();
 #endif
 
 #if CFG_TUD_HID
-    usb_hid_task();
+    hid_task();
 #endif
   }
 
@@ -100,7 +100,7 @@ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_i
   tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // waiting for next data
 }
 
-void virtual_com_task(void)
+void cdc_task(void)
 {
 
 }
@@ -111,7 +111,7 @@ void virtual_com_task(void)
 // USB HID
 //--------------------------------------------------------------------+
 #if CFG_TUH_HID_KEYBOARD
-void usb_hid_task(void)
+void hid_task(void)
 {
 
 }