From 99c8d2f801ddd2d743a1057e7f6b06ffac33efd3 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 26 Jun 2018 15:28:14 -0600 Subject: [PATCH] configs/nucleo-l476rg: Add support for an extern SPI-driver SPI card on the Nucleo-L476RG. --- configs/nucleo-l476rg/README.txt | 31 +++++ configs/nucleo-l476rg/src/Makefile | 8 +- configs/nucleo-l476rg/src/nucleo-l476rg.h | 40 ++++--- configs/nucleo-l476rg/src/stm32_appinit.c | 19 +++ configs/nucleo-l476rg/src/stm32_spi.c | 15 ++- configs/nucleo-l476rg/src/stm32_spimmcsd.c | 129 +++++++++++++++++++++ 6 files changed, 222 insertions(+), 20 deletions(-) create mode 100644 configs/nucleo-l476rg/src/stm32_spimmcsd.c diff --git a/configs/nucleo-l476rg/README.txt b/configs/nucleo-l476rg/README.txt index b1a1f9b6ac6..2057ba95786 100644 --- a/configs/nucleo-l476rg/README.txt +++ b/configs/nucleo-l476rg/README.txt @@ -54,6 +54,7 @@ Contents - LQFP64 - mbed - Shields + - Other External Hardware/Devices - Configurations Nucleo-64 Boards @@ -588,6 +589,36 @@ Shields - Current showstopper: I appear to be getting infinite interrupts as soon as joystick button interrupts are enabled. +Other External Hardware/Devices +=============================== + + Using external SPI SDCard + ------------------------- + It is possible to use external SDCard over SPI with the + nucleo-stm32l476rg Cortex-M4. This option will or can broaden the + functionality in your project, solution or application. + + In this Nuttx project we attach an MH-SD Card Module (SPI). + [http://www.geeetech.com/wiki/index.php/Arduino_SD_card_Module] + + Other solutions should also work. + + Nucleo CN10 STM32L4x6RG + ----------- ------------ + Pin 31 PB3 SLCK + Pin 27 PB4 MISO + Pin 29 PB5 MOSI + Pin 25 PB10 CS + + Nucleo CN7 STM32L4x6RG + ----------- ------------ + Pin 18 +5V 5V + Pin 22 GND GND + + On the board the pins are labeled and are corresponding with the functions + as written before. + Configuring can be done by using ./tools/configure.sh nucleo-l476rg/spimmcsd + Configurations ============== diff --git a/configs/nucleo-l476rg/src/Makefile b/configs/nucleo-l476rg/src/Makefile index 045922dba70..a7c47f6cbf9 100644 --- a/configs/nucleo-l476rg/src/Makefile +++ b/configs/nucleo-l476rg/src/Makefile @@ -61,12 +61,16 @@ endif # Ben vd Veen (DisruptiveNL) -- 31-03-2018 ifeq ($(CONFIG_DEV_GPIO),y) - CSRCS += stm32_gpio.c +CSRCS += stm32_gpio.c endif # Ben vd Veen (DisruptiveNL) -- 31-03-2018 ifeq ($(CONFIG_CAN),y) - CSRCS += stm32_can.c +CSRCS += stm32_can.c +endif + +ifeq ($(CONFIG_MMCSD_SPI),y) +CSRCS += stm32_spimmcsd.c endif ifeq ($(CONFIG_LCD_PCD8544),y) diff --git a/configs/nucleo-l476rg/src/nucleo-l476rg.h b/configs/nucleo-l476rg/src/nucleo-l476rg.h index b798eee9634..665889a4a16 100644 --- a/configs/nucleo-l476rg/src/nucleo-l476rg.h +++ b/configs/nucleo-l476rg/src/nucleo-l476rg.h @@ -53,9 +53,11 @@ /* Configuration ********************************************************************/ -#define HAVE_PROC 1 -#define HAVE_RTC_DRIVER 1 -#define HAVE_MMCSD 1 +#define HAVE_PROC 1 +#define HAVE_RTC_DRIVER 1 + +#define HAVE_MMCSD_SPI 1 +#define HAVE_MMCSD 1 #if !defined(CONFIG_FS_PROCFS) # undef HAVE_PROC @@ -72,6 +74,11 @@ # undef HAVE_RTC_DRIVER #endif +#if !defined(CONFIG_STM32L4_SPI1) || !defined(CONFIG_MMCSD) || \ + !defined(CONFIG_MMCSD_SPI) +# undef HAVE_MMCSD +#endif + #if !defined(CONFIG_STM32L4_SDIO) || !defined(CONFIG_MMCSD) || \ !defined(CONFIG_MMCSD_SDIO) # undef HAVE_MMCSD @@ -122,15 +129,6 @@ * mostly from: https://mbed.org/platforms/ST-Nucleo-F401RE/ */ -/* SPI1 off */ - -#define GPIO_SPI1_MOSI_OFF (GPIO_INPUT | GPIO_PULLDOWN | \ - GPIO_PORTB | GPIO_PIN5) -#define GPIO_SPI1_MISO_OFF (GPIO_INPUT | GPIO_PULLDOWN | \ - GPIO_PORTB | GPIO_PIN4) -#define GPIO_SPI1_SCK_OFF (GPIO_INPUT | GPIO_PULLDOWN | \ - GPIO_PORTB | GPIO_PIN3) - #ifdef CONFIG_WL_CC1101 # define GPIO_CC1101_PWR (GPIO_PORTC | GPIO_PIN6 | GPIO_OUTPUT_SET | \ GPIO_OUTPUT | GPIO_PULLUP | GPIO_SPEED_50MHz) @@ -149,10 +147,10 @@ /* SPI chip selects */ -#ifdef HAVE_MMCSD +#ifdef CONFIG_MMCSD_SPI # define GPIO_SPI_CS_SD_CARD \ - (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_2MHz | \ - GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN5) + (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTB | GPIO_PIN10) #endif #ifdef CONFIG_LCD_PCD8544 @@ -377,6 +375,18 @@ int stm32l4_adc_setup(void); int board_ajoy_initialize(void); #endif +/**************************************************************************** + * Name: stm32l4_mmcsd_initialize + * + * Description: + * Initializes SPI-based SD card + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_SPI +int stm32l4_mmcsd_initialize(int minor); +#endif + /**************************************************************************** * Name: board_timer_driver_initialize * diff --git a/configs/nucleo-l476rg/src/stm32_appinit.c b/configs/nucleo-l476rg/src/stm32_appinit.c index abba0e482ac..7a0c2ad1152 100644 --- a/configs/nucleo-l476rg/src/stm32_appinit.c +++ b/configs/nucleo-l476rg/src/stm32_appinit.c @@ -68,6 +68,14 @@ * Public Functions ****************************************************************************/ +/* Checking needed by MMC/SDCard */ + +#ifdef CONFIG_NSH_MMCSDMINOR +# define MMCSD_MINOR CONFIG_NSH_MMCSDMINOR +#else +# define MMCSD_MINOR 0 +#endif + /**************************************************************************** * Name: board_app_initialize * @@ -209,6 +217,17 @@ int board_app_initialize(uintptr_t arg) } #endif +/* Initialize MMC and register the MMC driver. */ + +#ifdef HAVE_MMCSD_SPI + ret = stm32l4_mmcsd_initialize(MMCSD_MINOR); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize SD slot %d: %d\n", ret); + return ret; + } +#endif + #ifdef CONFIG_AJOYSTICK /* Initialize and register the joystick driver */ diff --git a/configs/nucleo-l476rg/src/stm32_spi.c b/configs/nucleo-l476rg/src/stm32_spi.c index c4c2c4cca73..48e90e9f3d5 100644 --- a/configs/nucleo-l476rg/src/stm32_spi.c +++ b/configs/nucleo-l476rg/src/stm32_spi.c @@ -91,7 +91,7 @@ void weak_function stm32l4_spiinitialize(void) spierr("ERROR: FAILED to initialize SPI port 1\n"); } -#ifdef HAVE_MMCSD +#ifdef HAVE_MMCSD_SPI stm32l4_configgpio(GPIO_SPI_CS_SD_CARD); #endif @@ -146,7 +146,7 @@ void stm32l4_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected { spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); -#ifdef HAVE_MMCSD +#ifdef HAVE_MMCSD_SPI if (devid == SPIDEV_MMCSD(0)) { stm32l4_gpiowrite(GPIO_SPI_CS_SD_CARD, !selected); @@ -163,7 +163,16 @@ void stm32l4_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected uint8_t stm32l4_spi1status(FAR struct spi_dev_s *dev, uint32_t devid) { - return 0; + uint8_t status = 0; + + #ifdef HAVE_MMCSD_SPI + if (devid == SPIDEV_MMCSD(0)) + { + status |= SPI_STATUS_PRESENT; + } + #endif + + return status; } #endif diff --git a/configs/nucleo-l476rg/src/stm32_spimmcsd.c b/configs/nucleo-l476rg/src/stm32_spimmcsd.c new file mode 100644 index 00000000000..19216ce24e2 --- /dev/null +++ b/configs/nucleo-l476rg/src/stm32_spimmcsd.c @@ -0,0 +1,129 @@ +/***************************************************************************** + * configs/stm32f103-minimum/src/stm32_mmcsd.c + * + * Copyright (C) 2018 Greg Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 +#include + +#include +#include "stm32l4_spi.h" + +/***************************************************************************** +* Pre-processor Definitions +****************************************************************************/ + +#ifndef CONFIG_STM32L4_SPI1 +# error "SD driver requires CONFIG_STM32_SPI1 to be enabled" +#endif + +#ifdef CONFIG_DISABLE_MOUNTPOINT +# error "SD driver requires CONFIG_DISABLE_MOUNTPOINT to be disabled" +#endif + +/***************************************************************************** +* Private Definitions +****************************************************************************/ + +static const int SD_SPI_PORT = 1; /* SD is connected to SPI1 port */ +static const int SD_SLOT_NO = 0; /* There is only one SD slot */ + +/***************************************************************************** + * Private Functions + ****************************************************************************/ + +/* NOTE: We are using a SDCard adapter/module without Card Detect pin! + * Then we don't need to Card Detect callback here. + */ + +/***************************************************************************** + * Public Functions + ****************************************************************************/ + +/***************************************************************************** + * Name: stm32_spi1register + * + * Description: + * Registers media change callback + ****************************************************************************/ + +int stm32l4_spi1register(struct spi_dev_s *dev, spi_mediachange_t callback, + void *arg) +{ + spiinfo("INFO: Registering spi1 device\n"); + return OK; +} + +/***************************************************************************** + * Name: stm32_mmcsd_initialize + * + * Description: + * Initialize SPI-based SD card and card detect thread. + ****************************************************************************/ + +int stm32l4_mmcsd_initialize(int minor) +{ + struct spi_dev_s *spi; + int rv; + + mcinfo("INFO: Initializing mmcsd card\n"); + + spi = stm32l4_spibus_initialize(SD_SPI_PORT); + if (spi == NULL) + { + mcerr("ERROR: Failed to initialize SPI port %d\n", SD_SPI_PORT); + return -ENODEV; + } + + rv = mmcsd_spislotinitialize(minor, SD_SLOT_NO, spi); + if (rv < 0) + { + mcerr("ERROR: Failed to bind SPI port %d to SD slot %d\n", + SD_SPI_PORT, SD_SLOT_NO); + return rv; + } + + spiinfo("INFO: mmcsd card has been initialized successfully\n"); + return OK; +} +