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:
parent
15f4e5c3f3
commit
f1e6a55322
|
@ -278,19 +278,21 @@ static void otg_fifo_read_to_buffer(volatile uint32_t *fifop,
|
||||||
static void otg_rxfifo_handler(USBDriver *usbp) {
|
static void otg_rxfifo_handler(USBDriver *usbp) {
|
||||||
uint32_t sts, cnt, ep;
|
uint32_t sts, cnt, ep;
|
||||||
|
|
||||||
|
/* Popping the event word out of the RX FIFO.*/
|
||||||
sts = usbp->otg->GRXSTSP;
|
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) {
|
switch (sts & GRXSTSP_PKTSTS_MASK) {
|
||||||
case GRXSTSP_SETUP_COMP:
|
|
||||||
break;
|
|
||||||
case GRXSTSP_SETUP_DATA:
|
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,
|
otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf,
|
||||||
cnt, 8);
|
cnt, 8);
|
||||||
break;
|
break;
|
||||||
|
case GRXSTSP_SETUP_COMP:
|
||||||
|
break;
|
||||||
case GRXSTSP_OUT_DATA:
|
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],
|
otg_fifo_read_to_buffer(usbp->otg->FIFO[0],
|
||||||
usbp->epc[ep]->out_state->rxbuf,
|
usbp->epc[ep]->out_state->rxbuf,
|
||||||
cnt,
|
cnt,
|
||||||
|
@ -299,10 +301,12 @@ static void otg_rxfifo_handler(USBDriver *usbp) {
|
||||||
usbp->epc[ep]->out_state->rxbuf += cnt;
|
usbp->epc[ep]->out_state->rxbuf += cnt;
|
||||||
usbp->epc[ep]->out_state->rxcnt += cnt;
|
usbp->epc[ep]->out_state->rxcnt += cnt;
|
||||||
break;
|
break;
|
||||||
case GRXSTSP_OUT_GLOBAL_NAK:
|
|
||||||
case GRXSTSP_OUT_COMP:
|
case GRXSTSP_OUT_COMP:
|
||||||
|
break;
|
||||||
|
case GRXSTSP_OUT_GLOBAL_NAK:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,43 +419,41 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
|
||||||
specific callback.*/
|
specific callback.*/
|
||||||
_usb_isr_invoke_setup_cb(usbp, ep);
|
_usb_isr_invoke_setup_cb(usbp, ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) {
|
if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) {
|
||||||
USBOutEndpointState *osp;
|
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.*/
|
/* OUT state structure pointer for this endpoint.*/
|
||||||
osp = usbp->epc[ep]->out_state;
|
osp = usbp->epc[ep]->out_state;
|
||||||
|
|
||||||
/* A short packet always terminates a transaction.*/
|
/* EP0 requires special handling.*/
|
||||||
if ((ep == 0) &&
|
if (ep == 0) {
|
||||||
((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
|
|
||||||
(osp->rxsize < osp->totsize)) {
|
#if defined(STM32_OTG_SEQUENCE_WORKAROUND)
|
||||||
/* For EP 0 only, in case the transaction covered only part of the total
|
/* If an OUT transaction end interrupt is processed while the state
|
||||||
transfer then another transaction is immediately started in order to
|
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.*/
|
cover the remaining.*/
|
||||||
osp->rxsize = osp->totsize - osp->rxsize;
|
if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
|
||||||
osp->rxcnt = 0;
|
(osp->rxsize < osp->totsize)) {
|
||||||
osalSysLockFromISR();
|
osp->rxsize = osp->totsize - osp->rxsize;
|
||||||
usb_lld_start_out(usbp, ep);
|
osp->rxcnt = 0;
|
||||||
osalSysUnlockFromISR();
|
osalSysLockFromISR();
|
||||||
}
|
usb_lld_start_out(usbp, ep);
|
||||||
else {
|
osalSysUnlockFromISR();
|
||||||
/* End on OUT transfer.*/
|
return;
|
||||||
_usb_isr_invoke_out_cb(usbp, ep);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* End on OUT transfer.*/
|
||||||
|
_usb_isr_invoke_out_cb(usbp, ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -751,8 +751,17 @@ void _usb_wakeup(USBDriver *usbp) {
|
||||||
void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
||||||
size_t max;
|
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);
|
usbReadSetup(usbp, ep, usbp->setup);
|
||||||
|
|
||||||
/* First verify if the application has an handler installed for this
|
/* First verify if the application has an handler installed for this
|
||||||
|
|
Loading…
Reference in New Issue