From eab4f9642c27749a3232f09857079a9c9ab7aeb9 Mon Sep 17 00:00:00 2001
From: hathach <thach@tinyusb.org>
Date: Tue, 18 Mar 2014 18:07:48 +0700
Subject: [PATCH] refractor descriptor passing for device with user-friendly
 structures

---
 demos/device/src/tusb_descriptors.c | 50 ++++++++++++++++++++++-------
 demos/device/src/tusb_descriptors.h |  5 ---
 tinyusb/device/usbd.c               | 15 +++++----
 tinyusb/device/usbd.h               | 31 ++++++++++++------
 4 files changed, 69 insertions(+), 32 deletions(-)

diff --git a/demos/device/src/tusb_descriptors.c b/demos/device/src/tusb_descriptors.c
index 89d5d1fa5..666f1202e 100644
--- a/demos/device/src/tusb_descriptors.c
+++ b/demos/device/src/tusb_descriptors.c
@@ -38,6 +38,9 @@
 
 #include "tusb_descriptors.h"
 
+//--------------------------------------------------------------------+
+// Keyboard Report Descriptor
+//--------------------------------------------------------------------+
 #if TUSB_CFG_DEVICE_HID_KEYBOARD
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
 uint8_t tusbd_hid_keyboard_descriptor_report[] = {
@@ -82,6 +85,9 @@ uint8_t tusbd_hid_keyboard_descriptor_report[] = {
 };
 #endif
 
+//--------------------------------------------------------------------+
+// Mouse Report Descriptor
+//--------------------------------------------------------------------+
 #if TUSB_CFG_DEVICE_HID_MOUSE
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
 uint8_t tusbd_hid_mouse_descriptor_report[] = {
@@ -128,8 +134,11 @@ uint8_t tusbd_hid_mouse_descriptor_report[] = {
 };
 #endif
 
+//--------------------------------------------------------------------+
+// USB DEVICE DESCRIPTOR
+//--------------------------------------------------------------------+
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-tusb_descriptor_device_t tusbd_descriptor_device =
+tusb_descriptor_device_t desc_device =
 {
     .bLength            = sizeof(tusb_descriptor_device_t),
     .bDescriptorType    = TUSB_DESC_TYPE_DEVICE,
@@ -159,8 +168,11 @@ tusb_descriptor_device_t tusbd_descriptor_device =
     .bNumConfigurations = 0x01 // TODO multiple configurations
 };
 
+//--------------------------------------------------------------------+
+// USB COFNIGURATION DESCRIPTOR
+//--------------------------------------------------------------------+
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-app_descriptor_configuration_t tusbd_descriptor_configuration =
+app_descriptor_configuration_t desc_configuration =
 {
     .configuration =
     {
@@ -399,37 +411,53 @@ app_descriptor_configuration_t tusbd_descriptor_configuration =
 #define ENDIAN_BE16_FROM( high, low) ENDIAN_BE16(high << 8 | low)
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-uint16_t desc_str_language[] =
+uint16_t desc_string_language[] =
 {
     ENDIAN_BE16_FROM( STRING_LEN_UNICODE(1), TUSB_DESC_TYPE_STRING ),
     0x0409
 };
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-uint16_t desc_str_manufacturer[] =
+uint16_t desc_string_manufacturer[] =
 {
     ENDIAN_BE16_FROM( STRING_LEN_UNICODE(11), TUSB_DESC_TYPE_STRING),
     't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g' // len = 11
 };
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-uint16_t desc_str_product[] =
+uint16_t desc_string_product[] =
 {
     ENDIAN_BE16_FROM( STRING_LEN_UNICODE(14), TUSB_DESC_TYPE_STRING),
     't', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'D', 'e', 'v', 'i', 'c', 'e' // len = 14
 };
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-uint16_t desc_str_serial[] =
+uint16_t desc_string_serial[] =
 {
     ENDIAN_BE16_FROM( STRING_LEN_UNICODE(4), TUSB_DESC_TYPE_STRING),
     '1', '2', '3', '4' // len = 4
 };
 
-uint8_t* const tusbd_descriptor_string_table [TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT] =
+//--------------------------------------------------------------------+
+// TINYUSB Descriptors Pointer (this variable is required by the stack)
+//--------------------------------------------------------------------+
+tusbd_descriptor_pointer_t tusbd_descriptor_pointers =
 {
-    (uint8_t*) desc_str_language,
-    (uint8_t*) desc_str_manufacturer,
-    (uint8_t*) desc_str_product,
-    (uint8_t*) desc_str_serial
+    .p_device        = (uint8_t*) &desc_device,
+    .p_configuration = (uint8_t*) &desc_configuration,
+    .p_string_arr    =
+    {   // up to TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT (including language - index=0)
+        (uint8_t*) desc_string_language,
+        (uint8_t*) desc_string_manufacturer,
+        (uint8_t*) desc_string_product,
+        (uint8_t*) desc_string_serial
+    },
+
+    #if TUSB_CFG_DEVICE_HID_KEYBOARD
+    .p_hid_keyboard_report = tusbd_hid_keyboard_descriptor_report,
+    #endif
+
+    #if TUSB_CFG_DEVICE_HID_KEYBOARD
+    .p_hid_mouse_report    = tusbd_hid_mouse_descriptor_report,
+    #endif
 };
diff --git a/demos/device/src/tusb_descriptors.h b/demos/device/src/tusb_descriptors.h
index ee763f9a6..d81a0f51b 100644
--- a/demos/device/src/tusb_descriptors.h
+++ b/demos/device/src/tusb_descriptors.h
@@ -179,11 +179,6 @@ typedef ATTR_PACKED_STRUCT(struct)
 //--------------------------------------------------------------------+
 // Export descriptors
 //--------------------------------------------------------------------+
-extern tusb_descriptor_device_t tusbd_descriptor_device;
-extern app_descriptor_configuration_t tusbd_descriptor_configuration;
-
-extern uint8_t * const tusbd_descriptor_string_table[TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT];
-
 extern uint8_t tusbd_hid_keyboard_descriptor_report[];
 extern uint8_t tusbd_hid_mouse_descriptor_report[];
 
diff --git a/tinyusb/device/usbd.c b/tinyusb/device/usbd.c
index f265b51d2..3e780b390 100644
--- a/tinyusb/device/usbd.c
+++ b/tinyusb/device/usbd.c
@@ -46,7 +46,6 @@
 // INCLUDE
 //--------------------------------------------------------------------+
 #include "tusb.h"
-#include "tusb_descriptors.h" // TODO callback include
 #include "usbd_dcd.h"
 
 //--------------------------------------------------------------------+
@@ -270,6 +269,10 @@ tusb_error_t usbd_init (void)
 
   ASSERT_STATUS( osal_task_create( OSAL_TASK_REF(usbd_task) ));
 
+  //------------- Descriptor Check -------------//
+  ASSERT_PTR(tusbd_descriptor_pointers.p_device, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
+  ASSERT_PTR(tusbd_descriptor_pointers.p_configuration, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
+
   //------------- class init -------------//
   for (uint8_t class_code = TUSB_CLASS_AUDIO; class_code < USBD_CLASS_DRIVER_COUNT; class_code++)
   {
@@ -293,7 +296,7 @@ static tusb_error_t usbd_set_configure_received(uint8_t coreid, uint8_t config_n
   usbd_devices[coreid].state = TUSB_DEVICE_STATE_CONFIGURED;
 
   //------------- parse configuration & open drivers -------------//
-  uint8_t* p_desc_configure = (uint8_t*) &tusbd_descriptor_configuration;
+  uint8_t* p_desc_configure = tusbd_descriptor_pointers.p_configuration;
   uint8_t* p_desc = p_desc_configure + sizeof(tusb_descriptor_configuration_t);
 
   while( p_desc < p_desc_configure + ((tusb_descriptor_configuration_t*)p_desc_configure)->wTotalLength )
@@ -333,19 +336,19 @@ static tusb_error_t get_descriptor(uint8_t coreid, tusb_control_request_t const
 
   if ( TUSB_DESC_TYPE_DEVICE == desc_type )
   {
-    (*pp_buffer) = (uint8_t *) &tusbd_descriptor_device;
+    (*pp_buffer) = tusbd_descriptor_pointers.p_device;
     (*p_length)  = sizeof(tusb_descriptor_device_t);
   }
   else if ( TUSB_DESC_TYPE_CONFIGURATION == desc_type )
   {
-    (*pp_buffer) = (uint8_t *) &tusbd_descriptor_configuration;
-    (*p_length)  = sizeof(tusbd_descriptor_configuration);
+    (*pp_buffer) = tusbd_descriptor_pointers.p_configuration;
+    (*p_length)  = ((tusb_descriptor_configuration_t*)tusbd_descriptor_pointers.p_configuration)->wTotalLength;
   }
   else if ( TUSB_DESC_TYPE_STRING == desc_type )
   {
     if ( ! (desc_index < TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT) ) return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
 
-    (*pp_buffer) = (uint8_t *) tusbd_descriptor_string_table[desc_index];
+    (*pp_buffer) = tusbd_descriptor_pointers.p_string_arr[desc_index];
     (*p_length)  = **pp_buffer;
   }else
   {
diff --git a/tinyusb/device/usbd.h b/tinyusb/device/usbd.h
index 9a7be465c..684d2fbed 100644
--- a/tinyusb/device/usbd.h
+++ b/tinyusb/device/usbd.h
@@ -43,17 +43,19 @@
 #ifndef _TUSB_USBD_H_
 #define _TUSB_USBD_H_
 
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include "common/common.h"
-#include "osal/osal.h"
-#include "dcd.h"
-
 #ifdef __cplusplus
  extern "C" {
 #endif
 
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "common/common.h"
+#include "dcd.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
 // LPC11uxx and LPC13uxx requires each buffer has to be 64-byte alignment
 #if TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX
  #define ATTR_USB_MIN_ALIGNMENT   ATTR_ALIGNED(64)
@@ -61,9 +63,18 @@
  #define ATTR_USB_MIN_ALIGNMENT
 #endif
 
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
+typedef struct {
+  uint8_t * p_device;
+  uint8_t * p_configuration;
+  uint8_t * p_string_arr[TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT];
+
+  uint8_t * p_hid_keyboard_report;
+  uint8_t * p_hid_mouse_report;
+}tusbd_descriptor_pointer_t;
+
+// define by application
+extern tusbd_descriptor_pointer_t tusbd_descriptor_pointers;
+
 typedef struct {
   void (* const init) (void);
   tusb_error_t (* const open)(uint8_t, tusb_descriptor_interface_t const *, uint16_t*);