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:
patacongo 2009-10-30 17:33:54 +00:00
parent 93e30e4632
commit b93ccc37a7
2 changed files with 78 additions and 44 deletions

View File

@ -93,9 +93,9 @@
# undef CONFIG_STM32_USBDEV_REGDEBUG
#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
* bidirectional endpoints. However, when you take into account PMA buffer
@ -373,6 +373,8 @@ static inline uint16
stm32_geteprxstatus(ubyte epno);
static uint16 stm32_eptxstalled(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_initresume(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 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)
{
@ -2041,8 +2043,9 @@ static int stm32_hpinterrupt(int irq, void *context)
* for isochronous and double-buffer bulk transfers.
*/
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_HPINTERRUPT), irq);
while (((istr = stm32_getreg(STM32_USB_ISTR)) & USB_ISTR_CTR) != 0)
istr = stm32_getreg(STM32_USB_ISTR);
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_HPINTERRUPT), istr);
while ((istr & USB_ISTR_CTR) != 0)
{
stm32_putreg((uint16)~USB_ISTR_CTR, STM32_USB_ISTR);
@ -2090,6 +2093,10 @@ static int stm32_hpinterrupt(int irq, void *context)
privep->txbusy = 0;
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);
@ -2110,7 +2117,7 @@ static int stm32_lpinterrupt(int irq, void *context)
struct stm32_usbdev_s *priv = &g_usbdev;
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
* 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);
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);
return OK;
goto exit_lpinterrupt;
}
/* 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)
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSP), 0);
stm32_suspend(priv);
/* Clear of the ISTR bit must be done after setting of USB_CNTR_FSUSP */
stm32_putreg(~USB_ISTR_SUSP, STM32_USB_ISTR);
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSP), 0);
}
if ((istr & USB_ISTR_ESOF & priv->imask) != 0)
@ -2187,10 +2196,35 @@ static int stm32_lpinterrupt(int irq, void *context)
stm32_lptransfer(priv);
}
exit_lpinterrupt:
usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_LPINTERRUPT), 0);
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
****************************************************************************/
@ -2199,17 +2233,12 @@ static void stm32_suspend(struct stm32_usbdev_s *priv)
{
uint16 regval;
/* Disable ESOF polling, disable the SUSP interrupt, and
* enable the WKUP interrupt.
/* Disable ESOF polling, disable the SUSP interrupt, and enable the WKUP
* interrupt. Clear any pending WKUP interrupt.
*/
priv->imask &= ~(USB_CNTR_ESOFM|USB_CNTR_SUSPM);
priv->imask |= USB_CNTR_WKUPM;
stm32_putreg(priv->imask, STM32_USB_CNTR);
/* Clear any pending interrupts that we just enabled */
stm32_putreg(~USB_CNTR_WKUPM, STM32_USB_ISTR);
stm32_setimask(priv, USB_CNTR_WKUPM, USB_CNTR_ESOFM|USB_CNTR_SUSPM);
stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR);
/* Enter suspend mode */
@ -2288,17 +2317,12 @@ static void stm32_esofpoll(struct stm32_usbdev_s *priv)
stm32_putreg(regval, STM32_USB_CNTR);
priv->rsmstate = RSMSTATE_IDLE;
/* Disable ESOF polling, disable the SUSP interrupt, and
* enable the WKUP interrupt.
/* Disable ESOF polling, disable the SUSP interrupt, and enable
* the WKUP interrupt. Clear any pending WKUP interrupt.
*/
priv->imask &= ~(USB_CNTR_ESOFM|USB_CNTR_SUSPM);
priv->imask |= USB_CNTR_WKUPM;
stm32_putreg(priv->imask, STM32_USB_CNTR);
/* Clear any pending interrupts that we just enabled */
stm32_putreg(~USB_CNTR_WKUPM, STM32_USB_ISTR);
stm32_setimask(priv, USB_CNTR_WKUPM, USB_CNTR_ESOFM|USB_CNTR_SUSPM);
stm32_putreg(~USB_ISTR_WKUP, STM32_USB_ISTR);
}
break;
@ -3000,16 +3024,12 @@ static int stm32_wakeup(struct usbdev_s *dev)
/* Disable the SUSP interrupt (until we are fully resumed), disable
* 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);
priv->imask |= USB_CNTR_ESOFM;
stm32_putreg(priv->imask, STM32_USB_CNTR);
/* Clear any pending interrupts that we just enabled */
stm32_putreg(~USB_CNTR_ESOFM, STM32_USB_ISTR);
stm32_setimask(priv, USB_CNTR_ESOFM, USB_CNTR_WKUPM|USB_CNTR_SUSPM);
stm32_putreg(~USB_ISTR_ESOF, STM32_USB_ISTR);
irqrestore(flags);
return OK;
}
@ -3087,7 +3107,7 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
/* Set the interrrupt priority */
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)
{
/* 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);
/* Disable interrupts (and perhaps take the USB controller out of reset) */
priv->imask = 0;
stm32_putreg(priv->imask, STM32_USB_CNTR);
/* Clear pending interrupts */
stm32_putreg(0, STM32_USB_ISTR);
stm32_putreg((uint16)~USB_ISTR_ALLINTS, STM32_USB_ISTR);
/* Set the STM32 BTABLE address */
@ -3128,8 +3149,7 @@ static void stm32_hwreset(struct stm32_usbdev_s *priv)
/* Enable interrupts at the USB controllr */
priv->imask = STM32_CNTR_SETUP;
stm32_putreg(priv->imask, STM32_USB_CNTR);
stm32_setimask(priv, STM32_CNTR_SETUP, (USB_CNTR_ALLINTS & ~STM32_CNTR_SETUP));
}
/****************************************************************************
@ -3164,6 +3184,10 @@ void up_usbinitialize(void)
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
* have the initial value of zero and, hence, are not explicitly
* initialized here.
@ -3275,7 +3299,7 @@ void up_usbuninitialize(void)
/* Clear pending interrupts */
stm32_putreg(0, STM32_USB_ISTR);
stm32_putreg(~USB_ISTR_ALLINTS, STM32_USB_ISTR);
/* 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_USBLPCANRX0, CONFIG_USB_PRI);
/* Enable pull-up to connect the device */
stm32_usbpullup(&priv->usbdev, TRUE);
}
return ret;
}

View File

@ -161,9 +161,12 @@
#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_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_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 */
#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_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 */
#define USB_FNR_FN_SHIFT (0) /* Bits 10-0: Frame Number */