diff options
Diffstat (limited to 'main/common/sd.c')
-rw-r--r-- | main/common/sd.c | 822 |
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 |