Browse Source

drivers: udc_ambiq: added support for double endpoint buffer

implements option to enable double endpoint buffer to improve throughtput
for non-control endpoints.

Signed-off-by: Chew Zeh Yang <zeon.chew@ambiq.com>
pull/91646/head
Chew Zeh Yang 2 months ago committed by Benjamin Cabé
parent
commit
5e5c40c489
  1. 16
      drivers/usb/udc/Kconfig.ambiq
  2. 27
      drivers/usb/udc/udc_ambiq.c

16
drivers/usb/udc/Kconfig.ambiq

@ -56,4 +56,20 @@ config UDC_AMBIQ_PIO_MODE @@ -56,4 +56,20 @@ config UDC_AMBIQ_PIO_MODE
Select this option when cache coherency handling is to be avoided.
endchoice
config UDC_AMBIQ_DEB_ENABLE
hex "EP Double Buffer Enable"
default 0x0000
depends on SOC_SERIES_APOLLO5X
help
Double Endpoint Buffer acceleration (DEB) is doubles an EP's FIFO size so
that USB transfer could continue to happen while waiting for DMA/CPU to
load/unload data from the EP FIFO. This hex value is a bitmap of endpoints
for DEB to be enabled. BIT0-4 represents OUT_EP 1-5, while BIT16-20
represents IN_EP 1-5. Take note that this feature is limited by total EP
FIFO size. Proper calculation should be done before enabling DEB such that
the total usage of FIFO for all endpoint doesn't exceed the FIFO available
on SoC. The list of Soc with its FIFO size is listed below. The FIFO size
here includes 128 bytes required by control endpoints.
- Apollo510: (4096 Bytes FIFO)
endif # UDC_AMBIQ

27
drivers/usb/udc/udc_ambiq.c

@ -565,6 +565,29 @@ static int init_apollo5x(const struct udc_ambiq_data *priv) @@ -565,6 +565,29 @@ static int init_apollo5x(const struct udc_ambiq_data *priv)
}
#endif
#if CONFIG_UDC_AMBIQ_DEB_ENABLE
static void init_double_buffers(const struct udc_ambiq_data *priv)
{
uint32_t mask;
mask = CONFIG_UDC_AMBIQ_DEB_ENABLE & 0xFFFF;
while (mask) {
uint32_t ep = find_lsb_set(mask);
am_hal_usb_enable_ep_double_buffer(priv->usb_handle, ep, AM_HAL_USB_OUT_DIR, true);
mask &= ~(1U << (ep - 1));
}
mask = (CONFIG_UDC_AMBIQ_DEB_ENABLE >> 16) & 0xFFFF;
while (mask) {
uint32_t ep = find_lsb_set(mask);
am_hal_usb_enable_ep_double_buffer(priv->usb_handle, ep, AM_HAL_USB_IN_DIR, true);
mask &= ~(1U << (ep - 1));
}
}
#endif
static int udc_ambiq_init(const struct device *dev)
{
struct udc_ambiq_data *priv = udc_get_private(dev);
@ -599,6 +622,10 @@ static int udc_ambiq_init(const struct device *dev) @@ -599,6 +622,10 @@ static int udc_ambiq_init(const struct device *dev)
}
#endif
#if CONFIG_UDC_AMBIQ_DEB_ENABLE
init_double_buffers(priv);
#endif
/* Set USB Speed */
am_hal_usb_set_dev_speed(priv->usb_handle, priv->usb_speed);
/* Enable USB interrupt */

Loading…
Cancel
Save