mirror of
https://github.com/ApacheThunder/SCKILL.git
synced 2025-06-18 19:15:53 -04:00
Initial SDHC support, files open but breaks directories (credit to ausar)
This commit is contained in:
parent
378b8d8f16
commit
551332d5b1
@ -10,6 +10,8 @@
|
||||
#include "Save.h"
|
||||
#include "WhiteScreenPatch.h"
|
||||
|
||||
#include "my_io_scsd.h"
|
||||
|
||||
char *stpcpy(char*, char*);
|
||||
|
||||
void tryAgain() {
|
||||
@ -411,7 +413,8 @@ int main() {
|
||||
|
||||
iprintf("SCFW Kernel v0.3.3 GBA-mode\n\n");
|
||||
|
||||
if (fatInitDefault()) {
|
||||
_my_io_scsd.startup();
|
||||
if (fatMountSimple("fat", &_my_io_scsd)) {
|
||||
iprintf("FAT system initialised\n");
|
||||
} else {
|
||||
iprintf("FAT initialisation failed!\n");
|
||||
|
47
SCFW_Kernel_GBA/source/my_io_sc_common.c
Normal file
47
SCFW_Kernel_GBA/source/my_io_sc_common.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
io_m3_common.h
|
||||
|
||||
Routines common to all version of the Super Card
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "my_io_sc_common.h"
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
_SC_changeMode (was SC_Unlock)
|
||||
Added by MightyMax
|
||||
Modified by Chishm
|
||||
Modified again by loopy
|
||||
1=ram(readonly), 5=ram, 3=SD interface?
|
||||
-----------------------------------------------------------------*/
|
||||
void _SC_changeMode(u8 mode) {
|
||||
vu16 *unlockAddress = (vu16*)0x09FFFFFE;
|
||||
*unlockAddress = 0xA55A ;
|
||||
*unlockAddress = 0xA55A ;
|
||||
*unlockAddress = mode ;
|
||||
*unlockAddress = mode ;
|
||||
}
|
||||
|
||||
|
43
SCFW_Kernel_GBA/source/my_io_sc_common.h
Normal file
43
SCFW_Kernel_GBA/source/my_io_sc_common.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
io_sc_common.h
|
||||
|
||||
Routines common to all version of the Super Card
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_SC_COMMON_H
|
||||
#define IO_SC_COMMON_H
|
||||
|
||||
#include <disc_io.h>
|
||||
|
||||
// Values for changing mode
|
||||
#define SC_MODE_FLASH 0x1510
|
||||
#define SC_MODE_RAM 0x5
|
||||
#define SC_MODE_MEDIA 0x3
|
||||
#define SC_MODE_RAM_RO 0x1
|
||||
|
||||
extern void _SC_changeMode (u8 mode);
|
||||
|
||||
#endif // IO_SC_COMMON_H
|
423
SCFW_Kernel_GBA/source/my_io_scsd.c
Normal file
423
SCFW_Kernel_GBA/source/my_io_scsd.c
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
io_scsd.c
|
||||
|
||||
Hardware Routines for reading a Secure Digital card
|
||||
using the SC SD
|
||||
|
||||
Some code based on scsd_c.c, written by Amadeus
|
||||
and Jean-Pierre Thomasset as part of DSLinux.
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "my_io_scsd.h"
|
||||
#include "my_io_sd_common.h"
|
||||
#include "my_io_sc_common.h"
|
||||
|
||||
#define printf(...)
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// SCSD register addresses
|
||||
#define REG_SCSD_CMD (*(vu16*)(0x09800000))
|
||||
/* bit 0: command bit to read */
|
||||
/* bit 7: command bit to write */
|
||||
|
||||
#define REG_SCSD_DATAWRITE (*(vu16*)(0x09000000))
|
||||
#define REG_SCSD_DATAREAD (*(vu16*)(0x09100000))
|
||||
#define REG_SCSD_DATAREAD_32 (*(vu32*)(0x09100000))
|
||||
#define REG_SCSD_LITE_ENABLE (*(vu16*)(0x09440000))
|
||||
#define REG_SCSD_LOCK (*(vu16*)(0x09FFFFFE))
|
||||
/* bit 0: 1 */
|
||||
/* bit 1: enable IO interface (SD,CF) */
|
||||
/* bit 2: enable R/W SDRAM access */
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Responses
|
||||
#define SCSD_STS_BUSY 0x100
|
||||
#define SCSD_STS_INSERTED 0x300
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Send / receive timeouts, to stop infinite wait loops
|
||||
#define NUM_STARTUP_CLOCKS 100 // Number of empty (0xFF when sending) bytes to send/receive to/from the card
|
||||
#define TRANSMIT_TIMEOUT 100000 // Time to wait for the SC to respond to transmit or receive requests
|
||||
#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up
|
||||
#define BUSY_WAIT_TIMEOUT 500000
|
||||
#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing
|
||||
|
||||
#define BYTES_PER_READ 512
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Variables required for tracking SD state
|
||||
u32 _SCSD_relativeCardAddress = 0; // Preshifted Relative Card Address
|
||||
bool isSDHC;
|
||||
//---------------------------------------------------------------
|
||||
// Internal SC SD functions
|
||||
|
||||
extern bool _SCSD_writeData_s (u8 *data, u16* crc);
|
||||
|
||||
void _SCSD_unlock (void) {
|
||||
_SC_changeMode (SC_MODE_MEDIA);
|
||||
}
|
||||
|
||||
void _SCSD_enable_lite (void) {
|
||||
REG_SCSD_LITE_ENABLE = 0;
|
||||
}
|
||||
|
||||
bool _SCSD_sendCommand (u8 command, u32 argument) {
|
||||
u8 databuff[6]; //SD卡的命令是6个字节
|
||||
u8 *tempDataPtr = databuff;
|
||||
int length = 6;
|
||||
u16 dataByte;
|
||||
int curBit;
|
||||
int i;
|
||||
|
||||
*tempDataPtr++ = command | 0x40; //Byte1:最高位为01,剩下的6bit是command
|
||||
*tempDataPtr++ = argument>>24;
|
||||
*tempDataPtr++ = argument>>16;
|
||||
*tempDataPtr++ = argument>>8;
|
||||
*tempDataPtr++ = argument; //剩下的4byte是命令
|
||||
*tempDataPtr = _SD_CRC7 (databuff, 5); //最后的是进行CRC的校验
|
||||
|
||||
i = BUSY_WAIT_TIMEOUT;
|
||||
while (((REG_SCSD_CMD & 0x01) == 0) && (--i));
|
||||
if (i == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dataByte = REG_SCSD_CMD;
|
||||
|
||||
tempDataPtr = databuff;
|
||||
|
||||
while (length--) {
|
||||
dataByte = *tempDataPtr++;
|
||||
for (curBit = 7; curBit >=0; curBit--){//#7bit,也就是第8位是用来输出的,不断移位输出
|
||||
REG_SCSD_CMD = dataByte;
|
||||
dataByte = dataByte << 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the response from the SD card to a previous command.
|
||||
bool _SCSD_getResponse (u8* dest, u32 length) {
|
||||
u32 i;
|
||||
int dataByte;
|
||||
int numBits = length * 8;
|
||||
|
||||
// Wait for the card to be non-busy
|
||||
i = BUSY_WAIT_TIMEOUT;
|
||||
while (((REG_SCSD_CMD & 0x01) != 0) && (--i));
|
||||
if (dest == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
// Still busy after the timeout has passed
|
||||
return false;
|
||||
}
|
||||
|
||||
// The first bit is always 0
|
||||
dataByte = 0;
|
||||
numBits--;
|
||||
// Read the remaining bits in the response.
|
||||
// It's always most significant bit first
|
||||
while (numBits--) {
|
||||
dataByte = (dataByte << 1) | (REG_SCSD_CMD & 0x01);
|
||||
if ((numBits & 0x7) == 0) {
|
||||
// It's read a whole byte, so store it
|
||||
*dest++ = (u8)dataByte;
|
||||
dataByte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 16 more clocks, 8 more than the delay required between a response and the next command
|
||||
for (i = 0; i < 16; i++) {
|
||||
dataByte = REG_SCSD_CMD;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool _SCSD_getResponse_R1 (u8* dest) {
|
||||
return _SCSD_getResponse (dest, 6);
|
||||
}
|
||||
|
||||
inline bool _SCSD_getResponse_R1b (u8* dest) {
|
||||
return _SCSD_getResponse (dest, 6);
|
||||
}
|
||||
|
||||
inline bool _SCSD_getResponse_R2 (u8* dest) {
|
||||
return _SCSD_getResponse (dest, 17);
|
||||
}
|
||||
|
||||
inline bool _SCSD_getResponse_R3 (u8* dest) {
|
||||
return _SCSD_getResponse (dest, 6);
|
||||
}
|
||||
|
||||
inline bool _SCSD_getResponse_R6 (u8* dest) {
|
||||
return _SCSD_getResponse (dest, 6);
|
||||
}
|
||||
|
||||
void _SCSD_sendClocks (u32 numClocks) {
|
||||
do {
|
||||
REG_SCSD_CMD;
|
||||
} while (numClocks--);
|
||||
}
|
||||
|
||||
bool _SCSD_cmd_6byte_response_my (u8* responseBuffer, u8 command, u32 data) {
|
||||
_SCSD_sendCommand (command, data);
|
||||
return _SCSD_getResponse (responseBuffer, 6);
|
||||
}
|
||||
|
||||
bool _SCSD_cmd_17byte_response_my (u8* responseBuffer, u8 command, u32 data) {
|
||||
_SCSD_sendCommand (command, data);
|
||||
return _SCSD_getResponse (responseBuffer, 17);
|
||||
}
|
||||
|
||||
|
||||
bool _SCSD_initCard (void) {
|
||||
_SCSD_enable_lite();
|
||||
|
||||
// Give the card time to stabilise
|
||||
_SCSD_sendClocks (NUM_STARTUP_CLOCKS);
|
||||
|
||||
// Reset the card
|
||||
if (!_SCSD_sendCommand (GO_IDLE_STATE, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_SCSD_sendClocks (NUM_STARTUP_CLOCKS);
|
||||
|
||||
// Card is now reset, including it's address
|
||||
_SCSD_relativeCardAddress = 0;
|
||||
|
||||
// Init the card
|
||||
return _SD_InitCard_SDHC (_SCSD_cmd_6byte_response_my,
|
||||
_SCSD_cmd_17byte_response_my,
|
||||
true,
|
||||
&_SCSD_relativeCardAddress,&isSDHC);
|
||||
}
|
||||
|
||||
bool _SCSD_readData (void* buffer) {
|
||||
u8* buff_u8 = (u8*)buffer;
|
||||
u16* buff = (u16*)buffer;
|
||||
volatile register u32 temp;
|
||||
int i;
|
||||
|
||||
i = BUSY_WAIT_TIMEOUT;
|
||||
while ((REG_SCSD_DATAREAD & SCSD_STS_BUSY) && (--i));
|
||||
if (i == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
i=256;
|
||||
if ((u32)buff_u8 & 0x01) {
|
||||
while(i--) {
|
||||
temp = REG_SCSD_DATAREAD_32;
|
||||
temp = REG_SCSD_DATAREAD_32 >> 16;
|
||||
*buff_u8++ = (u8)temp;
|
||||
*buff_u8++ = (u8)(temp >> 8);
|
||||
}
|
||||
} else {
|
||||
while(i--) {
|
||||
temp = REG_SCSD_DATAREAD_32;
|
||||
temp = REG_SCSD_DATAREAD_32 >> 16;
|
||||
*buff++ = temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
temp = REG_SCSD_DATAREAD_32;
|
||||
}
|
||||
|
||||
temp = REG_SCSD_DATAREAD;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Functions needed for the external interface
|
||||
|
||||
bool _SCSD_startUp_my (void) {
|
||||
//printf("Starting _SCSD_startUp_my...\n");
|
||||
|
||||
_SCSD_unlock();
|
||||
//printf("Unlocked in _SCSD_startUp_my.\n");
|
||||
|
||||
bool initResult = _SCSD_initCard();
|
||||
//printf("Init card in _SCSD_startUp_my returned %d.\n", initResult);
|
||||
|
||||
return initResult;
|
||||
}
|
||||
|
||||
|
||||
bool _SCSD_isInserted_my (void) {
|
||||
//printf("Starting _SCSD_isInserted_my...\n");
|
||||
|
||||
u8 responseBuffer[6];
|
||||
|
||||
if (!_SCSD_sendCommand(SEND_STATUS, 0)) {
|
||||
//printf("Failed to send command in _SCSD_isInserted_my.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_SCSD_getResponse_R1(responseBuffer)) {
|
||||
//printf("Failed to get response in _SCSD_isInserted_my.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (responseBuffer[0] != SEND_STATUS) {
|
||||
//printf("Incorrect response in _SCSD_isInserted_my: Expected %d, got %d\n", SEND_STATUS, responseBuffer[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
//printf("Successful execution of _SCSD_isInserted_my.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool _SCSD_readSectors_my (u32 sector, u32 numSectors, void* buffer) {
|
||||
//printf("Starting _SCSD_readSectors_my with sector %u and numSectors %u.\n", sector, numSectors);
|
||||
|
||||
u32 i;
|
||||
u8* dest = (u8*) buffer;
|
||||
u8 responseBuffer[6];
|
||||
u32 argument = isSDHC ? sector : sector * BYTES_PER_READ;
|
||||
if (numSectors == 1) {
|
||||
//printf("Reading single sector.\n");
|
||||
if (!_SCSD_sendCommand(READ_SINGLE_BLOCK, argument)) {
|
||||
//printf("Failed to send READ_SINGLE_BLOCK command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_SCSD_readData(buffer)) {
|
||||
//printf("Failed to read data for single sector.\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//printf("Reading multiple sectors.\n");
|
||||
if (!_SCSD_sendCommand(READ_MULTIPLE_BLOCK, argument)) {
|
||||
//printf("Failed to send READ_MULTIPLE_BLOCK command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < numSectors; i++, dest += BYTES_PER_READ) {
|
||||
if (!_SCSD_readData(dest)) {
|
||||
//printf("Failed to read data at sector %u.\n", i + sector);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("Stopping transmission after multiple sectors.\n");
|
||||
_SCSD_sendCommand(STOP_TRANSMISSION, 0);
|
||||
_SCSD_getResponse_R1b(responseBuffer);
|
||||
}
|
||||
|
||||
_SCSD_sendClocks(64);
|
||||
//printf("Completed _SCSD_readSectors_my.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool _SCSD_writeSectors_my (u32 sector, u32 numSectors, const void* buffer) {
|
||||
//printf("Starting _SCSD_writeSectors_my with sector %u and numSectors %u.\n", sector, numSectors);
|
||||
|
||||
u16 crc[4];
|
||||
u8 responseBuffer[6];
|
||||
u32 offset = isSDHC ? sector : sector * BYTES_PER_READ;
|
||||
u8* data = (u8*) buffer;
|
||||
int i;
|
||||
|
||||
while (numSectors--) {
|
||||
//printf("Writing sector at offset %u.\n", offset);
|
||||
|
||||
_SD_CRC16(data, BYTES_PER_READ, (u8*)crc);
|
||||
|
||||
_SCSD_sendCommand(WRITE_BLOCK, offset);
|
||||
if (!_SCSD_getResponse_R1(responseBuffer)) {
|
||||
//printf("Failed to get response after WRITE_BLOCK command.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_SCSD_writeData_s(data, crc)) {
|
||||
//printf("Failed to write data and CRC.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_SCSD_sendClocks(64);
|
||||
|
||||
offset += BYTES_PER_READ;
|
||||
data += BYTES_PER_READ;
|
||||
|
||||
i = WRITE_TIMEOUT;
|
||||
do {
|
||||
_SCSD_sendCommand(SEND_STATUS, _SCSD_relativeCardAddress);
|
||||
if (!_SCSD_getResponse_R1(responseBuffer) || i-- <= 0) {
|
||||
//printf("Timeout or error during write confirmation.\n");
|
||||
return false;
|
||||
}
|
||||
} while (((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA)));
|
||||
|
||||
//printf("Sector at offset %u written successfully.\n", offset - BYTES_PER_READ);
|
||||
}
|
||||
|
||||
//printf("Completed _SCSD_writeSectors_my.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool _SCSD_clearStatus_my (void) {
|
||||
//printf("Starting _SCSD_clearStatus_my...\n");
|
||||
|
||||
bool initResult = _SCSD_initCard();
|
||||
//printf("Initialization in _SCSD_clearStatus_my returned %d.\n", initResult);
|
||||
|
||||
return initResult;
|
||||
}
|
||||
|
||||
|
||||
bool _SCSD_shutdown_my (void) {
|
||||
//printf("Starting _SCSD_shutdown_my...\n");
|
||||
|
||||
_SC_changeMode(SC_MODE_RAM_RO);
|
||||
//printf("Changed mode to SC_MODE_RAM_RO in _SCSD_shutdown_my.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const DISC_INTERFACE _my_io_scsd = {
|
||||
DEVICE_TYPE_SCSD,
|
||||
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
|
||||
(FN_MEDIUM_STARTUP)&_SCSD_startUp_my,
|
||||
(FN_MEDIUM_ISINSERTED)&_SCSD_isInserted_my,
|
||||
(FN_MEDIUM_READSECTORS)&_SCSD_readSectors_my,
|
||||
(FN_MEDIUM_WRITESECTORS)&_SCSD_writeSectors_my,
|
||||
(FN_MEDIUM_CLEARSTATUS)&_SCSD_clearStatus_my,
|
||||
(FN_MEDIUM_SHUTDOWN)&_SCSD_shutdown_my
|
||||
} ;
|
||||
|
||||
|
48
SCFW_Kernel_GBA/source/my_io_scsd.h
Normal file
48
SCFW_Kernel_GBA/source/my_io_scsd.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
io_scsd.h
|
||||
|
||||
Hardware Routines for reading a Secure Digital card
|
||||
using the Supercard SD
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
2006-07-11 - Chishm
|
||||
* Original release
|
||||
|
||||
2006-07-22 - Chishm
|
||||
* First release of stable code
|
||||
*/
|
||||
|
||||
#ifndef IO_SCSD_H
|
||||
#define IO_SCSD_H
|
||||
|
||||
// 'SCSD'
|
||||
#define DEVICE_TYPE_SCSD 0x44534353
|
||||
|
||||
#include <disc_io.h>
|
||||
|
||||
// export interface
|
||||
extern const DISC_INTERFACE _my_io_scsd ;
|
||||
|
||||
#endif // define IO_SCSD_H
|
139
SCFW_Kernel_GBA/source/my_io_scsd_s.s
Normal file
139
SCFW_Kernel_GBA/source/my_io_scsd_s.s
Normal file
@ -0,0 +1,139 @@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ io_scsd_s.s
|
||||
@
|
||||
@ Hardware Routines for reading a Secure Digital card
|
||||
@ using the SC SD
|
||||
@
|
||||
@ Based on code supplied by Romman
|
||||
@
|
||||
@ Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
@
|
||||
@ Redistribution and use in source and binary forms, with or without modification,
|
||||
@ are permitted provided that the following conditions are met:
|
||||
@
|
||||
@ 1. Redistributions of source code must retain the above copyright notice,
|
||||
@ this list of conditions and the following disclaimer.
|
||||
@ 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
@ this list of conditions and the following disclaimer in the documentation and/or
|
||||
@ other materials provided with the distribution.
|
||||
@ 3. The name of the author may not be used to endorse or promote products derived
|
||||
@ from this software without specific prior written permission.
|
||||
@
|
||||
@ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
@ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
@ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
@ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@
|
||||
@ 2006-07-22 - Chishm
|
||||
@ * First release of stable code
|
||||
@
|
||||
@ 2006-08-19 - Chishm
|
||||
@ * Added SuperCard Lite support
|
||||
@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
.align 4
|
||||
.arm
|
||||
|
||||
.equ REG_SCSD_DATAWRITE, 0x09000000
|
||||
.equ BYTES_PER_READ, 0x200
|
||||
.equ SCSD_STS_BUSY, 0x100
|
||||
.equ BUSY_WAIT_TIMEOUT, 0x10000
|
||||
.equ FALSE, 0
|
||||
.equ TRUE, 1
|
||||
|
||||
@ bool _SCSD_writeData_s (u8 *data, u16* crc)
|
||||
|
||||
.global _SCSD_writeData_s
|
||||
|
||||
_SCSD_writeData_s:
|
||||
stmfd r13!, {r4-r5}
|
||||
mov r5, #BYTES_PER_READ
|
||||
mov r2, #REG_SCSD_DATAWRITE
|
||||
|
||||
@ Wait for a free data buffer on the SD card
|
||||
mov r4, #BUSY_WAIT_TIMEOUT
|
||||
_SCSD_writeData_busy_wait:
|
||||
@ Test for timeout
|
||||
subs r4, r4, #1
|
||||
moveq r0, #FALSE @ return false on failure
|
||||
beq _SCSD_writeData_return
|
||||
@ Check the busy bit of the status register
|
||||
ldrh r3, [r2]
|
||||
tst r3, #SCSD_STS_BUSY
|
||||
beq _SCSD_writeData_busy_wait
|
||||
|
||||
ldrh r3, [r2] @ extra clock
|
||||
|
||||
mov r3, #0 @ start bit
|
||||
strh r3,[r2]
|
||||
|
||||
@ Check if the data buffer is aligned on a halfword boundary
|
||||
tst r0, #1
|
||||
beq _SCSD_writeData_data_loop
|
||||
|
||||
@ Used when the source data is unaligned
|
||||
_SCSD_writeData_data_loop_unaligned:
|
||||
ldrb r3, [r0], #1
|
||||
ldrb r4, [r0], #1
|
||||
orr r3, r3, r4, lsl #8
|
||||
stmia r2, {r3-r4}
|
||||
subs r5, r5, #2
|
||||
bne _SCSD_writeData_data_loop_unaligned
|
||||
b _SCSD_writeData_crc
|
||||
|
||||
@ Write the data to the card
|
||||
@ 4 halfwords are transmitted to the Supercard at once, for timing purposes
|
||||
@ Only the first halfword needs to contain data for standard SuperCards
|
||||
@ For the SuperCard Lite, the data is split into 4 nibbles, one per halfword
|
||||
_SCSD_writeData_data_loop:
|
||||
ldrh r3, [r0], #2
|
||||
|
||||
@ This bit added for SCLite. Notice that the shift is not the same as in
|
||||
@ the original (buggy) code supplied by Romman
|
||||
add r3, r3, r3, lsl #20
|
||||
mov r4, r3, lsr #8
|
||||
|
||||
stmia r2, {r3-r4}
|
||||
|
||||
subs r5, r5, #2
|
||||
bne _SCSD_writeData_data_loop
|
||||
|
||||
@ Send the data CRC
|
||||
_SCSD_writeData_crc:
|
||||
cmp r1, #0
|
||||
movne r0, r1
|
||||
movne r1, #0
|
||||
movne r5, #8
|
||||
bne _SCSD_writeData_data_loop
|
||||
|
||||
mov r3, #0xff @ end bit
|
||||
strh r3, [r2]
|
||||
|
||||
@ Wait for the SD card to signal that it is finished recieving
|
||||
mov r4, #BUSY_WAIT_TIMEOUT
|
||||
_SCSD_writeData_finished_wait:
|
||||
@ Test for timeout
|
||||
subs r4, r4, #1
|
||||
moveq r0, #FALSE @ return false on failure
|
||||
beq _SCSD_writeData_return
|
||||
@ Check the busy bit of the status register
|
||||
ldrh r3, [r2]
|
||||
tst r3, #0x100
|
||||
bne _SCSD_writeData_finished_wait
|
||||
|
||||
@ Send 8 more clocks, as required by the SD card
|
||||
ldmia r2, {r3-r4}
|
||||
|
||||
@ return true for success
|
||||
mov r0, #TRUE
|
||||
|
||||
_SCSD_writeData_return:
|
||||
ldmfd r13!,{r4-r5}
|
||||
bx r14
|
||||
|
248
SCFW_Kernel_GBA/source/my_io_sd_common.c
Normal file
248
SCFW_Kernel_GBA/source/my_io_sd_common.c
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
io_sd_common.c
|
||||
|
||||
By chishm (Michael Chisholm)
|
||||
|
||||
Common SD card routines
|
||||
|
||||
SD routines partially based on sd.s by Romman
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "my_io_sd_common.h"
|
||||
|
||||
#include <gba_console.h>
|
||||
#define MAX_STARTUP_TRIES 1000 // Arbitrary value, check if the card is ready 20 times before giving up
|
||||
#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up
|
||||
|
||||
#define iprintf(...)
|
||||
|
||||
/*
|
||||
Improved CRC7 function provided by cory1492
|
||||
Calculates the CRC of an SD command, and includes the end bit in the byte
|
||||
*/
|
||||
u8 _SD_CRC7_my(u8* data, int cnt) {
|
||||
int i, a;
|
||||
u8 crc, temp;
|
||||
|
||||
crc = 0;
|
||||
for (a = 0; a < cnt; a++)
|
||||
{
|
||||
temp = data[a];
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
crc <<= 1;
|
||||
if ((temp & 0x80) ^ (crc & 0x80)) crc ^= 0x09;
|
||||
temp <<= 1;
|
||||
}
|
||||
}
|
||||
crc = (crc << 1) | 1;
|
||||
return(crc);
|
||||
}
|
||||
|
||||
/*
|
||||
Calculates the CRC16 for a sector of data. Calculates it
|
||||
as 4 separate lots, merged into one buffer. This is used
|
||||
for 4 SD data lines, not for 1 data line alone.
|
||||
*/
|
||||
void _SD_CRC16_my (u8* buff, int buffLength, u8* crc16buff) {
|
||||
u32 a, b, c, d;
|
||||
int count;
|
||||
u32 bitPattern = 0x80808080; // r7
|
||||
u32 crcConst = 0x1021; // r8
|
||||
u32 dataByte = 0; // r2
|
||||
|
||||
a = 0; // r3
|
||||
b = 0; // r4
|
||||
c = 0; // r5
|
||||
d = 0; // r6
|
||||
|
||||
buffLength = buffLength * 8;
|
||||
|
||||
|
||||
do {
|
||||
if (bitPattern & 0x80) dataByte = *buff++;
|
||||
|
||||
a = a << 1;
|
||||
if ( a & 0x10000) a ^= crcConst;
|
||||
if (dataByte & (bitPattern >> 24)) a ^= crcConst;
|
||||
|
||||
b = b << 1;
|
||||
if (b & 0x10000) b ^= crcConst;
|
||||
if (dataByte & (bitPattern >> 25)) b ^= crcConst;
|
||||
|
||||
c = c << 1;
|
||||
if (c & 0x10000) c ^= crcConst;
|
||||
if (dataByte & (bitPattern >> 26)) c ^= crcConst;
|
||||
|
||||
d = d << 1;
|
||||
if (d & 0x10000) d ^= crcConst;
|
||||
if (dataByte & (bitPattern >> 27)) d ^= crcConst;
|
||||
|
||||
bitPattern = (bitPattern >> 4) | (bitPattern << 28);
|
||||
} while (buffLength-=4);
|
||||
|
||||
count = 16; // r8
|
||||
|
||||
do {
|
||||
bitPattern = bitPattern << 4;
|
||||
if (a & 0x8000) bitPattern |= 8;
|
||||
if (b & 0x8000) bitPattern |= 4;
|
||||
if (c & 0x8000) bitPattern |= 2;
|
||||
if (d & 0x8000) bitPattern |= 1;
|
||||
|
||||
a = a << 1;
|
||||
b = b << 1;
|
||||
c = c << 1;
|
||||
d = d << 1;
|
||||
|
||||
count--;
|
||||
|
||||
if (!(count & 0x01)) {
|
||||
*crc16buff++ = (u8)(bitPattern & 0xff);
|
||||
}
|
||||
} while (count != 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Initialise the SD card, after it has been sent into an Idle state
|
||||
cmd_6byte_response: a pointer to a function that sends the SD card a command and gets a 6 byte response
|
||||
cmd_17byte_response: a pointer to a function that sends the SD card a command and gets a 17 byte response
|
||||
use4bitBus: initialise card to use a 4 bit data bus when communicating with the card
|
||||
RCA: a pointer to the location to store the card's Relative Card Address, preshifted up by 16 bits.
|
||||
*/
|
||||
|
||||
#define CMD8 8
|
||||
#define CMD58 58
|
||||
#define R1_ILLEGAL_COMMAND 0x04
|
||||
bool _SD_InitCard_SDHC (_SD_FN_CMD_6BYTE_RESPONSE cmd_6byte_response,
|
||||
_SD_FN_CMD_17BYTE_RESPONSE cmd_17byte_response,
|
||||
bool use4bitBus,
|
||||
u32 *RCA,bool *isSDHC)
|
||||
{
|
||||
u8 responseBuffer[17] = {0};
|
||||
int i;
|
||||
|
||||
*isSDHC = false;
|
||||
|
||||
bool cmd8Response = cmd_17byte_response(responseBuffer, CMD8, 0x1AA);//0xa 是确定的 0xAA是推荐值
|
||||
|
||||
|
||||
iprintf("\n");
|
||||
//CMD8 也就是 Send Interface Condition Command
|
||||
//正确的回显是:CMD8,Ver=0,Reserved=0,EchoBack=1,EchoBack=0XAA
|
||||
if (cmd8Response && responseBuffer[0] == CMD8 && responseBuffer[1] == 0 && responseBuffer[2] == 0 && responseBuffer[3] == 0x1 && responseBuffer[4] == 0xAA) {
|
||||
*isSDHC = true;
|
||||
iprintf("CMD8 Return OK,might be a SDHC\n");
|
||||
}else{
|
||||
iprintf("CMD8 ERR not SDHC\n");
|
||||
iprintf("resp:");
|
||||
for(int i=0;i<17;i++){
|
||||
iprintf("[%d]=%X ",i,responseBuffer[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STARTUP_TRIES; i++) {
|
||||
cmd_6byte_response(responseBuffer, APP_CMD, 0);//CMD55
|
||||
if (responseBuffer[0] != APP_CMD) {
|
||||
iprintf("Failed to send APP_CMD\n"); //进入到APP模式,可以执行ACMD41
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 arg = SD_OCR_VALUE;
|
||||
if (*isSDHC) {
|
||||
arg |= (1<<30); // Set HCS bit,Supports SDHC
|
||||
arg |= (1<<28); //Max performance
|
||||
}
|
||||
|
||||
if (cmd_6byte_response(responseBuffer, SD_APP_OP_COND, arg) &&//ACMD41
|
||||
((responseBuffer[1] & (1<<7)) != 0)/*Busy:0b:initing 1b:init completed*/) {
|
||||
iprintf("ACMD41 accepted init completed\n");
|
||||
break; // Card is ready
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
if (isSDHC) {
|
||||
cmd_6byte_response(responseBuffer, CMD58, 0);
|
||||
iprintf("CMD58 response received\n");
|
||||
// u32 ocr = (responseBuffer[1] << 24) | (responseBuffer[2] << 16) |
|
||||
// (responseBuffer[3] << 8) | responseBuffer[4];
|
||||
if ((responseBuffer[1] & (1<<6)) == 0) {//Card Capacity Status (CCS)
|
||||
iprintf("CMD58 OCR ERROR!! Not SDHC\n\n");
|
||||
*isSDHC = false;
|
||||
}else{
|
||||
iprintf("OCR OK! Is SDHC\n");
|
||||
}
|
||||
// Further processing of OCR can be done here if needed
|
||||
}
|
||||
|
||||
// The card's name, as assigned by the manufacturer
|
||||
cmd_17byte_response (responseBuffer, ALL_SEND_CID, 0);
|
||||
|
||||
// Get a new address
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
cmd_6byte_response (responseBuffer, SEND_RELATIVE_ADDR, 0);
|
||||
*RCA = (responseBuffer[1] << 24) | (responseBuffer[2] << 16);
|
||||
if ((responseBuffer[3] & 0x1e) != (SD_STATE_STBY << 1)) {
|
||||
iprintf("RCA set\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some cards won't go to higher speeds unless they think you checked their capabilities
|
||||
cmd_17byte_response (responseBuffer, SEND_CSD, *RCA);
|
||||
|
||||
// Only this card should respond to all future commands
|
||||
cmd_6byte_response (responseBuffer, SELECT_CARD, *RCA);
|
||||
|
||||
if (use4bitBus) {
|
||||
// Set a 4 bit data bus
|
||||
cmd_6byte_response (responseBuffer, APP_CMD, *RCA);
|
||||
cmd_6byte_response (responseBuffer, SET_BUS_WIDTH, 2); // 4-bit mode.
|
||||
}
|
||||
|
||||
// Use 512 byte blocks
|
||||
cmd_6byte_response (responseBuffer, SET_BLOCKLEN, 512); // 512 byte blocks
|
||||
|
||||
// Wait until card is ready for data
|
||||
i = 0;
|
||||
do {
|
||||
if (i >= RESPONSE_TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
} while (!cmd_6byte_response (responseBuffer, SEND_STATUS, *RCA) && ((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
116
SCFW_Kernel_GBA/source/my_io_sd_common.h
Normal file
116
SCFW_Kernel_GBA/source/my_io_sd_common.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
io_sd_common.h
|
||||
|
||||
By chishm (Michael Chisholm)
|
||||
|
||||
Common SD card routines
|
||||
|
||||
SD routines partially based on sd.s by Romman
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_SD_COMMON_H
|
||||
#define IO_SD_COMMON_H
|
||||
|
||||
#include <disc_io.h>
|
||||
|
||||
/* SD commands */
|
||||
#define GO_IDLE_STATE 0
|
||||
#define ALL_SEND_CID 2
|
||||
#define SEND_RELATIVE_ADDR 3
|
||||
#define SELECT_CARD 7
|
||||
#define SEND_CSD 9
|
||||
#define STOP_TRANSMISSION 12
|
||||
#define SEND_STATUS 13
|
||||
#define GO_INACTIVE_STATE 15
|
||||
#define SET_BLOCKLEN 16
|
||||
#define READ_SINGLE_BLOCK 17
|
||||
#define READ_MULTIPLE_BLOCK 18
|
||||
#define WRITE_BLOCK 24
|
||||
#define WRITE_MULTIPLE_BLOCK 25
|
||||
#define APP_CMD 55
|
||||
#define CMD8 8
|
||||
#define CMD58 58
|
||||
|
||||
/* SD App commands */
|
||||
#define SET_BUS_WIDTH 6
|
||||
#define SD_APP_OP_COND 41
|
||||
|
||||
/* OCR (Operating Conditions Register) send value */
|
||||
#define SD_OCR_VALUE 0x00030000 /* 2.8V to 3.0V */
|
||||
//#define SD_OCR_VALUE 0x003F8000 /* 2.7V to 3.4V */
|
||||
//#define SD_OCR_VALUE 0x00FC0000
|
||||
|
||||
/* SD Data repsonses */
|
||||
#define SD_CARD_BUSY 0xff
|
||||
|
||||
/* SD states */
|
||||
#define SD_STATE_IDLE 0 // Idle state, after power on or GO_IDLE_STATE command
|
||||
#define SD_STATE_READY 1 // Ready state, after card replies non-busy to SD_APP_OP_COND
|
||||
#define SD_STATE_IDENT 2 // Identification state, after ALL_SEND_CID
|
||||
#define SD_STATE_STBY 3 // Standby state, when card is deselected
|
||||
#define SD_STATE_TRAN 4 // Transfer state, after card is selected and ready for data transfer
|
||||
#define SD_STATE_DATA 5 //
|
||||
#define SD_STATE_RCV 6 // Receive data state
|
||||
#define SD_STATE_PRG 7 // Programming state
|
||||
#define SD_STATE_DIS 8 // Disconnect state
|
||||
#define SD_STATE_INA 9 // Inactive state, after GO_INACTIVE_STATE
|
||||
|
||||
#define READY_FOR_DATA 1 // bit 8 in card status
|
||||
|
||||
|
||||
|
||||
///Mod:
|
||||
#define R1_ILLEGAL_COMMAND 0x04
|
||||
|
||||
|
||||
/*
|
||||
Calculate the CRC7 of a command and return it preshifted with
|
||||
an end bit added
|
||||
*/
|
||||
extern u8 _SD_CRC7(u8* data, int size);
|
||||
|
||||
/*
|
||||
Calculate the CRC16 of a block of data, ready for transmission on
|
||||
four data lines at once
|
||||
*/
|
||||
extern void _SD_CRC16 (u8* buff, int buffLength, u8* crc16buff);
|
||||
|
||||
typedef bool (*_SD_FN_CMD_6BYTE_RESPONSE) (u8* responseBuffer, u8 command, u32 data);
|
||||
typedef bool (*_SD_FN_CMD_17BYTE_RESPONSE) (u8* responseBuffer, u8 command, u32 data);
|
||||
|
||||
/*
|
||||
Initialise the SD card, after it has been sent into an Idle state
|
||||
cmd_6byte_response: a pointer to a function that sends the SD card a command and gets a 6 byte response
|
||||
cmd_17byte_response: a pointer to a function that sends the SD card a command and gets a 17 byte response
|
||||
use4bitBus: initialise card to use a 4 bit data bus when communicating with the card
|
||||
RCA: a pointer to the location to store the card's Relative Card Address, preshifted up by 16 bits.
|
||||
*/
|
||||
extern bool _SD_InitCard_SDHC (_SD_FN_CMD_6BYTE_RESPONSE cmd_6byte_response,
|
||||
_SD_FN_CMD_17BYTE_RESPONSE cmd_17byte_response,
|
||||
bool use4bitBus,
|
||||
u32 *RCA,bool *isSDHC);
|
||||
|
||||
#endif // define IO_SD_COMMON_H
|
Loading…
Reference in New Issue
Block a user