diff --git a/configs/samv71-xult/Kconfig b/configs/samv71-xult/Kconfig index 16131608a0..7d3f82c99e 100644 --- a/configs/samv71-xult/Kconfig +++ b/configs/samv71-xult/Kconfig @@ -4,4 +4,34 @@ # if ARCH_BOARD_SAMV71_XULT + +config SAMV7XULT_HSMCI0_AUTOMOUNT + bool "HSMCI0 automounter" + default n + depends on FS_AUTOMOUNTER && SAMA5_HSMCI0 + +if SAMV7XULT_HSMCI0_AUTOMOUNT + +config SAMV7XULT_HSMCI0_AUTOMOUNT_FSTYPE + string "HSMCI0 file system type" + default "vfat" + +config SAMV7XULT_HSMCI0_AUTOMOUNT_BLKDEV + string "HSMCI0 block device" + default "/dev/mmcsd0" + +config SAMV7XULT_HSMCI0_AUTOMOUNT_MOUNTPOINT + string "HSMCI0 mount point" + default "/mnt/sdcard0" + +config SAMV7XULT_HSMCI0_AUTOMOUNT_DDELAY + int "HSMCI0 debounce delay (milliseconds)" + default 1000 + +config SAMV7XULT_HSMCI0_AUTOMOUNT_UDELAY + int "HSMCI0 unmount retry delay (milliseconds)" + default 2000 + +endif # SAMV7XULT_HSMCI0_AUTOMOUNT + endif # ARCH_BOARD_SAMV71_XULT diff --git a/configs/samv71-xult/README.txt b/configs/samv71-xult/README.txt index cb5ab5250d..5d8944a1a5 100644 --- a/configs/samv71-xult/README.txt +++ b/configs/samv71-xult/README.txt @@ -10,6 +10,8 @@ Contents - Board Features - Serial Console + - SD card + - Automounter - LEDs and Buttons - AT24MAC402 Serial EEPROM - Debugging @@ -103,6 +105,131 @@ Any of these options can be selected as the serial console by: 2. Configuring the peripheral in the "Drivers -> Serial Configuration" menu. +SD Card +======= + +Card Slot +--------- +The SAM V71 Xplained Ultra has one standard SD card connector which is +connected to the High Speed Multimedia Card Interface (HSMCI) of the SAM +V71. SD card connector: + + ------ ----------------- --------------------- + SAMV71 SAMV71 Shared functionality + Pin Function + ------ ----------------- --------------------- + PA30 MCDA0 (DAT0) + PA31 MCDA1 (DAT1) + PA26 MCDA2 (DAT2) + PA27 MCDA3 (DAT3) Camera + PA25 MCCK (CLK) Shield + PA28 MCCDA (CMD) + PD18 Card Detect (C/D) Shield + ------ ----------------- --------------------- + +Configuration Settings +---------------------- +Enabling HSMCI support. The SAMV7-XULT provides a one, full-size SD memory card slots. The full size SD card slot connects via HSMCI0. Support for the SD slots can be enabled with the following settings: + + System Type->SAMV7 Peripheral Selection + CONFIG_SAMV7_HSMCI0=y : To enable HSMCI0 support + CONFIG_SAMV7_XDMAC=y : XDMAC is needed by HSMCI0/1 + + System Type + CONFIG_SAMV7_PIO_IRQ=y : PIO interrupts needed + CONFIG_SAMV7_PIOD_IRQ=y : Card detect pin is on PD18 + + Device Drivers -> MMC/SD Driver Support + CONFIG_MMCSD=y : Enable MMC/SD support + CONFIG_MMSCD_NSLOTS=1 : One slot per driver instance + CONFIG_MMCSD_MULTIBLOCK_DISABLE=y : (REVISIT) + CONFIG_MMCSD_HAVECARDDETECT=y : Supports card-detect PIOs + CONFIG_MMCSD_MMCSUPPORT=n : Interferes with some SD cards + CONFIG_MMCSD_SPI=n : No SPI-based MMC/SD support + CONFIG_MMCSD_SDIO=y : SDIO-based MMC/SD support + CONFIG_SDIO_DMA=y : Use SDIO DMA + CONFIG_SDIO_BLOCKSETUP=y : Needs to know block sizes + + RTOS Features -> Work Queue Support + CONFIG_SCHED_WORKQUEUE=y : Driver needs work queue support + + Application Configuration -> NSH Library + CONFIG_NSH_ARCHINIT=y : NSH board-initialization, OR + CONFIG_BOARD_INITIALIZE=y + +Using the SD card +----------------- + +1) After booting, the HSCMI device will appear as /dev/mmcsd0. + +2) If you try mounting an SD card with nothing in the slot, the mount will + fail: + + nsh> mount -t vfat /dev/mmcsd0 /mnt/sd0 + nsh: mount: mount failed: 19 + + NSH can be configured to provide errors as strings instead of + numbers. But in this case, only the error number is reported. The + error numbers can be found in nuttx/include/errno.h: + + #define ENODEV 19 + #define ENODEV_STR "No such device" + + So the mount command is saying that there is no device or, more + correctly, that there is no card in the SD card slot. + +3) Inserted the SD card. Then the mount should succeed. + + nsh> mount -t vfat /dev/mmcsd0 /mnt/sd0 + nsh> ls /mnt/sd1 + /mnt/sd1: + atest.txt + nsh> cat /mnt/sd1/atest.txt + This is a test + + NOTE: See the next section entitled "Auto-Mounter" for another way + to mount your SD card. + +4) Before removing the card, you must umount the file system. This is + equivalent to "ejecting" or "safely removing" the card on Windows: It + flushes any cached data to an SD card and makes the SD card unavailable + to the applications. + + nsh> umount -t /mnt/sd0 + + It is now safe to remove the card. NuttX provides into callbacks + that can be used by an application to automatically unmount the + volume when it is removed. But those callbacks are not used in + these configurations. + +Auto-Mounter +============ + + NuttX implements an auto-mounter than can make working with SD cards + easier. With the auto-mounter, the file system will be automatically + mounted when the SD card is inserted into the HSMCI slot and automatically + unmounted when the SD card is removed. + + Here is a sample configuration for the auto-mounter: + + File System Configuration + CONFIG_FS_AUTOMOUNTER=y + + Board-Specific Options + CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT=y + CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_FSTYPE="vfat" + CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_BLKDEV="/dev/mmcsd0" + CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_MOUNTPOINT="/mnt/sdcard" + CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_DDELAY=1000 + CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_UDELAY=2000 + + WARNING: SD cards should never be removed without first unmounting + them. This is to avoid data and possible corruption of the file + system. Certainly this is the case if you are writing to the SD card + at the time of the removal. If you use the SD card for read-only access, + however, then I cannot think of any reason why removing the card without + mounting would be harmful. + LEDs and Buttons ================ diff --git a/configs/samv71-xult/nsh/defconfig b/configs/samv71-xult/nsh/defconfig index addc073473..65d70434bd 100644 --- a/configs/samv71-xult/nsh/defconfig +++ b/configs/samv71-xult/nsh/defconfig @@ -156,13 +156,15 @@ CONFIG_ARCH_CHIP_SAMV71Q=y CONFIG_SAMV7_HAVE_CAN1=y CONFIG_SAMV7_HAVE_DAC1=y CONFIG_SAMV7_HAVE_EBI=y -CONFIG_SAMV7_HAVE_HSMCI=y +# CONFIG_SAMV7_HSMCI is not set +CONFIG_SAMV7_HAVE_HSMCI0=y # CONFIG_SAMV7_HAVE_ISI8 is not set CONFIG_SAMV7_HAVE_SDRAMC=y # CONFIG_SAMV7_HAVE_SPI is not set CONFIG_SAMV7_HAVE_SPI0=y CONFIG_SAMV7_HAVE_SPI1=y # CONFIG_SAMV7_QSPI_IS_SPI is not set +# CONFIG_SAMV7_SSC is not set CONFIG_SAMV7_HAVE_TWIHS2=y # CONFIG_SAMV7_HAVE_USBFS is not set CONFIG_SAMV7_HAVE_USBHS=y @@ -184,7 +186,7 @@ CONFIG_SAMV7_HAVE_USART2=y # CONFIG_SAMV7_EBI is not set # CONFIG_SAMV7_EMAC is not set # CONFIG_SAMV7_XDMAC is not set -# CONFIG_SAMV7_HSMCI is not set +# CONFIG_SAMV7_HSMCI0 is not set # CONFIG_SAMV7_ISI is not set # CONFIG_SAMV7_MLB is not set # CONFIG_SAMV7_PWM0 is not set @@ -196,7 +198,7 @@ CONFIG_SAMV7_HAVE_USART2=y # CONFIG_SAMV7_SMC is not set # CONFIG_SAMV7_SPI0 is not set # CONFIG_SAMV7_SPI1 is not set -# CONFIG_SAMV7_SSC is not set +# CONFIG_SAMV7_SSC0 is not set # CONFIG_SAMV7_TC0 is not set # CONFIG_SAMV7_TC1 is not set # CONFIG_SAMV7_TC2 is not set diff --git a/configs/samv71-xult/src/Makefile b/configs/samv71-xult/src/Makefile index d8f3606cb5..3942c6b0b5 100644 --- a/configs/samv71-xult/src/Makefile +++ b/configs/samv71-xult/src/Makefile @@ -42,6 +42,12 @@ AOBJS = $(ASRCS:.S=$(OBJEXT)) CSRCS = sam_boot.c +ifeq ($(CONFIG_NSH_ARCHINIT),y) +CSRCS += sam_nsh.c sam_bringup.c +else ifeq ($(CONFIG_BOARD_INITIALIZE),y) +CSRCS += sam_bringup.c +endif + ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y) CSRCS += sam_cxxinitialize.c endif @@ -56,19 +62,15 @@ ifeq ($(CONFIG_ARCH_BUTTONS),y) CSRCS += sam_buttons.c endif -ifeq ($(CONFIG_NSH_ARCHINIT),y) -CSRCS += sam_nsh.c -endif - -ifeq ($(CONFIG_SAM34_HSMCI),y) +ifeq ($(CONFIG_SAMV7_HSMCI0),y) CSRCS += sam_hsmci.c endif -ifeq ($(CONFIG_SAM34_EMAC),y) +ifeq ($(CONFIG_SAMV7_EMAC),y) CSRCS += sam_ethernet.c endif -ifeq ($(CONFIG_SAM34_SPI0),y) +ifeq ($(CONFIG_SAMV7_SPI0),y) CSRCS += sam_spi.c endif diff --git a/configs/samv71-xult/src/sam_boot.c b/configs/samv71-xult/src/sam_boot.c index 7a08efd491..58025e0a6d 100644 --- a/configs/samv71-xult/src/sam_boot.c +++ b/configs/samv71-xult/src/sam_boot.c @@ -117,13 +117,8 @@ void sam_boardinitialize(void) #ifdef CONFIG_BOARD_INITIALIZE void board_initialize(void) { - /* Perform NSH initialization here instead of from the NSH. This - * alternative NSH initialization is necessary when NSH is ran in user-space - * but the initialization function must run in kernel space. - */ + /* Perform board initialization */ -#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_NSH_ARCHINIT) - (void)nsh_archinitialize(); -#endif + (void)sam_bringup(); } #endif /* CONFIG_BOARD_INITIALIZE */ diff --git a/configs/samv71-xult/src/sam_bringup.c b/configs/samv71-xult/src/sam_bringup.c new file mode 100644 index 0000000000..50ae3951dd --- /dev/null +++ b/configs/samv71-xult/src/sam_bringup.c @@ -0,0 +1,222 @@ +/**************************************************************************** + * config/samv71-xult/src/sam_bringup.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SYSTEM_USBMONITOR +# include +#endif + +#include +#include + +#include "samv71-xult.h" + +#ifdef HAVE_ROMFS +# include +#endif + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +#define NSECTORS(n) \ + (((n)+CONFIG_SAMV7XULT_ROMFS_ROMDISK_SECTSIZE-1) / \ + CONFIG_SAMV7XULT_ROMFS_ROMDISK_SECTSIZE) + +/* Debug ********************************************************************/ + +#ifdef CONFIG_BOARD_INITIALIZE +# define SYSLOG lldbg +#else +# define SYSLOG dbg +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_bringup + * + * Description: + * Bring up board features + * + ****************************************************************************/ + +int sam_bringup(void) +{ +#if defined(HAVE_HSMCI) || defined(HAVE_USBHOST) || defined(HAVE_USBMONITOR) || \ + defined(HAVE_WM8904) || defined(HAVE_AUTOMOUNTER) || defined(HAVE_ELF) || \ + defined(HAVE_ROMFS) + int ret; +#endif + +#ifdef HAVE_HSMCI +#ifdef CONFIG_SAMV7_HSMCI0 + /* Initialize the HSMCI0 driver */ + + ret = sam_hsmci_initialize(HSMCI0_SLOTNO, HSMCI0_MINOR); + if (ret < 0) + { + SYSLOG("ERROR: sam_hsmci_initialize(%d,%d) failed: %d\n", + HSMCI0_SLOTNO, HSMCI0_MINOR, ret); + } + +#ifdef CONFIG_SAMV7XULT_HSMCI0_MOUNT + else + { + /* REVISIT: A delay seems to be required here or the mount will fail. */ + /* Mount the volume on HSMCI0 */ + + ret = mount(CONFIG_SAMV7XULT_HSMCI0_MOUNT_BLKDEV, + CONFIG_SAMV7XULT_HSMCI0_MOUNT_MOUNTPOINT, + CONFIG_SAMV7XULT_HSMCI0_MOUNT_FSTYPE, + 0, NULL); + + if (ret < 0) + { + SYSLOG("ERROR: Failed to mount %s: %d\n", + CONFIG_SAMV7XULT_HSMCI0_MOUNT_MOUNTPOINT, errno); + } + } + +#endif /* CONFIG_SAMV7XULT_HSMCI0_MOUNT */ +#endif /* CONFIG_SAMV7_HSMCI0 */ +#endif /* HAVE_HSMCI */ + +#ifdef HAVE_AUTOMOUNTER + /* Initialize the auto-mounter */ + + sam_automount_initialize(); +#endif + +#ifdef HAVE_ROMFS + /* Create a ROM disk for the /etc filesystem */ + + ret = romdisk_register(CONFIG_SAMV7XULT_ROMFS_ROMDISK_MINOR, romfs_img, + NSECTORS(romfs_img_len), + CONFIG_SAMV7XULT_ROMFS_ROMDISK_SECTSIZE); + if (ret < 0) + { + SYSLOG("ERROR: romdisk_register failed: %d\n", -ret); + } + else + { + /* Mount the file system */ + + ret = mount(CONFIG_SAMV7XULT_ROMFS_ROMDISK_DEVNAME, + CONFIG_SAMV7XULT_ROMFS_MOUNT_MOUNTPOINT, + "romfs", MS_RDONLY, NULL); + if (ret < 0) + { + SYSLOG("ERROR: mount(%s,%s,romfs) failed: %d\n", + CONFIG_SAMV7XULT_ROMFS_ROMDISK_DEVNAME, + CONFIG_SAMV7XULT_ROMFS_MOUNT_MOUNTPOINT, errno); + } + } +#endif + +#ifdef HAVE_USBHOST + /* Initialize USB host operation. sam_usbhost_initialize() starts a thread + * will monitor for USB connection and disconnection events. + */ + + ret = sam_usbhost_initialize(); + if (ret != OK) + { + SYSLOG("ERROR: Failed to initialize USB host: %d\n", ret); + } +#endif + +#ifdef HAVE_USBMONITOR + /* Start the USB Monitor */ + + ret = usbmonitor_start(0, NULL); + if (ret != OK) + { + SYSLOG("ERROR: Failed to start the USB monitor: %d\n", ret); + } +#endif + +#ifdef HAVE_WM8904 + /* Configure WM8904 audio */ + + ret = sam_wm8904_initialize(0); + if (ret != OK) + { + SYSLOG("ERROR: Failed to initialize WM8904 audio: %d\n", ret); + } +#endif + +#ifdef HAVE_AUDIO_NULL + /* Configure the NULL audio device */ + + ret = sam_audio_null_initialize(0); + if (ret != OK) + { + SYSLOG("ERROR: Failed to initialize the NULL audio device: %d\n", ret); + } +#endif + +#ifdef HAVE_ELF + /* Initialize the ELF binary loader */ + + SYSLOG("Initializing the ELF binary loader\n"); + ret = elf_initialize(); + if (ret < 0) + { + SYSLOG("ERROR: Initialization of the ELF loader failed: %d\n", ret); + } +#endif + + /* If we got here then perhaps not all initialization was successful, but + * at least enough succeeded to bring-up NSH with perhaps reduced + * capabilities. + */ + + return OK; +} diff --git a/configs/samv71-xult/src/sam_hsmci.c b/configs/samv71-xult/src/sam_hsmci.c new file mode 100644 index 0000000000..856d18c6bf --- /dev/null +++ b/configs/samv71-xult/src/sam_hsmci.c @@ -0,0 +1,320 @@ +/**************************************************************************** + * config/samv71-xult/src/sam_hsmci.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/* The SAM V71 Xplained Ultra has one standard SD card connector which is + * connected to the High Speed Multimedia Card Interface (HSMCI) of the SAM + * V71. SD card connector: + * + * ------ ----------------- --------------------- + * SAMV71 SAMV71 Shared functionality + * Pin Function + * ------ ----------------- --------------------- + * PA30 MCDA0 (DAT0) + * PA31 MCDA1 (DAT1) + * PA26 MCDA2 (DAT2) + * PA27 MCDA3 (DAT3) Camera + * PA25 MCCK (CLK) Shield + * PA28 MCCDA (CMD) + * PD18 Card Detect (C/D) Shield + * ------ ----------------- --------------------- + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "sam_gpio.h" +#include "sam_hsmci.h" + +#include "samv71-xult.h" + +#ifdef HAVE_HSMCI + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This structure holds static information unique to one HSMCI peripheral */ + +struct sam_hsmci_state_s +{ + struct sdio_dev_s *hsmci; /* R/W device handle */ + gpio_pinset_t cdcfg; /* Card detect PIO pin configuration */ + gpio_pinset_t pwrcfg; /* Power PIO pin configuration */ + uint8_t irq; /* Interrupt number (same as pid) */ + uint8_t slotno; /* Slot number */ + bool cd; /* TRUE: card is inserted */ + xcpt_t handler; /* Interrupt handler */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* HSCMI device state */ + +#ifdef CONFIG_SAMV7_HSMCI0 +static int sam_hsmci0_cardetect(int irq, void *regs); + +static struct sam_hsmci_state_s g_hsmci0 = +{ + .cdcfg = GPIO_MCI0_CD, + .irq = IRQ_MCI0_CD, + .slotno = 0, + .handler = sam_hsmci0_cardetect, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_cardinserted_internal + * + * Description: + * Check if a card is inserted into the selected HSMCI slot + * + ****************************************************************************/ + +bool sam_cardinserted_internal(struct sam_hsmci_state_s *state) +{ + bool inserted; + + /* Get the state of the PIO pin */ + + inserted = sam_gpioread(state->cdcfg); + fllvdbg("Slot %d inserted: %s\n", state->slotno, inserted ? "NO" : "YES"); + return !inserted; +} + +/**************************************************************************** + * Name: sam_hsmci_cardetect, sam_hsmci0_cardetect, and sam_hsmci1_cardetect + * + * Description: + * Card detect interrupt handlers + * + ****************************************************************************/ + +static int sam_hsmci_cardetect(struct sam_hsmci_state_s *state) +{ + /* Get the current card insertion state */ + + bool cd = sam_cardinserted_internal(state); + + /* Has the card detect state changed? */ + + if (cd != state->cd) + { + /* Yes... remember that new state and inform the HSMCI driver */ + + state->cd = cd; + + /* Report the new state to the SDIO driver */ + + sdio_mediachange(state->hsmci, cd); + } + + return OK; +} + +#ifdef CONFIG_SAMV7_HSMCI0 +static int sam_hsmci0_cardetect(int irq, void *regs) +{ + int ret; + + /* Handle the card detect interrupt. The interrupt level logic will + * kick of the driver-level operations to initialize the MMC/SD block + * device. + */ + + ret = sam_hsmci_cardetect(&g_hsmci0); + +#ifdef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT + /* Let the automounter know about the insertion event */ + + sam_automount_event(HSMCI0_SLOTNO, sam_cardinserted(HSMCI0_SLOTNO)); +#endif + + return ret; +} +#endif + +/**************************************************************************** + * Name: sam_hsmci_state + * + * Description: + * Initialize HSMCI PIOs. + * + ****************************************************************************/ + +static inline struct sam_hsmci_state_s *sam_hsmci_state(int slotno) +{ + struct sam_hsmci_state_s *state = NULL; + +#ifdef CONFIG_SAMV7_HSMCI0 + state = &g_hsmci0; +#endif + + return state; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_hsmci_initialize + * + * Description: + * Perform architecture specific initialization + * + ****************************************************************************/ + +int sam_hsmci_initialize(int slotno, int minor) +{ + struct sam_hsmci_state_s *state; + int ret; + + /* Get the static HSMI description */ + + state = sam_hsmci_state(slotno); + if (!state) + { + fdbg("ERROR: No state for slotno %d\n", slotno); + return -EINVAL; + } + + /* Initialize card-detect, write-protect, and power enable PIOs */ + + sam_configgpio(state->cdcfg); + sam_dumpgpio(state->cdcfg, "HSMCI Card Detect"); + + if (state->pwrcfg != 0) + { + sam_configgpio(state->pwrcfg); + sam_dumpgpio(state->pwrcfg, "HSMCI Power"); + } + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + state->hsmci = sdio_initialize(slotno); + if (!state->hsmci) + { + fdbg("ERROR: Failed to initialize SDIO slot %d\n", slotno); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + ret = mmcsd_slotinitialize(minor, state->hsmci); + if (ret != OK) + { + fdbg("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + /* Configure card detect interrupts */ + + sam_gpioirq(state->cdcfg); + (void)irq_attach(state->irq, state->handler); + + /* Then inform the HSMCI driver if there is or is not a card in the slot. */ + + state->cd = sam_cardinserted_internal(state); + sdio_mediachange(state->hsmci, state->cd); + + /* Enable card detect interrupts */ + + sam_gpioirqenable(state->irq); + return OK; +} + +/**************************************************************************** + * Name: sam_cardinserted + * + * Description: + * Check if a card is inserted into the selected HSMCI slot + * + ****************************************************************************/ + +bool sam_cardinserted(int slotno) +{ + struct sam_hsmci_state_s *state; + + /* Get the HSMI description */ + + state = sam_hsmci_state(slotno); + if (!state) + { + fdbg("ERROR: No state for slotno %d\n", slotno); + return false; + } + + /* Return the state of the PIO pin */ + + return sam_cardinserted_internal(state); +} + +/**************************************************************************** + * Name: sam_writeprotected + * + * Description: + * Check if a card is inserted into the selected HSMCI slot + * + ****************************************************************************/ + +bool sam_writeprotected(int slotno) +{ + /* There are no write protect pins */ + + return false; +} + +#endif /* HAVE_HSMCI */ diff --git a/configs/samv71-xult/src/sam_nsh.c b/configs/samv71-xult/src/sam_nsh.c new file mode 100644 index 0000000000..c618200d6e --- /dev/null +++ b/configs/samv71-xult/src/sam_nsh.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * config/samv71-xult/src/sam_nsh.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "samv71-xult.h" + +#if defined(CONFIG_NSH_ARCHINIT) && !defined(CONFIG_BUILD_KERNEL) + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_archinitialize + * + * Description: + * Perform architecture specific initialization + * + ****************************************************************************/ + +int nsh_archinitialize(void) +{ +#ifndef CONFIG_BOARD_INITIALIZE + /* Perform board initialization */ + + return sam_bringup(); +#else + return OK; +#endif +} + +#endif /* CONFIG_NSH_ARCHINIT && !CONFIG_BUILD_KERNEL */ diff --git a/configs/samv71-xult/src/samv71-xult.h b/configs/samv71-xult/src/samv71-xult.h index f1eafba7dd..d69b199309 100644 --- a/configs/samv71-xult/src/samv71-xult.h +++ b/configs/samv71-xult/src/samv71-xult.h @@ -44,26 +44,26 @@ #include #include +#include #include #include -//#include "chip/sam_pinmap.h" - /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ /* Configuration ********************************************************************/ -#define HAVE_HSMCI 1 -#define HAVE_USBDEV 1 -#define HAVE_USBMONITOR 1 -#define HAVE_NETWORK 1 +#define HAVE_HSMCI 1 +#define HAVE_AUTOMOUNTER 1 +#define HAVE_USBDEV 1 +#define HAVE_USBMONITOR 1 +#define HAVE_NETWORK 1 /* HSMCI */ /* Can't support MMC/SD if the card interface is not enabled */ -#if !defined(CONFIG_SAMV7_HSMCI) +#if !defined(CONFIG_SAMV7_HSMCI0) # undef HAVE_HSMCI #endif @@ -74,13 +74,69 @@ # undef HAVE_HSMCI #endif -/* We need PIO interrupts on GPIOA to support card detect interrupts */ +/* We need PIO interrupts on GPIOD to support card detect interrupts */ -#if defined(HAVE_HSMCI) && !defined(CONFIG_SAMV7_GPIOA_IRQ) -# warning PIOA interrupts not enabled. No MMC/SD support. +#if defined(HAVE_HSMCI) && !defined(CONFIG_SAMV7_GPIOD_IRQ) +# warning PIOD interrupts not enabled. No MMC/SD support. # undef HAVE_HSMCI #endif +/* MMC/SD minor numbers */ + +#ifndef CONFIG_NSH_MMCSDMINOR +# define CONFIG_NSH_MMCSDMINOR 0 +#endif + +#ifndef CONFIG_NSH_MMCSDMINOR +# define CONFIG_NSH_MMCSDSLOTNO 0 +#endif + +#if CONFIG_NSH_MMCSDMINOR != 0 +# error SAMV71 has only one MMC/SD slot (CONFIG_NSH_MMCSDMINOR) +# undef CONFIG_NSH_MMCSDSLOTNO +# define CONFIG_NSH_MMCSDSLOTNO 0 +#endif + +#define HSMCI0_SLOTNO CONFIG_NSH_MMCSDSLOTNO +#define HSMCI0_MINOR CONFIG_NSH_MMCSDMINOR + +/* Automounter. Currently only works with HSMCI. */ + +#if !defined(CONFIG_FS_AUTOMOUNTER) || !defined(HAVE_HSMCI) +# undef HAVE_AUTOMOUNTER +# undef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT +#endif + +#ifndef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT +# undef HAVE_AUTOMOUNTER +#endif + +#ifdef HAVE_AUTOMOUNTER +# ifdef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT + /* HSMCI0 Automounter defaults */ + +# ifndef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_FSTYPE +# define CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_FSTYPE "vfat" +# endif + +# ifndef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_BLKDEV +# define CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_BLKDEV "/dev/mmcds0" +# endif + +# ifndef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_MOUNTPOINT +# define CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_MOUNTPOINT "/mnt/sdcard0" +# endif + +# ifndef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_DDELAY +# define CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_DDELAY 1000 +# endif + +# ifndef CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_UDELAY +# define CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT_UDELAY 2000 +# endif +# endif /* CONFIG_SAMV7XULT_HSMCI0_AUTOMOUNT */ +#endif /* HAVE_AUTOMOUNTER */ + /* USB Device */ /* CONFIG_SAMV7_UDP and CONFIG_USBDEV must be defined, or there is no USB * device. @@ -171,9 +227,29 @@ #define IRQ_SW1 SAM_IRQ_PB12 /* HSMCI SD Card Detect - * To be provided + * + * The SAM V71 Xplained Ultra has one standard SD card connector which is + * connected to the High Speed Multimedia Card Interface (HSMCI) of the SAM + * V71. SD card connector: + * + * ------ ----------------- --------------------- + * SAMV71 SAMV71 Shared functionality + * Pin Function + * ------ ----------------- --------------------- + * PA30 MCDA0 (DAT0) + * PA31 MCDA1 (DAT1) + * PA26 MCDA2 (DAT2) + * PA27 MCDA3 (DAT3) Camera + * PA25 MCCK (CLK) Shield + * PA28 MCCDA (CMD) + * PD18 Card Detect (C/D) Shield + * ------ ----------------- --------------------- */ +#define GPIO_MCI0_CD (GPIO_INPUT | GPIO_CFG_DEFAULT | GPIO_CFG_DEGLITCH | \ + GPIO_INT_BOTHEDGES | GPIO_PORT_PIOD | GPIO_PIN18) +#define IRQ_MCI0_CD SAM_IRQ_PD18 + /* SPI Chip Selects * to be provided */ @@ -192,6 +268,18 @@ * Public Functions ************************************************************************************/ +/************************************************************************************ + * Name: sam_bringup + * + * Description: + * Bring up board features + * + ************************************************************************************/ + +#if defined(CONFIG_NSH_ARCHINIT) || defined(CONFIG_BOARD_INITIALIZE) +int sam_bringup(void); +#endif + /************************************************************************************ * Name: sam_spiinitialize * @@ -211,9 +299,9 @@ void weak_function sam_spiinitialize(void); ************************************************************************************/ #ifdef HAVE_HSMCI -int sam_hsmci_initialize(int minor); +int sam_hsmci_initialize(int slot, int minor); #else -# define sam_hsmci_initialize(minor) (-ENOSYS) +# define sam_hsmci_initialize(s,m) (-ENOSYS) #endif /************************************************************************************ @@ -242,6 +330,64 @@ bool sam_cardinserted(int slotno); # define sam_cardinserted(slotno) (false) #endif +/************************************************************************************ + * Name: sam_writeprotected + * + * Description: + * Check if the card in the MMCSD slot is write protected + * + ************************************************************************************/ + +#ifdef HAVE_HSMCI +bool sam_writeprotected(int slotno); +#endif + +/************************************************************************************ + * Name: sam_automount_initialize + * + * Description: + * Configure auto-mounters for each enable and so configured HSMCI + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef HAVE_AUTOMOUNTER +void sam_automount_initialize(void); +#endif + +/************************************************************************************ + * Name: sam_automount_event + * + * Description: + * The HSMCI card detection logic has detected an insertion or removal event. It + * has already scheduled the MMC/SD block driver operations. Now we need to + * schedule the auto-mount event which will occur with a substantial delay to make + * sure that everything has settle down. + * + * Input Parameters: + * slotno - Identifies the HSMCI0 slot: HSMCI0 or HSMCI1_SLOTNO. There is a + * terminology problem here: Each HSMCI supports two slots, slot A and slot B. + * Only slot A is used. So this is not a really a slot, but an HSCMI peripheral + * number. + * inserted - True if the card is inserted in the slot. False otherwise. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled. + * + ************************************************************************************/ + +#ifdef HAVE_AUTOMOUNTER +void sam_automount_event(int slotno, bool inserted); +#endif + /************************************************************************************ * Name: sam_writeprotected *