From 5d816174dfe5cdc49bf45fdad7f2a93f41200760 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 13 Nov 2009 15:16:33 +0000 Subject: [PATCH] Add to STM32 SDIO driver git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2252 42af7a65-404d-4744-a932-0658087f49c3 --- arch/arm/src/stm32/stm32_memorymap.h | 1 + arch/arm/src/stm32/stm32_sdio.c | 100 ++++++++++++++++++++++++++- arch/arm/src/stm32/stm32_sdio.h | 47 +++++++++++++ 3 files changed, 145 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/stm32/stm32_memorymap.h b/arch/arm/src/stm32/stm32_memorymap.h index 50b5593ca3..a3333605c3 100755 --- a/arch/arm/src/stm32/stm32_memorymap.h +++ b/arch/arm/src/stm32/stm32_memorymap.h @@ -53,6 +53,7 @@ #define STM32_FLASH_BASE 0x08000000 /* 0x08000000 - Up to 512Kb */ #define STM32_SRAM_BASE 0x20000000 /* 0x20000000 - 64Kb SRAM */ #define STM32_SRAMBB_BASE 0x22000000 +#define STM32_PERIPH_BASE 0x40000000 /* Register Base Address ************************************************************/ diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c index 26aeb0e482..edcd2bdffc 100644 --- a/arch/arm/src/stm32/stm32_sdio.c +++ b/arch/arm/src/stm32/stm32_sdio.c @@ -109,6 +109,17 @@ static inline void stm32_enableint(uint32 bitset); static inline void stm32_disableint(uint32 bitset); static void stm32_setpwrctrl(uint32 pwrctrl); static inline uint32 stm32_getpwrctrl(void); +static inline void stm32_clkenable(void) +static inline void stm32_clkdisable(void) + +/* DMA Helpers **************************************************************/ + +static inline void stm32_dmaenable(void); + +/* Data Transfer Helpers ****************************************************/ + +static void stm32_dataconfig(uint32 timeout, uint32 dlen, uint32 dctrl); +static void stm32_datadisable(void); /* SDIO interface methods ***************************************************/ @@ -338,6 +349,81 @@ static inline uint32 stm32_getpwrctrl(void) { return getreg32(STM32_SDIO_POWER) & SDIO_POWER_PWRCTRL_MASK; } + +static inline void stm32_clkenable(void) +{ + putreg32(1, SDIO_CLKCR_CLKEN_BB); +} + +static inline void stm32_clkdisable(void) +{ + putreg32(0, SDIO_CLKCR_CLKEN_BB); +} + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ +static inline void stm32_dmaenable(void) +{ + putreg32(1, SDIO_DCTRL_DMAEN_BB); +} + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_dataconfig + * + * Description: + * Configure the SDIO data path for the next data transfer + * + ****************************************************************************/ + +static void stm32_dataconfig(uint32 timeout, uint32 dlen, uint32 dctrl) +{ + uint32 regval = 0; + + /* Enable data path */ + + putreg32(timeout, STM32_SDIO_DTIMER); /* Set DTIMER */ + putreg32(dlen, STM32_SDIO_DLEN); /* Set DLEN */ + + /* Configure DCTRL DTDIR, DTMODE, and DBLOCKSIZE fields and set the DTEN + * field + */ + + regval = getreg32(STM32_SDIO_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|DIO_DCTRL_DTEN); + putreg32(regval, STM32_SDIO_DCTRL); +} + +/**************************************************************************** + * Name: stm32_datadisable + * + * Description: + * Disable the the SDIO data path setup by stm32_dataconfig() and + * disable DMA. + * + ****************************************************************************/ + +static void stm32_datadisable(void) +{ + uint32 regval; + + /* Disable the data path */ + + putreg32(SD_DATATIMEOUT, STM32_SDIO_DTIMER); /* Reset DTIMER */ + putreg32(0, STM32_SDIO_DLEN); /* Reset DLEN */ + + /* Reset DCTRL DTEN, DTDIR, DTMODE, DMAEN, and DBLOCKSIZE fields */ + + regval = getreg32(STM32_SDIO_DCTRL); + regval &= ~(SDIO_DCTRL_DTEN|SDIO_DCTRL_DTDIR|SDIO_DCTRL_DTMODE| + SDIO_DCTRL_DMAEN|SDIO_DCTRL_DBLOCKSIZE_MASK); + putreg32(regval, STM32_SDIO_DCTRL); +} /**************************************************************************** * SDIO Interface Methods @@ -752,6 +838,8 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshor } return OK; } + +/* MMC responses not supported */ static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rnotimpl) { @@ -858,7 +946,7 @@ static ubyte stm32_events(FAR struct sdio_dev_s *dev) #ifdef CONFIG_SDIO_DMA static boolean stm32_dmasupported(FAR struct sdio_dev_s *dev) { - return FALSE; + return TRUE; } #endif @@ -1071,9 +1159,15 @@ int mmcsd_slotinitialize(int minor, int slotno, FAR struct sdio_dev_s *dev) /* Put SDIO registers in their default, reset state */ - stm32_default(); + stm32_default(); + + /* Configure the SDIO peripheral */ + + stm32_setclkcr(STM32_CLCKCR_INIT); + stm32_setpwrctrl(SDIO_POWER_PWRCTRL_ON); + stm32_clkenable(ENABLE); return -ENOSYS; } -#endif /* CONFIG_STM32_SDIO */ \ No newline at end of file +#endif /* CONFIG_STM32_SDIO */ diff --git a/arch/arm/src/stm32/stm32_sdio.h b/arch/arm/src/stm32/stm32_sdio.h index 8c7f84391f..d276be8cff 100755 --- a/arch/arm/src/stm32/stm32_sdio.h +++ b/arch/arm/src/stm32/stm32_sdio.h @@ -93,6 +93,30 @@ #define STM32_SDIO_FIFOCNT (STM32_SDIO_BASE+STM32_SDIO_FIFOCNT_OFFSET) #define STM32_SDIO_FIFO (STM32_SDIO_BASE+STM32_SDIO_FIFO_OFFSET) +/* Bit-band (BB) base addresses ****************************************************/ + +#define STM32_SDIO_OFFSET (STM32_SDIO_BASE-STM32_PERIPH_BASE) + +#define STM32_SDIO_POWER_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_POWER_OFFSET)<<5)) +#define STM32_SDIO_CLKCR_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_CLKCR_OFFSET)<<5)) +#define STM32_SDIO_ARG_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_ARG_OFFSET)<<5)) +#define STM32_SDIO_CMD_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_CMD_OFFSET)<<5)) +#define STM32_SDIO_RESPCMD_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESPCMD_OFFSET)<<5)) +#define STM32_SDIO_RESP_BB(n) (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP_OFFSET(n))<<5)) +#define STM32_SDIO_RESP1_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP1_OFFSET)<<5)) +#define STM32_SDIO_RESP2_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP2_OFFSET)<<5)) +#define STM32_SDIO_RESP3_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP3_OFFSET)<<5)) +#define STM32_SDIO_RESP4_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_RESP4_OFFSET)<<5)) +#define STM32_SDIO_DTIMER_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DTIMER_OFFSET)<<5)) +#define STM32_SDIO_DLEN_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DLEN_OFFSET)<<5)) +#define STM32_SDIO_DCTRL_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DCTRL_OFFSET)<<5)) +#define STM32_SDIO_DCOUNT_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_DCOUNT_OFFSET)<<5)) +#define STM32_SDIO_STA_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_STA_OFFSET)<<5)) +#define STM32_SDIO_ICR_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_ICR_OFFSET)<<5)) +#define STM32_SDIO_MASK_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_MASK_OFFSET)<<5)) +#define STM32_SDIO_FIFOCNT_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_FIFOCNT_OFFSET)<<5)) +#define STM32_SDIO_FIFO_BB (STM32_PERIPHBB_BASE+((STM32_SDIO_OFFSET+STM32_SDIO_FIFO_OFFSET)<<5)) + /* Register Bitfield Definitions ****************************************************/ #define SDIO_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ @@ -119,6 +143,12 @@ #define SDIO_CLKCR_RESET (0) /* Reset value */ #define SDIO_ARG_RESET (0) /* Reset value */ +#define SDIO_CLKCR_CLKEN_BB (STM32_SDIO_CLKCR_BB + (8 * 4)) +#define SDIO_CLKCR_PWRSAV_BB (STM32_SDIO_CLKCR_BB + (9 * 4)) +#define SDIO_CLKCR_BYPASS_BB (STM32_SDIO_CLKCR_BB + (10 * 4)) +#define SDIO_CLKCR_NEGEDGE_BB (STM32_SDIO_CLKCR_BB + (13 * 4)) +#define SDIO_CLKCR_HWFC_EN_BB (STM32_SDIO_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 */ @@ -136,6 +166,14 @@ #define SDIO_CMD_RESET (0) /* Reset value */ +#define SDIO_CMD_WAITINT_BB (STM32_SDIO_CMD_BB + (8 * 4)) +#define SDIO_CMD_WAITPEND_BB (STM32_SDIO_CMD_BB + (9 * 4)) +#define SDIO_CMD_CPSMEN_BB (STM32_SDIO_CMD_BB + (10 * 4)) +#define SDIO_CMD_SUSPEND_BB (STM32_SDIO_CMD_BB + (11 * 4)) +#define SDIO_CMD_ENCMD_BB (STM32_SDIO_CMD_BB + (12 * 4)) +#define SDIO_CMD_NIEN_BB (STM32_SDIO_CMD_BB + (13 * 4)) +#define SDIO_CMD_ATACMD_BB (STM32_SDIO_CMD_BB + (14 * 4)) + #define SDIO_RESPCMD_SHIFT (0) #define SDIO_RESPCMD_MASK (0x3f << SDIO_RESPCMD_SHIFT) @@ -174,6 +212,15 @@ #define SDIO_DCTRL_RESET (0) /* Reset value */ +#define SDIO_DCTRL_DTEN_BB (STM32_SDIO_DCTRL_BB + (0 * 4)) +#define SDIO_DCTRL_DTDIR_BB (STM32_SDIO_DCTRL_BB + (1 * 4)) +#define SDIO_DCTRL_DTMODE_BB (STM32_SDIO_DCTRL_BB + (2 * 4)) +#define SDIO_DCTRL_DMAEN_BB (STM32_SDIO_DCTRL_BB + (3 * 4)) +#define SDIO_DCTRL_RWSTART_BB (STM32_SDIO_DCTRL_BB + (8 * 4)) +#define SDIO_DCTRL_RWSTOP_BB (STM32_SDIO_DCTRL_BB + (9 * 4)) +#define SDIO_DCTRL_RWMOD_BB (STM32_SDIO_DCTRL_BB + (10 * 4)) +#define SDIO_DCTRL_SDIOEN_BB (STM32_SDIO_DCTRL_BB + (11 * 4)) + #define SDIO_DATACOUNT_SHIFT (0) #define SDIO_DATACOUNT_MASK (0x01ffffff << SDIO_DATACOUNT_SHIFT)