@@ -250,8 +250,8 @@ struct port_obj {
250250 uint32_t val ;
251251 } flags ;
252252 bool initialized ;
253- // FIFO biasing related
254- usb_hal_fifo_bias_t fifo_bias ; // Bias is saved so it can be reconfigured upon reset
253+ // FIFO related
254+ usb_dwc_hal_fifo_config_t fifo_config ; // FIFO config to be applied at HAL level
255255 // Port callback and context
256256 hcd_port_callback_t callback ;
257257 void * callback_arg ;
@@ -554,6 +554,23 @@ static bool _port_check_all_pipes_halted(port_t *port);
554554 */
555555static bool _port_debounce (port_t * port );
556556
557+ /**
558+ * @brief Convert user-provided FIFO configuration to HAL format
559+ *
560+ * This function validates and converts a user-defined FIFO configuration
561+ * (provided via `hcd_config_t.fifo_config`) into the format expected by the HAL.
562+ * It ensures that both RX FIFO and Non-Periodic TX FIFO sizes are non-zero.
563+ *
564+ * @param[in] src Pointer to user-defined FIFO settings (HCD format)
565+ * @param[out] dst Pointer to HAL-compatible FIFO configuration structure
566+ *
567+ * @return
568+ * - ESP_OK: Conversion successful and values copied
569+ * - ESP_ERR_INVALID_SIZE: Either RX FIFO or Non-Periodic TX FIFO is zero
570+ */
571+
572+ static esp_err_t convert_fifo_config_to_hal_config (const hcd_fifo_settings_t * src , usb_dwc_hal_fifo_config_t * dst );
573+
557574/**
558575 * @brief Power ON the port
559576 *
@@ -744,16 +761,6 @@ static usb_speed_t get_usb_port_speed(usb_dwc_speed_t priv)
744761 }
745762}
746763
747- static usb_hal_fifo_bias_t get_hal_fifo_bias (hcd_port_fifo_bias_t public )
748- {
749- switch (public ) {
750- case HCD_PORT_FIFO_BIAS_BALANCED : return USB_HAL_FIFO_BIAS_DEFAULT ;
751- case HCD_PORT_FIFO_BIAS_RX : return USB_HAL_FIFO_BIAS_RX ;
752- case HCD_PORT_FIFO_BIAS_PTX : return USB_HAL_FIFO_BIAS_PTX ;
753- default : abort ();
754- }
755- }
756-
757764// ----------------- Interrupt Handlers --------------------
758765
759766/**
@@ -954,6 +961,46 @@ static void intr_hdlr_main(void *arg)
954961 }
955962}
956963
964+ // ----------------------- FIFO Config -------------------------
965+
966+ /**
967+ * @brief Calculate default FIFO configuration based on bias preference
968+ *
969+ * This function calculates the FIFO configuration (RX, non-periodic TX, and periodic TX)
970+ * according to the selected bias mode from Kconfig:
971+ *
972+ * - CONFIG_USB_HOST_HW_BUFFER_BIAS_IN: Prioritize RX FIFO space, useful for IN-heavy traffic.
973+ * - CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT: Prioritize periodic TX FIFO, suitable for periodic OUT transfers.
974+ * - USB_HOST_HW_BUFFER_BIAS_BALANCED: Balanced configuration between RX and both TX FIFOs.
975+ *
976+ * @param[inout] port Pointer to the port object whose fifo_config will be filled
977+ * @param[in] hal Pointer to an initialized HAL context providing hardware FIFO limits
978+ */
979+ static void _calculate_fifo_from_bias (port_t * port , const usb_dwc_hal_context_t * hal )
980+ {
981+ const int otg_dfifo_depth = hal -> constant_config .hsphy_type ? 1024 : 256 ;
982+ const uint16_t fifo_size_lines = hal -> constant_config .fifo_size ;
983+
984+ #if CONFIG_USB_HOST_HW_BUFFER_BIAS_IN
985+ // Prioritize RX FIFO (best for IN-heavy workloads)
986+ port -> fifo_config .nptx_fifo_lines = otg_dfifo_depth / 16 ;
987+ port -> fifo_config .ptx_fifo_lines = otg_dfifo_depth / 8 ;
988+ port -> fifo_config .rx_fifo_lines = fifo_size_lines - port -> fifo_config .ptx_fifo_lines - port -> fifo_config .nptx_fifo_lines ;
989+
990+ #elif CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT
991+ // Prioritize periodic TX FIFO (useful for high throughput periodic endpoints)
992+ port -> fifo_config .rx_fifo_lines = otg_dfifo_depth / 8 + 2 ; // 2 extra lines are allocated for status information. See USB-OTG Programming Guide, chapter 2.1.2.1
993+ port -> fifo_config .nptx_fifo_lines = otg_dfifo_depth / 16 ;
994+ port -> fifo_config .ptx_fifo_lines = fifo_size_lines - port -> fifo_config .nptx_fifo_lines - port -> fifo_config .rx_fifo_lines ;
995+
996+ #else // USB_HOST_HW_BUFFER_BIAS_BALANCED
997+ // Balanced configuration (default)
998+ port -> fifo_config .nptx_fifo_lines = otg_dfifo_depth / 4 ;
999+ port -> fifo_config .ptx_fifo_lines = otg_dfifo_depth / 8 ;
1000+ port -> fifo_config .rx_fifo_lines = fifo_size_lines - port -> fifo_config .ptx_fifo_lines - port -> fifo_config .nptx_fifo_lines ;
1001+ #endif
1002+ }
1003+
9571004// --------------------------------------------- Host Controller Driver ------------------------------------------------
9581005
9591006static port_t * port_obj_alloc (void )
@@ -1018,6 +1065,15 @@ esp_err_t hcd_install(const hcd_config_t *config)
10181065 ESP_LOGE (HCD_DWC_TAG , "Interrupt alloc error: %s" , esp_err_to_name (err_ret ));
10191066 goto intr_alloc_err ;
10201067 }
1068+ // Apply custom FIFO config if provided, otherwise mark as default (all zeros)
1069+ memset (& p_hcd_obj_dmy -> port_obj -> fifo_config , 0 , sizeof (p_hcd_obj_dmy -> port_obj -> fifo_config ));
1070+ if (config -> fifo_config != NULL ) {
1071+ // Convert and validate user-provided config
1072+ err_ret = convert_fifo_config_to_hal_config (config -> fifo_config , & p_hcd_obj_dmy -> port_obj -> fifo_config );
1073+ if (err_ret != ESP_OK ) {
1074+ goto assign_err ;
1075+ }
1076+ }
10211077 HCD_ENTER_CRITICAL ();
10221078 if (s_hcd_obj != NULL ) {
10231079 HCD_EXIT_CRITICAL ();
@@ -1100,6 +1156,34 @@ static bool _port_debounce(port_t *port)
11001156 return is_connected ;
11011157}
11021158
1159+ static esp_err_t convert_fifo_config_to_hal_config (const hcd_fifo_settings_t * src , usb_dwc_hal_fifo_config_t * dst )
1160+ {
1161+ // Check at least RX and NPTX are non-zero
1162+ if (src -> rx_fifo_lines == 0 || src -> nptx_fifo_lines == 0 ) {
1163+ ESP_LOGE (HCD_DWC_TAG , "RX and Non-Periodic TX FIFO must be > 0" );
1164+ return ESP_ERR_INVALID_SIZE ;
1165+ }
1166+ // Assign valid values
1167+ dst -> rx_fifo_lines = src -> rx_fifo_lines ;
1168+ dst -> nptx_fifo_lines = src -> nptx_fifo_lines ;
1169+ dst -> ptx_fifo_lines = src -> ptx_fifo_lines ; // OK even if zero
1170+
1171+ return ESP_OK ;
1172+ }
1173+
1174+ /**
1175+ * @brief Check if the FIFO config is marked to use bias-based default values.
1176+ *
1177+ * If all FIFO line sizes are zero, the configuration is considered uninitialized,
1178+ * and default values will be calculated based on bias settings.
1179+ */
1180+ static inline bool _is_fifo_config_by_bias (const usb_dwc_hal_fifo_config_t * cfg )
1181+ {
1182+ return (cfg -> rx_fifo_lines == 0 &&
1183+ cfg -> nptx_fifo_lines == 0 &&
1184+ cfg -> ptx_fifo_lines == 0 );
1185+ }
1186+
11031187// ---------------------- Commands -------------------------
11041188
11051189static esp_err_t _port_cmd_power_on (port_t * port )
@@ -1177,8 +1261,16 @@ static esp_err_t _port_cmd_reset(port_t *port)
11771261 goto bailout ;
11781262 }
11791263
1180- // Reinitialize port registers.
1181- usb_dwc_hal_set_fifo_bias (port -> hal , port -> fifo_bias ); // Set FIFO biases
1264+ // Reinitialize port registers
1265+ if (!usb_dwc_hal_fifo_config_is_valid (port -> hal , & port -> fifo_config )) {
1266+ HCD_EXIT_CRITICAL ();
1267+ ret = ESP_ERR_INVALID_SIZE ;
1268+ ESP_LOGE (HCD_DWC_TAG , "Invalid FIFO config" );
1269+ HCD_ENTER_CRITICAL ();
1270+ goto bailout ;
1271+ }
1272+ usb_dwc_hal_set_fifo_config (port -> hal , & port -> fifo_config );// Apply FIFO settings
1273+
11821274 usb_dwc_hal_port_set_frame_list (port -> hal , port -> frame_list , FRAME_LIST_LEN ); // Set periodic frame list
11831275 usb_dwc_hal_port_periodic_enable (port -> hal ); // Enable periodic scheduling
11841276
@@ -1287,7 +1379,6 @@ esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, h
12871379 TAILQ_INIT (& port_obj -> pipes_active_tailq );
12881380 port_obj -> state = HCD_PORT_STATE_NOT_POWERED ;
12891381 port_obj -> last_event = HCD_PORT_EVENT_NONE ;
1290- port_obj -> fifo_bias = get_hal_fifo_bias (port_config -> fifo_bias );
12911382 port_obj -> callback = port_config -> callback ;
12921383 port_obj -> callback_arg = port_config -> callback_arg ;
12931384 port_obj -> context = port_config -> context ;
@@ -1297,10 +1388,18 @@ esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, h
12971388 port_obj -> initialized = true;
12981389 // Clear the frame list. We set the frame list register and enable periodic scheduling after a successful reset
12991390 memset (port_obj -> frame_list , 0 , FRAME_LIST_LEN * sizeof (uint32_t ));
1391+ // If FIFO config is zeroed -> calculate from bias
1392+ if (_is_fifo_config_by_bias (& port_obj -> fifo_config )) {
1393+ // Calculate default FIFO sizes based on Kconfig bias settings
1394+ _calculate_fifo_from_bias (port_obj , port_obj -> hal );
1395+ }
13001396 esp_intr_enable (s_hcd_obj -> isr_hdl );
13011397 * port_hdl = (hcd_port_handle_t )port_obj ;
13021398 HCD_EXIT_CRITICAL ();
1303-
1399+ ESP_LOGD (HCD_DWC_TAG , "FIFO config lines: RX=%u, PTX=%u, NPTX=%u" ,
1400+ port_obj -> fifo_config .rx_fifo_lines ,
1401+ port_obj -> fifo_config .ptx_fifo_lines ,
1402+ port_obj -> fifo_config .nptx_fifo_lines );
13041403 vTaskDelay (pdMS_TO_TICKS (INIT_DELAY_MS )); // Need a short delay before host mode takes effect
13051404 return ESP_OK ;
13061405}
@@ -1455,28 +1554,6 @@ void *hcd_port_get_context(hcd_port_handle_t port_hdl)
14551554 return ret ;
14561555}
14571556
1458- esp_err_t hcd_port_set_fifo_bias (hcd_port_handle_t port_hdl , hcd_port_fifo_bias_t bias )
1459- {
1460- esp_err_t ret ;
1461- usb_hal_fifo_bias_t hal_bias = get_hal_fifo_bias (bias );
1462-
1463- // Configure the new FIFO sizes and store the pointers
1464- port_t * port = (port_t * )port_hdl ;
1465- xSemaphoreTake (port -> port_mux , portMAX_DELAY );
1466- HCD_ENTER_CRITICAL ();
1467- // Check that port is in the correct state to update FIFO sizes
1468- if (port -> initialized && !port -> flags .event_pending && port -> num_pipes_idle == 0 && port -> num_pipes_queued == 0 ) {
1469- usb_dwc_hal_set_fifo_bias (port -> hal , hal_bias );
1470- port -> fifo_bias = hal_bias ;
1471- ret = ESP_OK ;
1472- } else {
1473- ret = ESP_ERR_INVALID_STATE ;
1474- }
1475- HCD_EXIT_CRITICAL ();
1476- xSemaphoreGive (port -> port_mux );
1477- return ret ;
1478- }
1479-
14801557// --------------------------------------------------- HCD Pipes -------------------------------------------------------
14811558
14821559// ----------------------- Private -------------------------
0 commit comments