From 89ddb2f70935bdfe0fcf9c832f7b5ab92f0114d4 Mon Sep 17 00:00:00 2001 From: Rodrigo Sim Date: Sat, 25 Nov 2023 11:57:57 -0300 Subject: [PATCH] stm32f401rc-rs485: Add sdcard support --- .../boards/stm32f401rc-rs485/index.rst | 17 +- .../configs/sdcard/defconfig | 70 ++++++++ .../stm32f401rc-rs485/src/CMakeLists.txt | 4 + .../arm/stm32/stm32f401rc-rs485/src/Make.defs | 4 + .../stm32f401rc-rs485/src/stm32_bringup.c | 12 ++ .../stm32/stm32f401rc-rs485/src/stm32_sdio.c | 159 ++++++++++++++++++ .../stm32f401rc-rs485/src/stm32f401rc-rs485.h | 32 +++- 7 files changed, 290 insertions(+), 8 deletions(-) create mode 100644 boards/arm/stm32/stm32f401rc-rs485/configs/sdcard/defconfig create mode 100644 boards/arm/stm32/stm32f401rc-rs485/src/stm32_sdio.c diff --git a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst index 6b1e703347..ff778299c5 100644 --- a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst +++ b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst @@ -98,8 +98,8 @@ CK PA4 [1] Warning you make need to reverse RX/TX on some RS-232 converters -SDCARD -====== +SDCard support +============== The STM32F4-RS485 has 1 SDCard slot connected as below: @@ -197,3 +197,16 @@ nsh Configures the NuttShell (nsh) located at apps/examples/nsh. This configuration enables a serial console on UART2. + +sdcard +------ + +Configures the NuttShell (nsh) and enables SD card support. +The stm32f401rc-rs485 has an onboard microSD slot that should +be automatically registered as the block device /dev/mmcsd0 when +an SD card is present. The SD card can then be mounted by the +NSH commands:: + + nsh> mount -t procfs /proc + nsh> mount -t vfat /dev/mmcsd0 /mnt + diff --git a/boards/arm/stm32/stm32f401rc-rs485/configs/sdcard/defconfig b/boards/arm/stm32/stm32f401rc-rs485/configs/sdcard/defconfig new file mode 100644 index 0000000000..5c50b8bacc --- /dev/null +++ b/boards/arm/stm32/stm32f401rc-rs485/configs/sdcard/defconfig @@ -0,0 +1,70 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_FPU is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_SPI is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32f401rc-rs485" +CONFIG_ARCH_BOARD_STM32F401RC_RS485=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F401RC=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_IRQBUTTONS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=8499 +CONFIG_BUILTIN=y +CONFIG_EXAMPLES_BUTTONS=y +CONFIG_EXAMPLES_BUTTONS_NAME0="SW3" +CONFIG_EXAMPLES_BUTTONS_NAME1="SW4" +CONFIG_EXAMPLES_BUTTONS_NAME2="SW5" +CONFIG_EXAMPLES_BUTTONS_NAME3="SW6" +CONFIG_EXAMPLES_BUTTONS_NAMES=y +CONFIG_EXAMPLES_BUTTONS_QTD=4 +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INPUT_BUTTONS=y +CONFIG_INPUT_BUTTONS_LOWER=y +CONFIG_INTELHEX_BINARY=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=98304 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SPI=y +CONFIG_START_DAY=5 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2014 +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_OTGFS=y +CONFIG_STM32_PWR=y +CONFIG_STM32_SDIO=y +CONFIG_STM32_SDIO_CARD=y +CONFIG_STM32_USART2=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USART2_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt index 76bf3b8399..de9a485552 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt +++ b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt @@ -36,6 +36,10 @@ if(CONFIG_ARCH_BUTTONS) list(APPEND SRCS stm32_buttons.c) endif() +if(CONFIG_STM32_SDIO) + list(APPEND SRCS stm32_sdio.c) +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_ARCH_CHIP_STM32F401RC) diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs index 9a9341b309..4ca8152729 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs +++ b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs @@ -39,6 +39,10 @@ ifeq ($(CONFIG_ARCH_BUTTONS),y) CSRCS += stm32_buttons.c endif +ifeq ($(CONFIG_STM32_SDIO),y) +CSRCS += stm32_sdio.c +endif + DEPPATH += --dep-path board VPATH += :board CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c index 3607da0066..9038d174c7 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c @@ -89,5 +89,17 @@ int stm32_bringup(void) } #endif +#ifdef HAVE_SDIO + /* Initialize the SDIO block driver */ + + ret = stm32_sdio_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to initialize MMC/SD driver: %d\n", + ret); + return ret; + } +#endif + return ret; } diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_sdio.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_sdio.c new file mode 100644 index 0000000000..3f330904d6 --- /dev/null +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_sdio.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f401rc-rs485/src/stm32_sdio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "stm32.h" +#include "stm32f401rc-rs485.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 struct sdio_dev_s *g_sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, void *context, void *arg) +{ + 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 + /* 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, NULL); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + g_sdio_dev = sdio_initialize(SDIO_SLOTNO); + if (!g_sdio_dev) + { + ferr("ERROR: Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, g_sdio_dev); + if (ret != OK) + { + ferr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("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 */ + + g_sd_inserted = !stm32_gpioread(GPIO_SDIO_NCD); + finfo("Card detect : %d\n", g_sd_inserted); + + sdio_mediachange(g_sdio_dev, g_sd_inserted); +#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 */ diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h index f8b6679f5d..94e7ceefe9 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h @@ -36,15 +36,23 @@ /* Configuration ************************************************************/ -#define HAVE_MMCSD 1 +#define HAVE_SDIO 1 #if !defined(CONFIG_STM32_SDIO) || !defined(CONFIG_MMCSD) || \ !defined(CONFIG_MMCSD_SDIO) -# undef HAVE_MMCSD +# undef HAVE_SDIO #endif -/* LED. User LD2: the green LED is a user LED connected to Arduino signal - * D13 corresponding to MCU I/O PA5 (pin 21) or PB13 (pin 34) depending on - * the STM32 target. +#define SDIO_MINOR 0 /* Any minor number, default 0 */ +#define SDIO_SLOTNO 0 /* Only one slot */ + +#define GPIO_SDIO_NCD (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|\ + GPIO_PORTA|GPIO_PIN8) + +/* The STM32F401RC-RS485 has 4 blue LEDs connected as below: + * - LED_1 is connected to the GPIO PC0. + * - LED_2 is connected to the GPIO PC1. + * - LED_3 is connected to the GPIO PC2. + * - LED_4 is connected to the GPIO PC3. * * - When the I/O is HIGH value, the LED is on. * - When the I/O is LOW, the LED is off. @@ -67,7 +75,7 @@ GPIO_SPEED_50MHz) /* Buttons - * The STm32F401RC-RS485 has 4 user buttons. + * The STM32F401RC-RS485 has 4 user buttons. * - SW3 is connected to the GPIO PB13. * - SW4 is connected to the GPIO PB14. * - SW5 is connected to the GPIO PB15. @@ -326,4 +334,16 @@ int board_ajoy_initialize(void); int stm32_mcp2515initialize(const char *devpath); #endif +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_STM32_SDIO) +int stm32_sdio_initialize(void); +#endif + #endif /* __BOARDS_ARM_STM32_STM32F401RC_RS485_SRC_STM32F401RC_RS485_H */