summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2021-04-16 01:59:47 +0700
committerGitHub <[email protected]>2021-04-16 01:59:47 +0700
commitc611199632b9288eff76c1c4bfdce5d8cc024748 (patch)
tree8ccd5c0b34b4f1eb89276fce866ee34a9ff608e1 /src/device
parent93dffba0ac905d8525c3092a52888e1a5db96390 (diff)
parentc7e4a8616640165b48cfb0ba4f9346982faa4344 (diff)
Merge pull request #593 from hathach/edpt_ISO_xfer
Edpt iso xfer
Diffstat (limited to 'src/device')
-rw-r--r--src/device/dcd.h15
-rw-r--r--src/device/usbd.c37
-rw-r--r--src/device/usbd.h59
-rw-r--r--src/device/usbd_pvt.h3
4 files changed, 104 insertions, 10 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h
index b7e5a8da0..1e5b3ff1e 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -32,6 +32,7 @@
#define _TUSB_DCD_H_
#include "common/tusb_common.h"
+#include "common/tusb_fifo.h"
#ifdef __cplusplus
extern "C" {
@@ -124,20 +125,24 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
// Configure endpoint's registers according to descriptor
-bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
+bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
// Close an endpoint.
// Since it is weak, caller must TU_ASSERT this function's existence before calling it.
-void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK;
+void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK;
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
-bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+
+// Submit an transfer using fifo, When complete dcd_event_xfer_complete() is invoked to notify the stack
+// This API is optional, may be useful for register-based for transferring data.
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) TU_ATTR_WEAK;
// Stall endpoint
-void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
+void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
// clear stall, data toggle is also reset to DATA0
-void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
+void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
//--------------------------------------------------------------------+
// Event API (implemented by stack)
diff --git a/src/device/usbd.c b/src/device/usbd.c
index ca5a482fc..8a3d8ec2f 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -29,9 +29,9 @@
#if TUSB_OPT_DEVICE_ENABLED
#include "tusb.h"
-#include "usbd.h"
+#include "device/usbd.h"
#include "device/usbd_pvt.h"
-#include "dcd.h"
+#include "device/dcd.h"
#ifndef CFG_TUD_TASK_QUEUE_SZ
#define CFG_TUD_TASK_QUEUE_SZ 16
@@ -1241,6 +1241,39 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
}
}
+// The number of bytes has to be given explicitly to allow more flexible control of how many
+// bytes should be written and second to keep the return value free to give back a boolean
+// success message. If total_bytes is too big, the FIFO will copy only what is available
+// into the USB buffer!
+bool usbd_edpt_iso_xfer(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ TU_LOG2(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
+
+ // Attempt to transfer on a busy endpoint, sound like an race condition !
+ TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
+
+ // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
+ // and usbd task can preempt and clear the busy
+ _usbd_dev.ep_status[epnum][dir].busy = true;
+
+ if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
+ {
+ TU_LOG2("OK\r\n");
+ return true;
+ }else
+ {
+ // DCD error, mark endpoint as ready to allow next transfer
+ _usbd_dev.ep_status[epnum][dir].busy = false;
+ _usbd_dev.ep_status[epnum][dir].claimed = 0;
+ TU_LOG2("failed\r\n");
+ TU_BREAKPOINT();
+ return false;
+ }
+}
+
bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
diff --git a/src/device/usbd.h b/src/device/usbd.h
index 56615b081..7c50a6db0 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -353,6 +353,10 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
#define TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN (6+(2+1)*4)
#define TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _ctrlch2, _stridx) \
TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), U32_TO_U8S_LE(_ctrlch2), _stridx
+// 4 - Channels
+#define TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN (6+(4+1)*4)
+#define TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL(_unitid, _srcid, _ctrlch0master, _ctrlch1, _ctrlch2, _ctrlch3, _ctrlch4, _stridx) \
+ TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN, TUSB_DESC_CS_INTERFACE, AUDIO_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, U32_TO_U8S_LE(_ctrlch0master), U32_TO_U8S_LE(_ctrlch1), U32_TO_U8S_LE(_ctrlch2), U32_TO_U8S_LE(_ctrlch3), U32_TO_U8S_LE(_ctrlch4), _stridx
// For more channels, add definitions here
@@ -389,7 +393,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
// AUDIO simple descriptor (UAC2) for 1 microphone input
// - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source
-#define TUD_AUDIO_MIC_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\
+#define TUD_AUDIO_MIC_ONE_CH_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\
+ TUD_AUDIO_DESC_STD_AC_LEN\
+ TUD_AUDIO_DESC_CS_AC_LEN\
+ TUD_AUDIO_DESC_CLK_SRC_LEN\
@@ -403,9 +407,9 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
+ TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\
+ TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN)
-#define TUD_AUDIO_MIC_DESC_N_AS_INT 1 // Number of AS interfaces
+#define TUD_AUDIO_MIC_ONE_CH_DESC_N_AS_INT 1 // Number of AS interfaces
-#define TUD_AUDIO_MIC_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \
+#define TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \
/* Standard Interface Association Descriptor (IAD) */\
TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\
/* Standard AC Interface Descriptor(4.7.1) */\
@@ -435,6 +439,55 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
/* 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)
+// AUDIO simple descriptor (UAC2) for 4 microphone input
+// - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source
+
+#define TUD_AUDIO_MIC_FOUR_CH_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\
+ + TUD_AUDIO_DESC_STD_AC_LEN\
+ + TUD_AUDIO_DESC_CS_AC_LEN\
+ + TUD_AUDIO_DESC_CLK_SRC_LEN\
+ + TUD_AUDIO_DESC_INPUT_TERM_LEN\
+ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\
+ + TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN\
+ + TUD_AUDIO_DESC_STD_AS_INT_LEN\
+ + TUD_AUDIO_DESC_STD_AS_INT_LEN\
+ + TUD_AUDIO_DESC_CS_AS_INT_LEN\
+ + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\
+ + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\
+ + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN)
+
+#define TUD_AUDIO_MIC_FOUR_CH_DESC_N_AS_INT 1 // Number of AS interfaces
+
+#define TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \
+ /* Standard Interface Association Descriptor (IAD) */\
+ TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\
+ /* Standard AC Interface Descriptor(4.7.1) */\
+ TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\
+ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\
+ TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\
+ /* Clock Source Descriptor(4.7.2.1) */\
+ TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO_CTRL_R << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\
+ /* Input Terminal Descriptor(4.7.2.4) */\
+ TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x03, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x04, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00),\
+ /* Output Terminal Descriptor(4.7.2.5) */\
+ TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
+ /* Feature Unit Descriptor(4.7.2.8) */\
+ TUD_AUDIO_DESC_FEATURE_UNIT_FOUR_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch3*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch4*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_stridx*/ 0x00),\
+ /* Standard AS Interface Descriptor(4.9.1) */\
+ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\
+ TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\
+ /* Standard AS Interface Descriptor(4.9.1) */\
+ /* Interface 1, Alternate 1 - alternate interface for data streaming */\
+ TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum)+1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00),\
+ /* Class-Specific AS Interface Descriptor(4.9.2) */\
+ TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x03, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x04, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
+ /* 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*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 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)
+
// AUDIO simple descriptor (UAC2) for mono speaker
// - 1 Input Terminal, 2 Feature Unit (Mute and Volume Control), 3 Output Terminal, 4 Clock Source
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 212c3a202..412a97a5d 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -72,6 +72,9 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr);
// Submit a usb transfer
bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+// Submit a usb ISO transfer by use of a FIFO (ring buffer) - all bytes in FIFO get transmitted
+bool usbd_edpt_iso_xfer(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes);
+
// Claim an endpoint before submitting a transfer.
// If caller does not make any transfer, it must release endpoint for others.
bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr);