mirror of
https://github.com/wiiu-env/libfat.git
synced 2024-11-01 08:15:05 +01:00
Moved the SD initialization to a common function
This commit is contained in:
parent
8ceb43c66c
commit
7b4d9b8d0a
@ -38,6 +38,9 @@
|
||||
|
||||
2006-08-05 - Chishm
|
||||
* Tries multiple times to get a Relative Card Address at startup
|
||||
|
||||
2006-08-07 - Chishm
|
||||
* Moved the SD initialization to a common function
|
||||
*/
|
||||
|
||||
#include "io_m3sd.h"
|
||||
@ -56,11 +59,10 @@
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Send / receive timeouts, to stop infinite wait loops
|
||||
#define MAX_STARTUP_TRIES 20 // Arbitrary value, check if the card is ready 20 times before giving up
|
||||
#define NUM_STARTUP_CLOCKS 100 // Number of empty (0xFF when sending) bytes to send/receive to/from the card
|
||||
#define TRANSMIT_TIMEOUT 2000 // Time to wait for the M3 to respond to transmit or receive requests
|
||||
#define TRANSMIT_TIMEOUT 20000 // Time to wait for the M3 to respond to transmit or receive requests
|
||||
#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up
|
||||
#define WRITE_TIMEOUT 300 // Time to wait for the card to finish writing
|
||||
#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Variables required for tracking SD state
|
||||
@ -236,10 +238,17 @@ static void _M3SD_getClocks (u32 numClocks) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool _M3SD_initCard (void) {
|
||||
int i;
|
||||
u8 responseBuffer[17]; // sizeof 17 to hold the maximum response size possible
|
||||
bool _M3SD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||
_M3SD_sendCommand (command, data);
|
||||
return _M3SD_getResponse (responseBuffer, 6);
|
||||
}
|
||||
|
||||
bool _M3SD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||
_M3SD_sendCommand (command, data);
|
||||
return _M3SD_getResponse (responseBuffer, 17);
|
||||
}
|
||||
|
||||
static bool _M3SD_initCard (void) {
|
||||
// Give the card time to stabilise
|
||||
_M3SD_sendClocks (NUM_STARTUP_CLOCKS);
|
||||
|
||||
@ -253,69 +262,11 @@ static bool _M3SD_initCard (void) {
|
||||
// Card is now reset, including it's address
|
||||
_M3SD_relativeCardAddress = 0;
|
||||
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
_M3SD_sendCommand (APP_CMD, 0);
|
||||
if (!_M3SD_getResponse_R1 (responseBuffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_M3SD_sendCommand (SD_APP_OP_COND, SD_OCR_VALUE);
|
||||
if ((_M3SD_getResponse_R3 (responseBuffer)) && ((responseBuffer[1] & 0x80) != 0)) {
|
||||
// Card is ready to receive commands now
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The card's name, as assigned by the manufacturer
|
||||
_M3SD_sendCommand (ALL_SEND_CID, 0);
|
||||
_M3SD_getResponse_R2 (responseBuffer);
|
||||
|
||||
// Get a new address
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
_M3SD_sendCommand (SEND_RELATIVE_ADDR, 0);
|
||||
_M3SD_getResponse_R6 (responseBuffer);
|
||||
_M3SD_relativeCardAddress = (responseBuffer[1] << 24) | (responseBuffer[2] << 16);
|
||||
if ((responseBuffer[3] & 0x1e) != (SD_STATE_STBY << 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some cards won't go to higher speeds unless they think you checked their capabilities
|
||||
_M3SD_sendCommand (SEND_CSD, _M3SD_relativeCardAddress);
|
||||
_M3SD_getResponse_R2 (responseBuffer);
|
||||
|
||||
// Only this card should respond to all future commands
|
||||
_M3SD_sendCommand (SELECT_CARD, _M3SD_relativeCardAddress);
|
||||
_M3SD_getResponse_R1 (responseBuffer);
|
||||
|
||||
// Set a 4 bit data bus
|
||||
_M3SD_sendCommand (APP_CMD, _M3SD_relativeCardAddress);
|
||||
_M3SD_getResponse_R1 (responseBuffer);
|
||||
|
||||
_M3SD_sendCommand (SET_BUS_WIDTH, 2);
|
||||
_M3SD_getResponse_R1 (responseBuffer);
|
||||
|
||||
// Use 512 byte blocks
|
||||
_M3SD_sendCommand (SET_BLOCKLEN, BYTES_PER_READ);
|
||||
_M3SD_getResponse_R1 (responseBuffer);
|
||||
|
||||
// Wait until card is ready for data
|
||||
i = 0;
|
||||
do {
|
||||
if (i >= RESPONSE_TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
_M3SD_sendCommand (SEND_STATUS, _M3SD_relativeCardAddress);
|
||||
} while ((!_M3SD_getResponse_R1 (responseBuffer)) && ((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA)));
|
||||
return true;
|
||||
// Init the card
|
||||
return _SD_InitCard (_M3SD_cmd_6byte_response,
|
||||
_M3SD_cmd_17byte_response,
|
||||
true,
|
||||
&_M3SD_relativeCardAddress);
|
||||
}
|
||||
|
||||
static bool _M3SD_readData (void* buffer) {
|
||||
|
@ -35,6 +35,9 @@
|
||||
2006-08-06 - Chishm
|
||||
* Removed unneeded _NJSD_writeRAM function
|
||||
* Removed casts for calls to cardWriteCommand
|
||||
|
||||
2006-08-07 - Chishm
|
||||
* Moved the SD initialization to a common function
|
||||
*/
|
||||
|
||||
#include "io_njsd.h"
|
||||
@ -46,7 +49,6 @@
|
||||
#include "io_sd_common.h"
|
||||
|
||||
#define _NJSD_SYNC
|
||||
// #define _NJSD_DEBUG
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Card communication speeds
|
||||
@ -64,11 +66,10 @@
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Send / receive timeouts, to stop infinite wait loops
|
||||
#define IRQ_TIMEOUT 100000
|
||||
#define RESET_TIMEOUT 1000
|
||||
#define COMMAND_TIMEOUT 10000
|
||||
#define MAX_STARTUP_TRIES 20 // Arbitrary value, check if the card is ready 20 times before giving up
|
||||
#define WRITE_TIMEOUT 300 // Time to wait for the card to finish writing
|
||||
#define IRQ_TIMEOUT 1000000
|
||||
#define RESET_TIMEOUT 10000
|
||||
#define COMMAND_TIMEOUT 100000
|
||||
#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing
|
||||
|
||||
|
||||
static const u8 _NJSD_read_cmd[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
|
||||
@ -191,13 +192,6 @@ static bool _NJSD_sendCMDR (int speed, u8 *rsp_buf, int type, u8 cmd, u32 param)
|
||||
i++;
|
||||
}
|
||||
} while (CARD_CR2 & CARD_BUSY);
|
||||
|
||||
#ifdef _NJSD_DEBUG
|
||||
iprintf ("r: ");
|
||||
for (i = 0; i < 6; i++)
|
||||
iprintf ("%02X ", rsp_buf[i]);
|
||||
iprintf ("\n");
|
||||
#endif
|
||||
} else {
|
||||
CARD_CR2 = _NJSD_cardFlags;
|
||||
while (CARD_CR2 & CARD_BUSY);
|
||||
@ -390,62 +384,32 @@ static bool _NJSD_sendCMDN (int speed, u8 cmd, u32 param) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _NJSD_cardInit (void) {
|
||||
u8 responseBuffer[17];
|
||||
int i;
|
||||
bool _NJSD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||
return _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, command, data);
|
||||
}
|
||||
|
||||
bool _NJSD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||
return _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_136, command, data);
|
||||
}
|
||||
|
||||
static bool _NJSD_cardInit (void) {
|
||||
// If the commands succeed the first time, assume they'll always succeed
|
||||
if (! _NJSD_sendCLK (SD_CLK_167KHz, 256) ) return false;
|
||||
if (! _NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0) ) return false;
|
||||
if (! _NJSD_sendCLK (SD_CLK_167KHz, 256) ) {
|
||||
return false;
|
||||
}
|
||||
if (! _NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0) ) {
|
||||
return false;
|
||||
}
|
||||
_NJSD_sendCLK (SD_CLK_167KHz, 8);
|
||||
|
||||
_NJSD_sendCLK (SD_CLK_167KHz, 256);
|
||||
_NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0);
|
||||
_NJSD_sendCLK (SD_CLK_167KHz, 8);
|
||||
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, APP_CMD, 0);
|
||||
if (
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SD_APP_OP_COND, SD_OCR_VALUE) &&
|
||||
((responseBuffer[1] & 0x80) != 0))
|
||||
{
|
||||
// Card is ready to receive commands now
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The card's name, as assigned by the manufacturer
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_136, ALL_SEND_CID, 0);
|
||||
|
||||
// Get a new address
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SEND_RELATIVE_ADDR, 0);
|
||||
_NJSD_relativeCardAddress = (responseBuffer[1] << 24) | (responseBuffer[2] << 16);
|
||||
if ((responseBuffer[3] & 0x1e) != (SD_STATE_STBY << 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some cards won't go to higher speeds unless they think you checked their capabilities
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_136, SEND_CSD, _NJSD_relativeCardAddress);
|
||||
|
||||
// Only this card should respond to all future commands
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SELECT_CARD, _NJSD_relativeCardAddress);
|
||||
|
||||
// Set a 4 bit data bus
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, APP_CMD, _NJSD_relativeCardAddress);
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SET_BUS_WIDTH, 2); // 4-bit mode.
|
||||
|
||||
// Use 512 byte blocks
|
||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SET_BLOCKLEN, 512); // 512 byte blocks
|
||||
|
||||
return true;
|
||||
return _SD_InitCard (_NJSD_cmd_6byte_response,
|
||||
_NJSD_cmd_17byte_response,
|
||||
true,
|
||||
&_NJSD_relativeCardAddress);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +39,9 @@
|
||||
|
||||
2006-08-05 - Chishm
|
||||
* Tries multiple times to get a Relative Card Address at startup
|
||||
|
||||
2006-08-07 - Chishm
|
||||
* Moved the SD initialization to a common function
|
||||
*/
|
||||
|
||||
#include "io_scsd.h"
|
||||
@ -66,12 +69,11 @@
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Send / receive timeouts, to stop infinite wait loops
|
||||
#define MAX_STARTUP_TRIES 20 // Arbitrary value, check if the card is ready 20 times before giving up
|
||||
#define NUM_STARTUP_CLOCKS 100 // Number of empty (0xFF when sending) bytes to send/receive to/from the card
|
||||
#define TRANSMIT_TIMEOUT 10000 // Time to wait for the SC to respond to transmit or receive requests
|
||||
#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 300 // Time to wait for the card to finish writing
|
||||
#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing
|
||||
//---------------------------------------------------------------
|
||||
// Variables required for tracking SD state
|
||||
static u32 _SCSD_relativeCardAddress = 0; // Preshifted Relative Card Address
|
||||
@ -81,8 +83,17 @@ static u32 _SCSD_relativeCardAddress = 0; // Preshifted Relative Card Address
|
||||
|
||||
extern bool _SCSD_writeData_s (u8 *data, u16* crc);
|
||||
|
||||
static inline void _SCSD_unlock (void) {
|
||||
static bool _SCSD_unlock (void) {
|
||||
//see if we can write to SCSD RAM
|
||||
vu32 *ramPointer = (u32*)0x08000000;
|
||||
_SC_changeMode (SC_MODE_RAM);
|
||||
*ramPointer = 0x5555aaaa;
|
||||
*ramPointer = ~*ramPointer;
|
||||
if(*ramPointer != 0xaaaa5555) {
|
||||
return false;
|
||||
}
|
||||
_SC_changeMode (SC_MODE_MEDIA);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _SCSD_sendCommand (u8 command, u32 argument) {
|
||||
@ -188,10 +199,18 @@ static void _SCSD_sendClocks (u32 numClocks) {
|
||||
} while (numClocks--);
|
||||
}
|
||||
|
||||
static bool _SCSD_initCard (void) {
|
||||
int i;
|
||||
u8 responseBuffer[17] = {0}; // sizeof 17 to hold the maximum response size possible
|
||||
bool _SCSD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||
_SCSD_sendCommand (command, data);
|
||||
return _SCSD_getResponse (responseBuffer, 6);
|
||||
}
|
||||
|
||||
bool _SCSD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||
_SCSD_sendCommand (command, data);
|
||||
return _SCSD_getResponse (responseBuffer, 17);
|
||||
}
|
||||
|
||||
|
||||
static bool _SCSD_initCard (void) {
|
||||
// Give the card time to stabilise
|
||||
_SCSD_sendClocks (NUM_STARTUP_CLOCKS);
|
||||
|
||||
@ -205,70 +224,11 @@ static bool _SCSD_initCard (void) {
|
||||
// Card is now reset, including it's address
|
||||
_SCSD_relativeCardAddress = 0;
|
||||
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
_SCSD_sendCommand (APP_CMD, 0);
|
||||
if (!_SCSD_getResponse_R1 (responseBuffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_SCSD_sendCommand (SD_APP_OP_COND, SD_OCR_VALUE);
|
||||
if ((_SCSD_getResponse_R3 (responseBuffer)) && ((responseBuffer[1] & 0x80) != 0)) {
|
||||
// Card is ready to receive commands now
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The card's name, as assigned by the manufacturer
|
||||
_SCSD_sendCommand (ALL_SEND_CID, 0);
|
||||
_SCSD_getResponse_R2 (responseBuffer);
|
||||
|
||||
// Get a new address
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
_SCSD_sendCommand (SEND_RELATIVE_ADDR, 0);
|
||||
_SCSD_getResponse_R6 (responseBuffer);
|
||||
_SCSD_relativeCardAddress = (responseBuffer[1] << 24) | (responseBuffer[2] << 16);
|
||||
if ((responseBuffer[3] & 0x1e) != (SD_STATE_STBY << 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some cards won't go to higher speeds unless they think you checked their capabilities
|
||||
_SCSD_sendCommand (SEND_CSD, _SCSD_relativeCardAddress);
|
||||
_SCSD_getResponse_R2 (responseBuffer);
|
||||
|
||||
// Only this card should respond to all future commands
|
||||
_SCSD_sendCommand (SELECT_CARD, _SCSD_relativeCardAddress);
|
||||
_SCSD_getResponse_R1 (responseBuffer);
|
||||
|
||||
// Set a 4 bit data bus
|
||||
_SCSD_sendCommand (APP_CMD, _SCSD_relativeCardAddress);
|
||||
_SCSD_getResponse_R1 (responseBuffer);
|
||||
|
||||
_SCSD_sendCommand (SET_BUS_WIDTH, 2);
|
||||
_SCSD_getResponse_R1 (responseBuffer);
|
||||
|
||||
// Use 512 byte blocks
|
||||
_SCSD_sendCommand (SET_BLOCKLEN, BYTES_PER_READ);
|
||||
_SCSD_getResponse_R1 (responseBuffer);
|
||||
|
||||
// Wait until card is ready for data
|
||||
i = 0;
|
||||
do {
|
||||
if (i >= RESPONSE_TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
_SCSD_sendCommand (SEND_STATUS, _SCSD_relativeCardAddress);
|
||||
} while ((!_SCSD_getResponse_R1 (responseBuffer)) && ((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA)));
|
||||
|
||||
return true;
|
||||
// Init the card
|
||||
return _SD_InitCard (_SCSD_cmd_6byte_response,
|
||||
_SCSD_cmd_17byte_response,
|
||||
true,
|
||||
&_SCSD_relativeCardAddress);
|
||||
}
|
||||
|
||||
static bool _SCSD_readData (void* buffer) {
|
||||
@ -313,7 +273,9 @@ static bool _SCSD_readData (void* buffer) {
|
||||
// Functions needed for the external interface
|
||||
|
||||
bool _SCSD_startUp (void) {
|
||||
_SCSD_unlock();
|
||||
if (!_SCSD_unlock()) {
|
||||
return false;
|
||||
}
|
||||
return _SCSD_initCard();
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,17 @@
|
||||
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-08-07 - Chishm
|
||||
* Moved the SD initialization to a common function
|
||||
* Increased timeouts for slower cards
|
||||
*/
|
||||
|
||||
#include "io_sd_common.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
|
||||
|
||||
/*
|
||||
Improved CRC7 function provided by cory1492
|
||||
Calculates the CRC of an SD command, and includes the end bit in the byte
|
||||
@ -122,3 +129,75 @@ void _SD_CRC16 (u8* buff, int buffLength, u8* crc16buff) {
|
||||
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.
|
||||
*/
|
||||
bool _SD_InitCard (_SD_FN_CMD_6BYTE_RESPONSE cmd_6byte_response,
|
||||
_SD_FN_CMD_17BYTE_RESPONSE cmd_17byte_response,
|
||||
bool use4bitBus,
|
||||
u32 *RCA)
|
||||
{
|
||||
u8 responseBuffer[17] = {0};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
||||
cmd_6byte_response (responseBuffer, APP_CMD, 0);
|
||||
if (
|
||||
cmd_6byte_response (responseBuffer, SD_APP_OP_COND, SD_OCR_VALUE) &&
|
||||
((responseBuffer[1] & 0x80) != 0))
|
||||
{
|
||||
// Card is ready to receive commands now
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_STARTUP_TRIES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,8 @@
|
||||
|
||||
/* 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 0x003F8000 /* 2.7V to 3.4V */
|
||||
#define SD_OCR_VALUE 0x00FC0000
|
||||
|
||||
/* SD Data repsonses */
|
||||
#define SD_CARD_BUSY 0xff
|
||||
@ -95,5 +96,19 @@ 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 (_SD_FN_CMD_6BYTE_RESPONSE cmd_6byte_response,
|
||||
_SD_FN_CMD_17BYTE_RESPONSE cmd_17byte_response,
|
||||
bool use4bitBus,
|
||||
u32 *RCA);
|
||||
|
||||
#endif // define IO_SD_COMMON_H
|
||||
|
Loading…
Reference in New Issue
Block a user