Incremental progress on STM32 MMCSD driver

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2245 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-11-11 21:20:49 +00:00
parent d170816334
commit 7088acf110
2 changed files with 172 additions and 5 deletions

View File

@ -55,6 +55,25 @@
* Pre-Processor Definitions
****************************************************************************/
/* Friendly CLKCR bit re-definitions ****************************************/
#define SDIO_CLKCR_RISINGEDGE (0)
#define SDIO_CLKCR_FALLINGEDGE SDIO_CLKCR_NEGEDGE
/* HCLK=72MHz, SDIOCLK=72MHz, SDIO_CK=HCLK/(178+2)=400 KHz */
#define SDIO_INIT_CLKDIV (178 << SDIO_CLKCR_CLKDIV_SHIFT)
#define STM32_CLCKCR_INIT \
(SDIO_INIT_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D1)
/* HCLK=72 MHz, SDIOCLK=72MHz, SDIO_CK=HCLK/(1+2)=24 MHz */
#define SDIO_TRANSFER_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT)
#define STM32_CLCKCR_TRANSFER \
(SDIO_TRANSFER_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D1)
#define STM32_CLKCR_WIDETRANSFER \
(SDIO_TRANSFER_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D4)
/****************************************************************************
* Private Types
****************************************************************************/
@ -66,12 +85,20 @@ struct stm32_dev_s
struct sdio_dev_s dev; /* Standard, base MMC/SD interface */
/* STM32-specific extensions */
ubyte type; /* Card type (see MMCSD_CARDTYPE_ definitions) */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Low-level helpers ********************************************************/
static inline void stm32_setclkcr(uint32 clkcr);
static inline void stm32_enableint(uint32 bitset);
static inline void stm32_disableint(uint32 bitset);
/* SDIO interface methods ***************************************************/
/* Initialization/setup */
@ -87,7 +114,7 @@ static int stm32_attach(FAR struct sdio_dev_s *dev);
/* Command/Status/Data Transfer */
static void stm32_sendcmd(FAR struct sdio_dev_s *dev, ubyte cmd,
static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd,
uint32 arg, FAR const ubyte *data);
static int stm32_senddata(FAR struct sdio_dev_s *dev,
FAR const ubyte *buffer);
@ -175,6 +202,91 @@ struct stm32_dev_s g_mmcsd =
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_setclkcr
*
* Description:
* Modify oft-changed bits in the CLKCR register. Only the following bit-
* fields are changed:
*
* CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, and HWFC_EN
*
* Input Parameters:
* clkcr - A new CLKCR setting for the above mentions bits (other bits
* are ignored.
*
* Returned Value:
* None
*
****************************************************************************/
static inline void stm32_setclkcr(uint32 clkcr)
{
uint32 regval = getreg32(STM32_SDIO_CLKCR);
/* 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);
/* 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);
regval |= clkcr;
putreg32(regval, STM32_SDIO_CLKCR);
}
/****************************************************************************
* Name: stm32_enableint
*
* Description:
* Enable SDIO interrupts
*
* Input Parameters:
* bitset - The set of bits in the SDIO MASK register to set
*
* Returned Value:
* None
*
****************************************************************************/
static inline void stm32_enableint(uint32 bitset)
{
uint32 regval;
regval = getreg32(STM32_SDIO_MASK);
regval |= bitset;
putreg32(regval, STM32_SDIO_MASK);
}
/****************************************************************************
* Name: stm32_disableint
*
* Description:
* Disable SDIO interrupts
*
* Input Parameters:
* bitset - The set of bits in the SDIO MASK register to clear
*
* Returned Value:
* None
*
****************************************************************************/
static inline void stm32_disableint(uint32 bitset)
{
uint32 regval;
regval = getreg32(STM32_SDIO_MASK);
regval &= ~bitset;
putreg32(regval, STM32_SDIO_MASK);
}
/****************************************************************************
* SDIO Interface Methods
****************************************************************************/
/****************************************************************************
* Name: stm32_reset
*
@ -300,7 +412,7 @@ static int stm32_attach(FAR struct sdio_dev_s *dev)
*
* Input Parameters:
* dev - An instance of the MMC/SD device interface
* cmd - The command to send
* cmd - The command to send (32-bits, encoded)
* arg - 32-bit argument required with some commands
* data - A reference to data required with some commands
*
@ -309,9 +421,53 @@ static int stm32_attach(FAR struct sdio_dev_s *dev)
*
****************************************************************************/
static void stm32_sendcmd(FAR struct sdio_dev_s *dev, ubyte cmd,
static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd,
uint32 arg, FAR const ubyte *data)
{
uint32 regval;
uint32 cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT;
/* Set the SDIO Argument value */
putreg32(arg, STM32_SDIO_ARG);
/* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */
regval = getreg32(STM32_SDIO_CMD);
regval &= ~(SDIO_CMD_CMDINDEX_MASK|SDIO_CMD_WAITRESP_MASK|
SDIO_CMD_WAITINT|SDIO_CMD_WAITPEND|SDIO_CMD_CPSMEN);
/* Set WAITRESP bits */
#warning VERIFY
switch ((cmd & MMCSD_RESPONSE_MASK) >> MMCSD_RESPONSE_SHIFT)
{
case MMCSD_NO_RESPONSE:
regval |= SDIO_CMD_NORESPONSE;
break;
case MMCSD_R1_RESPONSE:
case MMCSD_R1B_RESPONSE:
case MMCSD_R3_RESPONSE:
case MMCSD_R4_RESPONSE:
case MMCSD_R5_RESPONSE:
case MMCSD_R6_RESPONSE:
case MMCSD_R7_RESPONSE:
regval |= SDIO_CMD_SHORTRESPONSE;
break;
case MMCSD_R2_RESPONSE:
regval |= SDIO_CMD_LONGRESPONSE;
break;
}
/* Set CPSMEN and the command index */
cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT;
regval |= cmdidx | SDIO_CMD_CPSMEN;
/* Write the SDIO CMD */
putreg32(regval, STM32_SDIO_CMD);
}
/****************************************************************************
@ -618,7 +774,17 @@ static int stm32_dmastop(FAR struct sdio_dev_s *dev)
#ifdef CONFIG_SDIO_DMA
static int stm32_dmastatus(FAR struct sdio_dev_s *dev, size_t *remaining)
{
return -ENOSYS;
#ifdef CONFIG_DEBUG
if (remaining)
{
*remaining = getreg32(STM32_SDIO_DCOUNT);
return OK;
}
return -EINVAL;
#else
*remaining = getreg32(STM32_SDIO_DCOUNT);
return OK;
#endif
}
#endif

View File

@ -123,7 +123,7 @@
#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_NORESPONSE1 (0 << SDIO_CMD_WAITRESP_SHIFT) /* 00/10: No response */
# 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 */
@ -217,6 +217,7 @@
#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 */