diff --git a/Documentation/platforms/arm/stm32h7/boards/weact-stm32h743/index.rst b/Documentation/platforms/arm/stm32h7/boards/weact-stm32h743/index.rst index fe3ea48903a..ce3a8662c86 100644 --- a/Documentation/platforms/arm/stm32h7/boards/weact-stm32h743/index.rst +++ b/Documentation/platforms/arm/stm32h7/boards/weact-stm32h743/index.rst @@ -56,6 +56,28 @@ USART1 RX PB15 ====== ===== + +SDMMC +====== + +The WeAct STM32H743 has one SDCard slot connected as below: + + ========== ===== + SDMMC1 PINS + ========== ===== + SDMMC_D0 PC8 + SDMMC_D1 PC9 + SDMMC_D2 PC10 + SDMMC_D3 PC11 + SDMMC_DK PC12 + ========== ===== + + =============== ===== + GPIO PINS + =============== ===== + SDCARD_DETECTED PD4 + =============== ===== + ============== Each weact-stm32h743 configuration is maintained in a sub-directory and @@ -95,3 +117,18 @@ After flashing and reboot your board you should see in your dmesg logs:: You may need to press **ENTER** 3 times before the NSH show up. +sdcard +------ + +Configures the NuttShell (nsh) and enables SD card support. The board 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 vfat /dev/mmcsd0 /mnt + nsh> mount + nsh> echo "Hello World!!" > /mnt/test_file.txt + nhs> ls /mnt/ + test_file.txt + nsh> cat /mnt/test_file.txt + Hello World!! diff --git a/boards/arm/stm32h7/weact-stm32h743/configs/sdcard/defconfig b/boards/arm/stm32h7/weact-stm32h743/configs/sdcard/defconfig new file mode 100644 index 00000000000..6f890ee33d9 --- /dev/null +++ b/boards/arm/stm32h7/weact-stm32h743/configs/sdcard/defconfig @@ -0,0 +1,69 @@ +# +# 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_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32H7_USE_LEGACY_PINMAP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="weact-stm32h743" +CONFIG_ARCH_BOARD_WEACT_STM32H743=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H743VI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_ALARM=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=4096 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBM=y +CONFIG_LINE_MAX=64 +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_REGIONS=4 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RTC_ALARM=y +CONFIG_RTC_DATETIME=y +CONFIG_RTC_DRIVER=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_MODE=y +CONFIG_START_DAY=11 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2024 +CONFIG_STM32H7_PWR=y +CONFIG_STM32H7_RTC=y +CONFIG_STM32H7_SDMMC1=y +CONFIG_STM32H7_USART1=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USART1_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32h7/weact-stm32h743/include/board.h b/boards/arm/stm32h7/weact-stm32h743/include/board.h index b3dd715fa53..5acb6320bf8 100644 --- a/boards/arm/stm32h7/weact-stm32h743/include/board.h +++ b/boards/arm/stm32h7/weact-stm32h743/include/board.h @@ -141,19 +141,30 @@ #define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(40) #define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(3) -/* PLL3 */ +/* PLL3 - 25 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL3_VCO = (25 MHz / 1) * 35 = 875 MHz + * + * PLL3P = PLL3_VCO/2 = 875 MHz / 2 = 437.7 MHz + * PLL3Q = PLL3_VCO/1 = 875 MHz / 1 = 875 MHz + * PLL3R = PLL3_VCO/20 = 875 MHz / 20 = 43.75 MHz + */ +#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE| \ + RCC_PLLCFGR_PLL3RGE_8_16_MHZ| \ + RCC_PLLCFGR_DIVP3EN| \ + RCC_PLLCFGR_DIVQ3EN| \ + RCC_PLLCFGR_DIVR3EN) -#define STM32_PLLCFG_PLL3CFG 0 -#define STM32_PLLCFG_PLL3M 0 -#define STM32_PLLCFG_PLL3N 0 -#define STM32_PLLCFG_PLL3P 0 -#define STM32_PLLCFG_PLL3Q 0 -#define STM32_PLLCFG_PLL3R 0 +#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(1) +#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(35) +#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2) +#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(1) +#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(20) -#define STM32_VCO3_FREQUENCY -#define STM32_PLL3P_FREQUENCY -#define STM32_PLL3Q_FREQUENCY -#define STM32_PLL3R_FREQUENCY +#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 35) +#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2) +#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 1) +#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 20) /* SYSCLK = PLL1P = 480 MHz * CPUCLK = SYSCLK / 1 = 480 MHz @@ -165,7 +176,7 @@ /* Configure Clock Assignments */ -/* AHB clock (HCLK) is SYSCLK/2 (480 MHz max) +/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max) * HCLK1 = HCLK2 = HCLK3 = HCLK4 */ @@ -248,6 +259,17 @@ #define STM32_RCC_D3CCIPR_ADCSRC RCC_D3CCIPR_ADCSEL_PLL2 +/* FDCAN 1 2 clock source, use STM32_HSE_FREQUENCY */ + +#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE + +/* SDMMC 1 2 clock source, use STM32_PLL1Q_FREQUENCY */ + +#define STM32_RCC_D1CCIPR_SDMMCSEL RCC_D1CCIPR_SDMMC_PLL1 + +/* FMC clock source, use STM32_PLL1Q_FREQUENCY */ +#define BOARD_FMC_CLK RCC_D1CCIPR_FMCSEL_HCLK + /* FLASH wait states * * ------------ ---------- ----------- @@ -285,6 +307,13 @@ #define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE +#define GPIO_SDMMC1_CK (GPIO_SDMMC1_CK_0|GPIO_SPEED_100MHz) /* PC12 */ +#define GPIO_SDMMC1_CMD (GPIO_SDMMC1_CMD_0|GPIO_SPEED_100MHz) /* PD2 */ +#define GPIO_SDMMC1_D0 (GPIO_SDMMC1_D0_0|GPIO_SPEED_100MHz) /* PC8 */ +#define GPIO_SDMMC1_D1 (GPIO_SDMMC1_D1_0|GPIO_SPEED_100MHz) /* PC9 */ +#define GPIO_SDMMC1_D2 (GPIO_SDMMC1_D2_0|GPIO_SPEED_100MHz) /* PC10 */ +#define GPIO_SDMMC1_D3 (GPIO_SDMMC1_D3_0|GPIO_SPEED_100MHz) /* PC11 */ + /* LED definitions **********************************************************/ /* The board has 1 user LED that could be used this diagnostic LED too. diff --git a/boards/arm/stm32h7/weact-stm32h743/src/CMakeLists.txt b/boards/arm/stm32h7/weact-stm32h743/src/CMakeLists.txt index 7245a37f209..e74471ede60 100644 --- a/boards/arm/stm32h7/weact-stm32h743/src/CMakeLists.txt +++ b/boards/arm/stm32h7/weact-stm32h743/src/CMakeLists.txt @@ -28,6 +28,14 @@ else() list(APPEND SRCS stm32_userleds.c) endif() +if(CONFIG_STM32H7_SDMMC) + list(APPEND SRCS stm32_sdmmc.c) +endif() + +if(CONFIG_FAT_DMAMEMORY) + list(APPEND SRCS stm32_dma_alloc.c) +endif() + if(CONFIG_BOARDCTL) list(APPEND SRCS stm32_appinitialize.c) endif() diff --git a/boards/arm/stm32h7/weact-stm32h743/src/Makefile b/boards/arm/stm32h7/weact-stm32h743/src/Makefile index d83fdda73d5..a4cd1ebebd8 100644 --- a/boards/arm/stm32h7/weact-stm32h743/src/Makefile +++ b/boards/arm/stm32h7/weact-stm32h743/src/Makefile @@ -30,6 +30,14 @@ else CSRCS += stm32_userleds.c endif +ifeq ($(CONFIG_STM32H7_SDMMC),y) +CSRCS += stm32_sdmmc.c +endif + +ifeq ($(CONFIG_FAT_DMAMEMORY),y) +CSRCS += stm32_dma_alloc.c +endif + ifeq ($(CONFIG_BOARDCTL),y) CSRCS += stm32_appinitialize.c endif diff --git a/boards/arm/stm32h7/weact-stm32h743/src/stm32_bringup.c b/boards/arm/stm32h7/weact-stm32h743/src/stm32_bringup.c index 75cbe0738a5..935b7bc5fda 100644 --- a/boards/arm/stm32h7/weact-stm32h743/src/stm32_bringup.c +++ b/boards/arm/stm32h7/weact-stm32h743/src/stm32_bringup.c @@ -78,5 +78,23 @@ int stm32_bringup(void) } #endif /* CONFIG_FS_PROCFS */ +#if defined(CONFIG_FAT_DMAMEMORY) + if (stm32_dma_alloc_init() < 0) + { + syslog(LOG_ERR, "DMA alloc FAILED"); + } +#endif + +#ifdef HAVE_SDIO + /* Initialize the SDIO block driver */ + + ret = stm32_sdio_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to initialize MMC/SD driver: %d\n", ret); + } +#endif + return OK; } diff --git a/boards/arm/stm32h7/weact-stm32h743/src/stm32_dma_alloc.c b/boards/arm/stm32h7/weact-stm32h743/src/stm32_dma_alloc.c new file mode 100644 index 00000000000..64d466cd692 --- /dev/null +++ b/boards/arm/stm32h7/weact-stm32h743/src/stm32_dma_alloc.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * boards/arm/stm32h7/weact-stm32h743/src/stm32_dma_alloc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "weact-stm32h743.h" + +#if defined(CONFIG_FAT_DMAMEMORY) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_GRAN) +# error microSD DMA support requires CONFIG_GRAN +#endif + +#define BOARD_DMA_ALLOC_POOL_SIZE (8*512) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static GRAN_HANDLE dma_allocator; + +/* The DMA heap size constrains the total number of things that can be + * ready to do DMA at a time. + * + * For example, FAT DMA depends on one sector-sized buffer per + * filesystem plus one sector-sized buffer per file. + * + * We use a fundamental alignment / granule size of 64B; this is + * sufficient to guarantee alignment for the largest STM32 DMA burst + * (16 beats x 32bits). + */ + +static uint8_t g_dma_heap[BOARD_DMA_ALLOC_POOL_SIZE] + aligned_data(64); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dma_alloc_init + * + * Description: + * All boards may optionally provide this API to instantiate a pool of + * memory for uses with FAST FS DMA operations. + * + ****************************************************************************/ + +int stm32_dma_alloc_init(void) +{ + dma_allocator = gran_initialize(g_dma_heap, + sizeof(g_dma_heap), + 7, /* 128B granule - must be > alignment (XXX bug?) */ + 6); /* 64B alignment */ + + if (dma_allocator == NULL) + { + return -ENOMEM; + } + + return OK; +} + +/* DMA-aware allocator stubs for the FAT filesystem. */ + +void *fat_dma_alloc(size_t size) +{ + return gran_alloc(dma_allocator, size); +} + +void fat_dma_free(void *memory, size_t size) +{ + gran_free(dma_allocator, memory, size); +} + +#endif /* CONFIG_FAT_DMAMEMORY */ diff --git a/boards/arm/stm32h7/weact-stm32h743/src/stm32_sdmmc.c b/boards/arm/stm32h7/weact-stm32h743/src/stm32_sdmmc.c new file mode 100644 index 00000000000..21923e7cc5d --- /dev/null +++ b/boards/arm/stm32h7/weact-stm32h743/src/stm32_sdmmc.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * boards/arm/stm32h7/weact-stm32h743/src/stm32_sdmmc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_gpio.h" +#include "stm32_sdmmc.h" +#include "weact-stm32h743.h" + +/**************************************************************************** + * 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 *param) +{ + 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; +} diff --git a/boards/arm/stm32h7/weact-stm32h743/src/weact-stm32h743.h b/boards/arm/stm32h7/weact-stm32h743/src/weact-stm32h743.h index 45f6c29b4fa..cafd40a9f78 100644 --- a/boards/arm/stm32h7/weact-stm32h743/src/weact-stm32h743.h +++ b/boards/arm/stm32h7/weact-stm32h743/src/weact-stm32h743.h @@ -115,6 +115,24 @@ #define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | GPIO_PORTC | GPIO_PIN13) +/* SD Card + * + * PD4 Card detected pin + */ + +#if defined(CONFIG_STM32H7_SDMMC1) +# define HAVE_SDIO +#endif + +#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_MMCSD_SDIO) +# undef HAVE_SDIO +#endif + +#define GPIO_SDIO_NCD (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTD|GPIO_PIN4) /* PD4 */ + +#define SDIO_SLOTNO 0 +#define SDIO_MINOR 0 + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -136,4 +154,31 @@ int stm32_bringup(void); +/**************************************************************************** + * Name: stm32_dma_alloc_init + * + * Description: + * Called to create a FAT DMA allocator. + * + * Returned Value: + * 0 on success or -ENOMEM + * + ****************************************************************************/ + +#if defined (CONFIG_FAT_DMAMEMORY) +int stm32_dma_alloc_init(void); +#endif + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support. + * + ****************************************************************************/ + +#ifdef HAVE_SDIO +int stm32_sdio_initialize(void); +#endif + #endif /* __BOARDS_ARM_STM32H7_WEACT_STM32H743_SRC_WEACT_STM32H743_H */