mirror of
https://github.com/libretro/Mu.git
synced 2026-09-22 22:56:12 +00:00
Try to get SD card multiblock read working, its still not though
This commit is contained in:
@@ -11,7 +11,6 @@ Setting the battery dead bit(PDDATA 0x80) if the emulated battery percent gets t
|
||||
DRAMC write enable
|
||||
Port M Infrared shutdown (PMDATA 0x20)
|
||||
some undocumented I/O might be on port e and port j
|
||||
SPI1(the SD card interface)
|
||||
SPITEST SSTATUS is undocumented and therefore unemulated
|
||||
When SPICLK2, SPITXD or SPIRXD on port e is disabled ADS7846 functions should respond appropriately(not transmitting or receiving or blocking both for the clock)
|
||||
REFREQ clock frequency in RTCCTL should slow down the RTC when enabled
|
||||
@@ -30,7 +29,6 @@ sound plays too long when the category's menu is selected on the home screen and
|
||||
ARM CPU state isn't saved
|
||||
|
||||
Memory:
|
||||
SD card can't be read or written to by Palm OS
|
||||
unknown if DRAM bit expanded address space is used for CSC when its not an extension of CSD
|
||||
there is conflicting information on whether the DRAM bit effects CSC, needs a test made
|
||||
the unemulated chip selects(CSB1, CSC0/1) privilege violation interrupts are not handled properly
|
||||
@@ -40,12 +38,16 @@ swivelview register
|
||||
|
||||
ADS7846:
|
||||
verify chip select(no test has been done yet, but everything points to port g bit 2)
|
||||
need to trigger a false PENIRQ interrupt on reading certain channels
|
||||
electrical noise on lines(conversions probably should have +-20 added to values)(probably no need for this, it works so theres no need to use less precise values)
|
||||
in the edge case that SPICLK2 is disabled while using ADS7846 and a 1 was the last bit shifted out 0s will still be shifted in
|
||||
need to to verify behavior of differential mode bit
|
||||
|
||||
SD Card:
|
||||
need to dump valid SCR
|
||||
block length is fixed at 512 right now
|
||||
data blocks won't work properly when CRC checks are enabled
|
||||
the CRC of CSD and CID are invalid
|
||||
SEND_SCR may not be sending in the proper format(the return data format was not specified in the spec I read)
|
||||
IRQ2 may actually be attached to the SD Card data out pin, triggering an interrupt when a 0 is received to process the return data
|
||||
need to test if Port J Pin 3(SD card chip select) is attached to Port D Pin 5(SD Card Status(IRQ2))(pinouts.ru says chip select and card detect are the same line)
|
||||
|
||||
@@ -56,6 +58,9 @@ MakePalmBitmap:
|
||||
|
||||
|
||||
Fixed:
|
||||
SPI1(the SD card interface)(SPI1 master mode seems fully implemented now)
|
||||
SD card can't be read or written to by Palm OS(SPI transactions are going both ways now, some flash chip read commands are implemented too)
|
||||
(ADS7846)need to trigger a false PENIRQ interrupt on reading certain channels(this is being done now)
|
||||
(MakePalmBitmap)the small icons are corrupt
|
||||
(MakePalmBitmap)the non 16 bpp large icons are corrupt
|
||||
need to test if Port J Pin 3(SD card chip select) is attached to Port D Pin 5(SD Card Status(IRQ2))(pinouts.ru says chip select and card detect are the same line)(IRQ2 doesnt change when SD card chip select is toggled regardless of wether the card is inserted)
|
||||
|
||||
@@ -47,7 +47,9 @@ static void debugLog(char* str, ...){};
|
||||
#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 SD_CARD_NCR_BYTES 1//how many 0xFF bytes come before the R1 response
|
||||
#define SD_CARD_READ_DELAY_BYTES 1//how many 0xFF bytes come before the data packet
|
||||
#define SD_CARD_WRITE_DELAY_BYTES 1
|
||||
#define SAVE_STATE_VERSION 0
|
||||
|
||||
//system constants
|
||||
@@ -104,6 +106,8 @@ typedef struct{
|
||||
typedef struct{
|
||||
uint64_t command;
|
||||
uint8_t commandBitsRemaining;
|
||||
uint8_t runningCommand;//not in savestates yet!!
|
||||
uint64_t runningCommandState;//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!!
|
||||
|
||||
84
src/sdCard.c
84
src/sdCard.c
@@ -6,6 +6,9 @@
|
||||
#include "specs/sdCardCommandSpec.h"
|
||||
|
||||
|
||||
#define SD_CARD_MAX_DATA_PACKET_SIZE (1 + 2048 + 2)
|
||||
|
||||
|
||||
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,
|
||||
@@ -28,7 +31,9 @@ static const uint8_t sdCardCrc7Table[256] = {
|
||||
//register data is from a "ULTRA SD HI-SPEED 1GB", thats actually the name of the card these IDs are from
|
||||
static const uint8_t sdCardCsd[16] = {0x00, 0x2F, 0x00, 0x32, 0x5F, 0x59, 0x83, 0xB8, 0x6D, 0xB7, 0xFF, 0x9F, 0x96, 0x40, 0x00, 0x00};//CRC7 is invalid here
|
||||
static const uint8_t sdCardCid[16] = {0x1D, 0x41, 0x44, 0x53, 0x44, 0x20, 0x20, 0x20, 0x10, 0xA0, 0x50, 0x33, 0xA4, 0x00, 0x81, 0x00};//CRC7 is invalid here
|
||||
static const uint8_t sdCardScr[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//need to dump this one
|
||||
static const uint8_t sdCardScr[8] = {0x01, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//dont know it this needs a CRC7 or not?
|
||||
static const uint8_t sdCardDsr[2] = {0x04, 0x04};
|
||||
//static const uint8_t sdCardRca[2] = {0x??, 0x??};//not available in SPI mode
|
||||
|
||||
static uint32_t sdCardGetOcr(void){
|
||||
return palmSdCard.inIdleState << 31/*power up status*/ | 0 << 30/*card capacity status*/ | 0x01FF8000/*supported voltages*/;
|
||||
@@ -65,6 +70,8 @@ static bool sdCardCmdIsCrcValid(uint8_t command, uint32_t argument, uint8_t crc)
|
||||
void sdCardReset(void){
|
||||
palmSdCard.command = UINT64_C(0x0000000000000000);
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
palmSdCard.runningCommand = 0x00;
|
||||
palmSdCard.runningCommandState = UINT64_C(0x0000000000000000);
|
||||
memset(palmSdCard.responseFifo, 0x00, SD_CARD_RESPONSE_FIFO_SIZE);
|
||||
palmSdCard.responseReadPosition = 0;
|
||||
palmSdCard.responseWritePosition = 0;
|
||||
@@ -95,8 +102,31 @@ bool sdCardExchangeBit(bool bit){
|
||||
|
||||
//make sure SD is actually plugged in and chip select is low
|
||||
if(palmSdCard.flashChip.data && !palmSdCard.chipSelect){
|
||||
//get output value first
|
||||
outputValue = sdCardResponseFifoReadBit();
|
||||
|
||||
//if running a continuous command check if it needs servicing
|
||||
if(!palmSdCard.inIdleState){
|
||||
switch(palmSdCard.runningCommand){
|
||||
case READ_MULTIPLE_BLOCK:
|
||||
if(sdCardResponseFifoByteEntrys() < palmSdCard.blockLength){
|
||||
//sdCardDoResponseDelay(1);//packets may have no delay in between
|
||||
if(palmSdCard.runningCommandState * palmSdCard.blockLength < palmSdCard.flashChip.size){
|
||||
sdCardDoResponseDataPacket(DATA_TOKEN_DEFAULT, palmSdCard.flashChip.data[palmSdCard.runningCommandState * palmSdCard.blockLength], palmSdCard.blockLength);
|
||||
palmSdCard.runningCommandState++;
|
||||
}
|
||||
else{
|
||||
sdCardDoResponseErrorToken(ET_OUT_OF_RANGE);
|
||||
palmSdCard.runningCommand = 0x00;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//route received bit as command or data
|
||||
if(palmSdCard.receivingCommand){
|
||||
//receiving a command
|
||||
@@ -173,9 +203,16 @@ bool sdCardExchangeBit(bool bit){
|
||||
break;
|
||||
|
||||
case SET_BLOCKLEN:
|
||||
if(!palmSdCard.inIdleState)
|
||||
palmSdCard.blockLength = argument;
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
if(!palmSdCard.inIdleState){
|
||||
//eventually may want to support other block lengths
|
||||
if(argument == 512)
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
else
|
||||
sdCardDoResponseR1(PARAMETER_ERROR | palmSdCard.inIdleState);
|
||||
}
|
||||
else{
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_CMD:
|
||||
@@ -183,15 +220,14 @@ bool sdCardExchangeBit(bool bit){
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
break;
|
||||
|
||||
case READ_SINGLE_BLOCK:
|
||||
case STOP_TRANSMISSION:
|
||||
if(!palmSdCard.inIdleState){
|
||||
if(argument * palmSdCard.blockLength < palmSdCard.flashChip.size){
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
if(palmSdCard.runningCommand == READ_MULTIPLE_BLOCK){
|
||||
palmSdCard.runningCommand = 0x00;
|
||||
sdCardResponseFifoFlush();
|
||||
sdCardDoResponseDelay(1);
|
||||
sdCardDoResponseDataPacket(DATA_TOKEN_DEFAULT, palmSdCard.flashChip.data[argument * palmSdCard.blockLength], palmSdCard.blockLength);
|
||||
}
|
||||
else{
|
||||
sdCardDoResponseR1(ADDRESS_ERROR | palmSdCard.inIdleState);
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
sdCardDoResponseBusy(1);
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -199,6 +235,32 @@ bool sdCardExchangeBit(bool bit){
|
||||
}
|
||||
break;
|
||||
|
||||
case READ_SINGLE_BLOCK:
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
if(!palmSdCard.inIdleState){
|
||||
sdCardDoResponseDelay(1);
|
||||
if(argument * palmSdCard.blockLength < palmSdCard.flashChip.size)
|
||||
sdCardDoResponseDataPacket(DATA_TOKEN_DEFAULT, palmSdCard.flashChip.data[argument * palmSdCard.blockLength], palmSdCard.blockLength);
|
||||
else
|
||||
sdCardDoResponseErrorToken(ET_OUT_OF_RANGE);
|
||||
}
|
||||
break;
|
||||
|
||||
case READ_MULTIPLE_BLOCK:
|
||||
sdCardDoResponseR1(palmSdCard.inIdleState);
|
||||
if(!palmSdCard.inIdleState){
|
||||
sdCardDoResponseDelay(1);
|
||||
if(argument * palmSdCard.blockLength < palmSdCard.flashChip.size){
|
||||
sdCardDoResponseDataPacket(DATA_TOKEN_DEFAULT, palmSdCard.flashChip.data[argument * palmSdCard.blockLength], palmSdCard.blockLength);
|
||||
palmSdCard.runningCommand = READ_MULTIPLE_BLOCK;
|
||||
palmSdCard.runningCommandState = argument + 1;
|
||||
}
|
||||
else{
|
||||
sdCardDoResponseErrorToken(ET_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("SD unknown command: cmd:%d, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
|
||||
sdCardDoResponseR1(ILLEGAL_COMMAND | palmSdCard.inIdleState);
|
||||
|
||||
@@ -68,8 +68,18 @@ static void sdCardDoResponseDataPacket(uint8_t token, uint8_t* location, uint16_
|
||||
sdCardResponseFifoWriteByte(crc16 & 0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseErrorToken(uint8_t token){
|
||||
sdCardResponseFifoWriteByte(token);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseDelay(uint16_t bytes){
|
||||
uint16_t index;
|
||||
for(index = 0; index < bytes; index++)
|
||||
sdCardResponseFifoWriteByte(0xFF);
|
||||
}
|
||||
|
||||
static void sdCardDoResponseBusy(uint16_t bytes){
|
||||
uint16_t index;
|
||||
for(index = 0; index < bytes; index++)
|
||||
sdCardResponseFifoWriteByte(0x00);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
#define ADDRESS_ERROR 0x20
|
||||
#define PARAMETER_ERROR 0x40
|
||||
|
||||
/*Error Token Bits*/
|
||||
#define ET_ERROR 0x01
|
||||
#define ET_CC_ERROR 0x02
|
||||
#define ET_CARD_ECC_FAILED 0x04
|
||||
#define ET_OUT_OF_RANGE 0x08
|
||||
#define ET_CARD_IS_LOCKED 0x10
|
||||
|
||||
/*Data Transfer Tokens*/
|
||||
#define DATA_TOKEN_DEFAULT 0xFE
|
||||
#define DATA_TOKEN_CMD25 0xFC
|
||||
|
||||
Reference in New Issue
Block a user