101101 #define USE_LINEAR_BUFFER 1
102102#endif
103103
104- // Temporarily put the check here for stm32_fsdev
105- #ifdef TUP_USBIP_FSDEV
106- #define USE_ISO_EP_ALLOCATION 1
107- #else
108- #define USE_ISO_EP_ALLOCATION 0
109- #endif
110-
111104// Declaration of buffers
112105
113106// Check for maximum supported numbers
@@ -306,10 +299,12 @@ typedef struct
306299
307300#endif
308301
309- #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
310- uint8_t ep_int_ctr ; // Audio control interrupt EP.
302+ #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
303+ uint8_t ep_int ; // Audio control interrupt EP.
311304#endif
312305
306+ bool mounted ; // Device opened
307+
313308 /*------------- From this point, data is not cleared by bus reset -------------*/
314309
315310 uint16_t desc_length ; // Length of audio function descriptor
@@ -363,8 +358,8 @@ typedef struct
363358#endif
364359
365360 // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74)
366- #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
367- CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf [ CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE ];
361+ #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
362+ CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf [ 6 ];
368363#endif
369364
370365 // Decoding parameters - parameters are set when alternate AS interface is set by host
@@ -491,23 +486,7 @@ bool tud_audio_n_mounted(uint8_t func_id)
491486 TU_VERIFY (func_id < CFG_TUD_AUDIO );
492487 audiod_function_t * audio = & _audiod_fct [func_id ];
493488
494- #if CFG_TUD_AUDIO_ENABLE_EP_OUT
495- if (audio -> ep_out == 0 ) return false;
496- #endif
497-
498- #if CFG_TUD_AUDIO_ENABLE_EP_IN
499- if (audio -> ep_in == 0 ) return false;
500- #endif
501-
502- #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
503- if (audio -> ep_int_ctr == 0 ) return false;
504- #endif
505-
506- #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
507- if (audio -> ep_fb == 0 ) return false;
508- #endif
509-
510- return true;
489+ return audio -> mounted ;
511490}
512491
513492//--------------------------------------------------------------------+
@@ -830,24 +809,30 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx)
830809#endif
831810
832811
833- #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
834-
835- // 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
836- uint16_t tud_audio_int_ctr_n_write (uint8_t func_id , uint8_t const * buffer , uint16_t len )
812+ #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
813+ // If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user
814+ bool tud_audio_int_n_write (uint8_t func_id , const audio_interrupt_data_t * data )
837815{
838816 TU_VERIFY (func_id < CFG_TUD_AUDIO && _audiod_fct [func_id ].p_desc != NULL );
839817
840- // We write directly into the EP's buffer - abort if previous transfer not complete
841- TU_VERIFY (!usbd_edpt_busy (_audiod_fct [func_id ].rhport , _audiod_fct [func_id ].ep_int_ctr ));
818+ TU_VERIFY (_audiod_fct [func_id ].ep_int != 0 );
842819
843- TU_VERIFY (tu_memcpy_s (_audiod_fct [func_id ].ep_int_ctr_buf , CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE , buffer , len )== 0 );
820+ // We write directly into the EP's buffer - abort if previous transfer not complete
821+ TU_VERIFY (usbd_edpt_claim (_audiod_fct [func_id ].rhport , _audiod_fct [func_id ].ep_int ));
844822
845- // Schedule transmit
846- TU_VERIFY (usbd_edpt_xfer (_audiod_fct [func_id ].rhport , _audiod_fct [func_id ].ep_int_ctr , _audiod_fct [func_id ].ep_int_ctr_buf , len ));
823+ // Check length
824+ if (tu_memcpy_s (_audiod_fct [func_id ].ep_int_buf , sizeof (_audiod_fct [func_id ].ep_int_buf ), data , sizeof (audio_interrupt_data_t )) == 0 )
825+ {
826+ // Schedule transmit
827+ TU_ASSERT (usbd_edpt_xfer (_audiod_fct [func_id ].rhport , _audiod_fct [func_id ].ep_int , _audiod_fct [func_id ].ep_int_buf , sizeof (_audiod_fct [func_id ].ep_int_buf )), 0 );
828+ } else
829+ {
830+ // Release endpoint since we don't make any transfer
831+ usbd_edpt_release (_audiod_fct [func_id ].rhport , _audiod_fct [func_id ].ep_int );
832+ }
847833
848834 return true;
849835}
850-
851836#endif
852837
853838// This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission.
@@ -1409,6 +1394,10 @@ void audiod_init(void)
14091394 }
14101395}
14111396
1397+ bool audiod_deinit (void ) {
1398+ return false; // TODO not implemented yet
1399+ }
1400+
14121401void audiod_reset (uint8_t rhport )
14131402{
14141403 (void ) rhport ;
@@ -1452,10 +1441,11 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
14521441 // Verify version is correct - this check can be omitted
14531442 TU_VERIFY (itf_desc -> bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2 );
14541443
1455- // Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted
1456- if (itf_desc -> bNumEndpoints == 1 ) // 0 or 1 EPs are allowed
1444+ // Verify interrupt control EP is enabled if demanded by descriptor
1445+ TU_ASSERT (itf_desc -> bNumEndpoints <= 1 ); // 0 or 1 EPs are allowed
1446+ if (itf_desc -> bNumEndpoints == 1 )
14571447 {
1458- TU_VERIFY ( CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0 );
1448+ TU_ASSERT ( CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP );
14591449 }
14601450
14611451 // Alternate setting MUST be zero - this check can be omitted
@@ -1488,7 +1478,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
14881478#endif
14891479 }
14901480
1491- #if USE_ISO_EP_ALLOCATION
1481+ #ifdef TUP_DCD_EDPT_ISO_ALLOC
14921482 {
14931483 #if CFG_TUD_AUDIO_ENABLE_EP_IN
14941484 uint8_t ep_in = 0 ;
@@ -1564,7 +1554,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
15641554 }
15651555 #endif
15661556 }
1567- #endif // USE_ISO_EP_ALLOCATION
1557+ #endif // TUP_DCD_EDPT_ISO_ALLOC
15681558
15691559#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
15701560 {
@@ -1599,6 +1589,32 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
15991589 }
16001590#endif // CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
16011591
1592+ #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
1593+ {
1594+ uint8_t const * p_desc = _audiod_fct [i ].p_desc ;
1595+ uint8_t const * p_desc_end = p_desc + _audiod_fct [i ].desc_length - TUD_AUDIO_DESC_IAD_LEN ;
1596+ // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning
1597+ while (p_desc_end - p_desc > 0 )
1598+ {
1599+ // For each endpoint
1600+ if (tu_desc_type (p_desc ) == TUSB_DESC_ENDPOINT )
1601+ {
1602+ tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const * ) p_desc ;
1603+ uint8_t const ep_addr = desc_ep -> bEndpointAddress ;
1604+ // If endpoint is input-direction and interrupt-type
1605+ if (tu_edpt_dir (ep_addr ) == TUSB_DIR_IN && desc_ep -> bmAttributes .xfer == TUSB_XFER_INTERRUPT )
1606+ {
1607+ // Store endpoint number and open endpoint
1608+ _audiod_fct [i ].ep_int = ep_addr ;
1609+ TU_ASSERT (usbd_edpt_open (_audiod_fct [i ].rhport , desc_ep ));
1610+ }
1611+ }
1612+ p_desc = tu_desc_next (p_desc );
1613+ }
1614+ }
1615+ #endif
1616+
1617+ _audiod_fct [i ].mounted = true;
16021618 break ;
16031619 }
16041620 }
@@ -1660,7 +1676,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
16601676 if (audio -> ep_in_as_intf_num == itf )
16611677 {
16621678 audio -> ep_in_as_intf_num = 0 ;
1663- #if ! USE_ISO_EP_ALLOCATION
1679+ #ifndef TUP_DCD_EDPT_ISO_ALLOC
16641680 usbd_edpt_close (rhport , audio -> ep_in );
16651681 #endif
16661682
@@ -1691,7 +1707,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
16911707 if (audio -> ep_out_as_intf_num == itf )
16921708 {
16931709 audio -> ep_out_as_intf_num = 0 ;
1694- #if ! USE_ISO_EP_ALLOCATION
1710+ #ifndef TUP_DCD_EDPT_ISO_ALLOC
16951711 usbd_edpt_close (rhport , audio -> ep_out );
16961712 #endif
16971713
@@ -1712,7 +1728,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
17121728
17131729 // Close corresponding feedback EP
17141730 #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
1715- #if ! USE_ISO_EP_ALLOCATION
1731+ #ifndef TUP_DCD_EDPT_ISO_ALLOC
17161732 usbd_edpt_close (rhport , audio -> ep_fb );
17171733 #endif
17181734 audio -> ep_fb = 0 ;
@@ -1734,7 +1750,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
17341750 // Find correct interface
17351751 if (tu_desc_type (p_desc ) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc )-> bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc )-> bAlternateSetting == alt )
17361752 {
1737- #if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
1753+ #if ( CFG_TUD_AUDIO_ENABLE_EP_IN && ( CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING )) || ( CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING )
17381754 uint8_t const * p_desc_parse_for_params = p_desc ;
17391755#endif
17401756 // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary
@@ -1744,7 +1760,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
17441760 if (tu_desc_type (p_desc ) == TUSB_DESC_ENDPOINT )
17451761 {
17461762 tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const * ) p_desc ;
1747- #if USE_ISO_EP_ALLOCATION
1763+ #ifdef TUP_DCD_EDPT_ISO_ALLOC
17481764 TU_ASSERT (usbd_edpt_iso_activate (rhport , desc_ep ));
17491765#else
17501766 TU_ASSERT (usbd_edpt_open (rhport , desc_ep ));
@@ -2004,7 +2020,10 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const
20042020 case TUSB_REQ_SET_INTERFACE :
20052021 return audiod_set_interface (rhport , p_request );
20062022
2007- // Unknown/Unsupported request
2023+ case TUSB_REQ_CLEAR_FEATURE :
2024+ return true;
2025+
2026+ // Unknown/Unsupported request
20082027 default : TU_BREAKPOINT (); return false;
20092028 }
20102029 }
@@ -2125,10 +2144,10 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
21252144 {
21262145 audiod_function_t * audio = & _audiod_fct [func_id ];
21272146
2128- #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
2147+ #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
21292148
21302149 // Data transmission of control interrupt finished
2131- if (audio -> ep_int_ctr == ep_addr )
2150+ if (audio -> ep_int == ep_addr )
21322151 {
21332152 // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49)
21342153 // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ???
@@ -2137,7 +2156,8 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
21372156 // I assume here, that things above are handled by PHY
21382157 // All transmission is done - what remains to do is to inform job was completed
21392158
2140- if (tud_audio_int_ctr_done_cb ) TU_VERIFY (tud_audio_int_ctr_done_cb (rhport , (uint16_t ) xferred_bytes ));
2159+ if (tud_audio_int_done_cb ) tud_audio_int_done_cb (rhport );
2160+ return true;
21412161 }
21422162
21432163#endif
0 commit comments