SD_Err SD_WriteBlock(uint32_t addr, uint32_t *writebuff, uint16_t BlockSize) 
{ 
    SD_Err Status = SD_OK; 
    uint8_t  power = 0, cardstate = 0; 
    uint32_t timeout = 0, bytestransferred = 0; 
    uint32_t cardstatus = 0, count = 0, restwords = 0; 
    uint32_t *tempbuff = writebuff; 
 
    if (writebuff == NULL) 
    { 
        Status = SD_INVALID_PARAMETER; 
        return(Status); 
    } 
 
    TransferError = SD_OK; 
    TransferEnd = 0; 
    TotalNumberOfBytes = 0; 
 
    /* 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); 
 
    /* Check whether the card is locked */ 
    if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) 
    { 
        Status = SD_LOCK_UNLOCK_FAILED; 
        return(Status); 
    } 
 
    /* SDHC card the blocksize is fixed in 512B */ 
    if (CardType == SDIO_HIGH_CAPACITY_SD_CARD) 
    { 
        BlockSize = 512; 
        addr /= 512; 
    } 
 
    /* Set the block size, both on controller and card */ 
    if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))  
    { 
        power = Bytes_To_PowerTwo(BlockSize); 
 
        /* CMD16 Set Block Size for Card */ 
        SDIO_CmdInitStructure.SDIO_CMDParameter = (uint32_t) BlockSize; 
        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); 
        } 
    } 
    else 
    { 
        Status = SD_INVALID_PARAMETER; 
        return(Status); 
    } 
 
    /* Wait till card is ready for writing data */ 
    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); 
 
    timeout = 10000; 
 
    while (((cardstatus & 0x00000100) == 0) && (timeout > 0)) 
    { 
        /* Card is busy, continue to send 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); 
    } 
 
    /* Polling timeout */ 
    if (timeout == 0) 
    { 
        return(SD_ERROR); 
    } 
 
    /* Send CMD24 WRITE_SINGLE_BLOCK */ 
    SDIO_CmdInitStructure.SDIO_CMDParameter = addr; 
    SDIO_CmdInitStructure.SDIO_CMDIndex = SDIO_WRITE_SINGLE_BLOCK; 
    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_WRITE_SINGLE_BLOCK); 
    if (Status != SD_OK) 
    { 
        return(Status); 
    } 
 
    TotalNumberOfBytes = BlockSize; 
    StopCondition = 0; 
    SrcBuffer = writebuff; 
 
    /* SDIO data transmisson config */ 
    SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT; 
    SDIO_DataInitStructure.SDIO_DataLength = BlockSize; 
    SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) power << 4; 
    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); 
 
 
    /* In case of single data block transfer no need of stop command at all */ 
    if (TransmissionMode == SD_POLLING_MODE) 
    { 
        /* Polling mode */ 
        while (!(SDIO->STR & (SDIO_FLAG_DTBLKEND | SDIO_FLAG_TXURE | SDIO_FLAG_DTCRCFAIL | SDIO_FLAG_DTTMOUT | SDIO_FLAG_STBITE))) 
        { 
            if (SDIO_GetBitState(SDIO_FLAG_TXFIFOHE) != RESET) 
            { 
                if ((TotalNumberOfBytes - bytestransferred) < 32) 
                { 
                    restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) : (( TotalNumberOfBytes -  bytestransferred) / 4 + 1); 
 
                    for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4) 
                    { 
                        SDIO_WriteData(*tempbuff); 
                    } 
                } 
                else 
                { 
                    for (count = 0; count < 8; count++) 
                    { 
                        SDIO_WriteData(*(tempbuff + count)); 
                    } 
                    tempbuff += 8; 
                    bytestransferred += 32; 
                } 
            } 
        } 
        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); 
        } 
    } 
    else if (TransmissionMode == SD_DMA_MODE) 
    { 
        /* DMA mode */ 
        /* Enable SDIO corresponding interrupts */ 
        SDIO_INTConfig(SDIO_INT_DTCRCFAIL | SDIO_INT_DTTMOUT | SDIO_INT_DTEND | SDIO_INT_TXURE | SDIO_INT_STBITE, ENABLE); 
 
        DMA_TxConfiguration(writebuff, BlockSize); 
 
        /* Enable the DMA of SDIO */ 
        SDIO_DMA_Enable(ENABLE); 
 
        while (DMA_GetBitState(DMA2_FLAG_TC4) == RESET) 
        {} 
 
        while ((TransferEnd == 0) && (TransferError == SD_OK)) 
        {} 
 
        if (TransferError != SD_OK) 
        { 
            return(TransferError); 
        } 
    } 
 
    /* 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); 
} 
 |