12
返回列表 发新帖

GD32 SD卡驱动

[复制链接]
楼主: chenqiang10
 楼主 | 2018-9-30 19:51 | 显示全部楼层
static SD_Err Check_Err_R1(uint8_t cmd)
{
    SD_Err Status = SD_OK;
    uint32_t status;
    uint32_t response_r1;

    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);
    }

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

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

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

    if ((response_r1 & SD_R1_ERRORBITS) == SD_ALLZERO)//no error
    {
        return(Status);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return(Status);
}
 楼主 | 2018-9-30 19:52 | 显示全部楼层
static SD_Err Check_Err_R3(void)
{
    SD_Err Status = SD_OK;
    uint32_t status;

    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);
    }

    /* Clear all the static flags */
    SDIO_ClearBitState(SDIO_STATIC_FLAGS);
    return(Status);
}
 楼主 | 2018-9-30 19:52 | 显示全部楼层
static SD_Err Check_Err_R2(void)
{
    SD_Err Status = SD_OK;
    uint32_t status;

    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);
    }

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

    return(Status);
}
 楼主 | 2018-9-30 19:52 | 显示全部楼层
static SD_Err Check_Err_R6(uint8_t cmd, uint16_t *prca)
{
    SD_Err Status = SD_OK;
    uint32_t status;
    uint32_t response_r1;

    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);
    }

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

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

    /* We have received response, retrieve it.  */
    response_r1 = SDIO_GetResponse(SDIO_RESP1);

    if (SD_ALLZERO == (response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)))
    {
        *prca = (uint16_t) (response_r1 >> 16);
        return(Status);
    }

    if (response_r1 & SD_R6_GENERAL_UNKNOWN_ERROR)
    {
        return(SD_GENERAL_UNKNOWN_ERROR);
    }
   
    if (response_r1 & SD_R6_ILLEGAL_CMD)
    {
        return(SD_ILLEGAL_CMD);
    }
   
    if (response_r1 & SD_R6_COM_CRC_FAILED)
    {
        return(SD_COM_CRC_FAILED);
    }

    return(Status);
}
 楼主 | 2018-9-30 19:53 | 显示全部楼层
static SD_Err WideBus_Enable(TypeState NewState)
{
    SD_Err Status = SD_OK;

    /* Check whether the card is locked */
    if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
    {
        Status = SD_LOCK_UNLOCK_FAILED;
        return(Status);
    }

    /* Get SCR Register */
    Status = Get_SCR(RCA, Scr);

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

    /* If wide bus operation to be enabled */
    if (NewState == ENABLE)
    {
        /* If requested card supports wide bus operation */
        if ((Scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO)
        {
            /* Send CMD55 APP_CMD with argument as card's RCA.*/
            SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
            SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
            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_APP_CMD);

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

            /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
            SDIO_CmdInitStructure.SDIO_CMDParameter = 0x2;
            SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_SD_SET_BUSWIDTH;
            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_APP_SD_SET_BUSWIDTH);
            
            if (Status != SD_OK)
            {
                return(Status);
            }
            return(Status);
        }
        else
        {
            Status = SD_REQUEST_NOT_APPLICABLE;
            return(Status);
        }
    }   /* If wide bus operation to be disabled */
    else
    {
        /* If requested card supports 1 bit mode operation */
        if ((Scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO)
        {
            /* Send CMD55 APP_CMD with argument as card's RCA.*/
            SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
            SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
            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_APP_CMD);
            if (Status != SD_OK)
            {
                return(Status);
            }

            /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
            SDIO_CmdInitStructure.SDIO_CMDParameter = 0x00;
            SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_SD_SET_BUSWIDTH;
            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_APP_SD_SET_BUSWIDTH);
            if (Status != SD_OK)
            {
                return(Status);
            }
            return(Status);
        }
        else
        {
            Status = SD_REQUEST_NOT_APPLICABLE;
            return(Status);
        }
    }
}
 楼主 | 2018-9-30 19:53 | 显示全部楼层
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);
}
 楼主 | 2018-9-30 19:53 | 显示全部楼层
static SD_Err Get_SCR(uint16_t rca, uint32_t *pscr)
{
    uint32_t index = 0;
    SD_Err Status = SD_OK;
    uint32_t tempscr[2] = {0, 0};

    /* Set Block Size To 8 Bytes */
    /* Send CMD8 SDIO_SET_BLOCKLEN to set block size */
    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);

    Status = Check_Err_R1(SDIO_SET_BLOCKLEN);

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

    /* CMD55 APP_CMD the next command is Application Specific Command */
    SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) RCA << 16;
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_APP_CMD;
    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_APP_CMD);
    if (Status != SD_OK)
    {
        return(Status);
    }

    /* 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_TOSDIO;
    SDIO_DataInitStructure.SDIO_TransMode = SDIO_TRANSMODE_BLOCK;
    SDIO_DataInitStructure.SDIO_DSMState = SDIO_DSMSTATE_ENABLE;
    SDIO_DataConfig(&SDIO_DataInitStructure);

    /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
    SDIO_CmdInitStructure.SDIO_CMDParameter = 0x0;
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_SD_APP_SEND_SCR;
    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_SD_APP_SEND_SCR);
    if (Status != SD_OK)
    {
        return(Status);
    }

    while (!(SDIO->STR & (SDIO_FLAG_RXORE | SDIO_FLAG_DTCRCFAIL | SDIO_FLAG_DTTMOUT | SDIO_FLAG_DTBLKEND | SDIO_FLAG_STBITE)))
    {
        if (SDIO_GetBitState(SDIO_FLAG_RXDTVAL) != RESET)
        {
            *(tempscr + index) = SDIO_ReadData();
            index++;
        }
    }

    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_RXORE) != RESET)
    {
        SDIO_ClearBitState(SDIO_FLAG_RXORE);
        Status = SD_RX_OVERRUN;
        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);

    *(pscr + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) | ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24);

    *(pscr) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) | ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24);

    return(Status);
}
 楼主 | 2018-9-30 19:54 | 显示全部楼层
static uint8_t Bytes_To_PowerTwo(uint16_t NumberOfBytes)
{
    uint8_t count = 0;

    while (NumberOfBytes != 1)
    {
        NumberOfBytes >>= 1;
        count++;
    }
    return(count);
}
 楼主 | 2018-9-30 19:54 | 显示全部楼层
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);
}
 楼主 | 2018-9-30 19:54 | 显示全部楼层
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);

}
 楼主 | 2018-9-30 19:54 | 显示全部楼层
static void DMA_RxConfiguration(uint32_t *BufferDST, 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)BufferDST;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC;
    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);
}
 楼主 | 2018-9-30 19:55 | 显示全部楼层
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);
}
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

快速回复 返回顶部 返回列表