mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
adding debug log function
This commit is contained in:
parent
78bf82291e
commit
661515a807
@ -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)
|
[![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)
|
![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
|
## 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
|
- **No OS** : Disabling USB IRQ is used as way to provide mutex
|
||||||
- **FreeRTOS**
|
- **FreeRTOS**
|
||||||
@ -84,6 +84,7 @@ TinyUSB is currently used by these other projects:
|
|||||||
* [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
|
* [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
|
||||||
* [Adafruit SAMD Arduino](https://github.com/adafruit/ArduinoCore-samd)
|
* [Adafruit SAMD Arduino](https://github.com/adafruit/ArduinoCore-samd)
|
||||||
* [CircuitPython](https://github.com/adafruit/circuitpython)
|
* [CircuitPython](https://github.com/adafruit/circuitpython)
|
||||||
|
* [MicroPython](https://github.com/micropython/micropython)
|
||||||
* [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
|
* [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
|
||||||
|
|
||||||
Let's me know if your project also uses TinyUSB and want to share.
|
Let's me know if your project also uses TinyUSB and want to share.
|
||||||
|
@ -214,8 +214,7 @@ int board_uart_read(uint8_t* buf, int len)
|
|||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const * buf, int len)
|
||||||
{
|
{
|
||||||
HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xffff);
|
HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xffff);
|
||||||
// (void) buf; (void) len;
|
return len;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Macros Helper
|
// Macros Helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
|
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
|
||||||
@ -58,7 +58,7 @@
|
|||||||
#define TU_BIT(n) (1U << (n))
|
#define TU_BIT(n) (1U << (n))
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INCLUDES
|
// Includes
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Standard Headers
|
// Standard Headers
|
||||||
@ -77,7 +77,7 @@
|
|||||||
#include "tusb_types.h"
|
#include "tusb_types.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INLINE FUNCTION
|
// Inline Functions
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#define tu_memclr(buffer, size) memset((buffer), 0, (size))
|
#define tu_memclr(buffer, size) memset((buffer), 0, (size))
|
||||||
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
|
#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))
|
+ TU_BIN8(dlsb))
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,7 +39,8 @@
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DCD_EVENT_BUS_RESET = 1,
|
DCD_EVENT_INVALID = 0,
|
||||||
|
DCD_EVENT_BUS_RESET,
|
||||||
DCD_EVENT_UNPLUGGED,
|
DCD_EVENT_UNPLUGGED,
|
||||||
DCD_EVENT_SOF,
|
DCD_EVENT_SOF,
|
||||||
DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
|
DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
|
||||||
@ -49,7 +50,9 @@ typedef enum
|
|||||||
DCD_EVENT_XFER_COMPLETE,
|
DCD_EVENT_XFER_COMPLETE,
|
||||||
|
|
||||||
// Not an DCD event, just a convenient way to defer ISR function
|
// 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;
|
} dcd_eventid_t;
|
||||||
|
|
||||||
typedef struct TU_ATTR_ALIGNED(4)
|
typedef struct TU_ATTR_ALIGNED(4)
|
||||||
|
@ -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);
|
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 * ) );
|
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
|
// Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -218,6 +237,8 @@ bool tud_remote_wakeup(void)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool usbd_init (void)
|
bool usbd_init (void)
|
||||||
{
|
{
|
||||||
|
TU_LOG2("USBD Init\r\n");
|
||||||
|
|
||||||
tu_varclr(&_usbd_dev);
|
tu_varclr(&_usbd_dev);
|
||||||
|
|
||||||
// Init device queue & task
|
// Init device queue & task
|
||||||
@ -279,6 +300,8 @@ void tud_task (void)
|
|||||||
|
|
||||||
if ( !osal_queue_receive(_usbd_q, &event) ) return;
|
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 )
|
switch ( event.event_id )
|
||||||
{
|
{
|
||||||
case DCD_EVENT_BUS_RESET:
|
case DCD_EVENT_BUS_RESET:
|
||||||
@ -293,6 +316,8 @@ void tud_task (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_SETUP_RECEIVED:
|
case DCD_EVENT_SETUP_RECEIVED:
|
||||||
|
TU_LOG2_MEM(&event.setup_received, 1, 8);
|
||||||
|
|
||||||
// Mark as connected after receiving 1st setup packet.
|
// 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
|
// But it is easier to set it every time instead of wasting time to check then set
|
||||||
_usbd_dev.connected = 1;
|
_usbd_dev.connected = 1;
|
||||||
@ -307,29 +332,29 @@ void tud_task (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_XFER_COMPLETE:
|
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);
|
||||||
|
|
||||||
|
TU_LOG2("Endpoint: 0x%02X, Bytes: %ld\r\n", ep_addr, event.xfer_complete.len);
|
||||||
|
|
||||||
|
_usbd_dev.ep_status[epnum][ep_dir].busy = false;
|
||||||
|
|
||||||
|
if ( 0 == epnum )
|
||||||
{
|
{
|
||||||
// Invoke the class callback associated with the endpoint address
|
// control transfer DATA stage callback
|
||||||
uint8_t const ep_addr = event.xfer_complete.ep_addr;
|
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_SUSPEND:
|
case DCD_EVENT_SUSPEND:
|
||||||
|
80
src/tusb.c
80
src/tusb.c
@ -43,11 +43,11 @@ bool tusb_init(void)
|
|||||||
if (_initialized) return true;
|
if (_initialized) return true;
|
||||||
|
|
||||||
#if TUSB_OPT_HOST_ENABLED
|
#if TUSB_OPT_HOST_ENABLED
|
||||||
TU_VERIFY( usbh_init() ); // init host stack
|
TU_ASSERT( usbh_init() ); // init host stack
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TUSB_OPT_DEVICE_ENABLED
|
#if TUSB_OPT_DEVICE_ENABLED
|
||||||
TU_VERIFY ( usbd_init() ); // init device stack
|
TU_ASSERT ( usbd_init() ); // init device stack
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
@ -64,7 +64,83 @@ bool tusb_inited(void)
|
|||||||
/* Debug
|
/* Debug
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
#if CFG_TUSB_DEBUG
|
#if CFG_TUSB_DEBUG
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) };
|
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
|
||||||
|
|
||||||
#endif // host or device enabled
|
#endif // host or device enabled
|
||||||
|
Loading…
x
Reference in New Issue
Block a user