Tentative fix for L4 OTG.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10454 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2017-08-22 07:52:33 +00:00
parent 15f4e5c3f3
commit f1e6a55322
2 changed files with 49 additions and 38 deletions

View File

@ -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;
switch (sts & GRXSTSP_PKTSTS_MASK) {
case GRXSTSP_SETUP_COMP:
break;
case GRXSTSP_SETUP_DATA:
/* 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_DATA:
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,45 +419,43 @@ 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.*/
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;
}
else {
}
/* End on OUT transfer.*/
_usb_isr_invoke_out_cb(usbp, ep);
}
}
}
/**
* @brief Isochronous IN transfer failed handler.

View File

@ -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