From 6d679a1bbfa260e337891f2db254de8bca98fba5 Mon Sep 17 00:00:00 2001 From: arighi Date: Tue, 15 Mar 2011 16:49:22 +0000 Subject: [PATCH] usb: introduce usb_endpointReadTimeout() and usb_endpointWriteTimeout() Allow to specify a timeout for the usb read/write functions. The timeout is an upper bound on the amount of time (in ms) elapsed before returns. If timeout is zero, the the function returns immediatly and it basically works in non-blocking fashion. A negative value for the timeout means that the function can block indefinitely. The last case is basically the old usb_endpointRead/Write() behaviour, so the compatibility with the old API is respected using this value for the timeout. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4772 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/cortex-m3/drv/usb_stm32.c | 18 ++++++++++++---- bertos/drv/usb.h | 32 ++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/bertos/cpu/cortex-m3/drv/usb_stm32.c b/bertos/cpu/cortex-m3/drv/usb_stm32.c index 46069ff0..393b3cc4 100644 --- a/bertos/cpu/cortex-m3/drv/usb_stm32.c +++ b/bertos/cpu/cortex-m3/drv/usb_stm32.c @@ -1123,7 +1123,8 @@ static void usb_endpointRead_complete(int ep) rx_size = ep_cnfg[ep].size; } -ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) +ssize_t usb_endpointReadTimeout(int ep, void *buffer, ssize_t size, + ticks_t timeout) { int ep_num = usb_ep_logical_to_hw(ep); ssize_t max_size = sizeof(ep_buffer[ep_num]); @@ -1158,7 +1159,11 @@ ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) /* Blocking read */ __usb_ep_read(ep_num, ep_buffer[ep_num], size, usb_endpointRead_complete); - event_wait(&usb_event_done[ep_num >> 1]); + if (timeout < 0) + event_wait(&usb_event_done[ep_num >> 1]); + else + if (!event_waitTimeout(&usb_event_done[ep_num >> 1], timeout)) + return 0; memcpy(buffer, ep_buffer[ep_num], rx_size); return rx_size; @@ -1177,7 +1182,8 @@ static void usb_endpointWrite_complete(int ep) tx_size = ep_cnfg[ep].size; } -ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) +ssize_t usb_endpointWriteTimeout(int ep, const void *buffer, ssize_t size, + ticks_t timeout) { int ep_num = usb_ep_logical_to_hw(ep); ssize_t max_size = sizeof(ep_buffer[ep_num]); @@ -1213,7 +1219,11 @@ ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) memcpy(ep_buffer[ep_num], buffer, size); __usb_ep_write(ep_num, ep_buffer[ep_num], size, usb_endpointWrite_complete); - event_wait(&usb_event_done[ep_num >> 1]); + if (timeout < 0) + event_wait(&usb_event_done[ep_num >> 1]); + else + if (!event_waitTimeout(&usb_event_done[ep_num >> 1], timeout)) + return 0; return tx_size; } diff --git a/bertos/drv/usb.h b/bertos/drv/usb.h index 4016864f..eee7828b 100644 --- a/bertos/drv/usb.h +++ b/bertos/drv/usb.h @@ -487,17 +487,41 @@ INLINE int usb_endpointIsIsocOut(const struct UsbEndpointDesc *epd) * Read up to \a size bytes from the USB endpoint identified by the address * \a ep and store them in \a buffer. * - * \return number of bytes actually read. + * The \a timeout is an upper bound on the amount of time (in ticks) elapsed + * before returns. If \a timeout is zero, the the function returns immediatly + * and it basically works in non-blocking fashion. A negative value for \a + * timeout means that the function can block indefinitely. + * + * \return number of bytes actually read, or a negative value in case of + * errors. */ -ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size); +ssize_t usb_endpointReadTimeout(int ep, void *buffer, ssize_t size, + ticks_t timeout); + +INLINE ssize_t usb_endpointRead(int ep, void *buffer, ssize_t size) +{ + return usb_endpointReadTimeout(ep, buffer, size, -1); +} /** * Write up to \a size bytes from the buffer pointed \a buffer to the USB * endpoint identified by the address \a ep. * - * \return number of bytes actually wrote. + * The \a timeout is an upper bound on the amount of time (in ticks) elapsed + * before returns. If \a timeout is zero, the the function returns immediatly + * and it basically works in non-blocking fashion. A negative value for \a + * timeout means that the function can block indefinitely. + * + * \return number of bytes actually wrote, or a negative value in case of + * errors. */ -ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size); +ssize_t usb_endpointWriteTimeout(int ep, const void *buffer, ssize_t size, + ticks_t timeout); + +INLINE ssize_t usb_endpointWrite(int ep, const void *buffer, ssize_t size) +{ + return usb_endpointWriteTimeout(ep, buffer, size, -1); +} /** * Register a generic USB device driver \a dev in the USB controller. -- 2.25.1