mirror of
https://github.com/coderkei/akmenu-next.git
synced 2025-06-18 17:05:48 -04:00
ttio: update from DLDI source
Fixes issues on R4iTT DSTT-based carts which have a weird quirk
This commit is contained in:
parent
c310511fe2
commit
5c632b58f5
@ -1,5 +1,3 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
SuperCard DSONE
|
||||
Card IO routines
|
||||
@ -15,85 +13,105 @@
|
||||
|
||||
u32 SCDS_isSDHC = 0;
|
||||
|
||||
static void SCDS_ReadCardData(u64 command, u32 flags, void *buffer, u32 length)
|
||||
static u32 SCDS_SDHostSetMode(u8 sdio, u32 parameter, u8 response_type, u32 latency)
|
||||
{
|
||||
u64 command = ((u64)SCDS_CMD_SD_HOST_PARAM << 56) | ((u64)parameter << 24) | ((u64)sdio << 16) | ((u64)response_type << 8);
|
||||
card_romSetCmd(command);
|
||||
card_romStartXfer(flags, false);
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B | MCCNT1_LATENCY1(latency), false);
|
||||
card_romWaitDataReady();
|
||||
return card_romGetData();
|
||||
}
|
||||
|
||||
static u32 SCDS_IsSDHostBusy(void)
|
||||
{
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_SD_HOST_BUSY;
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
return card_romGetData();
|
||||
}
|
||||
|
||||
static u32 SCDS_SDHostGetResponse(void)
|
||||
{
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_SD_HOST_RESPONSE;
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
return __builtin_bswap32(card_romGetData());
|
||||
}
|
||||
|
||||
static void SCDS_SDSendR0Command(u8 sdio, u32 parameter, u32 latency)
|
||||
{
|
||||
SCDS_SDHostSetMode(sdio, parameter, SCDS_SD_HOST_NORESPONSE, latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
}
|
||||
|
||||
static u32 SCDS_SDSendR1Command(u8 sdio, u32 parameter, u32 latency)
|
||||
{
|
||||
SCDS_SDHostSetMode(sdio, parameter, SCDS_SD_HOST_READ_4B, latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
return SCDS_SDHostGetResponse();
|
||||
}
|
||||
|
||||
// TODO: save the response to a buffer (also figure out in which order they're sent)
|
||||
static void SCDS_SDSendR2Command(u8 sdio, u32 parameter, u32 latency)
|
||||
{
|
||||
SCDS_SDHostSetMode(sdio, parameter, SCDS_SD_HOST_READ_4B_MULTI, latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
|
||||
// TODO: parse this response
|
||||
SCDS_SDHostGetResponse();
|
||||
|
||||
for(int i=0; i < 4; i++)
|
||||
{
|
||||
SCDS_SDHostSetMode(sdio, parameter, SCDS_SD_HOST_NEXT_4B, latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
// TODO: parse this response
|
||||
SCDS_SDHostGetResponse();
|
||||
}
|
||||
SCDS_SDHostSetMode(sdio, parameter, SCDS_SD_HOST_SEND_STOP_CLK, 0);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
}
|
||||
|
||||
void waitByLoop(u32 count);
|
||||
|
||||
static void SCDS_SDHostSetRegister(u8 bits)
|
||||
{
|
||||
u64 command = ((u64)SCDS_CMD_SD_HOST_SET_REGISTER << 56) | ((u64)(0x30 | bits) << 48);
|
||||
card_romSetCmd(command);
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
waitByLoop(0x300);
|
||||
}
|
||||
|
||||
static u32 SCDS_IsSDFIFOBusy(void) {
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_FIFO_BUSY;
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
return card_romGetData();
|
||||
}
|
||||
|
||||
// Reads max 512 bytes
|
||||
static void SCDS_SDFIFOReadData(void *buffer, u32 length)
|
||||
{
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_FIFO_READ_DATA;
|
||||
card_romStartXfer(SCDS_CTRL_READ_512B, false);
|
||||
if ((u32)buffer & 3)
|
||||
card_romCpuReadUnaligned((u8 *)buffer, length);
|
||||
else
|
||||
card_romCpuRead(buffer, length);
|
||||
}
|
||||
|
||||
static void SCDS_WriteCardData(u64 command, u32 flags, const void *buffer, u32 length)
|
||||
// Writes max 512 bytes
|
||||
static void SCDS_SDFIFOWriteData(const void *buffer, u32 length)
|
||||
{
|
||||
card_romSetCmd(command);
|
||||
card_romStartXfer(flags, false);
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_FIFO_WRITE_DATA;
|
||||
card_romStartXfer(SCDS_CTRL_WRITE_512B, false);
|
||||
if ((u32)buffer & 3)
|
||||
card_romCpuWriteUnaligned((u8 *)buffer, length);
|
||||
else
|
||||
card_romCpuWrite(buffer, length);
|
||||
}
|
||||
|
||||
static u32 SCDS_IsSDHostBusy(void)
|
||||
{
|
||||
return SCDS_SendCommand(SCDS_CMD_SD_HOST_BUSY, 0);
|
||||
}
|
||||
|
||||
static void SCDS_SDSendR0Command(u8 sdio, u32 parameter, u32 latency)
|
||||
{
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(sdio, parameter, SCDS_SD_HOST_NORESPONSE), latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
}
|
||||
|
||||
static u32 SCDS_SDSendR1Command(u8 sdio, u32 parameter, u32 latency)
|
||||
{
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(sdio, parameter, SCDS_SD_HOST_READ_4B), latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
return __builtin_bswap32(SCDS_SendCommand(SCDS_CMD_SD_HOST_RESPONSE, 0));
|
||||
}
|
||||
|
||||
// TODO: save the response to a buffer (also figure out in which order they're sent)
|
||||
static void SCDS_SDSendR2Command(u8 sdio, u32 parameter, u32 latency)
|
||||
{
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(sdio, parameter, SCDS_SD_HOST_READ_4B_MULTI), latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
|
||||
// TODO: parse this response
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_RESPONSE, 0);
|
||||
|
||||
for(int i=0; i < 4; i++)
|
||||
{
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(sdio, parameter, SCDS_SD_HOST_NEXT_4B), latency);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
// TODO: parse this response
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_RESPONSE, 0);
|
||||
}
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(sdio, parameter, SCDS_SD_HOST_SEND_STOP_CLK), 0);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
}
|
||||
|
||||
void waitByLoop(u32 count);
|
||||
|
||||
static void SCDS_SDSetHostRegister(u8 bits)
|
||||
{
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_SET_REGISTER(bits), 0);
|
||||
waitByLoop(0x300);
|
||||
}
|
||||
|
||||
void SCDS_SDGetSDHCStatusFromSRAM(void)
|
||||
{
|
||||
SCDS_isSDHC = SCDS_SendCommand(SCDS_CMD_SRAM_READ_DATA(0x7F9E0), 0) != 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
u32 SCDS_SendCommand(const u64 command, u32 latency)
|
||||
{
|
||||
card_romSetCmd(command);
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B | MCCNT1_LATENCY1(latency), false);
|
||||
card_romWaitDataReady();
|
||||
return card_romGetData();
|
||||
}
|
||||
|
||||
bool SCDS_SDInitialize(void)
|
||||
{
|
||||
u32 isSD20 = 0;
|
||||
@ -102,35 +120,38 @@ bool SCDS_SDInitialize(void)
|
||||
SCDS_isSDHC = 0;
|
||||
|
||||
// TODO: What is this command doing?
|
||||
SCDS_ReadCardData(0x6600000000000000ull, 0xA7586000, &response, 1);
|
||||
card_romSetCmd(0x6600000000000000ull);
|
||||
card_romStartXfer(0xA7586000, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
|
||||
// Reset SD host
|
||||
SCDS_SDSetHostRegister(0);
|
||||
SCDS_SDHostSetRegister(0);
|
||||
|
||||
// Init
|
||||
SCDS_SDSetHostRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_400KHZ_CLK | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(0, 0, SCDS_SD_HOST_SEND_CLK), SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
SCDS_SDHostSetRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_400KHZ_CLK | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
SCDS_SDHostSetMode(0, 0, SCDS_SD_HOST_SEND_CLK, SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
waitByLoop(0x1000);
|
||||
|
||||
// CMD0
|
||||
SCDS_SDSendR0Command(0, 0, SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(0, 0, SCDS_SD_HOST_SEND_STOP_CLK), SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
SCDS_SDHostSetMode(0, 0, SCDS_SD_HOST_SEND_STOP_CLK, SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
|
||||
// CMD8
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(8, 0x1AA, SCDS_SD_HOST_READ_4B), SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
SCDS_SDHostSetMode(8, 0x1AA, SCDS_SD_HOST_READ_4B, SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
|
||||
u32 retryCount = 9999;
|
||||
while(1)
|
||||
{
|
||||
if(!SCDS_IsSDHostBusy())
|
||||
{
|
||||
response = __builtin_bswap32(SCDS_SendCommand(SCDS_CMD_SD_HOST_RESPONSE, 0));
|
||||
response = SCDS_SDHostGetResponse();
|
||||
break;
|
||||
}
|
||||
if (--retryCount == 0)
|
||||
{
|
||||
SCDS_SDSetHostRegister(0);
|
||||
SCDS_SDSetHostRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_400KHZ_CLK | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
SCDS_SDHostSetRegister(0);
|
||||
SCDS_SDHostSetRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_400KHZ_CLK | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
response = 0;
|
||||
break;
|
||||
}
|
||||
@ -142,18 +163,18 @@ bool SCDS_SDInitialize(void)
|
||||
do
|
||||
{
|
||||
// CMD55
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(55, 0, SCDS_SD_HOST_READ_4B), SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
SCDS_SDHostSetMode(55, 0, SCDS_SD_HOST_READ_4B, SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
retryCount = 9999;
|
||||
while(SCDS_IsSDHostBusy())
|
||||
{
|
||||
if (--retryCount == 0)
|
||||
{
|
||||
SCDS_SDSetHostRegister(0);
|
||||
SCDS_SDSetHostRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_400KHZ_CLK | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
SCDS_SDHostSetRegister(0);
|
||||
SCDS_SDHostSetRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_400KHZ_CLK | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_RESPONSE, 0);
|
||||
SCDS_SDHostGetResponse();
|
||||
|
||||
// ACMD41
|
||||
u32 parameter = 0x00FC0000;
|
||||
@ -181,43 +202,49 @@ bool SCDS_SDInitialize(void)
|
||||
// CMD16
|
||||
SCDS_SDSendR1Command(16, 512, SCDS_CTRL_SD_LOW_CLK_LATENCY);
|
||||
|
||||
SCDS_SDSetHostRegister(0);
|
||||
SCDS_SDSetHostRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
if(SCDS_isSDHC )
|
||||
SCDS_SDSetHostRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_CLEAN_ROM_MODE | SCDS_SD_HOST_REG_SDHC);
|
||||
SCDS_SDHostSetRegister(0);
|
||||
SCDS_SDHostSetRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_CLEAN_ROM_MODE);
|
||||
if(SCDS_isSDHC)
|
||||
SCDS_SDHostSetRegister(SCDS_SD_HOST_REG_RESET | SCDS_SD_HOST_REG_CLEAN_ROM_MODE | SCDS_SD_HOST_REG_SDHC);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SCDS_SDReadSingleSector(u32 sector, void *buffer)
|
||||
{
|
||||
// instruct cart what to read
|
||||
SCDS_SendCommand(SCDS_CMD_SD_READ_SINGLE_BLOCK(SCDS_isSDHC ? sector : sector << 9), 0);
|
||||
u64 command = ((u64)SCDS_CMD_SD_READ_SINGLE_BLOCK << 56) | ((u64)(SCDS_isSDHC ? sector : sector << 9) << 24);
|
||||
card_romSetCmd(command);
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
|
||||
// wait until data ready
|
||||
while(SCDS_SendCommand(SCDS_CMD_FIFO_BUSY, 0));
|
||||
while(SCDS_IsSDFIFOBusy());
|
||||
|
||||
// retrieve data
|
||||
SCDS_ReadCardData(SCDS_CMD_FIFO_READ_DATA, SCDS_CTRL_READ_512B, buffer, 128);
|
||||
SCDS_SDFIFOReadData(buffer, 128);
|
||||
}
|
||||
|
||||
void SCDS_SDReadMultiSector(u32 sector, void *buffer, u32 num_sectors)
|
||||
{
|
||||
// instruct cart what to read
|
||||
SCDS_SendCommand(SCDS_CMD_SD_READ_MULTI_BLOCK(SCDS_isSDHC ? sector : sector << 9), 0);
|
||||
u64 command = ((u64)SCDS_CMD_SD_READ_MULTI_BLOCK << 56) | ((u64)(SCDS_isSDHC ? sector : sector << 9) << 24);
|
||||
card_romSetCmd(command);
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
|
||||
while(1)
|
||||
{
|
||||
// wait until data ready
|
||||
while(SCDS_SendCommand(SCDS_CMD_FIFO_BUSY, 0));
|
||||
while(SCDS_IsSDFIFOBusy());
|
||||
|
||||
// retrieve data
|
||||
SCDS_ReadCardData(SCDS_CMD_FIFO_READ_DATA, SCDS_CTRL_READ_512B, buffer, 128);
|
||||
SCDS_SDFIFOReadData(buffer, 128);
|
||||
buffer = (u8 *)buffer + 0x200;
|
||||
num_sectors--;
|
||||
if(num_sectors == 0)
|
||||
break;
|
||||
SCDS_SendCommand(SCDS_CMD_SD_HOST_PARAM(0, 0, SCDS_SD_HOST_NEXT_DATABLOCK), 0);
|
||||
SCDS_SDHostSetMode(0, 0, SCDS_SD_HOST_NEXT_DATABLOCK, 0);
|
||||
};
|
||||
|
||||
// end read
|
||||
@ -230,11 +257,14 @@ void SCDS_SDWriteSingleSector(u32 sector, const void *buffer)
|
||||
SCDS_SDSendR1Command(24, SCDS_isSDHC ? sector : sector << 9, 0);
|
||||
|
||||
// write
|
||||
SCDS_WriteCardData(SCDS_CMD_FIFO_WRITE_DATA, SCDS_CTRL_WRITE_512B, buffer, 128);
|
||||
SCDS_SDFIFOWriteData(buffer, 128);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
|
||||
// end write
|
||||
SCDS_SendCommand(SCDS_CMD_SD_WRITE_END, 0);
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_SD_WRITE_END;
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
while(SCDS_IsSDHostBusy());
|
||||
}
|
||||
|
||||
@ -247,16 +277,22 @@ void SCDS_SDWriteMultiSector(u32 sector, const void *buffer, u32 num_sectors)
|
||||
// end write
|
||||
// well, it's supposed to be end write. But doing it first is a no-op, and it's also
|
||||
// a little simpler to write this way
|
||||
SCDS_SendCommand(SCDS_CMD_SD_WRITE_END, 0);
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_SD_WRITE_END;
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
while(SCDS_IsSDHostBusy());
|
||||
// write
|
||||
SCDS_WriteCardData(SCDS_CMD_FIFO_WRITE_DATA, SCDS_CTRL_WRITE_512B, buffer, 128);
|
||||
SCDS_SDFIFOWriteData(buffer, 128);
|
||||
while(SCDS_IsSDHostBusy());
|
||||
buffer = (u8 *)buffer + 0x200;
|
||||
}
|
||||
|
||||
// *really* end write
|
||||
SCDS_SDSendR1Command(12, 0, 0);
|
||||
SCDS_SendCommand(SCDS_CMD_SD_WRITE_END, 0);
|
||||
REG_SCDS_MCCMD[0] = SCDS_CMD_SD_WRITE_END;
|
||||
card_romStartXfer(SCDS_CTRL_READ_4B, false);
|
||||
card_romWaitDataReady();
|
||||
card_romGetData();
|
||||
while(SCDS_IsSDHostBusy());
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
SuperCard DSONE
|
||||
Card IO routines
|
||||
@ -17,11 +15,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include "libtwl_card.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
// libtwl workaround
|
||||
// Certain DSTT clones need bytewise access to MCCMD
|
||||
#define REG_SCDS_MCCMD ((vu8*)®_MCCMD0)
|
||||
|
||||
// SCDS defines
|
||||
// SCDS ROMCTRL flags
|
||||
#define SCDS_CTRL_BASE (MCCNT1_ENABLE | MCCNT1_RESET_OFF | MCCNT1_LATENCY2(24) | MCCNT1_LATENCY1(0))
|
||||
@ -42,52 +45,32 @@ extern "C" {
|
||||
AA = command
|
||||
BBBBBBBB = address
|
||||
*/
|
||||
|
||||
static inline u64 SCDS_CMD_SRAM_READ_DATA(u32 address)
|
||||
{
|
||||
return (0x70ull << 56) | ((u64)address << 24);
|
||||
}
|
||||
|
||||
static inline u64 SCDS_CMD_SRAM_WRITE_DATA(u32 address)
|
||||
{
|
||||
return (0x71ull << 56) | ((u64)address << 24);
|
||||
}
|
||||
|
||||
/*
|
||||
This address in SRAM *usually* contains a bool for SD or SDHC
|
||||
While not exactly reliable, the original driver did it, so here goes
|
||||
|
||||
return 0 == SD
|
||||
return non-0 == SDHC
|
||||
*/
|
||||
static inline u64 SCDS_CMD_SD_IS_SDHC(void)
|
||||
{
|
||||
return SCDS_CMD_SRAM_READ_DATA(0x7F9E0);
|
||||
}
|
||||
#define SCDS_CMD_SRAM_READ_DATA (0x70)
|
||||
#define SCDS_CMD_SRAM_WRITE_DATA (0x71)
|
||||
|
||||
// FIFO commands
|
||||
#define SCDS_CMD_FIFO_BUSY (0x80ull << 56)
|
||||
#define SCDS_CMD_FIFO_READ_DATA (0x81ull << 56)
|
||||
#define SCDS_CMD_FIFO_WRITE_DATA (0x82ull << 56)
|
||||
#define SCDS_CMD_FIFO_BUSY (0x80)
|
||||
#define SCDS_CMD_FIFO_READ_DATA (0x81)
|
||||
#define SCDS_CMD_FIFO_WRITE_DATA (0x82)
|
||||
|
||||
/*
|
||||
SD host modes
|
||||
Used with 0x51 command, see below
|
||||
*/
|
||||
enum SCDS_SD_HOST_MODES {
|
||||
SCDS_SD_HOST_NORESPONSE = 0ull,
|
||||
SCDS_SD_HOST_READ_4B = 1ull,
|
||||
SCDS_SD_HOST_READ_4B_MULTI = 2ull, // use mode 3 to continue this read
|
||||
SCDS_SD_HOST_NEXT_4B = 3ull,
|
||||
SCDS_SD_HOST_SEND_CLK = 4ull,
|
||||
SCDS_SD_HOST_SEND_STOP_CLK = 5ull,
|
||||
SCDS_SD_HOST_READ_DATABLOCK = 6ull,
|
||||
SCDS_SD_HOST_NEXT_DATABLOCK = 7ull,
|
||||
SCDS_SD_HOST_CMD17_READ_DATA = 8ull, // Send SDIO CMD17 & read data
|
||||
SCDS_SD_HOST_CMD18_READ_DATA = 9ull, // Send SDIO CMD18 & read data until stop
|
||||
SCDS_SD_HOST_COMMIT_FIFO_DATA = 0xAull, // commit data in FIFO to SD card
|
||||
SCDS_SD_HOST_CMD24_WRITE_DATA = 0xBull, // Send SDIO CMD24 & send data in SRAM buffer
|
||||
SCDS_SD_HOST_WAIT_BUSY = 0xCull // wait until data transfer ends
|
||||
SCDS_SD_HOST_NORESPONSE = 0,
|
||||
SCDS_SD_HOST_READ_4B = 1,
|
||||
SCDS_SD_HOST_READ_4B_MULTI = 2, // use mode 3 to continue this read
|
||||
SCDS_SD_HOST_NEXT_4B = 3,
|
||||
SCDS_SD_HOST_SEND_CLK = 4,
|
||||
SCDS_SD_HOST_SEND_STOP_CLK = 5,
|
||||
SCDS_SD_HOST_READ_DATABLOCK = 6,
|
||||
SCDS_SD_HOST_NEXT_DATABLOCK = 7,
|
||||
SCDS_SD_HOST_CMD17_READ_DATA = 8, // Send SDIO CMD17 & read data
|
||||
SCDS_SD_HOST_CMD18_READ_DATA = 9, // Send SDIO CMD18 & read data until stop
|
||||
SCDS_SD_HOST_COMMIT_FIFO_DATA = 0xA, // commit data in FIFO to SD card
|
||||
SCDS_SD_HOST_CMD24_WRITE_DATA = 0xB, // Send SDIO CMD24 & send data in SRAM buffer
|
||||
SCDS_SD_HOST_WAIT_BUSY = 0xC // wait until data transfer ends
|
||||
};
|
||||
|
||||
/*
|
||||
@ -103,34 +86,22 @@ enum SCDS_SD_HOST_MODES {
|
||||
BB = SDIO command
|
||||
CC = SD host mode, see SCDS_SD_HOST_MODES enum
|
||||
*/
|
||||
static inline u64 SCDS_CMD_SD_HOST_PARAM(u8 sdio, u32 parameter, u8 mode)
|
||||
{
|
||||
return (0x51ull << 56) | ((u64)parameter << 24) | ((u64)sdio << 16) | ((u64)mode << 8);
|
||||
}
|
||||
#define SCDS_CMD_SD_HOST_PARAM (0x51)
|
||||
|
||||
// SD host misc commands
|
||||
// return 0 == idle
|
||||
// return non-0 == not idle
|
||||
#define SCDS_CMD_SD_HOST_BUSY (0x50ull << 56)
|
||||
#define SCDS_CMD_SD_HOST_BUSY (0x50)
|
||||
|
||||
// Gets response of SD_HOST commands, if the sent mode is 1 or 2
|
||||
#define SCDS_CMD_SD_HOST_RESPONSE (0x52ull << 56)
|
||||
#define SCDS_CMD_SD_HOST_RESPONSE (0x52)
|
||||
// Stops SD host data transfer
|
||||
#define SCDS_CMD_SD_WRITE_END (0x56ull << 56)
|
||||
#define SCDS_CMD_SD_WRITE_END (0x56)
|
||||
|
||||
// Sends CMD17
|
||||
// This is effectively 0x51/0x50/0x52 rolled into one command
|
||||
static inline u64 SCDS_CMD_SD_READ_SINGLE_BLOCK(u32 sector)
|
||||
{
|
||||
return (0x53ull << 56) | ((u64)sector << 24);
|
||||
}
|
||||
|
||||
#define SCDS_CMD_SD_READ_SINGLE_BLOCK (0x53)
|
||||
// Sends CMD18
|
||||
// This is effectively 0x51/0x50/0x52 rolled into one command
|
||||
static inline u64 SCDS_CMD_SD_READ_MULTI_BLOCK(u32 sector)
|
||||
{
|
||||
return (0x54ull << 56) | ((u64)sector << 24);
|
||||
}
|
||||
#define SCDS_CMD_SD_READ_MULTI_BLOCK (0x54)
|
||||
|
||||
/*
|
||||
SD host control registers
|
||||
@ -148,15 +119,10 @@ static inline u64 SCDS_CMD_SD_READ_MULTI_BLOCK(u32 sector)
|
||||
#define SCDS_SD_HOST_REG_CLEAN_ROM_MODE BIT(2)
|
||||
#define SCDS_SD_HOST_REG_SDHC BIT(3)
|
||||
|
||||
// This function will always set bits 4-5 to 1 and bits 6-7 to 0 for convenience
|
||||
static inline u64 SCDS_CMD_SD_HOST_SET_REGISTER(u8 bits)
|
||||
{
|
||||
return (0x5F30ull << 48) | ((u64)bits << 48);
|
||||
}
|
||||
// Command to write to host register
|
||||
#define SCDS_CMD_SD_HOST_SET_REGISTER (0x5F)
|
||||
|
||||
// user API
|
||||
u32 SCDS_SendCommand(const u64 command, u32 latency);
|
||||
void SCDS_SDGetSDHCStatusFromSRAM(void);
|
||||
bool SCDS_SDInitialize(void);
|
||||
void SCDS_SDReadSingleSector(u32 sector, void *buffer);
|
||||
void SCDS_SDReadMultiSector(u32 sector, void *buffer, u32 num_sectors);
|
||||
|
Loading…
Reference in New Issue
Block a user