diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-04-07 14:08:37 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-04-07 14:08:37 +0000 |
commit | 36e37f5da4d016e033006db34bc8abad1d299b5d (patch) | |
tree | 0757b55e583be618fe5eae3079126af82845d33d /nuttx/arch | |
parent | 2ac0dff544582a43ec516a7f3f56f14916362d33 (diff) | |
download | px4-firmware-36e37f5da4d016e033006db34bc8abad1d299b5d.tar.gz px4-firmware-36e37f5da4d016e033006db34bc8abad1d299b5d.tar.bz2 px4-firmware-36e37f5da4d016e033006db34bc8abad1d299b5d.zip |
Move include/math.h to include/nuttx/math.h
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4568 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/arch')
-rwxr-xr-x | nuttx/arch/arm/src/stm32/stm32_otgfsdev.c | 193 |
1 files changed, 147 insertions, 46 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c index 2bf2c9e8d..19bd3f17b 100755 --- a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c +++ b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c @@ -120,15 +120,16 @@ #define STM32_TRACEERR_DISPATCHSTALL 0x000f #define STM32_TRACEERR_DRIVER 0x0010 #define STM32_TRACEERR_DRIVERREGISTERED 0x0011 -#define STM32_TRACEERR_EP0SETUPSTALLED 0x0012 -#define STM32_TRACEERR_EPINNULLPACKET 0x0013 -#define STM32_TRACEERR_EPOUTNULLPACKET 0x0014 -#define STM32_TRACEERR_INVALIDCTRLREQ 0x0015 -#define STM32_TRACEERR_INVALIDPARMS 0x0016 -#define STM32_TRACEERR_IRQREGISTRATION 0x0017 -#define STM32_TRACEERR_NOEP 0x0018 -#define STM32_TRACEERR_NOTCONFIGURED 0x0019 -#define STM32_TRACEERR_EPOUTQEMPTY 0x001a +#define STM32_TRACEERR_EP0NOSETUP 0x0012 +#define STM32_TRACEERR_EP0SETUPSTALLED 0x0013 +#define STM32_TRACEERR_EPINNULLPACKET 0x0014 +#define STM32_TRACEERR_EPOUTNULLPACKET 0x0015 +#define STM32_TRACEERR_INVALIDCTRLREQ 0x0016 +#define STM32_TRACEERR_INVALIDPARMS 0x0017 +#define STM32_TRACEERR_IRQREGISTRATION 0x0018 +#define STM32_TRACEERR_NOEP 0x0019 +#define STM32_TRACEERR_NOTCONFIGURED 0x001a +#define STM32_TRACEERR_EPOUTQEMPTY 0x001b /* Trace interrupt codes */ @@ -333,6 +334,7 @@ struct stm32_usbdev_s uint8_t configured:1; /* 1: Class driver has been configured */ uint8_t wakeup:1; /* 1: Device remote wake-up */ uint8_t dotest:1; /* 1: Test mode selected */ + uint8_t setup:1; /* 1: SETUP received */ uint8_t devstate; /* See enum stm32_devstate_e */ uint8_t ep0state; /* See enum stm32_ep0state_e */ @@ -374,6 +376,7 @@ static bool stm32_addlast(FAR struct stm32_ep_s *privep, static inline void stm32_ep0xfer(uint8_t epphy, FAR uint8_t *data, uint32_t nbytes); static void stm32_ep0read(FAR uint8_t *dest, uint16_t len); +static void stm32_ep0configsetup(FAR struct stm32_usbdev_s *priv) /* IN request handling */ @@ -728,6 +731,24 @@ static void stm32_ep0read(FAR uint8_t *dest, uint16_t len) } } +/******************************************************************************* + * Name: stm32_ep0configsetup + * + * Description: + * Setup to receive a SETUP packet. + * + *******************************************************************************/ + +static void stm32_ep0configsetup(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) || + (OTGFS_DOEPTSIZ0_PKTCNT) || + (3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT); + stm32_putreg(regval, STM32_OTGFS_DOEPTSIZ0); +} + /**************************************************************************** * Name: stm32_wrrequest * @@ -943,49 +964,105 @@ static void stm32_epoutsetup(FAR struct stm32_usbdev_s *priv, FAR struct stm32_ep_s *privep) { struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint32_t xfrsize; + uint32_t pktcnt; - /* Loop until a valid request is found (or the request queue is empty) */ + /* Make sure that there is not already a pending request request. If there is, + * just return, leaving the newly received request in the request queue. + */ - for (;;) + if (!priv->active) { - /* Get a reference to the request at the head of the endpoint's request queue */ + /* Loop until a valid request is found (or the request queue is empty). + * The loop is only need to look at the request queue again is an invalid + * read request is encountered. + */ - privreq = stm32_rqpeek(privep); - if (!privreq) + for (;;) { - /* There are no read requests to be setup. Configure the hardware to - * NAK any incoming packets. - */ + /* Get a reference to the request at the head of the endpoint's request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + /* There are no read requests to be setup. Configure the hardware to + * NAK any incoming packets. + */ #warning "Missing logic" - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); - privep->active = false; - return; - } + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + privep->active = false; + return; + } - ullvdbg("EP%d: len=%d\n", privep->epphy, privreq->req.len); + ullvdbg("EP%d: len=%d\n", privep->epphy, privreq->req.len); - /* Ignore any attempt to receive a zero length packet (this really - * should not happen. - */ + /* Ignore any attempt to receive a zero length packet (this really + * should not happen. + */ - if (privreq->req.len == 0) - { - usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0); - stm32_reqcomplete(privep, OK); + if (privreq->req.len <= 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0); + stm32_reqcomplete(privep, OK); + } + + /* Otherwise, we have a usable read request... break out of the loop */ + + else + { + break; + } } - /* Otherwise, we have a usable read request... break out of the loop */ + /* Setup the pending read into the request buffer. First calculate: + * + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + * xfrsize = The total number of bytes required (in units of + * maxpacket bytes). + */ - else + pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + xfrsize = pktcnt * privep->ep.maxpacket; + + /* Then setup the hardware to perform this transfer */ + + regaddr = STM32_OTGFS_DOEPTSIZ(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~(OTGFS_DOEPTSIZ_XFRSIZ_MASK | OTGFS_DOEPTSIZ_PKTCNT_MASK); + regval |= (xfrsize << OTGFS_DOEPTSIZ_XFRSIZ_SHIFT); + regval |= (pktcnt << OTGFS_DOEPTSIZ_PKTCNT_SHIFT); + stm32_putreg(regval, regaddr); + + /* Then enable the transfer */ + + regaddr = STM32_OTGFS_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) { - break; + if (privep->odd) + { + regval |= OTGFS_DOEPCTL_SD1PID; + } + else + { + regval |= OTGFS_DOEPCTL_SD0PID; + } } - } +#endif - /* Set up the pending read into the request buffer */ -#warning "Missing logic" - privep->active = true; + regval |= (OTGFS_DOEPCTL_CNAK | OTGFS_DOEPCTL_EPENA); + stm32_putreg(regval, regaddr); + + /* A transfer is now active on this endpoint */ + + privep->active = true; + } } /******************************************************************************* @@ -1267,6 +1344,8 @@ static void stm32_ep0complete(struct stm32_usbdev_s *priv, uint8_t epphy) break; } + /* Check if the packet processing resulting in a STALL */ + if (priv->stalled) { usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); @@ -1816,6 +1895,14 @@ static inline void stm32_ep0setup(struct stm32_usbdev_s *priv) { struct stm32_ctrlreq_s ctrlreq; + /* Verify that a SETUP was received */ + + if (!priv->setup) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0NOSETUP), priv->ep0state); + return; + } + /* Terminate any pending requests - since all DTDs will have been retired * because of the setup packet. */ @@ -1829,10 +1916,6 @@ static inline void stm32_ep0setup(struct stm32_usbdev_s *priv) priv->epin[EP0].stalled = false; priv->stalled = false; - /* Read EP0 setup data */ -#warning "Doesn't this conflict with logic in stm32_rxinterrupt?" - stm32_ep0read((FAR uint8_t*)&ctrlreq, USB_SIZEOF_CTRLREQ); - /* Starting a control request - update state */ priv->ep0state = (priv->ctrlreq.type & USB_REQ_DIR_IN) ? EP0STATE_SETUP_IN : EP0STATE_SETUP_OUT; @@ -1863,11 +1946,17 @@ static inline void stm32_ep0setup(struct stm32_usbdev_s *priv) stm32_stdrequest(priv, &ctrlreq); } + /* Check if the setup processing resulted in a STALL */ + if (priv->stalled) { usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); stm32_ep0stall(priv); } + + /* The SETUP data has been processed */ + + priv->setup = false; } /******************************************************************************* @@ -1909,7 +1998,7 @@ static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, uint8_t epno) { priv->ep0state = EP0STATE_STATUS_OUT; stm32_rxsetup(priv, privep, NULL, 0); - stm32_ep0outstart(priv); + stm32_ep0configsetup(priv); } } @@ -1960,7 +2049,11 @@ static inline void stm32_epoutinterrupt(FAR struct stm32_usbdev_s *priv) doepint = stm32_getreg(STM32_OTGFS_DOEPINT(epno)); doepint &= stm32_getreg(STM32_OTGFS_DOEPMSK); - /* Transfer completed interrupt */ + /* Transfer completed interrupt. This interrupt is trigged when + * stm32_rxinterrupt() removes the last packet data from the RxFIFO. + * In this case, core internally sets the NAK bit for this endpoint to + * prevent it from receiving any more packets. + */ if ((doepint & OTGFS_DOEPINT_XFRC) != 0) { @@ -2384,10 +2477,16 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv) { usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); - /* Read EP0 setup data */ + /* Read EP0 setup data. NOTE: If multipe SETUP packets are received, + * the last one overwrites the previous setup packets and only that + * last SETUP packet will be processed. + */ stm32_ep0read((FAR uint8_t*)&priv->ctrlreq, USB_SIZEOF_CTRLREQ); -#warning "REVISIT... doesn't this conflict with logic in ep0setup?" + + /* The SETUP data has been processed */ + + priv->setup = false; } break; @@ -2571,7 +2670,7 @@ static int stm32_usbinterrupt(int irq, FAR void *context) } usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), (uint16_t)regval); - /* OUT endpoint interrupt */ + /* OUT endpoint interrupt. */ if ((regval & OTGFS_GINT_OEP) != 0) { @@ -3391,7 +3490,7 @@ static void stm32_ep0stall(FAR struct stm32_usbdev_s *priv) stm32_epsetstall(&priv->epin[EP0]); stm32_epsetstall(&priv->epout[EP0]); priv->stalled = true; - stm32_ep0outstart(priv); + stm32_ep0configsetup(priv); } /******************************************************************************* @@ -3476,9 +3575,11 @@ static FAR struct usbdev_ep_s *stm32_allocep(FAR struct usbdev_s *dev, uint8_t e epset &= STM32_EPBULKSET; break; +#ifdef CONFIG_USBDEV_ISOCHRONOUS case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ epset &= STM32_EPISOCSET; break; +#endif case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint -- not a valid choice */ default: |