u8 DualShock::command(const u32 counter, const u8 data)
{
	if(!gamepadPlugged)
	{
		if(counter == 0) Recheck();
		if(!gamepadPlugged) return 0x00;
	}

	if (counter >= sizeBuffer)
	{
		printf("Pokopom: Out of Bound Buffer ERROR! [%02d:%02d]\n", sizeBuffer, counter);
		return 0x00;
	}

	cmdBuffer[counter] = data;

	switch(counter)
	{
	case 0x00: Cmd0(); break;

	case 0x01:
		dataBuffer[1] = bConfig? ID_CONFIG : padID;
		Cmd1(cmdBuffer[1]);
		break;

	case 0x02: dataBuffer[2] = 0x5A; break;

	case 0x04:Cmd4(cmdBuffer[1]); break;
	case 0x08:Cmd8(cmdBuffer[1]); break;
	}

	return dataBuffer[counter];
}
Beispiel #2
0
//------------------------------------------------------------------------------
/// Run the SDcard SPI Mode initialization sequence. This function runs the
/// initialisation procedure and the identification process, then it sets the SD
/// card in transfer state to set the block length.
/// Returns 0 if successful; otherwise returns an SD_ERROR code.
/// \param pSd  Pointer to a SD card driver instance.
/// \param pSdDriver  Pointer to SD driver already initialized.
//------------------------------------------------------------------------------
unsigned char SD_SPI_Init(SdCard *pSd, SdDriver *pSpi)
{
    unsigned char isCCSet;
    unsigned char error;
    unsigned char cmd8Retries = 2;
    unsigned char cmd1Retries = 1;
    unsigned int pOCR;

    // The command GO_IDLE_STATE (CMD0) is the software reset command and sets card into Idle State
    // regardless of the current card state.
    error = Cmd0(pSd);
    if (error) {
        TRACE_ERROR("Error during initialization (%d)\n\r", error);
        return error;
    }

    // CMD8 is newly added in the Physical Layer Specification Version 2.00 to support multiple voltage
    // ranges and used to check whether the card supports supplied voltage. The version 2.00 host shall
    // issue CMD8 and verify voltage before card initialization.
    // The host that does not support CMD8 shall supply high voltage range...
    do {
        error = Cmd8(pSd, 1);
    }
    while ((error == SD_ERROR_NORESPONSE) && (cmd8Retries-- > 0));

    if (error == SD_ERROR_NORESPONSE) {
        // No response : Ver2.00 or later SD Memory Card(voltage mismatch)
        // or Ver1.X SD Memory Card
        // or not SD Memory Card

        TRACE_DEBUG("No response to Cmd8\n\r");

        // CMD58 ? !
        error = Cmd58(pSd, &pOCR);
        if (error) {
            TRACE_ERROR("Error during initialization (%d), 8\n\r", error);
            return error;
        }

        // ACMD41 is a synchronization command used to negotiate the operation voltage range and to poll the
        // cards until they are out of their power-up sequence.
        error = Acmd41(pSd, 0, &isCCSet);
        if (error) {
            // Acmd41 failed : MMC card or unknown card
            error = Cmd0(pSd);
            if (error) {
                TRACE_ERROR("Error during initialization (%d)\n\r", error);
                return error;
            }
            do {
                error = Cmd1(pSd);
            }
            while ((error) && (cmd1Retries-- > 0));

            if (error) {
                TRACE_ERROR("Error during initialization (%d)\n\r", error);
                return error;
            }
            else {
                pSd->cardType = CARD_MMC;
            }
        }
        else {
            if(isCCSet == 0) {
                TRACE_DEBUG("CARD SD\n\r");
                pSd->cardType = CARD_SD;
            }
        }
    }
    else if (!error) {
        error = Cmd58(pSd, &pOCR);
        if (error) {
            TRACE_ERROR("Error during initialization (%d), 8\n\r", error);
            return error;
        }

        // Valid response : Ver2.00 or later SD Memory Card
        error = Acmd41(pSd, 1, &isCCSet);
        if (error) {
            TRACE_ERROR("Error during initialization (%d)\n\r", error);
            return error;
        }
        error = Cmd58(pSd, &pOCR);
        if (error) {
            TRACE_ERROR("Error during initialization (%d), 8\n\r", error);
            return error;
        }
        if (isCCSet) {
            TRACE_DEBUG("CARD SDHC\n\r");
            pSd->cardType = CARD_SDHC;
        }
        else {
            TRACE_DEBUG("CARD SD\n\r");
            pSd->cardType = CARD_SD;
        }
    }
    else {
        TRACE_ERROR("Error during initialization (%d)\n\r", error);
        return error;
    }

    if (pSd->cardType != CARD_MMC) {
        // The host issues CRC_ON_OFF (CMD59) to set data CRC on/off
        // The host can turn the CRC option on and off using the CRC_ON_OFF command (CMD59).
        // Host should enable CRC verification before issuing ACMD41.
        error = Cmd59(pSd,0);  // turn crc option OFF
        if (error) {

            TRACE_ERROR("Error during initialization (%d)\n\r, 59", error);
            return error;
        }
    }

    // The host issues SEND_CSD (CMD9) to obtain the Card Specific Data (CSD register),
    // e.g. block length, card storage capacity, etc...
    error = Cmd9(pSd);
    if (error) {

        TRACE_ERROR("Error during initialization (%d), 9\n\r", error);
        return error;
    }
    return 0;
}