发新帖我要提问
12
返回列表

GD32F207 操作SD卡

[复制链接]
楼主: gaoke231
手机看帖
扫描二维码
随时随地手机跟帖
gaoke231|  楼主 | 2020-3-31 23:14 | 显示全部楼层
检查SD可卡是不是出于运行状态
static SD_Err IsCardProgramming(uint8_t *pstatus)
{
    SD_Err Status = SD_OK;
    __IO uint32_t respR1 = 0, status = 0;

    /* CMD13 to polling the state of the card */
    SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
    SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
    SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
    SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
    SDIO_SendCMD(&SDIO_CmdInitStructure);

    status = SDIO->STR;
    while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CMDTMOUT)))
    {
        status = SDIO->STR;
    }

    if (status & SDIO_FLAG_CMDTMOUT)
    {
        Status = SD_CMD_RSP_TIMEOUT;
        SDIO_ClearBitState(SDIO_FLAG_CMDTMOUT);
        return(Status);
    }
    else if (status & SDIO_FLAG_CCRCFAIL)
    {
        Status = SD_CMD_CRC_FAIL;
        SDIO_ClearBitState(SDIO_FLAG_CCRCFAIL);
        return(Status);
    }

    status = (uint32_t)SDIO_GetCMDResponse();

    /* Check response received is of desired command */
    if (status != SDIO_SEND_STATUS)
    {
        Status = SD_ILLEGAL_CMD;
        return(Status);
    }

    /* Clear all the static flags */
    SDIO_ClearBitState(SDIO_STATIC_FLAGS);


    /* We have received response, retrieve it for analysis  */
    respR1 = SDIO_GetResponse(SDIO_RESP1);

    /* Find out card status */
    *pstatus = (uint8_t) ((respR1 >> 9) & 0x0000000F);

    if ((respR1 & SD_R1_ERRORBITS) == SD_ALLZERO)
    {
        return(Status);
    }

    if (respR1 & SD_R1_ADDR_OUT_OF_RANGE)
    {
        return(SD_ADDR_OUT_OF_RANGE);
    }

    if (respR1 & SD_R1_ADDR_MISALIGNED)
    {
        return(SD_ADDR_MISALIGNED);
    }

    if (respR1 & SD_R1_BLOCK_LEN_ERR)
    {
        return(SD_BLOCK_LEN_ERR);
    }

    if (respR1 & SD_R1_ERASE_SEQ_ERR)
    {
        return(SD_ERASE_SEQ_ERR);
    }

    if (respR1 & SD_R1_BAD_ERASE_PARAM)
    {
        return(SD_BAD_ERASE_PARAM);
    }

    if (respR1 & SD_R1_WRITE_PROT_VIOLATION)
    {
        return(SD_WRITE_PROT_VIOLATION);
    }

    if (respR1 & SD_R1_LOCK_UNLOCK_FAILED)
    {
        return(SD_LOCK_UNLOCK_FAILED);
    }

    if (respR1 & SD_R1_COM_CRC_FAILED)
    {
        return(SD_COM_CRC_FAILED);
    }

    if (respR1 & SD_R1_ILLEGAL_CMD)
    {
        return(SD_ILLEGAL_CMD);
    }

    if (respR1 & SD_R1_CARD_ECC_FAILED)
    {
        return(SD_CARD_ECC_FAILED);
    }

    if (respR1 & SD_R1_CC_ERROR)
    {
        return(SD_CC_ERROR);
    }

    if (respR1 & SD_R1_GENERAL_UNKNOWN_ERROR)
    {
        return(SD_GENERAL_UNKNOWN_ERROR);
    }

    if (respR1 & SD_R1_STREAM_READ_UNDERRUN)
    {
        return(SD_STREAM_READ_UNDERRUN);
    }

    if (respR1 & SD_R1_STREAM_WRITE_OVERRUN)
    {
        return(SD_STREAM_WRITE_OVERRUN);
    }

    if (respR1 & SD_R1_CID_CSD_OVERWRIETE)
    {
        return(SD_CID_CSD_OVERWRITE);
    }

    if (respR1 & SD_R1_WP_ERASE_SKIP)
    {
        return(SD_WP_ERASE_SKIP);
    }

    if (respR1 & SD_R1_CARD_ECC_DISABLED)
    {
        return(SD_CARD_ECC_DISABLED);
    }

    if (respR1 & SD_R1_ERASE_RESET)
    {
        return(SD_ERASE_RESET);
    }

    if (respR1 & SD_R1_AKE_SEQ_ERROR)
    {
        return(SD_AKE_SEQ_ERROR);
    }

    return(Status);
}


使用特权

评论回复
gaoke231|  楼主 | 2020-3-31 23:15 | 显示全部楼层
初始化SD卡的GPIO
static void GPIO_Configuration(void)
{
    GPIO_InitPara  GPIO_InitStructure;

    /* Enable GPIOC and GPIOD clock */
    RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOC | RCC_APB2PERIPH_GPIOD, ENABLE);

    /* Configure relative ports(PC8, PC9, PC10, PC11, PC12: D0, D1, D2, D3, CLK pin) */
    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /* Configure PD2(CMD line) */
    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_2;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}


使用特权

评论回复
gaoke231|  楼主 | 2020-3-31 23:16 | 显示全部楼层
初始化DMA 作为SDIO传输
static void DMA_TxConfiguration(uint32_t *BufferSRC, uint32_t BufferSize)
{
    DMA_InitPara DMA_InitStructure;

    DMA_ClearBitState(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);

    /* DMA2 Channel4 disable */
    DMA_Enable(DMA2_CHANNEL4, DISABLE);

    /* DMA2 Channel4 Config */
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferSRC;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;
    DMA_InitStructure.DMA_BufferSize = BufferSize / 4;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_WORD;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_WORD;
    DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;
    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
    DMA_Init(DMA2_CHANNEL4, &DMA_InitStructure);

    /* DMA2 Channel4 enable */
    DMA_Enable(DMA2_CHANNEL4, ENABLE);

}


