SAM4E: Revise board-specific USB MSC support

This commit is contained in:
Gregory Nutt 2014-03-18 09:31:02 -06:00
parent 1ec72470e3
commit 6b65388023
4 changed files with 219 additions and 67 deletions

View File

@ -20,7 +20,7 @@ endchoice # CPU Frequency
config SAM4EEK_AT25_AUTOMOUNT config SAM4EEK_AT25_AUTOMOUNT
bool "AT25 serial FLASH auto-mount" bool "AT25 serial FLASH auto-mount"
default n default n
depends on NSH_ARCHINIT && SAM34_SPI0 && MTD_AT25 depends on SAM34_SPI0 && MTD_AT25
---help--- ---help---
Automatically initialize the AT25 SPI FLASH driver when NSH starts. Automatically initialize the AT25 SPI FLASH driver when NSH starts.
@ -47,4 +47,19 @@ config SAM4EEK_AT25_NXFFS
endchoice # AT25 serial FLASH configuration 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 endif # ARCH_BOARD_SAM4EEK

View File

@ -21,6 +21,7 @@ Contents
- Serial Console - Serial Console
- Networking Support - Networking Support
- AT25 Serial FLASH - AT25 Serial FLASH
- USB Full-Speed Device
- SAM4E-EK-specific Configuration Options - SAM4E-EK-specific Configuration Options
- Configurations - Configurations
@ -586,6 +587,138 @@ AT25 Serial FLASH
nsh> cat /mnt/at25/atest.txt nsh> cat /mnt/at25/atest.txt
This is a test 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 SAM4E-EK-specific Configuration Options
======================================= =======================================

View File

@ -66,6 +66,7 @@
struct sam_hsmci_state_s struct sam_hsmci_state_s
{ {
struct sdio_dev_s *hsmci; /* R/W device handle */ struct sdio_dev_s *hsmci; /* R/W device handle */
bool initialized; /* TRUE: HSMCI block driver is initialized */
bool inserted; /* TRUE: card is inserted */ bool inserted; /* TRUE: card is inserted */
}; };
@ -129,42 +130,52 @@ int sam_hsmci_initialize(int minor)
{ {
int ret; int ret;
/* Initialize card-detect GPIO. There is no write-protection GPIO. */ /* Have we already initialized? */
sam_configpio(GPIO_MCI_CD); if (!g_hsmci.initialized)
/* 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"); /* Initialize card-detect GPIO. There is no write-protection GPIO. */
return -ENODEV;
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; return OK;
} }

View File

@ -50,7 +50,7 @@
#include "sam_hsmci.h" #include "sam_hsmci.h"
#ifdef CONFIG_SAM34_HSMCI #ifdef CONFIG_SAM34_UDP
/**************************************************************************** /****************************************************************************
* Pre-Processor Definitions * Pre-Processor Definitions
@ -67,6 +67,16 @@
#undef SAM_MMCSDSLOTNO #undef SAM_MMCSDSLOTNO
#define SAM_MMCSDSLOTNO 0 #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 ********************************************************************/ /* Debug ********************************************************************/
#ifdef CONFIG_CPP_HAVE_VARARGS #ifdef CONFIG_CPP_HAVE_VARARGS
@ -101,48 +111,31 @@
int usbmsc_archinitialize(void) int usbmsc_archinitialize(void)
{ {
FAR struct sdio_dev_s *sdio; /* Initialize the AT25 MTD driver */
int ret;
/* First, get an instance of the SDIO interface */ #if defined(CONFIG_SAM4EEK_AT25_BLOCKDEVICE)
int ret = sam_at25_automount(0);
message("usbmsc_archinitialize: " if (ret < 0)
"Initializing SDIO slot %d\n",
SAM_MMCSDSLOTNO);
sdio = sdio_initialize(SAM_MMCSDSLOTNO);
if (!sdio)
{ {
message("usbmsc_archinitialize: Failed to initialize SDIO slot %d\n", message("ERROR: sam_at25_automount failed: %d\n", ret);
SAM_MMCSDSLOTNO);
return -ENODEV;
} }
/* Now bind the SPI interface to the MMC/SD driver */ return ret;
message("usbmsc_archinitialize: " #elif defined(CONFIG_SAM4EEK_HSMCI_BLOCKDEVICE)
"Bind SDIO to the MMC/SD driver, minor=%d\n", /* Initialize the HSMCI driver */
CONFIG_SYSTEM_USBMSC_DEVMINOR1);
ret = mmcsd_slotinitialize(CONFIG_SYSTEM_USBMSC_DEVMINOR1, sdio); ret = sam_hsmci_initialize(0);
if (ret != OK) if (ret < 0)
{ {
message("usbmsc_archinitialize: " message("ERROR: sam_hsmci_initialize(0) failed: %d\n", ret);
"Failed to bind SDIO to the MMC/SD driver: %d\n",
ret);
return ret;
} }
message("usbmsc_archinitialize: " return ret;
"Successfully bound SDIO to the MMC/SD driver\n");
/* Then let's guess and say that there is a card in the slot. I need to check to #else
* see if the SAM3U10E-EVAL board supports a GPIO to detect if there is a card in return -ENODEV;
* the slot. #endif
*/
sdio_mediachange(sdio, true);
return OK;
} }
#endif /* CONFIG_SAM34_HSMCI */ #endif /* CONFIG_SAM34_UDP */