mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32: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)
|
||||
|
||||
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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
// 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:
|
||||
|
80
src/tusb.c
80
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user