From d11f5b476338a5fe6a7bac33724015dc0d3bdae6 Mon Sep 17 00:00:00 2001 From: Jorge Guzman Date: Tue, 27 Feb 2024 21:36:45 -0300 Subject: [PATCH] stm32h7/linum-stm32h753bi: Add support to sdcard Signed-off-by: Jorge Guzman --- .../boards/linum-stm32h753bi/index.rst | 31 +++- .../configs/sdcard/defconfig | 70 ++++++++ .../stm32h7/linum-stm32h753bi/include/board.h | 156 +++++------------ .../linum-stm32h753bi/src/CMakeLists.txt | 8 + .../stm32h7/linum-stm32h753bi/src/Makefile | 8 + .../linum-stm32h753bi/src/linum-stm32h753bi.h | 48 ++++++ .../linum-stm32h753bi/src/stm32_bringup.c | 18 ++ .../linum-stm32h753bi/src/stm32_dma_alloc.c | 105 +++++++++++ .../linum-stm32h753bi/src/stm32_sdmmc.c | 163 ++++++++++++++++++ 9 files changed, 489 insertions(+), 118 deletions(-) create mode 100644 boards/arm/stm32h7/linum-stm32h753bi/configs/sdcard/defconfig create mode 100644 boards/arm/stm32h7/linum-stm32h753bi/src/stm32_dma_alloc.c create mode 100644 boards/arm/stm32h7/linum-stm32h753bi/src/stm32_sdmmc.c diff --git a/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst b/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst index 5330c2317c..f68cbe4642 100644 --- a/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst +++ b/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst @@ -115,25 +115,26 @@ The LINUM-STM32H753BI board has two on-board RS-485 transceiver connected to USA DE PG12 ====== ===== -SDCARD +SDMMC ====== The LINUM-STM32H753BI has one SDCard slot connected as below: ========== ===== - SDMMC1 PINS + SDMMC1 PINS ========== ===== - SDMMC_D0 PC8 - SDMMC_D1 PC9 - SDMMC_D2 PC10 - SDMMC_D3 PC11 - SDMMC_DK PC12 + SDMMC_D0 PC8 + SDMMC_D1 PC9 + SDMMC_D2 PC10 + SDMMC_D3 PC11 + SDMMC_DK PC12 ========== ===== =============== ===== GPIO PINS =============== ===== SDCARD_DETECTED PG7 + SDCARD_PWR_EN PD7 =============== ===== ETHERNET @@ -430,3 +431,19 @@ can enable the ModBus Master to create queries for device with address 10:: In your pc you will be able to create a ModBus Slave with address 10 using an application like ``diagslave``:: $ sudo diagslave -a 10 -b 38400 /dev/ttyUSB0 + +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/linum-stm32h753bi/configs/sdcard/defconfig b/boards/arm/stm32h7/linum-stm32h753bi/configs/sdcard/defconfig new file mode 100644 index 0000000000..cb14cb156d --- /dev/null +++ b/boards/arm/stm32h7/linum-stm32h753bi/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_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="linum-stm32h753bi" +CONFIG_ARCH_BOARD_LINUM_STM32H753BI=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32H753BI=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_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_LINELEN=64 +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=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32H7_HSI48=y +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/linum-stm32h753bi/include/board.h b/boards/arm/stm32h7/linum-stm32h753bi/include/board.h index 71f067f321..7471a016f9 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/include/board.h +++ b/boards/arm/stm32h7/linum-stm32h753bi/include/board.h @@ -88,7 +88,7 @@ /* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR * - * PLL1_VCO = (25,000,000 / 5) * 192 = 960 MHz + * PLL1_VCO = (25 MHz / 5) * 192 = 960 MHz * * PLL1P = PLL1_VCO/2 = 800 MHz / 2 = 480 MHz * PLL1Q = PLL1_VCO/4 = 800 MHz / 4 = 240 MHz @@ -100,32 +100,42 @@ RCC_PLLCFGR_DIVP1EN | \ RCC_PLLCFGR_DIVQ1EN | \ RCC_PLLCFGR_DIVR1EN) -#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(5) -#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(192) -#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) -#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) -#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(4) #define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 5) * 192) #define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) #define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) #define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 4) -/* PLL2 */ +#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(5) +#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(192) +#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) +#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) +#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(4) +/* PLL2, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR + * + * PLL1_VCO = (25 MHz / 2) * 48 = 600 MHz + * + * PLL2P = PLL2_VCO/2 = 600 MHz / 8 = 75 MHz + * PLL2Q = PLL2_VCO/4 = 600 MHz / 40 = 15 MHz + * PLL2R = PLL2_VCO/8 = 600 MHz / 3 = 200 MHz + */ #define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ - RCC_PLLCFGR_DIVP2EN) -#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) -#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) -#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(8) -#define STM32_PLLCFG_PLL2Q 1 -#define STM32_PLLCFG_PLL2R 3 + RCC_PLLCFGR_DIVP2EN | \ + RCC_PLLCFGR_DIVQ2EN | \ + RCC_PLLCFGR_DIVR2EN ) #define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 48) #define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 8) -#define STM32_PLL2Q_FREQUENCY -#define STM32_PLL2R_FREQUENCY +#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 40) +#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 3) + +#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) +#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48) +#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(8) +#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(40) +#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(3) /* PLL3 */ @@ -258,31 +268,19 @@ /* SDMMC definitions ********************************************************/ -/* Init 400kHz, PLL1Q/(2*250) */ +/* Init 400 kHz, PLL1Q/(2*300) = 240 MHz / (2*300) = 400 Khz */ -#define STM32_SDMMC_INIT_CLKDIV (250 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) -/* Just set these to 25 MHz for now, - * PLL1Q/(2*4), for default speed 12.5MB/s +/* Just set these to 24 MHz for now, + * PLL1Q/(2*5) = 240 MHz / (2*5) = 24 MHz */ -#define STM32_SDMMC_MMCXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) -#define STM32_SDMMC_SDXFR_CLKDIV (4 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE -/* Ethernet definitions *****************************************************/ - -#define GPIO_ETH_RMII_TXD0 (GPIO_ETH_RMII_TXD0_2 | GPIO_SPEED_100MHz) /* PG13 */ -#define GPIO_ETH_RMII_TXD1 (GPIO_ETH_RMII_TXD1_1 | GPIO_SPEED_100MHz) /* PB13 */ -#define GPIO_ETH_RMII_TX_EN (GPIO_ETH_RMII_TX_EN_2 | GPIO_SPEED_100MHz) /* PG11 */ -#define GPIO_ETH_MDC (GPIO_ETH_MDC_0 | GPIO_SPEED_100MHz) /* PC1 */ -#define GPIO_ETH_MDIO (GPIO_ETH_MDIO_0 | GPIO_SPEED_100MHz) /* PA2 */ -#define GPIO_ETH_RMII_RXD0 (GPIO_ETH_RMII_RXD0_0 | GPIO_SPEED_100MHz) /* PC4 */ -#define GPIO_ETH_RMII_RXD1 (GPIO_ETH_RMII_RXD1_0 | GPIO_SPEED_100MHz) /* PC5 */ -#define GPIO_ETH_RMII_CRS_DV (GPIO_ETH_RMII_CRS_DV_0 | GPIO_SPEED_100MHz) /* PA7 */ -#define GPIO_ETH_RMII_REF_CLK (GPIO_ETH_RMII_REF_CLK_0 | GPIO_SPEED_100MHz) /* PA1 */ - /* LED definitions **********************************************************/ /* The board has 1 user LED RGB that could be used this diagnostic LED too. @@ -384,85 +382,21 @@ #define GPIO_OTGFS_DM (GPIO_OTGFS_DM_0 | GPIO_SPEED_100MHz) #define GPIO_OTGFS_DP (GPIO_OTGFS_DP_0 | GPIO_SPEED_100MHz) -/* I2C4 - Used by Touchscreen and Audio Codec */ +/* SDMMC1 Pin mapping + * CLK - PC12 + * CMD - PD2 + * D0 - PC8 + * D1 - PC9 + * D2 - PC10 + * D3 - PC11 + */ -#define GPIO_I2C4_SCL (GPIO_I2C4_SCL_1 | GPIO_SPEED_50MHz) /* PD12 */ -#define GPIO_I2C4_SDA (GPIO_I2C4_SDA_1 | GPIO_SPEED_50MHz) /* PD13 */ - -/* LTDC */ - -#define GPIO_LTDC_R0 (GPIO_LTDC_R0_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R1 (GPIO_LTDC_R1_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R2 (GPIO_LTDC_R2_4 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R3 (GPIO_LTDC_R3_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R4 (GPIO_LTDC_R4_4 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R5 (GPIO_LTDC_R5_4 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R6 (GPIO_LTDC_R6_4 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_R7 (GPIO_LTDC_R7_3 | GPIO_SPEED_100MHz) - -#define GPIO_LTDC_G0 (GPIO_LTDC_G0_2 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G1 (GPIO_LTDC_G1_2 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G2 (GPIO_LTDC_G2_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G3 (GPIO_LTDC_G3_4 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G4 (GPIO_LTDC_G4_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G5 (GPIO_LTDC_G5_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G6 (GPIO_LTDC_G6_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_G7 (GPIO_LTDC_G7_3 | GPIO_SPEED_100MHz) - -#define GPIO_LTDC_B0 (GPIO_LTDC_B0_1 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B1 (GPIO_LTDC_B1_2 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B2 (GPIO_LTDC_B2_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B3 (GPIO_LTDC_B3_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B4 (GPIO_LTDC_B4_4 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B5 (GPIO_LTDC_B5_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B6 (GPIO_LTDC_B6_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_B7 (GPIO_LTDC_B7_3 | GPIO_SPEED_100MHz) - -#define GPIO_LTDC_VSYNC (GPIO_LTDC_VSYNC_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_HSYNC (GPIO_LTDC_HSYNC_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_DE (GPIO_LTDC_DE_3 | GPIO_SPEED_100MHz) -#define GPIO_LTDC_CLK (GPIO_LTDC_CLK_3 | GPIO_SPEED_100MHz) - -/* DMA **********************************************************************/ - -#define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_0 /* DMA1 */ -#define DMAMAP_SPI3_TX DMAMAP_DMA12_SPI3TX_0 /* DMA1 */ - -/* LCD definitions */ - -#define BOARD_LTDC_WIDTH 480 -#define BOARD_LTDC_HEIGHT 272 - -#define BOARD_LTDC_OUTPUT_BPP 24 -#define BOARD_LTDC_HFP 32 -#define BOARD_LTDC_HBP 13 -#define BOARD_LTDC_VFP 2 -#define BOARD_LTDC_VBP 2 -#define BOARD_LTDC_HSYNC 41 -#define BOARD_LTDC_VSYNC 10 - -#define BOARD_LTDC_PLLSAIN 192 -#define BOARD_LTDC_PLLSAIR 5 - -/* Pixel Clock Polarity */ - -#define BOARD_LTDC_GCR_PCPOL 0 /* !LTDC_GCR_PCPOL */ - -/* Data Enable Polarity */ - -#define BOARD_LTDC_GCR_DEPOL 0 /* !LTDC_GCR_DEPOL */ - -/* Vertical Sync Polarity */ - -#define BOARD_LTDC_GCR_VSPOL 0 /* !LTDC_GCR_VSPOL */ - -/* Horizontal Sync Polarity */ - -#define BOARD_LTDC_GCR_HSPOL 0 /* !LTDC_GCR_HSPOL */ - -/* GPIO pinset */ - -#define GPIO_LTDC_PINS 24 /* 24-bit display */ +#define GPIO_SDMMC1_CK (GPIO_SDMMC1_CK_0 | GPIO_SPEED_100MHz) +#define GPIO_SDMMC1_CMD (GPIO_SDMMC1_CMD_0 | GPIO_SPEED_100MHz) +#define GPIO_SDMMC1_D0 (GPIO_SDMMC1_D0_0 | GPIO_SPEED_100MHz) +#define GPIO_SDMMC1_D1 (GPIO_SDMMC1_D1_0 | GPIO_SPEED_100MHz) +#define GPIO_SDMMC1_D2 (GPIO_SDMMC1_D2_0 | GPIO_SPEED_100MHz) +#define GPIO_SDMMC1_D3 (GPIO_SDMMC1_D3_0 | GPIO_SPEED_100MHz) /**************************************************************************** * Public Data diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/CMakeLists.txt b/boards/arm/stm32h7/linum-stm32h753bi/src/CMakeLists.txt index e269c9b372..ede0805ab5 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/CMakeLists.txt +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/CMakeLists.txt @@ -36,6 +36,14 @@ if(CONFIG_STM32H7_OTGFS) list(APPEND SRCS stm32_usb.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() + target_sources(board PRIVATE ${SRCS}) set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/flash.ld") diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/Makefile b/boards/arm/stm32h7/linum-stm32h753bi/src/Makefile index 9e92b0a35a..e251e13a8b 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/Makefile +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/Makefile @@ -34,6 +34,14 @@ ifeq ($(CONFIG_STM32H7_OTGFS),y) CSRCS += stm32_usb.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/linum-stm32h753bi/src/linum-stm32h753bi.h b/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h index a40c3cda63..cfb6a69cdb 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h @@ -78,6 +78,27 @@ GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN13) #endif +/* SD Card + * + * PG7 Card detected pin + * PD7 Enable power supply SD Card 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_PORTG | GPIO_PIN7) +#define GPIO_SD1_PWR_EN_N (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | \ + GPIO_OUTPUT_SET | GPIO_PORTD | GPIO_PIN7) + +#define SDIO_SLOTNO 0 +#define SDIO_MINOR 0 + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -112,4 +133,31 @@ int stm32_bringup(void); void weak_function stm32_usbinitialize(void); #endif +/**************************************************************************** + * 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_LINUM_STM32H753BI_SRC_LINUM_STM32H753BI_H */ diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c index 5987ccdab7..a36ee12d19 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c @@ -124,5 +124,23 @@ int stm32_bringup(void) } #endif +#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/linum-stm32h753bi/src/stm32_dma_alloc.c b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_dma_alloc.c new file mode 100644 index 0000000000..2236dd4ffe --- /dev/null +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_dma_alloc.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * boards/arm/stm32h7/linum-stm32h753bi/src/stm32_dma_alloc.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 "linum-stm32h753bi.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/linum-stm32h753bi/src/stm32_sdmmc.c b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_sdmmc.c new file mode 100644 index 0000000000..5fce66e579 --- /dev/null +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_sdmmc.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * boards/arm/stm32h7/linum-stm32h753bi/src/stm32_sdmmc.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_gpio.h" +#include "stm32_sdmmc.h" +#include "linum-stm32h753bi.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; + + /* Enable the Power Supply */ + + stm32_configgpio(GPIO_SD1_PWR_EN_N); + stm32_gpiowrite(GPIO_SD1_PWR_EN_N, 0); + + usleep(50000); + +#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; +}