diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-08-29 18:11:34 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-08-29 18:11:34 -0600 |
commit | 9e89d126df9285991489ecf76845d89a50383976 (patch) | |
tree | 28a57b347e5907d6267044e5ee3790890aa0160c | |
parent | a3dbc581d78f662eb48509a888492a6f046510aa (diff) | |
download | px4-nuttx-9e89d126df9285991489ecf76845d89a50383976.tar.gz px4-nuttx-9e89d126df9285991489ecf76845d89a50383976.tar.bz2 px4-nuttx-9e89d126df9285991489ecf76845d89a50383976.zip |
SAMA5 UDPHS interrupt decoding logic
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_udphs.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/nuttx/arch/arm/src/sama5/sam_udphs.c b/nuttx/arch/arm/src/sama5/sam_udphs.c index 4fde302dd..0ec3e56ba 100644 --- a/nuttx/arch/arm/src/sama5/sam_udphs.c +++ b/nuttx/arch/arm/src/sama5/sam_udphs.c @@ -447,6 +447,7 @@ static int sam_udphs_interrupt(int irq, void *context); /* Endpoint helpers *********************************************************/ +static void sam_epset_reset(struct sam_usbdev_s *priv, uint32_t epset); static inline struct sam_ep_s * sam_epreserve(struct sam_usbdev_s *priv, uint8_t epset); static inline void @@ -2179,6 +2180,50 @@ static void sam_esofpoll(struct sam_usbdev_s *priv) * Endpoint Helpers ****************************************************************************/ /**************************************************************************** + * Name: sam_epset_reset + ****************************************************************************/ + +void sam_epset_reset(struct sam_usbdev_s *priv, uint32_t epset) +{ + struct sam_ep_s *privep; + uint32_t bit; + int epno; + + /* Restrict the set of of endpoints to those actually supported */ + + epset &= ((1 << SAM_UDPHS_NENDPOINTS) - 1); + + /* Then reset each endpoint in the set */ + + for (epno = 0, bit = 1; epno < SAM_UDPHS_NENDPOINTS; epno++) + { + if ((epset & bit) != 0) + { + privep = &priv->eplist[epno]; + + /* Disable endpoint interrupt */ + + sam_putreg(~UDPHS_INT_EPT(epno), SAM_UDPHS_IEN); + + /* Reset endpoint */ + + sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST); + + /* Endpoint is no longer functional */ + + privep->epstate = UDPHS_EPSTATE_DISABLED; + privep->bank = 0; + + /* Terminate transfer on this endpoint */ + + sam_endoftransfer(epno, USBD_STATUS_RESET); + } + + bit <<= 1; + } +} + +/**************************************************************************** * Name: sam_epreserve ****************************************************************************/ @@ -3058,9 +3103,9 @@ static void sam_hw_setup(struct sam_usbdev_s *priv) sam_udphs_enableclk(); - /* Reset & disable endpoints */ + /* Reset and disable endpoints */ - sam_ep_resetall(0xffffffff, USBD_STATUS_RESET, 0); + sam_epset_reset(priv, 0xffffffff); /* Configure the pull-up on D+ and disconnect it */ @@ -3071,7 +3116,17 @@ static void sam_hw_setup(struct sam_usbdev_s *priv) regval |= UDPHS_CTRL_PULLDDIS; sam_putreg(regval, SAM_UDPHS_CTRL); - /* Reset the UDPHS block */ + /* Reset the UDPHS block + * + * Paragraph 33.5.1. "One transceiver is shared with the USB High Speed + * Device (port A). The selection between Host Port A and USB Device is + * controlled by the UDPHS enable bit (EN_UDPHS) located in the UDPHS_CTRL + * control register. + * + * "In the case the port A is driven by the USB High Speed Device, the ... + * transceiver is automatically selected for Device operation once the + * USB High Speed Device is enabled." + */ regval &= ~UDPHS_CTRL_ENUDPHS; sam_putreg(regval, SAM_UDPHS_CTRL); |