summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2023-04-14 13:16:52 +0200
committerHiFiPhile <[email protected]>2023-04-14 13:16:52 +0200
commitcbf4b1aec8f5fbbfe65e21e94a72578a2066d621 (patch)
tree097dcf9f33540b2ce2bfa34a01d7b11dae4b9382 /src/class
parentf8a21fff171aa272360c89dab5faca4f688a656a (diff)
parent28817a715024c82b78f9b9d19f37a72771870759 (diff)
Merge branch 'master' of https://github.com/hathach/tinyusb into pr1942
Diffstat (limited to 'src/class')
-rw-r--r--src/class/audio/audio.h6
-rw-r--r--src/class/audio/audio_device.c8
-rw-r--r--src/class/audio/audio_device.h4
-rwxr-xr-xsrc/class/bth/bth_device.h2
-rw-r--r--src/class/cdc/cdc_device.c12
-rw-r--r--src/class/cdc/cdc_device.h2
-rw-r--r--src/class/cdc/cdc_host.c72
-rw-r--r--src/class/cdc/cdc_host.h14
-rw-r--r--src/class/cdc/cdc_rndis.h2
-rw-r--r--src/class/cdc/cdc_rndis_host.c6
-rw-r--r--src/class/cdc/cdc_rndis_host.h2
-rw-r--r--src/class/hid/hid.h2
-rw-r--r--src/class/hid/hid_host.c431
-rw-r--r--src/class/hid/hid_host.h54
-rw-r--r--src/class/midi/midi.h2
-rw-r--r--src/class/midi/midi_device.c2
-rw-r--r--src/class/midi/midi_device.h2
-rw-r--r--src/class/msc/msc.h2
-rw-r--r--src/class/msc/msc_device.h2
-rw-r--r--src/class/msc/msc_host.c20
-rw-r--r--src/class/msc/msc_host.h2
-rw-r--r--src/class/net/ecm_rndis_device.c2
-rw-r--r--src/class/net/ncm_device.c2
-rw-r--r--src/class/net/net_device.h4
-rw-r--r--src/class/usbtmc/usbtmc.h23
-rw-r--r--src/class/usbtmc/usbtmc_device.c11
-rw-r--r--src/class/vendor/vendor_device.c63
-rw-r--r--src/class/vendor/vendor_device.h22
-rw-r--r--src/class/vendor/vendor_host.c2
-rw-r--r--src/class/vendor/vendor_host.h2
-rw-r--r--src/class/video/video.h2
-rw-r--r--src/class/video/video_device.c2
32 files changed, 465 insertions, 319 deletions
diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h
index ba497906b..70d431282 100644
--- a/src/class/audio/audio.h
+++ b/src/class/audio/audio.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -824,10 +824,10 @@ typedef struct TU_ATTR_PACKED
uint8_t type : 2; ///< Request type tusb_request_type_t.
uint8_t direction : 1; ///< Direction type. tusb_dir_t
} bmRequestType_bit;
-
+
uint8_t bmRequestType;
};
-
+
uint8_t bRequest; ///< Request type audio_cs_req_t
uint8_t bChannelNumber;
uint8_t bControlSelector;
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index f21dfee64..f487fe60e 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Reinhard Panhuber, Jerzy Kasenberg
@@ -312,7 +312,7 @@ typedef struct
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
struct {
- uint32_t value; // Feedback value for asynchronous mode (in 16.16 format).
+ CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format).
uint32_t min_value; // min value according to UAC2 FMT-2.0 section 2.3.1.1.
uint32_t max_value; // max value according to UAC2 FMT-2.0 section 2.3.1.1.
@@ -1525,7 +1525,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
#endif
}
}
-
+
}
}
p_desc = tu_desc_next(p_desc);
@@ -2124,7 +2124,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
{
if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id);
- // Schedule a transmit with the new value if EP is not busy
+ // Schedule a transmit with the new value if EP is not busy
if (!usbd_edpt_busy(rhport, audio->ep_fb))
{
// Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent
diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h
index 0ef100fa4..7c88b99fc 100644
--- a/src/class/audio/audio_device.h
+++ b/src/class/audio/audio_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ha Thach (tinyusb.org)
@@ -473,7 +473,7 @@ TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id);
// the choice of format is left to the caller and feedback argument is sent as-is. If CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION is set, then tinyusb
// expects 16.16 format and handles the conversion to 10.14 on FS.
//
-// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the
+// Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the
// driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format.
// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value.
diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h
index 1b90d0915..921bd7a1a 100755
--- a/src/class/bth/bth_device.h
+++ b/src/class/bth/bth_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jerzy Kasenberg
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index f372fe462..a82ef1d62 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -386,7 +386,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
bool const rts = tu_bit_test(request->wValue, 1);
p_cdc->line_state = (uint8_t) request->wValue;
-
+
// Disable fifo overwriting if DTR bit is set
tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr);
@@ -433,7 +433,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
if ( ep_addr == p_cdc->ep_out )
{
tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes);
-
+
// Check for wanted char and invoke callback if needed
if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) )
{
@@ -445,14 +445,14 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
}
}
}
-
+
// invoke receive callback (if there is still data)
if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
-
+
// prepare for OUT transaction
_prep_out_transaction(p_cdc);
}
-
+
// Data sent to host, we continue to fetch from tx fifo to send.
// Note: This will cause incorrect baudrate set in line coding.
// Though maybe the baudrate is not really important !!!
diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h
index f8a004df4..a6e07aa5c 100644
--- a/src/class/cdc/cdc_device.h
+++ b/src/class/cdc/cdc_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index e9c3d34cb..c0cc41adf 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -62,10 +62,10 @@ typedef struct {
tu_edpt_stream_t rx;
uint8_t tx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE];
- CFG_TUSB_MEM_ALIGN uint8_t tx_ep_buf[CFG_TUH_CDC_TX_EPSIZE];
+ CFG_TUH_MEM_ALIGN uint8_t tx_ep_buf[CFG_TUH_CDC_TX_EPSIZE];
uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE];
- CFG_TUSB_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE];
+ CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE];
} stream;
} cdch_interface_t;
@@ -74,7 +74,7 @@ typedef struct {
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION
+CFG_TUH_MEM_SECTION
static cdch_interface_t cdch_data[CFG_TUH_CDC];
static inline cdch_interface_t* get_itf(uint8_t idx)
@@ -97,7 +97,7 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr)
}
}
- return TUSB_INDEX_INVALID;
+ return TUSB_INDEX_INVALID_8;
}
@@ -124,18 +124,28 @@ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num)
if (p_cdc->daddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i;
}
- return TUSB_INDEX_INVALID;
+ return TUSB_INDEX_INVALID_8;
}
-bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info)
+bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info)
{
cdch_interface_t* p_cdc = get_itf(idx);
TU_VERIFY(p_cdc && info);
- info->daddr = p_cdc->daddr;
- info->bInterfaceNumber = p_cdc->bInterfaceNumber;
- info->bInterfaceSubClass = p_cdc->bInterfaceSubClass;
- info->bInterfaceProtocol = p_cdc->bInterfaceProtocol;
+ info->daddr = p_cdc->daddr;
+
+ // re-construct descriptor
+ tusb_desc_interface_t* desc = &info->desc;
+ desc->bLength = sizeof(tusb_desc_interface_t);
+ desc->bDescriptorType = TUSB_DESC_INTERFACE;
+
+ desc->bInterfaceNumber = p_cdc->bInterfaceNumber;
+ desc->bAlternateSetting = 0;
+ desc->bNumEndpoints = 2u + (p_cdc->ep_notif ? 1u : 0u);
+ desc->bInterfaceClass = TUSB_CLASS_CDC;
+ desc->bInterfaceSubClass = p_cdc->bInterfaceSubClass;
+ desc->bInterfaceProtocol = p_cdc->bInterfaceProtocol;
+ desc->iInterface = 0; // not used yet
return true;
}
@@ -313,7 +323,8 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c
.user_data = user_data
};
- return tuh_control_xfer(&xfer);
+ TU_ASSERT(tuh_control_xfer(&xfer));
+ return true;
}
bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
@@ -353,7 +364,8 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding,
.user_data = user_data
};
- return tuh_control_xfer(&xfer);
+ TU_ASSERT(tuh_control_xfer(&xfer));
+ return true;
}
//--------------------------------------------------------------------+
@@ -533,32 +545,36 @@ static void process_cdc_config(tuh_xfer_t* xfer)
uintptr_t const state = xfer->user_data;
uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num);
- TU_ASSERT(idx != TUSB_INDEX_INVALID, );
+ cdch_interface_t * p_cdc = get_itf(idx);
+ TU_ASSERT(p_cdc, );
switch(state)
{
case CONFIG_SET_CONTROL_LINE_STATE:
- #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM
- TU_ASSERT( tuh_cdc_set_control_line_state(idx, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, process_cdc_config, CONFIG_SET_LINE_CODING), );
- break;
- #endif
- TU_ATTR_FALLTHROUGH;
+ #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM
+ if (p_cdc->acm_capability.support_line_request)
+ {
+ TU_ASSERT( tuh_cdc_set_control_line_state(idx, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, process_cdc_config, CONFIG_SET_LINE_CODING), );
+ break;
+ }
+ #endif
+ TU_ATTR_FALLTHROUGH;
case CONFIG_SET_LINE_CODING:
- #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
- {
- cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM;
- TU_ASSERT( tuh_cdc_set_line_coding(idx, &line_coding, process_cdc_config, CONFIG_COMPLETE), );
- break;
- }
- #endif
- TU_ATTR_FALLTHROUGH;
+ #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
+ if (p_cdc->acm_capability.support_line_request)
+ {
+ cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM;
+ TU_ASSERT( tuh_cdc_set_line_coding(idx, &line_coding, process_cdc_config, CONFIG_COMPLETE), );
+ break;
+ }
+ #endif
+ TU_ATTR_FALLTHROUGH;
case CONFIG_COMPLETE:
if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx);
// Prepare for incoming data
- cdch_interface_t* p_cdc = get_itf(idx);
tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
// notify usbh that driver enumeration is complete
diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h
index c759527e6..a1e78f158 100644
--- a/src/class/cdc/cdc_host.h
+++ b/src/class/cdc/cdc_host.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -71,21 +71,13 @@
// Application API
//--------------------------------------------------------------------+
-typedef struct
-{
- uint8_t daddr;
- uint8_t bInterfaceNumber;
- uint8_t bInterfaceSubClass;
- uint8_t bInterfaceProtocol;
-} tuh_cdc_itf_info_t;
-
// Get Interface index from device address + interface number
-// return TUSB_INDEX_INVALID (0xFF) if not found
+// return TUSB_INDEX_INVALID_8 (0xFF) if not found
uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num);
// Get Interface information
// return true if index is correct and interface is currently mounted
-bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info);
+bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info);
// Check if a interface is mounted
bool tuh_cdc_mounted(uint8_t idx);
diff --git a/src/class/cdc/cdc_rndis.h b/src/class/cdc/cdc_rndis.h
index e0f129fe3..ad153e0ac 100644
--- a/src/class/cdc/cdc_rndis.h
+++ b/src/class/cdc/cdc_rndis.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c
index 44de85b45..11a5355aa 100644
--- a/src/class/cdc/cdc_rndis_host.c
+++ b/src/class/cdc/cdc_rndis_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -50,8 +50,8 @@
//--------------------------------------------------------------------+
#define RNDIS_MSG_PAYLOAD_MAX (1024*4)
-CFG_TUSB_MEM_SECTION static uint8_t msg_notification[CFG_TUH_DEVICE_MAX][8];
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t msg_payload[RNDIS_MSG_PAYLOAD_MAX];
+CFG_TUH_MEM_SECTION static uint8_t msg_notification[CFG_TUH_DEVICE_MAX][8];
+CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static uint8_t msg_payload[RNDIS_MSG_PAYLOAD_MAX];
static rndish_data_t rndish_data[CFG_TUH_DEVICE_MAX];
diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h
index 447cc4e97..bb431ec1f 100644
--- a/src/class/cdc/cdc_rndis_host.h
+++ b/src/class/cdc/cdc_rndis_host.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h
index d9b0ead10..fbd3eef38 100644
--- a/src/class/hid/hid.h
+++ b/src/class/hid/hid.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index 42b5e2f4e..d95d3ef35 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -39,6 +39,8 @@
typedef struct
{
+ uint8_t daddr;
+
uint8_t itf_num;
uint8_t ep_in;
uint8_t ep_out;
@@ -52,78 +54,158 @@ typedef struct
uint16_t epin_size;
uint16_t epout_size;
- uint8_t epin_buf[CFG_TUH_HID_EPIN_BUFSIZE];
- uint8_t epout_buf[CFG_TUH_HID_EPOUT_BUFSIZE];
+ CFG_TUH_MEM_ALIGN uint8_t epin_buf[CFG_TUH_HID_EPIN_BUFSIZE];
+ CFG_TUH_MEM_ALIGN uint8_t epout_buf[CFG_TUH_HID_EPOUT_BUFSIZE];
} hidh_interface_t;
-typedef struct
+CFG_TUH_MEM_SECTION
+tu_static hidh_interface_t _hidh_itf[CFG_TUH_HID];
+
+//--------------------------------------------------------------------+
+// Helper
+//--------------------------------------------------------------------+
+
+TU_ATTR_ALWAYS_INLINE static inline
+hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx)
{
- uint8_t inst_count;
- hidh_interface_t instances[CFG_TUH_HID];
-} hidh_device_t;
+ TU_ASSERT(daddr && idx < CFG_TUH_HID, NULL);
+ hidh_interface_t* p_hid = &_hidh_itf[idx];
+ return (p_hid->daddr == daddr) ? p_hid : NULL;
+}
-CFG_TUSB_MEM_SECTION
-static hidh_device_t _hidh_dev[CFG_TUH_DEVICE_MAX];
+// Get instance ID by endpoint address
+static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr)
+{
+ for ( uint8_t idx = 0; idx < CFG_TUH_HID; idx++ )
+ {
+ hidh_interface_t const * p_hid = &_hidh_itf[idx];
-//------------- Internal prototypes -------------//
+ if ( p_hid->daddr == daddr &&
+ (p_hid->ep_in == ep_addr || p_hid->ep_out == ep_addr) )
+ {
+ return idx;
+ }
+ }
-// Get HID device & interface
-TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr);
-TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t instance);
-static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf);
-static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr);
+ return TUSB_INDEX_INVALID_8;
+}
+
+static hidh_interface_t* find_new_itf(void)
+{
+ for(uint8_t i=0; i<CFG_TUH_HID; i++)
+ {
+ if (_hidh_itf[i].daddr == 0) return &_hidh_itf[i];
+ }
+
+ return NULL;
+}
//--------------------------------------------------------------------+
// Interface API
//--------------------------------------------------------------------+
-uint8_t tuh_hid_instance_count(uint8_t dev_addr)
+uint8_t tuh_hid_itf_get_count(uint8_t daddr)
+{
+ uint8_t count = 0;
+
+ for(uint8_t i=0; i<CFG_TUH_HID; i++)
+ {
+ if (_hidh_itf[i].daddr == daddr) count++;
+ }
+
+ return count;
+}
+
+uint8_t tuh_hid_itf_get_total_count(void)
+{
+ uint8_t count = 0;
+
+ for(uint8_t i=0; i<CFG_TUH_HID; i++)
+ {
+ if (_hidh_itf[i].daddr != 0) count++;
+ }
+
+ return count;
+}
+
+bool tuh_hid_mounted(uint8_t daddr, uint8_t idx)
{
- return get_dev(dev_addr)->inst_count;
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ return p_hid != NULL;
+}
+
+bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info)
+{
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid && info);
+
+ info->daddr = daddr;
+
+ // re-construct descriptor
+ tusb_desc_interface_t* desc = &info->desc;
+ desc->bLength = sizeof(tusb_desc_interface_t);
+ desc->bDescriptorType = TUSB_DESC_INTERFACE;
+
+ desc->bInterfaceNumber = p_hid->itf_num;
+ desc->bAlternateSetting = 0;
+ desc->bNumEndpoints = (uint8_t) ((p_hid->ep_in ? 1u : 0u) + (p_hid->ep_out ? 1u : 0u));
+ desc->bInterfaceClass = TUSB_CLASS_HID;
+ desc->bInterfaceSubClass = (p_hid->itf_protocol ? HID_SUBCLASS_BOOT : HID_SUBCLASS_NONE);
+ desc->bInterfaceProtocol = p_hid->itf_protocol;
+ desc->iInterface = 0; // not used yet
+
+ return true;
}
-bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance)
+uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
- return (hid_itf->ep_in != 0) || (hid_itf->ep_out != 0);
+ for ( uint8_t idx = 0; idx < CFG_TUH_HID; idx++ )
+ {
+ hidh_interface_t const * p_hid = &_hidh_itf[idx];
+
+ if ( p_hid->daddr == daddr && p_hid->itf_num == itf_num) return idx;
+ }
+
+ return TUSB_INDEX_INVALID_8;
}
-uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance)
+uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
- return hid_itf->itf_protocol;
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ return p_hid ? p_hid->itf_protocol : 0;
}
//--------------------------------------------------------------------+
// Control Endpoint API
//--------------------------------------------------------------------+
-uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance)
+uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
- return hid_itf->protocol_mode;
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ return p_hid ? p_hid->protocol_mode : 0;
}
static void set_protocol_complete(tuh_xfer_t* xfer)
{
- uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
- uint8_t const daddr = xfer->daddr;
- uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num);
- hidh_interface_t* hid_itf = get_instance(daddr, instance);
+ uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
+ uint8_t const daddr = xfer->daddr;
+ uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num);
+
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid, );
if (XFER_RESULT_SUCCESS == xfer->result)
{
- hid_itf->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue);
+ p_hid->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue);
}
if (tuh_hid_set_protocol_complete_cb)
{
- tuh_hid_set_protocol_complete_cb(daddr, instance, hid_itf->protocol_mode);
+ tuh_hid_set_protocol_complete_cb(daddr, idx, p_hid->protocol_mode);
}
}
-
-static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
+static bool _hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
TU_LOG2("HID Set Protocol = %d\r\n", protocol);
@@ -143,7 +225,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc
tuh_xfer_t xfer =
{
- .daddr = dev_addr,
+ .daddr = daddr,
.ep_addr = 0,
.setup = &request,
.buffer = NULL,
@@ -151,16 +233,15 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc
.user_data = user_data
};
- TU_ASSERT( tuh_control_xfer(&xfer) );
- return true;
+ return tuh_control_xfer(&xfer);
}
-bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol)
+bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
- TU_VERIFY(hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE);
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid && p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE);
- return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0);
+ return _hidh_set_protocol(daddr, p_hid->itf_num, protocol, set_protocol_complete, 0);
}
static void set_report_complete(tuh_xfer_t* xfer)
@@ -169,20 +250,22 @@ static void set_report_complete(tuh_xfer_t* xfer)
if (tuh_hid_set_report_complete_cb)
{
- uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
- uint8_t const instance = get_instance_id_by_itfnum(xfer->daddr, itf_num);
+ uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
+ uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num);
uint8_t const report_type = tu_u16_high(xfer->setup->wValue);
uint8_t const report_id = tu_u16_low(xfer->setup->wValue);
- tuh_hid_set_report_complete_cb(xfer->daddr, instance, report_id, report_type,
+ tuh_hid_set_report_complete_cb(xfer->daddr, idx, report_id, report_type,
(xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0);
}
}
-bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len)
+bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid);
+
TU_LOG2("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len);
tusb_control_request_t const request =
@@ -194,14 +277,14 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u
.direction = TUSB_DIR_OUT
},
.bRequest = HID_REQ_CONTROL_SET_REPORT,
- .wValue = tu_u16(report_type, report_id),
- .wIndex = hid_itf->itf_num,
+ .wValue = tu_htole16(tu_u16(report_type, report_id)),
+ .wIndex = tu_htole16((uint16_t)p_hid->itf_num),
.wLength = len
};
tuh_xfer_t xfer =
{
- .daddr = dev_addr,
+ .daddr = daddr,
.ep_addr = 0,
.setup = &request,
.buffer = report,
@@ -209,14 +292,14 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u
.user_data = 0
};
- TU_ASSERT( tuh_control_xfer(&xfer) );
- return true;
+ return tuh_control_xfer(&xfer);
}
-static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
+static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
// SET IDLE request, device can stall if not support this request
TU_LOG2("HID Set Idle \r\n");
+
tusb_control_request_t const request =
{
.bmRequestType_bit =
@@ -226,14 +309,14 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate
.direction = TUSB_DIR_OUT
},
.bRequest = HID_REQ_CONTROL_SET_IDLE,
- .wValue = idle_rate,
- .wIndex = itf_num,
+ .wValue = tu_htole16(idle_rate),
+ .wIndex = tu_htole16((uint16_t)itf_num),
.wLength = 0
};
tuh_xfer_t xfer =
{
- .daddr = dev_addr,
+ .daddr = daddr,
.ep_addr = 0,
.setup = &request,
.buffer = NULL,
@@ -241,96 +324,148 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate
.user_data = user_data
};
- TU_ASSERT( tuh_control_xfer(&xfer) );
-
- return true;
+ return tuh_control_xfer(&xfer);
}
//--------------------------------------------------------------------+
// Interrupt Endpoint API
//--------------------------------------------------------------------+
-bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance)
+// Check if HID interface is ready to receive report
+bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx)
+{
+ hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx);
+ TU_VERIFY(p_hid);
+
+ return !usbh_edpt_busy(dev_addr, p_hid->ep_in);
+}
+
+bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid);
// claim endpoint
- TU_VERIFY( usbh_edpt_claim(dev_addr, hid_itf->ep_in) );
+ TU_VERIFY( usbh_edpt_claim(daddr, p_hid->ep_in) );
- if ( !usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size) )
+ if ( !usbh_edpt_xfer(daddr, p_hid->ep_in, p_hid->epin_buf, p_hid->epin_size) )
{
- usbh_edpt_release(dev_addr, hid_itf->ep_in);
+ usbh_edpt_release(daddr, p_hid->ep_in);
return false;
}
return true;
}
-//bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance)
-//{
-// TU_VERIFY(tuh_n_hid_n_mounted(dev_addr, instance));
-//
-// hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
-// return !usbh_edpt_busy(dev_addr, hid_itf->ep_in);
-//}
+bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx)
+{
+ hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx);
+ TU_VERIFY(p_hid);
+
+ return !usbh_edpt_busy(dev_addr, p_hid->ep_out);
+}
+
+bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len)
+{
+ TU_LOG2("HID Send Report %d\r\n", report_id);
+
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid);
+
+ if (p_hid->ep_out == 0)
+ {
+ // This HID does not have an out endpoint (other than control)
+ return false;
+ }
+ else if (len > CFG_TUH_HID_EPOUT_BUFSIZE ||
+ (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1)))
+ {
+ // ep_out buffer is not large enough to hold contents
+ return false;
+ }
-//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len);
+ // claim endpoint
+ TU_VERIFY( usbh_edpt_claim(daddr, p_hid->ep_out) );
+
+ if (report_id == 0)
+ {
+ // No report ID in transmission
+ memcpy(&p_hid->epout_buf[0], report, len);
+ }
+ else
+ {
+ p_hid->epout_buf[0] = report_id;
+ memcpy(&p_hid->epout_buf[1], report, len);
+ ++len; // 1 more byte for report_id
+ }
+
+ TU_LOG3_MEM(p_hid->epout_buf, len, 2);
+
+ if ( !usbh_edpt_xfer(daddr, p_hid->ep_out, p_hid->epout_buf, len) )
+ {
+ usbh_edpt_release(daddr, p_hid->ep_out);
+ return false;
+ }
+
+ return true;
+}
//--------------------------------------------------------------------+
// USBH API
//--------------------------------------------------------------------+
void hidh_init(void)
{
- tu_memclr(_hidh_dev, sizeof(_hidh_dev));
+ tu_memclr(_hidh_itf, sizeof(_hidh_itf));
}
-bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
+bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{
(void) result;
uint8_t const dir = tu_edpt_dir(ep_addr);
- uint8_t const instance = get_instance_id_by_epaddr(dev_addr, ep_addr);
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
+ uint8_t const idx = get_idx_by_epaddr(daddr, ep_addr);
+
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid);
if ( dir == TUSB_DIR_IN )
{
- TU_LOG2(" Get Report callback (%u, %u)\r\n", dev_addr, instance);
- TU_LOG3_MEM(hid_itf->epin_buf, xferred_bytes, 2);
- tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, (uint16_t) xferred_bytes);
+ TU_LOG2(" Get Report callback (%u, %u)\r\n", daddr, idx);
+ TU_LOG3_MEM(p_hid->epin_buf, xferred_bytes, 2);
+ tuh_hid_report_received_cb(daddr, idx, p_hid->epin_buf, (uint16_t) xferred_bytes);
}else
{
- if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, (uint16_t) xferred_bytes);
+ if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(daddr, idx, p_hid->epout_buf, (uint16_t) xferred_bytes);
}
return true;
}
-void hidh_close(uint8_t dev_addr)
+void hidh_close(uint8_t daddr)
{
- TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, );
-
- hidh_device_t* hid_dev = get_dev(dev_addr);
-
- if (tuh_hid_umount_cb)
+ for(uint8_t i=0; i<CFG_TUH_HID; i++)
{
- for (uint8_t inst = 0; inst < hid_dev->inst_count; inst++ ) tuh_hid_umount_cb(dev_addr, inst);
+ hidh_interface_t* p_hid = &_hidh_itf[i];
+ if (p_hid->daddr == daddr)
+ {
+ if(tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i);
+ p_hid->daddr = 0;
+ }
}
-
- tu_memclr(hid_dev, sizeof(hidh_device_t));
}
//--------------------------------------------------------------------+
// Enumeration
//--------------------------------------------------------------------+
-bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
+bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
{
(void) rhport;
(void) max_len;
TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass);
- TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber);
+ TU_LOG2("[%u] HID opening Interface %u\r\n", daddr, desc_itf->bInterfaceNumber);
// len = interface + hid + n*endpoints
uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) +
@@ -344,12 +479,9 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType);
- // not enough interface, try to increase CFG_TUH_HID
- // TODO multiple devices
- hidh_device_t* hid_dev = get_dev(dev_addr);
- TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0);
-
- hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count);
+ hidh_interface_t* p_hid = find_new_itf();
+ TU_ASSERT(p_hid); // not enough interface, try to increase CFG_TUH_HID
+ p_hid->daddr = daddr;
//------------- Endpoint Descriptors -------------//
p_desc = tu_desc_next(p_desc);
@@ -358,34 +490,35 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
for(int i = 0; i < desc_itf->bNumEndpoints; i++)
{
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType);
- TU_ASSERT( tuh_edpt_open(dev_addr, desc_ep) );
+ TU_ASSERT( tuh_edpt_open(daddr, desc_ep) );
if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN)
{
- hid_itf->ep_in = desc_ep->bEndpointAddress;
- hid_itf->epin_size = tu_edpt_packet_size(desc_ep);
+ p_hid->ep_in = desc_ep->bEndpointAddress;
+ p_hid->epin_size = tu_edpt_packet_size(desc_ep);
}
else
{
- hid_itf->ep_out = desc_ep->bEndpointAddress;
- hid_itf->epout_size = tu_edpt_packet_size(desc_ep);
+ p_hid->ep_out = desc_ep->bEndpointAddress;
+ p_hid->epout_size = tu_edpt_packet_size(desc_ep);
}
p_desc = tu_desc_next(p_desc);
desc_ep = (tusb_desc_endpoint_t const *) p_desc;
}
- hid_dev->inst_count++;
-
- hid_itf->itf_num = desc_itf->bInterfaceNumber;
+ p_hid->itf_num = desc_itf->bInterfaceNumber;
// Assume bNumDescriptors = 1
- hid_itf->report_desc_type = desc_hid->bReportType;
- hid_itf->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength);
+ p_hid->report_desc_type = desc_hid->bReportType;
+ p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength);
// Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config
- hid_itf->protocol_mode = HID_PROTOCOL_BOOT;
- if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol;
+ p_hid->protocol_mode = HID_PROTOCOL_BOOT;
+ if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass )
+ {
+ p_hid->itf_protocol = desc_itf->bInterfaceProtocol;
+ }
return true;
}
@@ -401,16 +534,16 @@ enum {
CONFIG_COMPLETE
};
-static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len);
+static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len);
static void process_set_config(tuh_xfer_t* xfer);
-bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num)
+bool hidh_set_config(uint8_t daddr, uint8_t itf_num)
{
tusb_control_request_t request;
request.wIndex = tu_htole16((uint16_t) itf_num);
tuh_xfer_t xfer;
- xfer.daddr = dev_addr;
+ xfer.daddr = daddr;
xfer.result = XFER_RESULT_SUCCESS;
xfer.setup = &request;
xfer.user_data = CONFG_SET_IDLE;
@@ -423,8 +556,10 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num)
static void process_set_config(tuh_xfer_t* xfer)
{
- // Stall is a valid response for SET_IDLE, therefore we could ignore its result
- if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE )
+ // Stall is a valid response for SET_IDLE, sometime SET_PROTOCOL as well
+ // therefore we could ignore its result
+ if ( !(xfer->setup->bRequest == HID_REQ_CONTROL_SET_IDLE ||
+ xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL) )
{
TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
}
@@ -433,8 +568,9 @@ static void process_set_config(tuh_xfer_t* xfer)
uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
uint8_t const daddr = xfer->daddr;
- uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num);
- hidh_interface_t* hid_itf = get_instance(daddr, instance);
+ uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num);
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid, );
switch(state)
{
@@ -442,27 +578,27 @@ static void process_set_config(tuh_xfer_t* xfer)
{
// Idle rate = 0 mean only report when there is changes
const uint16_t idle_rate = 0;
- const uintptr_t next_state = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC;
+ const uintptr_t next_state = (p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC;
_hidh_set_idle(daddr, itf_num, idle_rate, process_set_config, next_state);
}
break;
case CONFIG_SET_PROTOCOL:
- _hidh_set_protocol(daddr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC);
+ _hidh_set_protocol(daddr, p_hid->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC);
break;
case CONFIG_GET_REPORT_DESC:
// Get Report Descriptor if possible
// using usbh enumeration buffer since report descriptor can be very long
- if( hid_itf->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE )
+ if( p_hid->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE )
{
- TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len);
+ TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", p_hid->report_desc_len);
// Driver is mounted without report descriptor
- config_driver_mount_complete(daddr, instance, NULL, 0);
+ config_driver_mount_complete(daddr, idx, NULL, 0);
}else
{
- tuh_descriptor_get_hid_report(daddr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE);
+ tuh_descriptor_get_hid_report(daddr, itf_num, p_hid->report_desc_type, 0, usbh_get_enum_buf(), p_hid->report_desc_len, process_set_config, CONFIG_COMPLETE);
}
break;
@@ -471,7 +607,7 @@ static void process_set_config(tuh_xfer_t* xfer)
uint8_t const* desc_report = usbh_get_enum_buf();
uint16_t const desc_len = tu_le16toh(xfer->setup->wLength);
- config_driver_mount_complete(daddr, instance, desc_report, desc_len);
+ config_driver_mount_complete(daddr, idx, desc_report, desc_len);
}
break;
@@ -479,15 +615,16 @@ static void process_set_config(tuh_xfer_t* xfer)
}
}
-static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len)
+static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len)
{
- hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
+ hidh_interface_t* p_hid = get_hid_itf(daddr, idx);
+ TU_VERIFY(p_hid, );
// enumeration is complete
- tuh_hid_mount_cb(dev_addr, instance, desc_report, desc_len);
+ if (tuh_hid_mount_cb) tuh_hid_mount_cb(daddr, idx, desc_report, desc_len);
// notify usbh that driver enumeration is complete
- usbh_driver_set_config_complete(dev_addr, hid_itf->itf_num);
+ usbh_driver_set_config_complete(daddr, p_hid->itf_num);
}
//--------------------------------------------------------------------+
@@ -632,46 +769,4 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr,
return report_num;
}
-//--------------------------------------------------------------------+
-// Helper
-//--------------------------------------------------------------------+
-
-// Get Device by address
-TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr)
-{
- return &_hidh_dev[dev_addr-1];
-}
-
-// Get Interface by instance number
-TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t instance)
-{
- return &_hidh_dev[dev_addr-1].instances[instance];
-}
-
-// Get instance ID by interface number
-static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf)
-{
- for ( uint8_t inst = 0; inst < CFG_TUH_HID; inst++ )
- {
- hidh_interface_t *hid = get_instance(dev_addr, inst);
-
- if ( (hid->itf_num == itf) && (hid->ep_in || hid->ep_out) ) return inst;
- }
-
- return 0xff;
-}
-
-// Get instance ID by endpoint address
-static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr)
-{
- for ( uint8_t inst = 0; inst < CFG_TUH_HID; inst++ )
- {
- hidh_interface_t *hid = get_instance(dev_addr, inst);
-
- if ( (ep_addr == hid->ep_in) || ( ep_addr == hid->ep_out) ) return inst;
- }
-
- return 0xff;
-}
-
#endif
diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h
index ffc601d77..08ad421d2 100644
--- a/src/class/hid/hid_host.h
+++ b/src/class/hid/hid_host.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -62,14 +62,27 @@ typedef struct
// Interface API
//--------------------------------------------------------------------+
-// Get the number of HID instances
-uint8_t tuh_hid_instance_count(uint8_t dev_addr);
+// Get the total number of mounted HID interfaces of a device
+uint8_t tuh_hid_itf_get_count(uint8_t dev_addr);
-// Check if HID instance is mounted
-bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance);
+// Get all mounted interfaces across devices
+uint8_t tuh_hid_itf_get_total_count(void);
+
+// backward compatible rename
+#define tuh_hid_instance_count tuh_hid_itf_get_count
+
+// Get Interface information
+bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* itf_info);
+
+// Get Interface index from device address + interface number
+// return TUSB_INDEX_INVALID_8 (0xFF) if not found
+uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num);
// Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values
-uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance);
+uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t idx);
+
+// Check if HID interface is mounted
+bool tuh_hid_mounted(uint8_t dev_addr, uint8_t idx);
// Parse report descriptor into array of report_info struct and return number of reports.
// For complicated report, application should write its own parser.
@@ -82,31 +95,34 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr,
// Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1)
// Note: Device will be initialized in Boot protocol for simplicity.
// Application can use set_protocol() to switch back to Report protocol.
-uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance);
+uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t idx);
// Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1)
// This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE)
-bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol);
+bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol);
// Set Report using control endpoint
// report_type is either Input, Output or Feature, (value from hid_report_type_t)
-bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len);
+bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len);
//--------------------------------------------------------------------+
// Interrupt Endpoint API
//--------------------------------------------------------------------+
-// Check if the interface is ready to use
-//bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance);
+// Check if HID interface is ready to receive report
+bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx);
// Try to receive next report on Interrupt Endpoint. Immediately return
// - true If succeeded, tuh_hid_report_received_cb() callback will be invoked when report is available
// - false if failed to queue the transfer e.g endpoint is busy
-bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance);
+bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t idx);
+
+// Check if HID interface is ready to send report
+bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx);
// Send report using interrupt endpoint
// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is sent.
-//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len);
+bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len);
//--------------------------------------------------------------------+
// Callbacks (Weak is optional)
@@ -117,24 +133,24 @@ bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance);
// can be used to parse common/simple enough descriptor.
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
// therefore report_desc = NULL, desc_len = 0
-void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report_desc, uint16_t desc_len);
+TU_ATTR_WEAK void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report_desc, uint16_t desc_len);
// Invoked when device with hid interface is un-mounted
-TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance);
+TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t idx);
// Invoked when received report from device via interrupt endpoint
// Note: if there is report ID (composite), it is 1st byte of report
-void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len);
// Invoked when sent report to device successfully via interrupt endpoint
-TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
+TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len);
// Invoked when Sent Report to device via either control endpoint
// len = 0 indicate there is error in the transfer e.g stalled response
-TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, uint16_t len);
+TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len);
// Invoked when Set Protocol request is complete
-TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t protocol);
+TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t protocol);
//--------------------------------------------------------------------+
// Internal Class Driver API
diff --git a/src/class/midi/midi.h b/src/class/midi/midi.h
index 74dc41749..8b78c6555 100644
--- a/src/class/midi/midi.h
+++ b/src/class/midi/midi.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c
index 5dea43431..e3e7826da 100644
--- a/src/class/midi/midi_device.c
+++ b/src/class/midi/midi_device.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h
index 211edc8d1..1c6f996be 100644
--- a/src/class/midi/midi_device.h
+++ b/src/class/midi/midi_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h
index 84b6e4d79..7f25a29ba 100644
--- a/src/class/msc/msc.h
+++ b/src/class/msc/msc.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h
index 5839b168d..72f95be06 100644
--- a/src/class/msc/msc_device.h
+++ b/src/class/msc/msc_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index 6724e486c..1b48813ec 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -71,15 +71,15 @@ typedef struct
tuh_msc_complete_cb_t complete_cb;
uintptr_t complete_arg;
- msc_cbw_t cbw;
- msc_csw_t csw;
+ CFG_TUH_MEM_ALIGN msc_cbw_t cbw;
+ CFG_TUH_MEM_ALIGN msc_csw_t csw;
}msch_interface_t;
-CFG_TUSB_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX];
+CFG_TUH_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX];
// buffer used to read scsi information when mounted
// largest response data currently is inquiry TODO Inquiry is not part of enum anymore
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4)
+CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN
static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)];
TU_ATTR_ALWAYS_INLINE
@@ -232,23 +232,23 @@ bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba,
msc_cbw_t cbw;
cbw_init(&cbw, lun);
-
+
cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
cbw.dir = TUSB_DIR_IN_MASK;
cbw.cmd_len = sizeof(scsi_read10_t);
-
+
scsi_read10_t const cmd_read10 =
{
.cmd_code = SCSI_CMD_READ_10,
.lba = tu_htonl(lba),
.block_count = tu_htons(block_count)
};
-
+
memcpy(cbw.command, &cmd_read10, cbw.cmd_len);
-
+
return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg);
}
-
+
bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h
index 5134b63c2..6c0e5c9dd 100644
--- a/src/class/msc/msc_host.h
+++ b/src/class/msc/msc_host.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c
index a072bfd79..8ac7cbd01 100644
--- a/src/class/net/ecm_rndis_device.c
+++ b/src/class/net/ecm_rndis_device.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Peter Lawrence
diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c
index aa13c9535..9e9580249 100644
--- a/src/class/net/ncm_device.c
+++ b/src/class/net/ncm_device.c
@@ -430,7 +430,7 @@ static void handle_incoming_datagram(uint32_t len)
{
ncm_interface.num_datagrams++;
}
-
+
tud_network_recv_renew();
}
diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h
index 6e294465b..399916355 100644
--- a/src/class/net/net_device.h
+++ b/src/class/net/net_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Peter Lawrence
@@ -94,7 +94,7 @@ void tud_network_init_cb(void);
// client must provide this: 48-bit MAC address
// TODO removed later since it is not part of tinyusb stack
-extern const uint8_t tud_network_mac_address[6];
+extern uint8_t tud_network_mac_address[6];
//------------- NCM -------------//
diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h
index fd52d766e..090ab3c4a 100644
--- a/src/class/usbtmc/usbtmc.h
+++ b/src/class/usbtmc/usbtmc.h
@@ -262,14 +262,14 @@ typedef struct TU_ATTR_PACKED
struct TU_ATTR_PACKED
{
- unsigned int listenOnly :1;
- unsigned int talkOnly :1;
- unsigned int supportsIndicatorPulse :1;
+ uint8_t listenOnly :1;
+ uint8_t talkOnly :1;
+ uint8_t supportsIndicatorPulse :1;
} bmIntfcCapabilities;
struct TU_ATTR_PACKED
{
- unsigned int canEndBulkInOnTermChar :1;
+ uint8_t canEndBulkInOnTermChar :1;
} bmDevCapabilities;
uint8_t _reserved2[6];
@@ -277,17 +277,17 @@ typedef struct TU_ATTR_PACKED
struct TU_ATTR_PACKED
{
- unsigned int is488_2 :1;
- unsigned int supportsREN_GTL_LLO :1;
- unsigned int supportsTrigger :1;
+ uint8_t supportsTrigger :1;
+ uint8_t supportsREN_GTL_LLO :1;
+ uint8_t is488_2 :1;
} bmIntfcCapabilities488;
struct TU_ATTR_PACKED
{
- unsigned int SCPI :1;
- unsigned int SR1 :1;
- unsigned int RL1 :1;
- unsigned int DT1 :1;
+ uint8_t DT1 :1;
+ uint8_t RL1 :1;
+ uint8_t SR1 :1;
+ uint8_t SCPI :1;
} bmDevCapabilities488;
uint8_t _reserved3[8];
} usbtmc_response_capabilities_488_t;
@@ -316,4 +316,3 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length");
#endif
-
diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c
index a4e6eaeb3..4e320a778 100644
--- a/src/class/usbtmc/usbtmc_device.c
+++ b/src/class/usbtmc/usbtmc_device.c
@@ -83,7 +83,7 @@ tu_static char logMsg[150];
// Buffer size must be an exact multiple of the max packet size for both
// bulk (up to 64 bytes for FS, 512 bytes for HS). In addation, this driver
-// imposes a minimum buffer size of 32 bytes.
+// imposes a minimum buffer size of 32 bytes.
#define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
/*
@@ -154,7 +154,10 @@ TU_VERIFY_STATIC(USBTMCD_BUFFER_SIZE >= 32u,"USBTMC dev buffer size too small");
static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len);
static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen);
+#ifndef NDEBUG
tu_static uint8_t termChar;
+#endif
+
tu_static uint8_t termCharRequested = false;
#if OSAL_MUTEX_REQUIRED
@@ -442,7 +445,10 @@ static bool handle_devMsgIn(void *data, size_t len)
usbtmc_state.transfer_size_sent = 0u;
termCharRequested = msg->bmTransferAttributes.TermCharEnabled;
+
+#ifndef NDEBUG
termChar = msg->TermChar;
+#endif
if(termCharRequested)
TU_VERIFY(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar);
@@ -511,6 +517,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
return true;
case STATE_ABORTING_BULK_OUT:
+ // Should be stalled by now, shouldn't have received a packet.
return false;
case STATE_TX_REQUESTED:
@@ -598,7 +605,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
uint32_t ep_addr = (request->wIndex);
// At this point, a transfer MAY be in progress. Based on USB spec, when clearing bulk EP HALT,
- // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if
+ // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if
// the EP is not halted. The only USBD API interface to do this is to stall and then un-stall the EP.
if(ep_addr == usbtmc_state.ep_bulk_out)
{
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index d07bd75ec..93596ee33 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -86,8 +86,8 @@ static void _prep_out_transaction (vendord_interface_t* p_itf)
{
uint8_t const rhport = 0;
- // skip if previous transfer not complete
- if ( usbd_edpt_busy(rhport, p_itf->ep_out) ) return;
+ // claim endpoint
+ TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_out), );
// Prepare for incoming data but only allow what we can store in the ring buffer.
uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff);
@@ -95,6 +95,11 @@ static void _prep_out_transaction (vendord_interface_t* p_itf)
{
usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE);
}
+ else
+ {
+ // Release endpoint since we don't make any transfer
+ usbd_edpt_release(rhport, p_itf->ep_out);
+ }
}
uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize)
@@ -115,37 +120,47 @@ void tud_vendor_n_read_flush (uint8_t itf)
//--------------------------------------------------------------------+
// Write API
//--------------------------------------------------------------------+
-static uint16_t maybe_transmit(vendord_interface_t* p_itf)
-{
- uint8_t const rhport = 0;
-
- // skip if previous transfer not complete
- TU_VERIFY( !usbd_edpt_busy(rhport, p_itf->ep_in) );
-
- uint16_t count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE);
- if (count > 0)
- {
- TU_ASSERT( usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, count) );
- }
- return count;
-}
-
uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize)
{
vendord_interface_t* p_itf = &_vendord_itf[itf];
uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize);
+
+ // flush if queue more than packet size
if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) {
- maybe_transmit(p_itf);
+ tud_vendor_n_write_flush(itf);
}
return ret;
}
-uint32_t tud_vendor_n_flush (uint8_t itf)
+uint32_t tud_vendor_n_write_flush (uint8_t itf)
{
vendord_interface_t* p_itf = &_vendord_itf[itf];
- uint32_t ret = maybe_transmit(p_itf);
- return ret;
+ // Skip if usb is not ready yet
+ TU_VERIFY( tud_ready(), 0 );
+
+ // No data to send
+ if ( !tu_fifo_count(&p_itf->tx_ff) ) return 0;
+
+ uint8_t const rhport = 0;
+
+ // Claim the endpoint
+ TU_VERIFY( usbd_edpt_claim(rhport, p_itf->ep_in), 0 );
+
+ // Pull data from FIFO
+ uint16_t const count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, sizeof(p_itf->epin_buf));
+
+ if ( count )
+ {
+ TU_ASSERT( usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, count), 0 );
+ return count;
+ }else
+ {
+ // Release endpoint since we don't make any transfer
+ // Note: data is dropped if terminal is not connected
+ usbd_edpt_release(rhport, p_itf->ep_in);
+ return 0;
+ }
}
uint32_t tud_vendor_n_write_available (uint8_t itf)
@@ -225,10 +240,10 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui
// Prepare for incoming data
if ( p_vendor->ep_out )
{
- TU_ASSERT(usbd_edpt_xfer(rhport, p_vendor->ep_out, p_vendor->epout_buf, sizeof(p_vendor->epout_buf)), 0);
+ _prep_out_transaction(p_vendor);
}
- if ( p_vendor->ep_in ) maybe_transmit(p_vendor);
+ if ( p_vendor->ep_in ) tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
}
return (uint16_t) ((uintptr_t) p_desc - (uintptr_t) desc_itf);
@@ -263,7 +278,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
{
if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes);
// Send complete, try to send more if possible
- maybe_transmit(p_itf);
+ tud_vendor_n_write_flush(itf);
}
return true;
diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h
index 2bb6afa67..d239406b4 100644
--- a/src/class/vendor/vendor_device.h
+++ b/src/class/vendor/vendor_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -48,10 +48,13 @@ bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8);
void tud_vendor_n_read_flush (uint8_t itf);
uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
+uint32_t tud_vendor_n_write_flush (uint8_t itf);
uint32_t tud_vendor_n_write_available (uint8_t itf);
static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str);
-uint32_t tud_vendor_n_flush (uint8_t itf);
+
+// backward compatible
+#define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf)
//--------------------------------------------------------------------+
// Application API (Single Port)
@@ -64,7 +67,10 @@ static inline void tud_vendor_read_flush (void);
static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize);
static inline uint32_t tud_vendor_write_str (char const* str);
static inline uint32_t tud_vendor_write_available (void);
-static inline uint32_t tud_vendor_flush (void);
+static inline uint32_t tud_vendor_write_flush (void);
+
+// backward compatible
+#define tud_vendor_flush() tud_vendor_write_flush()
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
@@ -114,6 +120,11 @@ static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize)
return tud_vendor_n_write(0, buffer, bufsize);
}
+static inline uint32_t tud_vendor_write_flush (void)
+{
+ return tud_vendor_n_write_flush(0);
+}
+
static inline uint32_t tud_vendor_write_str (char const* str)
{
return tud_vendor_n_write_str(0, str);
@@ -124,11 +135,6 @@ static inline uint32_t tud_vendor_write_available (void)
return tud_vendor_n_write_available(0);
}
-static inline uint32_t tud_vendor_flush (void)
-{
- return tud_vendor_n_flush(0);
-}
-
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
diff --git a/src/class/vendor/vendor_host.c b/src/class/vendor/vendor_host.c
index dbea1228d..e66c5007f 100644
--- a/src/class/vendor/vendor_host.c
+++ b/src/class/vendor/vendor_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/vendor/vendor_host.h b/src/class/vendor/vendor_host.h
index 65223fbca..acfebe7a4 100644
--- a/src/class/vendor/vendor_host.h
+++ b/src/class/vendor/vendor_host.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/video/video.h b/src/class/video/video.h
index e8227ea60..c0088c4f6 100644
--- a/src/class/video/video.h
+++ b/src/class/video/video.h
@@ -549,7 +549,7 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c
/* 3.10.1.1 */
#define TUD_VIDEO_DESC_EP_ISO(_ep, _epsize, _ep_interval) \
- 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS,\
+ 7, TUSB_DESC_ENDPOINT, _ep, (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS),\
U16_TO_U8S_LE(_epsize), _ep_interval
/* 3.10.1.2 */
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index 02a490aee..d6e98602b 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Koji KITAYAMA