More SD card stuff

This commit is contained in:
meepingsnesroms
2019-02-22 11:36:40 -08:00
parent 8dbc416bfd
commit 142b8152d8
5 changed files with 66 additions and 21 deletions

View File

@@ -91,9 +91,11 @@ typedef struct{
uint8_t response;
uint64_t responseState;//this can contain many different types of data depending on the response type
uint8_t responseWaitBitsRemaining;//not in savestates yet!!
bool commandIsAcmd;//not in savestates yet!!
bool allowInvalidCrc;
bool chipSelect;
bool receivingCommand;//not in savstates yet!!
bool receivingCommand;//not in savestates yet!!
bool inIdleState;//not in savestates yet!!
buffer_t flashChip;
}sd_card_t;

View File

@@ -103,10 +103,10 @@ int32_t interruptAcknowledge(int32_t intLevel){
int32_t vector;
//If an interrupt occurs before the IVR has been programmed, interrupt vector 15 is returned to the CPU as an uninitialized interrupt.
if(!vectorOffset)
vector = 15;//EXCEPTION_UNINITIALIZED_INTERRUPT
else
if(vectorOffset)
vector = vectorOffset | intLevel;
else
vector = 15;//EXCEPTION_UNINITIALIZED_INTERRUPT
//only active interrupts should wake the CPU if the PLL is off
pllWakeCpuIfOff();
@@ -419,7 +419,7 @@ uint16_t getHwRegister16(uint32_t address){
uint16_t fifoVal = spi1RxFifoRead();
//check if SPI1 interrupts changed
setSpiIntCs(registerArrayRead16(SPIINTCS));
debugLog("SPIRXD read, FIFO value:0x%04X, SPIINTCS:0x%04X\n", fifoVal, registerArrayRead16(SPIINTCS));
//debugLog("SPIRXD read, FIFO value:0x%04X, SPIINTCS:0x%04X\n", fifoVal, registerArrayRead16(SPIINTCS));
return fifoVal;
}

View File

@@ -377,7 +377,7 @@ static void setSpiCont1(uint16_t value){
uint16_t startBit = 1 << (bitCount - 1);
uint8_t bits;
debugLog("SPI1 transfer, bitCount:%d, PC:0x%08X\n", bitCount, flx68000GetPc());
//debugLog("SPI1 transfer, bitCount:%d, PC:0x%08X\n", bitCount, flx68000GetPc());
//The most significant bit is output when the CPU loads the transmitted data, 13.2.3 SPI 1 Phase and Polarity Configurations MC68VZ328UM.pdf
for(bits = 0; bits < bitCount; bits++){

View File

@@ -34,14 +34,18 @@ static const uint8_t sdCardCrc7Table[256] = {
};
static const uint64_t sdCardCsd[2] = {0x0000000000000000, 0x0000000000000000};
static const uint64_t sdCardCid[2] = {0x0000000000000000, 0x0000000000000000};
static const uint32_t sdCardOcr = 0x00000000;
static void sdCardCmdStart(void){
static uint32_t sdCardGetOcr(){
return !palmSdCard.inIdleState << 31/*power up status*/ | 0 << 30/*card capacity status*/ | 0x01FF8000/*supported voltages*/;
}
static void sdCardCmdStart(bool isAcmd){
palmSdCard.command = UINT64_C(0x0000000000000000);
palmSdCard.commandBitsRemaining = 48;
palmSdCard.responseState = 0;
palmSdCard.response = SD_CARD_RESPONSE_NOTHING;
palmSdCard.commandIsAcmd = isAcmd;
palmSdCard.receivingCommand = true;
}
@@ -75,7 +79,7 @@ static void sdCardDoResponseR1(uint8_t r1){
static void sdCardDoResponseR3(uint8_t r1){
palmSdCard.response = SD_CARD_RESPONSE_SHIFT_OUT;
palmSdCard.responseState = (uint64_t)r1 << 56;
palmSdCard.responseState |= (uint64_t)sdCardOcr << 24;
palmSdCard.responseState |= (uint64_t)sdCardGetOcr() << 24;
palmSdCard.responseState |= UINT64_C(1) << 23;//add shift termination bit
}
@@ -85,9 +89,11 @@ void sdCardReset(void){
palmSdCard.responseState = 0;
palmSdCard.response = SD_CARD_RESPONSE_NOTHING;
palmSdCard.responseWaitBitsRemaining = 0;
palmSdCard.commandIsAcmd = false;
palmSdCard.allowInvalidCrc = false;
palmSdCard.chipSelect = false;
palmSdCard.receivingCommand = false;
palmSdCard.inIdleState = true;
}
void sdCardSetChipSelect(bool value){
@@ -96,7 +102,7 @@ void sdCardSetChipSelect(bool value){
//commands start when chip select goes from high to low
if(value == false)
sdCardCmdStart();
sdCardCmdStart(palmSdCard.commandIsAcmd);
palmSdCard.chipSelect = value;
}
@@ -158,7 +164,7 @@ bool sdCardExchangeBit(bool bit){
palmSdCard.commandBitsRemaining--;
}
else{
sdCardCmdStart();
sdCardCmdStart(palmSdCard.commandIsAcmd);
}
//process command if all bits are present
@@ -167,27 +173,57 @@ bool sdCardExchangeBit(bool bit){
uint32_t argument = palmSdCard.command >> 8 & 0xFFFFFFFF;
uint8_t crc = palmSdCard.command >> 1 & 0x7F;
debugLog("SD command:cmd:%d, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
debugLog("SD command: isAcmd:%d, cmd:%d, arg:0x%08X, CRC:0x%02X\n", palmSdCard.commandIsAcmd, command, argument, crc);
if(palmSdCard.allowInvalidCrc || sdCardCmdIsCrcValid(command, argument, crc)){
//respond with command value
//debugLog("SD valid CRC\n");
switch(command){
case GO_IDLE_STATE:
palmSdCard.allowInvalidCrc = true;
sdCardDoResponseR1(0x01);//"idle state" bit set should be set
break;
if(!palmSdCard.commandIsAcmd){
//normal command
switch(command){
case GO_IDLE_STATE:
palmSdCard.inIdleState = true;
palmSdCard.allowInvalidCrc = true;
sdCardDoResponseR1(palmSdCard.inIdleState);
break;
default:
debugLog("SD unknown command:cmd:%d, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
break;
case SEND_OP_COND:
palmSdCard.inIdleState = false;
sdCardDoResponseR1(palmSdCard.inIdleState);
break;
case READ_OCR:
sdCardDoResponseR3(palmSdCard.inIdleState);
break;
case APP_CMD:
sdCardCmdStart(true);
sdCardDoResponseR1(palmSdCard.inIdleState);
break;
default:
debugLog("SD unknown command: cmd:%d, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
break;
}
}
else{
//ACMD command
switch(command){
default:
debugLog("SD unknown ACMD command: cmd:%d, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
break;
}
//ACMD finished, go back to normal command format
palmSdCard.commandIsAcmd = false;
}
}
else{
//send back R1 response with CRC error set
debugLog("SD invalid CRC\n");
sdCardDoResponseR1(0x08);//"command CRC error" bit set
sdCardDoResponseR1(0x08 | palmSdCard.inIdleState);//"command CRC error" bit set
}
//needs to be at least 8 for MMC

View File

@@ -7,14 +7,21 @@
#define GO_IDLE_STATE 0/*software reset*/
#define SEND_OP_COND 1/*initiate initialization process*/
#define SEND_IF_COND 8/*only for SDC V2, checks voltage range.*/
#define SEND_CSD 9/*read CSD register*/
#define SEND_CID 10/*read CID register*/
#define STOP_TRANSMISSION 12/*stop to read data*/
#define SET_BLOCKLEN 16/*change R/W block size*/
#define READ_SINGLE_BLOCK 17/*read a block*/
#define READ_MULTIPLE_BLOCK 18/*read multiple blocks*/
#define SET_BLOCK_COUNT 23/*only for MMC, defines number of blocks to transfer with next multi-block read/write command*/
#define WRITE_SINGLE_BLOCK 24/*write a block*/
#define WRITE_MULTIPLE_BLOCK 25/*write multiple blocks*/
#define APP_CMD 55/*next command is ACMD<n> command*/
#define READ_OCR 58/*read OCR(operation condtion register)*/
/*Application Commands*/
#define APP_SEND_OP_COND 41/*only for SDC, same as SEND_OP_COND*/
#define SET_WR_BLOCK_ERASE_COUNT 23/*only for SDC, defines number of blocks to pre-erase with next multi-block write command*/
#endif