Browse Source

adding debug log function

hathach 6 years ago
parent
commit
661515a807
6 changed files with 172 additions and 30 deletions
  1. 3 2
      README.md
  2. 1 2
      hw/bsp/stm32f767nucleo/stm32f767nucleo.c
  3. 41 3
      src/common/tusb_common.h
  4. 5 2
      src/device/dcd.h
  5. 44 19
      src/device/usbd.c
  6. 78 2
      src/tusb.c

+ 3 - 2
README.md

@@ -4,7 +4,7 @@
 
 [![Build Status](https://travis-ci.org/hathach/tinyusb.svg?branch=master)](https://travis-ci.org/hathach/tinyusb) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)
 
-TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system. It is designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the stack's task function.
+TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.
 
 ![tinyusb](https://user-images.githubusercontent.com/249515/49858616-f60c9700-fe27-11e8-8627-e76936352ff7.png)
 
@@ -54,7 +54,7 @@ Support multiple device configurations by dynamically changing usb descriptors.
 
 ## OS Abtraction layer
 
-TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context. It also uses semphore/mutex to access shared resource such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box.
+TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context task function. It also uses semphore/mutex to access shared resource such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box.
 
 - **No OS** : Disabling USB IRQ is used as way to provide mutex
 - **FreeRTOS**
@@ -84,6 +84,7 @@ TinyUSB is currently used by these other projects:
 * [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
 * [Adafruit SAMD Arduino](https://github.com/adafruit/ArduinoCore-samd)
 * [CircuitPython](https://github.com/adafruit/circuitpython)
+* [MicroPython](https://github.com/micropython/micropython)
 * [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
 
 Let's me know if your project also uses TinyUSB and want to share.

+ 1 - 2
hw/bsp/stm32f767nucleo/stm32f767nucleo.c

@@ -214,8 +214,7 @@ int board_uart_read(uint8_t* buf, int len)
 int board_uart_write(void const * buf, int len)
 {
   HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xffff);
-//  (void) buf; (void) len;
-  return 0;
+  return len;
 }
 
 #if CFG_TUSB_OS  == OPT_OS_NONE

+ 41 - 3
src/common/tusb_common.h

@@ -35,7 +35,7 @@
  extern "C" {
 #endif
 
- //--------------------------------------------------------------------+
+//--------------------------------------------------------------------+
 // Macros Helper
 //--------------------------------------------------------------------+
 #define TU_ARRAY_SIZE(_arr)   ( sizeof(_arr) / sizeof(_arr[0]) )
@@ -58,7 +58,7 @@
 #define TU_BIT(n)             (1U << (n))
 
 //--------------------------------------------------------------------+
-// INCLUDES
+// Includes
 //--------------------------------------------------------------------+
 
 // Standard Headers
@@ -77,7 +77,7 @@
 #include "tusb_types.h"
 
 //--------------------------------------------------------------------+
-// INLINE FUNCTION
+// Inline Functions
 //--------------------------------------------------------------------+
 #define tu_memclr(buffer, size)  memset((buffer), 0, (size))
 #define tu_varclr(_var)          tu_memclr(_var, sizeof(*(_var)))
@@ -203,6 +203,44 @@ static inline bool     tu_bit_test (uint32_t value, uint8_t n) { return (value &
             + TU_BIN8(dlsb))
 #endif
 
+//--------------------------------------------------------------------+
+// Debug Function
+//--------------------------------------------------------------------+
+
+// CFG_TUSB_DEBUG for debugging
+// 0 : no debug
+// 1 : print when there is error
+// 2 : print out log
+#if CFG_TUSB_DEBUG
+
+void tu_print_mem(void const *buf, uint8_t size, uint16_t count);
+
+#ifndef tu_printf
+  #define tu_printf     printf
+#endif
+
+// Log with debug level 1
+#define TU_LOG1         tu_printf
+#define TU_LOG1_MEM     tu_print_mem
+
+// Log with debug level 2
+#if CFG_TUSB_DEBUG > 1
+  #define TU_LOG2       TU_LOG1
+  #define TU_LOG2_MEM   TU_LOG1_MEM
+#endif
+
+#endif // CFG_TUSB_DEBUG
+
+#ifndef TU_LOG1
+  #define TU_LOG1(...)
+  #define TU_LOG1_MEM(...)
+#endif
+
+#ifndef TU_LOG2
+  #define TU_LOG2(...)
+  #define TU_LOG2_MEM(...)
+#endif
+
 #ifdef __cplusplus
  }
 #endif

+ 5 - 2
src/device/dcd.h

@@ -39,7 +39,8 @@
 
 typedef enum
 {
-  DCD_EVENT_BUS_RESET = 1,
+  DCD_EVENT_INVALID = 0,
+  DCD_EVENT_BUS_RESET,
   DCD_EVENT_UNPLUGGED,
   DCD_EVENT_SOF,
   DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
@@ -49,7 +50,9 @@ typedef enum
   DCD_EVENT_XFER_COMPLETE,
 
   // Not an DCD event, just a convenient way to defer ISR function
-  USBD_EVENT_FUNC_CALL
+  USBD_EVENT_FUNC_CALL,
+
+  DCD_EVENT_COUNT
 } dcd_eventid_t;
 
 typedef struct TU_ATTR_ALIGNED(4)

+ 44 - 19
src/device/usbd.c

@@ -192,6 +192,25 @@ void usbd_control_reset (uint8_t rhport);
 bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
 void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) );
 
+
+//--------------------------------------------------------------------+
+// Debugging
+//--------------------------------------------------------------------+
+#if CFG_TUSB_DEBUG
+static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
+{
+  "INVALID"        ,
+  "BUS_RESET"      ,
+  "UNPLUGGED"      ,
+  "SOF"            ,
+  "SUSPEND"        ,
+  "RESUME"         ,
+  "SETUP_RECEIVED" ,
+  "XFER_COMPLETE"  ,
+  "FUNC_CALL"
+};
+#endif
+
 //--------------------------------------------------------------------+
 // Application API
 //--------------------------------------------------------------------+
@@ -218,6 +237,8 @@ bool tud_remote_wakeup(void)
 //--------------------------------------------------------------------+
 bool usbd_init (void)
 {
+  TU_LOG2("USBD Init\r\n");
+
   tu_varclr(&_usbd_dev);
 
   // Init device queue & task
@@ -279,6 +300,8 @@ void tud_task (void)
 
     if ( !osal_queue_receive(_usbd_q, &event) ) return;
 
+    TU_LOG2("USBD: event %s\r\n", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
+
     switch ( event.event_id )
     {
       case DCD_EVENT_BUS_RESET:
@@ -293,6 +316,8 @@ void tud_task (void)
       break;
 
       case DCD_EVENT_SETUP_RECEIVED:
+        TU_LOG2_MEM(&event.setup_received, 1, 8);
+
         // Mark as connected after receiving 1st setup packet.
         // But it is easier to set it every time instead of wasting time to check then set
         _usbd_dev.connected = 1;
@@ -307,29 +332,29 @@ void tud_task (void)
       break;
 
       case DCD_EVENT_XFER_COMPLETE:
-        // Only handle xfer callback in ready state
-        // if (_usbd_dev.connected && !_usbd_dev.suspended)
-        {
-          // Invoke the class callback associated with the endpoint address
-          uint8_t const ep_addr = event.xfer_complete.ep_addr;
-          uint8_t const epnum   = tu_edpt_number(ep_addr);
-          uint8_t const ep_dir  = tu_edpt_dir(ep_addr);
+      {
+        // Invoke the class callback associated with the endpoint address
+        uint8_t const ep_addr = event.xfer_complete.ep_addr;
+        uint8_t const epnum   = tu_edpt_number(ep_addr);
+        uint8_t const ep_dir  = tu_edpt_dir(ep_addr);
 
-          _usbd_dev.ep_status[epnum][ep_dir].busy = false;
+        TU_LOG2("Endpoint: 0x%02X, Bytes: %ld\r\n", ep_addr, event.xfer_complete.len);
 
-          if ( 0 == epnum )
-          {
-            // control transfer DATA stage callback
-            usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
-          }
-          else
-          {
-            uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir];
-            TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
+        _usbd_dev.ep_status[epnum][ep_dir].busy = false;
 
-            usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
-          }
+        if ( 0 == epnum )
+        {
+          // control transfer DATA stage callback
+          usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
         }
+        else
+        {
+          uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir];
+          TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
+
+          usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
+        }
+      }
       break;
 
       case DCD_EVENT_SUSPEND:

+ 78 - 2
src/tusb.c

@@ -43,11 +43,11 @@ bool tusb_init(void)
   if (_initialized) return true;
 
 #if TUSB_OPT_HOST_ENABLED
-  TU_VERIFY( usbh_init() ); // init host stack
+  TU_ASSERT( usbh_init() ); // init host stack
 #endif
 
 #if TUSB_OPT_DEVICE_ENABLED
-  TU_VERIFY ( usbd_init() ); // init device stack
+  TU_ASSERT ( usbd_init() ); // init device stack
 #endif
 
   _initialized = true;
@@ -64,7 +64,83 @@ bool tusb_inited(void)
 /* Debug
  *------------------------------------------------------------------*/
 #if CFG_TUSB_DEBUG
+#include <ctype.h>
+
 char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) };
+
+static void dump_str_line(uint8_t const* buf, uint16_t count)
+{
+  // each line is 16 bytes
+  for(int i=0; i<count; i++)
+  {
+    const char ch = buf[i];
+    tu_printf("%c", isprint(ch) ? ch : '.');
+  }
+}
+
+// size  : item size in bytes
+// count : number of item
+// print offet or not (handfy for dumping large memory)
+void tu_print_mem(void const *buf, uint8_t size, uint16_t count)
+{
+  if ( !buf || !count )
+  {
+    tu_printf("NULL\n");
+    return;
+  }
+
+  uint8_t const *buf8 = (uint8_t const *) buf;
+
+  char format[] = "%00lX";
+  format[2] += 2*size;
+
+  const uint8_t  item_per_line  = 16 / size;
+
+  for(uint32_t i=0; i<count; i++)
+  {
+    uint32_t value=0;
+
+    if ( i%item_per_line == 0 )
+    {
+      // Print Ascii
+      if ( i != 0 )
+      {
+        tu_printf(" | ");
+        dump_str_line(buf8-16, 16);
+        tu_printf("\n");
+      }
+
+      // print offset or absolute address
+      tu_printf("%03lX: ", 16*i/item_per_line);
+    }
+
+    memcpy(&value, buf8, size);
+    buf8 += size;
+
+    tu_printf(" ");
+    tu_printf(format, value);
+  }
+
+  // fill up last row to 16 for printing ascii
+  const uint16_t remain = count%16;
+  uint8_t nback = (remain ? remain : 16);
+
+  if ( remain )
+  {
+    for(int i=0; i< 16-remain; i++)
+    {
+      tu_printf(" ");
+      for(int j=0; j<2*size; j++) tu_printf(" ");
+    }
+  }
+
+  tu_printf(" | ");
+  dump_str_line(buf8-nback, nback);
+  tu_printf("\n");
+
+  tu_printf("\n");
+}
+
 #endif
 
 #endif // host or device enabled