Difference between revisions of "SD/MMC/SDIO Registers"
(Created page with "== DSi SD/MMC I/O Ports: Command/Param/Response/Data == '''4004800h - SD_CMD - Command and Response/Data Type (R/W)'''<br> '''4004A00h - SDIO_CMD - Command and Response/Data Typ...") |
|||
(18 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | SD_xxx is used to access onboard eMMC and external SD card slot (as selected via SD_CARD_PORT_SELECT).<br> | ||
+ | SDIO_xxx is used to access the Atheros Wifi unit. | ||
+ | |||
+ | == DSi SD/MMC I/O Map == | ||
+ | |||
+ | '''ARM7 DSi SD/MMC Registers for Memory Card access (SD Card and onboard eMMC)''' | ||
+ | 4004800h 2 SD_CMD Command and Response/Data Type | ||
+ | 4004802h 2 SD_CARD_PORT_SELECT (SD/MMC:020Fh, SDIO:010Fh) | ||
+ | 4004804h 4 SD_CMD_PARAM0-1 Argument (32bit, 2 halfwords) | ||
+ | 4004808h 2 SD_STOP_INTERNAL_ACTION | ||
+ | 400480Ah 2 SD_DATA16_BLK_COUNT "Transfer Block Count" | ||
+ | 400480Ch 16 SD_RESPONSE0-7 (128bit, 8 halfwords) | ||
+ | 400481Ch 4 SD_IRQ_STATUS0-1 ;IRQ Status (0=ack, 1=req) | ||
+ | 4004820h 4 SD_IRQ_MASK0-1 ;IRQ Disable (0=enable, 1=disable) | ||
+ | 4004824h 2 SD_CARD_CLK_CTL Card Clock Control | ||
+ | 4004826h 2 SD_DATA16_BLK_LEN Memory Card Transfer Data Length | ||
+ | 4004828h 2 SD_CARD_OPTION Memory Card Option Setup (can be C0FFh) | ||
+ | 400482Ah 2 Fixed always zero? | ||
+ | 400482Ch 4 SD_ERROR_DETAIL_STATUS0-1 Error Detail Status | ||
+ | 4004830h 2 SD_DATA16_FIFO Data Port (SD_FIFO?) | ||
+ | 4004832h 2 Fixed always zero? ;(TC6371AF:BUF1 Data MSBs?) | ||
+ | 4004834h 2 ? SD_TRANSACTION_CTL Transaction Control | ||
+ | 4004836h 2 ? SD_CARD_INTERRUPT_CONTROL ;4004A36h used in SDIO IRQ handler | ||
+ | 4004838h 2 ? SD_CLK_AND_WAIT_CTL ;4004A38h used in SDIO IRQ handler | ||
+ | 400483Ah 2 Fixed always zero? ;(SDCTL_SDIO_HOST_INFORMATION) | ||
+ | 400483Ch 2 Fixed always zero? ;(SDCTL_ERROR_CONTROL) | ||
+ | 400483Eh 2 Fixed always zero? ;(TC6387XB: LED_CONTROL) | ||
+ | 4004840h 2 Fixed always 003Fh? | ||
+ | 4004842h 2 Fixed always 002Ah? | ||
+ | 4004844h 6Eh Fixed always zerofilled? | ||
+ | 40048B2h 2 Fixed always FFFFh? | ||
+ | 40048B4h 6 Fixed always zerofilled? | ||
+ | 40048BAh 2 Fixed always 0200h? | ||
+ | 40048BCh 1Ch Fixed always zerofilled? | ||
+ | 40048D8h 2 SD_DATA_CTL | ||
+ | 40048DAh 6 Fixed always zerofilled? | ||
+ | 40048E0h 2 SD_SOFT_RESET Software Reset (bit0=SRST=0=reset) | ||
+ | 40048E2h 2 Fixed always 0009h? ;(RESERVED2/9, TC6371AF:CORE_REV) | ||
+ | 40048E4h 2 Fixed always zero? | ||
+ | 40048E6h 2 Fixed always zero? ;(RESERVED3, TC6371AF:BUF_ADR) | ||
+ | 40048E8h 2 Fixed always zero? ;(TC6371AF:Resp_Header) | ||
+ | 40048EAh 6 Fixed always zerofilled? | ||
+ | 40048F0h 2 Fixed always zero? ;(RESERVED10) | ||
+ | 40048F2h 2 ? Can be 0003h | ||
+ | 40048F4h 2 ? Can be 0770h | ||
+ | 40048F6h 2 ? Firmware tests bit0 (but, always 0?) (RESERVED4) | ||
+ | 40048F8h 2 Fixed always 0004h? (nonzero, unlike SDIO) (RESERVED5) | ||
+ | 40048FAh 2 ? Can be 0004h..0007h (nonzero, unlike SDIO) (RESERVED6) | ||
+ | 40048FCh 2 ? Can be 0024h..00FFh? (RESERVED7) | ||
+ | 40048FEh 2 ? Can be 0024h..00FFh? (RESERVED8 / TC6371AF:Revision) | ||
+ | 4004900h 2 SD_DATA32_IRQ | ||
+ | 4004902h 2 Fixed always zero? | ||
+ | 4004904h 2 SD_DATA32_BLK_LEN | ||
+ | 4004906h 2 Fixed always zero? | ||
+ | 4004908h 2 SD_DATA32_BLK_COUNT | ||
+ | 400490Ah 2 Fixed always zero? | ||
+ | 400490Ch 4 SD_DATA32_FIFO | ||
+ | 4004910h F0h Fixed always zerofilled? | ||
+ | '''ARM7 DSi SD/MMC Registers for SDIO access (for Atheros Wifi)''' | ||
+ | 4004A00h 200h SDIO_xxx (same as SD_xxx at 4004800h..40049FFh, see there) | ||
+ | 4004A02h 2 SDIO_CARD_PORT_SELECT (slightly different than 4004802h) | ||
+ | 4004AF8h 2 Fixed always zero? (unlike SD_xxx at 40048F8h) (RESERVED5) | ||
+ | 4004AFAh 2 Fixed always zero? (unlike SD_xxx at 40048FAh) (RESERVED6) | ||
+ | |||
== DSi SD/MMC I/O Ports: Command/Param/Response/Data == | == DSi SD/MMC I/O Ports: Command/Param/Response/Data == | ||
− | + | ===4004800h/4004A00h - SD_CMD - Command and Response/Data Type (R/W)=== | |
− | |||
15 undoc Unknown/undoc (read/write-able) | 15 undoc Unknown/undoc (read/write-able) | ||
− | 14 undoc Security Cmd | + | 14 undoc Security Cmd? (0=Normal, 1=Whatever/Security?) (sdio?) |
13 undoc Data Length (0=Single Block, 1=Multiple Blocks) | 13 undoc Data Length (0=Single Block, 1=Multiple Blocks) | ||
12 undoc Data Direction (0=Write, 1=Read) | 12 undoc Data Direction (0=Write, 1=Read) | ||
11 NTDT Data Transfer (0=No data, 1=With data) | 11 NTDT Data Transfer (0=No data, 1=With data) | ||
− | 10-8 REP2-0 Response Type (0..2=Unknown/Reserved, 3=None, 4=48bit, | + | 10-8 REP2-0 Response Type (0=Auto, 1..2=Unknown/Reserved, 3=None, 4=48bit, |
5=48bit+Busy, 6=136bit, 7=48bitOcrWithoutCRC7) | 5=48bit+Busy, 6=136bit, 7=48bitOcrWithoutCRC7) | ||
7-6 CMD1-0 Command Type (0=CMD, 1=ACMD, 2..3=unknown, maybe GEN WR/RD?) | 7-6 CMD1-0 Command Type (0=CMD, 1=ACMD, 2..3=unknown, maybe GEN WR/RD?) | ||
5-0 CIX Command Index (0..3Fh, command index) | 5-0 CIX Command Index (0..3Fh, command index) | ||
− | Invalid values can cause ILA error (particulary on setting NTDT for CMD12, or | + | Setting Command Type to "ACMD" is automatically sending an APP_CMD prefix prior to the command number. For Multiple Blocks, the hardware supports automatically sending STOP_TRANSMISSION after the last block.<br> |
− | for CMD's Response=None). ILA error will also occur if an old CMD is still | + | DSi software is usually setting Response Type to "Auto", which is causing the hardware to use the correct response/data type for standard SD/MMC commands (bit11-13 are ignored/should be zero when using "Auto"; and maybe same for bit14-15?).<br> |
− | busy. | + | One exception is that the DSi firmware isn't using "Auto" for SDIO commands (maybe the hardware isn't aware of them; or it's unable to distinguish between read/write direction of CMD53, which would require examining the command's PARAM bits).<br> |
− | + | There might be subtle differences between some SD and MMC commands, unknown if/how "Auto" is working in that cases; unknown if there's a SD-or-MMC mode select bit for that purpose in some configuration register.<br> | |
− | + | Invalid values can cause ILA error (particulary on setting NTDT for CMD12, or for CMD's Response=None). ILA error will also occur if an old CMD is still busy. | |
− | |||
− | |||
− | |||
− | + | ===4004804h/4004A04h - SD_CMD_PARAM0-1 - Argument (32bit, 2 halfwords) (R/W)=== | |
− | |||
− | |||
31-0 Parameter value for CMD | 31-0 Parameter value for CMD | ||
− | The parameter value should be written <before> sending the command via | + | The parameter value should be written <before> sending the command via SD_CMD/SDIO_CMD. |
− | SD_CMD/SDIO_CMD. | ||
− | + | ===400480Ch/4004A0Ch - SD_RESPONSE0-7 - Response (128bit, 8 halfwords) (R)=== | |
− | |||
− | |||
After sending a command, wait for the CMDRESPEND bit (IRQ_STATUS.bit0) to get | After sending a command, wait for the CMDRESPEND bit (IRQ_STATUS.bit0) to get | ||
set, then read the RESPONSE (if the command does have any response). | set, then read the RESPONSE (if the command does have any response). | ||
− | For normal 32bit responses: | + | For normal 32bit responses: |
31-0 Response | 31-0 Response | ||
127-32 Older Responses | 127-32 Older Responses | ||
− | For CID/CSD responses: | + | For CID/CSD responses: |
119-0 120bit Response | 119-0 120bit Response | ||
127-120 Zero (always?) | 127-120 Zero (always?) | ||
− | Seems to be left-shifted when receiving response bits. So, for 32bit responses, | + | Seems to be left-shifted when receiving response bits. So, for 32bit responses, bit0-31 would contain the current response, and bit32-127 would contain older responses. |
− | bit0-31 would contain the current response, and bit32-127 would contain older | ||
− | responses. | ||
+ | ===DATA16 vs DATA32=== | ||
+ | Data can be transferred in 16bit or 32bit units (as selected in DATA_CTL.bit1 and DATA32_IRQ.bit1). There are separate data, block len, and block count registers for 16bit and 32bit mode (that's probably due to some odd patchwork, where the manufacturer has added 32bit support to the original 16bit chip design).<br> | ||
+ | Naturally, a 32bit transfer is faster than two 16bit transfers. Nethertheless, the DSi firmware does use both 32bit and 16bit mode once and then; 32bit mode is required for NDMA transfers (which don't support 16bit). | ||
− | + | ===40048D8h/4004AD8h - SD_DATA_CTL=== | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
15-13 Unknown (usually 0) | 15-13 Unknown (usually 0) | ||
− | 12 Unknown (usually 1) | + | 12 Unknown (usually 1) (R?) |
11-6 Unknown (usually 0) | 11-6 Unknown (usually 0) | ||
− | 5 Unknown ( | + | 5 Unknown (read/write-able) (usually 0) (R/W) |
− | 4 Unknown (usually 1) | + | 4 Unknown (usually 1) (R?) |
3-2 Unknown (usually 0) | 3-2 Unknown (usually 0) | ||
− | 1 Select 16bit/32bit Data Mode (0=DATA16, 1=DATA32) | + | 1 Select 16bit/32bit Data Mode (0=DATA16, 1=DATA32, see 4004900h) (R/W) |
0 Unknown (usually 0) | 0 Unknown (usually 0) | ||
− | Known written values are 0000h and 0002h. However, known read values are 1010h | + | Known written values are 0000h and 0002h. However, known read values are 1010h and 1012h.<br> |
− | and 1012h. | + | DATA32 mode requires setting both 40048D8h.bit1 and 4004900h.bit1. For DATA16 mode, both bits should be zero (though DATA16 seems to be also working the same way when only either of the bits is zero). |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | ===400480Ah/4004A0Ah - SD_DATA16_BLK_COUNT - "Transfer Block Count" (R/W)=== | ||
+ | ===4004908h/4004B08h - SD_DATA32_BLK_COUNT (R/W)=== | ||
+ | 15-0 Number of Data Blocks for multiple read/write commands (0..FFFFh) | ||
+ | In Data32 mode, DATA32_BLK_COUNT is decremented after each block (except after the last block, where it stays at 0001h instead of getting zero). In Data16 mode, SD_DATA16_BLK_COUNT doesn't decrease (instead, there must be some hidden internal counter register).<br> | ||
+ | If enabled in STOP_INTERNAL_ACTION.bit8, then the hardware will be automatically sending STOP_TRANSMISSION (CMD12) after the last block (otherwise the decrement occurs as described above, but the hardware keeps transferring blocks infinitely). | ||
− | + | ===4004826h/4004A26h - SD_DATA16_BLK_LEN - Transfer Data Length (R/W)=== | |
− | + | ===4004904h/4004B04h - SD_DATA32_BLK_LEN (R/W)=== | |
− | |||
− | |||
15-10 Unknown/unused (appears to be always zero) | 15-10 Unknown/unused (appears to be always zero) | ||
9-0 Data Block Length in bytes (for DATA16: clipped to max 0200h by hw) | 9-0 Data Block Length in bytes (for DATA16: clipped to max 0200h by hw) | ||
− | Should be usually 0200h (for 512-byte SD/MMC memory blocks). Other values may | + | Should be usually 0200h (for 512-byte SD/MMC memory blocks). Other values may be needed for SDIO functions, or when accessing SSR/SCR/PWD registers via data transfers.<br> |
− | be needed for SDIO functions, or when accessing SSR/SCR/PWD registers via data | ||
− | transfers. | ||
DATA32_BLK_LEN can be max 3FFh (unlike DATA16_BLK_LEN which is clipped to | DATA32_BLK_LEN can be max 3FFh (unlike DATA16_BLK_LEN which is clipped to | ||
max=200h by hardware). | max=200h by hardware). | ||
− | + | ===4004830h/4004A30h - SD_DATA16_FIFO - Data Port (SD_FIFO?)=== | |
− | + | ===400490Ch/4004B0Ch - SD_DATA32_FIFO=== | |
− | + | For Data16: | |
− | |||
− | |||
− | For Data16: | ||
15-0 Data (16bit) (...or could it be accessed as 32bit, too?) | 15-0 Data (16bit) (...or could it be accessed as 32bit, too?) | ||
− | For Data32: | + | For Data32: |
31-0 Data (32bit) (...or could it be accessed as 16bit, too?) | 31-0 Data (32bit) (...or could it be accessed as 16bit, too?) | ||
Transfer data here (read after RXRDY gets set, or write after TXRQ gets set). | Transfer data here (read after RXRDY gets set, or write after TXRQ gets set). | ||
FIFO size is unknown (if there's any FIFO behind it). | FIFO size is unknown (if there's any FIFO behind it). | ||
− | |||
== DSi SD/MMC I/O Ports: Interrupt/Status == | == DSi SD/MMC I/O Ports: Interrupt/Status == | ||
− | + | ===400481Ch/4004A1Ch - SD_IRQ_STATUS0-1 - Interrupt Status (R/ack)=== | |
− | + | ===4004820h/4004A20h - SD_IRQ_MASK0-1 - Interrupt Mask (R/W)=== | |
− | + | The IRQ_STATUS registers contain acknowledge-able IRQ Flags (those bits that that are maskable in IRQ_MASK register), as well as static read-only status bits without IRQ function (eg. WRPROTECT). | |
− | + | *IRQ Flags/Write (0=Acknowledge, 1=No change) | |
− | IRQ | + | *IRQ Flags/Read (0=No IRQ, 1=IRQ) |
− | IRQ Mask (0=Enable, 1=Disable) | + | *IRQ Mask (0=Enable, 1=Disable) (8B7F031Dh when all IRQs disabled) |
− | Bit Stat Mask | + | Bit Stat Mask Function |
− | 0 SREP MREP | + | 0 SREP MREP CMDRESPEND (response end) (or R1b: busy end) |
− | 1 | + | 1 0 0 Unknown/unused (always 0) |
− | 2 SRWA MRWA | + | 2 SRWA MRWA DATAEND (set after (last) data block end) |
− | 3 SCOT MCOT | + | 3 SCOT MCOT CARD_REMOVE (0=No event, 1=Is/was newly ejected) ;\ |
− | 4 SCIN MCIN | + | 4 SCIN MCIN CARD_INSERT (0=No event, 1=Is/was newly inserted) ; SD |
− | 5 undoc | + | 5 undoc 0 SIGSTATE (0=Ejected, 1=Inserted) (SDIO: always 1) ; Slot |
− | 6 | + | 6 0 0 Unknown/unused (always 0) ; Sw's |
− | 7 undoc | + | 7 undoc 0 WRPROTECT (0=Locked/Ejected, 1=Unlocked/HalfEjected);/ |
− | 8 undoc undoc | + | 8 undoc undoc CARD_REMOVE_A (0=No event, 1=High-to-Low occurred) ;\SD |
− | 9 undoc undoc | + | 9 undoc undoc CARD_INSERT_A (0=No event, 1=Low-to-High óccurred) ; Slot |
− | 10 undoc | + | 10 undoc 0 SIGSTATE_A (usually 1=High) ;also as so for SDIO ;/Data3 |
− | 11 | + | 11 0 0 Unknown/unused (always 0) |
− | 12 | + | 12 0 0 Unknown/unused (always 0) |
− | 13 | + | 13 0 0 Unknown/unused (always 0) |
− | 14 | + | 14 0 0 Unknown/unused (always 0) |
− | 15 | + | 15 0 0 Unknown/unused (always 0) |
− | 16 SCIX MCIX | + | 16 SCIX MCIX CMD_IDX_ERR Bad CMD-index in response (RCMDE,SCMDE) |
− | 17 SCRC MCRC | + | 17 SCRC MCRC CRCFAIL CRC response error (WCRCE,RCRCE,SCRCE,CCRCE) |
− | 18 SEND MEND | + | 18 SEND MEND STOPBIT_ERR End bit error (WEBER,REBER,SEBER,CEBER) |
− | 19 SDTO MDTO | + | 19 SDTO MDTO DATATIMEOUT Data Timeout (NRCS,NWCS,KBSY) |
− | 20 SFOF MFOF | + | 20 SFOF MFOF RXOVERFLOW HOST tried write full |
− | 21 SFUF MFUF | + | 21 SFUF MFUF TXUNDERRUN HOST tried read empty |
− | 22 SCTO MCTO | + | 22 SCTO MCTO CMDTIMEOUT Response start-bit timeout (NRS,NSR) |
− | 23 ? | + | 23 ??? 0 Unknown/undoc (usually set) (zero after sending TX data?) |
− | 24 SBRE MBRE | + | 24 SBRE MBRE RXRDY (fifo not empty) (request data read) |
− | 25 SBWE MBWE | + | 25 SBWE MBWE TXRQ (datafifoempty?) (request data write) |
− | 26 | + | 26 0 0 Unknown/unused (always 0) |
− | 27 undoc undoc | + | 27 undoc undoc Unknown/undoc (bit27 is mask-able in IRQ_MASK) |
− | 28 | + | 28 0 0 Unknown/unused (always 0) |
− | 29 undoc | + | 29 undoc 0 CMD_READY? (inverse of BUSY?) (unlike toshiba ILFSL/IFSMSK) |
− | + | 30 undoc 0 CMD_BUSY | |
− | 30 undoc | + | 31 ILA IMSK Illegal Command Access (old CMD still busy, or wrong NTDT) |
− | 31 ILA IMSK | + | Normally, IRQs should be acknowledged by writing "FLAGS=NOT X", whilst the firmware is using an unstable "FLAGS=FLAGS AND NOT X" read-modify-write function (accidentally acknowledging any IRQs that have newly occurred during that operation). |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ===4004900h/4004B00h - SD_DATA32_IRQ=== | |
− | |||
− | |||
15-13 Unknown/unused (appears to be always zero) | 15-13 Unknown/unused (appears to be always zero) | ||
− | 12 | + | 12 DATA32_BUSY IRQ Enable (0=Disable, 1=Enable) (R/W) |
− | 11 | + | 11 DATA32_RXRDY IRQ Enable (0=Disable, 1=Enable) (R/W) |
− | 10 | + | 10 DATA32 Abort/Flush FIFO? (0=No change, 1=Clear Bit8,9) (W) |
− | 9 | + | 9 DATA32_BUSY IRQ Flag (auto cleared after...) (R) |
− | 8 | + | 8 DATA32_RXRDY IRQ Flag (auto cleared after...) (R) |
− | 7-2 Unknown ( | + | 7-2 Unknown/unused (appears to be always zero) |
− | 1 | + | 1 Select 16bit/32bit Data Mode (0=DATA16, 1=DATA32, see 40048D8h) (R/W) |
− | 0 Unknown ( | + | 0 Unknown/unused (appears to be always zero) |
− | Can be 1A02h, but changes to 1802h after reading from somewhere (maybe from | + | Can be 1A02h, but changes to 1802h after reading from somewhere (maybe from DATA32_FIFO?).<br> |
− | DATA32_FIFO?).<br> | + | Bit8,9 are extra IRQ flags, the flags get set ONLY in DATA32 mode (not in DATA16 mode). |
− | Bit8,9 | ||
− | mode (not in DATA16 mode). | ||
− | + | ===400482Ch/4004A2Ch - SD_ERROR_DETAIL_STATUS0-1 - Error Detail Status=== | |
− | + | This register contains extra info about the error bits in SD_IRQ_STATUS. The error bits (except bit13/always set) are automatically cleared when sending a new command by writing to SD_CMD. | |
− | + | 31-23 0 Unknown/unused (always zero) | |
− | 31-23 | + | 22 KBSY Timeout for CRC status busy ;\STAT.19 |
− | 22 KBSY Timeout for CRC status busy | + | 21 NWCS Timeout for CRC status (can occur for Data Write) ; (SDTO) |
− | 21 NWCS Timeout for CRC status | ||
20 NRCS Timeout for Data start-bit, or for Post Data Busy ;/ | 20 NRCS Timeout for Data start-bit, or for Post Data Busy ;/ | ||
− | 19-18 | + | 19-18 0 Unknown/unused (always zero) |
− | 17 NRS Response | + | 17 NRS Response Timeout for auto-issued CMD12 ;\STAT.22 |
− | 16 NCR Response | + | 16 NCR Response Timeout for non-auto-issued CMD's ;/(SCTO) |
− | 15-14 | + | 15-14 0 Unknown/unused (always zero) |
− | 13 | + | 13 undoc Unknown/undoc (always 1) ;-Always 1 |
− | 12 | + | 12 0 Unknown/unused (always zero) |
11 WCRCE CRC error for Write CRC status for a write command ;\ | 11 WCRCE CRC error for Write CRC status for a write command ;\ | ||
− | 10 RCRCE CRC error for | + | 10 RCRCE CRC error for Read Data ; STAT.17 |
− | 9 SCRCE CRC error for a | + | 9 SCRCE CRC error for a Response for auto-issued CMD12 ; (SCRC) |
− | 8 CCRCE CRC error for a | + | 8 CCRCE CRC error for a Response for non-auto-issued CMD's ;/ |
5 WEBER End bit error for Write CRC status ;\ | 5 WEBER End bit error for Write CRC status ;\ | ||
− | 4 REBER End bit error for | + | 4 REBER End bit error for Read Data ; STAT.18 |
− | 3 SEBER End bit error for | + | 3 SEBER End bit error for Response for auto-issued CMD12 ; (SEND) |
− | 2 CEBER End bit error for | + | 2 CEBER End bit error for Response for non-auto-issued CMD's ;/ |
− | 1? SCMDE Bad CMD-index in | + | 1? SCMDE Bad CMD-index in Response of auto-issued CMD12 ;\STAT.16 |
− | 0 RCMDE Bad CMD-index in | + | 0 RCMDE Bad CMD-index in Response of non-auto-issued CMD's ;/(SCIX) |
− | + | Note: CMD12 is STOP_TRANSMISSION (automatically sent after BLK_COUNT blocks).<br> | |
− | Note: CMD12 is STOP_TRANSMISSION ( | + | The four "auto-issued CMD12" bits exist for SD registers only (not for SDIO, going by old toshiba datasheets; which may be wrong). |
− | The four "auto-issued CMD12" bits exist for SD registers only (not SDIO). | + | SCMDE is probably in bit1 (though, official specs say bit0, which would be same as RCMDE).<br> |
− | SCMDE is probably in bit1 (though, official specs say bit0, which would be same | + | Some error bits can be intentionally provoked: Bit8=1 when programming the controller to expect GET_STATUS to return a 136bit response. Bit16=1 when sending GET_CID in "tran" state. Bit20=1 when sending GET_STATUS configured to expect a data/read reply. Bit21=1 when sending GET_STATUS configured to expect a data/write block (and with actually sending a data block to it). |
− | as | + | |
+ | == DSi SD/MMC I/O Ports: Control Registers == | ||
+ | |||
+ | ===4004802h/4004A02h - SD_CARD_PORT_SELECT=== | ||
+ | 15-11 Unknown/unused (appears to be always zero) | ||
+ | 10 Unknown (should be set on writing) (reads as zero) (W) | ||
+ | 9-8 Unknown (Always 2 for SD/4004802h, always 1 for SDIO/4004A02h) (R) | ||
+ | 7-4 Unknown/unused (appears to be always zero) | ||
+ | 3-1 Unknown (R/W) | ||
+ | 0 Port Select (0=SD Card Slot, 1=Onboard eMMC) (for SDIO: Unknown)(R/W) | ||
+ | |||
+ | ===4004828h/4004A28h - SD_CARD_OPTION - Card Option Setup=== | ||
+ | 15 undoc Bus Width (0=4bit, 1=1bit) (R/W) | ||
+ | 14 undoc Unknown (usually set) (R?) | ||
+ | 13-9 0 Unknown/unused (appears to be always zero) | ||
+ | 8 undoc Unknown (firmware tries to toggle this after CLK change?) (W?) | ||
+ | 7-4 RTO Data start/busy timout (2000h SHL 0..14, or 15=100h SDCLK's) (R/W) | ||
+ | 0-3 TO? Unknown (another timeout, maybe for SDIO? in 32KHz units?) (R/W) | ||
+ | Among others, this register should contain a 4bit timeout setting, "RTO[3:0] | ||
+ | for SD (aka TO[3:0] for SDIO) timeout period for data start/busy bits, in the | ||
+ | form of a multiple number of the SDCLK period." Unknown which "multiple | ||
+ | numbers" that's referring to (probably some exponential/table values). | ||
+ | Settings spotted on DSi are 40E0h,40EEh. | ||
+ | |||
+ | ===4004824h/4004A24h - SD_CARD_CLK_CTL Card Clock Control=== | ||
+ | 15-11 Unknown (always 0) ;unlike Toshiba: no HCLK divider-disable in bit15) | ||
+ | 10 Unknown (0=Normal, 1=Unknown, doesn't affect SDCLK output?) (R/W) | ||
+ | 9 Unknown (0=Normal, 1=Unknown, freezes SDCLK output?) (R/W) | ||
+ | 8 SDCLK Enable (0=Force SDCLK=LOW, 1=Output SDCLK=HCLK/n) (R/W) | ||
+ | 7-0 HCLK Div (0,1,2,4,8,16,32,64,128 = Div2,4,8,16,32,64,128,256,512) (R/W) | ||
+ | The DSi uses HCLK=33.513982 MHz, the SDCLK pin can range from HCLK/512=65kHz to HCLK/2=16.757MHz, max transfer rate would be thus 8MByte/s in 4bit mode.<br> | ||
+ | Card detection should be done at a low clock rate. For SD/MMC, the DSi starts with HCLK/128, and uses the clock specified in CSD register after detection (when extracting bits from CSD: mind the different 120bit-without-CRC vs 128bit-with-CRC notations). For SDIO, the DSi starts with HCLK/256, and switches to HCLK/2 after reading SDIO Bus Speed register (Function0:00013h).<br> | ||
+ | The SDCLK pins are permanently pulsed, even for devices deselected via SD_CARD_PORT_SELECT.0, and even if no CMD or DATA is being transferred. However, the DSi firmware is usually stopping SDCLK via Bit8=0 when not accessing SD/MMC (doing so may reduce noise and power consumption).<br> | ||
+ | Trying to set bit9, or to set more than one bit in bit7-0 will freeze the SDCLK output (in this case SDCLK may get stuck HIGH or LOW, unlike Bit8=0 which forces LOW). | ||
+ | |||
+ | ===4004808h/4004A08h - SD_STOP_INTERNAL_ACTION=== | ||
+ | 15-9 Unknown/unused (appears to be always zero) | ||
+ | 8 Auto-Stop (1=Automatically send CMD12 after BLK_COUNT blocks) (R/W) | ||
+ | 7-1 Unknown/unused (appears to be always zero) | ||
+ | 0 Unknown (R/W) | ||
+ | Stop whatever internal action for whatever purpose in whatever situation?<br> | ||
+ | Existing code does set bit8 (prior to changing SD_DATA16_BLK_COUNT).<br> | ||
+ | Existing code does clear bit0 (alongsides with IRQ enable/acknowlege or so).<br> | ||
+ | ===40048E0h/4004AE0h - SD_SOFT_RESET - Software Reset=== | ||
+ | 15-3 Unknown/unused (appears to be always zero) | ||
+ | 2 Unknown (always 1) (R?) | ||
+ | 1 Unknown (always 1) (though firmware tries to toggle this bit) (R?) | ||
+ | 0 SRST Soft Reset (0=Reset, 1=Release) (R/W) | ||
+ | Software should apply reset after sensing card insertion/removal, and (thereafter) release reset in case of card insertion. Software reset does acknowledge all IRQs (except that from SDIO /IRQ pin?), and does probably also reinitialize some other registers.<br> | ||
+ | Clearing bit0 does force following settings (while and as long as Bit0=0): | ||
+ | SD_STOP_INTERNAL_ACTION = 0000h | ||
+ | SD_RESPONSE0-7 = zerofilled | ||
+ | SD_IRQ_STATUS0-1 = all IRQs flags acknowledged | ||
+ | SD_ERROR_DETAIL_STATUS0-1 = all bits cleared (except bit13/always set) | ||
+ | SD_CARD_CLK_CTL = bit 8 and 10 cleared | ||
+ | SD_CARD_OPTION = 40EEh | ||
+ | SD_CARD_INTERRUPT_CONTROL = 0000h | ||
+ | All other registers seem to be left unaffected (including the the extra IRQ flags in 4004900h); though there may be some further hidden effects (like aborting transfers or resetting internal registers).<br> | ||
+ | Note: The DSi firmware does issue reset by toggling both bit0 and bit1, although bit1 does seem to be read-only (always 1), and trying to clear that bit doesn't seem to have any effect at all. | ||
− | + | == DSi SD/MMC I/O Ports: Unknown/Unused Registers == | |
− | + | ||
− | + | ===40048F6h/4004AF6h - Firmware tests bit0 (but, always 0?) (RESERVED4)=== | |
+ | 15-1 Unknown (0) | ||
+ | 0 Unknown (tested by firmware) (usually 0) (R) | ||
+ | |||
+ | ===4004836h/4004A36h - SD_CARD_INTERRUPT_CONTROL ---- USED by SDIO=== | ||
+ | 4004A36h is used in SDIO IRQ handler.<br> | ||
+ | On DSi, this register looks as so: | ||
+ | 15-2 Unknown (0) | ||
+ | 1 Unknown (gets set automatically after 2 seconds?) (and also R/W ?) | ||
+ | 0 Unknown (usually always 0) (tested by firmware?) (R?) | ||
+ | Whilst old toshiba datasheets specify it as so: | ||
15-13 ? Unknown (zero on DSi) | 15-13 ? Unknown (zero on DSi) | ||
− | 12 CINT0 SDIO Interrupt Flag (0=none, 1=irq) | + | 12 CINT0 SDIO Interrupt Flag (0=none/ack, 1=irq) (/IRQ aka Data1 pin) |
11-9 ? Unknown (zero on DSi) | 11-9 ? Unknown (zero on DSi) | ||
8 CIMSK0 SDIO Interrupt Mask (0=enable, 1=disable) (/IRQ aka Data1 pin) | 8 CIMSK0 SDIO Interrupt Mask (0=enable, 1=disable) (/IRQ aka Data1 pin) | ||
7-0 ? Unknown (zero on DSi) | 7-0 ? Unknown (zero on DSi) | ||
− | Acknowledge by writing CINT0=0, or CIMSK0=1, or hard reset (unlike as for other | + | Acknowledge by writing CINT0=0, or CIMSK0=1 (uh, really?), or hard reset (unlike as for other SD/MMC interrupts, soft reset does not acknowlege this interrupt type?). |
− | SD/MMC interrupts, soft reset does not acknowlege this interrupt type?). | + | |
+ | ===4004838h/4004A38h - SDCTL_CLK_AND_WAIT_CTL ---- USED by SDIO=== | ||
+ | 4004A38h is used in SDIO IRQ handler.<br> | ||
+ | On DSi, this register looks as so (usually zero): | ||
+ | 15-14 Unknown (usually 0) (R/W) | ||
+ | 13-3 Unknown (0) | ||
+ | 2-0 Unknown (usually 0) (R/W) | ||
+ | Whilst old toshiba datasheets specify it as so: | ||
+ | 15-0 Unknown (bit8 should be set after SD_CARD_CLK_CTL change?) | ||
+ | |||
+ | Below registers don't seem to be used by existing software... | ||
+ | |||
+ | ===4004834h/4004A34h - SD_TRANSACTION_CTL - Transaction Control=== | ||
+ | 15-10 Unknown/unused (appears to be always zero) | ||
+ | 9-8 Unknown (R/W) | ||
+ | 7-3 Unknown/unused (appears to be always zero) | ||
+ | 2 Unknown (R/W) | ||
+ | 1 Unknown/unused (appears to be always zero) | ||
+ | 0 Unknown (R/W) | ||
+ | |||
+ | ===40048F2h/4004AF2h - Can be 0003h=== | ||
+ | 15-2 Unknown (0) | ||
+ | 1-0 Unknown (0..3) (R/W) | ||
+ | |||
+ | ===40048F4h/4004AF4h - Can be 0770h=== | ||
+ | 15-11 Unknown (0) | ||
+ | 10-8 Unknown (0..7) (R/W) | ||
+ | 7 Unknown (0) | ||
+ | 6-4 Unknown (0..7) (R/W) | ||
+ | 3-0 Unknown (0) | ||
+ | |||
+ | ===40048FAh - Can be 0007h (nonzero, unlike SDIO) (RESERVED6)=== | ||
+ | 15-3 Unknown (0) | ||
+ | 2 Unknown (1=normal, 0=data/read from card to fifo busy?) (R) | ||
+ | 1-0 Unknown (0..3) (R/W? or rather R?) | ||
+ | |||
+ | ===40048FCh/4004AFCh - Can be 0024h..00FFh? (RESERVED7)=== | ||
+ | ===40048FEh/4004AFEh - Can be 0024h..00FFh? (RESERVED8 / TC6371AF:Revision)=== | ||
+ | 15-8 Unknown (0) | ||
+ | 7-0 Can be 24h..FFh parts (R) and parts (R/W)? | ||
+ | |||
+ | ===Unused Registers with Fixed value (all bits read-only, or write-only)=== | ||
+ | 400482Ah/4004A2Ah 2 Fixed always zero? | ||
+ | 4004832h/4004A32h 2 Fixed always zero? ;(TC6371AF:BUF1 Data MSBs?) | ||
+ | 400483Ah/4004A3Ah 2 Fixed always zero? ;(SDCTL_SDIO_HOST_INFORMATION) | ||
+ | 400483Ch/4004A3Ch 2 Fixed always zero? ;(SDCTL_ERROR_CONTROL) | ||
+ | 400483Eh/4004A3Eh 2 Fixed always zero? ;(TC6387XB: LED_CONTROL) | ||
+ | 4004840h/4004A40h 2 Fixed always 003Fh? | ||
+ | 4004842h/4004A42h 2 Fixed always 002Ah? | ||
+ | 4004844h/4004A44h 6Eh Fixed always zerofilled? | ||
+ | 40048B2h/4004AB2h 2 Fixed always FFFFh? | ||
+ | 40048B4h/4004AB4h 6 Fixed always zerofilled? | ||
+ | 40048BAh/4004ABAh 2 Fixed always 0200h? | ||
+ | 40048BCh/4004ABCh 1Ch Fixed always zerofilled? | ||
+ | 40048DAh/4004ADAh 6 Fixed always zerofilled? | ||
+ | 40048E2h/4004AE2h 2 Fixed always 0009h? ;(RESERVED2/9, TC6371AF:CORE_REV) | ||
+ | 40048E4h/4004AE4h 2 Fixed always zero? | ||
+ | 40048E6h/4004AE6h 2 Fixed always zero? ;(RESERVED3, TC6371AF:BUF_ADR) | ||
+ | 40048E8h/4004AE8h 2 Fixed always zero? ;(TC6371AF:Resp_Header) | ||
+ | 40048EAh/4004AEAh 6 Fixed always zerofilled? | ||
+ | 40048F0h/4004AF0h 2 Fixed always zero? ;(RESERVED10) | ||
+ | 40048F8h 2 Fixed always 0004h? (unlike SDIO) (RESERVED5) | ||
+ | 4004AF8h 2 Fixed always zero? (unlike SD) (RESERVED5) | ||
+ | 4004AFAh 2 Fixed always zero? (unlike SD) (RESERVED6) | ||
+ | 4004902h/4004B02h 2 Fixed always zero? | ||
+ | 4004906h/4004B06h 2 Fixed always zero? | ||
+ | 400490Ah/4004B0Ah 2 Fixed always zero? | ||
+ | 4004910h/4004B10h F0h Fixed always zerofilled? | ||
+ | |||
+ | == Links == | ||
+ | * [http://gbatemp.net/threads/dsi-reverse-engineering-sd-mmc-sdio-registers.395787/ DSi SD/MMC reverse engineering thread in gbatemp forum] |
Latest revision as of 13:29, 2 September 2015
SD_xxx is used to access onboard eMMC and external SD card slot (as selected via SD_CARD_PORT_SELECT).
SDIO_xxx is used to access the Atheros Wifi unit.
DSi SD/MMC I/O Map
ARM7 DSi SD/MMC Registers for Memory Card access (SD Card and onboard eMMC) 4004800h 2 SD_CMD Command and Response/Data Type 4004802h 2 SD_CARD_PORT_SELECT (SD/MMC:020Fh, SDIO:010Fh) 4004804h 4 SD_CMD_PARAM0-1 Argument (32bit, 2 halfwords) 4004808h 2 SD_STOP_INTERNAL_ACTION 400480Ah 2 SD_DATA16_BLK_COUNT "Transfer Block Count" 400480Ch 16 SD_RESPONSE0-7 (128bit, 8 halfwords) 400481Ch 4 SD_IRQ_STATUS0-1 ;IRQ Status (0=ack, 1=req) 4004820h 4 SD_IRQ_MASK0-1 ;IRQ Disable (0=enable, 1=disable) 4004824h 2 SD_CARD_CLK_CTL Card Clock Control 4004826h 2 SD_DATA16_BLK_LEN Memory Card Transfer Data Length 4004828h 2 SD_CARD_OPTION Memory Card Option Setup (can be C0FFh) 400482Ah 2 Fixed always zero? 400482Ch 4 SD_ERROR_DETAIL_STATUS0-1 Error Detail Status 4004830h 2 SD_DATA16_FIFO Data Port (SD_FIFO?) 4004832h 2 Fixed always zero? ;(TC6371AF:BUF1 Data MSBs?) 4004834h 2 ? SD_TRANSACTION_CTL Transaction Control 4004836h 2 ? SD_CARD_INTERRUPT_CONTROL ;4004A36h used in SDIO IRQ handler 4004838h 2 ? SD_CLK_AND_WAIT_CTL ;4004A38h used in SDIO IRQ handler 400483Ah 2 Fixed always zero? ;(SDCTL_SDIO_HOST_INFORMATION) 400483Ch 2 Fixed always zero? ;(SDCTL_ERROR_CONTROL) 400483Eh 2 Fixed always zero? ;(TC6387XB: LED_CONTROL) 4004840h 2 Fixed always 003Fh? 4004842h 2 Fixed always 002Ah? 4004844h 6Eh Fixed always zerofilled? 40048B2h 2 Fixed always FFFFh? 40048B4h 6 Fixed always zerofilled? 40048BAh 2 Fixed always 0200h? 40048BCh 1Ch Fixed always zerofilled? 40048D8h 2 SD_DATA_CTL 40048DAh 6 Fixed always zerofilled? 40048E0h 2 SD_SOFT_RESET Software Reset (bit0=SRST=0=reset) 40048E2h 2 Fixed always 0009h? ;(RESERVED2/9, TC6371AF:CORE_REV) 40048E4h 2 Fixed always zero? 40048E6h 2 Fixed always zero? ;(RESERVED3, TC6371AF:BUF_ADR) 40048E8h 2 Fixed always zero? ;(TC6371AF:Resp_Header) 40048EAh 6 Fixed always zerofilled? 40048F0h 2 Fixed always zero? ;(RESERVED10) 40048F2h 2 ? Can be 0003h 40048F4h 2 ? Can be 0770h 40048F6h 2 ? Firmware tests bit0 (but, always 0?) (RESERVED4) 40048F8h 2 Fixed always 0004h? (nonzero, unlike SDIO) (RESERVED5) 40048FAh 2 ? Can be 0004h..0007h (nonzero, unlike SDIO) (RESERVED6) 40048FCh 2 ? Can be 0024h..00FFh? (RESERVED7) 40048FEh 2 ? Can be 0024h..00FFh? (RESERVED8 / TC6371AF:Revision) 4004900h 2 SD_DATA32_IRQ 4004902h 2 Fixed always zero? 4004904h 2 SD_DATA32_BLK_LEN 4004906h 2 Fixed always zero? 4004908h 2 SD_DATA32_BLK_COUNT 400490Ah 2 Fixed always zero? 400490Ch 4 SD_DATA32_FIFO 4004910h F0h Fixed always zerofilled? ARM7 DSi SD/MMC Registers for SDIO access (for Atheros Wifi) 4004A00h 200h SDIO_xxx (same as SD_xxx at 4004800h..40049FFh, see there) 4004A02h 2 SDIO_CARD_PORT_SELECT (slightly different than 4004802h) 4004AF8h 2 Fixed always zero? (unlike SD_xxx at 40048F8h) (RESERVED5) 4004AFAh 2 Fixed always zero? (unlike SD_xxx at 40048FAh) (RESERVED6)
DSi SD/MMC I/O Ports: Command/Param/Response/Data
4004800h/4004A00h - SD_CMD - Command and Response/Data Type (R/W)
15 undoc Unknown/undoc (read/write-able) 14 undoc Security Cmd? (0=Normal, 1=Whatever/Security?) (sdio?) 13 undoc Data Length (0=Single Block, 1=Multiple Blocks) 12 undoc Data Direction (0=Write, 1=Read) 11 NTDT Data Transfer (0=No data, 1=With data) 10-8 REP2-0 Response Type (0=Auto, 1..2=Unknown/Reserved, 3=None, 4=48bit, 5=48bit+Busy, 6=136bit, 7=48bitOcrWithoutCRC7) 7-6 CMD1-0 Command Type (0=CMD, 1=ACMD, 2..3=unknown, maybe GEN WR/RD?) 5-0 CIX Command Index (0..3Fh, command index)
Setting Command Type to "ACMD" is automatically sending an APP_CMD prefix prior to the command number. For Multiple Blocks, the hardware supports automatically sending STOP_TRANSMISSION after the last block.
DSi software is usually setting Response Type to "Auto", which is causing the hardware to use the correct response/data type for standard SD/MMC commands (bit11-13 are ignored/should be zero when using "Auto"; and maybe same for bit14-15?).
One exception is that the DSi firmware isn't using "Auto" for SDIO commands (maybe the hardware isn't aware of them; or it's unable to distinguish between read/write direction of CMD53, which would require examining the command's PARAM bits).
There might be subtle differences between some SD and MMC commands, unknown if/how "Auto" is working in that cases; unknown if there's a SD-or-MMC mode select bit for that purpose in some configuration register.
Invalid values can cause ILA error (particulary on setting NTDT for CMD12, or for CMD's Response=None). ILA error will also occur if an old CMD is still busy.
4004804h/4004A04h - SD_CMD_PARAM0-1 - Argument (32bit, 2 halfwords) (R/W)
31-0 Parameter value for CMD
The parameter value should be written <before> sending the command via SD_CMD/SDIO_CMD.
400480Ch/4004A0Ch - SD_RESPONSE0-7 - Response (128bit, 8 halfwords) (R)
After sending a command, wait for the CMDRESPEND bit (IRQ_STATUS.bit0) to get set, then read the RESPONSE (if the command does have any response).
For normal 32bit responses: 31-0 Response 127-32 Older Responses For CID/CSD responses: 119-0 120bit Response 127-120 Zero (always?)
Seems to be left-shifted when receiving response bits. So, for 32bit responses, bit0-31 would contain the current response, and bit32-127 would contain older responses.
DATA16 vs DATA32
Data can be transferred in 16bit or 32bit units (as selected in DATA_CTL.bit1 and DATA32_IRQ.bit1). There are separate data, block len, and block count registers for 16bit and 32bit mode (that's probably due to some odd patchwork, where the manufacturer has added 32bit support to the original 16bit chip design).
Naturally, a 32bit transfer is faster than two 16bit transfers. Nethertheless, the DSi firmware does use both 32bit and 16bit mode once and then; 32bit mode is required for NDMA transfers (which don't support 16bit).
40048D8h/4004AD8h - SD_DATA_CTL
15-13 Unknown (usually 0) 12 Unknown (usually 1) (R?) 11-6 Unknown (usually 0) 5 Unknown (read/write-able) (usually 0) (R/W) 4 Unknown (usually 1) (R?) 3-2 Unknown (usually 0) 1 Select 16bit/32bit Data Mode (0=DATA16, 1=DATA32, see 4004900h) (R/W) 0 Unknown (usually 0)
Known written values are 0000h and 0002h. However, known read values are 1010h and 1012h.
DATA32 mode requires setting both 40048D8h.bit1 and 4004900h.bit1. For DATA16 mode, both bits should be zero (though DATA16 seems to be also working the same way when only either of the bits is zero).
400480Ah/4004A0Ah - SD_DATA16_BLK_COUNT - "Transfer Block Count" (R/W)
4004908h/4004B08h - SD_DATA32_BLK_COUNT (R/W)
15-0 Number of Data Blocks for multiple read/write commands (0..FFFFh)
In Data32 mode, DATA32_BLK_COUNT is decremented after each block (except after the last block, where it stays at 0001h instead of getting zero). In Data16 mode, SD_DATA16_BLK_COUNT doesn't decrease (instead, there must be some hidden internal counter register).
If enabled in STOP_INTERNAL_ACTION.bit8, then the hardware will be automatically sending STOP_TRANSMISSION (CMD12) after the last block (otherwise the decrement occurs as described above, but the hardware keeps transferring blocks infinitely).
4004826h/4004A26h - SD_DATA16_BLK_LEN - Transfer Data Length (R/W)
4004904h/4004B04h - SD_DATA32_BLK_LEN (R/W)
15-10 Unknown/unused (appears to be always zero) 9-0 Data Block Length in bytes (for DATA16: clipped to max 0200h by hw)
Should be usually 0200h (for 512-byte SD/MMC memory blocks). Other values may be needed for SDIO functions, or when accessing SSR/SCR/PWD registers via data transfers.
DATA32_BLK_LEN can be max 3FFh (unlike DATA16_BLK_LEN which is clipped to
max=200h by hardware).
4004830h/4004A30h - SD_DATA16_FIFO - Data Port (SD_FIFO?)
400490Ch/4004B0Ch - SD_DATA32_FIFO
For Data16: 15-0 Data (16bit) (...or could it be accessed as 32bit, too?) For Data32: 31-0 Data (32bit) (...or could it be accessed as 16bit, too?)
Transfer data here (read after RXRDY gets set, or write after TXRQ gets set). FIFO size is unknown (if there's any FIFO behind it).
DSi SD/MMC I/O Ports: Interrupt/Status
400481Ch/4004A1Ch - SD_IRQ_STATUS0-1 - Interrupt Status (R/ack)
4004820h/4004A20h - SD_IRQ_MASK0-1 - Interrupt Mask (R/W)
The IRQ_STATUS registers contain acknowledge-able IRQ Flags (those bits that that are maskable in IRQ_MASK register), as well as static read-only status bits without IRQ function (eg. WRPROTECT).
- IRQ Flags/Write (0=Acknowledge, 1=No change)
- IRQ Flags/Read (0=No IRQ, 1=IRQ)
- IRQ Mask (0=Enable, 1=Disable) (8B7F031Dh when all IRQs disabled)
Bit Stat Mask Function 0 SREP MREP CMDRESPEND (response end) (or R1b: busy end) 1 0 0 Unknown/unused (always 0) 2 SRWA MRWA DATAEND (set after (last) data block end) 3 SCOT MCOT CARD_REMOVE (0=No event, 1=Is/was newly ejected) ;\ 4 SCIN MCIN CARD_INSERT (0=No event, 1=Is/was newly inserted) ; SD 5 undoc 0 SIGSTATE (0=Ejected, 1=Inserted) (SDIO: always 1) ; Slot 6 0 0 Unknown/unused (always 0) ; Sw's 7 undoc 0 WRPROTECT (0=Locked/Ejected, 1=Unlocked/HalfEjected);/ 8 undoc undoc CARD_REMOVE_A (0=No event, 1=High-to-Low occurred) ;\SD 9 undoc undoc CARD_INSERT_A (0=No event, 1=Low-to-High óccurred) ; Slot 10 undoc 0 SIGSTATE_A (usually 1=High) ;also as so for SDIO ;/Data3 11 0 0 Unknown/unused (always 0) 12 0 0 Unknown/unused (always 0) 13 0 0 Unknown/unused (always 0) 14 0 0 Unknown/unused (always 0) 15 0 0 Unknown/unused (always 0) 16 SCIX MCIX CMD_IDX_ERR Bad CMD-index in response (RCMDE,SCMDE) 17 SCRC MCRC CRCFAIL CRC response error (WCRCE,RCRCE,SCRCE,CCRCE) 18 SEND MEND STOPBIT_ERR End bit error (WEBER,REBER,SEBER,CEBER) 19 SDTO MDTO DATATIMEOUT Data Timeout (NRCS,NWCS,KBSY) 20 SFOF MFOF RXOVERFLOW HOST tried write full 21 SFUF MFUF TXUNDERRUN HOST tried read empty 22 SCTO MCTO CMDTIMEOUT Response start-bit timeout (NRS,NSR) 23 ??? 0 Unknown/undoc (usually set) (zero after sending TX data?) 24 SBRE MBRE RXRDY (fifo not empty) (request data read) 25 SBWE MBWE TXRQ (datafifoempty?) (request data write) 26 0 0 Unknown/unused (always 0) 27 undoc undoc Unknown/undoc (bit27 is mask-able in IRQ_MASK) 28 0 0 Unknown/unused (always 0) 29 undoc 0 CMD_READY? (inverse of BUSY?) (unlike toshiba ILFSL/IFSMSK) 30 undoc 0 CMD_BUSY 31 ILA IMSK Illegal Command Access (old CMD still busy, or wrong NTDT)
Normally, IRQs should be acknowledged by writing "FLAGS=NOT X", whilst the firmware is using an unstable "FLAGS=FLAGS AND NOT X" read-modify-write function (accidentally acknowledging any IRQs that have newly occurred during that operation).
4004900h/4004B00h - SD_DATA32_IRQ
15-13 Unknown/unused (appears to be always zero) 12 DATA32_BUSY IRQ Enable (0=Disable, 1=Enable) (R/W) 11 DATA32_RXRDY IRQ Enable (0=Disable, 1=Enable) (R/W) 10 DATA32 Abort/Flush FIFO? (0=No change, 1=Clear Bit8,9) (W) 9 DATA32_BUSY IRQ Flag (auto cleared after...) (R) 8 DATA32_RXRDY IRQ Flag (auto cleared after...) (R) 7-2 Unknown/unused (appears to be always zero) 1 Select 16bit/32bit Data Mode (0=DATA16, 1=DATA32, see 40048D8h) (R/W) 0 Unknown/unused (appears to be always zero)
Can be 1A02h, but changes to 1802h after reading from somewhere (maybe from DATA32_FIFO?).
Bit8,9 are extra IRQ flags, the flags get set ONLY in DATA32 mode (not in DATA16 mode).
400482Ch/4004A2Ch - SD_ERROR_DETAIL_STATUS0-1 - Error Detail Status
This register contains extra info about the error bits in SD_IRQ_STATUS. The error bits (except bit13/always set) are automatically cleared when sending a new command by writing to SD_CMD.
31-23 0 Unknown/unused (always zero) 22 KBSY Timeout for CRC status busy ;\STAT.19 21 NWCS Timeout for CRC status (can occur for Data Write) ; (SDTO) 20 NRCS Timeout for Data start-bit, or for Post Data Busy ;/ 19-18 0 Unknown/unused (always zero) 17 NRS Response Timeout for auto-issued CMD12 ;\STAT.22 16 NCR Response Timeout for non-auto-issued CMD's ;/(SCTO) 15-14 0 Unknown/unused (always zero) 13 undoc Unknown/undoc (always 1) ;-Always 1 12 0 Unknown/unused (always zero) 11 WCRCE CRC error for Write CRC status for a write command ;\ 10 RCRCE CRC error for Read Data ; STAT.17 9 SCRCE CRC error for a Response for auto-issued CMD12 ; (SCRC) 8 CCRCE CRC error for a Response for non-auto-issued CMD's ;/ 5 WEBER End bit error for Write CRC status ;\ 4 REBER End bit error for Read Data ; STAT.18 3 SEBER End bit error for Response for auto-issued CMD12 ; (SEND) 2 CEBER End bit error for Response for non-auto-issued CMD's ;/ 1? SCMDE Bad CMD-index in Response of auto-issued CMD12 ;\STAT.16 0 RCMDE Bad CMD-index in Response of non-auto-issued CMD's ;/(SCIX)
Note: CMD12 is STOP_TRANSMISSION (automatically sent after BLK_COUNT blocks).
The four "auto-issued CMD12" bits exist for SD registers only (not for SDIO, going by old toshiba datasheets; which may be wrong).
SCMDE is probably in bit1 (though, official specs say bit0, which would be same as RCMDE).
Some error bits can be intentionally provoked: Bit8=1 when programming the controller to expect GET_STATUS to return a 136bit response. Bit16=1 when sending GET_CID in "tran" state. Bit20=1 when sending GET_STATUS configured to expect a data/read reply. Bit21=1 when sending GET_STATUS configured to expect a data/write block (and with actually sending a data block to it).
DSi SD/MMC I/O Ports: Control Registers
4004802h/4004A02h - SD_CARD_PORT_SELECT
15-11 Unknown/unused (appears to be always zero) 10 Unknown (should be set on writing) (reads as zero) (W) 9-8 Unknown (Always 2 for SD/4004802h, always 1 for SDIO/4004A02h) (R) 7-4 Unknown/unused (appears to be always zero) 3-1 Unknown (R/W) 0 Port Select (0=SD Card Slot, 1=Onboard eMMC) (for SDIO: Unknown)(R/W)
4004828h/4004A28h - SD_CARD_OPTION - Card Option Setup
15 undoc Bus Width (0=4bit, 1=1bit) (R/W) 14 undoc Unknown (usually set) (R?) 13-9 0 Unknown/unused (appears to be always zero) 8 undoc Unknown (firmware tries to toggle this after CLK change?) (W?) 7-4 RTO Data start/busy timout (2000h SHL 0..14, or 15=100h SDCLK's) (R/W) 0-3 TO? Unknown (another timeout, maybe for SDIO? in 32KHz units?) (R/W)
Among others, this register should contain a 4bit timeout setting, "RTO[3:0] for SD (aka TO[3:0] for SDIO) timeout period for data start/busy bits, in the form of a multiple number of the SDCLK period." Unknown which "multiple numbers" that's referring to (probably some exponential/table values). Settings spotted on DSi are 40E0h,40EEh.
4004824h/4004A24h - SD_CARD_CLK_CTL Card Clock Control
15-11 Unknown (always 0) ;unlike Toshiba: no HCLK divider-disable in bit15) 10 Unknown (0=Normal, 1=Unknown, doesn't affect SDCLK output?) (R/W) 9 Unknown (0=Normal, 1=Unknown, freezes SDCLK output?) (R/W) 8 SDCLK Enable (0=Force SDCLK=LOW, 1=Output SDCLK=HCLK/n) (R/W) 7-0 HCLK Div (0,1,2,4,8,16,32,64,128 = Div2,4,8,16,32,64,128,256,512) (R/W)
The DSi uses HCLK=33.513982 MHz, the SDCLK pin can range from HCLK/512=65kHz to HCLK/2=16.757MHz, max transfer rate would be thus 8MByte/s in 4bit mode.
Card detection should be done at a low clock rate. For SD/MMC, the DSi starts with HCLK/128, and uses the clock specified in CSD register after detection (when extracting bits from CSD: mind the different 120bit-without-CRC vs 128bit-with-CRC notations). For SDIO, the DSi starts with HCLK/256, and switches to HCLK/2 after reading SDIO Bus Speed register (Function0:00013h).
The SDCLK pins are permanently pulsed, even for devices deselected via SD_CARD_PORT_SELECT.0, and even if no CMD or DATA is being transferred. However, the DSi firmware is usually stopping SDCLK via Bit8=0 when not accessing SD/MMC (doing so may reduce noise and power consumption).
Trying to set bit9, or to set more than one bit in bit7-0 will freeze the SDCLK output (in this case SDCLK may get stuck HIGH or LOW, unlike Bit8=0 which forces LOW).
4004808h/4004A08h - SD_STOP_INTERNAL_ACTION
15-9 Unknown/unused (appears to be always zero) 8 Auto-Stop (1=Automatically send CMD12 after BLK_COUNT blocks) (R/W) 7-1 Unknown/unused (appears to be always zero) 0 Unknown (R/W)
Stop whatever internal action for whatever purpose in whatever situation?
Existing code does set bit8 (prior to changing SD_DATA16_BLK_COUNT).
Existing code does clear bit0 (alongsides with IRQ enable/acknowlege or so).
40048E0h/4004AE0h - SD_SOFT_RESET - Software Reset
15-3 Unknown/unused (appears to be always zero) 2 Unknown (always 1) (R?) 1 Unknown (always 1) (though firmware tries to toggle this bit) (R?) 0 SRST Soft Reset (0=Reset, 1=Release) (R/W)
Software should apply reset after sensing card insertion/removal, and (thereafter) release reset in case of card insertion. Software reset does acknowledge all IRQs (except that from SDIO /IRQ pin?), and does probably also reinitialize some other registers.
Clearing bit0 does force following settings (while and as long as Bit0=0):
SD_STOP_INTERNAL_ACTION = 0000h SD_RESPONSE0-7 = zerofilled SD_IRQ_STATUS0-1 = all IRQs flags acknowledged SD_ERROR_DETAIL_STATUS0-1 = all bits cleared (except bit13/always set) SD_CARD_CLK_CTL = bit 8 and 10 cleared SD_CARD_OPTION = 40EEh SD_CARD_INTERRUPT_CONTROL = 0000h
All other registers seem to be left unaffected (including the the extra IRQ flags in 4004900h); though there may be some further hidden effects (like aborting transfers or resetting internal registers).
Note: The DSi firmware does issue reset by toggling both bit0 and bit1, although bit1 does seem to be read-only (always 1), and trying to clear that bit doesn't seem to have any effect at all.
DSi SD/MMC I/O Ports: Unknown/Unused Registers
40048F6h/4004AF6h - Firmware tests bit0 (but, always 0?) (RESERVED4)
15-1 Unknown (0) 0 Unknown (tested by firmware) (usually 0) (R)
4004836h/4004A36h - SD_CARD_INTERRUPT_CONTROL ---- USED by SDIO
4004A36h is used in SDIO IRQ handler.
On DSi, this register looks as so:
15-2 Unknown (0) 1 Unknown (gets set automatically after 2 seconds?) (and also R/W ?) 0 Unknown (usually always 0) (tested by firmware?) (R?)
Whilst old toshiba datasheets specify it as so:
15-13 ? Unknown (zero on DSi) 12 CINT0 SDIO Interrupt Flag (0=none/ack, 1=irq) (/IRQ aka Data1 pin) 11-9 ? Unknown (zero on DSi) 8 CIMSK0 SDIO Interrupt Mask (0=enable, 1=disable) (/IRQ aka Data1 pin) 7-0 ? Unknown (zero on DSi)
Acknowledge by writing CINT0=0, or CIMSK0=1 (uh, really?), or hard reset (unlike as for other SD/MMC interrupts, soft reset does not acknowlege this interrupt type?).
4004838h/4004A38h - SDCTL_CLK_AND_WAIT_CTL ---- USED by SDIO
4004A38h is used in SDIO IRQ handler.
On DSi, this register looks as so (usually zero):
15-14 Unknown (usually 0) (R/W) 13-3 Unknown (0) 2-0 Unknown (usually 0) (R/W)
Whilst old toshiba datasheets specify it as so:
15-0 Unknown (bit8 should be set after SD_CARD_CLK_CTL change?)
Below registers don't seem to be used by existing software...
4004834h/4004A34h - SD_TRANSACTION_CTL - Transaction Control
15-10 Unknown/unused (appears to be always zero) 9-8 Unknown (R/W) 7-3 Unknown/unused (appears to be always zero) 2 Unknown (R/W) 1 Unknown/unused (appears to be always zero) 0 Unknown (R/W)
40048F2h/4004AF2h - Can be 0003h
15-2 Unknown (0) 1-0 Unknown (0..3) (R/W)
40048F4h/4004AF4h - Can be 0770h
15-11 Unknown (0) 10-8 Unknown (0..7) (R/W) 7 Unknown (0) 6-4 Unknown (0..7) (R/W) 3-0 Unknown (0)
40048FAh - Can be 0007h (nonzero, unlike SDIO) (RESERVED6)
15-3 Unknown (0) 2 Unknown (1=normal, 0=data/read from card to fifo busy?) (R) 1-0 Unknown (0..3) (R/W? or rather R?)
40048FCh/4004AFCh - Can be 0024h..00FFh? (RESERVED7)
40048FEh/4004AFEh - Can be 0024h..00FFh? (RESERVED8 / TC6371AF:Revision)
15-8 Unknown (0) 7-0 Can be 24h..FFh parts (R) and parts (R/W)?
Unused Registers with Fixed value (all bits read-only, or write-only)
400482Ah/4004A2Ah 2 Fixed always zero? 4004832h/4004A32h 2 Fixed always zero? ;(TC6371AF:BUF1 Data MSBs?) 400483Ah/4004A3Ah 2 Fixed always zero? ;(SDCTL_SDIO_HOST_INFORMATION) 400483Ch/4004A3Ch 2 Fixed always zero? ;(SDCTL_ERROR_CONTROL) 400483Eh/4004A3Eh 2 Fixed always zero? ;(TC6387XB: LED_CONTROL) 4004840h/4004A40h 2 Fixed always 003Fh? 4004842h/4004A42h 2 Fixed always 002Ah? 4004844h/4004A44h 6Eh Fixed always zerofilled? 40048B2h/4004AB2h 2 Fixed always FFFFh? 40048B4h/4004AB4h 6 Fixed always zerofilled? 40048BAh/4004ABAh 2 Fixed always 0200h? 40048BCh/4004ABCh 1Ch Fixed always zerofilled? 40048DAh/4004ADAh 6 Fixed always zerofilled? 40048E2h/4004AE2h 2 Fixed always 0009h? ;(RESERVED2/9, TC6371AF:CORE_REV) 40048E4h/4004AE4h 2 Fixed always zero? 40048E6h/4004AE6h 2 Fixed always zero? ;(RESERVED3, TC6371AF:BUF_ADR) 40048E8h/4004AE8h 2 Fixed always zero? ;(TC6371AF:Resp_Header) 40048EAh/4004AEAh 6 Fixed always zerofilled? 40048F0h/4004AF0h 2 Fixed always zero? ;(RESERVED10) 40048F8h 2 Fixed always 0004h? (unlike SDIO) (RESERVED5) 4004AF8h 2 Fixed always zero? (unlike SD) (RESERVED5) 4004AFAh 2 Fixed always zero? (unlike SD) (RESERVED6) 4004902h/4004B02h 2 Fixed always zero? 4004906h/4004B06h 2 Fixed always zero? 400490Ah/4004B0Ah 2 Fixed always zero? 4004910h/4004B10h F0h Fixed always zerofilled?