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) {
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue