mirror of
https://github.com/wiiu-env/libfat.git
synced 2024-11-26 03:44:15 +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
|
2006-08-05 - Chishm
|
||||||
* Tries multiple times to get a Relative Card Address at startup
|
* 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"
|
#include "io_m3sd.h"
|
||||||
@ -56,11 +59,10 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Send / receive timeouts, to stop infinite wait loops
|
// 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 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 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
|
// Variables required for tracking SD state
|
||||||
@ -236,10 +238,17 @@ static void _M3SD_getClocks (u32 numClocks) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _M3SD_initCard (void) {
|
bool _M3SD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||||
int i;
|
_M3SD_sendCommand (command, data);
|
||||||
u8 responseBuffer[17]; // sizeof 17 to hold the maximum response size possible
|
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
|
// Give the card time to stabilise
|
||||||
_M3SD_sendClocks (NUM_STARTUP_CLOCKS);
|
_M3SD_sendClocks (NUM_STARTUP_CLOCKS);
|
||||||
|
|
||||||
@ -253,69 +262,11 @@ static bool _M3SD_initCard (void) {
|
|||||||
// Card is now reset, including it's address
|
// Card is now reset, including it's address
|
||||||
_M3SD_relativeCardAddress = 0;
|
_M3SD_relativeCardAddress = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
// Init the card
|
||||||
_M3SD_sendCommand (APP_CMD, 0);
|
return _SD_InitCard (_M3SD_cmd_6byte_response,
|
||||||
if (!_M3SD_getResponse_R1 (responseBuffer)) {
|
_M3SD_cmd_17byte_response,
|
||||||
return false;
|
true,
|
||||||
}
|
&_M3SD_relativeCardAddress);
|
||||||
|
|
||||||
_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _M3SD_readData (void* buffer) {
|
static bool _M3SD_readData (void* buffer) {
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
2006-08-06 - Chishm
|
2006-08-06 - Chishm
|
||||||
* Removed unneeded _NJSD_writeRAM function
|
* Removed unneeded _NJSD_writeRAM function
|
||||||
* Removed casts for calls to cardWriteCommand
|
* Removed casts for calls to cardWriteCommand
|
||||||
|
|
||||||
|
2006-08-07 - Chishm
|
||||||
|
* Moved the SD initialization to a common function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "io_njsd.h"
|
#include "io_njsd.h"
|
||||||
@ -46,7 +49,6 @@
|
|||||||
#include "io_sd_common.h"
|
#include "io_sd_common.h"
|
||||||
|
|
||||||
#define _NJSD_SYNC
|
#define _NJSD_SYNC
|
||||||
// #define _NJSD_DEBUG
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Card communication speeds
|
// Card communication speeds
|
||||||
@ -64,11 +66,10 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Send / receive timeouts, to stop infinite wait loops
|
// Send / receive timeouts, to stop infinite wait loops
|
||||||
#define IRQ_TIMEOUT 100000
|
#define IRQ_TIMEOUT 1000000
|
||||||
#define RESET_TIMEOUT 1000
|
#define RESET_TIMEOUT 10000
|
||||||
#define COMMAND_TIMEOUT 10000
|
#define COMMAND_TIMEOUT 100000
|
||||||
#define MAX_STARTUP_TRIES 20 // Arbitrary value, check if the card is ready 20 times before giving up
|
#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing
|
||||||
#define WRITE_TIMEOUT 300 // Time to wait for the card to finish writing
|
|
||||||
|
|
||||||
|
|
||||||
static const u8 _NJSD_read_cmd[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
} while (CARD_CR2 & CARD_BUSY);
|
} 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 {
|
} else {
|
||||||
CARD_CR2 = _NJSD_cardFlags;
|
CARD_CR2 = _NJSD_cardFlags;
|
||||||
while (CARD_CR2 & CARD_BUSY);
|
while (CARD_CR2 & CARD_BUSY);
|
||||||
@ -390,62 +384,32 @@ static bool _NJSD_sendCMDN (int speed, u8 cmd, u32 param) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _NJSD_cardInit (void) {
|
bool _NJSD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||||
u8 responseBuffer[17];
|
return _NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, command, data);
|
||||||
int i;
|
}
|
||||||
|
|
||||||
|
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 the commands succeed the first time, assume they'll always succeed
|
||||||
if (! _NJSD_sendCLK (SD_CLK_167KHz, 256) ) return false;
|
if (! _NJSD_sendCLK (SD_CLK_167KHz, 256) ) {
|
||||||
if (! _NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0) ) return false;
|
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, 8);
|
||||||
|
|
||||||
_NJSD_sendCLK (SD_CLK_167KHz, 256);
|
_NJSD_sendCLK (SD_CLK_167KHz, 256);
|
||||||
_NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0);
|
_NJSD_sendCMDN (SD_CLK_167KHz, GO_IDLE_STATE, 0);
|
||||||
_NJSD_sendCLK (SD_CLK_167KHz, 8);
|
_NJSD_sendCLK (SD_CLK_167KHz, 8);
|
||||||
|
|
||||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
return _SD_InitCard (_NJSD_cmd_6byte_response,
|
||||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, APP_CMD, 0);
|
_NJSD_cmd_17byte_response,
|
||||||
if (
|
true,
|
||||||
_NJSD_sendCMDR (SD_CLK_167KHz, responseBuffer, SD_RSP_48, SD_APP_OP_COND, SD_OCR_VALUE) &&
|
&_NJSD_relativeCardAddress);
|
||||||
((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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
|
|
||||||
2006-08-05 - Chishm
|
2006-08-05 - Chishm
|
||||||
* Tries multiple times to get a Relative Card Address at startup
|
* 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"
|
#include "io_scsd.h"
|
||||||
@ -66,12 +69,11 @@
|
|||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Send / receive timeouts, to stop infinite wait loops
|
// 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 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 RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up
|
||||||
#define BUSY_WAIT_TIMEOUT 500000
|
#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
|
// Variables required for tracking SD state
|
||||||
static u32 _SCSD_relativeCardAddress = 0; // Preshifted Relative Card Address
|
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);
|
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);
|
_SC_changeMode (SC_MODE_MEDIA);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _SCSD_sendCommand (u8 command, u32 argument) {
|
static bool _SCSD_sendCommand (u8 command, u32 argument) {
|
||||||
@ -188,10 +199,18 @@ static void _SCSD_sendClocks (u32 numClocks) {
|
|||||||
} while (numClocks--);
|
} while (numClocks--);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _SCSD_initCard (void) {
|
bool _SCSD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) {
|
||||||
int i;
|
_SCSD_sendCommand (command, data);
|
||||||
u8 responseBuffer[17] = {0}; // sizeof 17 to hold the maximum response size possible
|
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
|
// Give the card time to stabilise
|
||||||
_SCSD_sendClocks (NUM_STARTUP_CLOCKS);
|
_SCSD_sendClocks (NUM_STARTUP_CLOCKS);
|
||||||
|
|
||||||
@ -205,70 +224,11 @@ static bool _SCSD_initCard (void) {
|
|||||||
// Card is now reset, including it's address
|
// Card is now reset, including it's address
|
||||||
_SCSD_relativeCardAddress = 0;
|
_SCSD_relativeCardAddress = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAX_STARTUP_TRIES ; i++) {
|
// Init the card
|
||||||
_SCSD_sendCommand (APP_CMD, 0);
|
return _SD_InitCard (_SCSD_cmd_6byte_response,
|
||||||
if (!_SCSD_getResponse_R1 (responseBuffer)) {
|
_SCSD_cmd_17byte_response,
|
||||||
return false;
|
true,
|
||||||
}
|
&_SCSD_relativeCardAddress);
|
||||||
|
|
||||||
_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _SCSD_readData (void* buffer) {
|
static bool _SCSD_readData (void* buffer) {
|
||||||
@ -313,7 +273,9 @@ static bool _SCSD_readData (void* buffer) {
|
|||||||
// Functions needed for the external interface
|
// Functions needed for the external interface
|
||||||
|
|
||||||
bool _SCSD_startUp (void) {
|
bool _SCSD_startUp (void) {
|
||||||
_SCSD_unlock();
|
if (!_SCSD_unlock()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return _SCSD_initCard();
|
return _SCSD_initCard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,17 @@
|
|||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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,
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
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"
|
#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
|
Improved CRC7 function provided by cory1492
|
||||||
Calculates the CRC of an SD command, and includes the end bit in the byte
|
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;
|
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 */
|
/* OCR (Operating Conditions Register) send value */
|
||||||
//#define SD_OCR_VALUE 0x00030000 /* 2.8V to 3.0V */
|
//#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 */
|
/* SD Data repsonses */
|
||||||
#define SD_CARD_BUSY 0xff
|
#define SD_CARD_BUSY 0xff
|
||||||
@ -95,5 +96,19 @@ four data lines at once
|
|||||||
*/
|
*/
|
||||||
extern void _SD_CRC16 (u8* buff, int buffLength, u8* crc16buff);
|
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
|
#endif // define IO_SD_COMMON_H
|
||||||
|
Loading…
Reference in New Issue
Block a user