本帖最后由 gaoke231 于 2020-3-31 23:04 编辑
在卡中指定地址写一个块
- 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);
- }
|