summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class/audio/audio_device.c58
-rw-r--r--src/class/audio/audio_device.h46
2 files changed, 96 insertions, 8 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index a65d605b7..05339f9ce 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -341,7 +341,7 @@ typedef struct
// Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74)
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE];
+ CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE];
#endif
// Decoding parameters - parameters are set when alternate AS interface is set by host
@@ -464,7 +464,7 @@ bool tud_audio_n_mounted(uint8_t func_id)
if (audio->ep_in == 0) return false;
#endif
-#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
if (audio->ep_int_ctr == 0) return false;
#endif
@@ -813,11 +813,13 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx)
#endif
-#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_ctr_done_cb() is called in inform user
uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len)
{
+ TU_VERIFY(_audiod_fct[func_id].ep_int_ctr != 0);
+
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL);
// We write directly into the EP's buffer - abort if previous transfer not complete
@@ -1079,6 +1081,52 @@ static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio)
}
#endif
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
+static bool set_int_ctr_number(audiod_function_t *audio)
+{
+
+ uint8_t const *p_desc = audio->p_desc;
+ // Get pointer at end
+ uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN;
+
+
+ // p_desc starts at required interface with alternate setting zero
+ while (p_desc < p_desc_end)
+ {
+ // Find correct interface
+ if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == 0 && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0)
+ {
+
+ uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints;
+ while (foundEPs < nEps && p_desc < p_desc_end)
+ {
+ // found :n endpoint
+ if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT)
+ {
+ tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc;
+
+ uint8_t const ep_addr = desc_ep->bEndpointAddress;
+
+ if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == 0x03) // Check if usage is interrupt EP
+ {
+ audio->ep_int_ctr = ep_addr;
+ TU_ASSERT(usbd_edpt_open(audio->rhport, desc_ep));
+ }
+
+ foundEPs += 1;
+ }
+ p_desc = tu_desc_next(p_desc);
+ }
+ break;
+ }
+ p_desc = tu_desc_next(p_desc);
+ }
+
+ return true;
+
+}
+#endif
+
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
@@ -1484,6 +1532,10 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
// This is all we need so far - the EPs are setup by a later set_interface request (as per UAC2 specification)
uint16_t drv_len = _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; // - TUD_AUDIO_DESC_IAD_LEN since tinyUSB already handles the IAD descriptor
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
+ TU_ASSERT(set_int_ctr_number(&_audiod_fct[i]));
+#endif
+
return drv_len;
}
diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h
index 0ef100fa4..0c394d235 100644
--- a/src/class/audio/audio_device.h
+++ b/src/class/audio/audio_device.h
@@ -191,9 +191,19 @@
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1
#endif
+// Enable/disable interrupt EP (required for notifying host of control changes)
+#ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
+#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1
+#endif
+
// Audio interrupt control EP size - disabled if 0
#ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
-#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74)
+// Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74)
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
+#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 6
+#else
+#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0
+#endif
#endif
#ifndef CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE
@@ -388,7 +398,7 @@ uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_i
tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_idx);
#endif
-#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
uint16_t tud_audio_int_ctr_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len);
#endif
@@ -431,7 +441,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx);
// INT CTR API
-#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
static inline uint16_t tud_audio_int_ctr_write (uint8_t const* buffer, uint16_t len);
#endif
@@ -531,7 +541,33 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
-#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
+// UAC2 ยง9.6
+// Structure of "interrupt data message"
+typedef struct TU_ATTR_PACKED
+{
+ uint8_t bInfo;
+ uint8_t bAttribute;
+ union TU_ATTR_PACKED
+ {
+ uint16_t wValue;
+ struct TU_ATTR_PACKED
+ {
+ uint8_t wValue_cn_or_mcn;
+ uint8_t wValue_cs;
+ };
+ };
+ union TU_ATTR_PACKED
+ {
+ uint16_t wIndex;
+ struct TU_ATTR_PACKED
+ {
+ uint8_t wIndex_ep_or_int;
+ uint8_t wIndex_entity_id;
+ };
+ };
+} audio_status_update_t;
+
TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied);
#endif
@@ -663,7 +699,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx)
#endif
-#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
+#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t len)
{
return tud_audio_int_ctr_n_write(0, buffer, len);