Merge branch 'master' into patch-5
This commit is contained in:
		@@ -47,8 +47,7 @@
 | 
			
		||||
// MACRO CONSTANT TYPEDEF PROTYPES
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
typedef enum {
 | 
			
		||||
  DCD_EVENT_INVALID = 0,
 | 
			
		||||
  DCD_EVENT_BUS_RESET,
 | 
			
		||||
  DCD_EVENT_UNPLUGGED,
 | 
			
		||||
@@ -65,13 +64,11 @@ typedef enum
 | 
			
		||||
  DCD_EVENT_COUNT
 | 
			
		||||
} dcd_eventid_t;
 | 
			
		||||
 | 
			
		||||
typedef struct TU_ATTR_ALIGNED(4)
 | 
			
		||||
{
 | 
			
		||||
typedef struct TU_ATTR_ALIGNED(4) {
 | 
			
		||||
  uint8_t rhport;
 | 
			
		||||
  uint8_t event_id;
 | 
			
		||||
 | 
			
		||||
  union
 | 
			
		||||
  {
 | 
			
		||||
  union {
 | 
			
		||||
    // BUS RESET
 | 
			
		||||
    struct {
 | 
			
		||||
      tusb_speed_t speed;
 | 
			
		||||
@@ -123,7 +120,10 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
// Initialize controller to device mode
 | 
			
		||||
void dcd_init       (uint8_t rhport);
 | 
			
		||||
void dcd_init(uint8_t rhport);
 | 
			
		||||
 | 
			
		||||
// Deinitialize controller, unset device mode.
 | 
			
		||||
bool dcd_deinit(uint8_t rhport);
 | 
			
		||||
 | 
			
		||||
// Interrupt Handler
 | 
			
		||||
void dcd_int_handler(uint8_t rhport);
 | 
			
		||||
@@ -155,7 +155,7 @@ void dcd_sof_enable(uint8_t rhport, bool en);
 | 
			
		||||
 | 
			
		||||
// Invoked when a control transfer's status stage is complete.
 | 
			
		||||
// May help DCD to prepare for next control transfer, this API is optional.
 | 
			
		||||
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
 | 
			
		||||
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request);
 | 
			
		||||
 | 
			
		||||
// Configure endpoint's registers according to descriptor
 | 
			
		||||
bool dcd_edpt_open            (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep);
 | 
			
		||||
@@ -184,11 +184,11 @@ void dcd_edpt_stall           (uint8_t rhport, uint8_t ep_addr);
 | 
			
		||||
void dcd_edpt_clear_stall     (uint8_t rhport, uint8_t ep_addr);
 | 
			
		||||
 | 
			
		||||
// Allocate packet buffer used by ISO endpoints
 | 
			
		||||
// Some MCU need manual packet buffer allocation, we allocation largest size to avoid clustering
 | 
			
		||||
// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering
 | 
			
		||||
TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size);
 | 
			
		||||
 | 
			
		||||
// Configure and enable an ISO endpoint according to descriptor
 | 
			
		||||
TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport,  tusb_desc_endpoint_t const * p_endpoint_desc);
 | 
			
		||||
TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
// Event API (implemented by stack)
 | 
			
		||||
@@ -198,23 +198,20 @@ TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport,  tusb_desc_endpoint_t co
 | 
			
		||||
extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
 | 
			
		||||
 | 
			
		||||
// helper to send bus signal event
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
 | 
			
		||||
{
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) {
 | 
			
		||||
  dcd_event_t event = { .rhport = rhport, .event_id = eid };
 | 
			
		||||
  dcd_event_handler(&event, in_isr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// helper to send bus reset event
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline  void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
 | 
			
		||||
{
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline  void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) {
 | 
			
		||||
  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
 | 
			
		||||
  event.bus_reset.speed = speed;
 | 
			
		||||
  dcd_event_handler(&event, in_isr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// helper to send setup received
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
 | 
			
		||||
{
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) {
 | 
			
		||||
  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
 | 
			
		||||
  memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t));
 | 
			
		||||
 | 
			
		||||
@@ -222,8 +219,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// helper to send transfer complete event
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
 | 
			
		||||
{
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) {
 | 
			
		||||
  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
 | 
			
		||||
 | 
			
		||||
  event.xfer_complete.ep_addr = ep_addr;
 | 
			
		||||
@@ -233,8 +229,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport
 | 
			
		||||
  dcd_event_handler(&event, in_isr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
 | 
			
		||||
{
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) {
 | 
			
		||||
  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF };
 | 
			
		||||
  event.sof.frame_count = frame_count;
 | 
			
		||||
  dcd_event_handler(&event, in_isr);
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -37,9 +37,12 @@ extern "C" {
 | 
			
		||||
// Application API
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
// Init device stack
 | 
			
		||||
// Init device stack on roothub port
 | 
			
		||||
bool tud_init (uint8_t rhport);
 | 
			
		||||
 | 
			
		||||
// Deinit device stack on roothub port
 | 
			
		||||
bool tud_deinit(uint8_t rhport);
 | 
			
		||||
 | 
			
		||||
// Check if device stack is already initialized
 | 
			
		||||
bool tud_inited(void);
 | 
			
		||||
 | 
			
		||||
@@ -50,8 +53,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr);
 | 
			
		||||
 | 
			
		||||
// Task function should be called in main/rtos loop
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline
 | 
			
		||||
void tud_task (void)
 | 
			
		||||
{
 | 
			
		||||
void tud_task (void) {
 | 
			
		||||
  tud_task_ext(UINT32_MAX, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -80,8 +82,7 @@ bool tud_suspended(void);
 | 
			
		||||
 | 
			
		||||
// Check if device is ready to transfer
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline
 | 
			
		||||
bool tud_ready(void)
 | 
			
		||||
{
 | 
			
		||||
bool tud_ready(void) {
 | 
			
		||||
  return tud_mounted() && !tud_suspended();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -151,6 +152,9 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en);
 | 
			
		||||
// Invoked when usb bus is resumed
 | 
			
		||||
TU_ATTR_WEAK void tud_resume_cb(void);
 | 
			
		||||
 | 
			
		||||
// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext()
 | 
			
		||||
void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
 | 
			
		||||
 | 
			
		||||
// Invoked when a new (micro) frame started
 | 
			
		||||
TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count);
 | 
			
		||||
 | 
			
		||||
@@ -223,8 +227,8 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
  5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
 | 
			
		||||
  /* CDC Call */\
 | 
			
		||||
  5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\
 | 
			
		||||
  /* CDC ACM: support line request */\
 | 
			
		||||
  4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\
 | 
			
		||||
  /* CDC ACM: support line request + send break */\
 | 
			
		||||
  4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 6,\
 | 
			
		||||
  /* CDC Union */\
 | 
			
		||||
  5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\
 | 
			
		||||
  /* Endpoint Notification */\
 | 
			
		||||
@@ -398,6 +402,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
 | 
			
		||||
// For more channels, add definitions here
 | 
			
		||||
 | 
			
		||||
/* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */
 | 
			
		||||
#define TUD_AUDIO_DESC_STD_AC_INT_EP_LEN 7
 | 
			
		||||
#define TUD_AUDIO_DESC_STD_AC_INT_EP(_ep, _interval) \
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval
 | 
			
		||||
 | 
			
		||||
/* Standard AS Interface Descriptor(4.9.1) */
 | 
			
		||||
#define TUD_AUDIO_DESC_STD_AS_INT_LEN 9
 | 
			
		||||
#define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \
 | 
			
		||||
@@ -426,7 +435,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
/* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */
 | 
			
		||||
#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN 7
 | 
			
		||||
#define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _interval) \
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_NO_SYNC | TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval
 | 
			
		||||
 | 
			
		||||
// AUDIO simple descriptor (UAC2) for 1 microphone input
 | 
			
		||||
// - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source
 | 
			
		||||
@@ -473,7 +482,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
  /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
 | 
			
		||||
  TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
 | 
			
		||||
  /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
 | 
			
		||||
  /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
 | 
			
		||||
  TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
 | 
			
		||||
 | 
			
		||||
@@ -522,7 +531,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
  /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
 | 
			
		||||
  TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
 | 
			
		||||
  /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
 | 
			
		||||
  /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
 | 
			
		||||
  TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
 | 
			
		||||
 | 
			
		||||
@@ -570,7 +579,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
  /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
 | 
			
		||||
  TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
 | 
			
		||||
  /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
 | 
			
		||||
  TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
 | 
			
		||||
  /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
 | 
			
		||||
  TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
 | 
			
		||||
  /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\
 | 
			
		||||
@@ -779,10 +788,6 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
 | 
			
		||||
#define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER  0x01
 | 
			
		||||
#define TUD_BT_PROTOCOL_AMP_CONTROLLER      0x02
 | 
			
		||||
 | 
			
		||||
#ifndef CFG_TUD_BTH_ISO_ALT_COUNT
 | 
			
		||||
#define CFG_TUD_BTH_ISO_ALT_COUNT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Length of template descriptor: 38 bytes + number of ISO alternatives * 23
 | 
			
		||||
#define TUD_BTH_DESC_LEN (8 + 9 + 7 + 7 + 7 + (CFG_TUD_BTH_ISO_ALT_COUNT) * (9 + 7 + 7))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,24 +32,32 @@
 | 
			
		||||
#include "tusb.h"
 | 
			
		||||
#include "device/usbd_pvt.h"
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
// Callback weak stubs (called if application does not provide)
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) {
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
  (void) request;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
// MACRO CONSTANT TYPEDEF
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
 | 
			
		||||
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
enum {
 | 
			
		||||
  EDPT_CTRL_OUT = 0x00,
 | 
			
		||||
  EDPT_CTRL_IN  = 0x80
 | 
			
		||||
  EDPT_CTRL_IN = 0x80
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
typedef struct {
 | 
			
		||||
  tusb_control_request_t request;
 | 
			
		||||
 | 
			
		||||
  uint8_t* buffer;
 | 
			
		||||
  uint16_t data_len;
 | 
			
		||||
  uint16_t total_xferred;
 | 
			
		||||
 | 
			
		||||
  usbd_control_xfer_cb_t complete_cb;
 | 
			
		||||
} usbd_control_xfer_t;
 | 
			
		||||
 | 
			
		||||
@@ -63,20 +71,18 @@ tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
// Queue ZLP status transaction
 | 
			
		||||
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const * request)
 | 
			
		||||
{
 | 
			
		||||
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) {
 | 
			
		||||
  // Opposite to endpoint in Data Phase
 | 
			
		||||
  uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN;
 | 
			
		||||
  return usbd_edpt_xfer(rhport, ep_addr, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Status phase
 | 
			
		||||
bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request)
 | 
			
		||||
{
 | 
			
		||||
  _ctrl_xfer.request       = (*request);
 | 
			
		||||
  _ctrl_xfer.buffer        = NULL;
 | 
			
		||||
bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) {
 | 
			
		||||
  _ctrl_xfer.request = (*request);
 | 
			
		||||
  _ctrl_xfer.buffer = NULL;
 | 
			
		||||
  _ctrl_xfer.total_xferred = 0;
 | 
			
		||||
  _ctrl_xfer.data_len      = 0;
 | 
			
		||||
  _ctrl_xfer.data_len = 0;
 | 
			
		||||
 | 
			
		||||
  return _status_stage_xact(rhport, request);
 | 
			
		||||
}
 | 
			
		||||
@@ -84,16 +90,15 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request)
 | 
			
		||||
// Queue a transaction in Data Stage
 | 
			
		||||
// Each transaction has up to Endpoint0's max packet size.
 | 
			
		||||
// This function can also transfer an zero-length packet
 | 
			
		||||
static bool _data_stage_xact(uint8_t rhport)
 | 
			
		||||
{
 | 
			
		||||
  uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE);
 | 
			
		||||
static bool _data_stage_xact(uint8_t rhport) {
 | 
			
		||||
  uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred,
 | 
			
		||||
                                     CFG_TUD_ENDPOINT0_SIZE);
 | 
			
		||||
 | 
			
		||||
  uint8_t ep_addr = EDPT_CTRL_OUT;
 | 
			
		||||
 | 
			
		||||
  if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN )
 | 
			
		||||
  {
 | 
			
		||||
  if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) {
 | 
			
		||||
    ep_addr = EDPT_CTRL_IN;
 | 
			
		||||
    if ( xact_len ) {
 | 
			
		||||
    if (xact_len) {
 | 
			
		||||
      TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -103,29 +108,24 @@ static bool _data_stage_xact(uint8_t rhport)
 | 
			
		||||
 | 
			
		||||
// Transmit data to/from the control endpoint.
 | 
			
		||||
// If the request's wLength is zero, a status packet is sent instead.
 | 
			
		||||
bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len)
 | 
			
		||||
{
 | 
			
		||||
  _ctrl_xfer.request       = (*request);
 | 
			
		||||
  _ctrl_xfer.buffer        = (uint8_t*) buffer;
 | 
			
		||||
bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, void* buffer, uint16_t len) {
 | 
			
		||||
  _ctrl_xfer.request = (*request);
 | 
			
		||||
  _ctrl_xfer.buffer = (uint8_t*) buffer;
 | 
			
		||||
  _ctrl_xfer.total_xferred = 0U;
 | 
			
		||||
  _ctrl_xfer.data_len      = tu_min16(len, request->wLength);
 | 
			
		||||
  _ctrl_xfer.data_len = tu_min16(len, request->wLength);
 | 
			
		||||
 | 
			
		||||
  if (request->wLength > 0U)
 | 
			
		||||
  {
 | 
			
		||||
    if(_ctrl_xfer.data_len > 0U)
 | 
			
		||||
    {
 | 
			
		||||
  if (request->wLength > 0U) {
 | 
			
		||||
    if (_ctrl_xfer.data_len > 0U) {
 | 
			
		||||
      TU_ASSERT(buffer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    TU_LOG2("  Control total data length is %u bytes\r\n", _ctrl_xfer.data_len);
 | 
			
		||||
 | 
			
		||||
    // Data stage
 | 
			
		||||
    TU_ASSERT( _data_stage_xact(rhport) );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    TU_ASSERT(_data_stage_xact(rhport));
 | 
			
		||||
  } else {
 | 
			
		||||
    // Status stage
 | 
			
		||||
    TU_ASSERT( _status_stage_xact(rhport, request) );
 | 
			
		||||
    TU_ASSERT(_status_stage_xact(rhport, request));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
@@ -134,49 +134,42 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
// USBD API
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
void usbd_control_reset(void);
 | 
			
		||||
void usbd_control_set_request(tusb_control_request_t const *request);
 | 
			
		||||
void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp );
 | 
			
		||||
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
 | 
			
		||||
void usbd_control_set_request(tusb_control_request_t const* request);
 | 
			
		||||
void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp);
 | 
			
		||||
bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
 | 
			
		||||
 | 
			
		||||
void usbd_control_reset(void)
 | 
			
		||||
{
 | 
			
		||||
void usbd_control_reset(void) {
 | 
			
		||||
  tu_varclr(&_ctrl_xfer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set complete callback
 | 
			
		||||
void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp )
 | 
			
		||||
{
 | 
			
		||||
void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) {
 | 
			
		||||
  _ctrl_xfer.complete_cb = fp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// for dcd_set_address where DCD is responsible for status response
 | 
			
		||||
void usbd_control_set_request(tusb_control_request_t const *request)
 | 
			
		||||
{
 | 
			
		||||
  _ctrl_xfer.request       = (*request);
 | 
			
		||||
  _ctrl_xfer.buffer        = NULL;
 | 
			
		||||
void usbd_control_set_request(tusb_control_request_t const* request) {
 | 
			
		||||
  _ctrl_xfer.request = (*request);
 | 
			
		||||
  _ctrl_xfer.buffer = NULL;
 | 
			
		||||
  _ctrl_xfer.total_xferred = 0;
 | 
			
		||||
  _ctrl_xfer.data_len      = 0;
 | 
			
		||||
  _ctrl_xfer.data_len = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// callback when a transaction complete on
 | 
			
		||||
// - DATA stage of control endpoint or
 | 
			
		||||
// - Status stage
 | 
			
		||||
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
 | 
			
		||||
{
 | 
			
		||||
bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
 | 
			
		||||
  (void) result;
 | 
			
		||||
 | 
			
		||||
  // Endpoint Address is opposite to direction bit, this is Status Stage complete event
 | 
			
		||||
  if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction )
 | 
			
		||||
  {
 | 
			
		||||
  if (tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction) {
 | 
			
		||||
    TU_ASSERT(0 == xferred_bytes);
 | 
			
		||||
 | 
			
		||||
    // invoke optional dcd hook if available
 | 
			
		||||
    if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request);
 | 
			
		||||
    dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request);
 | 
			
		||||
 | 
			
		||||
    if (_ctrl_xfer.complete_cb)
 | 
			
		||||
    {
 | 
			
		||||
    if (_ctrl_xfer.complete_cb) {
 | 
			
		||||
      // TODO refactor with usbd_driver_print_control_complete_name
 | 
			
		||||
      _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request);
 | 
			
		||||
    }
 | 
			
		||||
@@ -184,8 +177,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT )
 | 
			
		||||
  {
 | 
			
		||||
  if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
 | 
			
		||||
    TU_VERIFY(_ctrl_xfer.buffer);
 | 
			
		||||
    memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
 | 
			
		||||
    TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
 | 
			
		||||
@@ -196,15 +188,14 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
 | 
			
		||||
 | 
			
		||||
  // Data Stage is complete when all request's length are transferred or
 | 
			
		||||
  // a short packet is sent including zero-length packet.
 | 
			
		||||
  if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE) )
 | 
			
		||||
  {
 | 
			
		||||
  if ((_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) ||
 | 
			
		||||
      (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE)) {
 | 
			
		||||
    // DATA stage is complete
 | 
			
		||||
    bool is_ok = true;
 | 
			
		||||
 | 
			
		||||
    // invoke complete callback if set
 | 
			
		||||
    // callback can still stall control in status phase e.g out data does not make sense
 | 
			
		||||
    if ( _ctrl_xfer.complete_cb )
 | 
			
		||||
    {
 | 
			
		||||
    if (_ctrl_xfer.complete_cb) {
 | 
			
		||||
      #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
 | 
			
		||||
      usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
 | 
			
		||||
      #endif
 | 
			
		||||
@@ -212,21 +203,17 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
 | 
			
		||||
      is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( is_ok )
 | 
			
		||||
    {
 | 
			
		||||
    if (is_ok) {
 | 
			
		||||
      // Send status
 | 
			
		||||
      TU_ASSERT( _status_stage_xact(rhport, &_ctrl_xfer.request) );
 | 
			
		||||
    }else
 | 
			
		||||
    {
 | 
			
		||||
      TU_ASSERT(_status_stage_xact(rhport, &_ctrl_xfer.request));
 | 
			
		||||
    } else {
 | 
			
		||||
      // Stall both IN and OUT control endpoint
 | 
			
		||||
      dcd_edpt_stall(rhport, EDPT_CTRL_OUT);
 | 
			
		||||
      dcd_edpt_stall(rhport, EDPT_CTRL_IN);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
  } else {
 | 
			
		||||
    // More data to transfer
 | 
			
		||||
    TU_ASSERT( _data_stage_xact(rhport) );
 | 
			
		||||
    TU_ASSERT(_data_stage_xact(rhport));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,8 @@
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of the TinyUSB stack.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef USBD_PVT_H_
 | 
			
		||||
#define USBD_PVT_H_
 | 
			
		||||
#ifndef TUSB_USBD_PVT_H_
 | 
			
		||||
#define TUSB_USBD_PVT_H_
 | 
			
		||||
 | 
			
		||||
#include "osal/osal.h"
 | 
			
		||||
#include "common/tusb_fifo.h"
 | 
			
		||||
@@ -33,24 +33,16 @@
 | 
			
		||||
 extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Level where CFG_TUSB_DEBUG must be at least for USBD is logged
 | 
			
		||||
#ifndef CFG_TUD_LOG_LEVEL
 | 
			
		||||
#define CFG_TUD_LOG_LEVEL   2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TU_LOG_USBD(...)   TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
// Class Driver API
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char const* name;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  void     (* init             ) (void);
 | 
			
		||||
  bool     (* deinit           ) (void);
 | 
			
		||||
  void     (* reset            ) (uint8_t rhport);
 | 
			
		||||
  uint16_t (* open             ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len);
 | 
			
		||||
  bool     (* control_xfer_cb  ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
 | 
			
		||||
@@ -59,7 +51,7 @@ typedef struct
 | 
			
		||||
} usbd_class_driver_t;
 | 
			
		||||
 | 
			
		||||
// Invoked when initializing device stack to get additional class drivers.
 | 
			
		||||
// Can optionally implemented by application to extend/overwrite class driver support.
 | 
			
		||||
// Can be implemented by application to extend/overwrite class driver support.
 | 
			
		||||
// Note: The drivers array must be accessible at all time when stack is active
 | 
			
		||||
usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK;
 | 
			
		||||
 | 
			
		||||
@@ -111,8 +103,7 @@ bool usbd_edpt_iso_activate(uint8_t rhport,  tusb_desc_endpoint_t const * p_endp
 | 
			
		||||
 | 
			
		||||
// Check if endpoint is ready (not busy and not stalled)
 | 
			
		||||
TU_ATTR_ALWAYS_INLINE static inline
 | 
			
		||||
bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr)
 | 
			
		||||
{
 | 
			
		||||
bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) {
 | 
			
		||||
  return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -124,11 +115,10 @@ void usbd_sof_enable(uint8_t rhport, bool en);
 | 
			
		||||
 *------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
 | 
			
		||||
void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr );
 | 
			
		||||
 | 
			
		||||
void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* USBD_PVT_H_ */
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user