⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdmmc_spi.c

📁 Tried to make CAN logger on AT91sam7X-ek, but have no idea how to implement FATFs... -( I m just a
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;

    TRACE_DEBUG("Cmd13()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_SEND_STATUS_CMD;
    pCommand->resType = 2;
    pCommand->pResp = pStatus;
    // Set SD command state
    pSd->state = SD_STATE_STBY;

    // Send command
    error = SendCommand(pSd);
    error = SD_SPI_R2((unsigned char *)pStatus);
    return error;
}

//------------------------------------------------------------------------------
/// In the case of a Standard Capacity SD Memory Card, this command sets the
/// block length (in bytes) for all following block commands (read, write, lock).
/// Default block length is fixed to 512 Bytes.
/// Set length is valid for memory access commands only if partial block read
/// operation are allowed in CSD.
/// In the case of a High Capacity SD Memory Card, block length set by CMD16
/// command does not affect the memory read and write commands. Always 512
/// Bytes fixed block length is used. This command is effective for LOCK_UNLOCK command.
/// In both cases, if block length is set larger than 512Bytes, the card sets the
/// BLOCK_LEN_ERROR bit.
/// \param pSd  Pointer to a SD card driver instance.
/// \param blockLength  Block length in bytes.
//------------------------------------------------------------------------------
static unsigned char Cmd16(SdCard *pSd, unsigned short blockLength)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response;

    TRACE_DEBUG("Cmd16()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_SET_BLOCKLEN_CMD;
    pCommand->arg = blockLength;
    pCommand->resType = 1;
    pCommand->pResp = &response;
    // Set SD command state
    pSd->state = SD_STATE_STBY;

    // Send command
    //return SendCommand(pSd);
    error = SendCommand(pSd);
    error = SD_SPI_R1((unsigned char *)&response);
    return error;
}

//------------------------------------------------------------------------------
/// Continously transfers datablocks from card to host until interrupted by a
/// STOP_TRANSMISSION command.
/// \param pSd  Pointer to a SD card driver instance.
/// \param blockSize  Block size (shall be set to 512 in case of high capacity).
/// \param pData  Pointer to the application buffer to be filled.
/// \param address  SD card address.
//------------------------------------------------------------------------------
static unsigned char Cmd18(SdCard *pSd,
                           unsigned short nbBlock,
                           unsigned char *pData,
                           unsigned int address)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response;

    //TRACE_DEBUG("Cmd18()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_READ_MULTIPLE_BLOCK_CMD;
    pCommand->arg = address;
    pCommand->blockSize = SD_BLOCK_SIZE;
    pCommand->nbBlock = nbBlock;
    pCommand->pData = pData;
    pCommand->isRead = 1;
    pCommand->conTrans = SPI_NEW_TRANSFER;
    pCommand->resType = 1;
    pCommand->pResp = &response;
    // Set SD command state
    pSd->state = SD_STATE_DATA;

    // Send command
    // return SendCommand(pSd);
    error = SendCommand(pSd);
    error = SD_SPI_R1((unsigned char *)&response);
    return error;
}

//------------------------------------------------------------------------------
/// Write block command
/// \param pSd  Pointer to a SD card driver instance.
/// \param blockSize  Block size (shall be set to 512 in case of high capacity).
/// \param pData  Pointer to the application buffer to be filled.
/// \param address  SD card address.
//------------------------------------------------------------------------------
static unsigned char Cmd25(SdCard *pSd,
                           unsigned short nbBlock,
                           unsigned char *pData,
                           unsigned int address)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response;

    TRACE_DEBUG("Cmd25()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_WRITE_MULTIPLE_BLOCK_CMD;
    pCommand->arg = address;
    pCommand->blockSize = SD_BLOCK_SIZE;
    pCommand->nbBlock = nbBlock;
    pCommand->pData = (unsigned char *) pData;
    pCommand->conTrans = SPI_NEW_TRANSFER;
    pCommand->resType = 1;
    pCommand->pResp = &response;

    // Set SD command state
    pSd->state = SD_STATE_RCV;

    // Send command
    //return SendCommand(pSd);
    error = SendCommand(pSd);

    error = SD_SPI_R1((unsigned char *)&response);
    return error;
}


//------------------------------------------------------------------------------
/// Initialization delay: The maximum of 1 msec, 74 clock cycles and supply
/// ramp up time.
/// Returns the command transfer result (see SendCommand).
/// \param pSd  Pointer to a SD card driver instance.
//------------------------------------------------------------------------------
static unsigned char Cmd55(SdCard *pSd)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response;

    TRACE_DEBUG("Cmd55()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_APP_CMD;
    pCommand->resType = 1;
    pCommand->pResp = &response;
    // Set SD command state
    pSd->state = SD_STATE_STBY;

    // Send command
    //return SendCommand(pSd);
    error = SendCommand(pSd);
    error = SD_SPI_R1((unsigned char *)&response);
    return error;
}

