usb: add fallback implementation of emulated batch api

some targets can process requests fast enough without dedicated
batch api implementation.
provide generic implementationn for such targets.

Change-Id: I152681441e70e0e98396274d9305d371d2bbfbe3
This commit is contained in:
mojyack 2026-01-06 11:19:54 +09:00
parent d2b76a99f3
commit f84003fa40
3 changed files with 72 additions and 6 deletions

View file

@ -1362,6 +1362,9 @@ Lyre prototype 1 */
//#define USB_HAS_INTERRUPT -- seems to be broken
#endif /* CONFIG_USBOTG */
#define USB_BATCH_NON_NATIVE
#define USB_BATCH_SLOTS 1
/* define the class drivers to enable */
#ifdef BOOTLOADER

View file

@ -109,8 +109,6 @@ int usb_drv_deinit_endpoint(int endpoint);
int usb_drv_get_frame_number(void);
#endif
#if USB_BATCH_SLOTS > 0
/* batched request api is for workloads that perform very high-frequency,
* performance-sensitive isochronous transactions continuously.
* this api allows multiple transaction requests to be buffered in udc driver.
@ -128,8 +126,6 @@ int usb_drv_batch_start(void);
/* stop processing */
int usb_drv_batch_stop(void);
#endif
/* USB_STRING_INITIALIZER(u"Example String") */
#define USB_STRING_INITIALIZER(S) { \
sizeof(struct usb_string_descriptor) + sizeof(S) - sizeof(*S), \

View file

@ -554,6 +554,64 @@ void usb_core_hotswap_event(int volume, bool inserted)
}
#endif
#ifdef USB_BATCH_NON_NATIVE
static uint8_t batch_ep = 0;
static bool batch_stopped;
static usb_drv_batch_get_more batch_get_more;
int usb_drv_batch_init(int ep, usb_drv_batch_get_more get_more)
{
if(batch_ep != 0) {
logf("usb_core: batch api in use user=0x%02X", batch_ep);
return -1;
}
batch_ep = ep;
batch_get_more = get_more;
batch_stopped = false;
return 0;
}
int usb_drv_batch_deinit(void)
{
logf("usb_core: batch deinit");
usb_drv_batch_stop();
batch_ep = 0;
return 0;
}
static int batch_get_and_send(void)
{
const void* ptr;
size_t len;
batch_get_more(&ptr, &len);
if(len == 0 || batch_stopped) {
return 0;
}
return usb_drv_send_nonblocking(EP_NUM(batch_ep), (void*)ptr, len);
}
int usb_drv_batch_start(void)
{
logf("usb_core: batch start");
batch_stopped = false;
return batch_get_and_send();
}
int usb_drv_batch_stop(void)
{
batch_stopped = true;
return 0;
}
static void batch_xfer_complete(void) {
if(batch_stopped) {
return;
}
batch_get_and_send();
}
#endif
static void usb_core_set_serial_function_id(void)
{
int i, id = 0;
@ -1130,8 +1188,14 @@ void usb_core_bus_reset(void)
/* called by usb_drv_transfer_completed() */
void usb_core_transfer_complete(int endpoint, int dir, int status, int length)
{
struct usb_transfer_completion_event_data* completion_event =
&ep_data[endpoint].completion_event[EP_DIR(dir)];
#ifdef USB_BATCH_NON_NATIVE
/* batch api */
if(batch_ep != 0 && (endpoint | dir) == batch_ep) {
batch_xfer_complete();
return;
}
#endif
/* Fast notification */
fast_completion_handler_t handler = ep_data[endpoint].fast_completion_handler[EP_DIR(dir)];
if(handler != NULL && handler(endpoint, dir, status, length))
@ -1154,6 +1218,9 @@ void usb_core_transfer_complete(int endpoint, int dir, int status, int length)
}
#endif
struct usb_transfer_completion_event_data* completion_event =
&ep_data[endpoint].completion_event[EP_DIR(dir)];
completion_event->endpoint = endpoint;
completion_event->dir = dir;
completion_event->data[0] = data0;