mirror of
https://github.com/libretro/Mu.git
synced 2026-09-23 23:25:04 +00:00
Add large FIFO for SD card responses, can now read the OCR, CSD and CID
This commit is contained in:
@@ -146,7 +146,8 @@ HEADERS += \
|
||||
../../src/armv5/types.h \
|
||||
../../src/armv5/icache.h \
|
||||
../../src/armv5.h \
|
||||
../../src/expansionHardware.h
|
||||
../../src/expansionHardware.h \
|
||||
../../src/sdCardAccessors.c.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
|
||||
@@ -111,7 +111,7 @@ static uint32_t makePalmString(const char* str){
|
||||
uint32_t strLength = strlen(str) + 1;
|
||||
uint32_t strData = sandboxCallGuestFunction(false, 0x00000000, MemPtrNew, "p(l)", strLength);
|
||||
|
||||
if(strData != 0){
|
||||
if(strData){
|
||||
uint32_t count;
|
||||
|
||||
for(count = 0; count < strLength; count++)
|
||||
@@ -122,7 +122,7 @@ static uint32_t makePalmString(const char* str){
|
||||
}
|
||||
|
||||
static char* makeNativeString(uint32_t address){
|
||||
if(address != 0){
|
||||
if(address){
|
||||
int16_t strLength = sandboxCallGuestFunction(false, 0x00000000, StrLen, "w(p)", address) + 1;
|
||||
char* nativeStr = malloc(strLength);
|
||||
int16_t count;
|
||||
|
||||
@@ -376,10 +376,6 @@ bool emulatorSaveState(buffer_t buffer){
|
||||
offset += sizeof(uint64_t);
|
||||
writeStateValue8(buffer.data + offset, palmSdCard.commandBitsRemaining);
|
||||
offset += sizeof(uint8_t);
|
||||
writeStateValue8(buffer.data + offset, palmSdCard.response);
|
||||
offset += sizeof(uint8_t);
|
||||
writeStateValue64(buffer.data + offset, palmSdCard.responseState);
|
||||
offset += sizeof(uint64_t);
|
||||
writeStateValue8(buffer.data + offset, palmSdCard.allowInvalidCrc);
|
||||
offset += sizeof(uint8_t);
|
||||
writeStateValue8(buffer.data + offset, palmSdCard.chipSelect);
|
||||
@@ -557,10 +553,6 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
offset += sizeof(uint64_t);
|
||||
palmSdCard.commandBitsRemaining = readStateValue8(buffer.data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
palmSdCard.response = readStateValue8(buffer.data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
palmSdCard.responseState = readStateValue64(buffer.data + offset);
|
||||
offset += sizeof(uint64_t);
|
||||
palmSdCard.allowInvalidCrc = readStateValue8(buffer.data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
palmSdCard.chipSelect = readStateValue8(buffer.data + offset);
|
||||
|
||||
@@ -39,6 +39,22 @@ void frontendHandleDebugPrint();
|
||||
static void debugLog(char* str, ...){};
|
||||
#endif
|
||||
|
||||
//config options
|
||||
#define EMU_FPS 60
|
||||
#define EMU_SYSCLK_PRECISION 2000000//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy
|
||||
#define EMU_CPU_PERCENT_WAITING 0.30//account for wait states when reading memory, tested with SysInfo.prc
|
||||
#define AUDIO_SAMPLE_RATE 48000
|
||||
#define AUDIO_CLOCK_RATE 235929600//smallest amount of time a second can be split into:(2.0 * (14.0 * (255 + 1.0) + 15 + 1.0)) * 32768 == 235929600, used to convert the variable timing of SYSCLK and CLK32 to a fixed location in the current frame 0<->AUDIO_END_OF_FRAME
|
||||
#define AUDIO_SPEAKER_RANGE 0x6000//prevent hitting the top or bottom of the speaker when switching direction rapidly
|
||||
#define SD_CARD_RESPONSE_FIFO_SIZE 10000
|
||||
#define SD_CARD_NCR_BYTES 1
|
||||
#define SAVE_STATE_VERSION 0
|
||||
|
||||
//system constants
|
||||
#define CRYSTAL_FREQUENCY 32768
|
||||
#define AUDIO_SAMPLES_PER_FRAME (AUDIO_SAMPLE_RATE / EMU_FPS)
|
||||
#define AUDIO_END_OF_FRAME (AUDIO_CLOCK_RATE / EMU_FPS)
|
||||
|
||||
//emu errors
|
||||
enum{
|
||||
EMU_ERROR_NONE = 0,
|
||||
@@ -88,9 +104,10 @@ typedef struct{
|
||||
typedef struct{
|
||||
uint64_t command;
|
||||
uint8_t commandBitsRemaining;
|
||||
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!!
|
||||
uint8_t responseFifo[SD_CARD_RESPONSE_FIFO_SIZE];//not in savestates yet!!
|
||||
uint16_t responseReadPosition;//not in savestates yet!!
|
||||
int8_t responseReadPositionBit;//not in savestates yet!!
|
||||
uint16_t responseWritePosition;//not in savestates yet!!
|
||||
bool commandIsAcmd;//not in savestates yet!!
|
||||
bool allowInvalidCrc;
|
||||
bool chipSelect;
|
||||
@@ -118,20 +135,6 @@ typedef struct{
|
||||
//uint32_t cmd;//one time use, has no variable
|
||||
}emu_reg_t;
|
||||
|
||||
//config options
|
||||
#define EMU_FPS 60
|
||||
#define EMU_SYSCLK_PRECISION 2000000//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy
|
||||
#define EMU_CPU_PERCENT_WAITING 0.30//account for wait states when reading memory, tested with SysInfo.prc
|
||||
#define AUDIO_SAMPLE_RATE 48000
|
||||
#define AUDIO_CLOCK_RATE 235929600//smallest amount of time a second can be split into:(2.0 * (14.0 * (255 + 1.0) + 15 + 1.0)) * 32768 == 235929600, used to convert the variable timing of SYSCLK and CLK32 to a fixed location in the current frame 0<->AUDIO_END_OF_FRAME
|
||||
#define AUDIO_SPEAKER_RANGE 0x6000//prevent hitting the top or bottom of the speaker when switching direction rapidly
|
||||
#define SAVE_STATE_VERSION 0
|
||||
|
||||
//system constants
|
||||
#define CRYSTAL_FREQUENCY 32768
|
||||
#define AUDIO_SAMPLES_PER_FRAME (AUDIO_SAMPLE_RATE / EMU_FPS)
|
||||
#define AUDIO_END_OF_FRAME (AUDIO_CLOCK_RATE / EMU_FPS)
|
||||
|
||||
//emulator data, some are GUI interface variables, some should be left alone
|
||||
extern uint8_t* palmRam;//access allowed to read save RAM without allocating a giant buffer, but endianness must be taken into account
|
||||
extern uint8_t* palmRom;//dont touch
|
||||
|
||||
@@ -43,7 +43,6 @@ static uint16_t spi1RxFifoRead(void){
|
||||
if(spi1RxFifoEntrys() > 0)
|
||||
spi1RxReadPosition = (spi1RxReadPosition + 1) % 9;
|
||||
spi1RxOverflowed = false;
|
||||
|
||||
return spi1RxFifo[spi1RxReadPosition];
|
||||
}
|
||||
|
||||
|
||||
@@ -175,8 +175,9 @@
|
||||
* operations.
|
||||
*/
|
||||
#define M68K_USE_64_BIT OPT_OFF
|
||||
//it seems MASK_OUT_ABOVE_32 is has to be called on every 32 bit operation when using this option,
|
||||
//possibly even making the speed worse than with just 32 bits
|
||||
/* It seems MASK_OUT_ABOVE_32 is has to be called on every 32 bit operation when using this option,
|
||||
* possibly even making the speed worse than with just 32 bits.
|
||||
*/
|
||||
|
||||
|
||||
/* Set to your compiler's static inline keyword to enable it, or
|
||||
|
||||
141
src/sdCard.c
141
src/sdCard.c
@@ -1,46 +1,38 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "emulator.h"
|
||||
#include "specs/sdCardCommandSpec.h"
|
||||
|
||||
|
||||
enum{
|
||||
SD_CARD_RESPONSE_NOTHING = 0,
|
||||
SD_CARD_RESPONSE_SHIFT_OUT,
|
||||
SD_CARD_RESPONSE_READ_BLOCK
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t sdCardCrc7Table[256] = {
|
||||
0x00,0x09,0x12,0x1B,0x24,0x2D,0x36,0x3F,0x48,0x41,0x5A,0x53,0x6C,0x65,0x7E,
|
||||
0x77,0x19,0x10,0x0B,0x02,0x3D,0x34,0x2F,0x26,0x51,0x58,0x43,0x4A,0x75,0x7C,
|
||||
0x67,0x6E,0x32,0x3B,0x20,0x29,0x16,0x1F,0x04,0x0D,0x7A,0x73,0x68,0x61,0x5E,
|
||||
0x57,0x4C,0x45,0x2B,0x22,0x39,0x30,0x0F,0x06,0x1D,0x14,0x63,0x6A,0x71,0x78,
|
||||
0x47,0x4E,0x55,0x5C,0x64,0x6D,0x76,0x7F,0x40,0x49,0x52,0x5B,0x2C,0x25,0x3E,
|
||||
0x37,0x08,0x01,0x1A,0x13,0x7D,0x74,0x6F,0x66,0x59,0x50,0x4B,0x42,0x35,0x3C,
|
||||
0x27,0x2E,0x11,0x18,0x03,0x0A,0x56,0x5F,0x44,0x4D,0x72,0x7B,0x60,0x69,0x1E,
|
||||
0x17,0x0C,0x05,0x3A,0x33,0x28,0x21,0x4F,0x46,0x5D,0x54,0x6B,0x62,0x79,0x70,
|
||||
0x07,0x0E,0x15,0x1C,0x23,0x2A,0x31,0x38,0x41,0x48,0x53,0x5A,0x65,0x6C,0x77,
|
||||
0x7E,0x09,0x00,0x1B,0x12,0x2D,0x24,0x3F,0x36,0x58,0x51,0x4A,0x43,0x7C,0x75,
|
||||
0x6E,0x67,0x10,0x19,0x02,0x0B,0x34,0x3D,0x26,0x2F,0x73,0x7A,0x61,0x68,0x57,
|
||||
0x5E,0x45,0x4C,0x3B,0x32,0x29,0x20,0x1F,0x16,0x0D,0x04,0x6A,0x63,0x78,0x71,
|
||||
0x4E,0x47,0x5C,0x55,0x22,0x2B,0x30,0x39,0x06,0x0F,0x14,0x1D,0x25,0x2C,0x37,
|
||||
0x3E,0x01,0x08,0x13,0x1A,0x6D,0x64,0x7F,0x76,0x49,0x40,0x5B,0x52,0x3C,0x35,
|
||||
0x2E,0x27,0x18,0x11,0x0A,0x03,0x74,0x7D,0x66,0x6F,0x50,0x59,0x42,0x4B,0x17,
|
||||
0x1E,0x05,0x0C,0x33,0x3A,0x21,0x28,0x5F,0x56,0x4D,0x44,0x7B,0x72,0x69,0x60,
|
||||
0x0E,0x07,0x1C,0x15,0x2A,0x23,0x38,0x31,0x46,0x4F,0x54,0x5D,0x62,0x6B,0x70,
|
||||
0x79
|
||||
0x00,0x09,0x12,0x1B,0x24,0x2D,0x36,0x3F,0x48,0x41,0x5A,0x53,0x6C,0x65,0x7E,0x77,
|
||||
0x19,0x10,0x0B,0x02,0x3D,0x34,0x2F,0x26,0x51,0x58,0x43,0x4A,0x75,0x7C,0x67,0x6E,
|
||||
0x32,0x3B,0x20,0x29,0x16,0x1F,0x04,0x0D,0x7A,0x73,0x68,0x61,0x5E,0x57,0x4C,0x45,
|
||||
0x2B,0x22,0x39,0x30,0x0F,0x06,0x1D,0x14,0x63,0x6A,0x71,0x78,0x47,0x4E,0x55,0x5C,
|
||||
0x64,0x6D,0x76,0x7F,0x40,0x49,0x52,0x5B,0x2C,0x25,0x3E,0x37,0x08,0x01,0x1A,0x13,
|
||||
0x7D,0x74,0x6F,0x66,0x59,0x50,0x4B,0x42,0x35,0x3C,0x27,0x2E,0x11,0x18,0x03,0x0A,
|
||||
0x56,0x5F,0x44,0x4D,0x72,0x7B,0x60,0x69,0x1E,0x17,0x0C,0x05,0x3A,0x33,0x28,0x21,
|
||||
0x4F,0x46,0x5D,0x54,0x6B,0x62,0x79,0x70,0x07,0x0E,0x15,0x1C,0x23,0x2A,0x31,0x38,
|
||||
0x41,0x48,0x53,0x5A,0x65,0x6C,0x77,0x7E,0x09,0x00,0x1B,0x12,0x2D,0x24,0x3F,0x36,
|
||||
0x58,0x51,0x4A,0x43,0x7C,0x75,0x6E,0x67,0x10,0x19,0x02,0x0B,0x34,0x3D,0x26,0x2F,
|
||||
0x73,0x7A,0x61,0x68,0x57,0x5E,0x45,0x4C,0x3B,0x32,0x29,0x20,0x1F,0x16,0x0D,0x04,
|
||||
0x6A,0x63,0x78,0x71,0x4E,0x47,0x5C,0x55,0x22,0x2B,0x30,0x39,0x06,0x0F,0x14,0x1D,
|
||||
0x25,0x2C,0x37,0x3E,0x01,0x08,0x13,0x1A,0x6D,0x64,0x7F,0x76,0x49,0x40,0x5B,0x52,
|
||||
0x3C,0x35,0x2E,0x27,0x18,0x11,0x0A,0x03,0x74,0x7D,0x66,0x6F,0x50,0x59,0x42,0x4B,
|
||||
0x17,0x1E,0x05,0x0C,0x33,0x3A,0x21,0x28,0x5F,0x56,0x4D,0x44,0x7B,0x72,0x69,0x60,
|
||||
0x0E,0x07,0x1C,0x15,0x2A,0x23,0x38,0x31,0x46,0x4F,0x54,0x5D,0x62,0x6B,0x70,0x79
|
||||
};
|
||||
static const uint64_t sdCardCsd[2] = {0x0000000000000000, 0x0000000000000000};
|
||||
static const uint64_t sdCardCid[2] = {0x0000000000000000, 0x0000000000000000};
|
||||
static const uint8_t sdCardCsd[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static const uint8_t sdCardCid[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
static uint32_t sdCardGetOcr(){
|
||||
return !palmSdCard.inIdleState << 31/*power up status*/ | 0 << 30/*card capacity status*/ | 0x01FF8000/*supported voltages*/;
|
||||
static uint32_t sdCardGetOcr(void){
|
||||
return palmSdCard.inIdleState << 31/*power up status*/ | 0 << 30/*card capacity status*/ | 0x01FF8000/*supported voltages*/;
|
||||
}
|
||||
|
||||
static void sdCardCmdStart(){
|
||||
static void sdCardCmdStart(void){
|
||||
palmSdCard.command = UINT64_C(0x0000000000000000);
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
palmSdCard.receivingCommand = true;
|
||||
@@ -50,7 +42,8 @@ static bool sdCardCmdIsCrcValid(uint8_t command, uint32_t argument, uint8_t crc)
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
uint8_t commandCrc = 0;
|
||||
|
||||
command |= 0x40;//add the 01 command starting sequence, not actually part of the command but its counted in the checksum
|
||||
//add the 01 command starting sequence, not actually part of the command but its counted in the checksum
|
||||
command |= 0x40;
|
||||
|
||||
commandCrc = sdCardCrc7Table[(commandCrc << 1) ^ command];
|
||||
commandCrc = sdCardCrc7Table[(commandCrc << 1) ^ (argument >> 24 & 0xFF)];
|
||||
@@ -65,27 +58,15 @@ static bool sdCardCmdIsCrcValid(uint8_t command, uint32_t argument, uint8_t crc)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void sdCardDoResponseR1(uint8_t r1){
|
||||
palmSdCard.response = SD_CARD_RESPONSE_SHIFT_OUT;
|
||||
palmSdCard.responseState = (uint64_t)r1 << 56;
|
||||
palmSdCard.responseState |= UINT64_C(1) << 55;//add shift termination bit
|
||||
palmSdCard.responseWaitBitsRemaining = 8;//needs to be at least 8 for MMC
|
||||
}
|
||||
|
||||
static void sdCardDoResponseR3(uint8_t r1){
|
||||
palmSdCard.response = SD_CARD_RESPONSE_SHIFT_OUT;
|
||||
palmSdCard.responseState = (uint64_t)r1 << 56;
|
||||
palmSdCard.responseState |= (uint64_t)sdCardGetOcr() << 24;
|
||||
palmSdCard.responseState |= UINT64_C(1) << 23;//add shift termination bit
|
||||
palmSdCard.responseWaitBitsRemaining = 8;//needs to be at least 8 for MMC
|
||||
}
|
||||
#include "sdCardAccessors.c.h"
|
||||
|
||||
void sdCardReset(void){
|
||||
palmSdCard.command = UINT64_C(0x0000000000000000);
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
palmSdCard.responseState = 0;
|
||||
palmSdCard.response = SD_CARD_RESPONSE_NOTHING;
|
||||
palmSdCard.responseWaitBitsRemaining = 0;
|
||||
memset(palmSdCard.responseFifo, 0x00, SD_CARD_RESPONSE_FIFO_SIZE);
|
||||
palmSdCard.responseReadPosition = 0;
|
||||
palmSdCard.responseWritePosition = 0;
|
||||
palmSdCard.responseReadPositionBit = 7;
|
||||
palmSdCard.commandIsAcmd = false;
|
||||
palmSdCard.allowInvalidCrc = false;
|
||||
palmSdCard.chipSelect = false;
|
||||
@@ -96,7 +77,7 @@ void sdCardReset(void){
|
||||
void sdCardSetChipSelect(bool value){
|
||||
if(value != palmSdCard.chipSelect){
|
||||
//debugLog("SD card chip select set to:%s\n", value ? "true" : "false");
|
||||
printf("C%s", value ? "T" : "F");
|
||||
//printf("C%s", value ? "T" : "F");
|
||||
|
||||
//commands start when chip select goes from high to low
|
||||
if(value == false)
|
||||
@@ -107,33 +88,11 @@ void sdCardSetChipSelect(bool value){
|
||||
}
|
||||
|
||||
bool sdCardExchangeBit(bool bit){
|
||||
bool sdCardOutputValue = true;//default output value is true, if an action is ongoing it will be set to the data provided by that action
|
||||
bool outputValue = true;//default output value is true, if an action is ongoing it will be set to the data provided by that action
|
||||
|
||||
//make sure SD is actually plugged in and chip select is low
|
||||
if(palmSdCard.flashChip.data && !palmSdCard.chipSelect){
|
||||
//idle wait for NCR
|
||||
if(palmSdCard.responseWaitBitsRemaining == 0){
|
||||
//process current exchange, needs to happen before command is proccessed because command response starts the next bit after the command is processed
|
||||
switch(palmSdCard.response){
|
||||
case SD_CARD_RESPONSE_NOTHING:
|
||||
break;
|
||||
|
||||
case SD_CARD_RESPONSE_SHIFT_OUT:
|
||||
//debugLog("SD shift out state:0x%016lX\n", palmSdCard.responseState);
|
||||
sdCardOutputValue = !!(palmSdCard.responseState & UINT64_C(0x8000000000000000));
|
||||
palmSdCard.responseState <<= 1;
|
||||
if(palmSdCard.responseState == UINT64_C(0x8000000000000000))
|
||||
palmSdCard.response = SD_CARD_RESPONSE_NOTHING;
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("SD exchange:%d\n", palmSdCard.response);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
palmSdCard.responseWaitBitsRemaining--;
|
||||
}
|
||||
outputValue = sdCardResponseFifoReadBit();
|
||||
|
||||
//route received bit as command or data
|
||||
if(palmSdCard.receivingCommand){
|
||||
@@ -170,9 +129,7 @@ bool sdCardExchangeBit(bool bit){
|
||||
uint8_t command = palmSdCard.command >> 40 & 0x3F;
|
||||
uint32_t argument = palmSdCard.command >> 8 & 0xFFFFFFFF;
|
||||
uint8_t crc = palmSdCard.command >> 1 & 0x7F;
|
||||
|
||||
//command finished, wait for next chip select toggle to start the next
|
||||
palmSdCard.receivingCommand = false;
|
||||
bool commandWantsData = false;
|
||||
|
||||
debugLog("SD command: isAcmd:%d, cmd:%d, arg:0x%08X, CRC:0x%02X\n", palmSdCard.commandIsAcmd, command, argument, crc);
|
||||
|
||||
@@ -187,19 +144,33 @@ bool sdCardExchangeBit(bool bit){
|
||||
break;
|
||||
|
||||
case SEND_OP_COND:
|
||||
//after this is run the SD card is initialized
|
||||
palmSdCard.inIdleState = false;
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
break;
|
||||
|
||||
case READ_OCR:
|
||||
sdCardDoResponseR3(palmSdCard.inIdleState);
|
||||
sdCardDoResponseR3R7(palmSdCard.inIdleState, sdCardGetOcr());
|
||||
break;
|
||||
|
||||
case SEND_CSD:
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
if(!palmSdCard.inIdleState){
|
||||
sdCardDoResponseDelay(1);
|
||||
sdCardDoResponseDataPacket(DATA_TOKEN_DEFAULT, sdCardCsd, 16);
|
||||
}
|
||||
break;
|
||||
|
||||
case SEND_CID:
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
if(!palmSdCard.inIdleState){
|
||||
sdCardDoResponseDelay(1);
|
||||
sdCardDoResponseDataPacket(DATA_TOKEN_DEFAULT, sdCardCid, 16);
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_CMD:
|
||||
printf("A");
|
||||
debugLog("SD response state: waitBits:%d, responseType:%d, stateBits:0x%016lX\n", palmSdCard.responseWaitBitsRemaining, palmSdCard.response, palmSdCard.responseState);
|
||||
palmSdCard.commandIsAcmd = true;
|
||||
sdCardCmdStart();
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
break;
|
||||
|
||||
@@ -213,7 +184,7 @@ bool sdCardExchangeBit(bool bit){
|
||||
//ACMD command
|
||||
switch(command){
|
||||
case APP_SEND_OP_COND:
|
||||
//after this is run the SD card is fully initialized
|
||||
//after this is run the SD card is initialized
|
||||
palmSdCard.inIdleState = false;
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
break;
|
||||
@@ -233,6 +204,12 @@ bool sdCardExchangeBit(bool bit){
|
||||
debugLog("SD invalid CRC\n");
|
||||
sdCardDoResponseR1(COMMAND_CRC_ERROR | palmSdCard.inIdleState);
|
||||
}
|
||||
|
||||
//start next command if previous doesnt take any data
|
||||
if(commandWantsData)
|
||||
palmSdCard.receivingCommand = false;
|
||||
else
|
||||
sdCardCmdStart();
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -243,5 +220,5 @@ bool sdCardExchangeBit(bool bit){
|
||||
}
|
||||
}
|
||||
|
||||
return sdCardOutputValue;
|
||||
return outputValue;
|
||||
}
|
||||
|
||||
69
src/sdCardAccessors.c.h
Normal file
69
src/sdCardAccessors.c.h
Normal file
@@ -0,0 +1,69 @@
|
||||
//FIFO accessors
|
||||
static uint16_t sdCardResponseFifoByteEntrys(void){
|
||||
//check for wraparound
|
||||
if(palmSdCard.responseWritePosition <palmSdCard.responseReadPosition)
|
||||
return palmSdCard.responseWritePosition + SD_CARD_RESPONSE_FIFO_SIZE - palmSdCard.responseReadPosition;
|
||||
return palmSdCard.responseWritePosition - palmSdCard.responseReadPosition;
|
||||
}
|
||||
|
||||
static bool sdCardResponseFifoReadBit(void){
|
||||
if(sdCardResponseFifoByteEntrys() > 0){
|
||||
bool bit = !!(palmSdCard.responseFifo[palmSdCard.responseReadPosition] & 1 << palmSdCard.responseReadPositionBit);
|
||||
palmSdCard.responseReadPositionBit--;
|
||||
if(palmSdCard.responseReadPositionBit < 0){
|
||||
palmSdCard.responseReadPositionBit = 7;
|
||||
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void sdCardResponseFifoWriteByte(uint8_t value){
|
||||
if(sdCardResponseFifoByteEntrys() < SD_CARD_RESPONSE_FIFO_SIZE - 1){
|
||||
palmSdCard.responseFifo[palmSdCard.responseWritePosition] = value;
|
||||
palmSdCard.responseWritePosition = (palmSdCard.responseWritePosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static void sdCardResponseFifoFlush(void){
|
||||
palmSdCard.responseReadPosition = palmSdCard.responseWritePosition;
|
||||
palmSdCard.responseReadPositionBit = 7;
|
||||
}
|
||||
|
||||
//basic responses
|
||||
static void sdCardDoResponseR1(uint8_t r1){
|
||||
uint8_t ncrByte = 0;
|
||||
for(ncrByte = 0; ncrByte < SD_CARD_NCR_BYTES; ncrByte++)
|
||||
sdCardResponseFifoWriteByte(0xFF);
|
||||
sdCardResponseFifoWriteByte(r1);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseR3R7(uint8_t r1, uint32_t value){
|
||||
sdCardDoResponseR1(r1);
|
||||
sdCardResponseFifoWriteByte(value >> 24);
|
||||
sdCardResponseFifoWriteByte(value >> 16 & 0xFF);
|
||||
sdCardResponseFifoWriteByte(value >> 8 & 0xFF);
|
||||
sdCardResponseFifoWriteByte(value & 0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseDataPacket(uint8_t token, uint8_t* location, uint16_t size){
|
||||
uint16_t crc16 = 0x0000;
|
||||
uint16_t offset;
|
||||
|
||||
sdCardResponseFifoWriteByte(token);
|
||||
|
||||
for(offset = 0; offset < size; offset++){
|
||||
sdCardResponseFifoWriteByte(token);
|
||||
//need to add byte to CRC16 here
|
||||
}
|
||||
|
||||
sdCardResponseFifoWriteByte(crc16 >> 8);
|
||||
sdCardResponseFifoWriteByte(crc16 & 0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseDelay(uint16_t bytes){
|
||||
uint16_t index;
|
||||
for(index = 0; index < bytes; index++)
|
||||
sdCardResponseFifoWriteByte(0xFF);
|
||||
}
|
||||
@@ -33,4 +33,9 @@
|
||||
#define ADDRESS_ERROR 0x20
|
||||
#define PARAMETER_ERROR 0x40
|
||||
|
||||
/*Data Transfer Tokens*/
|
||||
#define DATA_TOKEN_DEFAULT 0xFE
|
||||
#define DATA_TOKEN_CMD25 0xFC
|
||||
#define STOP_TRAN 0xFD
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user