From f07be860dd078b8b95a6b181b9c7768791dcd736 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 5 Apr 2016 17:15:50 -0600 Subject: [PATCH] Olimex STM32 H407: Add basic infrastructure for MMC/Sd support --- configs/olimex-stm32-h407/src/Makefile | 4 + .../olimex-stm32-h407/src/olimex-stm32-h407.h | 72 +++++++ configs/olimex-stm32-h407/src/stm32_bringup.c | 14 +- configs/olimex-stm32-h407/src/stm32_sdio.c | 175 ++++++++++++++++++ 4 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 configs/olimex-stm32-h407/src/stm32_sdio.c diff --git a/configs/olimex-stm32-h407/src/Makefile b/configs/olimex-stm32-h407/src/Makefile index 5e289bd872..efb28f8870 100644 --- a/configs/olimex-stm32-h407/src/Makefile +++ b/configs/olimex-stm32-h407/src/Makefile @@ -76,6 +76,10 @@ ifeq ($(CONFIG_CAN),y) CSRCS += stm32_can.c endif +ifeq ($(CONFIG_STM32_SDIO),y) +CSRCS += stm32_sdio.c +endif + ifeq ($(CONFIG_ARCH_FPU),y) CSRCS += stm32_ostest.c endif diff --git a/configs/olimex-stm32-h407/src/olimex-stm32-h407.h b/configs/olimex-stm32-h407/src/olimex-stm32-h407.h index 92c46589cb..766ddb9c7b 100644 --- a/configs/olimex-stm32-h407/src/olimex-stm32-h407.h +++ b/configs/olimex-stm32-h407/src/olimex-stm32-h407.h @@ -52,6 +52,7 @@ #define HAVE_USBDEV 1 #define HAVE_USBHOST 1 #define HAVE_USBMONITOR 1 +#define HAVE_SDIO 1 #define HAVE_RTC_DRIVER 1 # /* Can't support USB host or device features if USB OTG HS is not enabled */ @@ -85,6 +86,49 @@ # undef CONFIG_CAN #endif +/* Can't support MMC/SD features if mountpoints are disabled or if SDIO support + * is not enabled. Can't support MMC/SD features if the upper half MMC/SD SDIO + * driver is not enabled. + */ + +#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_STM32_SDIO) +# undef HAVE_SDIO +#endif + +#if !defined(CONFIG_MMCSD_SDIO) +# undef HAVE_SDIO +#endif + +#undef SDIO_MINOR /* Any minor number, default 0 */ +#define SDIO_SLOTNO 0 /* Only one slot */ + +#ifdef HAVE_SDIO + +# if defined(CONFIG_NSH_MMCSDSLOTNO) && CONFIG_NSH_MMCSDSLOTNO != 0 +# warning Only one MMC/SD slot, slot 0 +# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO +# endif + +# if defined(CONFIG_NSH_MMCSDMINOR) +# define SDIO_MINOR CONFIG_NSH_MMCSDMINOR +# else +# define SDIO_MINOR 0 +# endif + + /* SD card bringup does not work if performed on the IDLE thread because it + * will cause waiting. Use either: + * + * CONFIG_LIB_BOARDCTL=y, OR + * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y + */ + +# if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_LIB_BOARDCTL) && \ + !defined(CONFIG_BOARD_INITTHREAD) +# warning SDIO initialization cannot be perfomed on the IDLE thread +# undef HAVE_SDIO +# endif +#endif + /* Check if we can support the RTC driver */ #if !defined(CONFIG_RTC) || !defined(CONFIG_RTC_DRIVER) @@ -135,6 +179,22 @@ GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN5) #endif +/* MicroSD SDIO + * + * ---------- -------- ------- --------------------------- + * PIO SIGNAL Pulled Comments + * ---------- -------- ------- ----------------------- + * -- NCD Card detect, combined with pins settings CD/PC11 + * PC9 DAT1 UP 33K Also interrupt + * PC8 DAT0 UP 33K " " "" " " + * PC12 CLK ---- " " "" " " + * PD2 CMD UP 33K " " "" " " + * PC11 CD/DAT3 DOWN 1M " " "" " " + * PC10 DAT2 UP 33K Also Read wait operation + * -- WrProtect Not Supported + * ---------- -------- ------- ---------------------- + */ + /**************************************************************************** * Public Types ****************************************************************************/ @@ -169,6 +229,18 @@ int stm32_bringup(void); +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +#if defined(HAVE_SDIO) +int stm32_sdio_initialize(void); +#endif + /**************************************************************************** * Name: stm32_usbinitialize * diff --git a/configs/olimex-stm32-h407/src/stm32_bringup.c b/configs/olimex-stm32-h407/src/stm32_bringup.c index f5844d8654..0907d78a3c 100644 --- a/configs/olimex-stm32-h407/src/stm32_bringup.c +++ b/configs/olimex-stm32-h407/src/stm32_bringup.c @@ -94,7 +94,8 @@ int stm32_bringup(void) #ifdef HAVE_RTC_DRIVER FAR struct rtc_lowerhalf_s *lower; #endif -#if defined(CONFIG_CAN) || defined(CONFIG_ADC) || defined(HAVE_RTC_DRIVER) +#if defined(CONFIG_CAN) || defined(CONFIG_ADC) || defined(HAVE_SDIO) || \ + defined(HAVE_RTC_DRIVER) int ret; #endif @@ -118,6 +119,17 @@ int stm32_bringup(void) } #endif +#ifdef HAVE_SDIO + /* Initialize the SDIO block driver */ + + ret = stm32_sdio_initialize(); + if (ret != OK) + { + fdbg("ERROR: Failed to initialize MMC/SD driver: %d\n", ret); + return ret; + } +#endif + #ifdef HAVE_USBHOST /* Initialize USB host operation. stm32_usbhost_initialize() starts a thread * will monitor for USB connection and disconnection events. diff --git a/configs/olimex-stm32-h407/src/stm32_sdio.c b/configs/olimex-stm32-h407/src/stm32_sdio.c new file mode 100644 index 0000000000..919c503252 --- /dev/null +++ b/configs/olimex-stm32-h407/src/stm32_sdio.c @@ -0,0 +1,175 @@ +/**************************************************************************** + * config/olimex-stm32_h407/src/stm32_sdio.c + * + * Copyright (C) 2016 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 +#include + +#include "stm32.h" +#include "olimex-stm32-h407.h" + +#ifdef HAVE_SDIO + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(HAVE_SDIO) || !defined(GPIO_SDIO_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *g_sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDIO_NCD); + if (present != g_sd_inserted) + { + sdio_mediachange(g_sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDIO_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDIO_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + fvdbg("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + g_sdio_dev = sdio_initialize(SDIO_SLOTNO); + if (!g_sdio_dev) + { + fdbg("Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + fvdbg("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, g_sdio_dev); + if (ret != OK) + { + fdbg("Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + fvdbg("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDIO_NCD); + fvdbg("Card detect : %d\n", cd_status); + + sdio_mediachange(g_sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(g_sdio_dev, true); +#endif + + return OK; +} + +#endif /* HAVE_SDIO */