@@ -110,6 +110,7 @@ typedef enum {
110110 UAC_INTERFACE_STATE_READY , /*!< UAC Interface has started but stream is suspended */
111111 UAC_INTERFACE_STATE_ACTIVE , /*!< UAC Interface is streaming */
112112 UAC_INTERFACE_STATE_SUSPENDING , /*!< UAC Interface is suspending */
113+ UAC_INTERFACE_STATE
113114} uac_iface_state_t ;
114115
115116/**
@@ -202,8 +203,8 @@ static esp_err_t _uac_host_device_add(uint8_t addr, usb_device_handle_t dev_hdl,
202203static esp_err_t _uac_host_device_delete (uac_device_t * uac_device );
203204static esp_err_t uac_cs_request_set (uac_device_t * uac_device , const uac_cs_request_t * req );
204205static esp_err_t uac_cs_request_set_ep_frequency (uac_iface_t * iface , uint8_t ep_addr , uint32_t freq );
205- static esp_err_t uac_host_interface_suspend ( uac_iface_t * iface , bool root_port_suspended );
206- static esp_err_t uac_host_interface_resume ( uac_iface_t * iface , bool root_port_suspended );
206+ static void stream_rx_xfer_done ( usb_transfer_t * in_xfer );
207+ static void stream_tx_xfer_done ( usb_transfer_t * out_xfer );
207208
208209// --------------------------- Utility Functions --------------------------------
209210/**
@@ -1011,6 +1012,101 @@ static esp_err_t _uac_host_device_disconnected(usb_device_handle_t dev_hdl)
10111012}
10121013
10131014#ifdef UAC_HOST_SUSPEND_RESUME_API_SUPPORTED
1015+
1016+ /**
1017+ * @brief Global root port suspend was called, suspend an interface
1018+ *
1019+ * @param[in] iface Pointer to Interface structure,
1020+ * @return esp_err_t
1021+ */
1022+ static esp_err_t _uac_host_interface_pm_suspend (uac_iface_t * iface )
1023+ {
1024+ UAC_RETURN_ON_INVALID_ARG (iface );
1025+ UAC_RETURN_ON_INVALID_ARG (iface -> parent );
1026+ UAC_RETURN_ON_INVALID_ARG (iface -> free_xfer_list );
1027+ UAC_RETURN_ON_FALSE (is_interface_in_list (iface ), ESP_ERR_NOT_FOUND , "Interface handle not found" );
1028+ UAC_RETURN_ON_FALSE ((UAC_INTERFACE_STATE_ACTIVE == iface -> state ), ESP_ERR_INVALID_STATE , "Interface wrong state" );
1029+ iface -> state = UAC_INTERFACE_STATE_SUSPENDING ;
1030+
1031+ // EPs are already flushed and halted, managed by the usb_host_lib
1032+
1033+ _ring_buffer_flush (iface -> ringbuf );
1034+
1035+ // add all the transfer to free list
1036+ UAC_ENTER_CRITICAL ();
1037+ for (int i = 0 ; i < iface -> xfer_num ; i ++ ) {
1038+ if (iface -> xfer_list [i ]) {
1039+ iface -> free_xfer_list [i ] = iface -> xfer_list [i ];
1040+ iface -> xfer_list [i ] = NULL ;
1041+ }
1042+ }
1043+ UAC_EXIT_CRITICAL ();
1044+ // Change state
1045+ iface -> state = UAC_INTERFACE_STATE_READY ;
1046+
1047+ return ESP_OK ;
1048+ }
1049+
1050+ /**
1051+ * @brief Global root port resume was called, resume an interface
1052+ *
1053+ * @param[in] iface Pointer to Interface structure,
1054+ * @return esp_err_t
1055+ */
1056+ static esp_err_t _uac_host_interface_pm_resume (uac_iface_t * iface )
1057+ {
1058+ UAC_RETURN_ON_INVALID_ARG (iface );
1059+ UAC_RETURN_ON_INVALID_ARG (iface -> parent );
1060+ UAC_RETURN_ON_INVALID_ARG (iface -> free_xfer_list );
1061+ UAC_RETURN_ON_FALSE (is_interface_in_list (iface ), ESP_ERR_NOT_FOUND , "Interface handle not found" );
1062+ UAC_RETURN_ON_FALSE ((UAC_INTERFACE_STATE_READY == iface -> state ), ESP_ERR_INVALID_STATE , "Interface wrong state" );
1063+
1064+ // for RX, we just submit all the transfers
1065+ if (iface -> dev_info .type == UAC_STREAM_RX ) {
1066+ assert (iface -> iface_alt [iface -> cur_alt ].ep_addr & 0x80 );
1067+ for (int i = 0 ; i < iface -> xfer_num ; i ++ ) {
1068+ assert (iface -> free_xfer_list [i ]);
1069+ iface -> free_xfer_list [i ]-> device_handle = iface -> parent -> dev_hdl ;
1070+ iface -> free_xfer_list [i ]-> callback = stream_rx_xfer_done ;
1071+ iface -> free_xfer_list [i ]-> context = iface ;
1072+ iface -> free_xfer_list [i ]-> timeout_ms = DEFAULT_ISOC_XFER_TIMEOUT_MS ;
1073+ iface -> free_xfer_list [i ]-> bEndpointAddress = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1074+ // we request the size same as the MPS of the endpoint, but the actual size should be checked in the callback
1075+ iface -> free_xfer_list [i ]-> num_bytes = iface -> iface_alt [iface -> cur_alt ].ep_mps * iface -> packet_num ;
1076+ // set request nub_bytes of each packet
1077+ for (int j = 0 ; j < iface -> packet_num ; j ++ ) {
1078+ iface -> free_xfer_list [i ]-> isoc_packet_desc [j ].num_bytes = iface -> iface_alt [iface -> cur_alt ].ep_mps ;
1079+ }
1080+ iface -> xfer_list [i ] = iface -> free_xfer_list [i ];
1081+ iface -> free_xfer_list [i ] = NULL ;
1082+ UAC_RETURN_ON_ERROR (usb_host_transfer_submit (iface -> xfer_list [i ]), "Unable to submit RX transfer" );
1083+ }
1084+ } else if (iface -> dev_info .type == UAC_STREAM_TX ) {
1085+ assert (!(iface -> iface_alt [iface -> cur_alt ].ep_addr & 0x80 ));
1086+ // for TX, we submit the first transfer with data 0 to make the speaker quiet
1087+ for (int i = 0 ; i < iface -> xfer_num ; i ++ ) {
1088+ assert (iface -> free_xfer_list [i ]);
1089+ iface -> free_xfer_list [i ]-> device_handle = iface -> parent -> dev_hdl ;
1090+ iface -> free_xfer_list [i ]-> callback = stream_tx_xfer_done ;
1091+ iface -> free_xfer_list [i ]-> context = iface ;
1092+ iface -> free_xfer_list [i ]-> timeout_ms = DEFAULT_ISOC_XFER_TIMEOUT_MS ;
1093+ iface -> free_xfer_list [i ]-> bEndpointAddress = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1094+ // set the data buffer to 0
1095+ memset (iface -> free_xfer_list [i ]-> data_buffer , 0 , iface -> free_xfer_list [i ]-> data_buffer_size );
1096+ // for synchronous transfer type, the packet size depends on the actual sample rate, channels and bit resolution.
1097+ for (int j = 0 ; j < iface -> packet_num ; j ++ ) {
1098+ iface -> free_xfer_list [i ]-> isoc_packet_desc [j ].num_bytes = iface -> packet_size ;
1099+ }
1100+ iface -> free_xfer_list [i ]-> num_bytes = iface -> packet_num * iface -> packet_size ;
1101+ }
1102+ }
1103+
1104+ // for TX, we check if data is available in the ringbuffer, if yes, we submit the transfer
1105+ iface -> state = UAC_INTERFACE_STATE_ACTIVE ;
1106+
1107+ return ESP_OK ;
1108+ }
1109+
10141110/**
10151111 * @brief Handler for global (root port) suspend event
10161112 *
@@ -1034,7 +1130,7 @@ static esp_err_t _uac_host_device_suspended(usb_device_handle_t dev_hdl)
10341130 ESP_LOGD (TAG , "Suspending interface %p in %d state" , uac_iface , uac_iface -> state );
10351131
10361132 if (uac_iface -> state == UAC_INTERFACE_STATE_ACTIVE ) {
1037- uac_host_interface_suspend (uac_iface , true );
1133+ _uac_host_interface_pm_suspend (uac_iface );
10381134 }
10391135 uac_host_user_interface_callback (uac_iface , UAC_HOST_DEVICE_EVENT_SUSPENDED );
10401136 }
@@ -1070,7 +1166,7 @@ static esp_err_t _uac_host_device_resumed(usb_device_handle_t dev_hdl)
10701166
10711167 // The interface is in ready state, we must submit RX transfer(s) poll
10721168 if (uac_iface -> state == UAC_INTERFACE_STATE_READY ) {
1073- uac_host_interface_resume (uac_iface , true );
1169+ _uac_host_interface_pm_resume (uac_iface );
10741170 }
10751171 uac_host_user_interface_callback (uac_iface , UAC_HOST_DEVICE_EVENT_RESUMED );
10761172 }
@@ -1346,7 +1442,7 @@ static void stream_tx_xfer_done(usb_transfer_t *out_xfer)
13461442 * @param[in] iface Pointer to Interface structure
13471443 * @return esp_err_t
13481444 */
1349- static esp_err_t uac_host_interface_suspend (uac_iface_t * iface , bool root_port_suspended )
1445+ static esp_err_t uac_host_interface_suspend (uac_iface_t * iface )
13501446{
13511447 UAC_RETURN_ON_INVALID_ARG (iface );
13521448 UAC_RETURN_ON_INVALID_ARG (iface -> parent );
@@ -1356,23 +1452,20 @@ static esp_err_t uac_host_interface_suspend(uac_iface_t *iface, bool root_port_s
13561452 iface -> state = UAC_INTERFACE_STATE_SUSPENDING ;
13571453
13581454 // Set Interface alternate setting to 0
1359- if (!root_port_suspended ) {
1360- usb_setup_packet_t request ;
1361- USB_SETUP_PACKET_INIT_SET_INTERFACE (& request , iface -> dev_info .iface_num , 0 );
1362- esp_err_t ret = uac_cs_request_set (iface -> parent , (uac_cs_request_t * )& request );
1363- if (ret != ESP_OK ) {
1364- ESP_LOGW (TAG , "Set Interface %d-%d Failed" , iface -> dev_info .iface_num , 0 );
1365- } else {
1366- ESP_LOGI (TAG , "Set Interface %d-%d" , iface -> dev_info .iface_num , 0 );
1367- }
1455+ usb_setup_packet_t request ;
1456+ USB_SETUP_PACKET_INIT_SET_INTERFACE (& request , iface -> dev_info .iface_num , 0 );
1457+ esp_err_t ret = uac_cs_request_set (iface -> parent , (uac_cs_request_t * )& request );
1458+ if (ret != ESP_OK ) {
1459+ ESP_LOGW (TAG , "Set Interface %d-%d Failed" , iface -> dev_info .iface_num , 0 );
1460+ } else {
1461+ ESP_LOGI (TAG , "Set Interface %d-%d" , iface -> dev_info .iface_num , 0 );
13681462 }
13691463
1370- if (!root_port_suspended ) {
1371- uint8_t ep_addr = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1372- UAC_RETURN_ON_ERROR (usb_host_endpoint_halt (iface -> parent -> dev_hdl , ep_addr ), "Unable to HALT EP" );
1373- UAC_RETURN_ON_ERROR (usb_host_endpoint_flush (iface -> parent -> dev_hdl , ep_addr ), "Unable to FLUSH EP" );
1374- usb_host_endpoint_clear (iface -> parent -> dev_hdl , ep_addr );
1375- }
1464+ uint8_t ep_addr = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1465+ UAC_RETURN_ON_ERROR (usb_host_endpoint_halt (iface -> parent -> dev_hdl , ep_addr ), "Unable to HALT EP" );
1466+ UAC_RETURN_ON_ERROR (usb_host_endpoint_flush (iface -> parent -> dev_hdl , ep_addr ), "Unable to FLUSH EP" );
1467+ usb_host_endpoint_clear (iface -> parent -> dev_hdl , ep_addr );
1468+
13761469 _ring_buffer_flush (iface -> ringbuf );
13771470
13781471 // add all the transfer to free list
@@ -1396,7 +1489,7 @@ static esp_err_t uac_host_interface_suspend(uac_iface_t *iface, bool root_port_s
13961489 * @param[in] iface Pointer to Interface structure
13971490 * @return esp_err_t
13981491 */
1399- static esp_err_t uac_host_interface_resume (uac_iface_t * iface , bool root_port_suspended )
1492+ static esp_err_t uac_host_interface_resume (uac_iface_t * iface )
14001493{
14011494 UAC_RETURN_ON_INVALID_ARG (iface );
14021495 UAC_RETURN_ON_INVALID_ARG (iface -> parent );
@@ -1405,18 +1498,17 @@ static esp_err_t uac_host_interface_resume(uac_iface_t *iface, bool root_port_su
14051498 UAC_RETURN_ON_FALSE ((UAC_INTERFACE_STATE_READY == iface -> state ), ESP_ERR_INVALID_STATE , "Interface wrong state" );
14061499
14071500 // Set Interface alternate setting
1408- if (!root_port_suspended ) {
1409- usb_setup_packet_t request ;
1410- USB_SETUP_PACKET_INIT_SET_INTERFACE (& request , iface -> dev_info .iface_num , iface -> cur_alt + 1 );
1411- UAC_RETURN_ON_ERROR (uac_cs_request_set (iface -> parent , (uac_cs_request_t * )& request ), "Unable to set Interface alternate" );
1412- ESP_LOGI (TAG , "Set Interface %d-%d" , iface -> dev_info .iface_num , iface -> cur_alt + 1 );
1413- // Set endpoint frequency control
1414- if (iface -> iface_alt [iface -> cur_alt ].freq_ctrl_supported ) {
1415- ESP_LOGI (TAG , "Set EP %02X frequency %" PRIu32 , iface -> iface_alt [iface -> cur_alt ].ep_addr , iface -> iface_alt [iface -> cur_alt ].cur_sampling_freq );
1416- UAC_RETURN_ON_ERROR (uac_cs_request_set_ep_frequency (iface , iface -> iface_alt [iface -> cur_alt ].ep_addr ,
1417- iface -> iface_alt [iface -> cur_alt ].cur_sampling_freq ), "Unable to set endpoint frequency" );
1418- }
1501+ usb_setup_packet_t request ;
1502+ USB_SETUP_PACKET_INIT_SET_INTERFACE (& request , iface -> dev_info .iface_num , iface -> cur_alt + 1 );
1503+ UAC_RETURN_ON_ERROR (uac_cs_request_set (iface -> parent , (uac_cs_request_t * )& request ), "Unable to set Interface alternate" );
1504+ ESP_LOGI (TAG , "Set Interface %d-%d" , iface -> dev_info .iface_num , iface -> cur_alt + 1 );
1505+ // Set endpoint frequency control
1506+ if (iface -> iface_alt [iface -> cur_alt ].freq_ctrl_supported ) {
1507+ ESP_LOGI (TAG , "Set EP %02X frequency %" PRIu32 , iface -> iface_alt [iface -> cur_alt ].ep_addr , iface -> iface_alt [iface -> cur_alt ].cur_sampling_freq );
1508+ UAC_RETURN_ON_ERROR (uac_cs_request_set_ep_frequency (iface , iface -> iface_alt [iface -> cur_alt ].ep_addr ,
1509+ iface -> iface_alt [iface -> cur_alt ].cur_sampling_freq ), "Unable to set endpoint frequency" );
14191510 }
1511+
14201512 // for RX, we just submit all the transfers
14211513 if (iface -> dev_info .type == UAC_STREAM_RX ) {
14221514 assert (iface -> iface_alt [iface -> cur_alt ].ep_addr & 0x80 );
@@ -2208,7 +2300,7 @@ esp_err_t uac_host_device_close(uac_host_device_handle_t uac_dev_handle)
22082300
22092301 UAC_RETURN_ON_ERROR (uac_host_interface_try_lock (uac_iface , DEFAULT_CTRL_XFER_TIMEOUT_MS ), "UAC Interface is busy by other task" );
22102302 if (UAC_INTERFACE_STATE_ACTIVE == uac_iface -> state ) {
2211- UAC_GOTO_ON_ERROR (uac_host_interface_suspend (uac_iface , false ), "Unable to disable UAC Interface" );
2303+ UAC_GOTO_ON_ERROR (uac_host_interface_suspend (uac_iface ), "Unable to disable UAC Interface" );
22122304 }
22132305
22142306 if (UAC_INTERFACE_STATE_READY == uac_iface -> state ) {
@@ -2380,7 +2472,7 @@ esp_err_t uac_host_device_start(uac_host_device_handle_t uac_dev_handle, const u
23802472 iface_claimed = true;
23812473
23822474 if (!(iface -> flags & FLAG_STREAM_SUSPEND_AFTER_START )) {
2383- UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface , false ), "Unable to resume UAC Interface" );
2475+ UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface ), "Unable to resume UAC Interface" );
23842476 }
23852477 uac_host_interface_unlock (iface );
23862478 return ESP_OK ;
@@ -2405,7 +2497,7 @@ esp_err_t uac_host_device_suspend(uac_host_device_handle_t uac_dev_handle)
24052497 }
24062498 esp_err_t ret = ESP_OK ;
24072499 UAC_GOTO_ON_FALSE ((UAC_INTERFACE_STATE_ACTIVE == iface -> state ), ESP_ERR_INVALID_STATE , "device not active" );
2408- UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface , false ), "Unable to suspend UAC Interface" );
2500+ UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface ), "Unable to suspend UAC Interface" );
24092501
24102502 uac_host_interface_unlock (iface );
24112503 return ESP_OK ;
@@ -2428,7 +2520,7 @@ esp_err_t uac_host_device_resume(uac_host_device_handle_t uac_dev_handle)
24282520
24292521 esp_err_t ret = ESP_OK ;
24302522 UAC_GOTO_ON_FALSE ((UAC_INTERFACE_STATE_READY == iface -> state ), ESP_ERR_INVALID_STATE , "device not ready" );
2431- UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface , false ), "Unable to resume UAC Interface" );
2523+ UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface ), "Unable to resume UAC Interface" );
24322524
24332525 uac_host_interface_unlock (iface );
24342526 return ESP_OK ;
@@ -2446,7 +2538,7 @@ esp_err_t uac_host_device_stop(uac_host_device_handle_t uac_dev_handle)
24462538 esp_err_t ret = ESP_OK ;
24472539 UAC_RETURN_ON_ERROR (uac_host_interface_try_lock (iface , DEFAULT_CTRL_XFER_TIMEOUT_MS ), "Unable to lock UAC Interface" );
24482540 if (UAC_INTERFACE_STATE_ACTIVE == iface -> state ) {
2449- UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface , false ), "Unable to suspend UAC Interface" );
2541+ UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface ), "Unable to suspend UAC Interface" );
24502542 }
24512543
24522544 if (UAC_INTERFACE_STATE_READY == iface -> state ) {
0 commit comments