diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index 0f2f65f84a2..a93aaa598b9 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1215,12 +1215,16 @@ config STM32F7_SDMMC1 bool "SDMMC1" default n select ARCH_HAVE_SDIO + select ARCH_HAVE_SDIOWAIT_WRCOMPLETE + select SDIO_PREFLIGHT config STM32F7_SDMMC2 bool "SDMMC2" default n depends on STM32F7_HAVE_SDMMC2 select ARCH_HAVE_SDIO + select ARCH_HAVE_SDIOWAIT_WRCOMPLETE + select SDIO_PREFLIGHT config STM32F7_SPDIFRX bool "SPDIFRX" @@ -1710,6 +1714,86 @@ config STM32F7_I2C_DUTY16_9 endmenu # "I2C Configuration" +config STM32F7_SDMMC_XFRDEBUG + bool "SDMMC transfer debug" + depends on DEBUG_FS_INFO && (STM32F7_SDMMC1 || STM32F7_SDMMC2) + default n + ---help--- + Enable special debug instrumentation analyze SDMMC data transfers. + This logic is as non-invasive as possible: It samples SDMMC + registers at key points in the data transfer and then dumps all of + the registers at the end of the transfer. If DEBUG_DMA is also + enabled, then DMA register will be collected as well. Requires also + DEBUG_FS and CONFIG_DEBUG_INFO. + +menu "SDMMC1 Configuration" + depends on STM32F7_SDMMC1 + +config SDMMC1_DMA + bool "Support DMA data transfers on SDMMC1" + default y if STM32F7_DMA2 + depends on STM32F7_DMA2 + ---help--- + Support DMA data transfers on SDMMC1. Requires STM32F7_SDMMC1 and config STM32F7_DMA2. + +config SDMMC1_PRI + hex "SDMMC1 interrupt priority" + default 128 + depends on ARCH_IRQPRIO && EXPERIMENTAL + ---help--- + Select SDMMC1 interrupt priority. Default: 128. + +config SDMMC1_DMAPRIO + hex "SDMMC1 DMA priority" + default 0x00010000 + ---help--- + Select SDMMC1 DMA prority. + + Options are: 0x00000000 low, 0x00010000 medium, + 0x00020000 high, 0x00030000 very high. Default: medium. + +config SDMMC1_WIDTH_D1_ONLY + bool "Use D1 only on SDMMC1" + default n + ---help--- + Select 1-bit transfer mode. Default: 4-bit transfer mode. + +endmenu # "SDMMC1 Configuration" + +menu "SDMMC2 Configuration" + depends on STM32F7_SDMMC2 + +config SDMMC2_DMA + bool "Support DMA data transfers on SDMMC2" + default y if STM32F7_DMA2 + depends on STM32F7_DMA2 + ---help--- + Support DMA data transfers on SDMMC2. Requires STM32F7_SDMMC2 and config STM32F7_DMA2. + +config SDMMC2_PRI + hex "SDMMC2 interrupt priority" + default 128 + depends on ARCH_IRQPRIO && EXPERIMENTAL + ---help--- + Select SDMMC2 interrupt priority. Default: 128. + +config SDMMC2_DMAPRIO + hex "SDMMC2 DMA priority" + default 0x00010000 + ---help--- + Select SDMMC1 DMA prority. + + Options are: 0x00000000 low, 0x00010000 medium, + 0x00020000 high, 0x00030000 very high. Default: medium. + +config SDMMC2_WIDTH_D1_ONLY + bool "Use D1 only on SDMMC2" + default n + ---help--- + Select 1-bit transfer mode. Default: 4-bit transfer mode. + +endmenu # "SDMMC2 Configuration" + config STM32F7_CUSTOM_CLOCKCONFIG bool "Custom clock configuration" default n diff --git a/arch/arm/src/stm32f7/chip/stm32_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h index 10ed29f2384..016ddb18fb9 100644 --- a/arch/arm/src/stm32f7/chip/stm32_sdmmc.h +++ b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h @@ -2,7 +2,8 @@ * arch/arm/src/stm32f7/chip/stm32_sdmmc.h * * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Authors: Gregory Nutt + * David Sidrane * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,8 +44,9 @@ #include #include "chip.h" -#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) -# include "stm32f74xx75xx_sdmmc.h" +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) || \ + defined(CONFIG_STM32F7_STM32F76XX) || defined(CONFIG_STM32F7_STM32F77XX) +# include "stm32f74xx77xx_sdmmc.h" #else # error "Unsupported STM32 F7 part" #endif diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h index 881f17dc560..70c9a2a5aa7 100644 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h @@ -574,7 +574,7 @@ # define RCC_PLLI2SCFGR_PLLI2SN(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) #define RCC_PLLI2SCFGR_PLLI2SP_SHIFT (16) /* Bits 16-17: PLLI2S division factor for SPDIFRX clock */ #define RCC_PLLI2SCFGR_PLLI2SP_MASK (3 << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) -# define RCC_PLLI2SCFGR_PLLI2SP(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SP(n) ((((n)>>1)-1) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) #define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT (24) /* Bits 24-27: PLLI2S division factor for SAIs clock */ #define RCC_PLLI2SCFGR_PLLI2SQ_MASK (15 << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) # define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) @@ -589,7 +589,7 @@ # define RCC_PLLSAICFGR_PLLSAIN(n) ((n) << RCC_PLLSAICFGR_PLLSAIN_SHIFT) #define RCC_PLLSAICFGR_PLLSAIP_SHIFT (16) /* Bits 16-17: PLLSAI division factor for 48MHz clock */ #define RCC_PLLSAICFGR_PLLSAIP_MASK (3 << RCC_PLLSAICFGR_PLLSAIP_SHIFT) -# define RCC_PLLSAICFGR_PLLSAIP(n) ((n) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIP(n) ((((n)>>1)-1) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) #define RCC_PLLSAICFGR_PLLSAIQ_SHIFT (24) /* Bits 24-27: PLLSAI division factor for SAI clock */ #define RCC_PLLSAICFGR_PLLSAIQ_MASK (0x0F << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) # define RCC_PLLSAICFGR_PLLSAIQ(n) ((n) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h deleted file mode 100644 index 117c4da2faf..00000000000 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************************ - * arch/arm/src/stm32f7/chip/stm32_sdmmc.h - * - * Copyright (C) 2009, 2011-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. - * - ************************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H -#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H - -/************************************************************************************ - * Pre-processor Definitions - ************************************************************************************/ - -/* Register Offsets *****************************************************************/ - -#define STM32_SDMMC1_POWER_OFFSET 0x0000 /* SDIO power control register */ -#define STM32_SDMMC1_CLKCR_OFFSET 0x0004 /* SDI clock control register */ -#define STM32_SDMMC1_ARG_OFFSET 0x0008 /* SDIO argument register */ -#define STM32_SDMMC1_CMD_OFFSET 0x000c /* SDIO command register */ -#define STM32_SDMMC1_RESPCMD_OFFSET 0x0010 /* SDIO command response register */ -#define STM32_SDMMC1_RESP_OFFSET(n) (0x0010+4*(n)) -#define STM32_SDMMC1_RESP1_OFFSET 0x0014 /* SDIO response 1 register */ -#define STM32_SDMMC1_RESP2_OFFSET 0x0018 /* SDIO response 2 register */ -#define STM32_SDMMC1_RESP3_OFFSET 0x001c /* SDIO response 3 register */ -#define STM32_SDMMC1_RESP4_OFFSET 0x0020 /* SDIO response 4 register */ -#define STM32_SDMMC1_DTIMER_OFFSET 0x0024 /* SDIO data timer register */ -#define STM32_SDMMC1_DLEN_OFFSET 0x0028 /* SDIO data length register */ -#define STM32_SDMMC1_DCTRL_OFFSET 0x002c /* SDIO data control register */ -#define STM32_SDMMC1_DCOUNT_OFFSET 0x0030 /* SDIO data counter register */ -#define STM32_SDMMC1_STA_OFFSET 0x0034 /* SDIO status register */ -#define STM32_SDMMC1_ICR_OFFSET 0x0038 /* SDIO interrupt clear register */ -#define STM32_SDMMC1_MASK_OFFSET 0x003c /* SDIO mask register */ -#define STM32_SDMMC1_FIFOCNT_OFFSET 0x0048 /* SDIO FIFO counter register */ -#define STM32_SDMMC1_FIFO_OFFSET 0x0080 /* SDIO data FIFO register */ - -/* Register Addresses ***************************************************************/ - -#define STM32_SDMMC1_POWER (STM32_SDMMC1_BASE+STM32_SDMMC1_POWER_OFFSET) -#define STM32_SDMMC1_CLKCR (STM32_SDMMC1_BASE+STM32_SDMMC1_CLKCR_OFFSET) -#define STM32_SDMMC1_ARG (STM32_SDMMC1_BASE+STM32_SDMMC1_ARG_OFFSET) -#define STM32_SDMMC1_CMD (STM32_SDMMC1_BASE+STM32_SDMMC1_CMD_OFFSET) -#define STM32_SDMMC1_RESPCMD (STM32_SDMMC1_BASE+STM32_SDMMC1_RESPCMD_OFFSET) -#define STM32_SDMMC1_RESP(n) (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP_OFFSET(n)) -#define STM32_SDMMC1_RESP1 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP1_OFFSET) -#define STM32_SDMMC1_RESP2 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP2_OFFSET) -#define STM32_SDMMC1_RESP3 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP3_OFFSET) -#define STM32_SDMMC1_RESP4 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP4_OFFSET) -#define STM32_SDMMC1_DTIMER (STM32_SDMMC1_BASE+STM32_SDMMC1_DTIMER_OFFSET) -#define STM32_SDMMC1_DLEN (STM32_SDMMC1_BASE+STM32_SDMMC1_DLEN_OFFSET) -#define STM32_SDMMC1_DCTRL (STM32_SDMMC1_BASE+STM32_SDMMC1_DCTRL_OFFSET) -#define STM32_SDMMC1_DCOUNT (STM32_SDMMC1_BASE+STM32_SDMMC1_DCOUNT_OFFSET) -#define STM32_SDMMC1_STA (STM32_SDMMC1_BASE+STM32_SDMMC1_STA_OFFSET) -#define STM32_SDMMC1_ICR (STM32_SDMMC1_BASE+STM32_SDMMC1_ICR_OFFSET) -#define STM32_SDMMC1_MASK (STM32_SDMMC1_BASE+STM32_SDMMC1_MASK_OFFSET) -#define STM32_SDMMC1_FIFOCNT (STM32_SDMMC1_BASE+STM32_SDMMC1_FIFOCNT_OFFSET) -#define STM32_SDMMC1_FIFO (STM32_SDMMC1_BASE+STM32_SDMMC1_FIFO_OFFSET) - - -/* Register Bitfield Definitions ****************************************************/ - -#define SDIO_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ -#define SDIO_POWER_PWRCTRL_MASK (3 << SDIO_POWER_PWRCTRL_SHIFT) -# define SDIO_POWER_PWRCTRL_OFF (0 << SDIO_POWER_PWRCTRL_SHIFT) /* 00: Power-off: card clock stopped */ -# define SDIO_POWER_PWRCTRL_PWRUP (2 << SDIO_POWER_PWRCTRL_SHIFT) /* 10: Reserved power-up */ -# define SDIO_POWER_PWRCTRL_ON (3 << SDIO_POWER_PWRCTRL_SHIFT) /* 11: Power-on: card is clocked */ - -#define SDIO_POWER_RESET (0) /* Reset value */ - -#define SDIO_CLKCR_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */ -#define SDIO_CLKCR_CLKDIV_MASK (0xff << SDIO_CLKCR_CLKDIV_SHIFT) -#define SDIO_CLKCR_CLKEN (1 << 8) /* Bit 8: Clock enable bit */ -#define SDIO_CLKCR_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */ -#define SDIO_CLKCR_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */ -#define SDIO_CLKCR_WIDBUS_SHIFT (11) /* Bits 12-11: Wide bus mode enable bits */ -#define SDIO_CLKCR_WIDBUS_MASK (3 << SDIO_CLKCR_WIDBUS_SHIFT) -# define SDIO_CLKCR_WIDBUS_D1 (0 << SDIO_CLKCR_WIDBUS_SHIFT) /* 00: Default (SDIO_D0) */ -# define SDIO_CLKCR_WIDBUS_D4 (1 << SDIO_CLKCR_WIDBUS_SHIFT) /* 01: 4-wide (SDIO_D[3:0]) */ -# define SDIO_CLKCR_WIDBUS_D8 (2 << SDIO_CLKCR_WIDBUS_SHIFT) /* 10: 8-wide (SDIO_D[7:0]) */ -#define SDIO_CLKCR_NEGEDGE (1 << 13) /* Bit 13: SDIO_CK dephasing selection bit */ -#define SDIO_CLKCR_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */ - -#define SDIO_CLKCR_RESET (0) /* Reset value */ -#define SDIO_ARG_RESET (0) /* Reset value */ - -#define SDIO_CLKCR_CLKEN_BB (STM32_SDMMC1_CLKCR_BB + (8 * 4)) -#define SDIO_CLKCR_PWRSAV_BB (STM32_SDMMC1_CLKCR_BB + (9 * 4)) -#define SDIO_CLKCR_BYPASS_BB (STM32_SDMMC1_CLKCR_BB + (10 * 4)) -#define SDIO_CLKCR_NEGEDGE_BB (STM32_SDMMC1_CLKCR_BB + (13 * 4)) -#define SDIO_CLKCR_HWFC_EN_BB (STM32_SDMMC1_CLKCR_BB + (14 * 4)) - -#define SDIO_CMD_CMDINDEX_SHIFT (0) -#define SDIO_CMD_CMDINDEX_MASK (0x3f << SDIO_CMD_CMDINDEX_SHIFT) -#define SDIO_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */ -#define SDIO_CMD_WAITRESP_MASK (3 << SDIO_CMD_WAITRESP_SHIFT) -# define SDIO_CMD_NORESPONSE (0 << SDIO_CMD_WAITRESP_SHIFT) /* 00/10: No response */ -# define SDIO_CMD_SHORTRESPONSE (1 << SDIO_CMD_WAITRESP_SHIFT) /* 01: Short response */ -# define SDIO_CMD_LONGRESPONSE (3 << SDIO_CMD_WAITRESP_SHIFT) /* 11: Long response */ -#define SDIO_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */ -#define SDIO_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */ -#define SDIO_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */ -#define SDIO_CMD_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command */ -#define SDIO_CMD_ENDCMD (1 << 12) /* Bit 12: Enable CMD completion */ -#define SDIO_CMD_NIEN (1 << 13) /* Bit 13: not Interrupt Enable */ -#define SDIO_CMD_ATACMD (1 << 14) /* Bit 14: CE-ATA command */ - -#define SDIO_CMD_RESET (0) /* Reset value */ - -#define SDIO_CMD_WAITINT_BB (STM32_SDMMC1_CMD_BB + (8 * 4)) -#define SDIO_CMD_WAITPEND_BB (STM32_SDMMC1_CMD_BB + (9 * 4)) -#define SDIO_CMD_CPSMEN_BB (STM32_SDMMC1_CMD_BB + (10 * 4)) -#define SDIO_CMD_SUSPEND_BB (STM32_SDMMC1_CMD_BB + (11 * 4)) -#define SDIO_CMD_ENCMD_BB (STM32_SDMMC1_CMD_BB + (12 * 4)) -#define SDIO_CMD_NIEN_BB (STM32_SDMMC1_CMD_BB + (13 * 4)) -#define SDIO_CMD_ATACMD_BB (STM32_SDMMC1_CMD_BB + (14 * 4)) - -#define SDIO_RESPCMD_SHIFT (0) -#define SDIO_RESPCMD_MASK (0x3f << SDIO_RESPCMD_SHIFT) - -#define SDIO_DTIMER_RESET (0) /* Reset value */ - -#define SDIO_DLEN_SHIFT (0) -#define SDIO_DLEN_MASK (0x01ffffff << SDIO_DLEN_SHIFT) - -#define SDIO_DLEN_RESET (0) /* Reset value */ - -#define SDIO_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */ -#define SDIO_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */ -#define SDIO_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */ -#define SDIO_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */ -#define SDIO_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: Data block size */ -#define SDIO_DCTRL_DBLOCKSIZE_MASK (15 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_1BYTE (0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_2BYTES (1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_4BYTES (2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_8BYTES (3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_16BYTES (4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_32BYTES (5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_64BYTES (6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_128BYTES (7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_256BYTES (8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_512BYTES (9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_1KBYTE (10 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_2KBYTES (11 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_4KBYTES (12 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_8KBYTES (13 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_16KBYTES (14 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -#define SDIO_DCTRL_RWSTART (1 << 8) /* Bit 8: Read wait start */ -#define SDIO_DCTRL_RWSTOP (1 << 9) /* Bit 9: Read wait stop */ -#define SDIO_DCTRL_RWMOD (1 << 10) /* Bit 10: Read wait mode */ -#define SDIO_DCTRL_SDIOEN (1 << 11) /* Bit 11: SD I/O enable functions */ - -#define SDIO_DCTRL_RESET (0) /* Reset value */ - -#define SDIO_DCTRL_DTEN_BB (STM32_SDMMC1_DCTRL_BB + (0 * 4)) -#define SDIO_DCTRL_DTDIR_BB (STM32_SDMMC1_DCTRL_BB + (1 * 4)) -#define SDIO_DCTRL_DTMODE_BB (STM32_SDMMC1_DCTRL_BB + (2 * 4)) -#define SDIO_DCTRL_DMAEN_BB (STM32_SDMMC1_DCTRL_BB + (3 * 4)) -#define SDIO_DCTRL_RWSTART_BB (STM32_SDMMC1_DCTRL_BB + (8 * 4)) -#define SDIO_DCTRL_RWSTOP_BB (STM32_SDMMC1_DCTRL_BB + (9 * 4)) -#define SDIO_DCTRL_RWMOD_BB (STM32_SDMMC1_DCTRL_BB + (10 * 4)) -#define SDIO_DCTRL_SDIOEN_BB (STM32_SDMMC1_DCTRL_BB + (11 * 4)) - -#define SDIO_DATACOUNT_SHIFT (0) -#define SDIO_DATACOUNT_MASK (0x01ffffff << SDIO_DATACOUNT_SHIFT) - -#define SDIO_STA_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */ -#define SDIO_STA_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */ -#define SDIO_STA_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */ -#define SDIO_STA_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */ -#define SDIO_STA_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */ -#define SDIO_STA_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */ -#define SDIO_STA_CMDREND (1 << 6) /* Bit 6: Command response received */ -#define SDIO_STA_CMDSENT (1 << 7) /* Bit 7: Command sent */ -#define SDIO_STA_DATAEND (1 << 8) /* Bit 8: Data end */ -#define SDIO_STA_STBITERR (1 << 9) /* Bit 9: Start bit not detected */ -#define SDIO_STA_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */ -#define SDIO_STA_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */ -#define SDIO_STA_TXACT (1 << 12) /* Bit 12: Data transmit in progress */ -#define SDIO_STA_RXACT (1 << 13) /* Bit 13: Data receive in progress */ -#define SDIO_STA_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */ -#define SDIO_STA_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */ -#define SDIO_STA_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */ -#define SDIO_STA_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */ -#define SDIO_STA_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */ -#define SDIO_STA_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */ -#define SDIO_STA_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */ -#define SDIO_STA_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */ -#define SDIO_STA_SDIOIT (1 << 22) /* Bit 22: SDIO interrupt received */ -#define SDIO_STA_CEATAEND (1 << 23) /* Bit 23: CMD6 CE-ATA command completion */ - -#define SDIO_ICR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */ -#define SDIO_ICR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */ -#define SDIO_ICR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */ -#define SDIO_ICR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */ -#define SDIO_ICR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */ -#define SDIO_ICR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */ -#define SDIO_ICR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */ -#define SDIO_ICR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */ -#define SDIO_ICR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */ -#define SDIO_ICR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */ -#define SDIO_ICR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */ -#define SDIO_ICR_SDIOITC (1 << 22) /* Bit 22: SDIOIT flag clear bit */ -#define SDIO_ICR_CEATAENDC (1 << 23) /* Bit 23: CEATAEND flag clear bit */ - -#define SDIO_ICR_RESET 0x00c007ff -#define SDIO_ICR_STATICFLAGS 0x000005ff - -#define SDIO_MASK_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */ -#define SDIO_MASK_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */ -#define SDIO_MASK_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */ -#define SDIO_MASK_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */ -#define SDIO_MASK_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */ -#define SDIO_MASK_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */ -#define SDIO_MASK_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */ -#define SDIO_MASK_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */ -#define SDIO_MASK_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */ -#define SDIO_MASK_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */ -#define SDIO_MASK_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */ -#define SDIO_MASK_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */ -#define SDIO_MASK_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */ -#define SDIO_MASK_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */ -#define SDIO_MASK_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */ -#define SDIO_MASK_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */ -#define SDIO_MASK_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */ -#define SDIO_MASK_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */ -#define SDIO_MASK_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */ -#define SDIO_MASK_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */ -#define SDIO_MASK_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */ -#define SDIO_MASK_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */ -#define SDIO_MASK_SDIOITIE (1 << 22) /* Bit 22: SDIO mode interrupt received interrupt enable */ -#define SDIO_MASK_CEATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion interrupt enable */ - -#define SDIO_MASK_RESET (0) - -#define SDIO_FIFOCNT_SHIFT (0) -#define SDIO_FIFOCNT_MASK (0x01ffffff << SDIO_FIFOCNT_SHIFT) - -#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H */ - diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h new file mode 100644 index 00000000000..e0d52edc4ef --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h @@ -0,0 +1,224 @@ + /* arch/arm/src/stm32f7/chip/stm32f74xx77xx_sdmmc.h + * + * Copyright (C) 2009, 2011-2016 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX77XX_SDMMC_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX77XX_SDMMC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_SDMMC_POWER_OFFSET 0x0000 /* SDMMC power control register */ +#define STM32_SDMMC_CLKCR_OFFSET 0x0004 /* SDMMC clock control register */ +#define STM32_SDMMC_ARG_OFFSET 0x0008 /* SDMMC argument register */ +#define STM32_SDMMC_CMD_OFFSET 0x000c /* SDMMC command register */ +#define STM32_SDMMC_RESPCMD_OFFSET 0x0010 /* SDMMC command response register */ +#define STM32_SDMMC_RESP_OFFSET(n) (0x0010+4*(n)) +#define STM32_SDMMC_RESP1_OFFSET 0x0014 /* SDMMC response 1 register */ +#define STM32_SDMMC_RESP2_OFFSET 0x0018 /* SDMMC response 2 register */ +#define STM32_SDMMC_RESP3_OFFSET 0x001c /* SDMMC response 3 register */ +#define STM32_SDMMC_RESP4_OFFSET 0x0020 /* SDMMC response 4 register */ +#define STM32_SDMMC_DTIMER_OFFSET 0x0024 /* SDMMC data timer register */ +#define STM32_SDMMC_DLEN_OFFSET 0x0028 /* SDMMC data length register */ +#define STM32_SDMMC_DCTRL_OFFSET 0x002c /* SDMMC data control register */ +#define STM32_SDMMC_DCOUNT_OFFSET 0x0030 /* SDMMC data counter register */ +#define STM32_SDMMC_STA_OFFSET 0x0034 /* SDMMC status register */ +#define STM32_SDMMC_ICR_OFFSET 0x0038 /* SDMMC interrupt clear register */ +#define STM32_SDMMC_MASK_OFFSET 0x003c /* SDMMC mask register */ +#define STM32_SDMMC_FIFOCNT_OFFSET 0x0048 /* SDMMC FIFO counter register */ +#define STM32_SDMMC_FIFO_OFFSET 0x0080 /* SDMMC data FIFO register */ + + +/* Register Bitfield Definitions ****************************************************/ + +#define STM32_SDMMC_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ +#define STM32_SDMMC_POWER_PWRCTRL_MASK (3 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) +# define STM32_SDMMC_POWER_PWRCTRL_OFF (0 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) /* 00: Power-off: card clock stopped */ +# define STM32_SDMMC_POWER_PWRCTRL_PWRUP (2 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) /* 10: Reserved power-up */ +# define STM32_SDMMC_POWER_PWRCTRL_ON (3 << STM32_SDMMC_POWER_PWRCTRL_SHIFT) /* 11: Power-on: card is clocked */ + +#define STM32_SDMMC_POWER_RESET (0) /* Reset value */ + +#define STM32_SDMMC_CLKCR_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */ +#define STM32_SDMMC_CLKCR_CLKDIV_MASK (0xff << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#define STM32_SDMMC_CLKCR_CLKEN (1 << 8) /* Bit 8: Clock enable bit */ +#define STM32_SDMMC_CLKCR_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */ +#define STM32_SDMMC_CLKCR_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */ +#define STM32_SDMMC_CLKCR_WIDBUS_SHIFT (11) /* Bits 12-11: Wide bus mode enable bits */ +#define STM32_SDMMC_CLKCR_WIDBUS_MASK (3 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) +# define STM32_SDMMC_CLKCR_WIDBUS_D1 (0 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) /* 00: Default (STM32_SDMMC_D0) */ +# define STM32_SDMMC_CLKCR_WIDBUS_D4 (1 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) /* 01: 4-wide (STM32_SDMMC_D[3:0]) */ +# define STM32_SDMMC_CLKCR_WIDBUS_D8 (2 << STM32_SDMMC_CLKCR_WIDBUS_SHIFT) /* 10: 8-wide (STM32_SDMMC_D[7:0]) */ +#define STM32_SDMMC_CLKCR_NEGEDGE (1 << 13) /* Bit 13: STM32_SDMMC_CK dephasing selection bit */ +#define STM32_SDMMC_CLKCR_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */ + +#define STM32_SDMMC_CLKCR_RESET (0) /* Reset value */ + +#define STM32_SDMMC_ARG_RESET (0) /* Reset value */ + +#define STM32_SDMMC_CMD_CMDINDEX_SHIFT (0) +#define STM32_SDMMC_CMD_CMDINDEX_MASK (0x3f << STM32_SDMMC_CMD_CMDINDEX_SHIFT) +#define STM32_SDMMC_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */ +#define STM32_SDMMC_CMD_WAITRESP_MASK (3 << STM32_SDMMC_CMD_WAITRESP_SHIFT) +# define STM32_SDMMC_CMD_NORESPONSE (0 << STM32_SDMMC_CMD_WAITRESP_SHIFT) /* 00/10: No response */ +# define STM32_SDMMC_CMD_SHORTRESPONSE (1 << STM32_SDMMC_CMD_WAITRESP_SHIFT) /* 01: Short response */ +# define STM32_SDMMC_CMD_LONGRESPONSE (3 << STM32_SDMMC_CMD_WAITRESP_SHIFT) /* 11: Long response */ +#define STM32_SDMMC_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */ +#define STM32_SDMMC_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */ +#define STM32_SDMMC_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */ +#define STM32_SDMMC_CMD_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command */ +#define STM32_SDMMC_CMD_ENDCMD (1 << 12) /* Bit 12: Enable CMD completion */ +#define STM32_SDMMC_CMD_NIEN (1 << 13) /* Bit 13: not Interrupt Enable */ +#define STM32_SDMMC_CMD_ATACMD (1 << 14) /* Bit 14: CE-ATA command */ + +#define STM32_SDMMC_CMD_RESET (0) /* Reset value */ + +#define STM32_SDMMC_RESPCMD_SHIFT (0) +#define STM32_SDMMC_RESPCMD_MASK (0x3f << STM32_SDMMC_RESPCMD_SHIFT) + +#define STM32_SDMMC_DTIMER_RESET (0) /* Reset value */ + +#define STM32_SDMMC_DLEN_SHIFT (0) +#define STM32_SDMMC_DLEN_MASK (0x01ffffff << STM32_SDMMC_DLEN_SHIFT) + +#define STM32_SDMMC_DLEN_RESET (0) /* Reset value */ + +#define STM32_SDMMC_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */ +#define STM32_SDMMC_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */ +#define STM32_SDMMC_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */ +#define STM32_SDMMC_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */ +#define STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: Data block size */ +#define STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK (15 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_1BYTE (0 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_2BYTES (1 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_4BYTES (2 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_8BYTES (3 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_16BYTES (4 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_32BYTES (5 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_64BYTES (6 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_128BYTES (7 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_256BYTES (8 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_512BYTES (9 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_1KBYTE (10 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_2KBYTES (11 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_4KBYTES (12 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_8KBYTES (13 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +# define STM32_SDMMC_DCTRL_16KBYTES (14 << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT) +#define STM32_SDMMC_DCTRL_RWSTART (1 << 8) /* Bit 8: Read wait start */ +#define STM32_SDMMC_DCTRL_RWSTOP (1 << 9) /* Bit 9: Read wait stop */ +#define STM32_SDMMC_DCTRL_RWMOD (1 << 10) /* Bit 10: Read wait mode */ +#define STM32_SDMMC_DCTRL_SDIOEN (1 << 11) /* Bit 11: SD I/O enable functions */ + +#define STM32_SDMMC_DCTRL_RESET (0) /* Reset value */ + +#define STM32_SDMMC_DCOUNT_SHIFT (0) +#define STM32_SDMMC_DCOUNT_MASK (0x01ffffff << STM32_SDMMC_DCOUNT_SHIFT) + +#define STM32_SDMMC_STA_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */ +#define STM32_SDMMC_STA_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */ +#define STM32_SDMMC_STA_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */ +#define STM32_SDMMC_STA_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */ +#define STM32_SDMMC_STA_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */ +#define STM32_SDMMC_STA_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */ +#define STM32_SDMMC_STA_CMDREND (1 << 6) /* Bit 6: Command response received */ +#define STM32_SDMMC_STA_CMDSENT (1 << 7) /* Bit 7: Command sent */ +#define STM32_SDMMC_STA_DATAEND (1 << 8) /* Bit 8: Data end */ +#define STM32_SDMMC_STA_STBITERR (1 << 9) /* Bit 9: Start bit not detected */ +#define STM32_SDMMC_STA_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */ +#define STM32_SDMMC_STA_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */ +#define STM32_SDMMC_STA_TXACT (1 << 12) /* Bit 12: Data transmit in progress */ +#define STM32_SDMMC_STA_RXACT (1 << 13) /* Bit 13: Data receive in progress */ +#define STM32_SDMMC_STA_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */ +#define STM32_SDMMC_STA_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */ +#define STM32_SDMMC_STA_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */ +#define STM32_SDMMC_STA_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */ +#define STM32_SDMMC_STA_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */ +#define STM32_SDMMC_STA_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */ +#define STM32_SDMMC_STA_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */ +#define STM32_SDMMC_STA_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */ +#define STM32_SDMMC_STA_SDIOIT (1 << 22) /* Bit 22: SDIO interrupt received */ +#define STM32_SDMMC_STA_CEATAEND (1 << 23) /* Bit 23: CMD6 CE-ATA command completion */ + +#define STM32_SDMMC_ICR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */ +#define STM32_SDMMC_ICR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */ +#define STM32_SDMMC_ICR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */ +#define STM32_SDMMC_ICR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */ +#define STM32_SDMMC_ICR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */ +#define STM32_SDMMC_ICR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */ +#define STM32_SDMMC_ICR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */ +#define STM32_SDMMC_ICR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */ +#define STM32_SDMMC_ICR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */ +#define STM32_SDMMC_ICR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */ +#define STM32_SDMMC_ICR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */ +#define STM32_SDMMC_ICR_SDIOITC (1 << 22) /* Bit 22: SDIOIT flag clear bit */ +#define STM32_SDMMC_ICR_CEATAENDC (1 << 23) /* Bit 23: CEATAEND flag clear bit */ + +#define STM32_SDMMC_ICR_RESET 0x00c007ff +#define STM32_SDMMC_ICR_STATICFLAGS 0x000005ff + +#define STM32_SDMMC_MASK_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */ +#define STM32_SDMMC_MASK_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */ +#define STM32_SDMMC_MASK_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */ +#define STM32_SDMMC_MASK_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */ +#define STM32_SDMMC_MASK_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */ +#define STM32_SDMMC_MASK_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */ +#define STM32_SDMMC_MASK_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */ +#define STM32_SDMMC_MASK_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */ +#define STM32_SDMMC_MASK_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */ +#define STM32_SDMMC_MASK_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */ +#define STM32_SDMMC_MASK_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */ +#define STM32_SDMMC_MASK_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */ +#define STM32_SDMMC_MASK_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */ +#define STM32_SDMMC_MASK_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */ +#define STM32_SDMMC_MASK_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */ +#define STM32_SDMMC_MASK_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */ +#define STM32_SDMMC_MASK_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */ +#define STM32_SDMMC_MASK_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */ +#define STM32_SDMMC_MASK_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */ +#define STM32_SDMMC_MASK_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */ +#define STM32_SDMMC_MASK_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */ +#define STM32_SDMMC_MASK_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */ +#define STM32_SDMMC_MASK_SDIOITIE (1 << 22) /* Bit 22: SDIO mode interrupt received interrupt enable */ +#define STM32_SDMMC_MASK_CEATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion interrupt enable */ + +#define STM32_SDMMC_MASK_RESET (0) + +#define STM32_SDMMC_FIFOCNT_SHIFT (0) +#define STM32_SDMMC_FIFOCNT_MASK (0x0ffffff << STM32_SDMMC_FIFOCNT_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX77XX_SDMMC_H */ + diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h index 4c60603c95a..b2ded840dfb 100644 --- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h +++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h @@ -943,7 +943,7 @@ #define GPIO_SDMMC2_CMD (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN7) #define GPIO_SDMMC2_D0_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14) #define GPIO_SDMMC2_D1_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15) -#define GPIO_SDMMC2_D2_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN) +#define GPIO_SDMMC2_D2_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) #define GPIO_SDMMC2_D3_1 (GPIO_ALT|GPIO_AF10|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4) #define GPIO_SDMMC2_D0_2 (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN9) #define GPIO_SDMMC2_D1_2 (GPIO_ALT|GPIO_AF11|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTG|GPIO_PIN10) diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h index a63cc1911a4..a1b9ed4e321 100644 --- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h +++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h @@ -595,7 +595,7 @@ # define RCC_PLLI2SCFGR_PLLI2SN(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SN_SHIFT) #define RCC_PLLI2SCFGR_PLLI2SP_SHIFT (16) /* Bits 16-17: PLLI2S division factor for SPDIFRX clock */ #define RCC_PLLI2SCFGR_PLLI2SP_MASK (3 << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) -# define RCC_PLLI2SCFGR_PLLI2SP(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SP(n) ((((n)>>1)-1) << RCC_PLLI2SCFGR_PLLI2SP_SHIFT) #define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT (24) /* Bits 24-27: PLLI2S division factor for SAIs clock */ #define RCC_PLLI2SCFGR_PLLI2SQ_MASK (15 << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) # define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) @@ -610,7 +610,7 @@ # define RCC_PLLSAICFGR_PLLSAIN(n) ((n) << RCC_PLLSAICFGR_PLLSAIN_SHIFT) #define RCC_PLLSAICFGR_PLLSAIP_SHIFT (16) /* Bits 16-17: PLLSAI division factor for 48MHz clock */ #define RCC_PLLSAICFGR_PLLSAIP_MASK (3 << RCC_PLLSAICFGR_PLLSAIP_SHIFT) -# define RCC_PLLSAICFGR_PLLSAIP(n) ((n) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) +# define RCC_PLLSAICFGR_PLLSAIP(n) ((((n)>>1)-1) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) #define RCC_PLLSAICFGR_PLLSAIQ_SHIFT (24) /* Bits 24-27: PLLSAI division factor for SAI clock */ #define RCC_PLLSAICFGR_PLLSAIQ_MASK (0x0F << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) # define RCC_PLLSAICFGR_PLLSAIQ(n) ((n) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) diff --git a/arch/arm/src/stm32f7/stm32_allocateheap.c b/arch/arm/src/stm32f7/stm32_allocateheap.c index 541e0654b1f..8b21ad68b76 100644 --- a/arch/arm/src/stm32f7/stm32_allocateheap.c +++ b/arch/arm/src/stm32f7/stm32_allocateheap.c @@ -41,6 +41,7 @@ #include #include +#include #include #include diff --git a/arch/arm/src/stm32f7/stm32_irq.c b/arch/arm/src/stm32f7/stm32_irq.c index eb7a8e1b868..758f32b1477 100644 --- a/arch/arm/src/stm32f7/stm32_irq.c +++ b/arch/arm/src/stm32f7/stm32_irq.c @@ -656,7 +656,7 @@ int up_prioritize_irq(int irq, int priority) uint32_t regval; int shift; - DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < STM32_IRQ_NIRQS && + DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS && (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN); if (irq < STM32_IRQ_FIRST) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 16473094b5a..d7d78f3006e 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -37,8 +37,6 @@ * Included Files ****************************************************************************/ -#include "stm32_sdmmc.h" - #include #include @@ -65,12 +63,9 @@ #include "stm32_dma.h" #include "stm32_gpio.h" +#include "stm32_sdmmc.h" - -/* TODO STM32F7_SDMMC2 - */ - -#ifdef CONFIG_STM32F7_SDMMC1 +#if defined(CONFIG_STM32F7_SDMMC1) || defined(CONFIG_STM32F7_SDMMC2) /**************************************************************************** * Pre-processor Definitions @@ -80,27 +75,27 @@ /* Required system configuration options: * * CONFIG_ARCH_DMA - Enable architecture-specific DMA subsystem - * initialization. Required if CONFIG_SDIO_DMA is enabled. + * initialization. Required if CONFIG_SDMMC[1|2]_DMA is enabled. * CONFIG_STM32F7_DMA2 - Enable STM32 DMA2 support. Required if - * CONFIG_SDIO_DMA is enabled + * CONFIG_SDMMC[1|2]_DMA is enabled * CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support. * * Driver-specific configuration options: * * CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking - * APIs to manage concurrent accesses on the SDIO bus. This is not + * APIs to manage concurrent accesses on the SDMMC bus. This is not * needed for the simple case of a single SD card, for example. - * CONFIG_SDIO_DMA - Enable SDIO. This is a marginally optional. For - * most usages, SDIO will cause data overruns if used without DMA. + * CONFIG_SDIO_DMA - Enable SDMMC. This is a marginally optional. For + * most usages, SDMMC will cause data overruns if used without DMA. * NOTE the above system DMA configuration options. - * CONFIG_SDIO_WIDTH_D1_ONLY - This may be selected to force the driver + * CONFIG_SDMMC_WIDTH_D1_ONLY - This may be selected to force the driver * operate with only a single data line (the default is to use all * 4 SD data lines). - * CONFIG_SDIO_PRI - SDIO interrupt priority. This setting is not very + * CONFIG_SDMMC_PRI - SDMMC interrupt priority. This setting is not very * important since interrupt nesting is not currently supported. - * CONFIG_SDM_DMAPRIO - SDIO DMA priority. This can be selecte if + * CONFIG_SDMMMC_DMAPRIO - SDMMC DMA priority. This can be selecte if * CONFIG_SDIO_DMA is enabled. - * CONFIG_SDIO_XFRDEBUG - Enables some very low-level debug output + * CONFIG_CONFIG_STM32F7_SDMMC_XFRDEBUG - Enables some very low-level debug output * This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_INFO */ @@ -116,52 +111,75 @@ # error "Callback support requires CONFIG_SCHED_WORKQUEUE" #endif -#ifndef CONFIG_SDIO_PRI -# define CONFIG_SDIO_PRI NVIC_SYSH_PRIORITY_DEFAULT +#ifdef CONFIG_STM32F7_SDMMC1 +# ifndef CONFIG_SDMMC1_PRI +# define CONFIG_SDMMC1_PRI NVIC_SYSH_PRIORITY_DEFAULT +# endif + +# ifdef CONFIG_SDIO_DMA +# ifndef CONFIG_SDMMC1_DMAPRIO +# define CONFIG_SDMMC1_DMAPRIO DMA_SCR_PRIVERYHI +# endif +# if (CONFIG_SDMMC1_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SDMMC1_DMAPRIO" +# endif +# else +# undef CONFIG_SDMMC1_DMAPRIO +# endif #endif -#ifdef CONFIG_SDIO_DMA -# ifndef CONFIG_SDIO_DMAPRIO -# define CONFIG_SDIO_DMAPRIO DMA_SCR_PRIVERYHI +#ifdef CONFIG_STM32F7_SDMMC2 +# ifndef CONFIG_SDMMC2_PRI +# define CONFIG_SDMMC2_PRI NVIC_SYSH_PRIORITY_DEFAULT # endif -# if (CONFIG_SDIO_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 -# error "Illegal value for CONFIG_SDIO_DMAPRIO" + +# ifdef CONFIG_SDIO_DMA +# ifndef CONFIG_SDMMC2_DMAPRIO +# define CONFIG_SDMMC2_DMAPRIO DMA_SCR_PRIVERYHI +# endif +# if (CONFIG_SDMMC2_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SDMMC2_DMAPRIO" +# endif +# else +# undef CONFIG_SDMMC2_DMAPRIO # endif -#else -# undef CONFIG_SDIO_DMAPRIO #endif #if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_FEATURES) -# undef CONFIG_SDIO_XFRDEBUG +# undef CONFIG_CONFIG_STM32F7_SDMMC_XFRDEBUG #endif /* Friendly CLKCR bit re-definitions ****************************************/ -#define SDIO_CLKCR_RISINGEDGE (0) -#define SDIO_CLKCR_FALLINGEDGE SDIO_CLKCR_NEGEDGE +#define STM32_CLKCR_RISINGEDGE (0) +#define STM32_CLKCR_FALLINGEDGE STM32_CLKCR_NEGEDGE -/* Mode dependent settings. These depend on clock devisor settings that must - * be defined in the board-specific board.h header file: SDIO_INIT_CLKDIV, - * SDIO_MMCXFR_CLKDIV, and SDIO_SDXFR_CLKDIV. +/* Mode dependent settings. These depend on clock divisor settings that must + * be defined in the board-specific board.h header file: STM32_SDMMC_INIT_CLKDIV, + * STM32_SDMMC_MMCXFR_CLKDIV, and STM32_SDMMC_SDXFR_CLKDIV. */ -#define STM32_CLCKCR_INIT (SDMMC1_INIT_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ - SDIO_CLKCR_WIDBUS_D1) -#define SDIO_CLKCR_MMCXFR (SDMMC1_MMCXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ - SDIO_CLKCR_WIDBUS_D1) -#define SDIO_CLCKR_SDXFR (SDMMC1_SDXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ - SDIO_CLKCR_WIDBUS_D1) -#define SDIO_CLCKR_SDWIDEXFR (SDMMC1_SDXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ - SDIO_CLKCR_WIDBUS_D4) +#define STM32_CLCKCR_INIT (STM32_SDMMC_INIT_CLKDIV | \ + STM32_CLKCR_RISINGEDGE | \ + STM32_SDMMC_CLKCR_WIDBUS_D1) +#define STM32_SDMMC_CLKCR_MMCXFR (STM32_SDMMC_MMCXFR_CLKDIV | \ + STM32_CLKCR_RISINGEDGE | \ + STM32_SDMMC_CLKCR_WIDBUS_D1) +#define STM32_SDMMC_CLCKR_SDXFR (STM32_SDMMC_SDXFR_CLKDIV | \ + STM32_CLKCR_RISINGEDGE | \ + STM32_SDMMC_CLKCR_WIDBUS_D1) +#define STM32_SDMMC_CLCKR_SDWIDEXFR (STM32_SDMMC_SDXFR_CLKDIV | \ + STM32_CLKCR_RISINGEDGE | \ + STM32_SDMMC_CLKCR_WIDBUS_D4) /* Timing */ -#define SDIO_CMDTIMEOUT (100000) -#define SDIO_LONGTIMEOUT (0x7fffffff) +#define SDMMC_CMDTIMEOUT (100000) +#define SDMMC_LONGTIMEOUT (0x7fffffff) /* Big DTIMER setting */ -#define SDIO_DTIMER_DATATIMEOUT (0x000fffff) +#define SDMMC_DTIMER_DATATIMEOUT (0x000fffff) /* DMA channel/stream configuration register settings. The following * must be selected. The DMA driver will select the remaining fields. @@ -173,76 +191,120 @@ */ -/* STM32 stream configuration register (SCR) settings. */ +/* STM32 stream configuration register (SCR) settings base settings sans + * priority. + */ -#define SDIO_RXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_P2M|DMA_SCR_MINC | \ +# define SDMMC_RXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_P2M|DMA_SCR_MINC | \ DMA_SCR_PSIZE_32BITS | DMA_SCR_MSIZE_32BITS | \ - CONFIG_SDIO_DMAPRIO | DMA_SCR_PBURST_INCR4 | \ - DMA_SCR_MBURST_INCR4) -#define SDIO_TXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_M2P | DMA_SCR_MINC | \ + DMA_SCR_PBURST_INCR4 | DMA_SCR_MBURST_INCR4) +# define SDMMC_TXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_M2P | DMA_SCR_MINC | \ DMA_SCR_PSIZE_32BITS | DMA_SCR_MSIZE_32BITS | \ - CONFIG_SDIO_DMAPRIO | DMA_SCR_PBURST_INCR4 | \ - DMA_SCR_MBURST_INCR4) + DMA_SCR_PBURST_INCR4 | DMA_SCR_MBURST_INCR4) -/* SDIO DMA Channel/Stream selection. There +#ifdef DMAMAP_SDMMC1 + +/* SDMMC DMA Channel/Stream selection. There * are multiple DMA stream options that must be dis-ambiguated in the board.h * file. */ -#define SDIO_DMACHAN DMAMAP_SDMMC1 +# define SDMMC1_DMACHAN DMAMAP_SDMMC1 +#endif + + +#ifdef DMAMAP_SDMMC2 + +/* SDMMC DMA Channel/Stream selection. There + * are multiple DMA stream options that must be dis-ambiguated in the board.h + * file. + */ + +# define SDMMC2_DMACHAN DMAMAP_SDMMC2 +#endif /* FIFO sizes */ -#define SDIO_HALFFIFO_WORDS (8) -#define SDIO_HALFFIFO_BYTES (8*4) +#define SDMMC_HALFFIFO_WORDS (8) +#define SDMMC_HALFFIFO_BYTES (8*4) /* Data transfer interrupt mask bits */ -#define SDIO_RECV_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ - SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE | \ - SDIO_MASK_RXFIFOHFIE | SDIO_MASK_STBITERRIE) -#define SDIO_SEND_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ - SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | \ - SDIO_MASK_TXFIFOHEIE | SDIO_MASK_STBITERRIE) -#define SDIO_DMARECV_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ - SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE | \ - SDIO_MASK_STBITERRIE) -#define SDIO_DMASEND_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ - SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | \ - SDIO_MASK_STBITERRIE) +#define STM32_SDMMC_RECV_MASK (STM32_SDMMC_MASK_DCRCFAILIE | \ + STM32_SDMMC_MASK_DTIMEOUTIE | \ + STM32_SDMMC_MASK_DATAENDIE | \ + STM32_SDMMC_MASK_RXOVERRIE | \ + STM32_SDMMC_MASK_RXFIFOHFIE | \ + STM32_SDMMC_MASK_STBITERRIE) + +#define STM32_SDMMC_SEND_MASK (STM32_SDMMC_MASK_DCRCFAILIE | \ + STM32_SDMMC_MASK_DTIMEOUTIE | \ + STM32_SDMMC_MASK_DATAENDIE | \ + STM32_SDMMC_MASK_TXUNDERRIE | \ + STM32_SDMMC_MASK_TXFIFOHEIE | \ + STM32_SDMMC_MASK_STBITERRIE) + +#define STM32_SDMMC_DMARECV_MASK (STM32_SDMMC_MASK_DCRCFAILIE | \ + STM32_SDMMC_MASK_DTIMEOUTIE | \ + STM32_SDMMC_MASK_DATAENDIE | \ + STM32_SDMMC_MASK_RXOVERRIE | \ + STM32_SDMMC_MASK_STBITERRIE) + +#define STM32_SDMMC_DMASEND_MASK (STM32_SDMMC_MASK_DCRCFAILIE | \ + STM32_SDMMC_MASK_DTIMEOUTIE | \ + STM32_SDMMC_MASK_DATAENDIE | \ + STM32_SDMMC_MASK_TXUNDERRIE | \ + STM32_SDMMC_MASK_STBITERRIE) /* Event waiting interrupt mask bits */ -#define SDIO_CMDDONE_STA (SDIO_STA_CMDSENT) -#define SDIO_RESPDONE_STA (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL | \ - SDIO_STA_CMDREND) -#define SDIO_XFRDONE_STA (0) +#define STM32_SDMMC_CMDDONE_STA (STM32_SDMMC_STA_CMDSENT) -#define SDIO_CMDDONE_MASK (SDIO_MASK_CMDSENTIE) -#define SDIO_RESPDONE_MASK (SDIO_MASK_CCRCFAILIE | SDIO_MASK_CTIMEOUTIE | \ - SDIO_MASK_CMDRENDIE) -#define SDIO_XFRDONE_MASK (0) +#define STM32_SDMMC_RESPDONE_STA (STM32_SDMMC_STA_CTIMEOUT | \ + STM32_SDMMC_STA_CCRCFAIL | \ + STM32_SDMMC_STA_CMDREND) -#define SDIO_CMDDONE_ICR (SDIO_ICR_CMDSENTC | SDIO_ICR_DBCKENDC) -#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC | \ - SDIO_ICR_CMDRENDC | SDIO_ICR_DBCKENDC) -#define SDIO_XFRDONE_ICR (SDIO_ICR_DATAENDC | SDIO_ICR_DCRCFAILC | \ - SDIO_ICR_DTIMEOUTC | SDIO_ICR_RXOVERRC | \ - SDIO_ICR_TXUNDERRC | SDIO_ICR_STBITERRC | \ - SDIO_ICR_DBCKENDC) +#define STM32_SDMMC_XFRDONE_STA (0) -#define SDIO_WAITALL_ICR (SDIO_CMDDONE_ICR | SDIO_RESPDONE_ICR | \ - SDIO_XFRDONE_ICR | SDIO_ICR_DBCKENDC) +#define STM32_SDMMC_CMDDONE_MASK (STM32_SDMMC_MASK_CMDSENTIE) + +#define STM32_SDMMC_RESPDONE_MASK (STM32_SDMMC_MASK_CCRCFAILIE | \ + STM32_SDMMC_MASK_CTIMEOUTIE | \ + STM32_SDMMC_MASK_CMDRENDIE) + +#define STM32_SDMMC_XFRDONE_MASK (0) + +#define STM32_SDMMC_CMDDONE_ICR (STM32_SDMMC_ICR_CMDSENTC | \ + STM32_SDMMC_ICR_DBCKENDC) + +#define STM32_SDMMC_RESPDONE_ICR (STM32_SDMMC_ICR_CTIMEOUTC | \ + STM32_SDMMC_ICR_CCRCFAILC | \ + STM32_SDMMC_ICR_CMDRENDC | \ + STM32_SDMMC_ICR_DBCKENDC) + +#define STM32_SDMMC_XFRDONE_ICR (STM32_SDMMC_ICR_DATAENDC | \ + STM32_SDMMC_ICR_DCRCFAILC | \ + STM32_SDMMC_ICR_DTIMEOUTC | \ + STM32_SDMMC_ICR_RXOVERRC | \ + STM32_SDMMC_ICR_TXUNDERRC | \ + STM32_SDMMC_ICR_STBITERRC | \ + STM32_SDMMC_ICR_DBCKENDC) + +#define STM32_SDMMC_WAITALL_ICR (STM32_SDMMC_CMDDONE_ICR | \ + STM32_SDMMC_RESPDONE_ICR | \ + STM32_SDMMC_XFRDONE_ICR | \ + STM32_SDMMC_ICR_DBCKENDC) /* Let's wait until we have both SDIO transfer complete and DMA complete. */ -#define SDIO_XFRDONE_FLAG (1) -#define SDIO_DMADONE_FLAG (2) -#define SDIO_ALLDONE (3) + +#define SDMMC_XFRDONE_FLAG (1) +#define SDMMC_DMADONE_FLAG (2) +#define SDMMC_ALLDONE (3) /* Register logging support */ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG # ifdef CONFIG_SDIO_DMA # define SAMPLENDX_BEFORE_SETUP 0 # define SAMPLENDX_BEFORE_ENABLE 1 @@ -262,13 +324,27 @@ * Private Types ****************************************************************************/ -/* This structure defines the state of the STM32 SDIO interface */ +/* This structure defines the state of the STM32 SDMMC interface */ struct stm32_dev_s { struct sdio_dev_s dev; /* Standard, base SDIO interface */ /* STM32-specific extensions */ + uint32_t base; + int nirq; + xcpt_t handler; +#ifdef CONFIG_ARCH_IRQPRIO + int irqprio; +#endif +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + uint32_t d0_gpio; + xcpt_t wrchandler; +#endif +#ifdef CONFIG_SDIO_DMA + uint32_t dmapri; +#endif + /* Event support */ sem_t waitsem; /* Implements event waiting */ @@ -295,7 +371,7 @@ struct stm32_dev_s bool widebus; /* Required for DMA support */ #ifdef CONFIG_SDIO_DMA - volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */ + volatile uint8_t xfrflags; /* Used to synchronize SDMMC and DMA completion events */ bool dmamode; /* true: DMA mode transfer */ DMA_HANDLE dma; /* Handle for DMA channel */ #endif @@ -303,7 +379,7 @@ struct stm32_dev_s /* Register logging support */ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG struct stm32_sdioregs_s { uint8_t power; @@ -332,20 +408,24 @@ struct stm32_sampleregs_s /* Low-level helpers ********************************************************/ +static inline void sdmmc_putreg32(struct stm32_dev_s *priv, uint32_t value,\ + int offset); +static inline uint32_t sdmmc_getreg32(struct stm32_dev_s *priv, int offset); static void stm32_takesem(struct stm32_dev_s *priv); #define stm32_givesem(priv) (sem_post(&priv->waitsem)) -static inline void stm32_setclkcr(uint32_t clkcr); +static inline void stm32_setclkcr(struct stm32_dev_s *priv, uint32_t clkcr); static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, sdio_eventset_t waitevents, sdio_eventset_t wkupevents); static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask); -static void stm32_setpwrctrl(uint32_t pwrctrl); -static inline uint32_t stm32_getpwrctrl(void); +static void stm32_setpwrctrl(struct stm32_dev_s *priv, uint32_t pwrctrl); +static inline uint32_t stm32_getpwrctrl(struct stm32_dev_s *priv); /* DMA Helpers **************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static void stm32_sampleinit(void); -static void stm32_sdiosample(struct stm32_sdioregs_s *regs); +static void stm32_sdiosample(struct stm32_dev_s *priv, + struct stm32_sdioregs_s *regs); static void stm32_sample(struct stm32_dev_s *priv, int index); static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg); static void stm32_dumpsample(struct stm32_dev_s *priv, @@ -364,8 +444,9 @@ static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg); /* Data Transfer Helpers ****************************************************/ static uint8_t stm32_log2(uint16_t value); -static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl); -static void stm32_datadisable(void); +static void stm32_dataconfig(struct stm32_dev_s *priv, uint32_t timeout, + uint32_t dlen, uint32_t dctrl); +static void stm32_datadisable(struct stm32_dev_s *priv); static void stm32_sendfifo(struct stm32_dev_s *priv); static void stm32_recvfifo(struct stm32_dev_s *priv); static void stm32_eventtimeout(int argc, uint32_t arg); @@ -374,9 +455,22 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupeven /* Interrupt Handling *******************************************************/ -static int stm32_interrupt(int irq, void *context); +static int stm32_sdmmc_interrupt(struct stm32_dev_s *sdmmc_dev); + +#ifdef CONFIG_STM32F7_SDMMC1 +static int stm32_sdmmc1_interrupt(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_SDMMC2 +static int stm32_sdmmc2_interrupt(int irq, void *context); +#endif + #ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE -static int stm32_rdyinterrupt(int irq, void *context); +#ifdef CONFIG_STM32F7_SDMMC1 +static int stm32_sdmmc1_rdyinterrupt(int irq, void *context); +#endif +#ifdef CONFIG_STM32F7_SDMMC2 +static int stm32_sdmmc2_rdyinterrupt(int irq, void *context); +#endif #endif /* SDIO interface methods ***************************************************/ @@ -444,13 +538,13 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, /* Initialization/uninitialization/reset ************************************/ static void stm32_callback(void *arg); -static void stm32_default(void); +static void stm32_default(struct stm32_dev_s *priv); /**************************************************************************** * Private Data ****************************************************************************/ - -struct stm32_dev_s g_sdiodev = +#ifdef CONFIG_STM32F7_SDMMC1 +struct stm32_dev_s g_sdmmcdev1 = { .dev = { @@ -490,11 +584,80 @@ struct stm32_dev_s g_sdiodev = .dmasendsetup = stm32_dmasendsetup, #endif }, + .base = STM32_SDMMC1_BASE, + .nirq = STM32_IRQ_SDMMC1, + .handler = stm32_sdmmc1_interrupt, +#ifdef CONFIG_SDMMC1_PRI + .irqprio = CONFIG_SDMMC1_PRI, +#endif +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + .d0_gpio = GPIO_SDMMC1_D0, + .wrchandler = stm32_sdmmc1_rdyinterrupt, +#endif +#ifdef CONFIG_SDMMC1_DMAPRIO + .dmapri = CONFIG_SDMMC1_DMAPRIO, +#endif }; - +#endif +#ifdef CONFIG_STM32F7_SDMMC2 +struct stm32_dev_s g_sdmmcdev2 = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = stm32_lock, +#endif + .reset = stm32_reset, + .status = stm32_status, + .widebus = stm32_widebus, + .clock = stm32_clock, + .attach = stm32_attach, + .sendcmd = stm32_sendcmd, +#ifdef CONFIG_SDIO_BLOCKSETUP + .blocksetup = stm32_blocksetup, /* Not implemented yet */ +#endif + .recvsetup = stm32_recvsetup, + .sendsetup = stm32_sendsetup, + .cancel = stm32_cancel, + .waitresponse = stm32_waitresponse, + .recvR1 = stm32_recvshortcrc, + .recvR2 = stm32_recvlong, + .recvR3 = stm32_recvshort, + .recvR4 = stm32_recvnotimpl, + .recvR5 = stm32_recvnotimpl, + .recvR6 = stm32_recvshortcrc, + .recvR7 = stm32_recvshort, + .waitenable = stm32_waitenable, + .eventwait = stm32_eventwait, + .callbackenable = stm32_callbackenable, + .registercallback = stm32_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = stm32_dmasupported, +#ifdef CONFIG_SDIO_PREFLIGHT + .dmapreflight = stm32_dmapreflight, +#endif + .dmarecvsetup = stm32_dmarecvsetup, + .dmasendsetup = stm32_dmasendsetup, +#endif + }, + .base = STM32_SDMMC2_BASE, + .nirq = STM32_IRQ_SDMMC2, + .handler = stm32_sdmmc2_interrupt, +#ifdef CONFIG_SDMMC2_PRI + .irqprio = CONFIG_SDMMC2_PRI, +#endif +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + .d0_gpio = GPIO_SDMMC2_D0, + .wrchandler = stm32_sdmmc2_rdyinterrupt, +#endif +#ifdef CONFIG_SDMMC2_DMAPRIO + .dmapri = CONFIG_SDMMC2_DMAPRIO, +#endif +}; +#endif /* Register logging support */ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES]; #endif @@ -505,6 +668,44 @@ static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES]; /**************************************************************************** * Low-level Helpers ****************************************************************************/ + +/**************************************************************************** + * Name: sdmmc_putreg32 + ****************************************************************************/ + +static inline void sdmmc_putreg32(struct stm32_dev_s *priv, uint32_t value,\ + int offset) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: sdmmc_gettreg32 + ****************************************************************************/ + +static inline uint32_t sdmmc_getreg32(struct stm32_dev_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: sdmmc_modifyreg32 + ****************************************************************************/ + +static inline void sdmmc_modifyreg32(struct stm32_dev_s *priv, int offset, + uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + int32_t regval; + + flags = enter_critical_section(); + regval = getreg32(priv->base + offset); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, priv->base + offset); + leave_critical_section(flags); +} + /**************************************************************************** * Name: stm32_takesem * @@ -513,7 +714,7 @@ static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES]; * of signals). * * Input Parameters: - * dev - Instance of the SDIO device driver state structure. + * priv - Instance of the SDMMC private state structure. * * Returned Value: * None @@ -544,6 +745,7 @@ static void stm32_takesem(struct stm32_dev_s *priv) * CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, and HWFC_EN * * Input Parameters: + * priv - Instance of the SDMMC private state structure. * clkcr - A new CLKCR setting for the above mentions bits (other bits * are ignored. * @@ -552,27 +754,30 @@ static void stm32_takesem(struct stm32_dev_s *priv) * ****************************************************************************/ -static inline void stm32_setclkcr(uint32_t clkcr) +static inline void stm32_setclkcr(struct stm32_dev_s *priv, uint32_t clkcr) { - uint32_t regval = getreg32(STM32_SDMMC1_CLKCR); + uint32_t regval = sdmmc_getreg32(priv, STM32_SDMMC_CLKCR_OFFSET); /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ - regval &= ~(SDIO_CLKCR_CLKDIV_MASK | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_BYPASS | - SDIO_CLKCR_WIDBUS_MASK | SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN | - SDIO_CLKCR_CLKEN); + regval &= ~(STM32_SDMMC_CLKCR_CLKDIV_MASK | STM32_SDMMC_CLKCR_PWRSAV | + STM32_SDMMC_CLKCR_BYPASS | STM32_SDMMC_CLKCR_WIDBUS_MASK | + STM32_SDMMC_CLKCR_NEGEDGE | STM32_SDMMC_CLKCR_HWFC_EN | + STM32_SDMMC_CLKCR_CLKEN); /* Replace with user provided settings */ - clkcr &= (SDIO_CLKCR_CLKDIV_MASK | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_BYPASS | - SDIO_CLKCR_WIDBUS_MASK | SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN | - SDIO_CLKCR_CLKEN); + clkcr &= (STM32_SDMMC_CLKCR_CLKDIV_MASK | STM32_SDMMC_CLKCR_PWRSAV | + STM32_SDMMC_CLKCR_BYPASS | STM32_SDMMC_CLKCR_WIDBUS_MASK | + STM32_SDMMC_CLKCR_NEGEDGE | STM32_SDMMC_CLKCR_HWFC_EN | + STM32_SDMMC_CLKCR_CLKEN); regval |= clkcr; - putreg32(regval, STM32_SDMMC1_CLKCR); + sdmmc_putreg32(priv, regval, STM32_SDMMC_CLKCR_OFFSET); - finfo("CLKCR: %08x PWR: %08x\n", - getreg32(STM32_SDMMC1_CLKCR), getreg32(STM32_SDMMC1_POWER)); + mcinfo("CLKCR: %08x PWR: %08x\n", + sdmmc_getreg32(priv, STM32_SDMMC_CLKCR_OFFSET), + sdmmc_getreg32(priv, STM32_SDMMC_POWER_OFFSET)); } /**************************************************************************** @@ -582,7 +787,7 @@ static inline void stm32_setclkcr(uint32_t clkcr) * Enable/disable SDIO interrupts needed to suport the wait function * * Input Parameters: - * priv - A reference to the SDIO device state structure + * priv - Instance of the SDMMC private state structure. * waitmask - The set of bits in the SDIO MASK register to set * waitevents - Waited for events * wkupevent - Wake-up events @@ -609,24 +814,24 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, #ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE if ((waitmask & SDIOWAIT_WRCOMPLETE) != 0) { - /* Do not use this in STM32_SDMMC1_MASK register */ + /* Do not use this in STM32_SDMMC_MASK register */ waitmask &= !SDIOWAIT_WRCOMPLETE; - pinset = GPIO_SDMMC1_D0 & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pinset = priv->d0_gpio & (GPIO_PORT_MASK | GPIO_PIN_MASK); pinset |= (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI); - /* Arm the SDIO_D Ready and install Isr */ + /* Arm the SDMMC_D Ready and install Isr */ - stm32_gpiosetevent(pinset, true, false, false, stm32_rdyinterrupt); + stm32_gpiosetevent(pinset, true, false, false, priv->wrchandler); } - /* Disarm SDIO_D ready */ + /* Disarm SDMMC_D ready */ if ((wkupevent & SDIOWAIT_WRCOMPLETE) != 0) { - stm32_gpiosetevent(GPIO_SDMMC1_D0, false, false, false , NULL); - stm32_configgpio(GPIO_SDMMC1_D0); + stm32_gpiosetevent(priv->d0_gpio, false, false, false , NULL); + stm32_configgpio(priv->d0_gpio); } #endif @@ -636,7 +841,7 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, #ifdef CONFIG_SDIO_DMA priv->xfrflags = 0; #endif - putreg32(priv->xfrmask | priv->waitmask, STM32_SDMMC1_MASK); + sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask, STM32_SDMMC_MASK_OFFSET); leave_critical_section(flags); } @@ -647,7 +852,7 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, * Enable SDIO interrupts needed to support the data transfer event * * Input Parameters: - * priv - A reference to the SDIO device state structure + * priv - Instance of the SDMMC private state structure. * xfrmask - The set of bits in the SDIO MASK register to set * * Returned Value: @@ -660,7 +865,7 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask) irqstate_t flags; flags = enter_critical_section(); priv->xfrmask = xfrmask; - putreg32(priv->xfrmask | priv->waitmask, STM32_SDMMC1_MASK); + sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask, STM32_SDMMC_MASK_OFFSET); leave_critical_section(flags); } @@ -672,6 +877,7 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask) * ON or OFF * * Input Parameters: + * priv - Instance of the SDMMC private state structure. * clkcr - A new PWRCTRL setting * * Returned Value: @@ -679,14 +885,14 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask) * ****************************************************************************/ -static void stm32_setpwrctrl(uint32_t pwrctrl) +static void stm32_setpwrctrl(struct stm32_dev_s *priv, uint32_t pwrctrl) { uint32_t regval; - regval = getreg32(STM32_SDMMC1_POWER); - regval &= ~SDIO_POWER_PWRCTRL_MASK; + regval = sdmmc_getreg32(priv, STM32_SDMMC_POWER_OFFSET); + regval &= ~STM32_SDMMC_POWER_PWRCTRL_MASK; regval |= pwrctrl; - putreg32(regval, STM32_SDMMC1_POWER); + sdmmc_putreg32(priv, regval, STM32_SDMMC_POWER_OFFSET); } /**************************************************************************** @@ -698,16 +904,17 @@ static void stm32_setpwrctrl(uint32_t pwrctrl) * or OFF * * Input Parameters: - * None + * priv - Instance of the SDMMC private state structure. * * Returned Value: * The current value of the the PWRCTRL field of the SDIO POWER register. * ****************************************************************************/ -static inline uint32_t stm32_getpwrctrl(void) +static inline uint32_t stm32_getpwrctrl(struct stm32_dev_s *priv) { - return getreg32(STM32_SDMMC1_POWER) & SDIO_POWER_PWRCTRL_MASK; + return sdmmc_getreg32(priv, STM32_SDMMC_POWER_OFFSET) & + STM32_SDMMC_POWER_PWRCTRL_MASK; } /**************************************************************************** @@ -722,7 +929,7 @@ static inline uint32_t stm32_getpwrctrl(void) * ****************************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static void stm32_sampleinit(void) { memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct stm32_sampleregs_s)); @@ -737,18 +944,19 @@ static void stm32_sampleinit(void) * ****************************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG -static void stm32_sdiosample(struct stm32_sdioregs_s *regs) +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG +static void stm32_sdiosample(struct stm32_dev_s *priv, + struct stm32_sdioregs_s *regs) { - regs->power = (uint8_t)getreg32(STM32_SDMMC1_POWER); - regs->clkcr = (uint16_t)getreg32(STM32_SDMMC1_CLKCR); - regs->dctrl = (uint16_t)getreg32(STM32_SDMMC1_DCTRL); - regs->dtimer = getreg32(STM32_SDMMC1_DTIMER); - regs->dlen = getreg32(STM32_SDMMC1_DLEN); - regs->dcount = getreg32(STM32_SDMMC1_DCOUNT); - regs->sta = getreg32(STM32_SDMMC1_STA); - regs->mask = getreg32(STM32_SDMMC1_MASK); - regs->fifocnt = getreg32(STM32_SDMMC1_FIFOCNT); + regs->power = (uint8_t)sdmmc_getreg32(priv, STM32_SDMMC_POWER_OFFSET); + regs->clkcr = (uint16_t)sdmmc_getreg32(priv, STM32_SDMMC_CLKCR_OFFSET); + regs->dctrl = (uint16_t)sdmmc_getreg32(priv, STM32_SDMMC_DCTRL_OFFSET); + regs->dtimer = sdmmc_getreg32(priv, STM32_SDMMC_DTIMER_OFFSET); + regs->dlen = sdmmc_getreg32(priv, STM32_SDMMC_DLEN_OFFSET); + regs->dcount = sdmmc_getreg32(priv, STM32_SDMMC_DCOUNT_OFFSET); + regs->sta = sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET); + regs->mask = sdmmc_getreg32(priv, STM32_SDMMC_MASK_OFFSET); + regs->fifocnt = sdmmc_getreg32(priv, STM32_SDMMC_FIFOCNT_OFFSET); } #endif @@ -760,7 +968,7 @@ static void stm32_sdiosample(struct stm32_sdioregs_s *regs) * ****************************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static void stm32_sample(struct stm32_dev_s *priv, int index) { struct stm32_sampleregs_s *regs = &g_sampleregs[index]; @@ -772,7 +980,7 @@ static void stm32_sample(struct stm32_dev_s *priv, int index) } #endif - stm32_sdiosample(®s->sdio); + stm32_sdiosample(priv, ®s->sdio); } #endif @@ -784,19 +992,19 @@ static void stm32_sample(struct stm32_dev_s *priv, int index) * ****************************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg) { - ferr("SDIO Registers: %s\n", msg); - ferr(" POWER[%08x]: %08x\n", STM32_SDMMC1_POWER, regs->power); - ferr(" CLKCR[%08x]: %08x\n", STM32_SDMMC1_CLKCR, regs->clkcr); - ferr(" DCTRL[%08x]: %08x\n", STM32_SDMMC1_DCTRL, regs->dctrl); - ferr(" DTIMER[%08x]: %08x\n", STM32_SDMMC1_DTIMER, regs->dtimer); - ferr(" DLEN[%08x]: %08x\n", STM32_SDMMC1_DLEN, regs->dlen); - ferr(" DCOUNT[%08x]: %08x\n", STM32_SDMMC1_DCOUNT, regs->dcount); - ferr(" STA[%08x]: %08x\n", STM32_SDMMC1_STA, regs->sta); - ferr(" MASK[%08x]: %08x\n", STM32_SDMMC1_MASK, regs->mask); - ferr("FIFOCNT[%08x]: %08x\n", STM32_SDMMC1_FIFOCNT, regs->fifocnt); + mcinfo("SDIO Registers: %s\n", msg); + mcinfo(" POWER[%08x]: %08x\n", STM32_SDMMC_POWER_OFFSET, regs->power); + mcinfo(" CLKCR[%08x]: %08x\n", STM32_SDMMC_CLKCR_OFFSET, regs->clkcr); + mcinfo(" DCTRL[%08x]: %08x\n", STM32_SDMMC_DCTRL_OFFSET, regs->dctrl); + mcinfo(" DTIMER[%08x]: %08x\n", STM32_SDMMC_DTIMER_OFFSET, regs->dtimer); + mcinfo(" DLEN[%08x]: %08x\n", STM32_SDMMC_DLEN_OFFSET, regs->dlen); + mcinfo(" DCOUNT[%08x]: %08x\n", STM32_SDMMC_DCOUNT_OFFSET, regs->dcount); + mcinfo(" STA[%08x]: %08x\n", STM32_SDMMC_STA_OFFSET, regs->sta); + mcinfo(" MASK[%08x]: %08x\n", STM32_SDMMC_MASK_OFFSET, regs->mask); + mcinfo("FIFOCNT[%08x]: %08x\n", STM32_SDMMC_FIFOCNT_OFFSET, regs->fifocnt); } #endif @@ -808,7 +1016,7 @@ static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg) * ****************************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static void stm32_dumpsample(struct stm32_dev_s *priv, struct stm32_sampleregs_s *regs, const char *msg) { @@ -831,7 +1039,7 @@ static void stm32_dumpsample(struct stm32_dev_s *priv, * ****************************************************************************/ -#ifdef CONFIG_SDIO_XFRDEBUG +#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG static void stm32_dumpsamples(struct stm32_dev_s *priv) { stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup"); @@ -882,7 +1090,7 @@ static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg) if ((status & DMA_STATUS_ERROR) != 0) { - fllerr("DMA error %02x, remaining: %d\n", status, priv->remaining); + mcerr("DMA error %02x, remaining: %d\n", status, priv->remaining); result = SDIOWAIT_ERROR; } else @@ -896,8 +1104,8 @@ static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg) * will appropriately time out. */ - priv->xfrflags |= SDIO_DMADONE_FLAG; - if (priv->xfrflags == SDIO_ALLDONE || result == SDIOWAIT_ERROR) + priv->xfrflags |= SDMMC_DMADONE_FLAG; + if (priv->xfrflags == SDMMC_ALLDONE || result == SDIOWAIT_ERROR) { stm32_endtransfer(priv, result); } @@ -947,29 +1155,27 @@ static uint8_t stm32_log2(uint16_t value) * ****************************************************************************/ -static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl) +static void stm32_dataconfig(struct stm32_dev_s *priv, uint32_t timeout, + uint32_t dlen, uint32_t dctrl) { uint32_t regval = 0; /* Enable data path */ - putreg32(timeout, STM32_SDMMC1_DTIMER); /* Set DTIMER */ - putreg32(dlen, STM32_SDMMC1_DLEN); /* Set DLEN */ + sdmmc_putreg32(priv, timeout, STM32_SDMMC_DTIMER_OFFSET); /* Set DTIMER */ + sdmmc_putreg32(priv, dlen, STM32_SDMMC_DLEN_OFFSET); /* Set DLEN */ /* Configure DCTRL DTDIR, DTMODE, and DBLOCKSIZE fields and set the DTEN * field */ - regval = getreg32(STM32_SDMMC1_DCTRL); - regval &= ~(SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); - dctrl &= (SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); - regval |= (dctrl | SDIO_DCTRL_DTEN); - -#ifdef CONFIG_SDIO_DMA - regval |= SDIO_DCTRL_DMAEN; -#endif - - putreg32(regval, STM32_SDMMC1_DCTRL); + regval = sdmmc_getreg32(priv, STM32_SDMMC_DCTRL_OFFSET); + regval &= ~(STM32_SDMMC_DCTRL_DTDIR | STM32_SDMMC_DCTRL_DTMODE | + STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK); + dctrl &= (STM32_SDMMC_DCTRL_DTDIR | STM32_SDMMC_DCTRL_DTMODE | + STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK); + regval |= (dctrl | STM32_SDMMC_DCTRL_DTEN); + sdmmc_putreg32(priv, regval, STM32_SDMMC_DCTRL_OFFSET); } /**************************************************************************** @@ -981,21 +1187,23 @@ static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl) * ****************************************************************************/ -static void stm32_datadisable(void) +static void stm32_datadisable(struct stm32_dev_s *priv) { uint32_t regval; /* Disable the data path */ - putreg32(SDIO_DTIMER_DATATIMEOUT, STM32_SDMMC1_DTIMER); /* Reset DTIMER */ - putreg32(0, STM32_SDMMC1_DLEN); /* Reset DLEN */ + /* Reset DTIMER */ + sdmmc_putreg32(priv, SDMMC_DTIMER_DATATIMEOUT, STM32_SDMMC_DTIMER_OFFSET); + sdmmc_putreg32(priv, 0, STM32_SDMMC_DLEN_OFFSET); /* Reset DLEN */ /* Reset DCTRL DTEN, DTDIR, DTMODE, DMAEN, and DBLOCKSIZE fields */ - regval = getreg32(STM32_SDMMC1_DCTRL); - regval &= ~(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | - SDIO_DCTRL_DMAEN | SDIO_DCTRL_DBLOCKSIZE_MASK); - putreg32(regval, STM32_SDMMC1_DCTRL); + regval = sdmmc_getreg32(priv, STM32_SDMMC_DCTRL_OFFSET); + regval &= ~(STM32_SDMMC_DCTRL_DTEN | STM32_SDMMC_DCTRL_DTDIR | + STM32_SDMMC_DCTRL_DTMODE | STM32_SDMMC_DCTRL_DMAEN | + STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK); + sdmmc_putreg32(priv, regval, STM32_SDMMC_DCTRL_OFFSET); } /**************************************************************************** @@ -1005,7 +1213,7 @@ static void stm32_datadisable(void) * Send SDIO data in interrupt mode * * Input Parameters: - * priv - An instance of the SDIO device interface + * priv - Instance of the SDMMC private state structure. * * Returned Value: * None @@ -1023,7 +1231,7 @@ static void stm32_sendfifo(struct stm32_dev_s *priv) /* Loop while there is more data to be sent and the RX FIFO is not full */ while (priv->remaining > 0 && - (getreg32(STM32_SDMMC1_STA) & SDIO_STA_TXFIFOF) == 0) + (sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) & STM32_SDMMC_STA_TXFIFOF) == 0) { /* Is there a full word remaining in the user buffer? */ @@ -1056,7 +1264,7 @@ static void stm32_sendfifo(struct stm32_dev_s *priv) /* Put the word in the FIFO */ - putreg32(data.w, STM32_SDMMC1_FIFO); + sdmmc_putreg32(priv, data.w, STM32_SDMMC_FIFO_OFFSET); } } @@ -1067,7 +1275,7 @@ static void stm32_sendfifo(struct stm32_dev_s *priv) * Receive SDIO data in interrupt mode * * Input Parameters: - * priv - An instance of the SDIO device interface + * priv - Instance of the SDMMC private state structure. * * Returned Value: * None @@ -1087,11 +1295,11 @@ static void stm32_recvfifo(struct stm32_dev_s *priv) */ while (priv->remaining > 0 && - (getreg32(STM32_SDMMC1_STA) & SDIO_STA_RXDAVL) != 0) + (sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) & STM32_SDMMC_STA_RXDAVL) != 0) { /* Read the next word from the RX FIFO */ - data.w = getreg32(STM32_SDMMC1_FIFO); + data.w = sdmmc_getreg32(priv, STM32_SDMMC_FIFO_OFFSET); if (priv->remaining >= sizeof(uint32_t)) { /* Transfer the whole word to the user buffer */ @@ -1127,7 +1335,8 @@ static void stm32_recvfifo(struct stm32_dev_s *priv) * * Input Parameters: * argc - The number of arguments (should be 1) - * arg - The argument (state structure reference cast to uint32_t) + * arg - The argument (the SDMMC private state structure reference cast + * to uint32_t) * * Returned Value: * None @@ -1143,7 +1352,8 @@ static void stm32_eventtimeout(int argc, uint32_t arg) /* There is always race conditions with timer expirations. */ - DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || priv->wkupevent != 0); + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || + priv->wkupevent != 0); /* Is a data transfer complete event expected? */ @@ -1152,7 +1362,7 @@ static void stm32_eventtimeout(int argc, uint32_t arg) /* Yes.. wake up any waiting threads */ stm32_endwait(priv, SDIOWAIT_TIMEOUT); - fllerr("Timeout: remaining: %d\n", priv->remaining); + mcerr("Timeout: remaining: %d\n", priv->remaining); } } @@ -1163,7 +1373,7 @@ static void stm32_eventtimeout(int argc, uint32_t arg) * Wake up a waiting thread if the waited-for event has occurred. * * Input Parameters: - * priv - An instance of the SDIO device interface + * priv - Instance of the SDMMC private state structure. * wkupevent - The event that caused the wait to end * * Returned Value: @@ -1198,7 +1408,7 @@ static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) * are detected. * * Input Parameters: - * priv - An instance of the SDIO device interface + * priv - Instance of the SDMMC private state structure. * wkupevent - The event that caused the transfer to end * * Returned Value: @@ -1209,7 +1419,8 @@ static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) * ****************************************************************************/ -static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) +static void stm32_endtransfer(struct stm32_dev_s *priv, + sdio_eventset_t wkupevent) { /* Disable all transfer related interrupts */ @@ -1217,7 +1428,7 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupeven /* Clearing pending interrupt status on all transfer related interrupts */ - putreg32(SDIO_XFRDONE_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_XFRDONE_ICR, STM32_SDMMC_ICR_OFFSET); /* If this was a DMA transfer, make sure that DMA is stopped */ @@ -1256,13 +1467,14 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupeven ****************************************************************************/ /**************************************************************************** - * Name: stm32_rdyinterrupt + * Name: stm32_sdmmc[1|2]_rdyinterrupt * * Description: - * SDIO ready interrupt handler + * SDMMC ready interrupt handler * * Input Parameters: - * dev - An instance of the SDIO device interface + * irq - not used + * context - not used * * Returned Value: * None @@ -1270,31 +1482,41 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupeven ****************************************************************************/ #ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE -static int stm32_rdyinterrupt(int irq, void *context) +# if defined(CONFIG_STM32F7_SDMMC1) +static int stm32_sdmmc1_rdyinterrupt(int irq, void *context) { - struct stm32_dev_s *priv = &g_sdiodev; + struct stm32_dev_s *priv = &g_sdmmcdev1; stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); return OK; } +# endif + +# if defined(CONFIG_STM32F7_SDMMC2) +static int stm32_sdmmc2_rdyinterrupt(int irq, void *context) +{ + struct stm32_dev_s *priv = &g_sdmmcdev2; + stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); + return OK; +} +# endif #endif /**************************************************************************** - * Name: stm32_interrupt + * Name: stm32_sdmmc_interrupt * * Description: - * SDIO interrupt handler + * SDMMC common interrupt handler * * Input Parameters: - * dev - An instance of the SDIO device interface + * priv - Instance of the SDMMC private state structure. * * Returned Value: * None * ****************************************************************************/ -static int stm32_interrupt(int irq, void *context) +static int stm32_sdmmc_interrupt(struct stm32_dev_s *priv) { - struct stm32_dev_s *priv = &g_sdiodev; uint32_t enabled; uint32_t pending; @@ -1305,7 +1527,8 @@ static int stm32_interrupt(int irq, void *context) * bits remaining, then we have work to do here. */ - while ((enabled = getreg32(STM32_SDMMC1_STA) & getreg32(STM32_SDMMC1_MASK)) != 0) + while ((enabled = sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) & + sdmmc_getreg32(priv, STM32_SDMMC_MASK_OFFSET)) != 0) { /* Handle in progress, interrupt driven data transfers ****************/ @@ -1320,7 +1543,7 @@ static int stm32_interrupt(int irq, void *context) * processing a receive transaction. */ - if ((pending & SDIO_STA_RXFIFOHF) != 0) + if ((pending & STM32_SDMMC_STA_RXFIFOHF) != 0) { /* Receive data from the RX FIFO */ @@ -1332,7 +1555,7 @@ static int stm32_interrupt(int irq, void *context) * both! */ - else if ((pending & SDIO_STA_TXFIFOHE) != 0) + else if ((pending & STM32_SDMMC_STA_TXFIFOHE) != 0) { /* Send data via the TX FIFO */ @@ -1342,7 +1565,7 @@ static int stm32_interrupt(int irq, void *context) /* Handle data end events */ - if ((pending & SDIO_STA_DATAEND) != 0) + if ((pending & STM32_SDMMC_STA_DATAEND) != 0) { /* Handle any data remaining the RX FIFO. If the RX FIFO is * less than half full at the end of the transfer, then no @@ -1358,8 +1581,8 @@ static int stm32_interrupt(int irq, void *context) * finished. */ - priv->xfrflags |= SDIO_XFRDONE_FLAG; - if (priv->xfrflags == SDIO_ALLDONE) + priv->xfrflags |= SDMMC_XFRDONE_FLAG; + if (priv->xfrflags == SDMMC_ALLDONE) { stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE); } @@ -1388,51 +1611,52 @@ static int stm32_interrupt(int irq, void *context) /* Handle data block send/receive CRC failure */ - else if ((pending & SDIO_STA_DCRCFAIL) != 0) + else if ((pending & STM32_SDMMC_STA_DCRCFAIL) != 0) { /* Terminate the transfer with an error */ - fllerr("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining); + mcerr("ERROR: Data block CRC failure, remaining: %d\n", + priv->remaining); stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle data timeout error */ - else if ((pending & SDIO_STA_DTIMEOUT) != 0) + else if ((pending & STM32_SDMMC_STA_DTIMEOUT) != 0) { /* Terminate the transfer with an error */ - fllerr("ERROR: Data timeout, remaining: %d\n", priv->remaining); + mcerr("ERROR: Data timeout, remaining: %d\n", priv->remaining); stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); } /* Handle RX FIFO overrun error */ - else if ((pending & SDIO_STA_RXOVERR) != 0) + else if ((pending & STM32_SDMMC_STA_RXOVERR) != 0) { /* Terminate the transfer with an error */ - fllerr("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining); + mcerr("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining); stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle TX FIFO underrun error */ - else if ((pending & SDIO_STA_TXUNDERR) != 0) + else if ((pending & STM32_SDMMC_STA_TXUNDERR) != 0) { /* Terminate the transfer with an error */ - fllerr("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining); + mcerr("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining); stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle start bit error */ - else if ((pending & SDIO_STA_STBITERR) != 0) + else if ((pending & STM32_SDMMC_STA_STBITERR) != 0) { /* Terminate the transfer with an error */ - fllerr("ERROR: Start bit, remaining: %d\n", priv->remaining); + mcerr("ERROR: Start bit, remaining: %d\n", priv->remaining); stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } } @@ -1444,7 +1668,7 @@ static int stm32_interrupt(int irq, void *context) { /* Is this a response completion event? */ - if ((pending & SDIO_RESPDONE_STA) != 0) + if ((pending & STM32_SDMMC_RESPDONE_STA) != 0) { /* Yes.. Is their a thread waiting for response done? */ @@ -1452,14 +1676,15 @@ static int stm32_interrupt(int irq, void *context) { /* Yes.. wake the thread up */ - putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_RESPDONE_ICR | + STM32_SDMMC_CMDDONE_ICR, STM32_SDMMC_ICR_OFFSET); stm32_endwait(priv, SDIOWAIT_RESPONSEDONE); } } /* Is this a command completion event? */ - if ((pending & SDIO_CMDDONE_STA) != 0) + if ((pending & STM32_SDMMC_CMDDONE_STA) != 0) { /* Yes.. Is their a thread waiting for command done? */ @@ -1467,7 +1692,8 @@ static int stm32_interrupt(int irq, void *context) { /* Yes.. wake the thread up */ - putreg32(SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_CMDDONE_ICR, + STM32_SDMMC_ICR_OFFSET); stm32_endwait(priv, SDIOWAIT_CMDDONE); } } @@ -1477,6 +1703,49 @@ static int stm32_interrupt(int irq, void *context) return OK; } +/**************************************************************************** + * Name: stm32_sdmmc1_interrupt + * + * Description: + * SDMMC 1 interrupt handler wrapper + * + * Input Parameters: + * irq - not used + * context - not used + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_STM32F7_SDMMC1 +static int stm32_sdmmc1_interrupt(int irq, void *context) +{ + return stm32_sdmmc_interrupt(&g_sdmmcdev1); +} +#endif + +/**************************************************************************** + * Name: stm32_sdmmc2_interrupt + * + * Description: + * SDMMC 2 interrupt handler wrapper + * + * Input Parameters: + * irq - not used + * context - not used + * + * + * Returned Value: + * None + * + ****************************************************************************/ +#ifdef CONFIG_STM32F7_SDMMC2 +static int stm32_sdmmc2_interrupt(int irq, void *context) +{ + return stm32_sdmmc_interrupt(&g_sdmmcdev2); +} +#endif /**************************************************************************** * SDIO Interface Methods ****************************************************************************/ @@ -1500,11 +1769,9 @@ static int stm32_interrupt(int irq, void *context) #ifdef CONFIG_SDIO_MUXBUS static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock) { - /* Single SDIO instance so there is only one possibility. The multiplex - * bus is part of board support package. + /* The multiplex bus is part of board support package. */ - - stm32_muxbus_sdio_lock(lock); + stm32_muxbus_sdio_lock(dev, lock); return OK; } #endif @@ -1531,11 +1798,12 @@ static void stm32_reset(FAR struct sdio_dev_s *dev) /* Disable clocking */ flags = enter_critical_section(); - stm32_setpwrctrl(SDIO_POWER_PWRCTRL_OFF); + sdmmc_modifyreg32(priv, STM32_SDMMC_CLKCR_OFFSET, STM32_SDMMC_CLKCR_CLKEN, 0); + stm32_setpwrctrl(priv, STM32_SDMMC_POWER_PWRCTRL_OFF); /* Put SDIO registers in their default, reset state */ - stm32_default(); + stm32_default(priv); /* Reset data */ @@ -1543,7 +1811,8 @@ static void stm32_reset(FAR struct sdio_dev_s *dev) priv->waitmask = 0; /* Interrupt enables for event waiting */ priv->wkupevent = 0; /* The event that caused the wakeup */ #ifdef CONFIG_SDIO_DMA - priv->xfrflags = 0; /* Used to synchronize SDIO and DMA completion events */ + priv->xfrflags = 0; /* Used to synchronize SDIO and DMA + * completion events */ #endif wd_cancel(priv->waitwdog); /* Cancel any timeouts */ @@ -1563,12 +1832,13 @@ static void stm32_reset(FAR struct sdio_dev_s *dev) /* Configure the SDIO peripheral */ - stm32_setclkcr(STM32_CLCKCR_INIT | SDIO_CLKCR_CLKEN); - stm32_setpwrctrl(SDIO_POWER_PWRCTRL_ON); + stm32_setclkcr(priv, STM32_CLCKCR_INIT | STM32_SDMMC_CLKCR_CLKEN); + stm32_setpwrctrl(priv, STM32_SDMMC_POWER_PWRCTRL_ON); leave_critical_section(flags); - finfo("CLCKR: %08x POWER: %08x\n", - getreg32(STM32_SDMMC1_CLKCR), getreg32(STM32_SDMMC1_POWER)); + mcinfo("CLCKR: %08x POWER: %08x\n", + sdmmc_getreg32(priv, STM32_SDMMC_CLKCR_OFFSET), + sdmmc_getreg32(priv, STM32_SDMMC_POWER_OFFSET)); } /**************************************************************************** @@ -1631,6 +1901,7 @@ static void stm32_widebus(FAR struct sdio_dev_s *dev, bool wide) static void stm32_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t clckr; switch (rate) @@ -1645,33 +1916,33 @@ static void stm32_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) /* Enable in initial ID mode clocking (<400KHz) */ case CLOCK_IDMODE: - clckr = (STM32_CLCKCR_INIT | SDIO_CLKCR_CLKEN); + clckr = (STM32_CLCKCR_INIT | STM32_SDMMC_CLKCR_CLKEN); break; /* Enable in MMC normal operation clocking */ case CLOCK_MMC_TRANSFER: - clckr = (SDIO_CLKCR_MMCXFR | SDIO_CLKCR_CLKEN); + clckr = (STM32_SDMMC_CLKCR_MMCXFR | STM32_SDMMC_CLKCR_CLKEN); break; /* SD normal operation clocking (wide 4-bit mode) */ case CLOCK_SD_TRANSFER_4BIT: -#ifndef CONFIG_SDIO_WIDTH_D1_ONLY - clckr = (SDIO_CLCKR_SDWIDEXFR | SDIO_CLKCR_CLKEN); +#ifndef CONFIG_SDMMC_WIDTH_D1_ONLY + clckr = (STM32_SDMMC_CLCKR_SDWIDEXFR | STM32_SDMMC_CLKCR_CLKEN); break; #endif /* SD normal operation clocking (narrow 1-bit mode) */ case CLOCK_SD_TRANSFER_1BIT: - clckr = (SDIO_CLCKR_SDXFR | SDIO_CLKCR_CLKEN); + clckr = (STM32_SDMMC_CLCKR_SDXFR | STM32_SDMMC_CLKCR_CLKEN); break; } /* Set the new clock frequency along with the clock enable/disable bit */ - stm32_setclkcr(clckr); + stm32_setclkcr(priv, clckr); } /**************************************************************************** @@ -1690,11 +1961,13 @@ static void stm32_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) static int stm32_attach(FAR struct sdio_dev_s *dev) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; int ret; /* Attach the SDIO interrupt handler */ - ret = irq_attach(STM32_IRQ_SDMMC1, stm32_interrupt); + ret = irq_attach(priv->nirq, priv->handler); + if (ret == OK) { @@ -1702,19 +1975,20 @@ static int stm32_attach(FAR struct sdio_dev_s *dev) * interrupt flags */ - putreg32(SDIO_MASK_RESET, STM32_SDMMC1_MASK); - putreg32(SDIO_ICR_STATICFLAGS, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_MASK_RESET, STM32_SDMMC_MASK_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_ICR_STATICFLAGS, STM32_SDMMC_ICR_OFFSET); /* Enable SDIO interrupts at the NVIC. They can now be enabled at * the SDIO controller as needed. */ - up_enable_irq(STM32_IRQ_SDMMC1); + up_enable_irq(priv->nirq); -#ifdef CONFIG_ARCH_IRQPRIO +#if defined(CONFIG_ARCH_IRQPRIO) && (defined(CONFIG_SDMMC1_DMAPRIO) || \ + defined(CONFIG_SDMMC2_DMAPRIO)) /* Set the interrupt priority */ - up_prioritize_irq(STM32_IRQ_SDIO, CONFIG_SDIO_PRI); + up_prioritize_irq(priv->nirq, priv->irqprio); #endif } @@ -1739,25 +2013,27 @@ static int stm32_attach(FAR struct sdio_dev_s *dev) static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t regval; uint32_t cmdidx; /* Set the SDIO Argument value */ - putreg32(arg, STM32_SDMMC1_ARG); + sdmmc_putreg32(priv, arg, STM32_SDMMC_ARG_OFFSET); /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, and CPSMEN bits */ - regval = getreg32(STM32_SDMMC1_CMD); - regval &= ~(SDIO_CMD_CMDINDEX_MASK | SDIO_CMD_WAITRESP_MASK | - SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND | SDIO_CMD_CPSMEN); + regval = sdmmc_getreg32(priv, STM32_SDMMC_CMD_OFFSET); + regval &= ~(STM32_SDMMC_CMD_CMDINDEX_MASK | STM32_SDMMC_CMD_WAITRESP_MASK | + STM32_SDMMC_CMD_WAITINT | STM32_SDMMC_CMD_WAITPEND | + STM32_SDMMC_CMD_CPSMEN); /* Set WAITRESP bits */ switch (cmd & MMCSD_RESPONSE_MASK) { case MMCSD_NO_RESPONSE: - regval |= SDIO_CMD_NORESPONSE; + regval |= STM32_SDMMC_CMD_NORESPONSE; break; case MMCSD_R1_RESPONSE: @@ -1767,25 +2043,26 @@ static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) case MMCSD_R5_RESPONSE: case MMCSD_R6_RESPONSE: case MMCSD_R7_RESPONSE: - regval |= SDIO_CMD_SHORTRESPONSE; + regval |= STM32_SDMMC_CMD_SHORTRESPONSE; break; case MMCSD_R2_RESPONSE: - regval |= SDIO_CMD_LONGRESPONSE; + regval |= STM32_SDMMC_CMD_LONGRESPONSE; break; } /* Set CPSMEN and the command index */ cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; - regval |= cmdidx | SDIO_CMD_CPSMEN; + regval |= cmdidx | STM32_SDMMC_CMD_CPSMEN; - finfo("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + mcinfo("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); /* Write the SDIO CMD */ - putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); - putreg32(regval, STM32_SDMMC1_CMD); + sdmmc_putreg32(priv, STM32_SDMMC_RESPDONE_ICR | STM32_SDMMC_CMDDONE_ICR, + STM32_SDMMC_ICR_OFFSET); + sdmmc_putreg32(priv, regval, STM32_SDMMC_CMD_OFFSET); return OK; } @@ -1797,7 +2074,7 @@ static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) * (interrupt driven mode). This method will do whatever controller setup * is necessary. This would be called for SD memory just BEFORE sending * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 - * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDMMC_WAITEVENT * will be called to receive the indication that the transfer is complete. * * Input Parameters: @@ -1821,7 +2098,7 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Reset the DPSM configuration */ - stm32_datadisable(); + stm32_datadisable(priv); stm32_sampleinit(); stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); @@ -1835,12 +2112,13 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Then set up the SDIO data path */ - dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; - stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize | SDIO_DCTRL_DTDIR); + dblocksize = stm32_log2(nbytes) << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(priv, SDMMC_DTIMER_DATATIMEOUT, nbytes, dblocksize | + STM32_SDMMC_DCTRL_DTDIR); /* And enable interrupts */ - stm32_configxfrints(priv, SDIO_RECV_MASK); + stm32_configxfrints(priv, STM32_SDMMC_RECV_MASK); stm32_sample(priv, SAMPLENDX_AFTER_SETUP); return OK; } @@ -1852,7 +2130,7 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * Setup hardware in preparation for data transfer from the card. This method * will do whatever controller setup is necessary. This would be called * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 - * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * (WRITE_MULTIPLE_BLOCK), ... and before SDMMC_SENDDATA is called. * * Input Parameters: * dev - An instance of the SDIO device interface @@ -1864,8 +2142,8 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * ****************************************************************************/ -static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t nbytes) +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const + uint8_t *buffer, size_t nbytes) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t dblocksize; @@ -1875,7 +2153,7 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer /* Reset the DPSM configuration */ - stm32_datadisable(); + stm32_datadisable(priv); stm32_sampleinit(); stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); @@ -1889,12 +2167,12 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer /* Then set up the SDIO data path */ - dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; - stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize); + dblocksize = stm32_log2(nbytes) << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(priv, SDMMC_DTIMER_DATATIMEOUT, nbytes, dblocksize); /* Enable TX interrupts */ - stm32_configxfrints(priv, SDIO_SEND_MASK); + stm32_configxfrints(priv, STM32_SDMMC_SEND_MASK); stm32_sample(priv, SAMPLENDX_AFTER_SETUP); return OK; } @@ -1903,8 +2181,8 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer * Name: stm32_cancel * * Description: - * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, - * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * Cancel the data transfer setup of SDMMC_RECVSETUP, SDMMC_SENDSETUP, + * SDMMC_DMARECVSETUP or SDMMC_DMASENDSETUP. This must be called to cancel * the data transfer setup if, for some reason, you cannot perform the * transfer. * @@ -1929,7 +2207,7 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev) * interrupts */ - putreg32(SDIO_WAITALL_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_WAITALL_ICR, STM32_SDMMC_ICR_OFFSET); /* Cancel any watchdog timeout */ @@ -1972,22 +2250,23 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev) static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; int32_t timeout; uint32_t events; switch (cmd & MMCSD_RESPONSE_MASK) { case MMCSD_NO_RESPONSE: - events = SDIO_CMDDONE_STA; - timeout = SDIO_CMDTIMEOUT; + events = STM32_SDMMC_CMDDONE_STA; + timeout = SDMMC_CMDTIMEOUT; break; case MMCSD_R1_RESPONSE: case MMCSD_R1B_RESPONSE: case MMCSD_R2_RESPONSE: case MMCSD_R6_RESPONSE: - events = SDIO_RESPDONE_STA; - timeout = SDIO_LONGTIMEOUT; + events = STM32_SDMMC_RESPDONE_STA; + timeout = SDMMC_LONGTIMEOUT; break; case MMCSD_R4_RESPONSE: @@ -1996,8 +2275,8 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) case MMCSD_R3_RESPONSE: case MMCSD_R7_RESPONSE: - events = SDIO_RESPDONE_STA; - timeout = SDIO_CMDTIMEOUT; + events = STM32_SDMMC_RESPDONE_STA; + timeout = SDMMC_CMDTIMEOUT; break; default: @@ -2006,18 +2285,18 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) /* Then wait for the response (or timeout) */ - while ((getreg32(STM32_SDMMC1_STA) & events) == 0) + while ((sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) & events) == 0) { if (--timeout <= 0) { - ferr("ERROR: Timeout cmd: %08x events: %08x STA: %08x\n", - cmd, events, getreg32(STM32_SDMMC1_STA)); + mcerr("ERROR: Timeout cmd: %08x events: %08x STA: %08x\n", + cmd, events, sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET)); return -ETIMEDOUT; } } - putreg32(SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_CMDDONE_ICR, STM32_SDMMC_ICR_OFFSET); return OK; } @@ -2036,15 +2315,17 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) * * Returned Value: * Number of bytes sent on success; a negated errno on failure. Here a - * failure means only a faiure to obtain the requested reponse (due to + * failure means only a faiure to obtain the requested response (due to * transport problem -- timeout, CRC, etc.). The implementation only - * assures that the response is returned intacta and does not check errors + * assures that the response is returned intact and does not check errors * within the response itself. * ****************************************************************************/ -static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; #ifdef CONFIG_DEBUG_FEATURES uint32_t respcmd; #endif @@ -2077,7 +2358,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t #ifdef CONFIG_DEBUG_FEATURES if (!rshort) { - ferr("ERROR: rshort=NULL\n"); + mcerr("ERROR: rshort=NULL\n"); ret = -EINVAL; } @@ -2087,7 +2368,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE) { - ferr("ERROR: Wrong response CMD=%08x\n", cmd); + mcerr("ERROR: Wrong response CMD=%08x\n", cmd); ret = -EINVAL; } else @@ -2095,15 +2376,15 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t { /* Check if a timeout or CRC error occurred */ - regval = getreg32(STM32_SDMMC1_STA); - if ((regval & SDIO_STA_CTIMEOUT) != 0) + regval = sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET); + if ((regval & STM32_SDMMC_STA_CTIMEOUT) != 0) { - ferr("ERROR: Command timeout: %08x\n", regval); + mcerr("ERROR: Command timeout: %08x\n", regval); ret = -ETIMEDOUT; } - else if ((regval & SDIO_STA_CCRCFAIL) != 0) + else if ((regval & STM32_SDMMC_STA_CCRCFAIL) != 0) { - ferr("ERROR: CRC failure: %08x\n", regval); + mcerr("ERROR: CRC failure: %08x\n", regval); ret = -EIO; } #ifdef CONFIG_DEBUG_FEATURES @@ -2111,10 +2392,11 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t { /* Check response received is of desired command */ - respcmd = getreg32(STM32_SDMMC1_RESPCMD); - if ((uint8_t)(respcmd & SDIO_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK)) + respcmd = sdmmc_getreg32(priv, STM32_SDMMC_RESPCMD_OFFSET); + if ((uint8_t)(respcmd & STM32_SDMMC_RESPCMD_MASK) != + (cmd & MMCSD_CMDIDX_MASK)) { - ferr("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd); + mcerr("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd); ret = -EINVAL; } } @@ -2123,13 +2405,16 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t /* Clear all pending message completion events and return the R1/R6 response */ - putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); - *rshort = getreg32(STM32_SDMMC1_RESP1); + sdmmc_putreg32(priv, STM32_SDMMC_RESPDONE_ICR | STM32_SDMMC_CMDDONE_ICR, + STM32_SDMMC_ICR_OFFSET); + *rshort = sdmmc_getreg32(priv, STM32_SDMMC_RESP1_OFFSET); return ret; } -static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t regval; int ret = OK; @@ -2147,7 +2432,7 @@ static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlo if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) { - ferr("ERROR: Wrong response CMD=%08x\n", cmd); + mcerr("ERROR: Wrong response CMD=%08x\n", cmd); ret = -EINVAL; } else @@ -2155,34 +2440,36 @@ static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlo { /* Check if a timeout or CRC error occurred */ - regval = getreg32(STM32_SDMMC1_STA); - if (regval & SDIO_STA_CTIMEOUT) + regval = sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET); + if (regval & STM32_SDMMC_STA_CTIMEOUT) { - ferr("ERROR: Timeout STA: %08x\n", regval); + mcerr("ERROR: Timeout STA: %08x\n", regval); ret = -ETIMEDOUT; } - else if (regval & SDIO_STA_CCRCFAIL) + else if (regval & STM32_SDMMC_STA_CCRCFAIL) { - ferr("ERROR: CRC fail STA: %08x\n", regval); + mcerr("ERROR: CRC fail STA: %08x\n", regval); ret = -EIO; } } /* Return the long response */ - putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_RESPDONE_ICR | STM32_SDMMC_CMDDONE_ICR, + STM32_SDMMC_ICR_OFFSET); if (rlong) { - rlong[0] = getreg32(STM32_SDMMC1_RESP1); - rlong[1] = getreg32(STM32_SDMMC1_RESP2); - rlong[2] = getreg32(STM32_SDMMC1_RESP3); - rlong[3] = getreg32(STM32_SDMMC1_RESP4); + rlong[0] = sdmmc_getreg32(priv, STM32_SDMMC_RESP1_OFFSET); + rlong[1] = sdmmc_getreg32(priv, STM32_SDMMC_RESP2_OFFSET); + rlong[2] = sdmmc_getreg32(priv, STM32_SDMMC_RESP3_OFFSET); + rlong[3] = sdmmc_getreg32(priv, STM32_SDMMC_RESP4_OFFSET); } return ret; } static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) { + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; uint32_t regval; int ret = OK; @@ -2201,7 +2488,7 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *r if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) { - ferr("ERROR: Wrong response CMD=%08x\n", cmd); + mcerr("ERROR: Wrong response CMD=%08x\n", cmd); ret = -EINVAL; } else @@ -2211,27 +2498,31 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *r * a good response) */ - regval = getreg32(STM32_SDMMC1_STA); - if (regval & SDIO_STA_CTIMEOUT) + regval = sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET); + if (regval & STM32_SDMMC_STA_CTIMEOUT) { - ferr("ERROR: Timeout STA: %08x\n", regval); + mcerr("ERROR: Timeout STA: %08x\n", regval); ret = -ETIMEDOUT; } } - putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_RESPDONE_ICR | STM32_SDMMC_CMDDONE_ICR, + STM32_SDMMC_ICR_OFFSET); if (rshort) { - *rshort = getreg32(STM32_SDMMC1_RESP1); + *rshort = sdmmc_getreg32(priv, STM32_SDMMC_RESP1_OFFSET); } return ret; } /* MMC responses not supported */ -static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rnotimpl) +static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl) { - putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + sdmmc_putreg32(priv, STM32_SDMMC_RESPDONE_ICR | STM32_SDMMC_CMDDONE_ICR, + STM32_SDMMC_ICR_OFFSET); return -ENOSYS; } @@ -2240,13 +2531,13 @@ static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t * * Description: * Enable/disable of a set of SDIO wait events. This is part of the - * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * the SDMMC_WAITEVENT sequence. The set of to-be-waited-for events is * configured before calling stm32_eventwait. This is done in this way * to help the driver to eliminate race conditions between the command * setup and the subsequent events. * - * The enabled events persist until either (1) SDIO_WAITENABLE is called - * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * The enabled events persist until either (1) SDMMC_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDMMC_EVENTWAIT * returns. * * Input Parameters: @@ -2286,22 +2577,22 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, waitmask = 0; if ((eventset & SDIOWAIT_CMDDONE) != 0) { - waitmask |= SDIO_CMDDONE_MASK; + waitmask |= STM32_SDMMC_CMDDONE_MASK; } if ((eventset & SDIOWAIT_RESPONSEDONE) != 0) { - waitmask |= SDIO_RESPDONE_MASK; + waitmask |= STM32_SDMMC_RESPDONE_MASK; } if ((eventset & SDIOWAIT_TRANSFERDONE) != 0) { - waitmask |= SDIO_XFRDONE_MASK; + waitmask |= STM32_SDMMC_XFRDONE_MASK; } /* Enable event-related interrupts */ - putreg32(SDIO_WAITALL_ICR, STM32_SDMMC1_ICR); + sdmmc_putreg32(priv, STM32_SDMMC_WAITALL_ICR, STM32_SDMMC_ICR_OFFSET); } stm32_configwaitints(priv, waitmask, eventset, 0); @@ -2312,8 +2603,8 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev, * * Description: * Wait for one of the enabled events to occur (or a timeout). Note that - * all events enabled by SDIO_WAITEVENTS are disabled when stm32_eventwait - * returns. SDIO_WAITEVENTS must be called again before stm32_eventwait + * all events enabled by SDMMC_WAITEVENTS are disabled when stm32_eventwait + * returns. SDMMC_WAITEVENTS must be called again before stm32_eventwait * can be used again. * * Input Parameters: @@ -2369,7 +2660,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, 1, (uint32_t)priv); if (ret != OK) { - ferr("ERROR: wd_start failed: %d\n", ret); + mcerr("ERROR: wd_start failed: %d\n", ret); } } @@ -2380,7 +2671,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, * If Pin is ready and if ISR did NOT fire end the wait here */ - if (stm32_gpioread(GPIO_SDMMC1_D0) && + if (stm32_gpioread(priv->d0_gpio) && (priv->wkupevent & SDIOWAIT_WRCOMPLETE) == 0) { stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); @@ -2456,7 +2747,7 @@ static void stm32_callbackenable(FAR struct sdio_dev_s *dev, { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; - finfo("eventset: %02x\n", eventset); + mcinfo("eventset: %02x\n", eventset); DEBUGASSERT(priv != NULL); priv->cbevents = eventset; @@ -2473,7 +2764,7 @@ static void stm32_callbackenable(FAR struct sdio_dev_s *dev, * thread. * * When this method is called, all callbacks should be disabled until they - * are enabled via a call to SDIO_CALLBACKENABLE + * are enabled via a call to SDMMC_CALLBACKENABLE * * Input Parameters: * dev - Device-specific state data @@ -2492,7 +2783,7 @@ static int stm32_registercallback(FAR struct sdio_dev_s *dev, /* Disable callbacks and register this callback and is argument */ - finfo("Register %p(%p)\n", callback, arg); + mcinfo("Register %p(%p)\n", callback, arg); DEBUGASSERT(priv != NULL); priv->cbevents = 0; @@ -2555,7 +2846,8 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, /* DMA must be possible to the buffer */ - if (!stm32_dmacapable((uintptr_t)buffer, (buflen + 3) >> 2, SDIO_RXDMA32_CONFIG)) + if (!stm32_dmacapable((uintptr_t)buffer, (buflen + 3) >> 2, + STM32_SDMMC_RXDMA32_CONFIG | priv->dmapri)) { return -EFAULT; } @@ -2598,7 +2890,8 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, #ifdef CONFIG_ARMV7M_DCACHE /* buffer alignment is required for DMA transfers with dcache */ - if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) + if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || + (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) { return -EFAULT; } @@ -2606,7 +2899,7 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Reset the DPSM configuration */ - stm32_datadisable(); + stm32_datadisable(priv); /* Initialize register sampling */ @@ -2621,15 +2914,18 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Then set up the SDIO data path */ - dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; - stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize | SDIO_DCTRL_DTDIR); + dblocksize = stm32_log2(buflen) << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(priv, SDMMC_DTIMER_DATATIMEOUT, buflen, dblocksize | + STM32_SDMMC_DCTRL_DTDIR); /* Configure the RX DMA */ - stm32_configxfrints(priv, SDIO_DMARECV_MASK); - - stm32_dmasetup(priv->dma, STM32_SDMMC1_FIFO, (uint32_t)buffer, - (buflen + 3) >> 2, SDIO_RXDMA32_CONFIG); + stm32_configxfrints(priv, STM32_SDMMC_DMARECV_MASK); + + sdmmc_modifyreg32(priv, STM32_SDMMC_DCTRL_OFFSET, 0, STM32_SDMMC_DCTRL_DMAEN); + stm32_dmasetup(priv->dma, priv->base + STM32_SDMMC_FIFO_OFFSET, + (uint32_t)buffer, (buflen + 3) >> 2, + SDMMC_RXDMA32_CONFIG | priv->dmapri); /* Force RAM reread */ @@ -2679,7 +2975,8 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, #ifdef CONFIG_ARMV7M_DCACHE /* buffer alignment is required for DMA transfers with dcache */ - if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) + if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || + (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) { return -EFAULT; } @@ -2687,7 +2984,7 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, /* Reset the DPSM configuration */ - stm32_datadisable(); + stm32_datadisable(priv); /* Initialize register sampling */ @@ -2706,13 +3003,13 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, /* Then set up the SDIO data path */ - dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; - stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize); + dblocksize = stm32_log2(buflen) << STM32_SDMMC_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(priv, SDMMC_DTIMER_DATATIMEOUT, buflen, dblocksize); /* Configure the TX DMA */ - stm32_dmasetup(priv->dma, STM32_SDMMC1_FIFO, (uint32_t)buffer, - (buflen + 3) >> 2, SDIO_TXDMA32_CONFIG); + stm32_dmasetup(priv->dma, priv->base + STM32_SDMMC_FIFO_OFFSET, (uint32_t)buffer, + (buflen + 3) >> 2, SDMMC_TXDMA32_CONFIG | priv->dmapri); stm32_sample(priv, SAMPLENDX_BEFORE_ENABLE); @@ -2723,7 +3020,7 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, /* Enable TX interrupts */ - stm32_configxfrints(priv, SDIO_DMASEND_MASK); + stm32_configxfrints(priv, STM32_SDMMC_DMASEND_MASK); return OK; } @@ -2752,7 +3049,7 @@ static void stm32_callback(void *arg) /* Is a callback registered? */ DEBUGASSERT(priv != NULL); - finfo("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + mcinfo("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); if (priv->callback) @@ -2797,14 +3094,14 @@ static void stm32_callback(void *arg) { /* Yes.. queue it */ - finfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); } else { /* No.. then just call the callback here */ - finfo("Callback to %p(%p)\n", priv->callback, priv->cbarg); + mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg); priv->callback(priv->cbarg); } } @@ -2818,17 +3115,17 @@ static void stm32_callback(void *arg) * ****************************************************************************/ -static void stm32_default(void) +static void stm32_default(struct stm32_dev_s *priv) { - putreg32(SDIO_POWER_RESET, STM32_SDMMC1_POWER); - putreg32(SDIO_CLKCR_RESET, STM32_SDMMC1_CLKCR); - putreg32(SDIO_ARG_RESET, STM32_SDMMC1_ARG); - putreg32(SDIO_CMD_RESET, STM32_SDMMC1_CMD); - putreg32(SDIO_DTIMER_RESET, STM32_SDMMC1_DTIMER); - putreg32(SDIO_DLEN_RESET, STM32_SDMMC1_DLEN); - putreg32(SDIO_DCTRL_RESET, STM32_SDMMC1_DCTRL); - putreg32(SDIO_ICR_RESET, STM32_SDMMC1_ICR); - putreg32(SDIO_MASK_RESET, STM32_SDMMC1_MASK); + sdmmc_putreg32(priv, STM32_SDMMC_POWER_RESET, STM32_SDMMC_POWER_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_CLKCR_RESET, STM32_SDMMC_CLKCR_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_ARG_RESET, STM32_SDMMC_ARG_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_CMD_RESET, STM32_SDMMC_CMD_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_DTIMER_RESET, STM32_SDMMC_DTIMER_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_DLEN_RESET, STM32_SDMMC_DLEN_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_DCTRL_RESET, STM32_SDMMC_DCTRL_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_ICR_RESET, STM32_SDMMC_ICR_OFFSET); + sdmmc_putreg32(priv, STM32_SDMMC_MASK_RESET, STM32_SDMMC_MASK_OFFSET); } /**************************************************************************** @@ -2851,9 +3148,68 @@ static void stm32_default(void) FAR struct sdio_dev_s *sdio_initialize(int slotno) { - /* There is only one slot */ + struct stm32_dev_s *priv = NULL; +#ifdef CONFIG_SDIO_DMA + unsigned int dmachan; +#endif - struct stm32_dev_s *priv = &g_sdiodev; +#ifdef CONFIG_STM32F7_SDMMC1 + if (slotno == 0) + { + /* Select SDMMC 1 */ + + priv = &g_sdmmcdev1; +#ifdef CONFIG_SDIO_DMA + dmachan = SDMMC1_DMACHAN; +#endif + + /* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of + * 8-bit wide bus operation but D4-D7 are not configured). + * + * If bus is multiplexed then there is a custom bus configuration utility + * in the scope of the board support package. + */ +#ifndef CONFIG_SDIO_MUXBUS + stm32_configgpio(GPIO_SDMMC1_D0); +#ifndef CONFIG_SDMMC_WIDTH_D1_ONLY + stm32_configgpio(GPIO_SDMMC1_D1); + stm32_configgpio(GPIO_SDMMC1_D2); + stm32_configgpio(GPIO_SDMMC1_D3); +#endif + stm32_configgpio(GPIO_SDMMC1_CK); + stm32_configgpio(GPIO_SDMMC1_CMD); +#endif + + } + else +#endif +#ifdef CONFIG_STM32F7_SDMMC2 + if (slotno == 1) + { + /* Select SDMMC 2 */ + + priv = &g_sdmmcdev2; +#ifdef CONFIG_SDIO_DMA + dmachan = SDMMC2_DMACHAN; +#endif + +#ifndef CONFIG_SDIO_MUXBUS + stm32_configgpio(GPIO_SDMMC2_D0); +#ifndef CONFIG_SDMMC_WIDTH_D1_ONLY + stm32_configgpio(GPIO_SDMMC2_D1); + stm32_configgpio(GPIO_SDMMC2_D2); + stm32_configgpio(GPIO_SDMMC2_D3); +#endif + stm32_configgpio(GPIO_SDMMC2_CK); + stm32_configgpio(GPIO_SDMMC2_CMD); +#endif +} + else +#endif + { + mcerr("ERROR: Unsupported SDMMC slot: %d\n", slotno); + return NULL; + } /* Initialize the SDIO slot structure */ @@ -2864,41 +3220,23 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) /* Allocate a DMA channel */ #ifdef CONFIG_SDIO_DMA - priv->dma = stm32_dmachannel(SDIO_DMACHAN); + priv->dma = stm32_dmachannel(dmachan); DEBUGASSERT(priv->dma); #endif - /* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of - * 8-bit wide bus operation but D4-D7 are not configured). - * - * If bus is multiplexed then there is a custom bus configuration utility - * in the scope of the board support package. - */ - -#ifndef CONFIG_SDIO_MUXBUS - stm32_configgpio(GPIO_SDMMC1_D0); -#ifndef CONFIG_SDIO_WIDTH_D1_ONLY - stm32_configgpio(GPIO_SDMMC1_D1); - stm32_configgpio(GPIO_SDMMC1_D2); - stm32_configgpio(GPIO_SDMMC1_D3); -#endif - stm32_configgpio(GPIO_SDMMC1_CK); - stm32_configgpio(GPIO_SDMMC1_CMD); -#endif - /* Reset the card and assure that it is in the initial, unconfigured * state. */ stm32_reset(&priv->dev); - return &g_sdiodev.dev; + return &priv->dev; } /**************************************************************************** * Name: sdio_mediachange * * Description: - * Called by board-specific logic -- posssible from an interrupt handler -- + * Called by board-specific logic -- possible from an interrupt handler -- * in order to signal to the driver that a card has been inserted or * removed from the slot * @@ -2934,7 +3272,7 @@ void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) leave_critical_section(flags); - finfo("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + mcinfo("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); /* Perform any requested callback if the status has changed */ @@ -2976,7 +3314,8 @@ void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) { priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; } - finfo("cdstatus: %02x\n", priv->cdstatus); + + mcinfo("cdstatus: %02x\n", priv->cdstatus); leave_critical_section(flags); } -#endif /* CONFIG_STM32F7_SDMMC1 */ +#endif /* CONFIG_STM32F7_SDMMC1 || CONFIG_STM32F7_SDMMC2 */ diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.h b/arch/arm/src/stm32f7/stm32_sdmmc.h index 12b6348559f..8e722497c5f 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.h +++ b/arch/arm/src/stm32f7/stm32_sdmmc.h @@ -40,13 +40,13 @@ * Included Files ************************************************************************************/ -#include "chip/stm32_sdmmc.h" - #include #include #include #include "chip.h" +#include "chip/stm32_sdmmc.h" + /************************************************************************************ * Public Functions diff --git a/configs/nucleo-144/include/board.h b/configs/nucleo-144/include/board.h index 1561ad8cc68..18d2727502b 100644 --- a/configs/nucleo-144/include/board.h +++ b/configs/nucleo-144/include/board.h @@ -127,8 +127,8 @@ #define CONFIG_STM32F7_PLLSAI 1 #define STM32_RCC_PLLSAICFGR_PLLSAIN RCC_PLLSAICFGR_PLLSAIN(192) -#define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(2) -#define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(2) +#define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(8) +#define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(4) #define STM32_RCC_PLLSAICFGR_PLLSAIR RCC_PLLSAICFGR_PLLSAIR(2) /* Configure Dedicated Clock Configuration Register */ @@ -167,7 +167,7 @@ #define STM32_RCC_DCKCFGR2_I2C4SRC RCC_DCKCFGR2_I2C4SEL_HSI #define STM32_RCC_DCKCFGR2_LPTIM1SRC RCC_DCKCFGR2_LPTIM1SEL_APB #define STM32_RCC_DCKCFGR2_CECSRC RCC_DCKCFGR2_CECSEL_HSI -#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLLSAI +#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLL #define STM32_RCC_DCKCFGR2_SDMMCSRC RCC_DCKCFGR2_SDMMCSEL_48MHZ #define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ #define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_48MHZ @@ -216,6 +216,61 @@ #define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY) #define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY) +/* SDMMC dividers. Note that slower clocking is required when DMA is disabled + * in order to avoid RX overrun/TX underrun errors due to delayed responses + * to service FIFOs in interrupt driven mode. These values have not been + * tuned!!! + * + * SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(118+2)=400 KHz + */ + +#define STM32_SDMMC_INIT_CLKDIV (118 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) + +/* DMA ON: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(1+2)=16 MHz + * DMA OFF: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(2+2)=12 MHz + */ + +#ifdef CONFIG_SDIO_DMA +# define STM32_SDMMC_MMCXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_MMCXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +/* DMA ON: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(1+2)=16 MHz + * DMA OFF: SDMMCCLK=48MHz, SDMMC_CK=SDMMCCLK/(2+2)=12 MHz + */ + +#ifdef CONFIG_SDIO_DMA +# define STM32_SDMMC_SDXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#else +# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#endif + +#if defined(CONFIG_STM32F7_SDMMC2) +# define GPIO_SDMMC2_D0 GPIO_SDMMC2_D0_1 +# define GPIO_SDMMC2_D1 GPIO_SDMMC2_D1_1 +# define GPIO_SDMMC2_D2 GPIO_SDMMC2_D2_1 +# define GPIO_SDMMC2_D3 GPIO_SDMMC2_D3_1 +#endif +/* DMA Channl/Stream Selections *****************************************************/ +/* Stream selections are arbitrary for now but might become important in the future + * if we set aside more DMA channels/streams. + * + * SDMMC DMA is on DMA2 + * + * SDMMC1 DMA + * DMAMAP_SDMMC1_1 = Channel 4, Stream 3 + * DMAMAP_SDMMC1_2 = Channel 4, Stream 6 + * + * SDMMC2 DMA + * DMAMAP_SDMMC2_1 = Channel 11, Stream 0 + * DMAMAP_SDMMC3_2 = Channel 11, Stream 5 + */ + +#define DMAMAP_SDMMC1 DMAMAP_SDMMC1_1 +#define DMAMAP_SDMMC2 DMAMAP_SDMMC2_1 + + /* FLASH wait states * * --------- ---------- ----------- diff --git a/configs/nucleo-144/src/Makefile b/configs/nucleo-144/src/Makefile index e4e02750bd4..ca3ede019c5 100644 --- a/configs/nucleo-144/src/Makefile +++ b/configs/nucleo-144/src/Makefile @@ -60,7 +60,7 @@ ifeq ($(CONFIG_ADC),y) CSRCS += stm32_adc.c endif -ifeq ($(HAVE_SDIO),y) +ifeq ($(CONFIG_MMCSD),y) CSRCS += stm32_sdio.c endif diff --git a/configs/nucleo-144/src/nucleo-144.h b/configs/nucleo-144/src/nucleo-144.h index 48a6f9f11a3..2d070539d25 100644 --- a/configs/nucleo-144/src/nucleo-144.h +++ b/configs/nucleo-144/src/nucleo-144.h @@ -128,8 +128,45 @@ #define NUCLEO_SPI_BUS3_CS2 10 #define NUCLEO_SPI_BUS3_CS3 11 -#if defined(CONFIG_STM32_SDIO) -#define GPIO_SDIO_NCD (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI | GPIO_PORTB | GPIO_PIN15) +#if defined(CONFIG_STM32F7_SDMMC1) || defined(CONFIG_STM32F7_SDMMC2) +# define HAVE_SDIO +#endif + +#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_MMCSD_SDIO) +# undef HAVE_SDIO +#endif + +#define SDIO_SLOTNO 0 /* Only one slot */ + +#ifdef HAVE_SDIO + +# if defined(CONFIG_STM32F7_SDMMC1) +# define GPIO_SDMMC1_NCD (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI | GPIO_PORTC | GPIO_PIN11) +# endif + +# 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 /************************************************************************************ @@ -196,5 +233,17 @@ int stm32_dma_alloc_init(void); int board_adc_initialize(void); #endif +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Called at application startup time to initialize the SCMMC functionality. + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD +int stm32_sdio_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_NUCLEO_144_SRC_NUCLEO_144_H */ diff --git a/configs/nucleo-144/src/stm32_appinitialize.c b/configs/nucleo-144/src/stm32_appinitialize.c index 9daf02a3ff0..17b26a1b05d 100644 --- a/configs/nucleo-144/src/stm32_appinitialize.c +++ b/configs/nucleo-144/src/stm32_appinitialize.c @@ -42,6 +42,7 @@ #include #include +#include #include #include "nucleo-144.h" diff --git a/configs/nucleo-144/src/stm32_sdio.c b/configs/nucleo-144/src/stm32_sdio.c index 87b316be2e0..7904f8c2eba 100644 --- a/configs/nucleo-144/src/stm32_sdio.c +++ b/configs/nucleo-144/src/stm32_sdio.c @@ -47,10 +47,13 @@ #include #include -#include "stm32.h" +#include "chip.h" #include "nucleo-144.h" +#include "stm32_gpio.h" +#include "stm32_sdmmc.h" + +#ifdef CONFIG_MMCSD -#ifdef HAVE_SDIO /**************************************************************************** * Pre-processor Definitions @@ -61,7 +64,7 @@ /* Card detections requires card support and a card detection GPIO */ #define HAVE_NCD 1 -#if !defined(CONFIG_STM32_SDIO) || !defined(GPIO_SDIO_NCD) +#if !defined(GPIO_SDMMC1_NCD) # undef HAVE_NCD #endif @@ -91,8 +94,8 @@ static int stm32_ncd_interrupt(int irq, FAR void *context) { bool present; - present = !stm32_gpioread(GPIO_SDIO_NCD); - if (present != g_sd_inserted) + present = !stm32_gpioread(GPIO_SDMMC1_NCD); + if (g_sdio_dev && present != g_sd_inserted) { sdio_mediachange(g_sdio_dev, present); g_sd_inserted = present; @@ -125,11 +128,11 @@ int stm32_sdio_initialize(void) /* Configure the card detect GPIO */ - stm32_configgpio(GPIO_SDIO_NCD); + stm32_configgpio(GPIO_SDMMC1_NCD); /* Register an interrupt handler for the card detect pin */ - stm32_gpiosetevent(GPIO_SDIO_NCD, true, true, true, stm32_ncd_interrupt); + stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt); #endif /* Mount the SDIO-based MMC/SD block driver */ @@ -160,7 +163,7 @@ int stm32_sdio_initialize(void) #ifdef HAVE_NCD /* Use SD card detect pin to check if a card is g_sd_inserted */ - cd_status = !stm32_gpioread(GPIO_SDIO_NCD); + cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD); finfo("Card detect : %d\n", cd_status); sdio_mediachange(g_sdio_dev, cd_status); diff --git a/tools/README.txt b/tools/README.txt index 44b0427427f..408bccad7b3 100644 --- a/tools/README.txt +++ b/tools/README.txt @@ -580,7 +580,7 @@ refresh.sh This is a bash script that automatics refreshing of board default configuration (defconfig) files. It does not do anything special - thet you cannot do manually, but is useful for me when I have to + that you cannot do manually, but is useful for me when I have to update dozens of confuration files. Configuration files have to be updated because over time, the