From 6b653880236a3819cde445bb40b9dddfde688c05 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 18 Mar 2014 09:31:02 -0600 Subject: [PATCH] SAM4E: Revise board-specific USB MSC support --- configs/sam4e-ek/Kconfig | 17 +++- configs/sam4e-ek/README.txt | 133 ++++++++++++++++++++++++++++++ configs/sam4e-ek/src/sam_hsmci.c | 75 ++++++++++------- configs/sam4e-ek/src/sam_usbmsc.c | 61 ++++++-------- 4 files changed, 219 insertions(+), 67 deletions(-) diff --git a/configs/sam4e-ek/Kconfig b/configs/sam4e-ek/Kconfig index aebc0f913f..382c8db563 100644 --- a/configs/sam4e-ek/Kconfig +++ b/configs/sam4e-ek/Kconfig @@ -20,7 +20,7 @@ endchoice # CPU Frequency config SAM4EEK_AT25_AUTOMOUNT bool "AT25 serial FLASH auto-mount" default n - depends on NSH_ARCHINIT && SAM34_SPI0 && MTD_AT25 + depends on SAM34_SPI0 && MTD_AT25 ---help--- Automatically initialize the AT25 SPI FLASH driver when NSH starts. @@ -47,4 +47,19 @@ config SAM4EEK_AT25_NXFFS endchoice # AT25 serial FLASH configuration +choice + prompt "USB MSC block device" + default SAM4EEK_AT25_BLOCKDEVICE if SAM4EEK_AT25_FTL + default SAM4EEK_HSMCI_BLOCKDEVICE if !SAM4EEK_AT25_FTL + depends on SYSTEM_USBMSC && (SAM4EEK_AT25_FTL || SAM34_HSMCI) + +config SAM4EEK_AT25_BLOCKDEVICE + bool "AT25 Serial FLASH" + +config SAM4EEK_HSMCI_BLOCKDEVICE + bool "SD card" + depends on SAM34_HSMCI + +endchoice # AT25 serial FLASH configuration + endif # ARCH_BOARD_SAM4EEK diff --git a/configs/sam4e-ek/README.txt b/configs/sam4e-ek/README.txt index d1b8af2749..e77ebfc157 100644 --- a/configs/sam4e-ek/README.txt +++ b/configs/sam4e-ek/README.txt @@ -21,6 +21,7 @@ Contents - Serial Console - Networking Support - AT25 Serial FLASH + - USB Full-Speed Device - SAM4E-EK-specific Configuration Options - Configurations @@ -586,6 +587,138 @@ AT25 Serial FLASH nsh> cat /mnt/at25/atest.txt This is a test +USB Full-Speed Device +===================== + + Basic USB Full-Speed Device Configuration + ----------------------------------------- + + Support the USB high-speed device (UDPHS) driver can be enabled with these + NuttX configuration settings. + + Device Drivers -> USB Device Driver Support + CONFIG_USBDEV=y : Enable USB device support + CONFIG_USBDEV_DUALSPEED=n : Device does not support High-Speed + CONFIG_USBDEV_DMA=n : Device does not use DMA + + System Type -> ATSAM3/4 Peripheral Support + CONFIG_SAM34_UDP=y : Enable UDP Full Speed USB device + + Application Configuration -> NSH Library + CONFIG_NSH_ARCHINIT=y : NSH board-initialization + + Mass Storage Class + ------------------ + + The Mass Storage Class (MSC) class driver can be selected for use with + UDPHS. Note: The following assumes that the internal AT24 Serial FLASH + is configured to support a FAT file system through an FTL layer as + described about under "AT25 Serial FLASH". + + Device Drivers -> USB Device Driver Support + CONFIG_USBMSC=y : Enable the USB MSC class driver + CONFIG_USBMSC_EPBULKOUT=4 : Use EP1 for the BULK OUT endpoint + CONFIG_USBMSC_EPBULKIN=5 : Use EP2 for the BULK IN endpoint + : Defaults for other settings? + Board Selection + CONFIG_SAM4EEK_AT25_BLOCKDEVICE=y : Export AT25 serial FLASH device + CONFIG_SAM4EEK_HSMCI_BLOCKDEVICE=n : Don't export HSMCI SD card + + Note: If properly configured, you could export the HSMCI SD card instead + of the internal AT25 Serial FLASH. + + The following setting enables an add-on that can can be used to control + the USB MSC device. It will add two new NSH commands: + + a. msconn will connect the USB serial device and export the AT25 + to the host, and + b. msdis which will disconnect the USB serial device. + + Application Configuration -> System Add-Ons: + CONFIG_SYSTEM_USBMSC=y : Enable the USBMSC add-on + CONFIG_SYSTEM_USBMSC_NLUNS=1 : One LUN + CONFIG_SYSTEM_USBMSC_DEVMINOR1=0 : Minor device zero + CONFIG_SYSTEM_USBMSC_DEVPATH1="/dev/mtdblock0" + : Use a single, LUN: The AT25 + : block driver. + NOTES: + + a. To prevent file system corruption, make sure that the AT25 is un- + mounted *before* exporting the mass storage device to the host: + + nsh> umount /mnt/at25 + nsh> mscon + + The AT25 can be re-mounted after the mass storage class is disconnected: + + nsh> msdis + nsh> mount -t vfat /dev/mtdblock0 /mnt/at25 + + b. If you change the value CONFIG_SYSTEM_USBMSC_DEVPATH1, then you + can export other file systems: + + "/dev/mmcsd0" would export the HSMCI SD slot + + "/dev/ram0" could even be used to export a RAM disk. But you would + first have to use mkrd to create the RAM disk and mkfatfs to put + a FAT file system on it. + + CDC/ACM Serial Device Class + --------------------------- + + 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 + CONFIG_CDCACM_BULKIN_REQLEN=96 : Default request size + + The following setting enables an example that can can be used to control + the CDC/ACM device. It will add two new NSH commands: + + a. sercon will connect the USB serial device (creating /dev/ttyACM0), and + b. serdis which will disconnect the USB serial device (destroying + /dev/ttyACM0). + + Application Configuration -> Examples: + CONFIG_SYSTEM_CDCACM=y : Enable an CDC/ACM example + + Debugging USB Device + -------------------- + + There is normal console debug output available that can be enabled with + CONFIG_DEBUG + CONFIG_DEBUG_USB. However, USB device operation is very + time critical and enabling this debug output WILL interfere with the + operation of the UDPHS. USB device tracing is a less invasive way to get + debug information: If tracing is enabled, the USB device will save + encoded trace output in in-memory buffer; if the USB monitor is also + enabled, that trace buffer will be periodically emptied and dumped to the + system logging device (the serial console in this configuration): + + Device Drivers -> "USB Device Driver Support: + CONFIG_USBDEV_TRACE=y : Enable USB trace feature + CONFIG_USBDEV_TRACE_NRECORDS=256 : Buffer 256 records in memory + CONFIG_USBDEV_TRACE_STRINGS=y : (optional) + + Application Configuration -> NSH LIbrary: + CONFIG_NSH_USBDEV_TRACE=n : No builtin tracing from NSH + CONFIG_NSH_ARCHINIT=y : Automatically start the USB monitor + + Application Configuration -> System NSH Add-Ons: + CONFIG_SYSTEM_USBMONITOR=y : Enable the USB monitor daemon + CONFIG_SYSTEM_USBMONITOR_STACKSIZE=2048 : USB monitor daemon stack size + CONFIG_SYSTEM_USBMONITOR_PRIORITY=50 : USB monitor daemon priority + CONFIG_SYSTEM_USBMONITOR_INTERVAL=1 : Dump trace data every second + CONFIG_SYSTEM_USBMONITOR_TRACEINIT=y : Enable TRACE output + CONFIG_SYSTEM_USBMONITOR_TRACECLASS=y + CONFIG_SYSTEM_USBMONITOR_TRACETRANSFERS=y + CONFIG_SYSTEM_USBMONITOR_TRACECONTROLLER=y + CONFIG_SYSTEM_USBMONITOR_TRACEINTERRUPTS=y + + NOTE: If USB debug output is also enabled, both outputs will appear on the + serial console. However, the debug output will be asynchronous with the + trace output and, hence, difficult to interpret. + SAM4E-EK-specific Configuration Options ======================================= diff --git a/configs/sam4e-ek/src/sam_hsmci.c b/configs/sam4e-ek/src/sam_hsmci.c index fe4858e3ec..c8dcc70854 100644 --- a/configs/sam4e-ek/src/sam_hsmci.c +++ b/configs/sam4e-ek/src/sam_hsmci.c @@ -66,6 +66,7 @@ struct sam_hsmci_state_s { struct sdio_dev_s *hsmci; /* R/W device handle */ + bool initialized; /* TRUE: HSMCI block driver is initialized */ bool inserted; /* TRUE: card is inserted */ }; @@ -129,42 +130,52 @@ int sam_hsmci_initialize(int minor) { int ret; - /* Initialize card-detect GPIO. There is no write-protection GPIO. */ + /* Have we already initialized? */ - sam_configpio(GPIO_MCI_CD); - - /* Mount the SDIO-based MMC/SD block driver */ - /* First, get an instance of the SDIO interface */ - - g_hsmci.hsmci = sdio_initialize(0); - if (!g_hsmci.hsmci) + if (!g_hsmci.initialized) { - fdbg("Failed to initialize SDIO\n"); - return -ENODEV; + /* Initialize card-detect GPIO. There is no write-protection GPIO. */ + + sam_configpio(GPIO_MCI_CD); + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + g_hsmci.hsmci = sdio_initialize(0); + if (!g_hsmci.hsmci) + { + fdbg("Failed to initialize SDIO\n"); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + ret = mmcsd_slotinitialize(minor, g_hsmci.hsmci); + if (ret != OK) + { + fdbg("Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + /* Configure card detect interrupts */ + + sam_pioirq(GPIO_MCI_CD); + (void)irq_attach(MCI_CD_IRQ, sam_hsmci_cardetect); + + /* Then inform the HSMCI driver if there is or is not a card in the slot. */ + + g_hsmci.inserted = sam_cardinserted(0); + sdio_mediachange(g_hsmci.hsmci, g_hsmci.inserted); + + /* Now we are initialized */ + + g_hsmci.initialized = true; + + /* Enable card detect interrupts */ + + sam_pioirqenable(MCI_CD_IRQ); } - /* Now bind the SDIO interface to the MMC/SD driver */ - - ret = mmcsd_slotinitialize(minor, g_hsmci.hsmci); - if (ret != OK) - { - fdbg("Failed to bind SDIO to the MMC/SD driver: %d\n", ret); - return ret; - } - - /* Configure card detect interrupts */ - - sam_pioirq(GPIO_MCI_CD); - (void)irq_attach(MCI_CD_IRQ, sam_hsmci_cardetect); - - /* Then inform the HSMCI driver if there is or is not a card in the slot. */ - - g_hsmci.inserted = sam_cardinserted(0); - sdio_mediachange(g_hsmci.hsmci, g_hsmci.inserted); - - /* Enable card detect interrupts */ - - sam_pioirqenable(MCI_CD_IRQ); return OK; } diff --git a/configs/sam4e-ek/src/sam_usbmsc.c b/configs/sam4e-ek/src/sam_usbmsc.c index 63e6538985..697ba0c869 100644 --- a/configs/sam4e-ek/src/sam_usbmsc.c +++ b/configs/sam4e-ek/src/sam_usbmsc.c @@ -50,7 +50,7 @@ #include "sam_hsmci.h" -#ifdef CONFIG_SAM34_HSMCI +#ifdef CONFIG_SAM34_UDP /**************************************************************************** * Pre-Processor Definitions @@ -67,6 +67,16 @@ #undef SAM_MMCSDSLOTNO #define SAM_MMCSDSLOTNO 0 +/* Can't use a block device if it is not available */ + +#ifndef HAVE_AT25 +# undef CONFIG_SAM4EEK_AT25_BLOCKDEVICE +#endif + +#ifndef HAVE_HSMCI +# undef CONFIG_SAM4EEK_HSMCI_BLOCKDEVICE +#endif + /* Debug ********************************************************************/ #ifdef CONFIG_CPP_HAVE_VARARGS @@ -101,48 +111,31 @@ int usbmsc_archinitialize(void) { - FAR struct sdio_dev_s *sdio; - int ret; + /* Initialize the AT25 MTD driver */ - /* First, get an instance of the SDIO interface */ - - message("usbmsc_archinitialize: " - "Initializing SDIO slot %d\n", - SAM_MMCSDSLOTNO); - - sdio = sdio_initialize(SAM_MMCSDSLOTNO); - if (!sdio) +#if defined(CONFIG_SAM4EEK_AT25_BLOCKDEVICE) + int ret = sam_at25_automount(0); + if (ret < 0) { - message("usbmsc_archinitialize: Failed to initialize SDIO slot %d\n", - SAM_MMCSDSLOTNO); - return -ENODEV; + message("ERROR: sam_at25_automount failed: %d\n", ret); } - /* Now bind the SPI interface to the MMC/SD driver */ + return ret; - message("usbmsc_archinitialize: " - "Bind SDIO to the MMC/SD driver, minor=%d\n", - CONFIG_SYSTEM_USBMSC_DEVMINOR1); +#elif defined(CONFIG_SAM4EEK_HSMCI_BLOCKDEVICE) + /* Initialize the HSMCI driver */ - ret = mmcsd_slotinitialize(CONFIG_SYSTEM_USBMSC_DEVMINOR1, sdio); - if (ret != OK) + ret = sam_hsmci_initialize(0); + if (ret < 0) { - message("usbmsc_archinitialize: " - "Failed to bind SDIO to the MMC/SD driver: %d\n", - ret); - return ret; + message("ERROR: sam_hsmci_initialize(0) failed: %d\n", ret); } - message("usbmsc_archinitialize: " - "Successfully bound SDIO to the MMC/SD driver\n"); + return ret; - /* Then let's guess and say that there is a card in the slot. I need to check to - * see if the SAM3U10E-EVAL board supports a GPIO to detect if there is a card in - * the slot. - */ - - sdio_mediachange(sdio, true); - return OK; +#else + return -ENODEV; +#endif } -#endif /* CONFIG_SAM34_HSMCI */ +#endif /* CONFIG_SAM34_UDP */