summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-03-13 14:07:35 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-03-13 14:07:35 -0600
commitb53a794218211b71b00b2a9167338b52b5f5f185 (patch)
treee42e372765156e531a859b9649b4e3faf51ee7e4
parentee7c9174c33024148562a1125f27e65dbfe7f4ec (diff)
downloadnuttx-b53a794218211b71b00b2a9167338b52b5f5f185.tar.gz
nuttx-b53a794218211b71b00b2a9167338b52b5f5f185.tar.bz2
nuttx-b53a794218211b71b00b2a9167338b52b5f5f185.zip
SAM4E-EK: Add support for the SAM4E-EK AT25 serial flash
-rw-r--r--nuttx/arch/arm/src/sam34/Kconfig6
-rw-r--r--nuttx/arch/arm/src/sam34/sam_spi.c2
-rw-r--r--nuttx/configs/sam4e-ek/Kconfig31
-rw-r--r--nuttx/configs/sam4e-ek/src/Makefile5
-rw-r--r--nuttx/configs/sam4e-ek/src/sam4e-ek.h174
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_at25.c143
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_boot.c34
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_hsmci.c (renamed from nuttx/configs/sam4e-ek/src/sam_mmcsd.c)193
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_nsh.c97
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_spi.c49
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h2
-rw-r--r--nuttx/drivers/mtd/at25.c24
12 files changed, 552 insertions, 208 deletions
diff --git a/nuttx/arch/arm/src/sam34/Kconfig b/nuttx/arch/arm/src/sam34/Kconfig
index 97b73f576..1ec5c9a8a 100644
--- a/nuttx/arch/arm/src/sam34/Kconfig
+++ b/nuttx/arch/arm/src/sam34/Kconfig
@@ -340,7 +340,7 @@ config SAM34_EIC
depends on ARCH_CHIP_SAM4L || ARCH_CHIP_SAM4E
config SAM34_DMAC
- bool "DMA controller"
+ bool "DMA controller (DMAC)"
default n
depends on ARCH_CHIP_SAM3U || ARCH_CHIP_SAM3X || ARCH_CHIP_SAM3A || ARCH_CHIP_SAM4E
select ARCH_DMA
@@ -875,7 +875,7 @@ endmenu # AT91SAM3/4 GPIO Interrupt Configuration
if SAM34_SPI0 || SAM34_SPI1
-menu "SPI device driver options"
+menu "AT91SAM3/4 SPI device driver options"
config SAM34_SPI_DMA
bool "SPI DMA"
@@ -911,7 +911,7 @@ config SAM34_SPI_REGDEBUG
Output detailed register-level SPI device debug information.
Requires also DEBUG.
-endmenu # SPI device driver options
+endmenu # AT91SAM3/4 SPI device driver options
endif # SAM34_SPI0 || SAM34_SPI1
if SAM34_EMAC
diff --git a/nuttx/arch/arm/src/sam34/sam_spi.c b/nuttx/arch/arm/src/sam34/sam_spi.c
index 36e3b6aae..7d020b804 100644
--- a/nuttx/arch/arm/src/sam34/sam_spi.c
+++ b/nuttx/arch/arm/src/sam34/sam_spi.c
@@ -213,7 +213,7 @@ typedef void (*select_t)(enum spi_dev_e devid, bool selected);
struct sam_spidev_s
{
uint32_t base; /* SPI controller register base address */
- sem_t spisem; /* Assures mutually exclusive acess to SPI */
+ sem_t spisem; /* Assures mutually exclusive access to SPI */
select_t select; /* SPI select callout */
bool initialized; /* TRUE: Controller has been initialized */
#ifdef CONFIG_SAM34_SPI_DMA
diff --git a/nuttx/configs/sam4e-ek/Kconfig b/nuttx/configs/sam4e-ek/Kconfig
index d052da007..aebc0f913 100644
--- a/nuttx/configs/sam4e-ek/Kconfig
+++ b/nuttx/configs/sam4e-ek/Kconfig
@@ -16,4 +16,35 @@ config SAM4EEK_120MHZ
bool "120 MHz"
endchoice # CPU Frequency
+
+config SAM4EEK_AT25_AUTOMOUNT
+ bool "AT25 serial FLASH auto-mount"
+ default n
+ depends on NSH_ARCHINIT && SAM34_SPI0 && MTD_AT25
+ ---help---
+ Automatically initialize the AT25 SPI FLASH driver when NSH starts.
+
+choice
+ prompt "AT25 serial FLASH configuration"
+ default SAM4EEK_AT25_FTL
+ depends on SAM4EEK_AT25_AUTOMOUNT
+
+config SAM4EEK_AT25_FTL
+ bool "Create AT25 Serial FLASH block driver"
+ ---help---
+ Create the MTD driver for the AT25 and "wrap" the AT25 as a standard
+ block driver that could then, for example, be mounted using FAT or
+ any other file system. Any file system may be used, but there will
+ be no wear-leveling.
+
+config SAM4EEK_AT25_NXFFS
+ bool "Create AT25 serial FLASH NXFFS file system"
+ depends on FS_NXFFS
+ ---help---
+ Create the MTD driver for the AT25 and mount the AT25 device as
+ a wear-leveling, NuttX FLASH file system (NXFFS). The downside of
+ NXFFS is that it can be very slow.
+
+endchoice # AT25 serial FLASH configuration
+
endif # ARCH_BOARD_SAM4EEK
diff --git a/nuttx/configs/sam4e-ek/src/Makefile b/nuttx/configs/sam4e-ek/src/Makefile
index 975269671..a3b12a7a6 100644
--- a/nuttx/configs/sam4e-ek/src/Makefile
+++ b/nuttx/configs/sam4e-ek/src/Makefile
@@ -55,11 +55,14 @@ CSRCS += sam_nsh.c
endif
ifeq ($(CONFIG_SAM34_HSMCI),y)
-CSRCS += sam_mmcsd.c
+CSRCS += sam_hsmci.c
endif
ifeq ($(CONFIG_SAM34_SPI0),y)
CSRCS += sam_spi.c
+ifeq ($(CONFIG_MTD_AT25),y)
+CSRCS += sam_at25.c
+endif
endif
ifeq ($(CONFIG_USBMSC),y)
diff --git a/nuttx/configs/sam4e-ek/src/sam4e-ek.h b/nuttx/configs/sam4e-ek/src/sam4e-ek.h
index 0e6c29358..cfbda16b4 100644
--- a/nuttx/configs/sam4e-ek/src/sam4e-ek.h
+++ b/nuttx/configs/sam4e-ek/src/sam4e-ek.h
@@ -51,19 +51,77 @@
#include "chip/sam_pinmap.h"
/************************************************************************************
- * Definitions
+ * Pre-processor Definitions
************************************************************************************/
+/* Configuration ********************************************************************/
-/* External Memory Usage ************************************************************/
-/* LCD on CS2 */
+#define HAVE_HSMCI 1
+#define HAVE_AT25 1
-#define LCD_BASE SAM_EXTCS2_BASE
+/* HSMCI */
+/* Can't support MMC/SD if the card interface is not enabled */
+
+#if !defined(CONFIG_SAM34_HSMCI)
+# undef HAVE_HSMCI
+#endif
+
+/* Can't support MMC/SD features if mountpoints are disabled */
+
+#if defined(HAVE_HSMCI) && defined(CONFIG_DISABLE_MOUNTPOINT)
+# warning Mountpoints disabled. No MMC/SD support
+# undef HAVE_HSMCI
+#endif
+
+/* We need PIO interrupts on PIOA to support card detect interrupts */
+
+#if defined(HAVE_HSMCI) && !defined(CONFIG_SAM34_PIOA_IRQ)
+# warning PIOA interrupts not enabled. No MMC/SD support.
+# undef HAVE_HSMCI
+#endif
+
+/* AT25 Serial FLASH */
+/* Can't support the AT25 device if it SPI0 or AT25 support are not enabled */
+
+#if !defined(CONFIG_SAM34_SPI0) || !defined(CONFIG_MTD_AT25)
+# undef HAVE_AT25
+#endif
+
+/* Can't support AT25 features if mountpoints are disabled or if we were not
+ * asked to mount the AT25 part
+ */
+
+#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_SAM4EEK_AT25_AUTOMOUNT)
+# undef HAVE_AT25
+#endif
+
+/* If we are going to mount the AT25, then they user must also have told
+ * us what to do with it by setting one of these.
+ */
+
+#ifndef CONFIG_FS_NXFFS
+# undef CONFIG_SAM4EEK_AT25_NXFFS
+#endif
+
+#if !defined(CONFIG_SAM4EEK_AT25_FTL) && !defined(CONFIG_SAM4EEK_AT25_NXFFS)
+# undef HAVE_AT25
+#endif
+
+#if defined(CONFIG_SAM4EEK_AT25_FTL) && defined(CONFIG_SAM4EEK_AT25_NXFFS)
+# warning Both CONFIG_SAM4EEK_AT25_FTL and CONFIG_SAM4EEK_AT25_NXFFS are set
+# warning Ignoring CONFIG_SAM4EEK_AT25_NXFFS
+# undef CONFIG_SAM4EEK_AT25_NXFFS
+#endif
/* Touchscreen controller (TSC) */
#define CONFIG_TSC_ADS7843 1 /* ADS7843 present on board */
#define CONFIG_TSC_SPI 0 /* On SPI0 */
+/* External Memory Usage ************************************************************/
+/* LCD on CS2 */
+
+#define LCD_BASE SAM_EXTCS2_BASE
+
/* SAM4E-EK GPIO Pin Definitions ****************************************************/
/* LCD:
@@ -167,7 +225,7 @@
* ------ -------
* GPIO PIN
* ------ -------
- * PA11 /CS
+ * PA11 /CS (pulled high)
* PA12 DOUT
* PA13 DIN
* PA14 DCLK
@@ -201,9 +259,9 @@
/* LEDs
*
- * D2 PA0 Blue Pulled high
- * D3 PD20 Amber Pulled high
- * D4 PD21 Green Pulled high
+ * D2 PA0 Blue Pulled high
+ * D3 PD20 Amber Pulled high
+ * D4 PD21 Green Pulled high
*/
#define GPIO_D3 (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_PORT_PIOD | \
@@ -253,13 +311,36 @@
#define GPIO_RS485_ENABLE (GPIO_OUTPUT | GPIO_CFG_DEFAULT | \
GPIO_OUTPUT_SET | GPIO_PORT_PIOA | GPIO_PIN21)
-/* SD Card Detect */
+/* HSMCI SD Card Detect
+ *
+ * PA26 DAT2
+ * PA27 DAT3
+ * PA28 CMD
+ * PA29 CLK
+ * PA30 DAT0
+ * PA31 DAT1
+ * PA6 CD Pulled high
+ */
-#define GPIO_MCI_CD (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN25)
+#define GPIO_MCI_CD (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_PORT_PIOA | GPIO_PIN6)
+#define MCI_CD_IRQ SAM_IRQ_PA6
/* SPI Chip Selects */
-/* Chip select pin connected to the touchscreen controller and to the ZigBee module
+/* Touchscreen Controller:
+ *
+ * ------ -------
+ * GPIO PIN
+ * ------ -------
+ * PA11 /CS (pulled high externally)
+ * PA12 DOUT
+ * PA13 DIN
+ * PA14 DCLK
+ * PA16 /PENIRQ
+ * PA17 BUSY
+ * ------ -------
+ *
+ * Chip select pin connected to the touchscreen controller and to the ZigBee module
* connector. Notice that the touchscreen chip select is implemented as a GPIO
* OUTPUT that must be controlled by board-specific. This is because the ADS7843E
* driver must be able to sample the device BUSY GPIO input between SPI transfers.
@@ -268,10 +349,26 @@
* it low throughout the SPI transfer.
*/
-#define GPIO_TSC_CS (GPIO_OUTPUT | GPIO_CFG_PULLUP | GPIO_OUTPUT_SET | \
+#define GPIO_TSC_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOA | GPIO_PIN11)
#define TSC_CSNUM 0
+/* Serial FLASH (AT25DF321A)
+ *
+ * ------ ------- ---------------
+ * GPIO PIN SAM4E FUNCTION
+ * ------ ------- ---------------
+ * PA13 SI MOSI
+ * PA12 SO MIS0
+ * PA14 SCK SPCK
+ * PA5 /CS NPCS3 (pulled high externally)
+ * ------ ------- ---------------
+ */
+
+#define GPIO_FLASH_CS (GPIO_OUTPUT | GPIO_CFG_DEFAULT | GPIO_OUTPUT_SET | \
+ GPIO_PORT_PIOA | GPIO_PIN5)
+#define FLASH_CSNUM 3
+
/************************************************************************************
* Public Types
************************************************************************************/
@@ -307,53 +404,70 @@ void weak_function sam_spiinitialize(void);
void weak_function sam_usbinitialize(void);
/************************************************************************************
- * Name: sam_hsmciinit
+ * Name: sam_hsmci_initialize
*
* Description:
* Initialize HSMCI support
*
************************************************************************************/
-#ifdef CONFIG_SAM34_HSMCI
-int weak_function sam_hsmciinit(void);
+#ifdef HAVE_HSMCI
+int weak_function sam_hsmci_initialize(void);
#else
-# define sam_hsmciinit()
+# define sam_hsmci_initialize()
#endif
/************************************************************************************
- * Name: board_led_initialize
+ * Name: sam_cardinserted
+ *
+ * Description:
+ * Check if a card is inserted into the selected HSMCI slot
+ *
************************************************************************************/
-#ifdef CONFIG_ARCH_LEDS
-void board_led_initialize(void);
+#ifdef HAVE_HSMCI
+bool sam_cardinserted(int slotno);
+#else
+# define sam_cardinserted(slotno) (false)
#endif
/************************************************************************************
- * Name: sam_cardinserted
+ * Name: sam_writeprotected
*
* Description:
- * Check if a card is inserted into the selected HSMCI slot
+ * Check if the card in the MMCSD slot is write protected
*
************************************************************************************/
-#ifdef CONFIG_SAM34_HSMCI
-bool sam_cardinserted(unsigned char slot);
+#ifdef HAVE_HSMCI
+bool sam_writeprotected(int slotno);
#else
-# define sam_cardinserted(slot) (false)
+# define sam_writeprotected(slotno) (false)
#endif
-/************************************************************************************
- * Name: sam_writeprotected
+/****************************************************************************
+ * Name: sam_at25_automount
*
* Description:
- * Check if a card is inserted into the selected HSMCI slot
+ * Initialize, configure, and mount the AT25 serial FLASH. The FLASH will
+ * be mounted at /dev/at25.
*
+ ****************************************************************************/
+
+#ifdef HAVE_AT25
+int sam_at25_automount(int minor);
+#else
+# define sam_at25_automount(minor) (-ENOSYS)
+#endif
+
+/************************************************************************************
+ * Name: board_led_initialize
************************************************************************************/
-#ifdef CONFIG_SAM34_HSMCI
-bool sam_writeprotected(unsigned char slot);
+#ifdef CONFIG_ARCH_LEDS
+void board_led_initialize(void);
#else
-# define sam_writeprotected(slot) (false)
+# define board_led_initialize()
#endif
#endif /* __ASSEMBLY__ */
diff --git a/nuttx/configs/sam4e-ek/src/sam_at25.c b/nuttx/configs/sam4e-ek/src/sam_at25.c
new file mode 100644
index 000000000..747f40e7b
--- /dev/null
+++ b/nuttx/configs/sam4e-ek/src/sam_at25.c
@@ -0,0 +1,143 @@
+/****************************************************************************
+ * config/sam4e-ek/src/sam_at25.c
+ *
+ * Copyright (C) 2014 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/mount.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/spi/spi.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/fs/nxffs.h>
+
+#include "sam_spi.h"
+#include "sam4e-ek.h"
+
+#ifdef HAVE_AT25
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_at25_automount
+ *
+ * Description:
+ * Initialize, configure, and mount the AT25 serial FLASH. The FLASH will
+ * be mounted at /dev/at25.
+ *
+ ****************************************************************************/
+
+int sam_at25_automount(int minor)
+{
+ FAR struct spi_dev_s *spi;
+ FAR struct mtd_dev_s *mtd;
+ static bool initialized = false;
+ int ret;
+
+ /* Have we already initialized? */
+
+ if (!initialized)
+ {
+ /* No.. Get the SPI port driver */
+
+ spi = up_spiinitialize(FLASH_CSNUM);
+ if (!spi)
+ {
+ fdbg("ERROR: Failed to initialize SPI port %d\n", FLASH_CSNUM);
+ return -ENODEV;
+ }
+
+ /* Now bind the SPI interface to the AT25 SPI FLASH driver */
+
+ mtd = at25_initialize(spi);
+ if (!mtd)
+ {
+ fdbg("ERROR: Failed to bind SPI port %d to the AT25 FLASH driver\n");
+ return -ENODEV;
+ }
+
+#if defined(CONFIG_SAM4EEK_AT25_FTL)
+ /* And finally, use the FTL layer to wrap the MTD driver as a block
+ * driver at /dev/mtdblockN, where N=minor device number.
+ */
+
+ ret = ftl_initialize(minor, mtd);
+ if (ret < 0)
+ {
+ fdbg("ERROR: Failed to initialize the FTL layer: %d\n", ret);
+ return ret;
+ }
+
+#elif defined(CONFIG_SAM4EEK_AT25_NXFFS)
+ /* Initialize to provide NXFFS on the MTD interface */
+
+ ret = nxffs_initialize(mtd);
+ if (ret < 0)
+ {
+ fdbg("ERROR: NXFFS initialization failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Mount the file system at /mnt/at25 */
+
+ ret = mount(NULL, "/mnt/at25", "nxffs", 0, NULL);
+ if (ret < 0)
+ {
+ fdbg("ERROR: Failed to mount the NXFFS volume: %d\n", errno);
+ return ret;
+ }
+#endif
+ /* Now we are initialized */
+
+ initialized = true;
+ }
+
+ return OK;
+}
+
+#endif /* HAVE_AT25 */
diff --git a/nuttx/configs/sam4e-ek/src/sam_boot.c b/nuttx/configs/sam4e-ek/src/sam_boot.c
index 5f6216366..05279200f 100644
--- a/nuttx/configs/sam4e-ek/src/sam_boot.c
+++ b/nuttx/configs/sam4e-ek/src/sam_boot.c
@@ -115,7 +115,7 @@ void sam_boardinitialize(void)
* into the build.
*/
-#if defined(CONFIG_USBDEV) && defined(CONFIG_SAM34_USB)
+#if defined(CONFIG_USBDEV) && defined(CONFIG_SAM34_UDP)
if (sam_usbinitialize)
{
sam_usbinitialize();
@@ -127,15 +127,31 @@ void sam_boardinitialize(void)
#ifdef CONFIG_ARCH_LEDS
board_led_initialize();
#endif
+}
- /* Setup SD card-related PIOs if 1) HSMCI is selected and 2) the weak
- * function sam_hsmciinit() has been brought into the build.
- */
+/****************************************************************************
+ * Name: board_initialize
+ *
+ * Description:
+ * If CONFIG_BOARD_INITIALIZE is selected, then an additional
+ * initialization call will be performed in the boot-up sequence to a
+ * function called board_initialize(). board_initialize() will be
+ * called immediately after up_intiialize() is called and just before the
+ * initial application is started. This additional initialization phase
+ * may be used, for example, to initialize board-specific device drivers.
+ *
+ ****************************************************************************/
-#ifdef CONFIG_SAM34_HSMCI
- if (sam_hsmciinit)
- {
- sam_hsmciinit();
- }
+#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.
+ */
+
+#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_NSH_ARCHINIT)
+ (void)nsh_archinitialize();
#endif
}
+#endif /* CONFIG_BOARD_INITIALIZE */
diff --git a/nuttx/configs/sam4e-ek/src/sam_mmcsd.c b/nuttx/configs/sam4e-ek/src/sam_hsmci.c
index a9cc11ac3..fe4858e3e 100644
--- a/nuttx/configs/sam4e-ek/src/sam_mmcsd.c
+++ b/nuttx/configs/sam4e-ek/src/sam_hsmci.c
@@ -1,5 +1,5 @@
-/************************************************************************************
- * configs/sam4e-ek/src/sam_mmcsd.c
+/****************************************************************************
+ * config/sam4e-ek/src/sam_hsmci.c
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -31,119 +31,176 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Included Files
- ************************************************************************************/
+ ****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
+#include <stdio.h>
#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/sdio.h>
+#include <nuttx/mmcsd.h>
#include "sam_gpio.h"
+#include "sam_hsmci.h"
+
#include "sam4e-ek.h"
-#ifdef CONFIG_SAM34_HSMCI
+#ifdef HAVE_HSMCI
-/************************************************************************************
- * Definitions
- ************************************************************************************/
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
-/* This needs to be extended. The card detect GPIO must be configured as an interrupt.
- * when the interrupt indicating that a card has been inserted or removed is received,
- * this function must call sio_mediachange() to handle that event. See
- * arch/arm/src/sam34/sam_hsmci.h for more information.
- *
- * Also see the SAMA5D3x-EK implementation of this same logic. The card detect
- * interrupt handling should be a drop-in.
- */
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+/* This structure holds static information unique to one HSMCI peripheral */
-#ifdef GPIO_MCI_CD
-# warning "Card detect interrupt handling needed"
-#endif
+struct sam_hsmci_state_s
+{
+ struct sdio_dev_s *hsmci; /* R/W device handle */
+ bool inserted; /* TRUE: card is inserted */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
-/* Usually defined in NuttX header files */
+/* HSCMI device state */
-#ifndef OK
-# define OK 0
-#endif
+static struct sam_hsmci_state_s g_hsmci;
-/************************************************************************************
+/****************************************************************************
* Private Functions
- ************************************************************************************/
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_hsmci_cardetect
+ *
+ * Description:
+ * Card detect interrupt handler
+ *
+ ****************************************************************************/
+
+static int sam_hsmci_cardetect(int irq, void *regs)
+{
+ bool inserted;
+
+ /* Get the state of the GPIO pin */
-/************************************************************************************
+ inserted = sam_cardinserted(0);
+
+ /* Has the card detect state changed? */
+
+ if (inserted == g_hsmci.inserted)
+ {
+ /* Yes... remember that new state and inform the HSMCI driver */
+
+ g_hsmci.inserted = inserted;
+
+ /* Report the new state to the SDIO driver */
+
+ sdio_mediachange(g_hsmci.hsmci, inserted);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
* Public Functions
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
- * Name: sam_hsmciinit
+/****************************************************************************
+ * Name: sam_hsmci_initialize
*
* Description:
- * Initialize HSMCI support. This function is called very early in board
- * initialization.
+ * Perform architecture specific initialization
*
- ************************************************************************************/
+ ****************************************************************************/
-int sam_hsmciinit(void)
+int sam_hsmci_initialize(int minor)
{
-#ifdef GPIO_MCI_CD
- sam_configgpio(GPIO_MCI_CD);
-#endif
-#ifdef GPIO_MCI_WP
- sam_configgpio(GPIO_MCI_WP);
-#endif
+ int ret;
+
+ /* 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);
+
+ /* Enable card detect interrupts */
+
+ sam_pioirqenable(MCI_CD_IRQ);
return OK;
}
-/************************************************************************************
+/****************************************************************************
* Name: sam_cardinserted
*
* Description:
* Check if a card is inserted into the selected HSMCI slot
*
- ************************************************************************************/
+ ****************************************************************************/
-bool sam_cardinserted(unsigned char slot)
+bool sam_cardinserted(int slotno)
{
- if (slot == 0)
- {
-#ifdef GPIO_MCI_CD
- bool inserted = sam_gpioread(GPIO_MCI_CD);
- fvdbg("inserted: %s\n", inserted ? "NO" : "YES");
- return !inserted;
-#else
- return true;
-#endif
- }
+ bool removed;
- return false;
+ /* Get the state of the GPIO pin */
+
+ removed = sam_pioread(GPIO_MCI_CD);
+ fllvdbg("Slot %d inserted: %s\n", slotno, removed ? "NO" : "YES");
+
+ return !removed;
}
-/************************************************************************************
+/****************************************************************************
* Name: sam_writeprotected
*
* Description:
* Check if a card is inserted into the selected HSMCI slot
*
- ************************************************************************************/
+ ****************************************************************************/
-bool sam_writeprotected(unsigned char slot)
+bool sam_writeprotected(int slotno)
{
- if (slot == 0)
- {
-#ifdef GPIO_MCI_WP
- bool protected = sam_gpioread(GPIO_MCI_WP);
- fvdbg("protected: %s\n", inserted ? "YES" : "NO");
- return protected;
-#else
- return false;
-#endif
- }
+ /* There are no write protect pins */
return false;
}
-#endif /* CONFIG_SAM34_HSMCI */
+#endif /* HAVE_HSMCI */
diff --git a/nuttx/configs/sam4e-ek/src/sam_nsh.c b/nuttx/configs/sam4e-ek/src/sam_nsh.c
index 43cdd21f7..7d47ca334 100644
--- a/nuttx/configs/sam4e-ek/src/sam_nsh.c
+++ b/nuttx/configs/sam4e-ek/src/sam_nsh.c
@@ -39,63 +39,23 @@
#include <nuttx/config.h>
+#include <sys/mount.h>
+
#include <stdbool.h>
#include <stdio.h>
-#include <debug.h>
#include <errno.h>
+#include <debug.h>
-#include <nuttx/sdio.h>
-#include <nuttx/mmcsd.h>
+#ifdef CONFIG_SYSTEM_USBMONITOR
+# include <apps/usbmonitor.h>
+#endif
-#include "sam_hsmci.h"
#include "sam4e-ek.h"
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
-/* Configuration ************************************************************/
-
-/* PORT and SLOT number probably depend on the board configuration */
-
-#define NSH_HAVE_USBDEV 1
-#define NSH_HAVE_MMCSD 1
-
-/* Can't support MMC/SD if the card interface is not enable */
-
-#ifndef CONFIG_SAM34_HSMCI
-# undef NSH_HAVE_MMCSD
-#endif
-
-/* Can't support MMC/SD features if mountpoints are disabled or if SDIO support
- * is not enabled.
- */
-
-#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_SAM34_HSMCI)
-# undef NSH_HAVE_MMCSD
-#endif
-
-#ifdef NSH_HAVE_MMCSD
-# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0
-# error "Only one MMC/SD slot"
-# undef CONFIG_NSH_MMCSDSLOTNO
-# endif
-
-# ifndef CONFIG_NSH_MMCSDMINOR
-# define CONFIG_NSH_MMCSDMINOR 0
-# endif
-
-# ifndef CONFIG_NSH_MMCSDSLOTNO
-# define CONFIG_NSH_MMCSDSLOTNO 0
-# endif
-#endif
-
-/* Can't support USB features if USB is not enabled */
-
-#ifndef CONFIG_USBDEV
-# undef NSH_HAVE_USBDEV
-#endif
-
/* Debug ********************************************************************/
#ifdef CONFIG_CPP_HAVE_VARARGS
@@ -126,41 +86,40 @@
int nsh_archinitialize(void)
{
-#ifdef NSH_HAVE_MMCSD
- FAR struct sdio_dev_s *sdio;
+#if defined(HAVE_AT25) || defined(HAVE_HSMCI) || defined(HAVE_USBMONITOR)
int ret;
+#endif
- /* Mount the SDIO-based MMC/SD block driver */
- /* First, get an instance of the SDIO interface */
-
- message("nsh_archinitialize: Initializing SDIO slot %d\n",
- CONFIG_NSH_MMCSDSLOTNO);
+#ifdef HAVE_AT25
+ /* Initialize the AT25 driver */
- sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO);
- if (!sdio)
+ ret = sam_at25_automount(0);
+ if (ret < 0)
{
- message("nsh_archinitialize: Failed to initialize SDIO slot %d\n",
- CONFIG_NSH_MMCSDSLOTNO);
- return -ENODEV;
+ message("ERROR: sam_at25_automount() failed: %d\n", ret);
+ return ret;
}
+#endif
- /* Now bind the SDIO interface to the MMC/SD driver */
-
- message("nsh_archinitialize: Bind SDIO to the MMC/SD driver, minor=%d\n",
- CONFIG_NSH_MMCSDMINOR);
+#ifdef HAVE_HSMCI
+ /* Initialize the HSMCI driver */
- ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, sdio);
- if (ret != OK)
+ ret = sam_hsmci_initialize(0);
+ if (ret < 0)
{
- message("nsh_archinitialize: Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
+ message("ERROR: sam_hsmci_initialize(0) failed: %d\n", ret);
return ret;
}
+#endif
- message("nsh_archinitialize: Successfully bound SDIO to the MMC/SD driver\n");
-
- /* Then inform the HSMCI driver if there is or is not a card in the slot. */
+#ifdef HAVE_USBMONITOR
+ /* Start the USB Monitor */
- sdio_mediachange(sdio, sam_cardinserted(0));
+ ret = usbmonitor_start(0, NULL);
+ if (ret != OK)
+ {
+ message("nsh_archinitialize: Start USB monitor: %d\n", ret);
+ }
#endif
return OK;
diff --git a/nuttx/configs/sam4e-ek/src/sam_spi.c b/nuttx/configs/sam4e-ek/src/sam_spi.c
index 714a643ed..46c3c2c4e 100644
--- a/nuttx/configs/sam4e-ek/src/sam_spi.c
+++ b/nuttx/configs/sam4e-ek/src/sam_spi.c
@@ -95,15 +95,17 @@
void weak_function sam_spiinitialize(void)
{
- /* The ZigBee module connects used NPCS0. However, there is not yet any
- * ZigBee support.
- */
-
+#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_ADS7843E)
/* The touchscreen connects using NPCS0 (PA11). */
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_ADS7843E)
sam_configgpio(GPIO_TSC_CS);
#endif
+
+#if defined(CONFIG_MTD_AT25)
+ /* The AT25 Serial FLASH connects using NPCS3 (PA5). */
+
+ sam_configgpio(GPIO_FLASH_CS);
+#endif
}
/****************************************************************************
@@ -166,20 +168,33 @@ void weak_function sam_spiinitialize(void)
void sam_spi0select(enum spi_dev_e devid, bool selected)
{
- /* The touchscreen chip select is implemented as a GPIO OUTPUT that must
- * be controlled by this function. This is because the ADS7843E driver
- * must be able to sample the device BUSY GPIO input between SPI transfers.
- * However, the AD7843E will tri-state the BUSY input whenever the chip
- * select is de-asserted. So the only option is to control the chip select
- * manually and hold it low throughout the SPI transfer.
- */
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_ADS7843E)
- if (devid == SPIDEV_TOUCHSCREEN)
+ switch (devid)
{
- sam_gpiowrite(GPIO_TSC_CS, !selected);
- }
+#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_ADS7843E)
+ /* The touchscreen chip select is implemented as a GPIO OUTPUT that must
+ * be controlled by this function. This is because the ADS7843E driver
+ * must be able to sample the device BUSY GPIO input between SPI transfers.
+ * However, the AD7843E will tri-state the BUSY input whenever the chip
+ * select is de-asserted. So the only option is to control the chip select
+ * manually and hold it low throughout the SPI transfer.
+ */
+
+ case SPIDEV_TOUCHSCREEN:
+ sam_gpiowrite(GPIO_TSC_CS, !selected);
+ break;
#endif
+
+#if defined(CONFIG_MTD_AT25)
+ /* The AT25 Serial FLASH connects using NPCS3 (PA5). */
+
+ case SPIDEV_FLASH:
+ sam_gpiowrite(GPIO_FLASH_CS, !selected);
+ break;
+#endif
+
+ default:
+ break;
+ }
}
/****************************************************************************
diff --git a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
index e19773c75..4e559ab49 100644
--- a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
+++ b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
@@ -238,7 +238,7 @@
# define AT24_MINOR _AT24_MINOR
#endif
-/* MMC/SD minor numbers: The NSH device minor extended is extened to support
+/* MMC/SD minor numbers: The NSH device minor extended is extended to support
* two devices. If CONFIG_NSH_MMCSDMINOR is zero, these will be: /dev/mmcsd0
* and /dev/mmcsd1.
*/
diff --git a/nuttx/drivers/mtd/at25.c b/nuttx/drivers/mtd/at25.c
index 25fa82d21..5d7ae96b0 100644
--- a/nuttx/drivers/mtd/at25.c
+++ b/nuttx/drivers/mtd/at25.c
@@ -100,10 +100,16 @@
/* Status register bit definitions */
-#define AT25_SR_WIP (1 << 0) /* Bit 0: Write in progress bit */
-#define AT25_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
-#define AT25_SR_EPE (1 << 5) /* Bit 5: Erase/program error */
-#define AT25_SR_UNPROT 0x00 /* Global unprotect command */
+#define AT25_SR_BUSY (1 << 0) /* Bit 0: Ready/Busy Status */
+#define AT25_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
+#define AT25_SR_SWP_SHIFT (2) /* Bits 2-3: Software protection */
+#define AT25_SR_SWP_MASK (3 << AT25_SR_SWP_SHIFT)
+#define AT25_SR_WPP (1 << 4) /* Bit 4: Write Protect (/WP) Pin Status */
+#define AT25_SR_EPE (1 << 5) /* Bit 5: Erase/program error */
+ /* Bit 6: Reserved */
+#define AT25_SR_SPRL (1 << 7) /* Bit 7: Sector Protection Registers Locked */
+
+#define AT25_SR_UNPROT 0x00 /* Global unprotect command */
#define AT25_DUMMY 0xa5
@@ -269,7 +275,7 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv)
status = SPI_SEND(priv->dev, AT25_DUMMY);
}
- while ((status & AT25_SR_WIP) != 0);
+ while ((status & AT25_SR_BUSY) != 0);
/* Deselect the FLASH */
@@ -302,19 +308,19 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv)
* other peripherals to access the SPI bus.
*/
- if ((status & AT25_SR_WIP) != 0)
+ if ((status & AT25_SR_BUSY) != 0)
{
at25_unlock(priv->dev);
usleep(10000);
at25_lock(priv->dev);
}
}
- while ((status & AT25_SR_WIP) != 0);
+ while ((status & AT25_SR_BUSY) != 0);
#endif
if (status & AT25_SR_EPE)
{
- fdbg("Write error, status: 0x%02x\n", status);
+ fdbg("ERROR: Write error, status: 0x%02x\n", status);
}
fvdbg("Complete, status: 0x%02x\n", status);
@@ -693,7 +699,7 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
{
/* Unrecognized! Discard all of that work we just did and return NULL */
- fdbg("Unrecognized\n");
+ fdbg("ERROR: Unrecognized\n");
kfree(priv);
priv = NULL;
}