Fix PMA addressing issues

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2203 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-10-31 18:34:54 +00:00
parent 67767c433a
commit 4f239a2fa7

View File

@ -354,18 +354,22 @@ static void stm32_dumpep(int epno);
static inline void static inline void
stm32_seteptxcount(ubyte epno, uint16 count); stm32_seteptxcount(ubyte epno, uint16 count);
static inline void static inline void
stm32_seteptxaddr(ubyte epno, ubyte addr); stm32_seteptxaddr(ubyte epno, uint16 addr);
static inline uint16
stm32_geteptxaddr(ubyte epno);
static void stm32_seteprxcount(ubyte epno, uint16 count); static void stm32_seteprxcount(ubyte epno, uint16 count);
static inline uint16 static inline uint16
stm32_geteprxcount(ubyte epno); stm32_geteprxcount(ubyte epno);
static inline void static inline void
stm32_seteprxaddr(ubyte epno, ubyte addr); stm32_seteprxaddr(ubyte epno, uint16 addr);
static inline uint16
stm32_geteprxaddr(ubyte epno);
static inline void static inline void
stm32_setepaddress(ubyte epno, ubyte addr); stm32_setepaddress(ubyte epno, uint16 addr);
static inline void static inline void
stm32_seteptype(ubyte epno, uint16 type); stm32_seteptype(ubyte epno, uint16 type);
static inline void static inline void
stm32_seteptxaddr(ubyte epno, ubyte addr); stm32_seteptxaddr(ubyte epno, uint16 addr);
static inline void static inline void
stm32_setstatusout(ubyte epno); stm32_setstatusout(ubyte epno);
static inline void static inline void
@ -393,9 +397,9 @@ static void stm32_esofpoll(struct stm32_usbdev_s *priv) ;
/* Request Helpers **********************************************************/ /* Request Helpers **********************************************************/
static void stm32_copytopma(const ubyte *buffer, uint16 pmaoffset, uint16 nbytes); static void stm32_copytopma(const ubyte *buffer, uint16 pma, uint16 nbytes);
static inline void static inline void
stm32_copyfrompma(ubyte *buffer, uint16 pmaoffset, uint16 nbytes); stm32_copyfrompma(ubyte *buffer, uint16 pma, uint16 nbytes);
static struct stm32_req_s * static struct stm32_req_s *
stm32_rqdequeue(struct stm32_ep_s *privep); stm32_rqdequeue(struct stm32_ep_s *privep);
static void stm32_rqenqueue(struct stm32_ep_s *privep, static void stm32_rqenqueue(struct stm32_ep_s *privep,
@ -661,12 +665,22 @@ static inline void stm32_seteptxcount(ubyte epno, uint16 count)
* Name: stm32_seteptxaddr * Name: stm32_seteptxaddr
****************************************************************************/ ****************************************************************************/
static inline void stm32_seteptxaddr(ubyte epno, ubyte addr) static inline void stm32_seteptxaddr(ubyte epno, uint16 addr)
{ {
volatile uint32 *txaddr = (uint32*)STM32_USB_ADDR_TX(epno); volatile uint32 *txaddr = (uint32*)STM32_USB_ADDR_TX(epno);
*txaddr = addr; *txaddr = addr;
} }
/****************************************************************************
* Name: stm32_geteptxaddr
****************************************************************************/
static inline uint16 stm32_geteptxaddr(ubyte epno)
{
volatile uint32 *txaddr = (uint32*)STM32_USB_ADDR_TX(epno);
return (uint16)*txaddr;
}
/**************************************************************************** /****************************************************************************
* Name: stm32_seteprxcount * Name: stm32_seteprxcount
****************************************************************************/ ****************************************************************************/
@ -726,17 +740,27 @@ static inline uint16 stm32_geteprxcount(ubyte epno)
* Name: stm32_seteprxaddr * Name: stm32_seteprxaddr
****************************************************************************/ ****************************************************************************/
static inline void stm32_seteprxaddr(ubyte epno, ubyte addr) static inline void stm32_seteprxaddr(ubyte epno, uint16 addr)
{ {
volatile uint32 *rxaddr = (uint32*)STM32_USB_ADDR_RX(epno); volatile uint32 *rxaddr = (uint32*)STM32_USB_ADDR_RX(epno);
*rxaddr = addr; *rxaddr = addr;
} }
/****************************************************************************
* Name: stm32_seteprxaddr
****************************************************************************/
static inline uint16 stm32_geteprxaddr(ubyte epno)
{
volatile uint32 *rxaddr = (uint32*)STM32_USB_ADDR_RX(epno);
return (uint16)*rxaddr;
}
/**************************************************************************** /****************************************************************************
* Name: stm32_setepaddress * Name: stm32_setepaddress
****************************************************************************/ ****************************************************************************/
static inline void stm32_setepaddress(ubyte epno, ubyte addr) static inline void stm32_setepaddress(ubyte epno, uint16 addr)
{ {
uint32 epaddr = STM32_USB_EPR(epno); uint32 epaddr = STM32_USB_EPR(epno);
uint16 regval; uint16 regval;
@ -969,7 +993,7 @@ static inline uint16 stm32_eprxstalled(ubyte epno)
* Name: stm32_copytopma * Name: stm32_copytopma
****************************************************************************/ ****************************************************************************/
static void stm32_copytopma(const ubyte *buffer, uint16 pmaoffset, uint16 nbytes) static void stm32_copytopma(const ubyte *buffer, uint16 pma, uint16 nbytes)
{ {
uint16 *dest; uint16 *dest;
uint16 ms; uint16 ms;
@ -977,9 +1001,11 @@ static void stm32_copytopma(const ubyte *buffer, uint16 pmaoffset, uint16 nbytes
int nwords = (nbytes + 1) >> 1; int nwords = (nbytes + 1) >> 1;
int i; int i;
ullvdbg("pma=%08x, nbytes=%d\n", pma, nbytes);
/* Copy loop. Source=user buffer, Dest=packet memory */ /* Copy loop. Source=user buffer, Dest=packet memory */
dest = (uint16*)((pmaoffset << 1) + STM32_USBCANRAM_BASE); dest = (uint16*)(STM32_USBCANRAM_BASE + ((uint32)pma << 1));
for (i = nwords; i != 0; i--) for (i = nwords; i != 0; i--)
{ {
/* Read two bytes and pack into on 16-bit word */ /* Read two bytes and pack into on 16-bit word */
@ -1001,15 +1027,17 @@ static void stm32_copytopma(const ubyte *buffer, uint16 pmaoffset, uint16 nbytes
****************************************************************************/ ****************************************************************************/
static inline void static inline void
stm32_copyfrompma(ubyte *buffer, uint16 pmaoffset, uint16 nbytes) stm32_copyfrompma(ubyte *buffer, uint16 pma, uint16 nbytes)
{ {
uint32 *src; uint32 *src;
int nwords = (nbytes + 1) >> 1; int nwords = (nbytes + 1) >> 1;
int i; int i;
ullvdbg("pma=%08x, nbytes=%d\n", pma, nbytes);
/* Copy loop. Source=packet memory, Dest=user buffer */ /* Copy loop. Source=packet memory, Dest=user buffer */
src = (uint32*)((pmaoffset << 1) + STM32_USBCANRAM_BASE); src = (uint32*)(STM32_USBCANRAM_BASE + ((uint32)pma << 1));
for (i = nwords; i != 0; i--) for (i = nwords; i != 0; i--)
{ {
/* Copy 16-bits from packet memory to user buffer. */ /* Copy 16-bits from packet memory to user buffer. */
@ -1019,6 +1047,7 @@ stm32_copyfrompma(ubyte *buffer, uint16 pmaoffset, uint16 nbytes)
/* Source address increments by 1*sizeof(uint32) = 4; Dest address /* Source address increments by 1*sizeof(uint32) = 4; Dest address
* increments by 2*sizeof(ubyte) = 2. * increments by 2*sizeof(ubyte) = 2.
*/ */
buffer += 2; buffer += 2;
} }
} }
@ -1144,7 +1173,7 @@ static void stm32_epwrite(struct stm32_usbdev_s *priv,
* endpoint * endpoint
*/ */
stm32_copytopma(buf, (uint16)STM32_USB_ADDR_RX(epno), nbytes); stm32_copytopma(buf, stm32_geteptxaddr(epno), nbytes);
} }
/* Send the packet (might be a null packet nbytes == 0) */ /* Send the packet (might be a null packet nbytes == 0) */
@ -1261,7 +1290,8 @@ static int stm32_wrrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep) static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *privep)
{ {
struct stm32_req_s *privreq; struct stm32_req_s *privreq;
ubyte *buf; uint32 src;
ubyte *dest;
ubyte epno; ubyte epno;
int pmalen; int pmalen;
int readlen; int readlen;
@ -1295,16 +1325,20 @@ static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd); usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
/* Get the source and desintion transfer addresses */
dest = privreq->req.buf + privreq->req.xfrd;
src = stm32_geteprxaddr(epno);
/* Get the number of bytes to read from packet memory */ /* Get the number of bytes to read from packet memory */
#warning "Doesn't this length include 2 bytes for the CRC?" #warning "Doesn't this length include 2 bytes for the CRC?"
pmalen = stm32_geteprxcount(epno); pmalen = stm32_geteprxcount(epno);
readlen = MIN(privreq->req.len, pmalen);
/* Receive the next packet */ /* Receive the next packet */
buf = privreq->req.buf + privreq->req.xfrd; stm32_copyfrompma(dest, src, readlen);
readlen = MIN(privreq->req.len, pmalen);
stm32_copyfrompma(buf, (uint16)STM32_USB_ADDR_TX(EP0), readlen);
/* If the receive buffer is full then we are finished with the transfer */ /* If the receive buffer is full then we are finished with the transfer */
@ -1390,7 +1424,6 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
union wb_u len; union wb_u len;
union wb_u response; union wb_u response;
boolean handled = FALSE; boolean handled = FALSE;
ubyte *buf;
ubyte epno; ubyte epno;
int nbytes = 0; int nbytes = 0;
int ret; int ret;
@ -1413,23 +1446,9 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
ep0->stalled = 0; ep0->stalled = 0;
/* Get a 32-bit PMA address */ /* Get a 32-bit PMA address and use that to get the 8-byte setup request */
buf = (ubyte*)(STM32_USBCANRAM_BASE + ((uint16)STM32_USB_ADDR_RX(EP0) << 1)); stm32_copyfrompma((ubyte*)&priv->ctrl, stm32_geteprxaddr(EP0), USB_SIZEOF_CTRLREQ);
/* Extract the request from PMA */
priv->ctrl.type = *buf++; /* bmRequestType */
priv->ctrl.req = *buf++; /* bRequest */
buf += 2; /* Skip for 32 bits addressing */
priv->ctrl.value[0] = *buf++; /* wValue */
priv->ctrl.value[1] = *buf++; /* " " */
buf += 2; /* Skip for 32 bits addressing */
priv->ctrl.index[0] = *buf++; /* wIndex */
priv->ctrl.index[1] = *buf++; /* " " */
buf += 2; /* Skip for 32 bits addressing */
priv->ctrl.len[0] = *buf++; /* wLength */
priv->ctrl.len[1] = *buf++; /* " " */
/* And extract the little-endian 16-bit values to host order */ /* And extract the little-endian 16-bit values to host order */
@ -1437,7 +1456,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
index.w = GETUINT16(priv->ctrl.index); index.w = GETUINT16(priv->ctrl.index);
len.w = GETUINT16(priv->ctrl.len); len.w = GETUINT16(priv->ctrl.len);
ullvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n",
priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w);
priv->devstate = DEVSTATE_INIT; priv->devstate = DEVSTATE_INIT;
@ -2561,6 +2580,7 @@ static int stm32_epconfigure(struct usbdev_ep_s *ep,
if (!ep || !desc) if (!ep || !desc)
{ {
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
ulldbg("ERROR: ep=%p desc=%p\n");
return -EINVAL; return -EINVAL;
} }
#endif #endif
@ -2658,6 +2678,7 @@ static int stm32_epdisable(struct usbdev_ep_s *ep)
if (!ep) if (!ep)
{ {
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
ulldbg("ERROR: ep=%p\n", ep);
return -EINVAL; return -EINVAL;
} }
#endif #endif
@ -2744,7 +2765,7 @@ static int stm32_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
if (!req || !req->callback || !req->buf || !ep) if (!req || !req->callback || !req->buf || !ep)
{ {
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
ullvdbg("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); ulldbg("ERROR: req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep);
return -EINVAL; return -EINVAL;
} }
#endif #endif
@ -2752,11 +2773,17 @@ static int stm32_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog)); usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog));
priv = privep->dev; priv = privep->dev;
if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) #ifdef CONFIG_DEBUG
if (!priv->driver)
{ {
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed);
ulldbg("ERROR: driver=%p\n", priv->driver);
return -ESHUTDOWN; return -ESHUTDOWN;
} }
#endif
usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog));
priv = privep->dev;
/* Handle the request from the class driver */ /* Handle the request from the class driver */
@ -2769,6 +2796,7 @@ static int stm32_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
if (privep->stalled) if (privep->stalled)
{ {
stm32_abortrequest(privep, privreq, -EBUSY); stm32_abortrequest(privep, privreq, -EBUSY);
ulldbg("ERROR: stalled\n");
ret = -EBUSY; ret = -EBUSY;
} }
@ -3198,6 +3226,7 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
/* Re-configure the USB controller in its initial, unconnected state */ /* Re-configure the USB controller in its initial, unconnected state */
stm32_hwreset(priv); stm32_hwreset(priv);
priv->usbdev.speed = USB_SPEED_FULL;
} }
/**************************************************************************** /****************************************************************************
@ -3321,6 +3350,16 @@ void up_usbinitialize(void)
#if STM32_EP0MAXPACKET < STM32_MAXPACKET_SIZE #if STM32_EP0MAXPACKET < STM32_MAXPACKET_SIZE
priv->eplist[EP0].ep.maxpacket = STM32_EP0MAXPACKET; priv->eplist[EP0].ep.maxpacket = STM32_EP0MAXPACKET;
#endif #endif
/* Configure the USB controller. USB uses the following GPIO pins:
*
* PA9 - VBUS
* PA10 - ID
* PA11 - DM
* PA12 - DP
*
* "As soon as the USB is enabled, these pins [DM and DP] are connected to
* the USB internal transceiver automatically."
*/
/* Power up the USB controller, holding it in reset. There is a delay of /* Power up the USB controller, holding it in reset. There is a delay of
* about 1uS after applying power before the USB will behave predictably. * about 1uS after applying power before the USB will behave predictably.
@ -3485,6 +3524,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
*/ */
stm32_usbpullup(&priv->usbdev, TRUE); stm32_usbpullup(&priv->usbdev, TRUE);
priv->usbdev.speed = USB_SPEED_FULL;
} }
return ret; return ret;
} }