@@ -202,8 +202,8 @@ static esp_err_t _uac_host_device_add(uint8_t addr, usb_device_handle_t dev_hdl,
202202static esp_err_t _uac_host_device_delete (uac_device_t * uac_device );
203203static esp_err_t uac_cs_request_set (uac_device_t * uac_device , const uac_cs_request_t * req );
204204static 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 );
205+ static void stream_rx_xfer_done ( usb_transfer_t * in_xfer );
206+ static void stream_tx_xfer_done ( usb_transfer_t * out_xfer );
207207
208208// --------------------------- Utility Functions --------------------------------
209209/**
@@ -1011,6 +1011,101 @@ static esp_err_t _uac_host_device_disconnected(usb_device_handle_t dev_hdl)
10111011}
10121012
10131013#ifdef UAC_HOST_SUSPEND_RESUME_API_SUPPORTED
1014+
1015+ /**
1016+ * @brief Global root port suspend was called, suspend an interface
1017+ *
1018+ * @param[in] iface Pointer to Interface structure,
1019+ * @return esp_err_t
1020+ */
1021+ static esp_err_t _uac_host_interface_pm_suspend (uac_iface_t * iface )
1022+ {
1023+ UAC_RETURN_ON_INVALID_ARG (iface );
1024+ UAC_RETURN_ON_INVALID_ARG (iface -> parent );
1025+ UAC_RETURN_ON_INVALID_ARG (iface -> free_xfer_list );
1026+ UAC_RETURN_ON_FALSE (is_interface_in_list (iface ), ESP_ERR_NOT_FOUND , "Interface handle not found" );
1027+ UAC_RETURN_ON_FALSE ((UAC_INTERFACE_STATE_ACTIVE == iface -> state ), ESP_ERR_INVALID_STATE , "Interface wrong state" );
1028+ iface -> state = UAC_INTERFACE_STATE_SUSPENDING ;
1029+
1030+ // EPs are already flushed and halted, managed by the usb_host_lib
1031+
1032+ _ring_buffer_flush (iface -> ringbuf );
1033+
1034+ // add all the transfer to free list
1035+ UAC_ENTER_CRITICAL ();
1036+ for (int i = 0 ; i < iface -> xfer_num ; i ++ ) {
1037+ if (iface -> xfer_list [i ]) {
1038+ iface -> free_xfer_list [i ] = iface -> xfer_list [i ];
1039+ iface -> xfer_list [i ] = NULL ;
1040+ }
1041+ }
1042+ UAC_EXIT_CRITICAL ();
1043+ // Change state
1044+ iface -> state = UAC_INTERFACE_STATE_READY ;
1045+
1046+ return ESP_OK ;
1047+ }
1048+
1049+ /**
1050+ * @brief Global root port resume was called, resume an interface
1051+ *
1052+ * @param[in] iface Pointer to Interface structure,
1053+ * @return esp_err_t
1054+ */
1055+ static esp_err_t _uac_host_interface_pm_resume (uac_iface_t * iface )
1056+ {
1057+ UAC_RETURN_ON_INVALID_ARG (iface );
1058+ UAC_RETURN_ON_INVALID_ARG (iface -> parent );
1059+ UAC_RETURN_ON_INVALID_ARG (iface -> free_xfer_list );
1060+ UAC_RETURN_ON_FALSE (is_interface_in_list (iface ), ESP_ERR_NOT_FOUND , "Interface handle not found" );
1061+ UAC_RETURN_ON_FALSE ((UAC_INTERFACE_STATE_READY == iface -> state ), ESP_ERR_INVALID_STATE , "Interface wrong state" );
1062+
1063+ // for RX, we just submit all the transfers
1064+ if (iface -> dev_info .type == UAC_STREAM_RX ) {
1065+ assert (iface -> iface_alt [iface -> cur_alt ].ep_addr & 0x80 );
1066+ for (int i = 0 ; i < iface -> xfer_num ; i ++ ) {
1067+ assert (iface -> free_xfer_list [i ]);
1068+ iface -> free_xfer_list [i ]-> device_handle = iface -> parent -> dev_hdl ;
1069+ iface -> free_xfer_list [i ]-> callback = stream_rx_xfer_done ;
1070+ iface -> free_xfer_list [i ]-> context = iface ;
1071+ iface -> free_xfer_list [i ]-> timeout_ms = DEFAULT_ISOC_XFER_TIMEOUT_MS ;
1072+ iface -> free_xfer_list [i ]-> bEndpointAddress = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1073+ // we request the size same as the MPS of the endpoint, but the actual size should be checked in the callback
1074+ iface -> free_xfer_list [i ]-> num_bytes = iface -> iface_alt [iface -> cur_alt ].ep_mps * iface -> packet_num ;
1075+ // set request nub_bytes of each packet
1076+ for (int j = 0 ; j < iface -> packet_num ; j ++ ) {
1077+ iface -> free_xfer_list [i ]-> isoc_packet_desc [j ].num_bytes = iface -> iface_alt [iface -> cur_alt ].ep_mps ;
1078+ }
1079+ iface -> xfer_list [i ] = iface -> free_xfer_list [i ];
1080+ iface -> free_xfer_list [i ] = NULL ;
1081+ UAC_RETURN_ON_ERROR (usb_host_transfer_submit (iface -> xfer_list [i ]), "Unable to submit RX transfer" );
1082+ }
1083+ } else if (iface -> dev_info .type == UAC_STREAM_TX ) {
1084+ assert (!(iface -> iface_alt [iface -> cur_alt ].ep_addr & 0x80 ));
1085+ // for TX, we submit the first transfer with data 0 to make the speaker quiet
1086+ for (int i = 0 ; i < iface -> xfer_num ; i ++ ) {
1087+ assert (iface -> free_xfer_list [i ]);
1088+ iface -> free_xfer_list [i ]-> device_handle = iface -> parent -> dev_hdl ;
1089+ iface -> free_xfer_list [i ]-> callback = stream_tx_xfer_done ;
1090+ iface -> free_xfer_list [i ]-> context = iface ;
1091+ iface -> free_xfer_list [i ]-> timeout_ms = DEFAULT_ISOC_XFER_TIMEOUT_MS ;
1092+ iface -> free_xfer_list [i ]-> bEndpointAddress = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1093+ // set the data buffer to 0
1094+ memset (iface -> free_xfer_list [i ]-> data_buffer , 0 , iface -> free_xfer_list [i ]-> data_buffer_size );
1095+ // for synchronous transfer type, the packet size depends on the actual sample rate, channels and bit resolution.
1096+ for (int j = 0 ; j < iface -> packet_num ; j ++ ) {
1097+ iface -> free_xfer_list [i ]-> isoc_packet_desc [j ].num_bytes = iface -> packet_size ;
1098+ }
1099+ iface -> free_xfer_list [i ]-> num_bytes = iface -> packet_num * iface -> packet_size ;
1100+ }
1101+ }
1102+
1103+ // for TX, we check if data is available in the ringbuffer, if yes, we submit the transfer
1104+ iface -> state = UAC_INTERFACE_STATE_ACTIVE ;
1105+
1106+ return ESP_OK ;
1107+ }
1108+
10141109/**
10151110 * @brief Handler for global (root port) suspend event
10161111 *
@@ -1034,7 +1129,7 @@ static esp_err_t _uac_host_device_suspended(usb_device_handle_t dev_hdl)
10341129 ESP_LOGD (TAG , "Suspending interface %p in %d state" , uac_iface , uac_iface -> state );
10351130
10361131 if (uac_iface -> state == UAC_INTERFACE_STATE_ACTIVE ) {
1037- uac_host_interface_suspend (uac_iface , true );
1132+ _uac_host_interface_pm_suspend (uac_iface );
10381133 }
10391134 uac_host_user_interface_callback (uac_iface , UAC_HOST_DEVICE_EVENT_SUSPENDED );
10401135 }
@@ -1070,7 +1165,7 @@ static esp_err_t _uac_host_device_resumed(usb_device_handle_t dev_hdl)
10701165
10711166 // The interface is in ready state, we must submit RX transfer(s) poll
10721167 if (uac_iface -> state == UAC_INTERFACE_STATE_READY ) {
1073- uac_host_interface_resume (uac_iface , true );
1168+ _uac_host_interface_pm_resume (uac_iface );
10741169 }
10751170 uac_host_user_interface_callback (uac_iface , UAC_HOST_DEVICE_EVENT_RESUMED );
10761171 }
@@ -1346,7 +1441,7 @@ static void stream_tx_xfer_done(usb_transfer_t *out_xfer)
13461441 * @param[in] iface Pointer to Interface structure
13471442 * @return esp_err_t
13481443 */
1349- static esp_err_t uac_host_interface_suspend (uac_iface_t * iface , bool root_port_suspended )
1444+ static esp_err_t uac_host_interface_suspend (uac_iface_t * iface )
13501445{
13511446 UAC_RETURN_ON_INVALID_ARG (iface );
13521447 UAC_RETURN_ON_INVALID_ARG (iface -> parent );
@@ -1356,23 +1451,19 @@ static esp_err_t uac_host_interface_suspend(uac_iface_t *iface, bool root_port_s
13561451 iface -> state = UAC_INTERFACE_STATE_SUSPENDING ;
13571452
13581453 // 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- }
1454+ usb_setup_packet_t request ;
1455+ USB_SETUP_PACKET_INIT_SET_INTERFACE (& request , iface -> dev_info .iface_num , 0 );
1456+ esp_err_t ret = uac_cs_request_set (iface -> parent , (uac_cs_request_t * )& request );
1457+ if (ret != ESP_OK ) {
1458+ ESP_LOGW (TAG , "Set Interface %d-%d Failed" , iface -> dev_info .iface_num , 0 );
1459+ } else {
1460+ ESP_LOGI (TAG , "Set Interface %d-%d" , iface -> dev_info .iface_num , 0 );
13681461 }
13691462
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- }
1463+ uint8_t ep_addr = iface -> iface_alt [iface -> cur_alt ].ep_addr ;
1464+ UAC_RETURN_ON_ERROR (usb_host_endpoint_halt (iface -> parent -> dev_hdl , ep_addr ), "Unable to HALT EP" );
1465+ UAC_RETURN_ON_ERROR (usb_host_endpoint_flush (iface -> parent -> dev_hdl , ep_addr ), "Unable to FLUSH EP" );
1466+ usb_host_endpoint_clear (iface -> parent -> dev_hdl , ep_addr );
13761467 _ring_buffer_flush (iface -> ringbuf );
13771468
13781469 // add all the transfer to free list
@@ -1396,7 +1487,7 @@ static esp_err_t uac_host_interface_suspend(uac_iface_t *iface, bool root_port_s
13961487 * @param[in] iface Pointer to Interface structure
13971488 * @return esp_err_t
13981489 */
1399- static esp_err_t uac_host_interface_resume (uac_iface_t * iface , bool root_port_suspended )
1490+ static esp_err_t uac_host_interface_resume (uac_iface_t * iface )
14001491{
14011492 UAC_RETURN_ON_INVALID_ARG (iface );
14021493 UAC_RETURN_ON_INVALID_ARG (iface -> parent );
@@ -1405,17 +1496,15 @@ static esp_err_t uac_host_interface_resume(uac_iface_t *iface, bool root_port_su
14051496 UAC_RETURN_ON_FALSE ((UAC_INTERFACE_STATE_READY == iface -> state ), ESP_ERR_INVALID_STATE , "Interface wrong state" );
14061497
14071498 // 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- }
1499+ usb_setup_packet_t request ;
1500+ USB_SETUP_PACKET_INIT_SET_INTERFACE (& request , iface -> dev_info .iface_num , iface -> cur_alt + 1 );
1501+ UAC_RETURN_ON_ERROR (uac_cs_request_set (iface -> parent , (uac_cs_request_t * )& request ), "Unable to set Interface alternate" );
1502+ ESP_LOGI (TAG , "Set Interface %d-%d" , iface -> dev_info .iface_num , iface -> cur_alt + 1 );
1503+ // Set endpoint frequency control
1504+ if (iface -> iface_alt [iface -> cur_alt ].freq_ctrl_supported ) {
1505+ 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 );
1506+ UAC_RETURN_ON_ERROR (uac_cs_request_set_ep_frequency (iface , iface -> iface_alt [iface -> cur_alt ].ep_addr ,
1507+ iface -> iface_alt [iface -> cur_alt ].cur_sampling_freq ), "Unable to set endpoint frequency" );
14191508 }
14201509 // for RX, we just submit all the transfers
14211510 if (iface -> dev_info .type == UAC_STREAM_RX ) {
@@ -2208,7 +2297,7 @@ esp_err_t uac_host_device_close(uac_host_device_handle_t uac_dev_handle)
22082297
22092298 UAC_RETURN_ON_ERROR (uac_host_interface_try_lock (uac_iface , DEFAULT_CTRL_XFER_TIMEOUT_MS ), "UAC Interface is busy by other task" );
22102299 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" );
2300+ UAC_GOTO_ON_ERROR (uac_host_interface_suspend (uac_iface ), "Unable to disable UAC Interface" );
22122301 }
22132302
22142303 if (UAC_INTERFACE_STATE_READY == uac_iface -> state ) {
@@ -2380,7 +2469,7 @@ esp_err_t uac_host_device_start(uac_host_device_handle_t uac_dev_handle, const u
23802469 iface_claimed = true;
23812470
23822471 if (!(iface -> flags & FLAG_STREAM_SUSPEND_AFTER_START )) {
2383- UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface , false ), "Unable to resume UAC Interface" );
2472+ UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface ), "Unable to resume UAC Interface" );
23842473 }
23852474 uac_host_interface_unlock (iface );
23862475 return ESP_OK ;
@@ -2405,7 +2494,7 @@ esp_err_t uac_host_device_suspend(uac_host_device_handle_t uac_dev_handle)
24052494 }
24062495 esp_err_t ret = ESP_OK ;
24072496 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" );
2497+ UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface ), "Unable to suspend UAC Interface" );
24092498
24102499 uac_host_interface_unlock (iface );
24112500 return ESP_OK ;
@@ -2428,7 +2517,7 @@ esp_err_t uac_host_device_resume(uac_host_device_handle_t uac_dev_handle)
24282517
24292518 esp_err_t ret = ESP_OK ;
24302519 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" );
2520+ UAC_GOTO_ON_ERROR (uac_host_interface_resume (iface ), "Unable to resume UAC Interface" );
24322521
24332522 uac_host_interface_unlock (iface );
24342523 return ESP_OK ;
@@ -2446,7 +2535,7 @@ esp_err_t uac_host_device_stop(uac_host_device_handle_t uac_dev_handle)
24462535 esp_err_t ret = ESP_OK ;
24472536 UAC_RETURN_ON_ERROR (uac_host_interface_try_lock (iface , DEFAULT_CTRL_XFER_TIMEOUT_MS ), "Unable to lock UAC Interface" );
24482537 if (UAC_INTERFACE_STATE_ACTIVE == iface -> state ) {
2449- UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface , false ), "Unable to suspend UAC Interface" );
2538+ UAC_GOTO_ON_ERROR (uac_host_interface_suspend (iface ), "Unable to suspend UAC Interface" );
24502539 }
24512540
24522541 if (UAC_INTERFACE_STATE_READY == iface -> state ) {
0 commit comments