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:
parent
d170816334
commit
7088acf110
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user