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 dbfaa18d76
commit 624c01ed82
1 changed files with 79 additions and 39 deletions

View File

@ -354,18 +354,22 @@ static void stm32_dumpep(int epno);
static inline void
stm32_seteptxcount(ubyte epno, uint16 count);
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 inline uint16
stm32_geteprxcount(ubyte epno);
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
stm32_setepaddress(ubyte epno, ubyte addr);
stm32_setepaddress(ubyte epno, uint16 addr);
static inline void
stm32_seteptype(ubyte epno, uint16 type);
static inline void
stm32_seteptxaddr(ubyte epno, ubyte addr);
stm32_seteptxaddr(ubyte epno, uint16 addr);
static inline void
stm32_setstatusout(ubyte epno);
static inline void
@ -393,9 +397,9 @@ static void stm32_esofpoll(struct stm32_usbdev_s *priv) ;
/* 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
stm32_copyfrompma(ubyte *buffer, uint16 pmaoffset, uint16 nbytes);
stm32_copyfrompma(ubyte *buffer, uint16 pma, uint16 nbytes);
static struct stm32_req_s *
stm32_rqdequeue(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
****************************************************************************/
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);
*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
****************************************************************************/
@ -726,17 +740,27 @@ static inline uint16 stm32_geteprxcount(ubyte epno)
* 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);
*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
****************************************************************************/
static inline void stm32_setepaddress(ubyte epno, ubyte addr)
static inline void stm32_setepaddress(ubyte epno, uint16 addr)
{
uint32 epaddr = STM32_USB_EPR(epno);
uint16 regval;
@ -969,7 +993,7 @@ static inline uint16 stm32_eprxstalled(ubyte epno)
* 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 ms;
@ -977,9 +1001,11 @@ static void stm32_copytopma(const ubyte *buffer, uint16 pmaoffset, uint16 nbytes
int nwords = (nbytes + 1) >> 1;
int i;
ullvdbg("pma=%08x, nbytes=%d\n", pma, nbytes);
/* 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--)
{
/* 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
stm32_copyfrompma(ubyte *buffer, uint16 pmaoffset, uint16 nbytes)
stm32_copyfrompma(ubyte *buffer, uint16 pma, uint16 nbytes)
{
uint32 *src;
int nwords = (nbytes + 1) >> 1;
int i;
ullvdbg("pma=%08x, nbytes=%d\n", pma, nbytes);
/* 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--)
{
/* 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
* increments by 2*sizeof(ubyte) = 2.
*/
buffer += 2;
}
}
@ -1144,7 +1173,7 @@ static void stm32_epwrite(struct stm32_usbdev_s *priv,
* 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) */
@ -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)
{
struct stm32_req_s *privreq;
ubyte *buf;
uint32 src;
ubyte *dest;
ubyte epno;
int pmalen;
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);
/* 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 */
#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 */
buf = privreq->req.buf + privreq->req.xfrd;
readlen = MIN(privreq->req.len, pmalen);
stm32_copyfrompma(buf, (uint16)STM32_USB_ADDR_TX(EP0), readlen);
stm32_copyfrompma(dest, src, readlen);
/* 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 response;
boolean handled = FALSE;
ubyte *buf;
ubyte epno;
int nbytes = 0;
int ret;
@ -1413,23 +1446,9 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
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));
/* 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++; /* " " */
stm32_copyfrompma((ubyte*)&priv->ctrl, stm32_geteprxaddr(EP0), USB_SIZEOF_CTRLREQ);
/* 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);
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->devstate = DEVSTATE_INIT;
@ -2561,6 +2580,7 @@ static int stm32_epconfigure(struct usbdev_ep_s *ep,
if (!ep || !desc)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
ulldbg("ERROR: ep=%p desc=%p\n");
return -EINVAL;
}
#endif
@ -2658,6 +2678,7 @@ static int stm32_epdisable(struct usbdev_ep_s *ep)
if (!ep)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0);
ulldbg("ERROR: ep=%p\n", ep);
return -EINVAL;
}
#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)
{
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;
}
#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));
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);
ulldbg("ERROR: driver=%p\n", priv->driver);
return -ESHUTDOWN;
}
#endif
usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog));
priv = privep->dev;
/* 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)
{
stm32_abortrequest(privep, privreq, -EBUSY);
ulldbg("ERROR: stalled\n");
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 */
stm32_hwreset(priv);
priv->usbdev.speed = USB_SPEED_FULL;
}
/****************************************************************************
@ -3321,6 +3350,16 @@ void up_usbinitialize(void)
#if STM32_EP0MAXPACKET < STM32_MAXPACKET_SIZE
priv->eplist[EP0].ep.maxpacket = STM32_EP0MAXPACKET;
#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
* 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);
priv->usbdev.speed = USB_SPEED_FULL;
}
return ret;
}