//------------------------------------------------------------------------------
/// SPI Mode, Reads the OCR register of a card
/// Returns the command transfer result (see SendCommand).
/// \param pSd  Pointer to a SD card driver instance.
/// \param pOcr   OCR value of the card
//------------------------------------------------------------------------------
static unsigned char Cmd58(SdCard *pSd, unsigned int *pOcr)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response[2];

    TRACE_DEBUG("Cmd58()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_READ_OCR_CMD;
    pCommand->resType = 3;
    pCommand->pResp = &response[0];

    // Set SD command state
    pSd->state = SD_STATE_STBY;

    // Send command
    error = SendCommand(pSd);
    error = SD_SPI_R3((unsigned char *)&response, pOcr);
    return error;
}

//------------------------------------------------------------------------------
/// SPI Mode, Set CRC option of a card
/// Returns the command transfer result (see SendCommand).
/// \param pSd  Pointer to a SD card driver instance.
/// \param option  CRC option, 1 to turn on, 0 to trun off
//------------------------------------------------------------------------------
static unsigned char Cmd59(SdCard *pSd, unsigned char option)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response;

    TRACE_DEBUG("Cmd59()\n\r");
    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->cmd = AT91C_CRC_ON_OFF_CMD;
    pCommand->arg = (option & 0x1);
    pCommand->resType = 1;
    pCommand->pResp = &response;

    // Set SD command state
    pSd->state = SD_STATE_STBY;

    // Send command
    error = SendCommand(pSd);
    error = SD_SPI_R1((unsigned char *)&response);
    return error;
}

//------------------------------------------------------------------------------
/// Asks to all cards to send their operations conditions.
/// Returns the command transfer result (see SendCommand).
/// \param pSd  Pointer to a SD card driver instance.
/// \param hcs  Shall be true if Host support High capacity.
/// \param pCCS  Set the pointed flag to 1 if hcs != 0 and SD OCR CCS flag is set.
//------------------------------------------------------------------------------
static unsigned char Acmd41(SdCard *pSd, unsigned char hcs, unsigned char *pCCS)
{
    SdCmd *pCommand = &(pSd->command);
    unsigned char error;
    unsigned int response;

    do {
        error = Cmd55(pSd);
        if (error) {
            return error;
        }

        memset(pCommand, 0, sizeof(SdCmd));
        // Fill command information
        pCommand->cmd = AT91C_SDCARD_APP_OP_COND_CMD;
        pCommand->arg = AT91C_MMC_HOST_VOLTAGE_RANGE;
        if (hcs) {
            pCommand->arg |= AT91C_CCS;
        }

        pCommand->resType = 1;
        pCommand->pResp = &response;

        // Set SD command state
        pSd->state = SD_STATE_STBY;

        // Send command
        TRACE_DEBUG("Acmd41()\n\r");
        error = SendCommand(pSd);
        if (error) {
            return error;
        }
        error = SD_SPI_R1((unsigned char *)&response);
        if (error) {
            return error;
        }
        // continue if in idle mode
        if ((response & 0x1) != 0) { // R1_SPI_IDLE
            continue;
        }
        *pCCS  = ((response & AT91C_CCS) != 0);
        return 0;
    }
    while ((response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY);

    return 0;
}


//------------------------------------------------------------------------------
/// Continue to transfer datablocks from card to host until interrupted by a
/// STOP_TRANSMISSION command.
/// \param pSd  Pointer to a SD card driver instance.
/// \param blockSize  Block size (shall be set to 512 in case of high capacity).
/// \param pData  Pointer to the application buffer to be filled.
/// \param address  SD card address.
//------------------------------------------------------------------------------
static unsigned char ContinuousRead(SdCard *pSd,
                                    unsigned short nbBlock,
                                    unsigned char *pData,
                                    unsigned int address)
{
    SdCmd *pCommand = &(pSd->command);

    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->blockSize = SD_BLOCK_SIZE;
    pCommand->nbBlock = nbBlock;
    pCommand->pData = pData;
    pCommand->isRead = 1;
    pCommand->conTrans = SPI_CONTINUE_TRANSFER;
    // Set SD command state
    pSd->state = SD_STATE_DATA;

    // Send command
    return SendCommand(pSd);
}

//------------------------------------------------------------------------------
/// Continue to transfer datablocks from host to card until interrupted by a
/// STOP_TRANSMISSION command.
/// \param pSd  Pointer to a SD card driver instance.
/// \param blockSize  Block size (shall be set to 512 in case of high capacity).
/// \param pData  Pointer to the application buffer to be filled.
/// \param address  SD card address.
//------------------------------------------------------------------------------
static unsigned char ContinuousWrite(SdCard *pSd,
                                     unsigned short nbBlock,
                                     const unsigned char *pData,
                                     unsigned int address)
{
    SdCmd *pCommand = &(pSd->command);

    memset(pCommand, 0, sizeof(SdCmd));
    // Fill command information
    pCommand->blockSize = SD_BLOCK_SIZE;
    pCommand->nbBlock = nbBlock;
    pCommand->pData = (unsigned char *) pData;
    pCommand->isRead = 0;
    pCommand->conTrans = SPI_CONTINUE_TRANSFER;
    // Set SD command state
    pSd->state = SD_STATE_RCV;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -