mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 01:05:54 +08:00
Add IOCTLs and card identification logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2253 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -81,7 +81,12 @@
|
||||
#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)
|
||||
(SDIO_TRANSFER_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D4)
|
||||
|
||||
/* Timing */
|
||||
|
||||
#define SDIO_CMDTIMEOUT 100000
|
||||
#define SDIO_LONGTIMEOUT 0x7fffffff
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@@ -139,7 +144,8 @@ static int stm32_attach(FAR struct sdio_dev_s *dev);
|
||||
static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg);
|
||||
static int stm32_senddata(FAR struct sdio_dev_s *dev,
|
||||
FAR const ubyte *buffer);
|
||||
|
||||
|
||||
static int stm32_waitresponseFAR struct sdio_dev_s *dev, uint32 cmd);
|
||||
static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshort);
|
||||
static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 rlong[4]);
|
||||
static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshort);
|
||||
@@ -191,7 +197,8 @@ struct stm32_dev_s g_mmcsd =
|
||||
.setblocklen = stm32_setblocklen,
|
||||
.attach = stm32_attach,
|
||||
.sendcmd = stm32_sendcmd,
|
||||
.senddata = stm32_senddata,
|
||||
.senddata = stm32_senddata,
|
||||
.waitresponse = stm32_waitresponse,
|
||||
.recvR1 = stm32_recvshortcrc,
|
||||
.recvR2 = stm32_recvlong,
|
||||
.recvR3 = stm32_recvshort,
|
||||
@@ -629,6 +636,71 @@ static int stm32_senddata(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_waitresponse
|
||||
*
|
||||
* Description:
|
||||
* Poll-wait for the response to the last command to be ready.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the MMC/SD device interface
|
||||
* cmd - The command that was sent. See 32-bit command definitions above.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK is success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_waitresponseFAR struct sdio_dev_s *dev, uint32 cmd)
|
||||
{
|
||||
sint32 timeout = SDIO_LONGTIMEOUT;
|
||||
uint32 events;
|
||||
|
||||
switch (cmd & MMCSD_RESPONSE_MASK)
|
||||
{
|
||||
case MMCSD_NO_RESPONSE:
|
||||
timeout = SDIO_CMDTIMEOUT;
|
||||
events = SDIO_STA_CMDSENT;
|
||||
break;
|
||||
|
||||
case MMCSD_R1_RESPONSE:
|
||||
case MMCSD_R1B_RESPONSE:
|
||||
case MMCSD_R2_RESPONSE:
|
||||
case MMCSD_R6_RESPONSE:
|
||||
events = SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND;
|
||||
break;
|
||||
|
||||
case MMCSD_R4_RESPONSE:
|
||||
case MMCSD_R5_RESPONSE:
|
||||
return -ENOSYS;
|
||||
|
||||
case MMCSD_R3_RESPONSE:
|
||||
case MMCSD_R7_RESPONSE:
|
||||
events = SDIO_STA_CTIMEOUT|SDIO_STA_CMDREND;
|
||||
timeout = SDIO_CMDTIMEOUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Then wait for the response (or timeout) */
|
||||
|
||||
while ((getreg32(STM32_SDIO_STA) & events) == 0)
|
||||
{
|
||||
if (--timeout <= 0)
|
||||
{
|
||||
fdbg("ERROR: Timeout cmd=%04x\n", cmd);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all the static flags */
|
||||
|
||||
putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_recvRx
|
||||
*
|
||||
@@ -817,7 +889,7 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshor
|
||||
}
|
||||
#endif
|
||||
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if (regval & SDIO_STA_CTIMEOUT)
|
||||
{
|
||||
putreg32(SDIO_ICR_CTIMEOUTC, STM32_SDIO_ICR);
|
||||
|
||||
+488
-17
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,108 @@
|
||||
* Pre-Processor Definitions
|
||||
********************************************************************************************/
|
||||
|
||||
/* CMD8 Argument:
|
||||
* [31:12]: Reserved (shall be set to '0')
|
||||
* [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
|
||||
* [7:0]: Check Pattern (recommended 0xaa)
|
||||
* CMD8 Response: R7
|
||||
*/
|
||||
|
||||
#define MMCSD_CMD8VOLTAGE_SHIFT 8 /* Bits 8-11: Supply voltage */
|
||||
#define MMCSD_CMD8VOLTAGE_MASK (0x0f << MMCSD_CMD8VOLTAGE_SHIFT)
|
||||
# define MMCSD_CMD8VOLTAGE_27 (0x01 << MMCSD_CMD8VOLTAGE_SHIFT) /* 2.7-3.6V */
|
||||
#define MMCSD_CMD8ECHO_SHIFT 0 /* Bits 0-7: Check pattern */
|
||||
#define MMCSD_CMD8ECHO_MASK (0xff << MMCSD_CMD8ECHO_SHIFT)
|
||||
# define MMCSD_CMD8CHECKPATTERN (0xaa << MMCSD_CMD8ECHO_SHIFT)
|
||||
|
||||
/* ACMD41 argument */
|
||||
|
||||
#define MMCD_ACMD41_VOLTAGEWINDOW 0x80100000
|
||||
#define MMCD_ACMD41_HIGHCAPACITY (1 << 30)
|
||||
#define MMCD_ACMD41_STDCAPACITY (0)
|
||||
|
||||
/* R1 Card Status bit definitions */
|
||||
|
||||
#define MMCSD_R1_OUTOFRANGE (1 << 31) /* Bad argument */
|
||||
#define MMCSD_R1_ADDRESSERROR (1 << 30) /* Bad address */
|
||||
#define MMCSD_R1_BLOCKLENERROR (1 << 29) /* Bad block length */
|
||||
#define MMCSD_R1_ERASESEQERROR (1 << 28) /* Erase cmd error */
|
||||
#define MMCSD_R1_ERASEPARAM (1 << 27) /* Bad write blocks */
|
||||
#define MMCSD_R1_WPVIOLATION (1 << 26) /* Erase access failure */
|
||||
#define MMCSD_R1_CARDISLOCKED (1 << 25) /* Card is locked */
|
||||
#define MMCSD_R1_LOCKUNLOCKFAILED (1 << 24) /* Password error */
|
||||
#define MMCSD_R1_COMCRCERROR (1 << 23) /* CRC error */
|
||||
#define MMCSD_R1_ILLEGALCOMMAND (1 << 22) /* Bad command */
|
||||
#define MMCSD_R1_CARDECCFAILED (1 << 21) /* Failed to correct data */
|
||||
#define MMCSD_R1_CCERROR (1 << 20) /* Card controller error */
|
||||
#define MMCSD_R1_ERROR (1 << 19) /* General error */
|
||||
#define MMCSD_R1_UNDERRUN (1 << 18) /* Underrun (MMC only) */
|
||||
#define MMCSD_R1_OVERRRUN (1 << 17) /* Overrun (MMC only) */
|
||||
#define MMCSD_R1_CIDCSDOVERWRITE (1 << 16) /* CID/CSD error */
|
||||
#define MMCSD_R1_WPERASESKIP (1 << 15) /* Not all erased */
|
||||
#define MMCSD_R1_CARDECCDISABLED (1 << 14) /* Internal ECC not used */
|
||||
#define MMCSD_R1_ERASERESET (1 << 13) /* Reset sequence cleared */
|
||||
#define MMCSD_R1_STATE_SHIFT (9) /* Current card state */
|
||||
#define MMCSD_R1_STATE_MASK (15 << MMCSD_R1_STATE_SHIFT)
|
||||
/* Card identification mode states */
|
||||
# define MMCSD_R1_STATE_IDLE (0 << MMCSD_R1_STATE_SHIFT) /* 0=Idle state */
|
||||
# define MMCSD_R1_STATE_READY (1 << MMCSD_R1_STATE_SHIFT) /* 1=Ready state */
|
||||
# define MMCSD_R1_STATE_IDENT (2 << MMCSD_R1_STATE_SHIFT) /* 2=Identification state */
|
||||
/* Data transfer states */
|
||||
# define MMCSD_R1_STATE_STBY (3 << MMCSD_R1_STATE_SHIFT) /* 3=Standby state */
|
||||
# define MMCSD_R1_STATE_TRAN (4 << MMCSD_R1_STATE_SHIFT) /* 4=Transfer state */
|
||||
# define MMCSD_R1_STATE_DATA (5 << MMCSD_R1_STATE_SHIFT) /* 5=Sending data state */
|
||||
# define MMCSD_R1_STATE_RCV (6 << MMCSD_R1_STATE_SHIFT) /* 6=Receiving data state */
|
||||
# define MMCSD_R1_STATE_PRG (7 << MMCSD_R1_STATE_SHIFT) /* 7=Programming state */
|
||||
# define MMCSD_R1_STATE_DIS (8 << MMCSD_R1_STATE_SHIFT) /* 8=Disconnect state */
|
||||
#define MMCSD_R1_READYFORDATA (1 << 8) /* Buffer empty */
|
||||
#define MMCSD_R1_APPCMD (1 << 5) /* Next CMD is ACMD */
|
||||
#define MMCSD_R1_AKESEQERROR (1 << 3) /* Authentication error */
|
||||
#define MMCSD_R1_ERRORMASK 0xfdff0008 /* Error mask */
|
||||
|
||||
#define IS_STATE(v,s) (((v)&MMCSD_R1_CURRENTSTATE_MASK)==(s))
|
||||
|
||||
/* R3 (OCR) */
|
||||
|
||||
#define MMC_VDD_20_36 0x00ffff00 /* VDD voltage 2.0-3.6 */
|
||||
|
||||
#define MMCSD_VDD_145_150 (1 << 0) /* VDD voltage 1.45 - 1.50 */
|
||||
#define MMCSD_VDD_150_155 (1 << 1) /* VDD voltage 1.50 - 1.55 */
|
||||
#define MMCSD_VDD_155_160 (1 << 2) /* VDD voltage 1.55 - 1.60 */
|
||||
#define MMCSD_VDD_160_165 (1 << 3) /* VDD voltage 1.60 - 1.65 */
|
||||
#define MMCSD_VDD_165_170 (1 << 4) /* VDD voltage 1.65 - 1.70 */
|
||||
#define MMCSD_VDD_17_18 (1 << 5) /* VDD voltage 1.7 - 1.8 */
|
||||
#define MMCSD_VDD_18_19 (1 << 6) /* VDD voltage 1.8 - 1.9 */
|
||||
#define MMCSD_VDD_19_20 (1 << 7) /* VDD voltage 1.9 - 2.0 */
|
||||
#define MMCSD_VDD_20_21 (1 << 8) /* VDD voltage 2.0-2.1 */
|
||||
#define MMCSD_VDD_21_22 (1 << 9) /* VDD voltage 2.1-2.2 */
|
||||
#define MMCSD_VDD_22_23 (1 << 10) /* VDD voltage 2.2-2.3 */
|
||||
#define MMCSD_VDD_23_24 (1 << 11) /* VDD voltage 2.3-2.4 */
|
||||
#define MMCSD_VDD_24_25 (1 << 12) /* VDD voltage 2.4-2.5 */
|
||||
#define MMCSD_VDD_25_26 (1 << 13) /* VDD voltage 2.5-2.6 */
|
||||
#define MMCSD_VDD_26_27 (1 << 14) /* VDD voltage 2.6-2.7 */
|
||||
#define MMCSD_VDD_27_28 (1 << 15) /* VDD voltage 2.7-2.8 */
|
||||
#define MMCSD_VDD_28_29 (1 << 16) /* VDD voltage 2.8-2.9 */
|
||||
#define MMCSD_VDD_29_30 (1 << 17) /* VDD voltage 2.9-3.0 */
|
||||
#define MMCSD_VDD_30_31 (1 << 18) /* VDD voltage 3.0-3.1 */
|
||||
#define MMCSD_VDD_31_32 (1 << 19) /* VDD voltage 3.1-3.2 */
|
||||
#define MMCSD_VDD_32_33 (1 << 20) /* VDD voltage 3.2-3.3 */
|
||||
#define MMCSD_VDD_33_34 (1 << 21) /* VDD voltage 3.3-3.4 */
|
||||
#define MMCSD_VDD_34_35 (1 << 22) /* VDD voltage 3.4-3.5 */
|
||||
#define MMCSD_VDD_35_36 (1 << 23) /* VDD voltage 3.5-3.6 */
|
||||
#define MMCD_R3_HIGHCAPACITY (1 << 30) /* TRUE: Card supports block addressing */
|
||||
#define MMCSD_CARD_BUSY (1 << 31) /* Card power-up busy bit */
|
||||
|
||||
/* Last 4 bytes of the 48-bit R7 response */
|
||||
|
||||
#define MMCSD_R7VERSION_SHIFT 28 /* Bits 28-31: Command version number */
|
||||
#define MMCSD_R7VERSION_MASK (0x0f << MMCSD_R7VERSION_SHIFT)
|
||||
#define MMCSD_R7VOLTAGE_SHIFT 8 /* Bits 8-11: Voltage accepted */
|
||||
#define MMCSD_R7VOLTAGE_MASK (0x0f << MMCSD_R7VOLTAGE_SHIFT)
|
||||
# define MMCSD_R7VOLTAGE_27 (0x01 << MMCSD_R7VOLTAGE_SHIFT) /* 2.7-3.6V */
|
||||
#define MMCSD_R7ECHO_SHIFT 0 /* Bits 0-7: Echoed check pattern */
|
||||
#define MMCSD_R7ECHO_MASK (0xff << MMCSD_R7ECHO_SHIFT)
|
||||
# define MMCSD_R7CHECKPATTERN (0xaa << MMCSD_R7ECHO_SHIFT)
|
||||
|
||||
/********************************************************************************************
|
||||
* Public Types
|
||||
|
||||
+11
-2
@@ -97,12 +97,21 @@
|
||||
#define _BIOCVALID(c) (_IOC_TYPE(c)==_BIOCBASE)
|
||||
#define _BIOC(nr) _IOC(_BIOCBASE,nr)
|
||||
|
||||
#define BIOC_XIPBASE _BIOC(0x0001) /* IN: Pointer to pointer to void in
|
||||
#define BIOC_XIPBASE _BIOC(0x0001) /* Perform mapping to random access memory.
|
||||
* IN: Pointer to pointer to void in
|
||||
* which to received the XIP base.
|
||||
* OUT: If media is directly acccesible,
|
||||
* return (void*) base address
|
||||
* of device memory */
|
||||
|
||||
#define BIOC_PROBE _BIOC(0x0002) /* Re-probe and interface; check for media
|
||||
* in the slot
|
||||
* IN: None
|
||||
* OUT: None (ioctl return value provides
|
||||
* success/failure indication). */
|
||||
#define BIOC_EJECT _BIOC(0x0003) /* Eject/disable media in the slot
|
||||
* IN: None
|
||||
* OUT: None (ioctl return value provides
|
||||
* success/failure indication). */
|
||||
/* NuttX MTD driver ioctl definitions */
|
||||
|
||||
#define _MTDIOCVALID(c) (_IOC_TYPE(c)==_MTDIOCBASE)
|
||||
|
||||
+24
-5
@@ -313,7 +313,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define SDIO_STATUS(dev) ((d)->status(dev))
|
||||
#define SDIO_STATUS(dev) ((dev)->status(dev))
|
||||
|
||||
/* MMC/SD status bits */
|
||||
|
||||
@@ -430,6 +430,23 @@
|
||||
|
||||
#define SDIO_SENDDATA(dev,data) ((dev)->senddata(dev,data))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SDIO_WAITRESPONSE
|
||||
*
|
||||
* Description:
|
||||
* Poll-wait for the response to the last command to be ready.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the MMC/SD device interface
|
||||
* cmd - The command that was sent. See 32-bit command definitions above.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK is success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define SDIO_WAITRESPONSE(dev,cmd) ((dev)->waitresponse(dev,cmd))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SDIO_RECVRx
|
||||
*
|
||||
@@ -694,10 +711,11 @@
|
||||
enum sdio_clock_e
|
||||
{
|
||||
CLOCK_SDIO_DISABLED = 0, /* Clock is disabled */
|
||||
CLOCK_MMC_SLOW, /* MMC initialization clocking */
|
||||
CLOCK_SD_SLOW, /* SD initialization clocking */
|
||||
CLOCK_MMC_FAST, /* MMC normal operation clocking */
|
||||
CLOCK_SD_FAST /* SD normal operation clocking */
|
||||
CLOCK_IDMODE, /* Initial ID mode clocking (<400KHz) */
|
||||
CLOCK_MMC_SLOW, /* MMC initialization clocking */
|
||||
CLOCK_SD_SLOW, /* SD initialization clocking */
|
||||
CLOCK_MMC_FAST, /* MMC normal operation clocking */
|
||||
CLOCK_SD_FAST /* SD normal operation clocking */
|
||||
};
|
||||
|
||||
/* This structure defines the interface between the NuttX MMC/SD
|
||||
@@ -728,6 +746,7 @@ struct sdio_dev_s
|
||||
void (*sendcmd)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg);
|
||||
int (*senddata)(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer);
|
||||
|
||||
int (*waitresponse)(FAR struct sdio_dev_s *dev, uint32 cmd);
|
||||
int (*recvR1)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R1);
|
||||
int (*recvR2)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 R2[4]);
|
||||
int (*recvR3)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R3);
|
||||
|
||||
Reference in New Issue
Block a user