usb: introduce usb_endpointReadTimeout() and usb_endpointWriteTimeout()
authorarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 15 Mar 2011 16:49:22 +0000 (16:49 +0000)
committerarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 15 Mar 2011 16:49:22 +0000 (16:49 +0000)
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
bertos/drv/usb.h

index 46069ff0bec281321b7d951d50f731648c4ea4d5..393b3cc4a49aa619b272ef802a519136770fdc97 100644 (file)
@@ -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;
 }
index 4016864f0e9966f83d6ca5d36c428e76ce4bffd4..eee7828bafdecf32f2181b69037056aca6f0c4ef 100644 (file)
@@ -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.