From 3299a93723bfc0476b5969bb8de8e034c8411159 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 24 Mar 2015 11:19:34 -0600 Subject: SAMV7 USB: Updates to endpoint configuration logic --- nuttx/arch/arm/src/samv7/chip/sam_usbhs.h | 11 ++- nuttx/arch/arm/src/samv7/sam_usbdevhs.c | 113 ++++++++++++++++++------------ 2 files changed, 77 insertions(+), 47 deletions(-) (limited to 'nuttx/arch') diff --git a/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h b/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h index ba9293766..f63578219 100644 --- a/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h +++ b/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h @@ -298,6 +298,7 @@ #define USBHS_DEVEPTCFG_ALLOC (1 << 0) /* Bit 0: Endpoint Memory Allocate */ #define USBHS_DEVEPTCFG_EPBK_SHIFT (2) /* Bits 2-3: Endpoint Banks */ #define USBHS_DEVEPTCFG_EPBK_MASK (3 << USBHS_DEVEPTCFG_EPBK_SHIFT) +# define USBHS_DEVEPTCFG_EPBK(n) ((uint32_t)((n)-1) << USBHS_DEVEPTCFG_EPBK_SHIFT) # define USBHS_DEVEPTCFG_EPBK_1BANK (0 << USBHS_DEVEPTCFG_EPBK_SHIFT) /* Single-bank endpoint */ # define USBHS_DEVEPTCFG_EPBK_2BANK (1 << USBHS_DEVEPTCFG_EPBK_SHIFT) /* Double-bank endpoint */ # define USBHS_DEVEPTCFG_EPBK_3BANK (2 << USBHS_DEVEPTCFG_EPBK_SHIFT) /* Triple-bank endpoint */ @@ -312,16 +313,19 @@ # define USBHS_DEVEPTCFG_EPSIZE_512 (6 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 512 bytes */ # define USBHS_DEVEPTCFG_EPSIZE_1024 (7 << USBHS_DEVEPTCFG_EPSIZE_SHIFT) /* 1024 bytes */ #define USBHS_DEVEPTCFG_EPDIR_SHIFT (8) /* Bit 8: Endpoint Direction */ -#define USBHS_DEVEPTCFG_EPDIR (1 << 8) /* Bit 8: Endpoint Direction */ +#define USBHS_DEVEPTCFG_EPDIR_MASK (1 << 8) /* Bit 8: Endpoint Direction */ +# define USBHS_DEVEPTCFG_EPDIR(n) ((uint32_t)(n) << 8) #define USBHS_DEVEPTCFG_AUTOSW (1 << 9) /* Bit 9: Automatic Switch */ #define USBHS_DEVEPTCFG_EPTYPE_SHIFT (11) /* Bits 11-12: Endpoint Type */ #define USBHS_DEVEPTCFG_EPTYPE_MASK (3 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) +# define USBHS_DEVEPTCFG_EPTYPE(n) ((uint32_t)(n) << USBHS_DEVEPTCFG_EPTYPE_SHIFT) # define USBHS_DEVEPTCFG_EPTYPE_CTRL (0 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Control endpoint */ # define USBHS_DEVEPTCFG_EPTYPE_ISO (1 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Isochronous endpoint */ # define USBHS_DEVEPTCFG_EPTYPE_BLK (2 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Bulk endpoint */ # define USBHS_DEVEPTCFG_EPTYPE_INTRPT (3 << USBHS_DEVEPTCFG_EPTYPE_SHIFT) /* Interrupt endpoint */ #define USBHS_DEVEPTCFG_NBTRANS_SHIFT (13) /* Bits 13-14: Number Transaction per uframe */ #define USBHS_DEVEPTCFG_NBTRANS_MASK (3 << USBHS_DEVEPTCFG_NBTRANS_SHIFT) +# define USBHS_DEVEPTCFG_NBTRANS(n) ((uint32_t)(n) << USBHS_DEVEPTCFG_NBTRANS_SHIFT) /* Common Endpoint Interrupt Bit Definitions * @@ -372,6 +376,11 @@ #define USBHS_DEVEPTINT_RSTDTI (1 << 18) /* Bit 18: Reset Data Toggle */ #define USBHS_DEVEPTINT_STALLRQI (1 << 19) /* Bit 19: STALL Request (1) */ +#define USBHS_DEVEPTICR_ALLINTS 0x000000ff +#define USBHS_DEVEPTIFR_ALLINTS 0x000010ff +#define USBHS_DEVEPTIDR_ALLINTS 0x000d57ff +#define USBHS_DEVEPTIER_ALLINTS 0x000f77ff + /* Device Endpoint Status Register only */ #define USBHS_DEVEPTISR_DTSEQ_SHIFT (8) /* Bits 8-9: Data Toggle Sequence */ diff --git a/nuttx/arch/arm/src/samv7/sam_usbdevhs.c b/nuttx/arch/arm/src/samv7/sam_usbdevhs.c index 97cc4c0ed..e0d0d129e 100644 --- a/nuttx/arch/arm/src/samv7/sam_usbdevhs.c +++ b/nuttx/arch/arm/src/samv7/sam_usbdevhs.c @@ -166,13 +166,13 @@ #define SAM_TRACEERR_EP0SETUPSTALLED 0x0015 #define SAM_TRACEERR_EPOUTNULLPACKET 0x0016 #define SAM_TRACEERR_EPRESERVE 0x0017 -#define SAM_TRACEERR_EPTCFGMAPD 0x0018 +#define SAM_TRACEERR_NCFGOK 0x0018 #define SAM_TRACEERR_INVALIDCTRLREQ 0x0019 #define SAM_TRACEERR_INVALIDPARMS 0x001a #define SAM_TRACEERR_IRQREGISTRATION 0x001b #define SAM_TRACEERR_NOTCONFIGURED 0x001c #define SAM_TRACEERR_REQABORTED 0x001d -#define SAM_TRACEERR_TXINERR 0x001e +#define SAM_TRACEERR_TXINERR 0x001e /* Trace interrupt codes */ @@ -595,7 +595,7 @@ const struct trace_msg_t g_usb_trace_strings_deverror[] = TRACE_STR(SAM_TRACEERR_EP0SETUPSTALLED), TRACE_STR(SAM_TRACEERR_EPOUTNULLPACKET), TRACE_STR(SAM_TRACEERR_EPRESERVE), - TRACE_STR(SAM_TRACEERR_EPTCFGMAPD), + TRACE_STR(SAM_TRACEERR_NCFGOK), TRACE_STR(SAM_TRACEERR_INVALIDCTRLREQ), TRACE_STR(SAM_TRACEERR_INVALIDPARMS), TRACE_STR(SAM_TRACEERR_IRQREGISTRATION), @@ -3210,9 +3210,15 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep, maxpacket = GETUINT16(desc->mxpacketsize); nbtrans = 1; + /* Initialize the endpoint structure */ + + priv = privep->dev; + privep->ep.eplog = desc->addr; /* Includes direction */ + privep->epstate = USBHS_EPSTATE_IDLE; + privep->bank = SAM_USBHS_NBANKS(epno); + /* Special case maxpacket handling for high-speed endpoints */ - priv = privep->dev; if (priv->usbdev.speed == USB_SPEED_HIGH) { /* HS Interval, 125us */ @@ -3228,17 +3234,26 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep, nbtrans++; } + /* nbtrans = 0: Reserved to endpoint that does not have the high- + * bandwidth isochronous capability. + * nbtrans = 1: Default value: one transaction per microframe. + * nbtrans = 2: Two transactions per microframe. This endpoint + * should be configured as double-bank. + * nbtrans = 3 Three transactions per microframe. This endpoint + * should be configured as triple-bank + */ + + if (privep->bank < nbtrans) + { + nbtrans = privep->bank; + } + /* Mask, bit 10..0 is the max packet size */ maxpacket &= 0x7ff; } - /* Initialize the endpoint structure */ - - privep->ep.eplog = desc->addr; /* Includes direction */ - privep->ep.maxpacket = maxpacket; - privep->epstate = USBHS_EPSTATE_IDLE; - privep->bank = SAM_USBHS_NBANKS(epno); + privep->ep.maxpacket = maxpacket; /* Initialize the endpoint hardware */ /* Disable the endpoint */ @@ -3247,13 +3262,7 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep, regval &= ~USBHS_DEVEPT_EPEN(epno); sam_putreg(regval, SAM_USBHS_DEVEPT); - sam_putreg(USBHS_DEVEPTINT_SHRTPCKTI | USBHS_DEVEPTINT_NBUSYBKI | - USBHS_DEVEPTINT_NAKOUTI | USBHS_DEVEPTINT_NAKINI | - USBHS_DEVEPTINT_STALLEDI | USBHS_DEVEPTINT_STALLRQI | - USBHS_DEVEPTINT_TXINI | USBHS_DEVEPTINT_RXOUTI | - USBHS_DEVEPTINT_OVERFI | USBHS_DEVEPTINT_MDATAI | - USBHS_DEVEPTINT_DATAXI | USBHS_DEVEPTINT_NYETDISI, - SAM_USBHS_DEVEPTIDR(epno)); + sam_putreg(USBHS_DEVEPTIDR_ALLINTS, SAM_USBHS_DEVEPTIDR(epno)); /* Reset Endpoint FIFOs */ @@ -3279,10 +3288,10 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep, /* Configure the endpoint */ regval = USBHS_DEVEPTCFG_ALLOC | - ((uint32_t)dirin << USBHS_DEVEPTCFG_EPDIR_SHIFT) | - ((uint32_t)eptype << USBHS_DEVEPTCFG_EPTYPE_SHIFT) | - ((uint32_t)(privep->bank) << USBHS_DEVEPTCFG_EPBK_SHIFT) | - ((uint32_t)nbtrans << USBHS_DEVEPTCFG_NBTRANS_SHIFT); + USBHS_DEVEPTCFG_EPDIR(dirin) | + USBHS_DEVEPTCFG_EPTYPE(eptype) | + USBHS_DEVEPTCFG_EPBK(privep->bank) | + USBHS_DEVEPTCFG_NBTRANS(nbtrans); if (maxpacket <= 8) { @@ -3333,7 +3342,7 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep, if ((sam_getreg(regaddr) & USBHS_DEVEPTISR_CFGOK) == 0) { - usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPTCFGMAPD), epno); + usbtrace(TRACE_DEVERROR(SAM_TRACEERR_NCFGOK), epno); return -EINVAL; } @@ -3365,6 +3374,32 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep, regval |= USBHS_DEVEPT_EPEN(epno); sam_putreg(regval, SAM_USBHS_DEVEPT); + /* If this is EP0, enable interrupts now */ + + if (eptype == USB_EP_ATTR_XFER_CONTROL) + { + /* Enable the endpoint 0 RX interrupts */ + + regaddr = SAM_USBHS_DEVEPTIER(epno); + regval = USBHS_DEVEPTINT_RXOUTI | USBHS_DEVEPTINT_RXSTPI; + sam_putreg(regval, regaddr); + + /* Enable endpoint 0 general interrupts */ + + sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIER); + } +#ifdef CONFIG_USBDEV_DMA + else + { + /* Enable automatic bank switching */ + + regaddr = SAM_USBHS_DEVEPTIER(epno); + regval = sam_getreg(regaddr); + regval |= USBHS_DEVEPTCFG_AUTOSW; + sam_putreg(regval, regaddr); + } +#endif + sam_dumpep(priv, epno); return OK; } @@ -4232,37 +4267,23 @@ static void sam_hw_setup(struct sam_usbdev_s *priv) sam_putreg(regval, SAM_USBHS_DEVDMACTRL(i)); } - /* Initialize Endpoints */ + /* Disable all interrupts. Disable all endpoints */ + + sam_putreg(USBHS_DEVEPT_ALLEPEN, SAM_USBHS_DEVIDR); + sam_putreg(0, SAM_USBHS_DEVEPT); + + /* Disable each endpoint interrupt */ for (i = 0; i < SAM_USBHS_NENDPOINTS; i++) { - /* Disable endpoint */ + /* Disable endpoint interrupts */ - regval = sam_getreg(SAM_USBHS_DEVEPT); - regval &= ~USBHS_DEVEPT_EPEN(i); - sam_putreg(regval, SAM_USBHS_DEVEPT); - - regval = USBHS_DEVEPTINT_SHRTPCKTI | USBHS_DEVEPTINT_NBUSYBKI | - USBHS_DEVEPTINT_NAKOUTI | USBHS_DEVEPTINT_NAKINI | - USBHS_DEVEPTINT_STALLEDI | USBHS_DEVEPTINT_STALLRQI | - USBHS_DEVEPTINT_TXINI | USBHS_DEVEPTINT_RXOUTI | - USBHS_DEVEPTINT_OVERFI | USBHS_DEVEPTINT_MDATAI | - USBHS_DEVEPTINT_DATAXI | USBHS_DEVEPTINT_NYETDISI | - USBHS_DEVEPTINT_EPDISHDMAI; - sam_putreg(regval, SAM_USBHS_DEVEPTIDR(i)); + sam_putreg(USBHS_DEVEPTIDR_ALLINTS, SAM_USBHS_DEVEPTIDR(i)); /* Clear endpoint status */ - regval = USBHS_DEVEPTINT_STALLEDI | USBHS_DEVEPTINT_RXOUTI | - USBHS_DEVEPTINT_TXINI | USBHS_DEVEPTINT_RXSTPI | - USBHS_DEVEPTINT_STALLEDI | USBHS_DEVEPTINT_NAKINI | - USBHS_DEVEPTINT_NAKOUTI; - sam_putreg(regval, SAM_USBHS_DEVEPTICR(i)); - - /* Reset endpoint configuration */ - - sam_putreg(USBHS_DEVEPT_ALLEPEN, SAM_USBHS_DEVEPTIDR(i)); - } + sam_putreg(USBHS_DEVEPTICR_ALLINTS, SAM_USBHS_DEVEPTICR(i)); + } /* Disable all interrupts */ -- cgit v1.2.3