aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-08-22 07:52:33 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-08-22 07:52:33 +0000
commitf1e6a55322f18fe69293ce9cc4e1da31a589ea6f (patch)
tree6daf42852a08e87e0400601a449b686f5e4080d6 /os/hal
parent15f4e5c3f36595e9fb03a9143fe6d52183700220 (diff)
downloadChibiOS-f1e6a55322f18fe69293ce9cc4e1da31a589ea6f.tar.gz
ChibiOS-f1e6a55322f18fe69293ce9cc4e1da31a589ea6f.tar.bz2
ChibiOS-f1e6a55322f18fe69293ce9cc4e1da31a589ea6f.zip
Tentative fix for L4 OTG.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10454 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c76
-rw-r--r--os/hal/src/hal_usb.c11
2 files changed, 49 insertions, 38 deletions
diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
index 7490c2c8b..b1802bc71 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
+++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
@@ -278,19 +278,21 @@ static void otg_fifo_read_to_buffer(volatile uint32_t *fifop,
static void otg_rxfifo_handler(USBDriver *usbp) {
uint32_t sts, cnt, ep;
+ /* Popping the event word out of the RX FIFO.*/
sts = usbp->otg->GRXSTSP;
+
+ /* Event details.*/
+ cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
+ ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
+
switch (sts & GRXSTSP_PKTSTS_MASK) {
- case GRXSTSP_SETUP_COMP:
- break;
case GRXSTSP_SETUP_DATA:
- cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
- ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf,
cnt, 8);
break;
+ case GRXSTSP_SETUP_COMP:
+ break;
case GRXSTSP_OUT_DATA:
- cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
- ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
otg_fifo_read_to_buffer(usbp->otg->FIFO[0],
usbp->epc[ep]->out_state->rxbuf,
cnt,
@@ -299,10 +301,12 @@ static void otg_rxfifo_handler(USBDriver *usbp) {
usbp->epc[ep]->out_state->rxbuf += cnt;
usbp->epc[ep]->out_state->rxcnt += cnt;
break;
- case GRXSTSP_OUT_GLOBAL_NAK:
case GRXSTSP_OUT_COMP:
+ break;
+ case GRXSTSP_OUT_GLOBAL_NAK:
+ break;
default:
- ;
+ break;
}
}
@@ -415,43 +419,41 @@ 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)) {
USBOutEndpointState *osp;
-#if defined(STM32_OTG_SEQUENCE_WORKAROUND)
- /* If an OUT transaction end interrupt is processed after the state
- machine advanced to an IN state then it is ignored, this is caused
- on some devices (L4) by STUP and XFRCM interrupts arriving in random
- order.*/
- if ((ep == 0) && ((usbp->ep0state & USB_OUT_STATE) == 0))
- return;
-#else
- /* Receive transfer complete, checking if it is a SETUP transfer on EP0,
- than it must be ignored, the STUP handler will take care of it.*/
- if ((ep == 0) && (usbp->ep0state == USB_EP0_STP_WAITING))
- return;
-#endif
-
/* OUT state structure pointer for this endpoint.*/
osp = usbp->epc[ep]->out_state;
- /* A short packet always terminates a transaction.*/
- if ((ep == 0) &&
- ((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
- (osp->rxsize < osp->totsize)) {
- /* For EP 0 only, in case the transaction covered only part of the total
- transfer then another transaction is immediately started in order to
+ /* EP0 requires special handling.*/
+ if (ep == 0) {
+
+#if defined(STM32_OTG_SEQUENCE_WORKAROUND)
+ /* If an OUT transaction end interrupt is processed while the state
+ machine is not in an OUT state then it is ignored, this is caused
+ on some devices (L4) apparently injecting spurious data complete
+ words in the RX FIFO.*/
+ if ((usbp->ep0state & USB_OUT_STATE) == 0)
+ return;
+#endif
+
+ /* 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;
- osalSysLockFromISR();
- usb_lld_start_out(usbp, ep);
- osalSysUnlockFromISR();
- }
- else {
- /* End on OUT transfer.*/
- _usb_isr_invoke_out_cb(usbp, ep);
+ if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
+ (osp->rxsize < osp->totsize)) {
+ osp->rxsize = osp->totsize - osp->rxsize;
+ osp->rxcnt = 0;
+ osalSysLockFromISR();
+ usb_lld_start_out(usbp, ep);
+ osalSysUnlockFromISR();
+ return;
+ }
}
+
+ /* End on OUT transfer.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
}
}
diff --git a/os/hal/src/hal_usb.c b/os/hal/src/hal_usb.c
index e58055714..451b19aa4 100644
--- a/os/hal/src/hal_usb.c
+++ b/os/hal/src/hal_usb.c
@@ -751,8 +751,17 @@ void _usb_wakeup(USBDriver *usbp) {
void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
size_t max;
- osalDbgAssert(usbp->ep0state == USB_EP0_STP_WAITING, "not in setup state");
+ /* Is the EP0 state machine in the correct state for handling setup
+ packets?*/
+ if (usbp->ep0state != USB_EP0_STP_WAITING) {
+ /* This is unexpected could require handling with a warning event.*/
+ /* TODO: handling here.*/
+ /* Resetting the EP0 state machine and going ahead.*/
+ usbp->ep0state = USB_EP0_STP_WAITING;
+ }
+
+ /* Reading the setup data into the driver buffer.*/
usbReadSetup(usbp, ep, usbp->setup);
/* First verify if the application has an handler installed for this