summaryrefslogtreecommitdiffstats
path: root/main/common/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/common/sd.c')
-rw-r--r--main/common/sd.c822
1 files changed, 421 insertions, 401 deletions
diff --git a/main/common/sd.c b/main/common/sd.c
index 1be4c2f..b96880a 100644
--- a/main/common/sd.c
+++ b/main/common/sd.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2013 Alcatel-Lucent
- *
+ *
* Alcatel Lucent licenses this file to You under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. A copy of the License is contained the
@@ -42,179 +42,181 @@
struct sdinfo sdInfoTbl[SD_DEVTOT];
char sdVerbose;
-static int sdInum; /* Interface number: to support multiple SD interfaces.
- * Typically this will always be zero.
- */
+static int sdInum; /* Interface number: to support multiple SD interfaces.
+ * Typically this will always be zero.
+ */
static struct sdcmd sdCardCmdTbl[] = {
- { GO_IDLE_STATE, R1_RLEN, R1 },
- { SEND_OP_COND, R1_RLEN, R1 },
- { SWITCH_FUNC, R1_RLEN, R1 },
- { SEND_IF_COND, R7_RLEN, R7 },
- { SEND_CSD, R1_RLEN, R1 },
- { SEND_CID, R1_RLEN, R1 },
- { STOP_TRANSMISSION, R1_RLEN, R1B },
- { SEND_STATUS, R2_RLEN, R2 },
- { SET_BLOCKLEN, R1_RLEN, R1 },
- { READ_SINGLE_BLK, R1_RLEN, R1 },
- { READ_MULTIPLE_BLK, R1_RLEN, R1 },
- { WRITE_BLK, R1_RLEN, R1B },
- { WRITE_MULTIPLE_BLK, R1_RLEN, R1B },
- { PROGRAM_CSD, R1_RLEN, R1 },
- { SET_WRITE_PROT, R1_RLEN, R1B },
- { CLR_WRITE_PROT, R1_RLEN, R1B },
- { SEND_WRITE_PROT, R1_RLEN, R1 },
- { ERASE_WR_BLK_START_ADDR, R1_RLEN, R1 },
- { ERASE_WR_BLK_END_ADDR, R1_RLEN, R1 },
- { ERASE, R1_RLEN, R1B },
- { LOCK_UNLOCK, R1_RLEN, R1 },
- { APP_CMD, R1_RLEN, R1 },
- { GEN_CMD, R1_RLEN, R1 },
- { READ_OCR, R3_RLEN, R3 },
- { CRC_ON_OFF, R1_RLEN, R1 },
- { SD_SEND_OP_COND, R1_RLEN, R1 },
- { -1,-1,-1 }
+ { GO_IDLE_STATE, R1_RLEN, R1 },
+ { SEND_OP_COND, R1_RLEN, R1 },
+ { SWITCH_FUNC, R1_RLEN, R1 },
+ { SEND_IF_COND, R7_RLEN, R7 },
+ { SEND_CSD, R1_RLEN, R1 },
+ { SEND_CID, R1_RLEN, R1 },
+ { STOP_TRANSMISSION, R1_RLEN, R1B },
+ { SEND_STATUS, R2_RLEN, R2 },
+ { SET_BLOCKLEN, R1_RLEN, R1 },
+ { READ_SINGLE_BLK, R1_RLEN, R1 },
+ { READ_MULTIPLE_BLK, R1_RLEN, R1 },
+ { WRITE_BLK, R1_RLEN, R1B },
+ { WRITE_MULTIPLE_BLK, R1_RLEN, R1B },
+ { PROGRAM_CSD, R1_RLEN, R1 },
+ { SET_WRITE_PROT, R1_RLEN, R1B },
+ { CLR_WRITE_PROT, R1_RLEN, R1B },
+ { SEND_WRITE_PROT, R1_RLEN, R1 },
+ { ERASE_WR_BLK_START_ADDR, R1_RLEN, R1 },
+ { ERASE_WR_BLK_END_ADDR, R1_RLEN, R1 },
+ { ERASE, R1_RLEN, R1B },
+ { LOCK_UNLOCK, R1_RLEN, R1 },
+ { APP_CMD, R1_RLEN, R1 },
+ { GEN_CMD, R1_RLEN, R1 },
+ { READ_OCR, R3_RLEN, R3 },
+ { CRC_ON_OFF, R1_RLEN, R1 },
+ { SD_SEND_OP_COND, R1_RLEN, R1 },
+ { -1,-1,-1 }
};
char *SdHelp[] = {
- "Secure Digital Flash Interface",
- "[options] {operation} [args]...",
+ "Secure Digital Flash Interface",
+ "[options] {operation} [args]...",
#if INCLUDE_VERBOSEHELP
- "",
- "Options:",
- " -i ## interface # (default is 0)",
- " -v additive verbosity",
- "",
- "Operations:",
- " init [prefix]",
- " cmd {cmdnum} [arg]",
- " read {dest} {blk} {blktot}",
- " write {src} {blk} {blktot}",
+ "",
+ "Options:",
+ " -i ## interface # (default is 0)",
+ " -v additive verbosity",
+ "",
+ "Operations:",
+ " init [prefix]",
+ " cmd {cmdnum} [arg]",
+ " read {dest} {blk} {blktot}",
+ " write {src} {blk} {blktot}",
#endif
- 0
+ 0
};
int
SdCmd(int argc, char *argv[])
{
- char *cmd, *buf, *prefix, varname[16];
- int opt, verbose, sdret, blknum, blkcnt;
-
- verbose = 0;
- while ((opt=getopt(argc,argv,"i:v")) != -1) {
- switch(opt) {
- case 'i':
- sdInum = atoi(optarg); /* sticky */
- break;
- case 'v':
- verbose++;
- break;
- default:
- return(CMD_PARAM_ERROR);
- }
- }
-
- if (argc < optind + 1)
- return(CMD_PARAM_ERROR);
-
- cmd = argv[optind];
-
- if (sdInum >= SD_DEVTOT) {
- printf("Configured to support %d SD interface%s\n",
- SD_DEVTOT,SD_DEVTOT == 1 ? "" : "s");
- return(CMD_FAILURE);
- }
-
- if (sdInstalled(sdInum) == 0) {
- printf("SDCard not installed\n");
- return(CMD_FAILURE);
- }
-
- if (strcmp(cmd,"init") == 0) {
- sdret = sdInit(sdInum, verbose);
- if (sdret < 0) {
- printf("sdInit returned %d\n",sdret);
- return(CMD_FAILURE);
- }
-
- // If prefix is specified, then load shell variables:
- if (argc == optind+2) {
- prefix = argv[optind+1];
- if (strlen(prefix)+4 > sizeof(varname)) {
- printf("prefix %s too long\n",prefix);
- return(CMD_PARAM_ERROR);
- }
-
- sprintf(varname,"%s_RD",prefix);
- shell_sprintf(varname,"0x%lx",(long)sdRead);
-
- sprintf(varname,"%s_WR",prefix);
- shell_sprintf(varname,"0x%lx",(long)sdWrite);
- }
-
- shell_sprintf("SD_BLKSIZE","0x%lx",SD_BLKSIZE);
- }
- else if (strcmp(cmd,"cmd") == 0) {
- ulong cmdarg;
- uchar resp[8];
- int rtot, i, cmdnum;
-
- cmdarg = 0;
- memset((char *)resp,0xff,sizeof(resp));
-
- if ((argc != (optind+2)) && (argc != (optind+3)))
- return(CMD_PARAM_ERROR);
-
- cmdnum = (uchar)strtoul(argv[optind+1],0,0);
- if (argc == optind+3)
- cmdarg = strtoul(argv[optind+2],0,0);
- sdret = sdCardCmd(sdInum, cmdnum , cmdarg ,resp);
- if (sdret < 0) {
- printf("sdCardCmd returned %d\n",sdret);
- return(CMD_FAILURE);
- }
-
- rtot = sdCmdrlen(cmdnum);
-
- printf("CMD_%d resp: ",cmdnum);
- for(i=0;i<rtot;i++)
- printf("%02x ",resp[i]);
- printf("\n");
- }
- else if (strcmp(cmd,"read") == 0) {
- if (argc != optind+4)
- return(CMD_PARAM_ERROR);
-
- buf = (char *)strtoul(argv[optind+1],0,0);
- blknum = strtoul(argv[optind+2],0,0);
- blkcnt = strtoul(argv[optind+3],0,0);
-
- sdret = sdRead(sdInum,buf,blknum,blkcnt);
- if (sdret < 0) {
- printf("sdRead returned %d\n",sdret);
- return(CMD_FAILURE);
- }
- }
- else if (strcmp(cmd,"write") == 0) {
- if (argc != optind+4)
- return(CMD_PARAM_ERROR);
- buf = (char *)strtoul(argv[optind+1],0,0);
- blknum = strtoul(argv[optind+2],0,0);
- blkcnt = strtoul(argv[optind+3],0,0);
-
- sdret = sdWrite(sdInum,buf,blknum,blkcnt);
- if (sdret < 0) {
- printf("sdWrite returned %d\n",sdret);
- return(CMD_FAILURE);
- }
- }
- else {
- printf("sd op <%s> not found\n",cmd);
- return(CMD_FAILURE);
- }
-
- return(CMD_SUCCESS);
+ char *cmd, *buf, *prefix, varname[16];
+ int opt, verbose, sdret, blknum, blkcnt;
+
+ verbose = 0;
+ while((opt=getopt(argc,argv,"i:v")) != -1) {
+ switch(opt) {
+ case 'i':
+ sdInum = atoi(optarg); /* sticky */
+ break;
+ case 'v':
+ verbose++;
+ break;
+ default:
+ return(CMD_PARAM_ERROR);
+ }
+ }
+
+ if(argc < optind + 1) {
+ return(CMD_PARAM_ERROR);
+ }
+
+ cmd = argv[optind];
+
+ if(sdInum >= SD_DEVTOT) {
+ printf("Configured to support %d SD interface%s\n",
+ SD_DEVTOT,SD_DEVTOT == 1 ? "" : "s");
+ return(CMD_FAILURE);
+ }
+
+ if(sdInstalled(sdInum) == 0) {
+ printf("SDCard not installed\n");
+ return(CMD_FAILURE);
+ }
+
+ if(strcmp(cmd,"init") == 0) {
+ sdret = sdInit(sdInum, verbose);
+ if(sdret < 0) {
+ printf("sdInit returned %d\n",sdret);
+ return(CMD_FAILURE);
+ }
+
+ // If prefix is specified, then load shell variables:
+ if(argc == optind+2) {
+ prefix = argv[optind+1];
+ if(strlen(prefix)+4 > sizeof(varname)) {
+ printf("prefix %s too long\n",prefix);
+ return(CMD_PARAM_ERROR);
+ }
+
+ sprintf(varname,"%s_RD",prefix);
+ shell_sprintf(varname,"0x%lx",(long)sdRead);
+
+ sprintf(varname,"%s_WR",prefix);
+ shell_sprintf(varname,"0x%lx",(long)sdWrite);
+ }
+
+ shell_sprintf("SD_BLKSIZE","0x%lx",SD_BLKSIZE);
+ } else if(strcmp(cmd,"cmd") == 0) {
+ ulong cmdarg;
+ uchar resp[8];
+ int rtot, i, cmdnum;
+
+ cmdarg = 0;
+ memset((char *)resp,0xff,sizeof(resp));
+
+ if((argc != (optind+2)) && (argc != (optind+3))) {
+ return(CMD_PARAM_ERROR);
+ }
+
+ cmdnum = (uchar)strtoul(argv[optind+1],0,0);
+ if(argc == optind+3) {
+ cmdarg = strtoul(argv[optind+2],0,0);
+ }
+ sdret = sdCardCmd(sdInum, cmdnum , cmdarg ,resp);
+ if(sdret < 0) {
+ printf("sdCardCmd returned %d\n",sdret);
+ return(CMD_FAILURE);
+ }
+
+ rtot = sdCmdrlen(cmdnum);
+
+ printf("CMD_%d resp: ",cmdnum);
+ for(i=0; i<rtot; i++) {
+ printf("%02x ",resp[i]);
+ }
+ printf("\n");
+ } else if(strcmp(cmd,"read") == 0) {
+ if(argc != optind+4) {
+ return(CMD_PARAM_ERROR);
+ }
+
+ buf = (char *)strtoul(argv[optind+1],0,0);
+ blknum = strtoul(argv[optind+2],0,0);
+ blkcnt = strtoul(argv[optind+3],0,0);
+
+ sdret = sdRead(sdInum,buf,blknum,blkcnt);
+ if(sdret < 0) {
+ printf("sdRead returned %d\n",sdret);
+ return(CMD_FAILURE);
+ }
+ } else if(strcmp(cmd,"write") == 0) {
+ if(argc != optind+4) {
+ return(CMD_PARAM_ERROR);
+ }
+ buf = (char *)strtoul(argv[optind+1],0,0);
+ blknum = strtoul(argv[optind+2],0,0);
+ blkcnt = strtoul(argv[optind+3],0,0);
+
+ sdret = sdWrite(sdInum,buf,blknum,blkcnt);
+ if(sdret < 0) {
+ printf("sdWrite returned %d\n",sdret);
+ return(CMD_FAILURE);
+ }
+ } else {
+ printf("sd op <%s> not found\n",cmd);
+ return(CMD_FAILURE);
+ }
+
+ return(CMD_SUCCESS);
}
/* sdCmdrlen():
@@ -223,110 +225,112 @@ SdCmd(int argc, char *argv[])
int
sdCmdrlen(int cmd)
{
- struct sdcmd *sdp = sdCardCmdTbl;
-
- while(sdp->cmd != -1) {
- if (cmd == sdp->cmd)
- return(sdp->rlen);
- sdp++;
- }
- return(-1);
+ struct sdcmd *sdp = sdCardCmdTbl;
+
+ while(sdp->cmd != -1) {
+ if(cmd == sdp->cmd) {
+ return(sdp->rlen);
+ }
+ sdp++;
+ }
+ return(-1);
}
-
+
/* sdCmdrtype():
* Given the command number, return the response type.
*/
int
sdCmdrtype(int cmd)
{
- struct sdcmd *sdp = sdCardCmdTbl;
-
- while(sdp->cmd != -1) {
- if (cmd == sdp->cmd)
- return(sdp->rtype);
- sdp++;
- }
- return(-1);
+ struct sdcmd *sdp = sdCardCmdTbl;
+
+ while(sdp->cmd != -1) {
+ if(cmd == sdp->cmd) {
+ return(sdp->rtype);
+ }
+ sdp++;
+ }
+ return(-1);
}
static char *months[] = {
- "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
};
void
sdShowCID(uchar *cid)
{
- int year, mon;
-
- printf(" Manufacturer ID: x%02x\n", cid[0]);
- printf(" OEM/Application ID: x%02x%02x\n", cid[1],cid[2]);
- printf(" Product name: %c%c%c%c%c\n",
- cid[3],cid[4],cid[5],cid[6],cid[7]);
- printf(" Product rev: x%02x\n", cid[8]);
- printf(" Product serialno: x%02x%02x%02x%02x\n",
- cid[9],cid[10],cid[11],cid[12]);
-
- year = (((cid[13] & 0x0f) << 4) | ((cid[14] & 0xf0) >> 4));
- mon = (cid[14] & 0x0f);
- if ((mon < 1) || (mon > 12))
- mon = 0;
- printf(" Manufactured: %s/%d\n",months[mon],2000+year);
+ int year, mon;
+
+ printf(" Manufacturer ID: x%02x\n", cid[0]);
+ printf(" OEM/Application ID: x%02x%02x\n", cid[1],cid[2]);
+ printf(" Product name: %c%c%c%c%c\n",
+ cid[3],cid[4],cid[5],cid[6],cid[7]);
+ printf(" Product rev: x%02x\n", cid[8]);
+ printf(" Product serialno: x%02x%02x%02x%02x\n",
+ cid[9],cid[10],cid[11],cid[12]);
+
+ year = (((cid[13] & 0x0f) << 4) | ((cid[14] & 0xf0) >> 4));
+ mon = (cid[14] & 0x0f);
+ if((mon < 1) || (mon > 12)) {
+ mon = 0;
+ }
+ printf(" Manufactured: %s/%d\n",months[mon],2000+year);
}
void
sdShowCSD(uchar *csd)
{
- uchar csdver;
- long long capacity;
- int mult, csize, csm, rbl;
- int blocknr, blocklen, i;
-
- printf(" CSD Response: ");
- for(i=0;i<16;i++)
- printf("%02x ",csd[i]);
- printf("\n");
-
- mult = csize = csm = rbl = 0;
-
- if ((csd[0] & 0xc0) == 0)
- csdver = 1;
- else if ((csd[0] & 0xc0) == 0x40)
- csdver = 2;
- else {
- printf("Invalid CSD structure type\n");
- return;
- }
-
- printf(" CSD version %d.0\n",csdver);
- if (csdver == 1) {
- rbl = csd[5] & 0x0f;
- csize = ((csd[8] & 0xC0) >> 6);
- csize |= (csd[7] << 2);
- csize |= ((csd[6] & 0x03) << 10);
- csm = (csd[9] & 0x03);
- csm <<= 1;
- csm |= ((csd[10] & 0x80) >> 7);
-
- mult = (1 << (csm+2));
- blocknr = (csize+1)*mult;
- blocklen = (1 << rbl);
- capacity = (long long)((long long)blocknr * (long long)blocklen);
- //printf(" (csm=%d, csize=%d, rbl=%d, mult=%d, blknr=%d, blkln=%d)\n",
- // csm, csize, rbl, mult, blocknr, blocklen);
- }
- else if (csdver == 2) {
- rbl = csd[5] & 0x0f;
- csize = (csd[7] & 0x3f) << 16;
- csize |= (csd[8] << 8);
- csize |= csd[9];
- capacity = (long long)((long long)(csize + 1) * 512LL * 1024LL);
- }
- else {
- printf(" Unrecognized CSD version.\n");
- return;
- }
- printf(" Card capacity: %lld bytes\n",capacity);
+ uchar csdver;
+ long long capacity;
+ int mult, csize, csm, rbl;
+ int blocknr, blocklen, i;
+
+ printf(" CSD Response: ");
+ for(i=0; i<16; i++) {
+ printf("%02x ",csd[i]);
+ }
+ printf("\n");
+
+ mult = csize = csm = rbl = 0;
+
+ if((csd[0] & 0xc0) == 0) {
+ csdver = 1;
+ } else if((csd[0] & 0xc0) == 0x40) {
+ csdver = 2;
+ } else {
+ printf("Invalid CSD structure type\n");
+ return;
+ }
+
+ printf(" CSD version %d.0\n",csdver);
+ if(csdver == 1) {
+ rbl = csd[5] & 0x0f;
+ csize = ((csd[8] & 0xC0) >> 6);
+ csize |= (csd[7] << 2);
+ csize |= ((csd[6] & 0x03) << 10);
+ csm = (csd[9] & 0x03);
+ csm <<= 1;
+ csm |= ((csd[10] & 0x80) >> 7);
+
+ mult = (1 << (csm+2));
+ blocknr = (csize+1)*mult;
+ blocklen = (1 << rbl);
+ capacity = (long long)((long long)blocknr * (long long)blocklen);
+ //printf(" (csm=%d, csize=%d, rbl=%d, mult=%d, blknr=%d, blkln=%d)\n",
+ // csm, csize, rbl, mult, blocknr, blocklen);
+ } else if(csdver == 2) {
+ rbl = csd[5] & 0x0f;
+ csize = (csd[7] & 0x3f) << 16;
+ csize |= (csd[8] << 8);
+ csize |= csd[9];
+ capacity = (long long)((long long)(csize + 1) * 512LL * 1024LL);
+ } else {
+ printf(" Unrecognized CSD version.\n");
+ return;
+ }
+ printf(" Card capacity: %lld bytes\n",capacity);
}
/* sdGenericStartup():
@@ -335,7 +339,7 @@ sdShowCSD(uchar *csd)
*
* Refer to the flowchart shown in figure 7.2 of the Simplified
* Physical Layer Specification for an overview of the initialization.
- *
+ *
* The card wakes up in SD bus mode, so the first thing we need to d
* here (after the very basic initialization of the SPI pin config) is
* to get the card into SPI mode.
@@ -346,123 +350,134 @@ sdShowCSD(uchar *csd)
int
sdGenericStartup(int interface)
{
- ulong hcs;
- uchar resp[16], cid[16], csd[16];
- int retry, rc, version;
+ ulong hcs;
+ uchar resp[16], cid[16], csd[16];
+ int retry, rc, version;
struct elapsed_tmr tmr;
- int check_pattern_retry = 2;
-
- sdInfoTbl[interface].initialized = 0;
-
- rc = 0;
- check_pattern_retry = 2;
-
- // Start with at least 74 clocks to powerup the card...
- sdPowerup(10);
-
- // Put card in SPI mode:
-
- // This command always seems to fail on the first try after a
- // powerup, so give it a few attempts...
- for(retry=0;retry<3;retry++) {
- if ((rc = sdCardCmd(interface,GO_IDLE_STATE,0,resp)) != -1)
- break;
- }
-
- if (retry == 3) {
- printf("\nSD GO_IDLE_STATE failed, card installed?\n");
- return(-1);
- }
-
- // According to Physical Layer Simplified Spec (PLSS), it is mandatory
- // for the host compliant to Version 2.00 to send CMD8 (SEND_IF_COND).
- // If CMD8 is not recognized (illegal command), then we can assume that
- // the card is version 1.00.
- // The argument sent with the command is defined in section 4.3.13
- // of the PLSS.
- // The spec says that if the check-patter test fails, to retry...
- do {
- if ((rc = sdCardCmd(interface,SEND_IF_COND,SEND_IF_COND_ARG,resp)) == -1)
- return(-1);
-
- if (resp[0] & R1_ILLEGAL_CMD) {
- version = VERSION_10;
- hcs = 0;
- break; // Check pattern only applies to V2 and later
- }
- else {
- // The card should echo back the VHS and check pattern...
- if (resp[3] != VHS27_36) {
- if (sdVerbose & 2)
- printf("SDCARD not 3.3v compliant!\n");
- return(-1);
- }
- if (resp[4] != CHECK_PATTERN) {
- if (--check_pattern_retry <= 0) {
- if (sdVerbose & 2)
- printf("SDCARD check-pattern failed.\n");
- return(-1);
- }
- }
- version = VERSION_20;
- hcs = HCS;
- }
- } while(resp[4] != CHECK_PATTERN);
-
- // Read OCR to make sure the card will run at 3.3v...
- if ((rc = sdCardCmd(interface,READ_OCR,hcs,resp)) == -1)
- return(-1);
-
- if ((resp[2] & MSK_OCR_33) != MSK_OCR_33) {
- if (sdVerbose & 2)
- printf("SDCARD: OCR_33 failed, card isn't 3.3v capable\n");
- return(-1);
- }
-
- // Wait for card to complete initialization:
+ int check_pattern_retry = 2;
+
+ sdInfoTbl[interface].initialized = 0;
+
+ rc = 0;
+ check_pattern_retry = 2;
+
+ // Start with at least 74 clocks to powerup the card...
+ sdPowerup(10);
+
+ // Put card in SPI mode:
+
+ // This command always seems to fail on the first try after a
+ // powerup, so give it a few attempts...
+ for(retry=0; retry<3; retry++) {
+ if((rc = sdCardCmd(interface,GO_IDLE_STATE,0,resp)) != -1) {
+ break;
+ }
+ }
+
+ if(retry == 3) {
+ printf("\nSD GO_IDLE_STATE failed, card installed?\n");
+ return(-1);
+ }
+
+ // According to Physical Layer Simplified Spec (PLSS), it is mandatory
+ // for the host compliant to Version 2.00 to send CMD8 (SEND_IF_COND).
+ // If CMD8 is not recognized (illegal command), then we can assume that
+ // the card is version 1.00.
+ // The argument sent with the command is defined in section 4.3.13
+ // of the PLSS.
+ // The spec says that if the check-patter test fails, to retry...
+ do {
+ if((rc = sdCardCmd(interface,SEND_IF_COND,SEND_IF_COND_ARG,resp)) == -1) {
+ return(-1);
+ }
+
+ if(resp[0] & R1_ILLEGAL_CMD) {
+ version = VERSION_10;
+ hcs = 0;
+ break; // Check pattern only applies to V2 and later
+ } else {
+ // The card should echo back the VHS and check pattern...
+ if(resp[3] != VHS27_36) {
+ if(sdVerbose & 2) {
+ printf("SDCARD not 3.3v compliant!\n");
+ }
+ return(-1);
+ }
+ if(resp[4] != CHECK_PATTERN) {
+ if(--check_pattern_retry <= 0) {
+ if(sdVerbose & 2) {
+ printf("SDCARD check-pattern failed.\n");
+ }
+ return(-1);
+ }
+ }
+ version = VERSION_20;
+ hcs = HCS;
+ }
+ } while(resp[4] != CHECK_PATTERN);
+
+ // Read OCR to make sure the card will run at 3.3v...
+ if((rc = sdCardCmd(interface,READ_OCR,hcs,resp)) == -1) {
+ return(-1);
+ }
+
+ if((resp[2] & MSK_OCR_33) != MSK_OCR_33) {
+ if(sdVerbose & 2) {
+ printf("SDCARD: OCR_33 failed, card isn't 3.3v capable\n");
+ }
+ return(-1);
+ }
+
+ // Wait for card to complete initialization:
startElapsedTimer(&tmr,1000);
- while(1) {
- if ((rc = sdCardCmd(interface,SD_SEND_OP_COND,HCS,resp)) == -1)
- return(-1);
- if ((resp[0] & R1_IDLE) == 0)
- break;
- if(msecElapsed(&tmr)) {
- printf("SDCARD: gaveup waiting for init to complete.\n");
- return(-1);
- }
- }
-
- if (version == VERSION_20) {
- // Get CCS...
- if ((rc = sdCardCmd(interface,READ_OCR,0,resp)) == -1)
- return(-1);
- }
- else {
- if ((rc = sdCardCmd(interface,SET_BLOCKLEN,SD_BLKSIZE,resp)) == -1)
- return(-1);
- }
-
- if (sdVerbose) {
- printf("SD/SPI Initialized (version %s)\n",
- version == VERSION_10 ? "1.0" : ">=2.0");
- }
-
- sdInfoTbl[interface].cardversion = version;
-
- sdReadCxD(interface,cid,SEND_CID);
- if (sdVerbose)
- sdShowCID(cid);
- sdReadCxD(interface,csd,SEND_CSD);
- if (sdVerbose)
- sdShowCSD(csd);
-
- if ((csd[0] & 0xc0) == 0x00)
- sdInfoTbl[interface].highcapacity = 0;
- else
- sdInfoTbl[interface].highcapacity = 1;
-
- sdInfoTbl[interface].initialized = 1;
- return(0);
+ while(1) {
+ if((rc = sdCardCmd(interface,SD_SEND_OP_COND,HCS,resp)) == -1) {
+ return(-1);
+ }
+ if((resp[0] & R1_IDLE) == 0) {
+ break;
+ }
+ if(msecElapsed(&tmr)) {
+ printf("SDCARD: gaveup waiting for init to complete.\n");
+ return(-1);
+ }
+ }
+
+ if(version == VERSION_20) {
+ // Get CCS...
+ if((rc = sdCardCmd(interface,READ_OCR,0,resp)) == -1) {
+ return(-1);
+ }
+ } else {
+ if((rc = sdCardCmd(interface,SET_BLOCKLEN,SD_BLKSIZE,resp)) == -1) {
+ return(-1);
+ }
+ }
+
+ if(sdVerbose) {
+ printf("SD/SPI Initialized (version %s)\n",
+ version == VERSION_10 ? "1.0" : ">=2.0");
+ }
+
+ sdInfoTbl[interface].cardversion = version;
+
+ sdReadCxD(interface,cid,SEND_CID);
+ if(sdVerbose) {
+ sdShowCID(cid);
+ }
+ sdReadCxD(interface,csd,SEND_CSD);
+ if(sdVerbose) {
+ sdShowCSD(csd);
+ }
+
+ if((csd[0] & 0xc0) == 0x00) {
+ sdInfoTbl[interface].highcapacity = 0;
+ } else {
+ sdInfoTbl[interface].highcapacity = 1;
+ }
+
+ sdInfoTbl[interface].initialized = 1;
+ return(0);
}
/* Got this crc7 code off the web...
@@ -473,32 +488,34 @@ sdGenericStartup(int interface)
static unsigned char
Encode(uchar seed, uchar input, uchar depth)
{
- uchar regval, count, cc;
-
- regval = seed;
- cc = input;
-
- for (count = depth ; count-- ; cc <<= 1) {
- regval = (regval << 1) + ((cc & 0x80) ? 1 : 0);
- if (regval & 0x80)
- regval ^= POLYNOM;
- }
- return(regval & 0x7f); // return lower 7 bits of CRC as value to use.
+ uchar regval, count, cc;
+
+ regval = seed;
+ cc = input;
+
+ for(count = depth ; count-- ; cc <<= 1) {
+ regval = (regval << 1) + ((cc & 0x80) ? 1 : 0);
+ if(regval & 0x80) {
+ regval ^= POLYNOM;
+ }
+ }
+ return(regval & 0x7f); // return lower 7 bits of CRC as value to use.
}
uchar
crc7(uchar seed, uchar *buf, int len)
{
- int i;
- uchar crc;
+ int i;
+ uchar crc;
- crc = seed;
- for (i = 0; i < len; i++)
- crc = Encode(crc, buf[i], 8);
+ crc = seed;
+ for(i = 0; i < len; i++) {
+ crc = Encode(crc, buf[i], 8);
+ }
- crc = Encode(crc,0,7);
- crc = (crc << 1) + 1;
- return(crc);
+ crc = Encode(crc,0,7);
+ crc = (crc << 1) + 1;
+ return(crc);
}
#ifdef INCLUDE_SD_DUMMY_FUNCS
@@ -510,50 +527,53 @@ crc7(uchar seed, uchar *buf, int len)
int
sdInit(int interface, int verbose)
{
- if (interface != 0)
- return(-1);
+ if(interface != 0) {
+ return(-1);
+ }
- return(0);
+ return(0);
}
int
sdRead(int interface, char *buf, int blk, int blkcnt)
{
- char *from;
- int size;
+ char *from;
+ int size;
- if (interface != 0)
- return(-1);
+ if(interface != 0) {
+ return(-1);
+ }
- from = (char *)(blk * SD_BLKSIZE);
- size = blkcnt * SD_BLKSIZE;
- memcpy(buf,from,size);
- return(0);
+ from = (char *)(blk * SD_BLKSIZE);
+ size = blkcnt * SD_BLKSIZE;
+ memcpy(buf,from,size);
+ return(0);
}
int
sdWrite(int interface, char *buf, int blk, int blkcnt)
{
- char *to;
- int size;
+ char *to;
+ int size;
- if (interface != 0)
- return(-1);
+ if(interface != 0) {
+ return(-1);
+ }
- to = (char *)(blk * SD_BLKSIZE);
- size = blkcnt * SD_BLKSIZE;
- memcpy(to,buf,size);
- return(0);
+ to = (char *)(blk * SD_BLKSIZE);
+ size = blkcnt * SD_BLKSIZE;
+ memcpy(to,buf,size);
+ return(0);
}
/* sdInstalled():
- * Return 1 if installed, 0 if not installed or -1 if
+ * Return 1 if installed, 0 if not installed or -1 if
* the hardware can't detect installation.
*/
int
sdInstalled(int interface)
{
- return(-1);
+ return(-1);
}
#endif