static BOOL SDSendCommand(UINT8 idx, UINT32 arg) { // sanity checking on parameters if(idx >= TOTAL_COMMANDS) { OALMSG(1, (TEXT("SDBootMDD: %s: command index is invalid\r\n"),TEXT(__FUNCTION__))); return FALSE; } if( cmdTable[idx].isAppCmd && !SDSendCommand( APP_CMD, HIGH_SHIFT(g_cardRCA) ) ) { return FALSE; } return PDD_SDSendCommand( cmdTable[idx].index, arg, cmdTable[idx].resp, cmdTable[idx].type, cmdTable[idx].isRead); }
static BOOL SDSendCommand(UINT8 idx, UINT32 arg) { // sanity checking on parameters if(idx >= TOTAL_COMMANDS) { // KITLOutputDebugString("SDBootMDD: SDSendCommand: command index is invalid\r\n"); return FALSE; } if( cmdTable[idx].isAppCmd && !SDSendCommand( APP_CMD, HIGH_SHIFT(g_cardRCA) ) ) { return FALSE; } return PDD_SDSendCommand( cmdTable[idx].index, arg, cmdTable[idx].resp, cmdTable[idx].type, cmdTable[idx].isRead); }
BOOL SDInitializeHardware() { CARD_TYPE cardType = CARD_TYPE_NONE; int timeOut; COMPILE_TIME_ASSERT( DIMOF(cmdTable) == (TOTAL_COMMANDS) ); // To check to see why your compile time assert failed... g_cardRCA = 0; // -------- INITIALIZE HARDWARE ------- if( !PDD_SDInitializeHardware() ) { return FALSE; } // -------- DETECT CARD TYPE ------- if( !SDSendCommand(GO_IDLE_STATE,0) ) { OALMSG(1, (TEXT("SDBootMDD: %s: GO_IDLE command returned error\r\n"),TEXT(__FUNCTION__))); return FALSE; } if( SDSendCommand(SD_APP_OP_COND,0) ) { cardType = CARD_TYPE_SD; } else if( SDSendCommand(SEND_OP_COND,0) ) { cardType = CARD_TYPE_MMC; } // If no card exists, exit. SDIO cards are not supported by this driver. if( cardType == CARD_TYPE_NONE ) { OALMSG(1, (TEXT("SDBootMDD: %s: No valid SD/MMC cards detected\r\n"),TEXT(__FUNCTION__))); return FALSE; } // ------ INITIALIZE CARD SEQUENCE ------- // // ---- 1. Reset to consistent state with CMD0 ---- // if( !SDSendCommand(GO_IDLE_STATE,0) ) { OALMSG(1, (TEXT("SDBootMDD: %s: GO_IDLE command returned error\r\n"),TEXT(__FUNCTION__))); return FALSE; } if( cardType == CARD_TYPE_MMC ) PDD_SDSetPDDCapabilities(SET_OPEN_DRAIN, TRUE); // ---- 2. Check voltages using CMD1/ACMD41 ---- // for( timeOut = 0; timeOut < 100; ++timeOut ) { if( cardType == CARD_TYPE_SD ) { if( !SDSendCommand( SD_APP_OP_COND, PDD_SDGetPDDCapabilities(GET_SUPPORTED_OCR_SD) )) { OALMSG(1, (TEXT("SDBootMDD: %s: Error issuing SD_APP_OP_COND command\r\n"),TEXT(__FUNCTION__))); return FALSE; } } else { if( !SDSendCommand( SEND_OP_COND, PDD_SDGetPDDCapabilities(GET_SUPPORTED_OCR_MMC) )) { OALMSG(1, (TEXT("SDBootMDD: %s: Error issuing SEND_OP_COND command\r\n"),TEXT(__FUNCTION__))); return FALSE; } } if( PDD_SDGetResponse(OCR_REGISTER) & OCR_POWER_UP_BUSY) { // card finish power init? break; } PDD_SDStallExecute(100); } if( timeOut >= 100 ) { OALMSG(1, (TEXT("SDBootMDD: %s: Failed to validate card OCR voltage range\r\n"),TEXT(__FUNCTION__))); return FALSE; } // ---- 3. Have first card identify itself (multiple cards unsupported) ---- // for( timeOut = 0; timeOut < 30; ++timeOut ) { if( SDSendCommand(ALL_SEND_CID,0) ) { break; } PDD_SDStallExecute(100); } if( timeOut >= 30 ) { OALMSG(1, (TEXT("SDBootMDD: %s: Failed to receive valid CID response from card\r\n"),TEXT(__FUNCTION__))); return FALSE; } // ---- 4. Give the card an address / get an address ---- // if( cardType == CARD_TYPE_SD ) { if( !SDSendCommand( SEND_RELATIVE_ADDR,0) ) { OALMSG(1, (TEXT("SDBootMDD: %s: Error receiving card relative address\r\n"),TEXT(__FUNCTION__))); return FALSE; } g_cardRCA = (UINT16) PDD_SDGetResponse(RCA_REGISTER); } else { if( !SDSendCommand( SET_RELATIVE_ADDR, HIGH_SHIFT(1) ) ) { OALMSG(1, (TEXT("SDBootMDD: %s: Error setting card relative address\r\n"),TEXT(__FUNCTION__))); return FALSE; } g_cardRCA = 1; } // To see the published RCA... OALMSG(OAL_INFO, (TEXT("SDBootMDD: Card address is %x\r\n"),g_cardRCA)); if( cardType == CARD_TYPE_MMC ) PDD_SDSetPDDCapabilities(SET_OPEN_DRAIN, FALSE); // ---- 5. Select card for future commands using CMD7 ---- // if( !SDSendCommand(SELECT_DESELECT_CARD, HIGH_SHIFT(g_cardRCA)) ) { OALMSG(1, (TEXT("SDBootMDD: %s: Error selecting card for data transfer\r\n"),TEXT(__FUNCTION__))); return FALSE; } // ---- 6. Select clock rate and bus width ---- // if( cardType == CARD_TYPE_SD ) { if( SDSendCommand(SET_BUS_WIDTH, 0x2) ) { OALMSG(OAL_INFO, (TEXT("SDBootMDD: 4-bit data bus selected\r\n"))); PDD_SDSetPDDCapabilities(SET_4BIT_MODE, TRUE); } else { OALMSG(OAL_INFO, (TEXT("SDBootMDD: 1-bit data bus selected\r\n"))); } PDD_SDSetPDDCapabilities(SET_CLOCK_RATE, SDCARD_CLOCK_RATE); } else { OALMSG(OAL_INFO, (TEXT("SDBootMDD: 1-bit data bus selected\r\n"))); PDD_SDSetPDDCapabilities(SET_CLOCK_RATE, MMCCARD_CLOCK_RATE); } // ---- 7. Prep card for reading by setting default block length ---- // if( !SDSendCommand(SET_BLOCKLEN, BLOCK_LEN) ) { OALMSG(1, (TEXT("SDBootMDD: %s: Error setting default block transfer length\r\n"),TEXT(__FUNCTION__))); return FALSE; } return TRUE; }