aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-09-14 08:07:49 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-09-14 08:07:49 +0000
commita8042eea482ec599855db752d87f1227e57c4778 (patch)
tree6ba1efd2a8be0b0d859575fdef0ff7e027d19da2 /os
parent653a7e9ad0f0d946cb277258933043f3c9c442c2 (diff)
downloadChibiOS-a8042eea482ec599855db752d87f1227e57c4778.tar.gz
ChibiOS-a8042eea482ec599855db752d87f1227e57c4778.tar.bz2
ChibiOS-a8042eea482ec599855db752d87f1227e57c4778.zip
Fixed bug #531.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7273 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/ports/STM32/LLD/OTGv1/usb_lld.c59
-rw-r--r--os/hal/ports/STM32/LLD/OTGv1/usb_lld.h12
2 files changed, 48 insertions, 23 deletions
diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c
index fad1932b1..cf22ac91e 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c
+++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c
@@ -32,12 +32,13 @@
/* Driver local definitions. */
/*===========================================================================*/
-#define TRDT_VALUE 5
-
-#define EP0_MAX_INSIZE 64
-
-/*===========================================================================*/
-/* Driver exported variables. */
+#define TRDT_VALUE 5
+
+#define EP0_MAX_INSIZE 64
+#define EP0_MAX_OUTSIZE 64
+
+/*===========================================================================*/
+/* Driver exported variables. */
/*===========================================================================*/
/** @brief OTG_FS driver identifier.*/
@@ -589,13 +590,29 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
specific callback.*/
_usb_isr_invoke_setup_cb(usbp, ep);
- }
- if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) {
- /* Receive transfer complete.*/
- _usb_isr_invoke_out_cb(usbp, ep);
- }
-}
-
+ }
+ if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) {
+ /* Receive transfer complete.*/
+ USBOutEndpointState *osp = usbp->epc[ep]->out_state;
+
+ if (osp->rxsize < osp->totsize) {
+ /* In case the transaction covered only part of the total transfer
+ then another transaction is immediately started in order to
+ cover the remaining.*/
+ osp->rxsize = osp->totsize - osp->rxsize;
+ osp->rxcnt = 0;
+ usb_lld_prepare_receive(usbp, ep);
+ chSysLockFromIsr();
+ usb_lld_start_out(usbp, ep);
+ chSysUnlockFromIsr();
+ }
+ else {
+ /* End on OUT transfer.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ }
+}
+
/**
* @brief OTG shared ISR.
*
@@ -1140,12 +1157,16 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
*/
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) {
uint32_t pcnt;
- USBOutEndpointState *osp = usbp->epc[ep]->out_state;
-
- /* Transfer initialization.*/
- pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
- usbp->epc[ep]->out_maxsize;
- usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
+ USBOutEndpointState *osp = usbp->epc[ep]->out_state;
+
+ /* Transfer initialization.*/
+ osp->totsize = osp->rxsize;
+ if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE))
+ osp->rxsize = EP0_MAX_OUTSIZE;
+
+ pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
+ usbp->epc[ep]->out_maxsize;
+ usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
DOEPTSIZ_XFRSIZ(osp->rxsize);
}
diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h
index 334c1e1df..1b6bf6480 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h
+++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h
@@ -260,10 +260,14 @@ typedef struct {
* @brief Pointer to the input queue.
*/
input_queue_t *rxqueue;
- } queue;
- } mode;
-} USBOutEndpointState;
-
+ } queue;
+ } mode;
+ /**
+ * @brief Total transmit transfer size.
+ */
+ size_t totsize;
+} USBOutEndpointState;
+
/**
* @brief Type of an USB endpoint configuration structure.
* @note Platform specific restrictions may apply to endpoints.