使用特权

评论回复
gaoke231|  楼主 | 2020-3-31 23:17 | 显示全部楼层
SD卡上锁
SD_Err SD_Lock_Unlock(uint8_t lockstate)
{
    SD_Err Status = SD_OK;
    u8 cardstate = 0;
    u32 pwd1,pwd2,cardstatus,timeout;

    /* Check if the card command class supports Lock/Unlock command */
    if ((SD_CCC_LOCK_UNLOCK&SDIOInfo.SD_csd.CardComdClasses) == 0)
    {
        Status = SD_REQUEST_NOT_APPLICABLE;
        return(Status);
    }
    /* PWD pattern */
    pwd1 = (0x01020600|lockstate);
    pwd2 = 0x03040506;

    /* Clear all DSM configuration */
    SDIO_DataInitStructure.SDIO_DataTimeOut = 0;
    SDIO_DataInitStructure.SDIO_DataLength = 0;
    SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_1B;
    SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
    SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
    SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_DISABLE;
    SDIO_DataConfig(&SDIO_DataInitStructure);
    SDIO_DMA_Enable(DISABLE);

    /* CMD16 Set Block Size for Card */
    SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) 8;
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SET_BLOCKLEN;
    SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
    SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
    SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
    SDIO_SendCMD(&SDIO_CmdInitStructure);

    /* Check CMD errors */
    Status = Check_Err_R1(SDIO_SET_BLOCKLEN);
    if (Status != SD_OK)
    {
        return(Status);
    }

    cardstatus = SDIO_GetResponse(SDIO_RESP1);

    /* Wait till card is ready for data writing */
    SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
    SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
    SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
    SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
    SDIO_SendCMD(&SDIO_CmdInitStructure);

    Status = Check_Err_R1(SDIO_SEND_STATUS);

    if (Status != SD_OK)
    {
        return(Status);
    }

    cardstatus = SDIO_GetResponse(SDIO_RESP1);

    timeout = 10000;

    while (((cardstatus & 0x00000100) == 0) && (timeout > 0))
    {
        /* CMD13 to polling the state of the card */
        timeout--;
        SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) (RCA << 16);
        SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SEND_STATUS;
        SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
        SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
        SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
        SDIO_SendCMD(&SDIO_CmdInitStructure);

        /* Check CMD errors */
        Status = Check_Err_R1(SDIO_SEND_STATUS);
        if (Status != SD_OK)
        {
            return(Status);
        }

        cardstatus = SDIO_GetResponse(SDIO_RESP1);
    }

    if (timeout == 0)
    {
        return(SD_ERROR);
    }

     /* CMD42 LOCK_UNLOCK */
    SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t)0x00000000;
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_LOCK_UNLOCK;
    SDIO_CmdInitStructure.SDIO_ResponseType = SDIO_RESPONSETYPE_SHORT;
    SDIO_CmdInitStructure.SDIO_WaitINTState = SDIO_WAITINTSTATE_NO;
    SDIO_CmdInitStructure.SDIO_CSMState = SDIO_CSMSTATE_ENABLE;
    SDIO_SendCMD(&SDIO_CmdInitStructure);

    /* Check CMD errors */
    Status = Check_Err_R1(SDIO_LOCK_UNLOCK);
    if (Status != SD_OK)
    {
        return(Status);
    }

    cardstatus = SDIO_GetResponse(SDIO_RESP1);

    /* SDIO data transmisson config */
    SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
    SDIO_DataInitStructure.SDIO_DataLength = 8;
    SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DATABLOCKSIZE_8B;
    SDIO_DataInitStructure.SDIO_TransDirection = SDIO_TRANSDIRECTION_TOCARD;
    SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
    SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
    SDIO_DataConfig(&SDIO_DataInitStructure);

    /* Write PWD pattern */
    SDIO_WriteData(pwd1);
    SDIO_WriteData(pwd2);

    if (SDIO_GetBitState(SDIO_FLAG_DTTMOUT) != RESET)
    {
        SDIO_ClearBitState(SDIO_FLAG_DTTMOUT);
        Status = SD_DATA_TIMEOUT;
        return(Status);
    }
    else if (SDIO_GetBitState(SDIO_FLAG_DTCRCFAIL) != RESET)
    {
        SDIO_ClearBitState(SDIO_FLAG_DTCRCFAIL);
        Status = SD_DATA_CRC_FAIL;
        return(Status);
    }
    else if (SDIO_GetBitState(SDIO_FLAG_TXURE) != RESET)
    {
        SDIO_ClearBitState(SDIO_FLAG_TXURE);
        Status = SD_TX_UNDERRUN;
        return(Status);
    }
    else if (SDIO_GetBitState(SDIO_FLAG_STBITE) != RESET)
    {
        SDIO_ClearBitState(SDIO_FLAG_STBITE);
        Status = SD_START_BIT_ERR;
        return(Status);
    }

    /* Clear all the static flags */
    SDIO_ClearBitState(SDIO_STATIC_FLAGS);

    /* Wait till the card is in programming state */
    Status = IsCardProgramming(&cardstate);
    while ((Status == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
    {
        Status = IsCardProgramming(&cardstate);
    }

    return(Status);
}


使用特权

评论回复
renzheshengui| | 2020-4-7 14:13 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
wakayi| | 2020-4-7 14:13 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
wowu| | 2020-4-7 14:14 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
xiaoqizi| | 2020-4-7 14:14 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
磨砂| | 2020-4-7 14:14 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则