USB integration in progress
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2195 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
93e30e4632
commit
b93ccc37a7
@ -93,9 +93,9 @@
|
|||||||
# undef CONFIG_STM32_USBDEV_REGDEBUG
|
# undef CONFIG_STM32_USBDEV_REGDEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initial interrupt mask */
|
/* Initial interrupt mask: Reset + Suspend + Correct Transfer */
|
||||||
|
|
||||||
#define STM32_CNTR_SETUP (USB_CNTR_RESETM|USB_CNTR_SUSPM|USB_CNTR_WKUPM|USB_CNTR_CTRM)
|
#define STM32_CNTR_SETUP (USB_CNTR_RESETM|USB_CNTR_SUSPM|USB_CNTR_CTRM)
|
||||||
|
|
||||||
/* Endpoint identifiers. The STM32 supports up to 16 mono-directional or 8
|
/* Endpoint identifiers. The STM32 supports up to 16 mono-directional or 8
|
||||||
* bidirectional endpoints. However, when you take into account PMA buffer
|
* bidirectional endpoints. However, when you take into account PMA buffer
|
||||||
@ -373,6 +373,8 @@ static inline uint16
|
|||||||
stm32_geteprxstatus(ubyte epno);
|
stm32_geteprxstatus(ubyte epno);
|
||||||
static uint16 stm32_eptxstalled(ubyte epno);
|
static uint16 stm32_eptxstalled(ubyte epno);
|
||||||
static uint16 stm32_eprxstalled(ubyte epno);
|
static uint16 stm32_eprxstalled(ubyte epno);
|
||||||
|
static void stm32_setimask(struct stm32_usbdev_s *priv, uint16 setbits,
|
||||||
|
uint16 clrbits);
|
||||||
static void stm32_suspend(struct stm32_usbdev_s *priv);
|
static void stm32_suspend(struct stm32_usbdev_s *priv);
|
||||||
static void stm32_initresume(struct stm32_usbdev_s *priv);
|
static void stm32_initresume(struct stm32_usbdev_s *priv);
|
||||||
static void stm32_esofpoll(struct stm32_usbdev_s *priv) ;
|
static void stm32_esofpoll(struct stm32_usbdev_s *priv) ;
|
||||||
@ -1890,7 +1892,7 @@ static void stm32_lptransfer(struct stm32_usbdev_s *priv)
|
|||||||
uint16 epval;
|
uint16 epval;
|
||||||
uint16 istr;
|
uint16 istr;
|
||||||
|
|
||||||
/* Etay in loop while pending ints */
|
/* Stay in loop while LP interrupts are pending */
|
||||||
|
|
||||||
while (((istr = stm32_getreg(STM32_USB_ISTR)) & USB_ISTR_CTR) != 0)
|
while (((istr = stm32_getreg(STM32_USB_ISTR)) & USB_ISTR_CTR) != 0)
|
||||||
{
|
{
|
||||||
@ -2041,8 +2043,9 @@ static int stm32_hpinterrupt(int irq, void *context)
|
|||||||
* for isochronous and double-buffer bulk transfers.
|
* for isochronous and double-buffer bulk transfers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_HPINTERRUPT), irq);
|
istr = stm32_getreg(STM32_USB_ISTR);
|
||||||
while (((istr = stm32_getreg(STM32_USB_ISTR)) & USB_ISTR_CTR) != 0)
|
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_HPINTERRUPT), istr);
|
||||||
|
while ((istr & USB_ISTR_CTR) != 0)
|
||||||
{
|
{
|
||||||
stm32_putreg((uint16)~USB_ISTR_CTR, STM32_USB_ISTR);
|
stm32_putreg((uint16)~USB_ISTR_CTR, STM32_USB_ISTR);
|
||||||
|
|
||||||
@ -2090,6 +2093,10 @@ static int stm32_hpinterrupt(int irq, void *context)
|
|||||||
privep->txbusy = 0;
|
privep->txbusy = 0;
|
||||||
stm32_wrrequest(priv, privep);
|
stm32_wrrequest(priv, privep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fetch the status again for the next time through the loop */
|
||||||
|
|
||||||
|
istr = stm32_getreg(STM32_USB_ISTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_HPINTERRUPT), 0);
|
usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_HPINTERRUPT), 0);
|
||||||
@ -2110,7 +2117,7 @@ static int stm32_lpinterrupt(int irq, void *context)
|
|||||||
struct stm32_usbdev_s *priv = &g_usbdev;
|
struct stm32_usbdev_s *priv = &g_usbdev;
|
||||||
uint16 istr = stm32_getreg(STM32_USB_ISTR);
|
uint16 istr = stm32_getreg(STM32_USB_ISTR);
|
||||||
|
|
||||||
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_LPINTERRUPT), irq);
|
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_LPINTERRUPT), istr);
|
||||||
|
|
||||||
/* Handle Reset interrupts. When this event occurs, the peripheral is left
|
/* Handle Reset interrupts. When this event occurs, the peripheral is left
|
||||||
* in the same conditions it is left by the system reset (but with the
|
* in the same conditions it is left by the system reset (but with the
|
||||||
@ -2124,10 +2131,12 @@ static int stm32_lpinterrupt(int irq, void *context)
|
|||||||
stm32_putreg(~USB_ISTR_RESET, STM32_USB_ISTR);
|
stm32_putreg(~USB_ISTR_RESET, STM32_USB_ISTR);
|
||||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RESET), 0);
|
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RESET), 0);
|
||||||
|
|
||||||
/* Restore our power-up state and exit now. */
|
/* Restore our power-up state and exit now because istr is no longer
|
||||||
|
* valid.
|
||||||
|
*/
|
||||||
|
|
||||||
stm32_reset(priv);
|
stm32_reset(priv);
|
||||||
return OK;
|
goto exit_lpinterrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle Wakeup interrupts. This interrupt is only enable while the USB is
|
/* Handle Wakeup interrupts. This interrupt is only enable while the USB is
|
||||||
@ -2161,12 +2170,12 @@ static int stm32_lpinterrupt(int irq, void *context)
|
|||||||
|
|
||||||
if ((istr & USB_ISTR_SUSP & priv->imask) != 0)
|
if ((istr & USB_ISTR_SUSP & priv->imask) != 0)
|
||||||
{
|
{
|
||||||
|
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSP), 0);
|
||||||
stm32_suspend(priv);
|
stm32_suspend(priv);
|
||||||
|
|
||||||
/* Clear of the ISTR bit must be done after setting of USB_CNTR_FSUSP */
|
/* Clear of the ISTR bit must be done after setting of USB_CNTR_FSUSP */
|
||||||
|
|
||||||
stm32_putreg(~USB_ISTR_SUSP, STM32_USB_ISTR);
|
stm32_putreg(~USB_ISTR_SUSP, STM32_USB_ISTR);
|
||||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSP), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((istr & USB_ISTR_ESOF & priv->imask) != 0)
|
if ((istr & USB_ISTR_ESOF & priv->imask) != 0)
|
||||||
@ -2187,10 +2196,35 @@ static int stm32_lpinterrupt(int irq, void *context)
|
|||||||
stm32_lptransfer(priv);
|
stm32_lptransfer(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit_lpinterrupt:
|
||||||
usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_LPINTERRUPT), 0);
|
usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_LPINTERRUPT), 0);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: stm32_setimask
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
stm32_setimask(struct stm32_usbdev_s *priv, uint16 setbits, uint16 clrbits)
|
||||||
|
{
|
||||||
|
uint16 regval;
|
||||||
|
|
||||||
|
/* Adjust the interrupt mask bits in the shadow copy first */
|
||||||
|
|
||||||
|
priv->imask &= ~clrbits;
|
||||||
|
priv->imask |= setbits;
|
||||||
|
|
||||||
|
/* Then make the interrupt mask bits in the CNTR register match the shadow
|
||||||
|
* register (Hmmm... who is shadowing whom?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
regval = stm32_getreg(STM32_USB_CNTR);
|
||||||
|
regval &= ~USB_CNTR_ALLINTS;
|
||||||
|
regval |= priv->imask;
|
||||||
|
stm32_putreg(regval, STM32_USB_CNTR);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: stm32_suspend
|
* Name: stm32_suspend
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -2199,17 +2233,12 @@ static void stm32_suspend(struct stm32_usbdev_s *priv)
|
|||||||
{
|
{
|
||||||
uint16 regval;
|
uint16 regval;
|
||||||
|
|
||||||
/* Disable ESOF polling, disable the SUSP interrupt, and
|
/* Disable ESOF polling, disable the SUSP interrupt, and enable the WKUP
|
||||||
* enable the WKUP interrupt.
|
* interrupt. Clear any pending WKUP interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->imask &= ~(USB_CNTR_ESOFM|USB_CNTR_SUSPM);
|
stm32_setimask(priv, USB_CNTR_WKUPM, USB_CNTR_ESOFM|USB_CNTR_SUSPM);
|
||||||
priv->imask |= USB_CNTR_WKUPM;
|
stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR);
|
||||||
stm32_putreg(priv->imask, STM32_USB_CNTR);
|
|
||||||
|
|
||||||
/* Clear any pending interrupts that we just enabled */
|
|
||||||
|
|
||||||
stm32_putreg(~USB_CNTR_WKUPM, STM32_USB_ISTR);
|
|
||||||
|
|
||||||
/* Enter suspend mode */
|
/* Enter suspend mode */
|
||||||
|
|
||||||
@ -2288,17 +2317,12 @@ static void stm32_esofpoll(struct stm32_usbdev_s *priv)
|
|||||||
stm32_putreg(regval, STM32_USB_CNTR);
|
stm32_putreg(regval, STM32_USB_CNTR);
|
||||||
priv->rsmstate = RSMSTATE_IDLE;
|
priv->rsmstate = RSMSTATE_IDLE;
|
||||||
|
|
||||||
/* Disable ESOF polling, disable the SUSP interrupt, and
|
/* Disable ESOF polling, disable the SUSP interrupt, and enable
|
||||||
* enable the WKUP interrupt.
|
* the WKUP interrupt. Clear any pending WKUP interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->imask &= ~(USB_CNTR_ESOFM|USB_CNTR_SUSPM);
|
stm32_setimask(priv, USB_CNTR_WKUPM, USB_CNTR_ESOFM|USB_CNTR_SUSPM);
|
||||||
priv->imask |= USB_CNTR_WKUPM;
|
stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR);
|
||||||
stm32_putreg(priv->imask, STM32_USB_CNTR);
|
|
||||||
|
|
||||||
/* Clear any pending interrupts that we just enabled */
|
|
||||||
|
|
||||||
stm32_putreg(~USB_CNTR_WKUPM, STM32_USB_ISTR);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3000,16 +3024,12 @@ static int stm32_wakeup(struct usbdev_s *dev)
|
|||||||
|
|
||||||
/* Disable the SUSP interrupt (until we are fully resumed), disable
|
/* Disable the SUSP interrupt (until we are fully resumed), disable
|
||||||
* the WKUP interrupt (we are already waking up), and enable the
|
* the WKUP interrupt (we are already waking up), and enable the
|
||||||
* ESOF interrupt that will drive the resume operations.
|
* ESOF interrupt that will drive the resume operations. Clear any
|
||||||
|
* pending ESOF interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->imask &= ~(USB_CNTR_WKUPM|USB_CNTR_SUSPM);
|
stm32_setimask(priv, USB_CNTR_ESOFM, USB_CNTR_WKUPM|USB_CNTR_SUSPM);
|
||||||
priv->imask |= USB_CNTR_ESOFM;
|
stm32_putreg(~USB_ISTR_ESOF, STM32_USB_ISTR);
|
||||||
stm32_putreg(priv->imask, STM32_USB_CNTR);
|
|
||||||
|
|
||||||
/* Clear any pending interrupts that we just enabled */
|
|
||||||
|
|
||||||
stm32_putreg(~USB_CNTR_ESOFM, STM32_USB_ISTR);
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -3087,7 +3107,7 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
|
|||||||
/* Set the interrrupt priority */
|
/* Set the interrrupt priority */
|
||||||
|
|
||||||
up_prioritize_irq(STM32_IRQ_USBHPCANTX, CONFIG_USB_PRI);
|
up_prioritize_irq(STM32_IRQ_USBHPCANTX, CONFIG_USB_PRI);
|
||||||
up_prioritize_irq( STM32_IRQ_USBLPCANRX0, CONFIG_USB_PRI);
|
up_prioritize_irq(STM32_IRQ_USBLPCANRX0, CONFIG_USB_PRI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -3096,17 +3116,18 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
|
|||||||
|
|
||||||
static void stm32_hwreset(struct stm32_usbdev_s *priv)
|
static void stm32_hwreset(struct stm32_usbdev_s *priv)
|
||||||
{
|
{
|
||||||
/* Enable pull-up to connect the device */
|
/* Put the USB controller into reset */
|
||||||
|
|
||||||
stm32_usbpullup(&priv->usbdev, TRUE);
|
|
||||||
stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR);
|
stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR);
|
||||||
|
|
||||||
|
/* Disable interrupts (and perhaps take the USB controller out of reset) */
|
||||||
|
|
||||||
priv->imask = 0;
|
priv->imask = 0;
|
||||||
stm32_putreg(priv->imask, STM32_USB_CNTR);
|
stm32_putreg(priv->imask, STM32_USB_CNTR);
|
||||||
|
|
||||||
/* Clear pending interrupts */
|
/* Clear pending interrupts */
|
||||||
|
|
||||||
stm32_putreg(0, STM32_USB_ISTR);
|
stm32_putreg((uint16)~USB_ISTR_ALLINTS, STM32_USB_ISTR);
|
||||||
|
|
||||||
/* Set the STM32 BTABLE address */
|
/* Set the STM32 BTABLE address */
|
||||||
|
|
||||||
@ -3128,8 +3149,7 @@ static void stm32_hwreset(struct stm32_usbdev_s *priv)
|
|||||||
|
|
||||||
/* Enable interrupts at the USB controllr */
|
/* Enable interrupts at the USB controllr */
|
||||||
|
|
||||||
priv->imask = STM32_CNTR_SETUP;
|
stm32_setimask(priv, STM32_CNTR_SETUP, (USB_CNTR_ALLINTS & ~STM32_CNTR_SETUP));
|
||||||
stm32_putreg(priv->imask, STM32_USB_CNTR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -3164,6 +3184,10 @@ void up_usbinitialize(void)
|
|||||||
|
|
||||||
stm32_putreg(USB_CNTR_FRES|USB_CNTR_PDWN, STM32_USB_CNTR);
|
stm32_putreg(USB_CNTR_FRES|USB_CNTR_PDWN, STM32_USB_CNTR);
|
||||||
|
|
||||||
|
/* Disconnect the device / disable the pull-up */
|
||||||
|
|
||||||
|
stm32_usbpullup(&priv->usbdev, FALSE);
|
||||||
|
|
||||||
/* Initialize the device state structure. NOTE: many fields
|
/* Initialize the device state structure. NOTE: many fields
|
||||||
* have the initial value of zero and, hence, are not explicitly
|
* have the initial value of zero and, hence, are not explicitly
|
||||||
* initialized here.
|
* initialized here.
|
||||||
@ -3275,7 +3299,7 @@ void up_usbuninitialize(void)
|
|||||||
|
|
||||||
/* Clear pending interrupts */
|
/* Clear pending interrupts */
|
||||||
|
|
||||||
stm32_putreg(0, STM32_USB_ISTR);
|
stm32_putreg(~USB_ISTR_ALLINTS, STM32_USB_ISTR);
|
||||||
|
|
||||||
/* Disconnect the device / disable the pull-up */
|
/* Disconnect the device / disable the pull-up */
|
||||||
|
|
||||||
@ -3346,6 +3370,10 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
|
|||||||
|
|
||||||
up_prioritize_irq(STM32_IRQ_USBHPCANTX, CONFIG_USB_PRI);
|
up_prioritize_irq(STM32_IRQ_USBHPCANTX, CONFIG_USB_PRI);
|
||||||
up_prioritize_irq(STM32_IRQ_USBLPCANRX0, CONFIG_USB_PRI);
|
up_prioritize_irq(STM32_IRQ_USBLPCANRX0, CONFIG_USB_PRI);
|
||||||
|
|
||||||
|
/* Enable pull-up to connect the device */
|
||||||
|
|
||||||
|
stm32_usbpullup(&priv->usbdev, TRUE);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -161,9 +161,12 @@
|
|||||||
#define USB_CNTR_SUSPM (1 << 11) /* Bit 11: Suspend mode Interrupt Mask */
|
#define USB_CNTR_SUSPM (1 << 11) /* Bit 11: Suspend mode Interrupt Mask */
|
||||||
#define USB_CNTR_WKUPM (1 << 12) /* Bit 12: Wakeup Interrupt Mask */
|
#define USB_CNTR_WKUPM (1 << 12) /* Bit 12: Wakeup Interrupt Mask */
|
||||||
#define USB_CNTR_ERRM (1 << 13) /* Bit 13: Error Interrupt Mask */
|
#define USB_CNTR_ERRM (1 << 13) /* Bit 13: Error Interrupt Mask */
|
||||||
#define USB_CNTR_DMAOVRN (1 << 14) /* Bit 14: Packet Memory Area Over / Underrun Interrupt Mask */
|
#define USB_CNTR_DMAOVRNM (1 << 14) /* Bit 14: Packet Memory Area Over / Underrun Interrupt Mask */
|
||||||
#define USB_CNTR_CTRM (1 << 15) /* Bit 15: Correct Transfer Interrupt Mask */
|
#define USB_CNTR_CTRM (1 << 15) /* Bit 15: Correct Transfer Interrupt Mask */
|
||||||
|
|
||||||
|
#define USB_CNTR_ALLINTS (USB_CNTR_ESOFM|USB_CNTR_SOFM|USB_CNTR_RESETM|USB_CNTR_SUSPM|\
|
||||||
|
USB_CNTR_WKUPM|USB_CNTR_ERRM|USB_CNTR_DMAOVRNM|USB_CNTR_CTRM)
|
||||||
|
|
||||||
/* USB interrupt status register */
|
/* USB interrupt status register */
|
||||||
|
|
||||||
#define USB_ISTR_EPID_SHIFT (0) /* Bits 3-0: Endpoint Identifier */
|
#define USB_ISTR_EPID_SHIFT (0) /* Bits 3-0: Endpoint Identifier */
|
||||||
@ -178,6 +181,9 @@
|
|||||||
#define USB_ISTR_DMAOVRN (1 << 14) /* Bit 14: Packet Memory Area Over / Underrun */
|
#define USB_ISTR_DMAOVRN (1 << 14) /* Bit 14: Packet Memory Area Over / Underrun */
|
||||||
#define USB_ISTR_CTR (1 << 15) /* Bit 15: Correct Transfer */
|
#define USB_ISTR_CTR (1 << 15) /* Bit 15: Correct Transfer */
|
||||||
|
|
||||||
|
#define USB_ISTR_ALLINTS (USB_ISTR_ESOF|USB_ISTR_SOF|USB_ISTR_RESET|USB_ISTR_SUSP|\
|
||||||
|
USB_ISTR_WKUP|USB_ISTR_ERR|USB_ISTR_DMAOVRN|USB_ISTR_CTR)
|
||||||
|
|
||||||
/* USB frame number register */
|
/* USB frame number register */
|
||||||
|
|
||||||
#define USB_FNR_FN_SHIFT (0) /* Bits 10-0: Frame Number */
|
#define USB_FNR_FN_SHIFT (0) /* Bits 10-0: Frame Number */
|
||||||
|
Loading…
Reference in New Issue
Block a user