summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-31 17:37:51 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-31 17:37:51 -0600
commit3282abcdf16d7de9d0b755ad8021a6236ad71a38 (patch)
tree1c534cfb9b82b6e29d00a74f6c626fccc053fa88
parenta1497ec8f26a898ee5472a0f760de2a3ad8075eb (diff)
downloadpx4-nuttx-3282abcdf16d7de9d0b755ad8021a6236ad71a38.tar.gz
px4-nuttx-3282abcdf16d7de9d0b755ad8021a6236ad71a38.tar.bz2
px4-nuttx-3282abcdf16d7de9d0b755ad8021a6236ad71a38.zip
SAMA UDPHS: Add pull-up and stall logic. Added to build system but does not yet build
-rw-r--r--nuttx/arch/arm/src/sama5/Kconfig40
-rw-r--r--nuttx/arch/arm/src/sama5/Make.defs4
-rw-r--r--nuttx/arch/arm/src/sama5/chip/sam_udphs.h4
-rw-r--r--nuttx/arch/arm/src/sama5/sam_periphclks.h52
-rw-r--r--nuttx/arch/arm/src/sama5/sam_udphs.c662
-rw-r--r--nuttx/arch/arm/src/sama5/sam_udphs.h84
-rw-r--r--nuttx/configs/sama5d3x-ek/README.txt25
7 files changed, 591 insertions, 280 deletions
diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig
index 8de20d733..52630d7f4 100644
--- a/nuttx/arch/arm/src/sama5/Kconfig
+++ b/nuttx/arch/arm/src/sama5/Kconfig
@@ -335,8 +335,44 @@ config SAMA5_HSMCI_REGDEBUG
endmenu # HSMCI device driver options
endif # SAMA5_HSMCI0 || SAMA5_HSMCI1 || SAMA5_HSMCI2
+if SAMA5_UDPHS
+menu "USB High Speed Device Controller driver (DCD) options"
+
+config UDPHS_SCATTERGATHER
+ bool
+ default n
+ ---help---
+ Scatter gather DMA is not yet supported
+
+config SAMA5_UDPHS_NDTDS
+ int "Number of UDPHS DMA transfer descriptors"
+ default 9
+ depends on UDPHS_SCATTERGATHER
+ ---help---
+ DMA tranfer descriptors are allocated in a pool at boot time. This
+ setting provides the number of DMA transfer descriptors to be
+ allocated.
+
+config SAMA5_UDPHS_PREALLOCATE
+ bool "Pre-allocate DMA transfer descriptors"
+ default y
+ depends on UDPHS_SCATTERGATHER
+ ---help---
+ If this option is selected then DMA tranfer descriptors will be
+ pre-allocated in .bss. Otherwise, the descriptors will be allocated
+ at start-up time with kmalloc(). This might be important if a larger
+ memory pool is available after startup.
+
+config SAMA5_UDPHS_REGDEBUG
+ bool "Enable low-level UPPHS register debug"
+ default n
+ depends on DEBUG
+
+endmenu # USB High Speed Host Device driver (DCD) options
+endif # SAMA5_UDPHS
+
if SAMA5_UHPHS
-menu "USB High Speed Host device driver options"
+menu "USB High Speed Host Controller driver (HCD) options"
config SAMA5_OHCI
bool "Full/low speed OHCI support"
@@ -436,7 +472,7 @@ config SAMA5_UHPHS_RHPORT3
endif # SAMA5_OHCI || SAMA5_EHCI
-endmenu # USB High Speed Host driver option
+endmenu # USB High Speed Host Controller driver (HCD) options
endif # SAMA5_UHPHS
menu "External Memory Configuration"
diff --git a/nuttx/arch/arm/src/sama5/Make.defs b/nuttx/arch/arm/src/sama5/Make.defs
index 13649932a..1d77ebf55 100644
--- a/nuttx/arch/arm/src/sama5/Make.defs
+++ b/nuttx/arch/arm/src/sama5/Make.defs
@@ -124,6 +124,10 @@ CHIP_CSRCS += sam_ehci.c
endif
endif
+ifeq ($(CONFIG_SAMA5_UDPHS),y)
+CHIP_CSRCS += sam_udphs.c
+endif
+
ifeq ($(CONFIG_SAMA5_HSMCI0),y)
CHIP_CSRCS += sam_hsmci.c
else
diff --git a/nuttx/arch/arm/src/sama5/chip/sam_udphs.h b/nuttx/arch/arm/src/sama5/chip/sam_udphs.h
index 91627f50a..a05720f27 100644
--- a/nuttx/arch/arm/src/sama5/chip/sam_udphs.h
+++ b/nuttx/arch/arm/src/sama5/chip/sam_udphs.h
@@ -82,7 +82,7 @@
/* 0x00e4-0x00e8 Reserved */
/* Endpoint Offsets */
-#define SAM_UPPHS_EP_OFFSET(ep) (0x0100+((unsigned int)(ep)<<5)
+#define SAM_UPPHS_EP_OFFSET(ep) (0x0100+((unsigned int)(ep)<<5))
#define SAM_UPPHS_EP0_OFFSET 0x0100
#define SAM_UPPHS_EP1_OFFSET 0x0120
#define SAM_UPPHS_EP2_OFFSET 0x0140
@@ -252,7 +252,7 @@
# define UDPHS_INT_EPT15 (1 << 23) /* Bit 23: Endpoint 15 Interrupt */
#define UDPHS_INT_DMA_SHIFT (25) /* Bits 25-31: Endpoint interrupts */
#define UDPHS_INT_DMA_MASK (0x7f << UDPHS_INT_DMA_SHIFT)
-#define UDPHS_INT_DMA(ch) (1 << ((ch)+24) /* DMA Channel ch Interrupt */
+#define UDPHS_INT_DMA(ch) (1 << ((ch)+24)) /* DMA Channel ch Interrupt */
# define UDPHS_INT_DMA1 (1 << 25) /* Bit 25: DMA Channel 1 Interrupt */
# define UDPHS_INT_DMA2 (1 << 26) /* Bit 26: DMA Channel 2 Interrupt */
# define UDPHS_INT_DMA3 (1 << 27) /* Bit 27: DMA Channel 3 Interrupt */
diff --git a/nuttx/arch/arm/src/sama5/sam_periphclks.h b/nuttx/arch/arm/src/sama5/sam_periphclks.h
index 92d403b55..a89d0f95f 100644
--- a/nuttx/arch/arm/src/sama5/sam_periphclks.h
+++ b/nuttx/arch/arm/src/sama5/sam_periphclks.h
@@ -54,6 +54,8 @@
#define sam_enableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PCER1)
#define sam_disableperiph0(s) putreg32((1 << (s)), SAM_PMC_PDER0)
#define sam_disableperiph1(s) putreg32((1 << ((s) - 32)), SAM_PMC_PDER1)
+#define sam_isenabled0(s) (getreg32(SAM_PMC_PCER0) & (1 << (s)) != 0)
+#define sam_isenabled1(s) (getreg32(SAM_PMC_PCER1) & (1 << ((s) - 32)) != 0)
#define sam_dbgu_enableclk() sam_enableperiph0(SAM_PID_DBGU)
#define sam_pit_enableclk() sam_enableperiph0(SAM_PID_PIT)
@@ -155,6 +157,56 @@
#define sam_fuse_disableclk() sam_disableperiph1(SAM_PID_FUSE)
#define sam_mpddrc_disableclk() sam_disableperiph1(SAM_PID_MPDDRC)
+#define sam_dbgu_isenabled() sam_isenabled0(SAM_PID_DBGU)
+#define sam_pit_isenabled() sam_isenabled0(SAM_PID_PIT)
+#define sam_wdt_isenabled() sam_isenabled0(SAM_PID_WDT)
+#define sam_hsmc_isenabled() sam_isenabled0(SAM_PID_HSMC)
+#define sam_pioa_isenabled() sam_isenabled0(SAM_PID_PIOA)
+#define sam_piob_isenabled() sam_isenabled0(SAM_PID_PIOB)
+#define sam_pioc_isenabled() sam_isenabled0(SAM_PID_PIOC)
+#define sam_piod_isenabled() sam_isenabled0(SAM_PID_PIOD)
+#define sam_pioe_isenabled() sam_isenabled0(SAM_PID_PIOE)
+#define sam_smd_isenabled() sam_isenabled0(SAM_PID_SMD)
+#define sam_usart0_isenabled() sam_isenabled0(SAM_PID_USART0)
+#define sam_usart1_isenabled() sam_isenabled0(SAM_PID_USART1)
+#define sam_usart2_isenabled() sam_isenabled0(SAM_PID_USART2)
+#define sam_usart3_isenabled() sam_isenabled0(SAM_PID_USART3)
+#define sam_uart0_isenabled() sam_isenabled0(SAM_PID_UART0)
+#define sam_uart1_isenabled() sam_isenabled0(SAM_PID_UART1)
+#define sam_twi0_isenabled() sam_isenabled0(SAM_PID_TWI0)
+#define sam_twi1_isenabled() sam_isenabled0(SAM_PID_TWI1)
+#define sam_twi2_isenabled() sam_isenabled0(SAM_PID_TWI2)
+#define sam_hsmci0_isenabled() sam_isenabled0(SAM_PID_HSMCI0)
+#define sam_hsmci1_isenabled() sam_isenabled0(SAM_PID_HSMCI1)
+#define sam_hsmci2_isenabled() sam_isenabled0(SAM_PID_HSMCI2)
+#define sam_spi0_isenabled() sam_isenabled0(SAM_PID_SPI0)
+#define sam_spi1_isenabled() sam_isenabled0(SAM_PID_SPI1)
+#define sam_tc0_isenabled() sam_isenabled0(SAM_PID_TC0)
+#define sam_tc1_isenabled() sam_isenabled0(SAM_PID_TC1)
+#define sam_pwm_isenabled() sam_isenabled0(SAM_PID_PWM)
+#define sam_adc_isenabled() sam_isenabled0(SAM_PID_ADC)
+#define sam_dmac0_isenabled() sam_isenabled0(SAM_PID_DMAC0)
+#define sam_dmac1_isenabled() sam_isenabled0(SAM_PID_DMAC1)
+
+#define sam_uhphs_isenabled() sam_isenabled1(SAM_PID_UHPHS)
+#define sam_udphs_isenabled() sam_isenabled1(SAM_PID_UDPHS)
+#define sam_gmac_isenabled() sam_isenabled1(SAM_PID_GMAC)
+#define sam_emac_isenabled() sam_isenabled1(SAM_PID_EMAC)
+#define sam_lcdc_isenabled() sam_isenabled1(SAM_PID_LCDC)
+#define sam_isi_isenabled() sam_isenabled1(SAM_PID_ISI)
+#define sam_ssc0_isenabled() sam_isenabled1(SAM_PID_SSC0)
+#define sam_ssc1_isenabled() sam_isenabled1(SAM_PID_SSC1)
+#define sam_can0_isenabled() sam_isenabled1(SAM_PID_CAN0)
+#define sam_can1_isenabled() sam_isenabled1(SAM_PID_CAN1)
+#define sam_sha_isenabled() sam_isenabled1(SAM_PID_SHA)
+#define sam_aes_isenabled() sam_isenabled1(SAM_PID_AES)
+#define sam_tdes_isenabled() sam_isenabled1(SAM_PID_TDES)
+#define sam_trng_isenabled() sam_isenabled1(SAM_PID_TRNG)
+#define sam_arm_isenabled() sam_isenabled1(SAM_PID_ARM)
+#define sam_aic_isenabled() sam_isenabled1(SAM_PID_AIC)
+#define sam_fuse_isenabled() sam_isenabled1(SAM_PID_FUSE)
+#define sam_mpddrc_isenabled() sam_isenabled1(SAM_PID_MPDDRC)
+
/************************************************************************************
* Public Types
************************************************************************************/
diff --git a/nuttx/arch/arm/src/sama5/sam_udphs.c b/nuttx/arch/arm/src/sama5/sam_udphs.c
index 9773bb7a5..b1fe761f0 100644
--- a/nuttx/arch/arm/src/sama5/sam_udphs.c
+++ b/nuttx/arch/arm/src/sama5/sam_udphs.c
@@ -65,12 +65,14 @@
#include <arch/irq.h>
#include "up_arch.h"
+#include "cache.h"
+
#include "sam_periphclks.h"
-#include "sam_syscfg.h"
-#include "sam_gpio.h"
-#include "sam_usbdev.h"
+#include "sam_memories.h"
+#include "chip/sam_udphs.h"
+#include "sam_udphs.h"
-#if defined(CONFIG_USBDEV) && defined(CONFIG_SAM_USB)
+#if defined(CONFIG_USBDEV) && defined(CONFIG_SAMA5_UDPHS)
/****************************************************************************
* Pre-processor Definitions
@@ -82,14 +84,10 @@
# define CONFIG_USBDEV_EP0_MAXSIZE 64
#endif
-#ifndef CONFIG_USB_PRI
-# define CONFIG_USB_PRI NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-
/* Number of DMA transfer descriptors. Default: 8 */
-#ifndef CONFIG_SAMA5_UDPHS_NTDS
-# define CONFIG_SAMA5_UDPHS_NTDS 8
+#ifndef CONFIG_SAMA5_UDPHS_NDTDS
+# define CONFIG_SAMA5_UDPHS_NDTDS 8
#endif
/* Extremely detailed register debug that you would normally never want
@@ -159,47 +157,56 @@
#define SAM_TRACEERR_DRIVERREGISTERED 0x0010
#define SAM_TRACEERR_EP0BADCTR 0x0011
#define SAM_TRACEERR_EP0SETUPSTALLED 0x0012
-#define SAM_TRACEERR_EPBUFFER 0x0013
-#define SAM_TRACEERR_EPDISABLED 0x0014
-#define SAM_TRACEERR_EPOUTNULLPACKET 0x0015
-#define SAM_TRACEERR_EPRESERVE 0x0016
-#define SAM_TRACEERR_INVALIDCTRLREQ 0x0017
-#define SAM_TRACEERR_INVALIDPARMS 0x0018
-#define SAM_TRACEERR_IRQREGISTRATION 0x0019
-#define SAM_TRACEERR_NOTCONFIGURED 0x001a
-#define SAM_TRACEERR_REQABORTED 0x001b
+#define SAM_TRACEERR_EPINBUSY 0x0013
+#define SAM_TRACEERR_EPOUTNULLPACKET 0x0014
+#define SAM_TRACEERR_EPRESERVE 0x0015
+#define SAM_TRACEERR_INVALIDCTRLREQ 0x0016
+#define SAM_TRACEERR_INVALIDPARMS 0x0017
+#define SAM_TRACEERR_IRQREGISTRATION 0x0018
+#define SAM_TRACEERR_NOTCONFIGURED 0x0019
+#define SAM_TRACEERR_REQABORTED 0x001a
+#define SAM_TRACEERR_TXRDYERR 0x001b
/* Trace interrupt codes */
#define SAM_TRACEINTID_CLEARFEATURE 0x0001
-#define SAM_TRACEINTID_DEVGETSTATUS 0x0002
-#define SAM_TRACEINTID_DISPATCH 0x0003
-#define SAM_TRACEINTID_EP0IN 0x0004
-#define SAM_TRACEINTID_EP0INDONE 0x0005
-#define SAM_TRACEINTID_EP0OUTDONE 0x0006
-#define SAM_TRACEINTID_EP0SETUPDONE 0x0007
-#define SAM_TRACEINTID_EP0SETUPSETADDRESS 0x0008
-#define SAM_TRACEINTID_EPGETSTATUS 0x0009
-#define SAM_TRACEINTID_EPINDONE 0x000a
-#define SAM_TRACEINTID_EPINQEMPTY 0x000b
-#define SAM_TRACEINTID_EPOUTDONE 0x000c
-#define SAM_TRACEINTID_EPOUTPENDING 0x000d
-#define SAM_TRACEINTID_EPOUTQEMPTY 0x000e
-#define SAM_TRACEINTID_ESOF 0x000f
-#define SAM_TRACEINTID_GETCONFIG 0x0010
-#define SAM_TRACEINTID_GETSETDESC 0x0011
-#define SAM_TRACEINTID_GETSETIF 0x0012
-#define SAM_TRACEINTID_GETSTATUS 0x0013
-#define SAM_TRACEINTID_INTERRUPT 0x0014
-#define SAM_TRACEINTID_IFGETSTATUS 0x0015
-#define SAM_TRACEINTID_LPCTR 0x0016
-#define SAM_TRACEINTID_NOSTDREQ 0x0017
-#define SAM_TRACEINTID_RESET 0x0018
-#define SAM_TRACEINTID_SETCONFIG 0x0019
-#define SAM_TRACEINTID_SETFEATURE 0x001a
-#define SAM_TRACEINTID_SUSP 0x001b
-#define SAM_TRACEINTID_SYNCHFRAME 0x001c
-#define SAM_TRACEINTID_WKUP 0x001d
+#define SAM_TRACEINTID_DETSUSPD 0x0002
+#define SAM_TRACEINTID_DEVGETSTATUS 0x0003
+#define SAM_TRACEINTID_DISPATCH 0x0004
+#define SAM_TRACEINTID_DMA 0x0005
+#define SAM_TRACEINTID_DMAEOB 0x0006
+#define SAM_TRACEINTID_DMAEOC 0x0007
+#define SAM_TRACEINTID_DMAERR 0x0008
+#define SAM_TRACEINTID_ENDRESET 0x0009
+#define SAM_TRACEINTID_EP 0x000a
+#define SAM_TRACEINTID_EP0IN 0x000b
+#define SAM_TRACEINTID_EP0INDONE 0x000c
+#define SAM_TRACEINTID_EP0OUTDONE 0x000d
+#define SAM_TRACEINTID_EP0SETUPDONE 0x000e
+#define SAM_TRACEINTID_EP0SETUPSETADDRESS 0x000f
+#define SAM_TRACEINTID_EPGETSTATUS 0x0010
+#define SAM_TRACEINTID_EPINDONE 0x0011
+#define SAM_TRACEINTID_EPINQEMPTY 0x0012
+#define SAM_TRACEINTID_EPOUTDONE 0x0013
+#define SAM_TRACEINTID_EPOUTPENDING 0x0014
+#define SAM_TRACEINTID_EPOUTQEMPTY 0x0015
+#define SAM_TRACEINTID_GETCONFIG 0x0016
+#define SAM_TRACEINTID_GETSETDESC 0x0017
+#define SAM_TRACEINTID_GETSETIF 0x0018
+#define SAM_TRACEINTID_GETSTATUS 0x0019
+#define SAM_TRACEINTID_IFGETSTATUS 0x001a
+#define SAM_TRACEINTID_INTERRUPT 0x001b
+#define SAM_TRACEINTID_INTSOF 0x001c
+#define SAM_TRACEINTID_NOSTDREQ 0x001d
+#define SAM_TRACEINTID_RXRDY 0x001e
+#define SAM_TRACEINTID_RXSETUP 0x001f
+#define SAM_TRACEINTID_SETCONFIG 0x0020
+#define SAM_TRACEINTID_SETFEATURE 0x0021
+#define SAM_TRACEINTID_STALLSNT 0x0022
+#define SAM_TRACEINTID_SYNCHFRAME 0x0023
+#define SAM_TRACEINTID_TXRDY 0x0024
+#define SAM_TRACEINTID_UPSTRRES 0x0025
+#define SAM_TRACEINTID_WAKEUP 0x0026
/* Ever-present MIN and MAX macros */
@@ -229,7 +236,7 @@
enum sam_epstate_e
{
UDPHS_EPSTATE_DISABLED = 0, /* Endpoint is disabled */
- UDPHS_EPSTATE_HALTED, /* Endpoint is halted (i.e. STALLs every request) */
+ UDPHS_EPSTATE_STALLED, /* Endpoint is stalled */
UDPHS_EPSTATE_IDLE, /* Endpoint is idle (i.e. ready for transmission) */
UDPHS_EPSTATE_SENDING, /* Endpoint is sending data */
UDPHS_EPSTATE_RECEIVING /* Endpoint is receiving data */
@@ -374,8 +381,6 @@ static inline void sam_putreg(uint32_t regval, uintptr_t regaddr);
# define sam_dumpep(priv,epno)
#endif
-/* Low-Level Helpers ********************************************************/
-
/* Suspend/Resume Helpers ***************************************************/
static void sam_suspend(struct sam_usbdev_s *priv);
@@ -407,7 +412,7 @@ static void sam_req_complete(struct sam_ep_s *privep, int16_t result);
static void sam_fifo_write(struct sam_usbdev_s *priv,
struct sam_ep_s *privep, const uint8_t *data, size_t nbytes);
static int sam_req_wrnodma(struct sam_usbdev_s *priv,
- struct sam_ep_s *privep, struct sam_req_s *privreq)
+ struct sam_ep_s *privep, struct sam_req_s *privreq);
static int sam_req_write(struct sam_usbdev_s *priv,
struct sam_ep_s *privep);
static int sam_req_rddnoma(struct sam_usbdev_s *priv,
@@ -418,7 +423,7 @@ static void sam_req_cancel(struct sam_ep_s *privep);
/* Interrupt level processing ***********************************************/
-static void sam_ep0_read(struct usb_ctrlreq_s *req);
+static void sam_ep0_readsetup(struct usb_ctrlreq_s *req);
static void sam_ep0_dispatch(struct sam_usbdev_s *priv);
static void sam_ep_done(struct sam_usbdev_s *priv, uint8_t epno);
static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t value);
@@ -434,6 +439,7 @@ static int sam_udphs_interrupt(int irq, void *context);
/* Endpoint helpers *********************************************************/
+static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno);
static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset);
static inline struct sam_ep_s *
sam_ep_reserve(struct sam_usbdev_s *priv, uint8_t epset);
@@ -469,6 +475,7 @@ static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep);
static int sam_getframe(struct usbdev_s *dev);
static int sam_wakeup(struct usbdev_s *dev);
static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered);
+static int sam_pullup(FAR struct usbdev_s *dev, bool enable);
/* Initialization/Reset *****************************************************/
@@ -487,7 +494,7 @@ static void sam_sw_shutdown(struct sam_usbdev_s *priv);
* be simply retained in a single global instance.
*/
-static struct sam_usbdev_s g_usbdev;
+static struct sam_usbdev_s g_udphs;
static const struct usbdev_epops_s g_epops =
{
@@ -507,7 +514,7 @@ static const struct usbdev_ops_s g_devops =
.getframe = sam_getframe,
.wakeup = sam_wakeup,
.selfpowered = sam_selfpowered,
- .pullup = sam_usbpullup,
+ .pullup = sam_pullup,
};
/* This describes endpoint 0 */
@@ -518,7 +525,7 @@ static const struct usb_epdesc_s g_ep0desc =
.type = USB_DESC_TYPE_ENDPOINT,
.addr = EP0,
.attr = USB_EP_ATTR_XFER_CONTROL,
- .maxpacketsize = {64, 0},
+ .mxpacketsize = {64, 0},
.interval = 0
};
@@ -526,7 +533,7 @@ static const struct usb_epdesc_s g_ep0desc =
#ifdef CONFIG_SAMA5_UDPHS_PREALLOCATE
/* This is a properly aligned pool of preallocated DMA transfer desciptors */
-static struct sam_dtd_s g_dtdpool[CONFIG_SAMA5_UDPHS_NTDS]
+static struct sam_dtd_s g_dtdpool[CONFIG_SAMA5_UDPHS_NDTDS]
__attribute__ ((aligned(16)));
#endif
#endif
@@ -551,8 +558,7 @@ static struct sam_dtd_s g_dtdpool[CONFIG_SAMA5_UDPHS_NTDS]
*******************************************************************************/
#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG
-static void sam_printreg(uint32_t regaddr, uint32_t regval,
- bool iswrite)
+static void sam_printreg(uintptr_t regaddr, uint32_t regval, bool iswrite)
{
lldbg("%p%s%08x\n", regaddr, iswrite ? "<-" : "->", regval);
}
@@ -568,12 +574,12 @@ static void sam_printreg(uint32_t regaddr, uint32_t regval,
*******************************************************************************/
#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG
-static void sam_checkreg(uint32_t regaddr, uint32_t regval, bool iswrite)
+static void sam_checkreg(uintptr_t regaddr, uint32_t regval, bool iswrite)
{
- static uint32_t *prevaddr = NULL;
- static uint32_t preval = 0;
- static uint32_t count = 0;
- static bool prevwrite = false;
+ static uintptr_t prevaddr = 0;
+ static uint32_t preval = 0;
+ static uint32_t count = 0;
+ static bool prevwrite = false;
/* Is this the same value that we read from/wrote to the same register last time?
* Are we polling the register? If so, suppress the output.
@@ -611,7 +617,7 @@ static void sam_checkreg(uint32_t regaddr, uint32_t regval, bool iswrite)
/* Save the new address, value, count, and operation for next time */
- prevaddr = (uint32_t *)regaddr;
+ prevaddr = regaddr;
preval = regval;
count = 0;
prevwrite = iswrite;
@@ -632,11 +638,11 @@ static void sam_checkreg(uint32_t regaddr, uint32_t regval, bool iswrite)
*******************************************************************************/
#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG
-static uint32_t sam_getreg(uint32_t regaddr)
+static uint32_t sam_getreg(uintptr_t regaddr)
{
/* Read the value from the register */
- uint32_t regval = *regaddr;
+ uint32_t regval = getreg32(regaddr);
/* Check if we need to print this value */
@@ -644,9 +650,9 @@ static uint32_t sam_getreg(uint32_t regaddr)
return regval;
}
#else
-static inline uint32_t sam_getreg(uint32_t regaddr)
+static inline uint32_t sam_getreg(uintptr_t regaddr)
{
- return *regaddr;
+ return getreg32(regaddr;
}
#endif
@@ -659,7 +665,7 @@ static inline uint32_t sam_getreg(uint32_t regaddr)
*******************************************************************************/
#ifdef CONFIG_SAMA5_UDPHS_REGDEBUG
-static void sam_putreg(uint32_t regval, uint32_t regaddr)
+static void sam_putreg(uint32_t regval, uintptr_t regaddr)
{
/* Check if we need to print this value */
@@ -667,12 +673,12 @@ static void sam_putreg(uint32_t regval, uint32_t regaddr)
/* Write the value */
- *regaddr = regval;
+ putreg32(regval, regaddr);
}
#else
static inline void sam_putreg(uint32_t regval, uint32_t regaddr)
{
- *regaval = regval;
+ putreg32(regval, regaddr);
}
#endif
@@ -683,8 +689,6 @@ static inline void sam_putreg(uint32_t regval, uint32_t regaddr)
#if defined(CONFIG_SAMA5_UDPHS_REGDEBUG) && defined(CONFIG_DEBUG)
static void sam_dumpep(struct sam_usbdev_s *priv, int epno)
{
- uintptr_t addr;
-
/* Global Registers */
lldbg("Global Register:\n");
@@ -717,10 +721,6 @@ static void sam_dumpep(struct sam_usbdev_s *priv, int epno)
#endif
/****************************************************************************
- * Low-Level Helpers
- ****************************************************************************/
-
-/****************************************************************************
* DMA
****************************************************************************/
/****************************************************************************
@@ -788,6 +788,7 @@ static void sam_dma_single(uint8_t epno, struct sam_req_s *privreq,
{
uintptr_t buffer;
uintptr_t physaddr;
+ uint32_t regval;
/* Not all endpoints support DMA */
@@ -795,19 +796,19 @@ static void sam_dma_single(uint8_t epno, struct sam_req_s *privreq,
/* Flush the contents of the DMA buffer to RAM */
- buffer = (uintptr_t)&privreq->req.buf[privreg->req.xfrd];
+ buffer = (uintptr_t)&privreq->req.buf[privreq->req.xfrd];
cp15_clean_dcache(buffer, buffer + privreq->inflight);
/* Set up the DMA */
- physaddr = sam_phyramaddr(buffer);
+ physaddr = sam_physramaddr(buffer);
sam_putreg(physaddr, SAM_UDPHS_DMAADDRESS(epno));
/* Clear any pending interrupts then enable the DMA interrupt */
(void)sam_getreg(SAM_UDPHS_DMASTATUS(epno));
regval = sam_getreg(SAM_UDPHS_IEN);
- regval |= UDPHS_INT_DMA(epno)
+ regval |= UDPHS_INT_DMA(epno);
sam_putreg(regval, SAM_UDPHS_IEN);
/* Setup and enable the DMA */
@@ -830,6 +831,7 @@ static int sam_req_wrdma(struct sam_usbdev_s *priv, struct sam_ep_s *privep,
struct sam_req_s *privreq)
{
uint32_t regval;
+ int remaining;
int epno;
/* The endpoint must be IDLE and ready to begin the next transfer */
@@ -892,7 +894,7 @@ static int sam_req_wrdma(struct sam_usbdev_s *priv, struct sam_ep_s *privep,
regval |= UDPHS_INT_EPT(epno);
sam_putreg(regval, SAM_UDPHS_IEN);
- sam_putreg(UDPHS_EPTCTL_TXRDY, SAM_UDPHS_EPTCTLENB);
+ sam_putreg(UDPHS_EPTCTL_TXRDY, SAM_UDPHS_EPTCTLENB(epno));
return OK;
}
@@ -908,6 +910,7 @@ static int sam_req_rddma(struct sam_usbdev_s *priv, struct sam_ep_s *privep,
struct sam_req_s *privreq)
{
uint32_t regval;
+ int remaining;
int epno;
/* The endpoint must be IDLE and ready to begin the next transfer */
@@ -948,7 +951,7 @@ static int sam_req_rddma(struct sam_usbdev_s *priv, struct sam_ep_s *privep,
/* And perform the single DMA transfer */
regval = UDPHS_DMACONTROL_ENDBEN | UDPHS_DMACONTROL_ENDBUFFIT |
- UDPHS_DMACONTROL_CHANNENB
+ UDPHS_DMACONTROL_CHANNENB;
sam_dma_single(epno, privreq, regval);
return OK;
}
@@ -1069,7 +1072,6 @@ static void sam_req_complete(struct sam_ep_s *privep, int16_t result)
privep->epstate = UDPHS_EPSTATE_IDLE;
privep->stalled = stalled;
privep->txnullpkt = 0;
- privep->inflight = 0;
}
}
@@ -1099,7 +1101,7 @@ static int sam_req_wrnodma(struct sam_usbdev_s *priv, struct sam_ep_s *privep,
* successfully transferred, minus the number of bytes in-flight.
*/
- committed = privreg.req.xfrd + privreq.inflight
+ committed = privreq->req.xfrd + privreq->inflight;
bytesleft = privreq->req.len - committed;
/* Clip the requested transfer size to the number of bytes actually
@@ -1190,6 +1192,7 @@ static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep)
{
struct sam_req_s *privreq;
uint8_t epno;
+ int ret;
/* We get here when an IN endpoint interrupt occurs. So now we know that
* there is no TX transfer in progress.
@@ -1227,25 +1230,23 @@ static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep)
ret = sam_req_wrnodma(priv, privep, privreq);
}
- if (ret < 0)
+ if (ret == OK)
{
- return ret;
- }
-
- /* If all of the bytes were sent (including any final null packet)
- * then we are finished with the request buffer).
- */
+ /* If all of the bytes were sent (including any final null packet)
+ * then we are finished with the request buffer).
+ */
- if (privreq->req.len == privreq->req.xfrd && !privep->txnullpkt)
- {
- /* Return the write request to the class driver */
+ if (privreq->req.len == privreq->req.xfrd && !privep->txnullpkt)
+ {
+ /* Return the write request to the class driver */
- usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
- privep->txnullpkt = 0;
- sam_req_complete(privep, OK);
+ usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
+ privep->txnullpkt = 0;
+ sam_req_complete(privep, OK);
+ }
}
- return OK;
+ return ret;
}
/****************************************************************************
@@ -1299,10 +1300,10 @@ static int sam_req_read(struct sam_usbdev_s *priv, struct sam_ep_s *privep)
* transferred to the user-buffer.
*/
- remaining = privreq->req.len - privreg.req.xfrd;
+ remaining = privreq->req.len - privreq->req.xfrd;
/* Get the number of bytes to read from FIFO memory */
-#missing logic
+#warning missing logic
/* Read the smaller of the number of bytes available in FIFO and the
* size remaining in the request buffer provided by the caller.
@@ -1346,6 +1347,18 @@ static int sam_req_read(struct sam_usbdev_s *priv, struct sam_ep_s *privep)
static void sam_req_cancel(struct sam_ep_s *privep)
{
+ uint32_t regval;
+ uint8_t epno;
+
+ /* Disable endpoint interrupts */
+
+ epno = USB_EPNO(privep->ep.eplog);
+ regval = sam_getreg(SAM_UDPHS_IEN);
+ regval &= ~UDPHS_INT_DMA(epno);
+ sam_putreg(regval, SAM_UDPHS_IEN);
+
+ /* Then complete every queued request with -ESHUTDOWN status */
+
while (!sam_rqempty(privep))
{
usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)),
@@ -1358,14 +1371,14 @@ static void sam_req_cancel(struct sam_ep_s *privep)
* Interrupt Level Processing
****************************************************************************/
/****************************************************************************
- * Name: sam_ep0_read
+ * Name: sam_ep0_readsetup
*
* Description:
* Read a general USB request from the UDPHS FIFO
*
****************************************************************************/
-static void sam_ep0_read(struct usb_ctrlreq_s *req)
+static void sam_ep0_readsetup(struct usb_ctrlreq_s *req)
{
uint32_t *buffer = (uint32_t *)req;
volatile uint32_t *fifo;
@@ -1430,7 +1443,7 @@ static void sam_ep_done(struct sam_usbdev_s *priv, uint8_t epno)
{
/* Read host data into the current read request */
- (void)sam_ep0_read(priv, privep);
+ (void)sam_req_read(priv, privep);
/* Enable further transactions on the endpoint */
#warning Missing logic
@@ -1478,6 +1491,8 @@ static void sam_ep_done(struct sam_usbdev_s *priv, uint8_t epno)
static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t address)
{
+ uint32_t regval;
+
if (address)
{
/* Enable the address */
@@ -1496,7 +1511,7 @@ static void sam_setdevaddr(struct sam_usbdev_s *priv, uint8_t address)
/* Disable address */
regval = sam_getreg(SAM_UDPHS_CTRL);
- regval &= ~SAM_UDPHS_CTRL_FADDR_EN;
+ regval &= ~UDPHS_CTRL_FADDREN;
sam_putreg(regval, SAM_UDPHS_CTRL);
/* Revert to the un-addressed, default state */
@@ -1607,27 +1622,11 @@ static void sam_ep0_setup(struct sam_usbdev_s *priv)
response.w = 0; /* Not stalled */
nbytes = 2; /* Response size: 2 bytes */
- if (USB_ISEPIN(index.b[LSB]))
+ if (sam_epstalled(epno))
{
- /* IN endpoint */
-
- if (sam_eptxstalled(epno))
- {
- /* IN Endpoint stalled */
-
- response.b[LSB] = 1; /* Stalled */
- }
- }
- else
- {
- /* OUT endpoint */
-
- if (sam_eprxstalled(epno))
- {
- /* OUT Endpoint stalled */
+ /* Endpoint stalled */
- response.b[LSB] = 1; /* Stalled */
- }
+ response.b[LSB] = 1; /* Stalled */
}
}
}
@@ -1846,7 +1845,10 @@ static void sam_ep0_setup(struct sam_usbdev_s *priv)
if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE &&
index.w == 0 && len.w == 0)
{
- /* The request seems valid... let the class implementation handle it */
+ /* The request seems valid... let the class implementation handle it.
+ * If the class implementation accespts it new configuration, it will
+ * call sam_ep_configure() to configure the endpoints.
+ */
sam_ep0_dispatch(priv);
handled = true;
@@ -2054,7 +2056,6 @@ static inline void sam_ep0_done(struct sam_usbdev_s *priv, uint32_t intsta)
else if ((epr & USB_EPR_SETUP) != 0)
{
usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0SETUPDONE), epr);
- sam_clrepctrrx(EP0);
sam_ep0_setup(priv);
}
@@ -2065,7 +2066,6 @@ static inline void sam_ep0_done(struct sam_usbdev_s *priv, uint32_t intsta)
else if ((epr & USB_EPR_CTR_RX) != 0)
{
usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_EP0OUTDONE), epr);
- sam_clrepctrrx(EP0);
sam_ep0_out(priv);
}
@@ -2078,10 +2078,6 @@ static inline void sam_ep0_done(struct sam_usbdev_s *priv, uint32_t intsta)
}
}
- /* Make sure that the EP0 packet size is still OK (superstitious?) */
-
- sam_seteprxcount(EP0, SAM_EP0MAXPACKET);
-
/* Handle the STALL condition: */
if (priv->ep0state == EP0STATE_STALLED)
@@ -2157,23 +2153,23 @@ static void sam_dma_interrupt(struct sam_usbdev_s *priv, int epno)
/* Get the request from the head of the endpoint request queue */
privreq = sam_rqpeek(privep);
- DEBUGASSERT(privreg);
+ DEBUGASSERT(privreq);
/* Invalidate the data cache for region that just completed DMA.
* This will force the buffer data to be reloaded from RAM.
*/
buf = &privreq->req.buf[privreq->req.xfrd];
- cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + privreg->inflight);
+ cp15_invalidate_dcache((uintptr_t)buf, (uintptr_t)buf + privreq->inflight);
/* Get the result of the DMA operation */
- dmastatus = pUdp->UDPHS_DMA[epno].UDPHS_DMASTATUS;
+ dmastatus = sam_getreg(SAM_UDPHS_DMASTATUS(epno));
uvdbg("DMA%d DMASTATUS: %08x\n", epno, dmastatus);
/* Disable DMA interrupt to avoid receiving 2 (B_EN and TR_EN) */
- regaddr = SAM_UDPHS_DMACONTROL(epno)
+ regaddr = SAM_UDPHS_DMACONTROL(epno);
regval = sam_getreg(regaddr);
regval &= ~(UDPHS_DMACONTROL_ENDTREN | UDPHS_DMACONTROL_ENDBEN);
sam_putreg(regval, regaddr);
@@ -2270,8 +2266,6 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
{
struct sam_ep_s *privep;
struct sam_req_s *privreq;
- struct usb_ctrlreq_s *req;
- uint32_t reqbuf[2];
uint32_t eptsta;
uint32_t eptype;
uint32_t regval;
@@ -2286,7 +2280,7 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
/* Get the request from the head of the endpoint request queue */
privreq = sam_rqpeek(privep);
- DEBUGASSERT(privreg);
+ DEBUGASSERT(privreq);
/* Get the endpoint status */
@@ -2294,11 +2288,9 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
/* Get the endpoint type */
- regval = sam_getreg(SAM_UDPHS_EPTCFG(epno))
+ regval = sam_getreg(SAM_UDPHS_EPTCFG(epno));
eptype = regval & UDPHS_EPTCFG_TYPE_MASK;
- req = (struct usb_ctrlreq_s *)reqbuf;
-
/* IN packet sent */
if ((sam_getreg(SAM_UDPHS_EPTCTL(epno)) & UDPHS_EPTCTL_TXRDY) != 0 &&
@@ -2310,8 +2302,6 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
if (privep->epstate == UDPHS_EPSTATE_SENDING)
{
- ssize_t remaining;
-
/* Were their bytes in flight? */
if (privreq->inflight)
@@ -2338,7 +2328,7 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
/* Send next packet */
(void)sam_req_wrdma(priv, privep);
- sam_putreg(UDPHS_EPTSETSTA_TXRDY, SAM_UDPHS_EPTSETSTA(ep));
+ sam_putreg(UDPHS_EPTSETSTA_TXRDY, SAM_UDPHS_EPTSETSTA(epno));
}
else
{
@@ -2358,7 +2348,7 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
}
else
{
- usbtrace(TRACE_INTDECODE(SAM_TRACEINTID_TXRDYERR), privep->txnullpkt);
+ usbtrace(TRACE_DEVERROR(SAM_TRACEERR_TXRDYERR), privep->txnullpkt);
}
}
@@ -2377,15 +2367,15 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
if (eptype == UDPHS_EPTCFG_TYPE_CTRL8 &&
(eptsta & UDPHS_EPTSTA_BYTECNT_MASK) == 0)
{
- sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno));
sam_req_complete(privep, OK);
}
/* Data has been STALLed */
- else if ((epsta & UDPHS_EPTSTA_FRCESTALL) != 0)
+ else if ((eptsta & UDPHS_EPTSTA_FRCESTALL) != 0)
{
- sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno));
}
/* NAK the data */
@@ -2405,8 +2395,8 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
pktsize = (uint16_t)
((eptsta & UDPHS_EPTSTA_BYTECNT_MASK) >> UDPHS_EPTSTA_BYTECNT_SHIFT);
- sam_ep0_read(priv, privep);
- sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_req_read(priv, privep);
+ sam_putreg(UDPHS_EPTSTA_RXRDYTXKL, SAM_UDPHS_EPTCLRSTA(epno));
/* Check if transfer is finished */
@@ -2437,7 +2427,7 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
/* Acknowledge */
- sam_putreg(UDPHS_EPTSTA_STALLSNT, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_putreg(UDPHS_EPTSTA_STALLSNT, SAM_UDPHS_EPTCLRSTA(epno));
/* ISO error */
@@ -2450,9 +2440,9 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
else
{
- if (privep->epstate != UDPHS_EPSTATE_HALTED)
+ if (privep->epstate != UDPHS_EPSTATE_STALLED)
{
- sam_putreg(UDPHS_EPTSTA_FRCESTALL, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_putreg(UDPHS_EPTSTA_FRCESTALL, SAM_UDPHS_EPTCLRSTA(epno));
}
}
}
@@ -2480,17 +2470,17 @@ static void sam_ep_interrupt(struct sam_usbdev_s *priv, int epno)
{
/* Acknowledge setup packet */
- sam_putreg(UDPHS_EPTSTA_RXSETUP, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_putreg(UDPHS_EPTSTA_RXSETUP, SAM_UDPHS_EPTCLRSTA(epno));
}
else
{
/* Copy setup */
- sam_ep0_read(priv->ctrl);
+ sam_ep0_readsetup(&priv->ctrl);
/* Acknowledge setup packet */
- sam_putreg(UDPHS_EPTSTA_RXSETUP, SAM_UDPHS_EPTCLRSTA(ep));
+ sam_putreg(UDPHS_EPTSTA_RXSETUP, SAM_UDPHS_EPTCLRSTA(epno));
/* Handle the EP0 SETUP command */
@@ -2514,19 +2504,20 @@ static int sam_udphs_interrupt(int irq, void *context)
* easier.
*/
- struct sam_usbdev_s *priv = &g_usbdev;
+ struct sam_usbdev_s *priv = &g_udphs;
uint32_t intsta;
uint32_t ien;
uint32_t pending;
+ uint32_t regval;
int i;
/* Get the set of pending interrupts */
- intsta = sam_getreg(SAM_UDPHS_INTSTA);
+ intsta = sam_getreg(SAM_UDPHS_INTSTA);
usbtrace(TRACE_INTENTRY(SAM_TRACEINTID_INTERRUPT), intsta);
- inten = sam_getreg(SAM_UDPHS_IEN);
- pending = insta & inten;
+ ien = sam_getreg(SAM_UDPHS_IEN);
+ pending = intsta & ien;
/* Handle all pending UDPHS interrupts (and new interrupts that become
* pending)
@@ -2544,7 +2535,7 @@ static int sam_udphs_interrupt(int irq, void *context)
/* Enable wakeup interrupts */
- regval = inten;
+ regval = ien;
regval &= ~UDPHS_INT_DETSUSPD;
regval |= (UDPHS_INT_WAKEUP | UDPHS_INT_ENDOFRSM);
sam_putreg(regval, SAM_UDPHS_IEN);
@@ -2580,9 +2571,9 @@ static int sam_udphs_interrupt(int irq, void *context)
/* Enable suspend interrupts */
- inten &= ~UDPHS_INT_WAKEUP;
- inten |= (UDPHS_INT_ENDOFRSM | UDPHS_INT_DETSUSPD);
- sam_putreg(inten, SAM_UDPHS_IEN);
+ ien &= ~UDPHS_INT_WAKEUP;
+ ien |= (UDPHS_INT_ENDOFRSM | UDPHS_INT_DETSUSPD);
+ sam_putreg(ien, SAM_UDPHS_IEN);
}
/* Bus reset */
@@ -2595,8 +2586,8 @@ static int sam_udphs_interrupt(int irq, void *context)
sam_putreg(UDPHS_INT_WAKEUP | UDPHS_INT_DETSUSPD, SAM_UDPHS_CLRINT);
- inten |= UDPHS_INT_DETSUSPD;
- sam_putreg(inten, SAM_UDPHS_IEN);
+ ien |= UDPHS_INT_DETSUSPD;
+ sam_putreg(ien, SAM_UDPHS_IEN);
/* Handle the reset */
@@ -2648,11 +2639,11 @@ static int sam_udphs_interrupt(int irq, void *context)
/* Re-sample the set of pending interrupts */
intsta = sam_getreg(SAM_UDPHS_INTSTA);
- inten = sam_getreg(SAM_UDPHS_IEN);
- pending = insta & inten;
+ ien = sam_getreg(SAM_UDPHS_IEN);
+ pending = intsta & ien;
}
- usbtrace(TRACE_INTEXIT(SAM_TRACEINTID_INTERRUPT), insta);
+ usbtrace(TRACE_INTEXIT(SAM_TRACEINTID_INTERRUPT), intsta);
return OK;
}
@@ -2689,8 +2680,6 @@ sam_setimask(struct sam_usbdev_s *priv, uint16_t setbits, uint16_t clrbits)
static void sam_suspend(struct sam_usbdev_s *priv)
{
- uint32_t regval;
-
/* Don't do anything if the device is already suspended */
if (priv->devstate != UDPHS_DEVSTATE_SUSPENDED)
@@ -2732,8 +2721,6 @@ static void sam_suspend(struct sam_usbdev_s *priv)
static void sam_resume(struct sam_usbdev_s *priv)
{
- uint32_t regval;
-
/* This function is called when either (1) a WKUP interrupt is received from
* the host PC, or (2) the class device implementation calls the wakeup()
* method.
@@ -2772,55 +2759,77 @@ static void sam_resume(struct sam_usbdev_s *priv)
/****************************************************************************
* Endpoint Helpers
****************************************************************************/
+
/****************************************************************************
- * Name: sam_epset_reset
+ * Name: sam_ep_reset
+ *
+ * Description
+ * Reset and disable a set of endpoints.
+ *
****************************************************************************/
-void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset)
+static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno)
{
- struct sam_ep_s *privep;
- uint32_t bit;
- int epno;
+ struct sam_ep_s *privep = &priv->eplist[epno];
+ uint32_t regval;
- /* Reset each endpoint in the set */
+ /* Disable endpoint interrupt */
- for (epno = 0, bit = 1; epno < SAM_UDPHS_NENDPOINTS; epno++)
- {
- if ((epset & bit) != 0)
- {
- privep = &priv->eplist[epno];
+ regval = sam_getreg(SAM_UDPHS_IEN);
+ regval &= ~UDPHS_INT_EPT(epno);
+ sam_putreg(regval, SAM_UDPHS_IEN);
- /* Disable endpoint interrupt */
+ /* Cancel any queued requests. Since they are canceled with status
+ * -ESHUTDOWN, then will not be requeued until the configuration is reset.
+ * NOTE: This should not be necessary... the CLASS_DISCONNECT above
+ * should result in the class implementation calling sam_ep_disable
+ * for each of its configured endpoints.
+ */
- regval = sam_getreg(SAM_UDPHS_IEN);
- regval &= ~UDPHS_INT_EPT(epno);
- sam_putreg(regval, SAM_UDPHS_IEN);
+ sam_req_cancel(privep);
- /* Cancel any queued requests. Since they are canceled
- * with status -ESHUTDOWN, then will not be requeued
- * until the configuration is reset. NOTE: This should
- * not be necessary... the CLASS_DISCONNECT above should
- * result in the class implementation calling sam_ep_disable
- * for each of its configured endpoints.
- */
+ /* Reset endpoint */
+
+ sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST);
- sam_req_cancel(privep);
+ /* Reset endpoint status */
- /* Reset endpoint */
+ privep->epstate = UDPHS_EPSTATE_DISABLED;
+ privep->stalled = false;
+ privep->halted = false;
+ privep->txbusy = false;
+ privep->txnullpkt = false;
+ privep->bank = 0;
+}
- sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST);
+/****************************************************************************
+ * Name: sam_epset_reset
+ *
+ * Description
+ * Reset and disable a set of endpoints.
+ *
+ ****************************************************************************/
- /* Reset endpoint status */
+static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset)
+{
+ uint32_t bit;
+ int epno;
- privep->epstate = UDPHS_EPSTATE_DISABLED;
- privep->stalled = false;
- privep->halted = false;
- privep->txbusy = false;
- privep->txnullpkt = false;
- privep->bank = 0;
- }
+ /* Reset each endpoint in the set */
- bit <<= 1;
+ for (epno = 0, bit = 1, epset &= SAM_EPSET_ALL;
+ epno < SAM_UDPHS_NENDPOINTS || epset == 0;
+ epno++, bit <<= 1)
+ {
+ /* Is this endpoint in the set? */
+
+ if ((epset & bit) != 0)
+ {
+ /* Yes.. reset it */
+
+ sam_ep_reset(priv, epno);
+ epset &= ~bit;
+ }
}
}
@@ -2913,6 +2922,7 @@ sam_ep_reserved(struct sam_usbdev_s *priv, int epno)
static int sam_ep_configure_internal(struct sam_ep_s *privep,
const struct usb_epdesc_s *desc)
{
+ struct sam_usbdev_s *priv;
uint32_t regval;
uint8_t epno;
uint8_t eptype;
@@ -2976,7 +2986,7 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep,
/* Reset Endpoint Fifos */
sam_putreg(UDPHS_EPTSTA_TOGGLESQ_MASK | UDPHS_EPTSTA_FRCESTALL,
- SAM_UDPHS_EPTCLRSTA(ep));
+ SAM_UDPHS_EPTCLRSTA(epno));
sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST);
/* If this is EP0, disable interrupts now */
@@ -3049,6 +3059,12 @@ static int sam_ep_configure_internal(struct sam_ep_s *privep,
SAM_UDPHS_EPTCTLENB(epno));
}
+ /* If this was the last endpoint, then the class driver is fully
+ * configured.
+ */
+
+ priv = privep->dev;
+ priv->devstate = UDPHS_DEVSTATE_CONFIGURED;
sam_dumpep(priv, epno);
return OK;
}
@@ -3072,7 +3088,7 @@ static int sam_ep_configure(struct usbdev_ep_s *ep,
/* Verify parameters. Endpoint 0 is not available at this interface */
-#if defing(CONFIG_DEBUG) || defined(CONFIG_USBDEV_TRACE)
+#if defined(CONFIG_DEBUG) || defined(CONFIG_USBDEV_TRACE)
uint8_t epno = USB_EPNO(desc->addr);
usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno);
@@ -3092,6 +3108,7 @@ static int sam_ep_configure(struct usbdev_ep_s *ep,
static int sam_ep_disable(struct usbdev_ep_s *ep)
{
struct sam_ep_s *privep = (struct sam_ep_s *)ep;
+ struct sam_usbdev_s *priv;
irqstate_t flags;
uint8_t epno;
@@ -3112,9 +3129,14 @@ static int sam_ep_disable(struct usbdev_ep_s *ep)
flags = irqsave();
sam_req_cancel(privep);
- /* Disable TX; disable RX */
-#warning Missing logic
+ /* Reset the endpoint */
+
+ sam_ep_reset(priv, epno);
+ /* Revert to the addressed-but-not-configured state */
+
+ priv = privep->dev;
+ priv->devstate = UDPHS_DEVSTATE_ADDRESS;
irqrestore(flags);
return OK;
}
@@ -3271,7 +3293,6 @@ static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
static int sam_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
{
struct sam_ep_s *privep = (struct sam_ep_s *)ep;
- struct sam_usbdev_s *priv;
irqstate_t flags;
#ifdef CONFIG_DEBUG
@@ -3282,7 +3303,6 @@ static int sam_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
}
#endif
usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog));
- priv = privep->dev;
flags = irqsave();
sam_req_cancel(privep);
@@ -3299,7 +3319,7 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
struct sam_ep_s *privep;
struct sam_usbdev_s *priv;
uint8_t epno = USB_EPNO(ep->eplog);
- uint16_t status;
+ uint32_t regval;
irqstate_t flags;
#ifdef CONFIG_DEBUG
@@ -3308,7 +3328,12 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
return -EINVAL;
}
+
+ /* Check that endpoint is in Idle state */
+
+ DEBUGASSERT(privep->epstate == UDPHS_EPSTATE_IDLE);
#endif
+
privep = (struct sam_ep_s *)ep;
priv = (struct sam_usbdev_s *)privep->dev;
epno = USB_EPNO(ep->eplog);
@@ -3318,62 +3343,38 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
flags = irqsave();
usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, USB_EPNO(ep->eplog));
- /* Get status of the endpoint; stall the request if the endpoint is
- * disabled
- */
-#warning Missing logic
-
+ /* Handle the resume condition */
- if (status == 0)
+ if (resume)
{
- usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPDISABLED), 0);
+ /* Check if the endpoint is halted */
- if (epno == 0)
+ if (privep->epstate == UDPHS_EPSTATE_STALLED)
{
- priv->ep0state = EP0STATE_STALLED;
- }
-
- return -ENODEV;
- }
+ usbtrace(TRACE_EPRESUME, epno);
+ privep->stalled = false;
- /* Handle the resume condition */
+ /* Return endpoint to Idle state */
- if (resume)
- {
- /* Resuming a stalled endpoint */
+ privep->epstate = UDPHS_EPSTATE_IDLE;
- usbtrace(TRACE_EPRESUME, epno);
- privep->stalled = false;
+ /* Clear FORCESTALL flag */
- if (USB_ISEPIN(ep->eplog))
- {
- /* IN endpoint */
+ sam_putreg(UDPHS_EPTSTA_TOGGLESQ_MASK | UDPHS_EPTSTA_FRCESTALL,
+ SAM_UDPHS_EPTCLRSTA(epno));
- if (sam_eptxstalled(epno))
- {
- sam_clrtxdtog(epno);
+ /* Reset xndpoint FIFOs */
- /* Restart any queued write requests */
+ sam_putreg(UDPHS_EPTRST(epno), SAM_UDPHS_EPTRST);
- (void)sam_req_write(priv, privep);
- }
- }
- else
- {
- /* OUT endpoint */
+ /* Resuming any blocked data transfers on the endpoint */
- if (sam_eprxstalled(epno))
+ if (USB_ISEPIN(ep->eplog))
{
- if (epno == EP0)
- {
- /* After clear the STALL, enable the default endpoint receiver */
+ /* IN endpoint */
+ /* Restart any queued write requests */
- sam_seteprxcount(epno, ep->maxpacket);
- }
- else
- {
- sam_clrrxdtog(epno);
- }
+ (void)sam_req_write(priv, privep);
}
}
}
@@ -3382,9 +3383,46 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
else
{
- usbtrace(TRACE_EPSTALL, epno);
- privep->stalled = true;
-#warning Missing logic
+ /* Check that endpoint is enabled and not already in Halt state */
+
+ if ((privep->epstate != UDPHS_EPSTATE_DISABLED) &&
+ (privep->epstate != UDPHS_EPSTATE_STALLED))
+ {
+ usbtrace(TRACE_EPSTALL, epno);
+
+ /* Abort the current transfer if necessary */
+
+ sam_req_complete(privep, -EIO);
+
+ /* Put endpoint into Halt state */
+
+ privep->epstate = UDPHS_EPSTATE_STALLED;
+ privep->stalled = true;
+
+ if (epno == 0)
+ {
+ priv->ep0state = EP0STATE_STALLED;
+ }
+
+ sam_putreg(UDPHS_EPTSETSTA_FRCESTALL, SAM_UDPHS_EPTSETSTA(epno));
+
+ /* Enable endpoint/DMA interrupts */
+
+ regval = sam_getreg(SAM_UDPHS_IEN);
+ if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0)
+ {
+ /* Enable the endpoint DMA interrupt */
+
+ regval &= ~UDPHS_INT_DMA(epno);
+ }
+ else
+ {
+ /* Enable the endpoint interrupt */
+
+ regval &= ~UDPHS_INT_EPT(epno);
+ }
+ sam_putreg(regval, SAM_UDPHS_IEN);
+ }
}
irqrestore(flags);
@@ -3396,6 +3434,10 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
****************************************************************************/
/****************************************************************************
* Name: sam_allocep
+ *
+ * Description:
+ * This is the allocep() method of the USB device driver interface
+ *
****************************************************************************/
static struct usbdev_ep_s *sam_allocep(struct usbdev_s *dev, uint8_t epno,
@@ -3449,23 +3491,18 @@ static struct usbdev_ep_s *sam_allocep(struct usbdev_s *dev, uint8_t epno,
if (!privep)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_EPRESERVE), (uint16_t)epset);
- goto errout;
+ return NULL;
}
- epno = USB_EPNO(privep->ep.eplog);
-
- /* Allocate a PMA buffer for this endpoint */
-#warning Missing logic
return &privep->ep;
-
-errout_with_ep:
- sam_ep_unreserve(priv, privep);
-errout:
- return NULL;
}
/****************************************************************************
* Name: sam_freeep
+ *
+ * Description:
+ * This is the freeep() method of the USB device driver interface
+ *
****************************************************************************/
static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep)
@@ -3497,6 +3534,10 @@ static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep)
/****************************************************************************
* Name: sam_getframe
+ *
+ * Description:
+ * This is the getframe() method of the USB device driver interface
+ *
****************************************************************************/
static int sam_getframe(struct usbdev_s *dev)
@@ -3520,12 +3561,17 @@ static int sam_getframe(struct usbdev_s *dev)
/****************************************************************************
* Name: sam_wakeup
+ *
+ * Description:
+ * This is the wakeup() method of the USB device driver interface
+ *
****************************************************************************/
static int sam_wakeup(struct usbdev_s *dev)
{
struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev;
irqstate_t flags;
+ uint32_t regval;
usbtrace(TRACE_DEVWAKEUP, 0);
#ifdef CONFIG_DEBUG
@@ -3540,12 +3586,32 @@ static int sam_wakeup(struct usbdev_s *dev)
flags = irqsave();
sam_resume(priv);
+
+ /* Activate a remote wakeup. Setting this bit forces an external interrupt
+ * on the UDPHS controller for Remote Wake UP purposes. An Upstream Resume
+ * is sent only after the UDPHS bus has been in SUSPEND state for at least 5
+ * ms.
+ */
+
+ regval = sam_getreg(SAM_UDPHS_CTRL);
+ regval |= UDPHS_CTRL_REWAKEUP;
+ sam_putreg(regval, SAM_UDPHS_CTRL);
irqrestore(flags);
+
+ /* This bit is automatically cleared by hardware at the end of the Upstream
+ * Resume
+ */
+
+ while ((sam_getreg(SAM_UDPHS_CTRL) & UDPHS_CTRL_REWAKEUP) != 0);
return OK;
}
/****************************************************************************
* Name: sam_selfpowered
+ *
+ * Description:
+ * This is the selfpowered() method of the USB device driver interface
+ *
****************************************************************************/
static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered)
@@ -3567,6 +3633,47 @@ static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered)
}
/****************************************************************************
+ * Name: sam_pullup
+ *
+ * Description:
+ * This is the pullup() method of the USB device driver interface
+ *
+ ****************************************************************************/
+
+static int sam_pullup(FAR struct usbdev_s *dev, bool enable)
+{
+ struct sam_usbdev_s *priv = (struct sam_usbdev_s *)dev;
+ uint32_t regval;
+
+ regval = sam_getreg(SAM_UDPHS_CTRL);
+ if (enable)
+ {
+ regval |= UDPHS_CTRL_PULLDDIS;
+ sam_putreg(regval, SAM_UDPHS_CTRL);
+
+ regval &= ~UDPHS_CTRL_DETACH;
+ sam_putreg(regval, SAM_UDPHS_CTRL);
+ }
+ else
+ {
+ regval |= UDPHS_CTRL_DETACH;
+ sam_putreg(regval, SAM_UDPHS_CTRL);
+
+ regval &= ~UDPHS_CTRL_PULLDDIS;
+ sam_putreg(regval, SAM_UDPHS_CTRL);
+
+ /* Device returns to the Powered state */
+
+ if (priv->devstate > UDPHS_DEVSTATE_POWERED)
+ {
+ priv->devstate = UDPHS_DEVSTATE_POWERED;
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
* Initialization/Reset
****************************************************************************/
@@ -3576,6 +3683,8 @@ static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered)
static void sam_reset(struct sam_usbdev_s *priv)
{
+ uint8_t epno;
+
/* Make sure that clocking is eanbled to the UDPHS peripheral. */
sam_udphs_enableclk();
@@ -3814,10 +3923,11 @@ static void sam_hw_setup(struct sam_usbdev_s *priv)
static void sam_sw_setup(struct sam_usbdev_s *priv)
{
int epno;
- int i;
#ifdef CONFIG_SAMA5_UDPHS_SCATTERGATHER
#ifndef CONFIG_SAMA5_EHCI_PREALLOCATE
+ int i;
+
/* Allocate a pool of free DMA transfer descriptors */
priv->dtdpool = (struct sam_dtd_s *)
@@ -3911,7 +4021,7 @@ static void sam_hw_shutdown(struct sam_usbdev_s *priv)
/* Disconnect the device / disable the pull-up */
- sam_usbpullup(&priv->usbdev, false);
+ sam_pullup(&priv->usbdev, false);
/* Power down the USB controller */
@@ -3949,7 +4059,7 @@ void up_usbinitialize(void)
* easier.
*/
- struct sam_usbdev_s *priv = &g_usbdev;
+ struct sam_usbdev_s *priv = &g_udphs;
usbtrace(TRACE_DEVINIT, 0);
@@ -4002,7 +4112,7 @@ void up_usbuninitialize(void)
* easier.
*/
- struct sam_usbdev_s *priv = &g_usbdev;
+ struct sam_usbdev_s *priv = &g_udphs;
irqstate_t flags;
flags = irqsave();
@@ -4042,7 +4152,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
* easier.
*/
- struct sam_usbdev_s *priv = &g_usbdev;
+ struct sam_usbdev_s *priv = &g_udphs;
int ret;
usbtrace(TRACE_DEVREGISTER, 0);
@@ -4088,7 +4198,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
* some time after this
*/
- sam_usbpullup(&priv->usbdev, true);
+ sam_pullup(&priv->usbdev, true);
priv->usbdev.speed = USB_SPEED_FULL;
}
return ret;
@@ -4112,7 +4222,7 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
* easier.
*/
- struct sam_usbdev_s *priv = &g_usbdev;
+ struct sam_usbdev_s *priv = &g_udphs;
irqstate_t flags;
usbtrace(TRACE_DEVUNREGISTER, 0);
@@ -4158,4 +4268,4 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
return OK;
}
-#endif /* CONFIG_USBDEV && CONFIG_SAM_USB */
+#endif /* CONFIG_USBDEV && CONFIG_SAMA5_UDPHS */
diff --git a/nuttx/arch/arm/src/sama5/sam_udphs.h b/nuttx/arch/arm/src/sama5/sam_udphs.h
new file mode 100644
index 000000000..72592f860
--- /dev/null
+++ b/nuttx/arch/arm/src/sama5/sam_udphs.h
@@ -0,0 +1,84 @@
+/************************************************************************************
+ * arch/arm/src/sama5/sam_udphs.h
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAMA5_SAM_UDPHS_H
+#define __ARCH_ARM_SRC_SAMA5_SAM_UDPHS_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/usb/usbdev.h>
+#include <stdint.h>
+
+#include "chip.h"
+#include "chip/sam_udphs.h"
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Name: sam_usbsuspend
+ *
+ * Description:
+ * Board logic must provide the sam_usbsuspend logic if the USBDEV driver is
+ * used. This function is called whenever the USB enters or leaves suspend mode.
+ * This is an opportunity for the board logic to shutdown clocks, power, etc.
+ * while the USB is suspended.
+ *
+ ************************************************************************************/
+
+void sam_usbsuspend(FAR struct usbdev_s *dev, bool resume);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_SAMA5_SAM_UDPHS_H */
+
diff --git a/nuttx/configs/sama5d3x-ek/README.txt b/nuttx/configs/sama5d3x-ek/README.txt
index d1b2f3675..cfebbc954 100644
--- a/nuttx/configs/sama5d3x-ek/README.txt
+++ b/nuttx/configs/sama5d3x-ek/README.txt
@@ -1220,6 +1220,27 @@ Configurations
Application Configuration -> NSH Library
CONFIG_NSH_ARCHINIT=y : NSH board-initialization
+ 10) Support the USB high-speed EHCI host driver can be enabled by changing
+ the NuttX configuration file as follows. If EHCI is enabled by itself,
+
+ Device Drivers -> USB Device Driver Support
+ CONFIG_USBDEV=y : Enable USB device support
+ CONFIG_USBDEV_DMA=y : Device uses DMA
+ CONFIG_USBDEV_DUALSPEED=y : Device support High and Full Speed
+
+ System Type -> ATSAMA5 Peripheral Support
+ CONFIG_SAMA5_UDPHS=y : Enable UDPHS High Speed USB device
+
+ Application Configuration -> NSH Library
+ CONFIG_NSH_ARCHINIT=y : NSH board-initialization
+
+ You also need to select a device-side class driver for the USB device,
+ This will select the CDC/ACM serial device. Defaults for the other
+ options should be okay.
+
+ Device Drivers -> USB Device Driver Support
+ CONFIG_CDCACM=y : Enable the CDC/ACM device
+
STATUS:
2013-7-19: This configuration (as do the others) run at 396MHz.
The SAMA5D3 can run at 536MHz. I still need to figure out the
@@ -1293,6 +1314,10 @@ Configurations
2013-8-28: EHCI is partially functional. It is able to mount a high-
speed USB FLASH drive using the Mass Storage Class (MSC) interface.
+ 2013-8-31: Added description to add UDPHS high-speed USB device
+ support. That function is still, however, a long way from being
+ functional.
+
ostest:
This configuration directory, performs a simple OS test using
examples/ostest.