From cdc0c59a3f49724611bed98f54400c7e53d74591 Mon Sep 17 00:00:00 2001 From: YuanHongbin <975559679@qq.com> Date: Fri, 15 May 2026 13:46:05 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=88=A0=E9=99=A4AD7924=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=96=87=E4=BB=B6=202=E3=80=81=E5=88=A0=E9=99=A4SDCar?= =?UTF-8?q?d=E7=9B=AE=E5=BD=95=E6=96=87=E4=BB=B6=203=E3=80=81=E5=88=A0?= =?UTF-8?q?=E9=99=A4SHT20=E7=9B=AE=E5=BD=95=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/GateWay/source/Module/AD7924/ad7924.c | 2 - .../GateWay/source/Module/SDCard/sd_card.c | 1319 ------------- .../GateWay/source/Module/SDCard/sd_card.h | 404 ---- .../GateWay/source/Module/SDCard/sd_card_1.c | 1268 ------------- .../GateWay/source/Module/SDCard/sdmmc_cmd.c | 1641 ----------------- .../GateWay/source/Module/SDCard/sdmmc_cmd.h | 311 ---- .../source/Module/SDCard/sdmmc_cmd_1.c | 1641 ----------------- Project/GateWay/source/Module/SHT20/SHT20.C | 615 ------ Project/GateWay/source/Module/SHT20/SHT20.H | 156 -- 9 files changed, 7357 deletions(-) delete mode 100644 Project/GateWay/source/Module/AD7924/ad7924.c delete mode 100644 Project/GateWay/source/Module/SDCard/sd_card.c delete mode 100644 Project/GateWay/source/Module/SDCard/sd_card.h delete mode 100644 Project/GateWay/source/Module/SDCard/sd_card_1.c delete mode 100644 Project/GateWay/source/Module/SDCard/sdmmc_cmd.c delete mode 100644 Project/GateWay/source/Module/SDCard/sdmmc_cmd.h delete mode 100644 Project/GateWay/source/Module/SDCard/sdmmc_cmd_1.c delete mode 100644 Project/GateWay/source/Module/SHT20/SHT20.C delete mode 100644 Project/GateWay/source/Module/SHT20/SHT20.H diff --git a/Project/GateWay/source/Module/AD7924/ad7924.c b/Project/GateWay/source/Module/AD7924/ad7924.c deleted file mode 100644 index e4d51f1..0000000 --- a/Project/GateWay/source/Module/AD7924/ad7924.c +++ /dev/null @@ -1,2 +0,0 @@ -#include "bps.h" - diff --git a/Project/GateWay/source/Module/SDCard/sd_card.c b/Project/GateWay/source/Module/SDCard/sd_card.c deleted file mode 100644 index 02945a0..0000000 --- a/Project/GateWay/source/Module/SDCard/sd_card.c +++ /dev/null @@ -1,1319 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - */ -/******************************************************************************/ -/** \file sd_card.c - ** - ** A detailed description is available at - ** @link SdiocGroup SDIOC description @endlink - ** - ** - 2018-11-15 CDT First version for Device Driver Library of SDIOC. - ** - ******************************************************************************/ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "sdmmc_cmd.h" -#include "sd_card.h" - -/** - ******************************************************************************* - ** \addtogroup SdiocGroup - ******************************************************************************/ -//@{ - -/******************************************************************************* - * Local type definitions ('typedef') - ******************************************************************************/ -typedef enum en_sd_card_type -{ - SdCardSdsc = 0u, - SdCardSdhcSdxc = 1u, - SdCardSecured = 3u, -} en_sd_card_type_t; - -/******************************************************************************* - * Local pre-processor symbols/macros ('#define') - ******************************************************************************/ - -/*!< Card Command Class supported. */ -#define SDMMC_CARD_CCCC_ERASE (0x00000020u) - -/*!< Card locked */ -#define SDMMC_CARD_LOCKED (0x02000000u) - -/*!< Voltage trial times */ -#define SD_CARD_MAX_VOLT_TRIAL (0x0000FFFFu) - -/*!< High speed */ -#define SD_CHECK_FUNCTION_HIGH_SPEED (0x00FFFF01u) -#define SD_SET_FUNCTION_HIGH_SPEED (0x80FFFF01u) - -/*!< Block size is 512 bytes */ -#define SD_CARD_BLOCK_SIZE (512u) - -/*!< SDIOC buffer align size */ -#define SDIOC_BUF_ALIGN_SIZE (4ul) - -/*!< Log Block Number for 2G bytes Cards */ -#define SD_CARD_CAPACITY (0x400000u) - -/*!< Card power up status bit (busy) */ -#define SD_CARD_OCR_BUSY (0x80000000ul) - -#define SD_CARD_OP_NONE (0x00000000u) /*!< None */ -#define SD_CARD_OP_READ_SINGLE_BLOCK (0x00000001u) /*!< Read single block operation */ -#define SD_CARD_OP_READ_MULTIPLE_BLOCK (0x00000002u) /*!< Read multiple blocks operation */ -#define SD_CARD_OP_WRITE_SINGLE_BLOCK (0x00000010u) /*!< Write single block operation */ -#define SD_CARD_OP_WRITE_MULTIPLE_BLOCK (0x00000020u) /*!< Write multiple blocks operation */ -#define SD_CARD_OP_IT (0x00000008u) /*!< Process in Interrupt mode */ -#define SD_CARD_OP_DMA (0x00000080u) /*!< Process in DMA mode */ - -/*!< the SD card relative card address. */ -#define RelCardAddress(handle) ((handle)->stcSdCardInfo.u32RelCardAddr) -#define IsCardProgramming(handle) ((SdmmcCardStatePgm == (handle)->stcCardStatus.CURRENT_STATE) ? true : false) -#define IsCardReadyForData(handle) ((1u == (handle)->stcCardStatus.READY_FOR_DATA) ? true : false) - -#define IS_DMA_CFG_VALID(handle) \ -( (NULL != (handle)->pstcDmaInitCfg) && \ - (NULL != (handle)->pstcDmaInitCfg->DMAx)) - -/*!< the SD card use DMA unit && channel. */ -#define DMA_Unit(handle) ((handle)->pstcDmaInitCfg->DMAx) -#define DMA_CH(handle) ((handle)->pstcDmaInitCfg->enDmaCh) - -/*!< Parameter valid check for buffer address. */ -#define IS_VALID_TRANSFER_BUF_ALIGN(x) (!((SDIOC_BUF_ALIGN_SIZE-1ul) & ((uint32_t)(x)))) - -/*!< Parameter valid check for SDIOC command value. */ -#define IS_VALID_TRANSFER_BUF_LEN(x) (!((SD_CARD_BLOCK_SIZE - 1u) & (x))) - -/******************************************************************************* - * Global variable definitions (declared in header file with 'extern') - ******************************************************************************/ - -/******************************************************************************* - * Local function prototypes ('static') - ******************************************************************************/ -static en_result_t SdCardInitSd(stc_sd_handle_t *handle); -static en_result_t SdCardPowerON(stc_sd_handle_t *handle); -static en_result_t SdCardInitHost(const stc_sd_handle_t *handle); -static en_result_t SdCardSetSpeed(stc_sd_handle_t *handle); -static en_result_t SdCardSetBusWidth(stc_sd_handle_t *handle); -static en_result_t SdCardCheckReayForData(stc_sd_handle_t *handle, - uint32_t u32Timeout); -static en_result_t DmaSdiocTxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8TxBuf, - uint16_t u16len); -static en_result_t DmaSdiocRxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8RxBuf, - uint16_t u16len); - -/******************************************************************************* - * Local variable definitions ('static') - ******************************************************************************/ - -/******************************************************************************* - * Function implementation - global ('extern') and local ('static') - ******************************************************************************/ - -/** - ******************************************************************************* - ** \brief Initialize SD. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] pstcInitCfg The pointer of SD configure structure - ** \arg This parameter detail refer @ref stc_sdcard_init_t - ** - ** \retval Ok Initialize SD successfully. - ** \retval Error Initialize SD unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - pstcInitCfg == NULL - ** - ******************************************************************************/ -en_result_t SDCARD_Init(stc_sd_handle_t *handle, - const stc_sdcard_init_t *pstcInitCfg) -{ - en_result_t enRet = ErrorInvalidParameter; - - if ((NULL != handle) && (NULL != pstcInitCfg)) - { - handle->pstcCardInitCfg = pstcInitCfg; - - enRet = SdCardInitHost(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardPowerON(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardInitSd(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardSetBusWidth(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardSetSpeed(handle); - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Set SD Card device Read/Write mode. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] enDevMode Read/Write mode - ** \arg SdCardDmaMode DMA mode transfer - ** \arg SdCardPollingMode Polling mode transfer - ** - ** \retval Ok Set successfully. - ** \retval ErrorInvalidParameter handle pointer is NULL. - ** - ******************************************************************************/ -en_result_t SDCARD_SetDeviceMode(stc_sd_handle_t *handle, - en_sd_card_device_mode_t enDevMode) -{ - en_result_t enRet = ErrorInvalidParameter; - - if (NULL != handle) - { - handle->enDevMode = enDevMode; - enRet = Ok; - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get SD Card device Read/Write mode. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval SdCardDmaMode DMA mode transfer - ** \retval SdCardPollingMode Polling mode transfer - ** - ******************************************************************************/ -en_sd_card_device_mode_t SDCARD_GetDeviceMode(const stc_sd_handle_t *handle) -{ - DDL_ASSERT(NULL != handle); - - return handle->enDevMode; -} - -/** - ******************************************************************************* - ** \brief Get Card specified Data information. - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Get successfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - ******************************************************************************/ -en_result_t SDCARD_GetCardCSD(stc_sd_handle_t *handle) -{ - uint32_t u32Csize = 0ul; - uint32_t u32NumSector = 0ul; - uint32_t u32CsizeMulti = 0ul; - stc_sdcard_csd_v1_t *pstcCsdSd = NULL; - stc_sdcard_csd_v2_t *pstcCsdSdHc = NULL; - en_result_t enRet = ErrorInvalidParameter; - - if (NULL != handle) - { - /* High Capacity CSD Version 2.0*/ - if ((handle->CSD[3] & 0x00FF0000ul) == 0x00400000ul) - { - pstcCsdSdHc = (stc_sdcard_csd_v2_t *)&handle->CSD[0]; - u32Csize = ((unsigned int)pstcCsdSdHc->C_SIZE3 << 16ul) - + ((unsigned int)pstcCsdSdHc->C_SIZE2 << 8ul) - + pstcCsdSdHc->C_SIZE1; - - u32NumSector = (u32Csize + 1ul) << 10ul; - - handle->stcSdCardInfo.u32Class = (((uint32_t)pstcCsdSdHc->CCC2) << 4u) | ((uint32_t)pstcCsdSdHc->CCC1); - handle->stcSdCardInfo.u32BlockSize = 1ul << (pstcCsdSdHc->READ_BL_LEN); - } - else /* Standard Capacity CSD Version 1.xx */ - { - pstcCsdSd = (stc_sdcard_csd_v1_t *)&handle->CSD[0]; - - u32Csize = ((unsigned int)pstcCsdSd->C_SIZE3 << 10) - + ((unsigned int)pstcCsdSd->C_SIZE2 << 2) - + pstcCsdSd->C_SIZE1; - - u32CsizeMulti = ((uint32_t)(pstcCsdSd->C_SIZE_MULTI2) << 1) + (uint32_t)pstcCsdSd->C_SIZE_MULTI1; - u32NumSector = (u32Csize + 1ul) << (u32CsizeMulti + 2ul); - - if (pstcCsdSd->READ_BL_LEN == 0x0Au) - { - u32NumSector *= 2ul; - } - else if (pstcCsdSd->READ_BL_LEN == 0x0Bu) - { - u32NumSector *= 4ul; - } - else - { - /* Do nothing: only avoid MISRA warning */ - } - - handle->stcSdCardInfo.u32Class = ((uint32_t)pstcCsdSd->CCC2 << 4) | (uint32_t)pstcCsdSd->CCC1; - handle->stcSdCardInfo.u32BlockSize = 1ul << (pstcCsdSd->READ_BL_LEN); - } - - handle->stcSdCardInfo.u32BlockNbr = u32NumSector; - handle->stcSdCardInfo.u32LogBlockNbr = (handle->stcSdCardInfo.u32BlockNbr) * ((handle->stcSdCardInfo.u32BlockSize) / SD_CARD_BLOCK_SIZE); - handle->stcSdCardInfo.u32LogBlockSize = SD_CARD_BLOCK_SIZE; - enRet = Ok; - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Erase SD card blocks. - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32BlkStartAddr Block start address - ** \param [in] u32BlkEndAddr Block end address - ** \param [in] u32Timeout Erase timeout value - ** - ** \retval Ok Erase successfully. - ** \retval Error Erase unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - u32BlkStartAddr out of range - ** - u32BlkEndAddr out of range - ** - ******************************************************************************/ -en_result_t SDCARD_Erase(stc_sd_handle_t *handle, - uint32_t u32BlkStartAddr, - uint32_t u32BlkEndAddr, - uint32_t u32Timeout) -{ - en_result_t enCmdRet = Error; - __IO uint32_t u32TimeCount = u32Timeout * (SystemCoreClock / 8u / 1000u); - - if ((NULL == handle) || - (u32BlkStartAddr > u32BlkEndAddr) || - (u32BlkEndAddr > handle->stcSdCardInfo.u32BlockNbr)) - { - return ErrorInvalidParameter; - } - - /* Check if the card command class supports erase command */ - if (!(handle->stcSdCardInfo.u32Class & SDMMC_CARD_CCCC_ERASE)) - { - return ErrorAccessRights; - } - - if ((SDIOC_GetResponse(handle->SDIOCx, SdiocRegResp01) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) - { - return ErrorAccessRights; - } - - /* Check the Card capacity in term of Logical number of blocks */ - if (handle->stcSdCardInfo.u32CardType != SdCardSdhcSdxc) - { - u32BlkStartAddr *= SD_CARD_BLOCK_SIZE; - u32BlkEndAddr *= SD_CARD_BLOCK_SIZE; - } - - /* Send CMD35 ERASE_GRP_START with argument as address */ - enCmdRet = SDMMC_Cmd32_EraseWrBlkStart(handle->SDIOCx, u32BlkStartAddr, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* Send CMD36 ERASE_GRP_END with argument as address */ - enCmdRet = SDMMC_Cmd33_EraseWrBlkEnd(handle->SDIOCx, u32BlkEndAddr, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SDMMC_Cmd38_Erase(handle->SDIOCx, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SdCardCheckReayForData(handle, u32TimeCount); - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Read block data from SD card - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32BlockAddr Block address - ** \param [in] u16BlockCnt Block Count - ** \param [in] pu8Data Pointer to buffer which will store SD Card data. - ** \param [in] u32Timeout Transfer timeout - ** - ** \retval Ok Read successfully. - ** \retval Error Read unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - pu8Data == NULL - ** - u16BlockCnt == 0 - ** - (u32BlockAddr + u16BlockCnt) out of range - ** - ******************************************************************************/ -en_result_t SDCARD_ReadBlocks(stc_sd_handle_t *handle, - uint32_t u32BlockAddr, - uint16_t u16BlockCnt, - uint8_t *pu8Data, - uint32_t u32Timeout) -{ - en_result_t enCmdRet; - stc_sdioc_data_cfg_t stcDataCfg; - uint8_t *pu8TempBuf = (uint8_t *)pu8Data; - uint32_t u32TimeCount = u32Timeout * (SystemCoreClock / 8u / 1000u); - __IO uint32_t u32Count = u32TimeCount; - en_sd_card_device_mode_t enDeviceMode = SDCARD_GetDeviceMode(handle); - en_flag_status_t enStatus = Reset; - en_flag_status_t enIrqFlag = Reset; - - if (NULL == handle) - { - return ErrorInvalidParameter; - } - - if ((NULL == pu8Data) || (0u == u16BlockCnt)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_PARAM; - return ErrorInvalidParameter; - } - - handle->u32ErrorCode = SD_CARD_ERROR_NONE; - - if ((u32BlockAddr + u16BlockCnt) > (handle->stcSdCardInfo.u32LogBlockNbr)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_ADDR_OUT_OF_RANGE; - return ErrorInvalidParameter; - } - - if (handle->stcSdCardInfo.u32CardType != SdCardSdhcSdxc) - { - u32BlockAddr *= SD_CARD_BLOCK_SIZE; - } - - /* Set Block Size for Card */ - enCmdRet = SDMMC_Cmd16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - stcDataCfg.u16BlkCnt = u16BlockCnt; - stcDataCfg.u16BlkSize = SD_CARD_BLOCK_SIZE; - stcDataCfg.enDataTimeOut = SdiocDtoSdclk_2_27; - stcDataCfg.enTransferDir = SdiocTransferToHost; - stcDataCfg.enAutoCmd12Enable = (u16BlockCnt > 1u) ? Enable:Disable; - stcDataCfg.enTransferMode = (u16BlockCnt > 1u) ? SdiocTransferMultiple:SdiocTransferSingle; - enCmdRet = SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (enDeviceMode == SdCardDmaMode) - { - if (IS_DMA_CFG_VALID(handle)) - { - DmaSdiocRxConfig(DMA_Unit(handle), DMA_CH(handle), handle->SDIOCx, pu8TempBuf, u16BlockCnt * SD_CARD_BLOCK_SIZE); - } - } - - /* Read block(s) in polling mode */ - if (1u == u16BlockCnt) - { - handle->Context = SD_CARD_OP_READ_SINGLE_BLOCK; - /* Read Single Block command */ - enCmdRet = SDMMC_Cmd17_ReadSingleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - else - { - handle->Context = SD_CARD_OP_READ_MULTIPLE_BLOCK; - /* Read Multi Block command */ - enCmdRet = SDMMC_Cmd18_ReadMultipleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (SdCardPollingMode == enDeviceMode) - { - /* Poll on SDIO flags */ - while (u16BlockCnt) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocBufferReadEnble); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocBufferReadReady); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - SDIOC_ReadBuffer(handle->SDIOCx, pu8TempBuf, SD_CARD_BLOCK_SIZE); - - u16BlockCnt--; - u32Count = u32TimeCount; - pu8TempBuf += SD_CARD_BLOCK_SIZE; - } - - if (0ul == u32Count--) - { - return ErrorTimeout; - } - } - } - - for (u32Count = u32TimeCount; u32Count > 0ul; u32Count--) - { - if (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete)) - { - break; - } - } - - if (0ul == u32Count) - { - return ErrorTimeout; - } - else - { - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - } - - /* check whether Data transfer stops */ - if (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocErrorInt)) - { - enCmdRet = Error; - } - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Write block data to SD card - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32BlockAddr Block address - ** \param [in] u16BlockCnt Block Count - ** \param [in] pu8Data Pointer to buffer which contains data to be send to SD Card. - ** \param [in] u32Timeout Transfer timeout - ** - ** \retval Ok Write successfully. - ** \retval Error Write unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - pu8Data == NULL - ** - u16BlockCnt == 0 - ** - (u32BlockAddr + u16BlockCnt) out of range - ** - ******************************************************************************/ -en_result_t SDCARD_WriteBlocks(stc_sd_handle_t *handle, - uint32_t u32BlockAddr, - uint16_t u16BlockCnt, - uint8_t *pu8Data, - uint32_t u32Timeout) -{ - en_result_t enCmdRet; - stc_sdioc_data_cfg_t stcDataCfg; - uint8_t *pu8TempBuf = (uint8_t *)pu8Data; - uint32_t u32TimeCount = u32Timeout * (SystemCoreClock / 50ul / 1000ul); - __IO uint32_t u32Count = u32TimeCount; - en_sd_card_device_mode_t enDeviceMode = SDCARD_GetDeviceMode(handle); - en_flag_status_t enStatus = Reset; - en_flag_status_t enIrqFlag = Reset; - - if (NULL == handle) - { - return ErrorInvalidParameter; - } - - if ((NULL == pu8Data) || (0u == u16BlockCnt)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_PARAM; - return ErrorInvalidParameter; - } - - handle->u32ErrorCode = SD_CARD_ERROR_NONE; - - if ((u32BlockAddr + u16BlockCnt) > (handle->stcSdCardInfo.u32LogBlockNbr)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_ADDR_OUT_OF_RANGE; - return ErrorInvalidParameter; - } - - /* Set Block Size for Card */ - enCmdRet = SDMMC_Cmd16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - stcDataCfg.u16BlkCnt = u16BlockCnt; - stcDataCfg.u16BlkSize = SD_CARD_BLOCK_SIZE; - stcDataCfg.enDataTimeOut = SdiocDtoSdclk_2_27; - stcDataCfg.enTransferDir = SdiocTransferToCard; - stcDataCfg.enAutoCmd12Enable = (u16BlockCnt > 1u) ? Enable:Disable; - stcDataCfg.enTransferMode = (u16BlockCnt > 1u) ? SdiocTransferMultiple:SdiocTransferSingle; - enCmdRet = SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (handle->stcSdCardInfo.u32CardType != SdCardSdhcSdxc) - { - u32BlockAddr *= SD_CARD_BLOCK_SIZE; - } - - if (enDeviceMode == SdCardDmaMode) - { - if (IS_DMA_CFG_VALID(handle)) - { - DmaSdiocTxConfig(DMA_Unit(handle), DMA_CH(handle), handle->SDIOCx, pu8TempBuf, u16BlockCnt * SD_CARD_BLOCK_SIZE); - } - } - - /* Write block(s) in polling mode */ - if (1u == u16BlockCnt) - { - /* Read Single Block command */ - enCmdRet = SDMMC_Cmd24_WriteSingleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - else - { - /* Read Multi Block command */ - enCmdRet = SDMMC_Cmd25_WriteMultipleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (SdCardPollingMode == enDeviceMode) - { - /* Poll on SDIO flags */ - while (u16BlockCnt) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocBufferWriteEnble); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocBufferWriteReady); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - /* Write data to SDIO Tx Buffer */ - SDIOC_WriteBuffer(handle->SDIOCx, pu8TempBuf, SD_CARD_BLOCK_SIZE); - - u16BlockCnt--; - u32Count = u32TimeCount; - pu8TempBuf += SD_CARD_BLOCK_SIZE; - } - - if (u32Count-- == 0ul) - { - return ErrorTimeout; - } - } - } - - for (u32Count = u32TimeCount; u32Count > 0ul; u32Count--) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocData0PinLvl); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - break; - } - } - - if (0u == u32Count) - { - return ErrorTimeout; - } - else - { - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - } - - enCmdRet = SdCardCheckReayForData(handle, u32TimeCount); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* check whether Data transfer stops */ - if(Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocErrorInt)) - { - return Error; - } - - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocBufferWriteReady); - - return Ok; -} - -/** - ****************************************************************************** - ** \brief Set SD bus width. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Set SD bus width successfully. - ** \retval Error Set SD bus width unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcCfg - ** - enBusWidth is invalid. - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardSetBusWidth(stc_sd_handle_t *handle) -{ - uint32_t u32CmdArg = 0ul; - en_result_t enCmdRet = Ok; - - if ((NULL == handle) || (NULL == handle->pstcCardInitCfg)) - { - return ErrorInvalidParameter; - } - - switch (handle->pstcCardInitCfg->enBusWidth) - { - case SdiocBusWidth1Bit: - u32CmdArg = 0u; - break; - case SdiocBusWidth4Bit: - u32CmdArg = 2u; - break; - default: - enCmdRet = ErrorInvalidParameter; - break; - } - - if (Ok != enCmdRet) - { - return enCmdRet; - } - - enCmdRet = SDMMC_Cmd55_AppCmd(handle->SDIOCx, (RelCardAddress(handle) << 16u), (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SDMMC_Acmd6_SetBusWidth(handle->SDIOCx, u32CmdArg, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SDIOC_SetBusWidth(handle->SDIOCx, handle->pstcCardInitCfg->enBusWidth); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - return Ok; -} - -/** - ****************************************************************************** - ** \brief Set SD high speed mode. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Set SD bus width successfully. - ** \retval Ok Set SD bus width unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcCfg - ** - u32Freq is invalid. - ** - ******************************************************************************/ -static en_result_t SdCardSetSpeed(stc_sd_handle_t *handle) -{ - uint8_t au8TempBuf[64] = {0}; - uint32_t u32TimeCount = 2000 * (SystemCoreClock / 8u / 1000u); - __IO uint32_t u32Count = u32TimeCount; - en_flag_status_t enStatus = Reset; - en_flag_status_t enIrqFlag = Reset; - - en_result_t enCmdRet = ErrorInvalidParameter; - stc_sdioc_data_cfg_t stcDataCfg; - uint32_t u32Arg = SD_SET_FUNCTION_HIGH_SPEED; - - if ((NULL != handle) && (NULL != handle->pstcCardInitCfg)) - { - enCmdRet = Ok; - if (SdiocHighSpeedMode == handle->pstcCardInitCfg->enSpeedMode) - { - /* Set Block Size for Card */ - enCmdRet = SDMMC_Cmd16_SetBlockLength(handle->SDIOCx, 64u, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet == Ok) - { - stcDataCfg.u16BlkCnt = 1u; - stcDataCfg.u16BlkSize = 64u; - stcDataCfg.enDataTimeOut = SdiocDtoSdclk_2_27; - stcDataCfg.enTransferDir = SdiocTransferToHost; - stcDataCfg.enAutoCmd12Enable = Disable; - stcDataCfg.enTransferMode = SdiocTransferSingle; - enCmdRet = SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); - if (enCmdRet == Ok) - { - enCmdRet = SDMMC_Cmd6_SwitchFunc(handle->SDIOCx, u32Arg, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet == Ok) - { - while (u32Count--) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocBufferReadEnble); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocBufferReadReady); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - SDIOC_ReadBuffer(handle->SDIOCx, au8TempBuf, sizeof(au8TempBuf)); - break; - } - } - - if (0ul == u32Count) - { - return ErrorTimeout; - } - - u32Count = u32TimeCount; - while (u32Count--) - { - if (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete)) - { - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - break; - } - } - - if (0ul == u32Count) - { - return ErrorTimeout; - } - - /* Check whether switch function with error or transfer error occur */ - if ((!(au8TempBuf[16] & 0x01)) || - (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocErrorInt))) - { - enCmdRet = Error; - } - } - } - } - } - - if (enCmdRet == Ok) - { - SDIOC_SetSpeedMode(handle->SDIOCx, handle->pstcCardInitCfg->enSpeedMode); - - enCmdRet = SDIOC_SetClk(handle->SDIOCx, handle->pstcCardInitCfg->enClkFreq); - } - } - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Initialize SDIO Host - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok SDIO host initialized successfully - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcInitCfg - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardInitHost(const stc_sd_handle_t *handle) -{ - en_result_t enRet = Ok; - - if ((NULL == handle) || (NULL == handle->pstcCardInitCfg)) - { - return ErrorInvalidParameter; - } - - /* Enable SD clock supply */ - if (M4_SDIOC1 == handle->SDIOCx) - { - PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_SDIOC1, Enable); - } - else if (M4_SDIOC2 == handle->SDIOCx) - { - PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_SDIOC2, Enable); - } - else - { - return ErrorInvalidParameter; - } - - /* Set mode: SD */ - SDIOC_SetMode(handle->SDIOCx, SdiocModeSD); - - enRet = SDIOC_Init(handle->SDIOCx, handle->pstcCardInitCfg->pstcInitCfg); - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Initialize SD bus - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok SDIO bus cmd operate successfully. - ** \retval Error SDIO bus cmd operate unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcCfg - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardInitSd(stc_sd_handle_t *handle) -{ - en_result_t enCmdRet = Ok; - - if(NULL == handle) - { - return ErrorInvalidParameter; - } - - if (handle->stcSdCardInfo.u32CardType != SdCardSecured) - { - /* Send CMD2 ALL_SEND_CID */ - enCmdRet = SDMMC_Cmd2_AllSendCID(handle->SDIOCx, handle->CID); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* Send CMD3 SET_REL_ADDR with argument 0 */ - /* SD Card publishes its RCA. */ - enCmdRet = SDMMC_Cmd3_SendRelativeAddr(handle->SDIOCx, &(handle->RCA)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* Get the SD card RCA */ - RelCardAddress(handle) = handle->RCA; - - /* Send CMD9 SEND_CSD with argument as card's RCA */ - enCmdRet = SDMMC_Cmd9_SendCSD(handle->SDIOCx, RelCardAddress(handle), handle->CSD); - if (enCmdRet != Ok) - { - return enCmdRet; - } - } - - /* Get CSD parameters */ - enCmdRet = SDCARD_GetCardCSD(handle); - if (enCmdRet == Ok) - { - /* Select the Card */ - enCmdRet = SDMMC_Cmd7_SelectDeselectCard(handle->SDIOCx, RelCardAddress(handle), (uint32_t *)(&handle->stcCardStatus)); - } - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Activate SD in power-on stage - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Activate successfully. - ** \retval Error Activate unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == handle - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardPowerON(stc_sd_handle_t *handle) -{ - uint32_t u32IfCond = 0u; - __IO uint32_t u32Count = 0ul; - en_result_t enCmdRet = Error; - - if (NULL == handle) - { - return ErrorInvalidParameter; - } - - handle->u32ErrorCode = SD_CARD_ERROR_NONE; - - /* CMD0: GO_IDLE_STATE */ - enCmdRet = SDMMC_Cmd0_GoIdleState(handle->SDIOCx); - if (enCmdRet != Ok) - { - handle->u32ErrorCode |= SD_CARD_ERROR_GENERAL_UNKNOWN_ERR; - return enCmdRet; - } - - /* Reset OCR valude */ - handle->OCR = 0ul; - - /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */ - enCmdRet = SDMMC_Cmd8_SendIfCond(handle->SDIOCx, &u32IfCond); - if (enCmdRet != Ok) - { - handle->stcSdCardInfo.u32CardVersion = SdCardVer1x; - - /* Send ACMD41 SD_APP_OP_COND with Argument 0x00100000 */ - while (SD_CARD_OCR_BUSY != (handle->OCR & SD_CARD_OCR_BUSY)) - { - if (SD_CARD_MAX_VOLT_TRIAL == u32Count++) - { - handle->u32ErrorCode |= SD_CARD_ERROR_INVALID_VOLTRANGE; - return enCmdRet; - } - - /* SEND CMD55 APP_CMD with RCA as 0 */ - enCmdRet = SDMMC_Cmd55_AppCmd(handle->SDIOCx, 0u, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - continue; - } - - /* Send CMD41 */ - enCmdRet = SDMMC_Acmd41_SdSendOpCond(handle->SDIOCx, SdmmcStanderdCapacity, &handle->OCR); - if (enCmdRet == Error) - { - handle->u32ErrorCode |= SD_CARD_ERROR_UNSUPPORTED_FEATURE; - return enCmdRet; - } - } - - /* Card type is SDSC */ - handle->stcSdCardInfo.u32CardType = SdCardSdsc; - } - else - { - handle->stcSdCardInfo.u32CardVersion = SdCardVer2x; - - /* Send ACMD41 SD_APP_OP_COND with Argument 0x40100000 */ - while (SD_CARD_OCR_BUSY != (handle->OCR & SD_CARD_OCR_BUSY)) - { - if (SD_CARD_MAX_VOLT_TRIAL == u32Count++) - { - handle->u32ErrorCode |= SD_CARD_ERROR_INVALID_VOLTRANGE; - return Error; - } - - /* SEND CMD55 APP_CMD with RCA as 0 */ - enCmdRet = SDMMC_Cmd55_AppCmd(handle->SDIOCx, 0u, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - continue; - } - - /* Send CMD41 */ - enCmdRet = SDMMC_Acmd41_SdSendOpCond(handle->SDIOCx, SdmmcHighCapacity, &handle->OCR); - if (enCmdRet == Error) - { - handle->u32ErrorCode |= SD_CARD_ERROR_UNSUPPORTED_FEATURE; - return enCmdRet; - } - } - - if ((handle->OCR & SdmmcHighCapacity) == SdmmcHighCapacity) - { - handle->stcSdCardInfo.u32CardType = SdCardSdhcSdxc; - } - else - { - handle->stcSdCardInfo.u32CardType = SdCardSdsc; - } - } - - return Ok; -} - -/** - ******************************************************************************* - ** \brief Checks if the SD card is ready for data. - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32Timeout Retry to get card status time - ** - ** \retval Ok Card is ready for data - ** \retval Error Card is not ready for data - ** \retval ErrorInvalidParameter NULL == handle - ** - ******************************************************************************/ -static en_result_t SdCardCheckReayForData(stc_sd_handle_t *handle, uint32_t u32Timeout) -{ - en_result_t enRet = ErrorInvalidParameter; - - if (NULL != handle) - { - do - { - enRet = SDMMC_Cmd13_SendStatus(handle->SDIOCx, RelCardAddress(handle), (uint32_t *)(&handle->stcCardStatus)); - if (Ok != enRet) - { - break; - } - } while ((--u32Timeout) && (false == IsCardReadyForData(handle))); - - if (0u == u32Timeout) - { - enRet = ErrorTimeout; - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Configures the DMA Channel for SDIO Tx request. - ** - ** \param [in] DMAx The pointer to DMAC register base - ** \arg M4_DMA1 DMAC unit 1 instance register base - ** \arg M4_DMA2 DMAC unit 2 instance register base - ** \param [in] enCh The specified DMAC channel. - ** \arg DmaCh0 DMAC channel 0 - ** \arg DmaCh1 DMAC channel 1 - ** \arg DmaCh2 DMAC channel 2 - ** \arg DmaCh3 DMAC channel 3 - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu8TxBuf Pointer to the Tx buffer - ** \param [in] u16len Tx buffer size - ** - ** \retval Ok Set successfully. - ** \retval ErrorInvalidParameter Set unsuccessfully. - ** - ******************************************************************************/ -static en_result_t DmaSdiocTxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8TxBuf, - uint16_t u16len) -{ - stc_dma_config_t stcDmaInit; - uint32_t u32Fcg0Periph = (M4_DMA1 == DMAx) ? PWC_FCG0_PERIPH_DMA1 : PWC_FCG0_PERIPH_DMA2; - en_event_src_t enEvtSrc = (M4_SDIOC1 == SDIOCx) ? EVT_SDIOC1_DMAW : EVT_SDIOC2_DMAW; - en_result_t enRet = ErrorInvalidParameter; - - if ((NULL != pu8TxBuf) && \ - (IS_VALID_TRANSFER_BUF_LEN(u16len)) && \ - (IS_VALID_TRANSFER_BUF_ALIGN(pu8TxBuf))) - { - /* Enable peripheral clock */ - PWC_Fcg0PeriphClockCmd(u32Fcg0Periph, Enable); - - /* Enable DMA. */ - DMA_Cmd(DMAx, Enable); - - /* Initialize DMA. */ - MEM_ZERO_STRUCT(stcDmaInit); - stcDmaInit.u16BlockSize = SD_CARD_BLOCK_SIZE/4u; /* Set data block size. */ - stcDmaInit.u16TransferCnt = u16len/SD_CARD_BLOCK_SIZE; /* Set transfer count. */ - stcDmaInit.u32SrcAddr = (uint32_t)(&pu8TxBuf[0]); /* Set source address. */ - stcDmaInit.u32DesAddr = (uint32_t)(&SDIOCx->BUF0); /* Set destination address. */ - stcDmaInit.stcDmaChCfg.enSrcInc = AddressIncrease; /* Set source address mode. */ - stcDmaInit.stcDmaChCfg.enDesInc = AddressFix; /* Set destination address mode. */ - stcDmaInit.stcDmaChCfg.enTrnWidth = Dma32Bit; /* Set data width 8bit. */ - DMA_InitChannel(DMAx, enCh, &stcDmaInit); - - /* Enable the specified DMA channel. */ - DMA_ChannelCmd(DMAx, enCh, Enable); - - /* Clear DMA flag. */ - DMA_ClearIrqFlag(DMAx, enCh, TrnCpltIrq); - DMA_ClearIrqFlag(DMAx, enCh, BlkTrnCpltIrq); - - /* Enable peripheral circuit trigger function. */ - PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable); - - /* Set DMA trigger source. */ - DMA_SetTriggerSrc(DMAx, enCh, enEvtSrc); - - enRet = Ok; - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Configures the DMA Channel for SDIO Rx request. - ** - ** \param [in] DMAx The pointer to DMAC register base - ** \arg M4_DMA1 DMAC unit 1 instance register base - ** \arg M4_DMA2 DMAC unit 2 instance register base - ** \param [in] enCh The specified DMAC channel. - ** \arg DmaCh0 DMAC channel 0 - ** \arg DmaCh1 DMAC channel 1 - ** \arg DmaCh2 DMAC channel 2 - ** \arg DmaCh3 DMAC channel 3 - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu8RxBuf Pointer to the Rx buffer - ** \param [in] u16len Rx buffer size - ** - ** \retval Ok Set successfully. - ** \retval ErrorInvalidParameter Set unsuccessfully. - ** - ******************************************************************************/ -static en_result_t DmaSdiocRxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8RxBuf, - uint16_t u16len) -{ - stc_dma_config_t stcDmaInit; - uint32_t u32Fcg0Periph = (M4_DMA1 == DMAx) ? PWC_FCG0_PERIPH_DMA1 : PWC_FCG0_PERIPH_DMA2; - en_event_src_t enEvtSrc = (M4_SDIOC1 == SDIOCx) ? EVT_SDIOC1_DMAR : EVT_SDIOC2_DMAR; - en_result_t enRet = ErrorInvalidParameter; - - if ((NULL != pu8RxBuf) && \ - (IS_VALID_TRANSFER_BUF_LEN(u16len)) && \ - (IS_VALID_TRANSFER_BUF_ALIGN(pu8RxBuf))) - { - /* Enable peripheral clock */ - PWC_Fcg0PeriphClockCmd(u32Fcg0Periph,Enable); - - /* Enable DMA. */ - DMA_Cmd(DMAx, Enable); - - /* Initialize DMA. */ - MEM_ZERO_STRUCT(stcDmaInit); - stcDmaInit.u16BlockSize = SD_CARD_BLOCK_SIZE/4u; /* Set data block size. */ - stcDmaInit.u16TransferCnt = u16len/SD_CARD_BLOCK_SIZE; /* Set transfer count. */ - stcDmaInit.u32SrcAddr = (uint32_t)(&SDIOCx->BUF0); /* Set source address. */ - stcDmaInit.u32DesAddr = (uint32_t)(&pu8RxBuf[0]); /* Set destination address. */ - stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix; /* Set source address mode. */ - stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease; /* Set destination address mode. */ - stcDmaInit.stcDmaChCfg.enTrnWidth = Dma32Bit; /* Set data width 8bit. */ - DMA_InitChannel(DMAx, enCh, &stcDmaInit); - - /* Enable the specified DMA channel. */ - DMA_ChannelCmd(DMAx, enCh, Enable); - - /* Clear DMA flag. */ - DMA_ClearIrqFlag(DMAx, enCh, TrnCpltIrq); - DMA_ClearIrqFlag(DMAx, enCh, BlkTrnCpltIrq); - - /* Enable peripheral circuit trigger function. */ - PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable); - - /* Set DMA trigger source. */ - DMA_SetTriggerSrc(DMAx, enCh, enEvtSrc); - - enRet = Ok; - } - - return enRet; -} - -/** - * @brief Get the current card status. - * @param [in] handle Pointer to a @ref stc_sd_handle_t structure - * @param [out] pu32CardStatus Pointer to the value of current card status - * @retval int32_t: - * - LL_OK: Get card status success - * - LL_ERR: Refer to u32ErrorCode for the reason of error - * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command - * - LL_ERR_TIMEOUT: Send command timeout - */ -static en_result_t SD_GetCurrCardStatus(stc_sd_handle_t *handle, uint32_t *pu32CardStatus) -{ - en_result_t i32Ret; - - /* Send Status command */ - i32Ret = SDMMC_Cmd13_SendStatus(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelCardAddr), (uint32_t *)&handle->u32ErrorCode); - if (Ok != i32Ret) { - return i32Ret; - } - /* Get SD card status */ - *pu32CardStatus = SDIOC_GetResponse(handle->SDIOCx, SdiocRegResp01); - - return i32Ret; -} - -/** - * @brief Get the current sd card state. - * @param [in] handle Pointer to a @ref stc_sd_handle_t structure - * @param [out] peCardState Pointer to a @ref en_sd_card_state_t enumeration - * @retval int32_t: - * - LL_OK: Get sd card state success - * - LL_ERR: Refer to u32ErrorCode for the reason of error - * - LL_ERR_INVD_PARAM: handle == NULL or peCardState == NULL or - * An invalid parameter was write to the send command - * - LL_ERR_TIMEOUT: Send command timeout - */ -en_result_t SD_GetCardState(stc_sd_handle_t *handle, en_sd_card_state_t *peCardState) -{ - en_result_t i32Ret; - uint32_t u32Response = 0UL; - - if ((NULL == peCardState) || (NULL == handle)) { - i32Ret = ErrorInvalidParameter; - } else { - i32Ret = SD_GetCurrCardStatus(handle, &u32Response); - *peCardState = (en_sd_card_state_t)(uint32_t)((u32Response >> 9) & 0x0FU); - } - - return i32Ret; -} - -//@} // SdiocGroup - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Project/GateWay/source/Module/SDCard/sd_card.h b/Project/GateWay/source/Module/SDCard/sd_card.h deleted file mode 100644 index 93eb041..0000000 --- a/Project/GateWay/source/Module/SDCard/sd_card.h +++ /dev/null @@ -1,404 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - */ -/******************************************************************************/ -/** \file sd_card.h - ** - ** A detailed description is available at - ** @link SdiocGroup SDIOC description @endlink - ** - ** - 2018-11-15 CDT First version for Device Driver Library of SDIOC. - ** - ******************************************************************************/ -#ifndef __SD_CARD_H__ -#define __SD_CARD_H__ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "sdmmc_cmd.h" - -/* C binding of definitions if building with C++ compiler */ -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - ******************************************************************************* - ** \defgroup SdiocGroup Secure Digital Input and Output Controller(SDIOC) - ** - ******************************************************************************/ -//@{ - -/******************************************************************************* - * Global type definitions ('typedef') - ******************************************************************************/ - -/** - ******************************************************************************* - ** \brief SD Card version definition - ** - ******************************************************************************/ - /** - * @brief SD Card State enumeration structure definition - */ -typedef enum { - SD_CARD_STAT_IDLE = 0x00U, /*!< Card state is idle */ - SD_CARD_STAT_RDY = 0x01U, /*!< Card state is ready */ - SD_CARD_STAT_IDENTIFY = 0x02U, /*!< Card is in identification state */ - SD_CARD_STAT_STANDBY = 0x03U, /*!< Card is in standby state */ - SD_CARD_STAT_TRANS = 0x04U, /*!< Card is in transfer state */ - SD_CARD_STAT_TX_DATA = 0x05U, /*!< Card is sending an operation */ - SD_CARD_STAT_RX_DATA = 0x06U, /*!< Card is receiving operation information */ - SD_CARD_STAT_PGM = 0x07U, /*!< Card is in programming state */ - SD_CARD_STAT_DISCONNECT = 0x08U /*!< Card is disconnected */ -} en_sd_card_state_t; - - -typedef enum en_sd_card_version -{ - SdCardVer1x = 0u, ///< SD Card version: 1.x - SdCardVer2x = 1u, ///< SD Card version: 2.x -} en_sd_card_version_t; - -/** - ******************************************************************************* - ** \brief SD Card device Read/Write mode - ** - ******************************************************************************/ -typedef enum en_sd_card_device_mode -{ - SdCardPollingMode = 0u, ///< Polling mode transfer - SdCardDmaMode = 1u, ///< DMA mode transfer -} en_sd_card_device_mode_t; - -/** - ******************************************************************************* - ** \brief SD Card Information Structure definition - ** - ******************************************************************************/ -typedef struct stc_sd_card_info -{ - uint32_t u32CardType; ///< Specifies the card Type - - uint32_t u32CardVersion; ///< Specifies the card version - - uint32_t u32Class; ///< Specifies the class of the card class - - uint32_t u32RelCardAddr; ///< Specifies the Relative Card Address - - uint32_t u32BlockNbr; ///< Specifies the Card Capacity in blocks - - uint32_t u32BlockSize; ///< Specifies one block size in bytes - - uint32_t u32LogBlockNbr; ///< Specifies the Card logical Capacity in blocks - - uint32_t u32LogBlockSize; ///< Specifies logical block size in bytes - -} stc_sd_card_info_t; - -/** - ******************************************************************************* - ** \brief CSD Register ver1.0(for Standard Capacity Card) - ** - ******************************************************************************/ -typedef struct stc_sdcard_csd_v1 -{ - /* Byte 1 */ - uint8_t RESERVE1 : 2; - uint8_t FILE_FORMAT : 2; - uint8_t TMP_WRITE_PROTECT : 1; - uint8_t PERM_WRITE_PROTECT : 1; - uint8_t COPY : 1; - uint8_t FILE_FORMAT_GRP : 1; - - /* Byte 2 */ - uint8_t RESERVE2 : 5; - uint8_t WRITE_BL_PARTIAL : 1; - uint8_t WRITE_BL_LEN1 : 2; - /* Byte 3 */ - uint8_t WRITE_BL_LEN2 : 2; - uint8_t R2W_FACTOR : 3; - uint8_t RESERVE3 : 2; - uint8_t WP_GRP_ENABLE : 1; - - /* Byte 4 */ - uint8_t WP_GRP_SIZE : 7; - uint8_t SECTOR_SIZE1 : 1; - /* Byte 5 */ - uint8_t SECTOR_SIZE2 : 6; - uint8_t ERASE_BLK_EN : 1; - uint8_t C_SIZE_MULTI1 : 1; - /* Byte 6 */ - uint8_t C_SIZE_MULTI2 : 2; - uint8_t CDD_W_CURR_MAX : 3; - uint8_t CDD_W_CURR_MIN : 3; - - /* Byte 7 */ - uint8_t VDD_R_CURR_MAX : 3; - uint8_t VDD_R_CURR_MIN : 3; - uint8_t C_SIZE1 : 2; - /* Byte 8 */ - uint8_t C_SIZE2 : 8; - /* Byte 9 */ - uint8_t C_SIZE3 : 2; - uint8_t RESERVED4 : 2; - uint8_t DSR_IMP : 1; - uint8_t READ_BLK_MISALIGH : 1; - uint8_t WRITE_BLK_MISALIGN : 1; - uint8_t READ_BL_PARTIAL : 1; - - /* Byte 10 */ - uint8_t READ_BL_LEN : 4; - uint8_t CCC1 : 4; - /* Byte 11 */ - uint8_t CCC2 : 8; - - /* Byte 12 */ - uint8_t TRAN_SPEED : 8; - - /* Byte 13 */ - uint8_t NSAC : 8; - - /* Byte 14 */ - uint8_t TAAC : 8; - - /* Byte 15 */ - uint8_t RESERVE5 : 6; - uint8_t CSD_STRUCTURE : 2; -}stc_sdcard_csd_v1_t; - -/** - ******************************************************************************* - ** \brief CSD Register ver2.0(for High Capacity Card) - ** - ******************************************************************************/ -typedef struct stc_sdcard_csd_v2 -{ - /* Byte 1 */ - uint8_t RESERVED1 : 2; - uint8_t FILE_FORMAT : 2; - uint8_t TMP_WRITE_PROTECT : 1; - uint8_t PERM_WRITE_PROTECT : 1; - uint8_t COPY : 1; - uint8_t FILE_FORMAT_GRP : 1; - - /* Byte 2 */ - uint8_t RESERVED2 : 5; - uint8_t WRITE_BL_PARTIAL : 1; - uint8_t WRITE_BL_LEN1 : 2; - /* Byte 3 */ - uint8_t WRITE_BL_LEN2 : 2; - uint8_t R2W_FACTOR : 3; - uint8_t RESERVED3 : 2; - uint8_t WP_GRP_ENABLE : 1; - - /* Byte 4 */ - uint8_t WP_GRP_SIZE : 7; - uint8_t SECTOR_SIZE1 : 1; - /* Byte 5 */ - uint8_t SECTOR_SIZE2 : 6; - uint8_t ERASE_BLK_EN : 1; - uint8_t RESERVED4 : 1; - - /* Byte 6 */ - uint8_t C_SIZE1 : 8; - /* Byte 7 */ - uint8_t C_SIZE2 : 8; - /* Byte 8 */ - uint8_t C_SIZE3 : 6; - uint8_t RESERVED5 : 2; - - /* Byte 9 */ - uint8_t RESERVED6 : 4; - uint8_t DSR_IMP : 1; - uint8_t READ_BLK_MISALIGH : 1; - uint8_t WRITE_BLK_MISALIGN : 1; - uint8_t READ_BL_PARTIAL : 1; - - /* Byte 10 */ - uint8_t READ_BL_LEN : 4; - uint8_t CCC1 : 4; - - /* Byte 11 */ - uint8_t CCC2 : 8; - - /* Byte 12 */ - uint8_t TRAN_SPEED : 8; - - /* Byte 13 */ - uint8_t NSAC : 8; - - /* Byte 14 */ - uint8_t TAAC : 8; - - /* Byte 15 */ - uint8_t RESERVED7 : 6; - uint8_t CSD_STRUCTURE : 2; -} stc_sdcard_csd_v2_t; - -/** - ******************************************************************************* - ** \brief SD Card initilization parameters - ** - ******************************************************************************/ -typedef struct stc_sdcard_init -{ - en_sdioc_bus_width_t enBusWidth; ///< Specifies the SDIOC bus width. - ///< This parameter can be a value of @ref en_sdioc_bus_width_t - - en_sdioc_clk_freq_t enClkFreq; ///< Specifies the SDIOC clock frequency. - ///< This parameter can be a value of @ref en_sdioc_clk_freq_t - - en_sdioc_speed_mode_t enSpeedMode; ///< Specifies the SDIOC speed mode. - ///< This parameter can be a value of @ref en_sdioc_speed_mode_t - - const stc_sdioc_init_t *pstcInitCfg; ///< SD required parameters - ///< and this structure detail refer @ref stc_sdioc_init_t -} stc_sdcard_init_t; - -/** - ******************************************************************************* - ** \brief SD Card use DMA unit/channel parameters - ** - ******************************************************************************/ -typedef struct stc_sdcard_dma_init -{ - M4_DMA_TypeDef *DMAx; ///< Pointer to DMA registers base address - ///< and this structure detail refer @ref M4_DMA_TypeDef - - en_dma_channel_t enDmaCh; ///< Specifies the DMA channel. - ///< This parameter can be a value of @ref en_dma_channel_t -} stc_sdcard_dma_init_t; - -/** - ******************************************************************************* - ** \brief SD handle Structure definition - ** - ******************************************************************************/ -typedef struct stc_sd_handle -{ - M4_SDIOC_TypeDef *SDIOCx; ///< Pointer to SD registers base address - ///< and this structure detail refer @ref M4_SDIOC_TypeDef - - en_sd_card_device_mode_t enDevMode; ///< SD Card Write/Read mode and this parameter can be a value of @ref en_sd_card_device_mode_t - - const stc_sdcard_dma_init_t *pstcDmaInitCfg; ///< Pointer to SD Card initialization parameters - ///< and this structure detail refer @ref stc_sdcard_init_t - - const stc_sdcard_init_t *pstcCardInitCfg; ///< Pointer to SD Card initialization parameters - ///< and this structure detail refer @ref stc_sdcard_init_t - - __IO uint32_t Context; ///< SD transfer context - - __IO uint32_t u32ErrorCode; ///< SD Card Error codes - - stc_sd_card_info_t stcSdCardInfo; ///< SD Card information - ///< and this structure detail refer @ref stc_sd_card_info_t - - stc_sdmmc_resp_card_status_t stcCardStatus; ///< SD Card status - ///< and this structure detail refer @ref stc_sdmmc_resp_card_status_t - - uint32_t OCR; ///< SD Card Operation Condition Register - - uint32_t CID[4]; ///< SD Card IDentification - - uint32_t CSD[4]; ///< SD Card Specific Data - - uint32_t DSR; ///< DSR value - - uint32_t RCA; ///< RCA value - - uint32_t SCR[2]; ///< SD Card Configuration Register - - uint32_t CSR; ///< SD Card Status Register -}stc_sd_handle_t; - - -/******************************************************************************* - * Global pre-processor symbols/macros ('#define') - ******************************************************************************/ - -#define SD_CARD_ERROR_NONE (SDMMC_ERROR_NONE) /*!< No error */ -#define SD_CARD_ERROR_CMD_CRC_FAIL (SDMMC_ERROR_CMD_CRC_FAIL) /*!< Command response received (but CRC check failed) */ -#define SD_CARD_ERROR_DATA_CRC_FAIL (SDMMC_ERROR_DATA_CRC_FAIL) /*!< Data block sent/received (CRC check failed) */ -#define SD_CARD_ERROR_CMD_RSP_TIMEOUT (SDMMC_ERROR_CMD_RSP_TIMEOUT) /*!< Command response timeout */ -#define SD_CARD_ERROR_DATA_TIMEOUT (SDMMC_ERROR_DATA_TIMEOUT) /*!< Data timeout */ -#define SD_CARD_ERROR_TX_UNDERRUN (SDMMC_ERROR_TX_UNDERRUN) /*!< Transmit FIFO underrun */ -#define SD_CARD_ERROR_RX_OVERRUN (SDMMC_ERROR_RX_OVERRUN) /*!< Receive FIFO overrun */ -#define SD_CARD_ERROR_ADDR_MISALIGNED (SDMMC_ERROR_ADDR_MISALIGNED) /*!< Misaligned address */ -#define SD_CARD_ERROR_BLOCK_LEN_ERR (SDMMC_ERROR_BLOCK_LEN_ERR) /*!< Transferred block length is not allowed for the card or the - number of transferred bytes does not match the block length */ -#define SD_CARD_ERROR_ERASE_SEQ_ERR (SDMMC_ERROR_ERASE_SEQ_ERR) /*!< An error in the sequence of erase command occurs */ -#define SD_CARD_ERROR_BAD_ERASE_PARAM (SDMMC_ERROR_BAD_ERASE_PARAM) /*!< An invalid selection for erase groups */ -#define SD_CARD_ERROR_WRITE_PROT_VIOLATION (SDMMC_ERROR_WRITE_PROT_VIOLATION) /*!< Attempt to program a write protect block */ -#define SD_CARD_ERROR_LOCK_UNLOCK_FAILED (SDMMC_ERROR_LOCK_UNLOCK_FAILED) /*!< Sequence or password error has been detected in unlock - command or if there was an attempt to access a locked card */ -#define SD_CARD_ERROR_COM_CRC_FAILED (SDMMC_ERROR_COM_CRC_FAILED) /*!< CRC check of the previous command failed */ -#define SD_CARD_ERROR_ILLEGAL_CMD (SDMMC_ERROR_ILLEGAL_CMD) /*!< Command is not legal for the card state */ -#define SD_CARD_ERROR_CARD_ECC_FAILED (SDMMC_ERROR_CARD_ECC_FAILED) /*!< Card internal ECC was applied but failed to correct the data */ -#define SD_CARD_ERROR_CC_ERR (SDMMC_ERROR_CC_ERR) /*!< Internal card controller error */ -#define SD_CARD_ERROR_GENERAL_UNKNOWN_ERR (SDMMC_ERROR_GENERAL_UNKNOWN_ERR) /*!< General or unknown error */ -#define SD_CARD_ERROR_STREAM_READ_UNDERRUN (SDMMC_ERROR_STREAM_READ_UNDERRUN) /*!< The card could not sustain data reading in stream rmode */ -#define SD_CARD_ERROR_STREAM_WRITE_OVERRUN (SDMMC_ERROR_STREAM_WRITE_OVERRUN) /*!< The card could not sustain data programming in stream mode */ -#define SD_CARD_ERROR_CID_CSD_OVERWRITE (SDMMC_ERROR_CID_CSD_OVERWRITE) /*!< CID/CSD overwrite error */ -#define SD_CARD_ERROR_WP_ERASE_SKIP (SDMMC_ERROR_WP_ERASE_SKIP) /*!< Only partial address space was erased */ -#define SD_CARD_ERROR_CARD_ECC_DISABLED (SDMMC_ERROR_CARD_ECC_DISABLED) /*!< Command has been executed without using internal ECC */ -#define SD_CARD_ERROR_ERASE_RESET (SDMMC_ERROR_ERASE_RESET) /*!< Erase sequence was cleared before executing because an out - of erase sequence command was received */ -#define SD_CARD_ERROR_AKE_SEQ_ERR (SDMMC_ERROR_AKE_SEQ_ERR) /*!< Error in sequence of authentication */ -#define SD_CARD_ERROR_INVALID_VOLTRANGE (SDMMC_ERROR_INVALID_VOLTRANGE) /*!< Error in case of invalid voltage range */ -#define SD_CARD_ERROR_ADDR_OUT_OF_RANGE (SDMMC_ERROR_ADDR_OUT_OF_RANGE) /*!< Error when addressed block is out of range */ -#define SD_CARD_ERROR_REQUEST_NOT_APPLICABLE (SDMMC_ERROR_REQUEST_NOT_APPLICABLE)/*!< Error when command request is not applicable */ -#define SD_CARD_ERROR_PARAM (SDMMC_ERROR_INVALID_PARAMETER) /*!< the used parameter is not valid */ -#define SD_CARD_ERROR_UNSUPPORTED_FEATURE (SDMMC_ERROR_UNSUPPORTED_FEATURE) /*!< Error when feature is not insupported */ -#define SD_CARD_ERROR_BUSY (SDMMC_ERROR_BUSY) /*!< Error when transfer process is busy */ -#define SD_CARD_ERROR_DMA (SDMMC_ERROR_DMA) /*!< Error while DMA transfer */ -#define SD_CARD_ERROR_TIMEOUT (SDMMC_ERROR_TIMEOUT) /*!< Timeout error */ - -/******************************************************************************* - * Global variable definitions ('extern') - ******************************************************************************/ - -/******************************************************************************* - * Global function prototypes (definition in C source) - ******************************************************************************/ - -en_result_t SDCARD_Init(stc_sd_handle_t *handle, - const stc_sdcard_init_t *pstcInitCfg); -en_result_t SDCARD_SetDeviceMode(stc_sd_handle_t *handle, - en_sd_card_device_mode_t enDevMode); -en_sd_card_device_mode_t SDCARD_GetDeviceMode(const stc_sd_handle_t *handle); -en_result_t SDCARD_GetCardCSD(stc_sd_handle_t *handle); -en_result_t SDCARD_Erase(stc_sd_handle_t *handle, - uint32_t u32BlkStartAddr, - uint32_t u32BlkEndAddr, - uint32_t u32Timeout); -en_result_t SDCARD_ReadBlocks( stc_sd_handle_t *handle, - uint32_t u32BlockAddr, - uint16_t u16BlockCnt, - uint8_t *pu8Data, - uint32_t u32Timeout); -en_result_t SDCARD_WriteBlocks( stc_sd_handle_t *handle, - uint32_t u32BlockAddr, - uint16_t u16BlockCnt, - uint8_t *pu8Data, - uint32_t u32Timeout); -en_result_t SD_GetCardState(stc_sd_handle_t *handle, en_sd_card_state_t *peCardState); -//@} // SdiocGroup - -#ifdef __cplusplus -} -#endif - -#endif /* __SD_CARD_H__ */ - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Project/GateWay/source/Module/SDCard/sd_card_1.c b/Project/GateWay/source/Module/SDCard/sd_card_1.c deleted file mode 100644 index 568cb05..0000000 --- a/Project/GateWay/source/Module/SDCard/sd_card_1.c +++ /dev/null @@ -1,1268 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - */ -/******************************************************************************/ -/** \file sd_card.c - ** - ** A detailed description is available at - ** @link SdiocGroup SDIOC description @endlink - ** - ** - 2018-11-15 CDT First version for Device Driver Library of SDIOC. - ** - ******************************************************************************/ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "sdmmc_cmd.h" -#include "sd_card.h" - -/** - ******************************************************************************* - ** \addtogroup SdiocGroup - ******************************************************************************/ -//@{ - -/******************************************************************************* - * Local type definitions ('typedef') - ******************************************************************************/ -typedef enum en_sd_card_type -{ - SdCardSdsc = 0u, - SdCardSdhcSdxc = 1u, - SdCardSecured = 3u, -} en_sd_card_type_t; - -/******************************************************************************* - * Local pre-processor symbols/macros ('#define') - ******************************************************************************/ - -/*!< Card Command Class supported. */ -#define SDMMC_CARD_CCCC_ERASE (0x00000020u) - -/*!< Card locked */ -#define SDMMC_CARD_LOCKED (0x02000000u) - -/*!< Voltage trial times */ -#define SD_CARD_MAX_VOLT_TRIAL (0x0000FFFFu) - -/*!< High speed */ -#define SD_CHECK_FUNCTION_HIGH_SPEED (0x00FFFF01u) -#define SD_SET_FUNCTION_HIGH_SPEED (0x80FFFF01u) - -/*!< Block size is 512 bytes */ -#define SD_CARD_BLOCK_SIZE (512u) - -/*!< SDIOC buffer align size */ -#define SDIOC_BUF_ALIGN_SIZE (4ul) - -/*!< Log Block Number for 2G bytes Cards */ -#define SD_CARD_CAPACITY (0x400000u) - -/*!< Card power up status bit (busy) */ -#define SD_CARD_OCR_BUSY (0x80000000ul) - -#define SD_CARD_OP_NONE (0x00000000u) /*!< None */ -#define SD_CARD_OP_READ_SINGLE_BLOCK (0x00000001u) /*!< Read single block operation */ -#define SD_CARD_OP_READ_MULTIPLE_BLOCK (0x00000002u) /*!< Read multiple blocks operation */ -#define SD_CARD_OP_WRITE_SINGLE_BLOCK (0x00000010u) /*!< Write single block operation */ -#define SD_CARD_OP_WRITE_MULTIPLE_BLOCK (0x00000020u) /*!< Write multiple blocks operation */ -#define SD_CARD_OP_IT (0x00000008u) /*!< Process in Interrupt mode */ -#define SD_CARD_OP_DMA (0x00000080u) /*!< Process in DMA mode */ - -/*!< the SD card relative card address. */ -#define RelCardAddress(handle) ((handle)->stcSdCardInfo.u32RelCardAddr) -#define IsCardProgramming(handle) ((SdmmcCardStatePgm == (handle)->stcCardStatus.CURRENT_STATE) ? true : false) -#define IsCardReadyForData(handle) ((1u == (handle)->stcCardStatus.READY_FOR_DATA) ? true : false) - -#define IS_DMA_CFG_VALID(handle) \ -( (NULL != (handle)->pstcDmaInitCfg) && \ - (NULL != (handle)->pstcDmaInitCfg->DMAx)) - -/*!< the SD card use DMA unit && channel. */ -#define DMA_Unit(handle) ((handle)->pstcDmaInitCfg->DMAx) -#define DMA_CH(handle) ((handle)->pstcDmaInitCfg->enDmaCh) - -/*!< Parameter valid check for buffer address. */ -#define IS_VALID_TRANSFER_BUF_ALIGN(x) (!((SDIOC_BUF_ALIGN_SIZE-1ul) & ((uint32_t)(x)))) - -/*!< Parameter valid check for SDIOC command value. */ -#define IS_VALID_TRANSFER_BUF_LEN(x) (!((SD_CARD_BLOCK_SIZE - 1u) & (x))) - -/******************************************************************************* - * Global variable definitions (declared in header file with 'extern') - ******************************************************************************/ - -/******************************************************************************* - * Local function prototypes ('static') - ******************************************************************************/ -static en_result_t SdCardInitSd(stc_sd_handle_t *handle); -static en_result_t SdCardPowerON(stc_sd_handle_t *handle); -static en_result_t SdCardInitHost(const stc_sd_handle_t *handle); -static en_result_t SdCardSetSpeed(stc_sd_handle_t *handle); -static en_result_t SdCardSetBusWidth(stc_sd_handle_t *handle); -static en_result_t SdCardCheckReayForData(stc_sd_handle_t *handle, - uint32_t u32Timeout); -static en_result_t DmaSdiocTxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8TxBuf, - uint16_t u16len); -static en_result_t DmaSdiocRxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8RxBuf, - uint16_t u16len); - -/******************************************************************************* - * Local variable definitions ('static') - ******************************************************************************/ - -/******************************************************************************* - * Function implementation - global ('extern') and local ('static') - ******************************************************************************/ - -/** - ******************************************************************************* - ** \brief Initialize SD. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] pstcInitCfg The pointer of SD configure structure - ** \arg This parameter detail refer @ref stc_sdcard_init_t - ** - ** \retval Ok Initialize SD successfully. - ** \retval Error Initialize SD unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - pstcInitCfg == NULL - ** - ******************************************************************************/ -en_result_t SDCARD_Init(stc_sd_handle_t *handle, - const stc_sdcard_init_t *pstcInitCfg) -{ - en_result_t enRet = ErrorInvalidParameter; - - if ((NULL != handle) && (NULL != pstcInitCfg)) - { - handle->pstcCardInitCfg = pstcInitCfg; - - enRet = SdCardInitHost(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardPowerON(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardInitSd(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardSetBusWidth(handle); - if (enRet != Ok) - { - return enRet; - } - - enRet = SdCardSetSpeed(handle); - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Set SD Card device Read/Write mode. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] enDevMode Read/Write mode - ** \arg SdCardDmaMode DMA mode transfer - ** \arg SdCardPollingMode Polling mode transfer - ** - ** \retval Ok Set successfully. - ** \retval ErrorInvalidParameter handle pointer is NULL. - ** - ******************************************************************************/ -en_result_t SDCARD_SetDeviceMode(stc_sd_handle_t *handle, - en_sd_card_device_mode_t enDevMode) -{ - en_result_t enRet = ErrorInvalidParameter; - - if (NULL != handle) - { - handle->enDevMode = enDevMode; - enRet = Ok; - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get SD Card device Read/Write mode. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval SdCardDmaMode DMA mode transfer - ** \retval SdCardPollingMode Polling mode transfer - ** - ******************************************************************************/ -en_sd_card_device_mode_t SDCARD_GetDeviceMode(const stc_sd_handle_t *handle) -{ - DDL_ASSERT(NULL != handle); - - return handle->enDevMode; -} - -/** - ******************************************************************************* - ** \brief Get Card specified Data information. - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Get successfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - ******************************************************************************/ -en_result_t SDCARD_GetCardCSD(stc_sd_handle_t *handle) -{ - uint32_t u32Csize = 0ul; - uint32_t u32NumSector = 0ul; - uint32_t u32CsizeMulti = 0ul; - stc_sdcard_csd_v1_t *pstcCsdSd = NULL; - stc_sdcard_csd_v2_t *pstcCsdSdHc = NULL; - en_result_t enRet = ErrorInvalidParameter; - - if (NULL != handle) - { - /* High Capacity CSD Version 2.0*/ - if ((handle->CSD[3] & 0x00FF0000ul) == 0x00400000ul) - { - pstcCsdSdHc = (stc_sdcard_csd_v2_t *)&handle->CSD[0]; - u32Csize = ((unsigned int)pstcCsdSdHc->C_SIZE3 << 16ul) - + ((unsigned int)pstcCsdSdHc->C_SIZE2 << 8ul) - + pstcCsdSdHc->C_SIZE1; - - u32NumSector = (u32Csize + 1ul) << 10ul; - - handle->stcSdCardInfo.u32Class = (((uint32_t)pstcCsdSdHc->CCC2) << 4u) | ((uint32_t)pstcCsdSdHc->CCC1); - handle->stcSdCardInfo.u32BlockSize = 1ul << (pstcCsdSdHc->READ_BL_LEN); - } - else /* Standard Capacity CSD Version 1.xx */ - { - pstcCsdSd = (stc_sdcard_csd_v1_t *)&handle->CSD[0]; - - u32Csize = ((unsigned int)pstcCsdSd->C_SIZE3 << 10) - + ((unsigned int)pstcCsdSd->C_SIZE2 << 2) - + pstcCsdSd->C_SIZE1; - - u32CsizeMulti = ((uint32_t)(pstcCsdSd->C_SIZE_MULTI2) << 1) + (uint32_t)pstcCsdSd->C_SIZE_MULTI1; - u32NumSector = (u32Csize + 1ul) << (u32CsizeMulti + 2ul); - - if (pstcCsdSd->READ_BL_LEN == 0x0Au) - { - u32NumSector *= 2ul; - } - else if (pstcCsdSd->READ_BL_LEN == 0x0Bu) - { - u32NumSector *= 4ul; - } - else - { - /* Do nothing: only avoid MISRA warning */ - } - - handle->stcSdCardInfo.u32Class = ((uint32_t)pstcCsdSd->CCC2 << 4) | (uint32_t)pstcCsdSd->CCC1; - handle->stcSdCardInfo.u32BlockSize = 1ul << (pstcCsdSd->READ_BL_LEN); - } - - handle->stcSdCardInfo.u32BlockNbr = u32NumSector; - handle->stcSdCardInfo.u32LogBlockNbr = (handle->stcSdCardInfo.u32BlockNbr) * ((handle->stcSdCardInfo.u32BlockSize) / SD_CARD_BLOCK_SIZE); - handle->stcSdCardInfo.u32LogBlockSize = SD_CARD_BLOCK_SIZE; - enRet = Ok; - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Erase SD card blocks. - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32BlkStartAddr Block start address - ** \param [in] u32BlkEndAddr Block end address - ** \param [in] u32Timeout Erase timeout value - ** - ** \retval Ok Erase successfully. - ** \retval Error Erase unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - u32BlkStartAddr out of range - ** - u32BlkEndAddr out of range - ** - ******************************************************************************/ -en_result_t SDCARD_Erase(stc_sd_handle_t *handle, - uint32_t u32BlkStartAddr, - uint32_t u32BlkEndAddr, - uint32_t u32Timeout) -{ - en_result_t enCmdRet = Error; - __IO uint32_t u32TimeCount = u32Timeout * (SystemCoreClock / 8u / 1000u); - - if ((NULL == handle) || - (u32BlkStartAddr > u32BlkEndAddr) || - (u32BlkEndAddr > handle->stcSdCardInfo.u32BlockNbr)) - { - return ErrorInvalidParameter; - } - - /* Check if the card command class supports erase command */ - if (!(handle->stcSdCardInfo.u32Class & SDMMC_CARD_CCCC_ERASE)) - { - return ErrorAccessRights; - } - - if ((SDIOC_GetResponse(handle->SDIOCx, SdiocRegResp01) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) - { - return ErrorAccessRights; - } - - /* Check the Card capacity in term of Logical number of blocks */ - if (handle->stcSdCardInfo.u32CardType != SdCardSdhcSdxc) - { - u32BlkStartAddr *= SD_CARD_BLOCK_SIZE; - u32BlkEndAddr *= SD_CARD_BLOCK_SIZE; - } - - /* Send CMD35 ERASE_GRP_START with argument as address */ - enCmdRet = SDMMC_Cmd32_EraseWrBlkStart(handle->SDIOCx, u32BlkStartAddr, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* Send CMD36 ERASE_GRP_END with argument as address */ - enCmdRet = SDMMC_Cmd33_EraseWrBlkEnd(handle->SDIOCx, u32BlkEndAddr, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SDMMC_Cmd38_Erase(handle->SDIOCx, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SdCardCheckReayForData(handle, u32TimeCount); - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Read block data from SD card - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32BlockAddr Block address - ** \param [in] u16BlockCnt Block Count - ** \param [in] pu8Data Pointer to buffer which will store SD Card data. - ** \param [in] u32Timeout Transfer timeout - ** - ** \retval Ok Read successfully. - ** \retval Error Read unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - pu8Data == NULL - ** - u16BlockCnt == 0 - ** - (u32BlockAddr + u16BlockCnt) out of range - ** - ******************************************************************************/ -en_result_t SDCARD_ReadBlocks(stc_sd_handle_t *handle, - uint32_t u32BlockAddr, - uint16_t u16BlockCnt, - uint8_t *pu8Data, - uint32_t u32Timeout) -{ - en_result_t enCmdRet; - stc_sdioc_data_cfg_t stcDataCfg; - uint8_t *pu8TempBuf = (uint8_t *)pu8Data; - uint32_t u32TimeCount = u32Timeout * (SystemCoreClock / 8u / 1000u); - __IO uint32_t u32Count = u32TimeCount; - en_sd_card_device_mode_t enDeviceMode = SDCARD_GetDeviceMode(handle); - en_flag_status_t enStatus = Reset; - en_flag_status_t enIrqFlag = Reset; - - if (NULL == handle) - { - return ErrorInvalidParameter; - } - - if ((NULL == pu8Data) || (0u == u16BlockCnt)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_PARAM; - return ErrorInvalidParameter; - } - - handle->u32ErrorCode = SD_CARD_ERROR_NONE; - - if ((u32BlockAddr + u16BlockCnt) > (handle->stcSdCardInfo.u32LogBlockNbr)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_ADDR_OUT_OF_RANGE; - return ErrorInvalidParameter; - } - - if (handle->stcSdCardInfo.u32CardType != SdCardSdhcSdxc) - { - u32BlockAddr *= SD_CARD_BLOCK_SIZE; - } - - /* Set Block Size for Card */ - enCmdRet = SDMMC_Cmd16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - stcDataCfg.u16BlkCnt = u16BlockCnt; - stcDataCfg.u16BlkSize = SD_CARD_BLOCK_SIZE; - stcDataCfg.enDataTimeOut = SdiocDtoSdclk_2_27; - stcDataCfg.enTransferDir = SdiocTransferToHost; - stcDataCfg.enAutoCmd12Enable = (u16BlockCnt > 1u) ? Enable:Disable; - stcDataCfg.enTransferMode = (u16BlockCnt > 1u) ? SdiocTransferMultiple:SdiocTransferSingle; - enCmdRet = SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (enDeviceMode == SdCardDmaMode) - { - if (IS_DMA_CFG_VALID(handle)) - { - DmaSdiocRxConfig(DMA_Unit(handle), DMA_CH(handle), handle->SDIOCx, pu8TempBuf, u16BlockCnt * SD_CARD_BLOCK_SIZE); - } - } - - /* Read block(s) in polling mode */ - if (1u == u16BlockCnt) - { - handle->Context = SD_CARD_OP_READ_SINGLE_BLOCK; - /* Read Single Block command */ - enCmdRet = SDMMC_Cmd17_ReadSingleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - else - { - handle->Context = SD_CARD_OP_READ_MULTIPLE_BLOCK; - /* Read Multi Block command */ - enCmdRet = SDMMC_Cmd18_ReadMultipleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (SdCardPollingMode == enDeviceMode) - { - /* Poll on SDIO flags */ - while (u16BlockCnt) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocBufferReadEnble); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocBufferReadReady); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - SDIOC_ReadBuffer(handle->SDIOCx, pu8TempBuf, SD_CARD_BLOCK_SIZE); - - u16BlockCnt--; - u32Count = u32TimeCount; - pu8TempBuf += SD_CARD_BLOCK_SIZE; - } - - if (0ul == u32Count--) - { - return ErrorTimeout; - } - } - } - - for (u32Count = u32TimeCount; u32Count > 0ul; u32Count--) - { - if (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete)) - { - break; - } - } - - if (0ul == u32Count) - { - return ErrorTimeout; - } - else - { - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - } - - /* check whether Data transfer stops */ - if (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocErrorInt)) - { - enCmdRet = Error; - } - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Write block data to SD card - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32BlockAddr Block address - ** \param [in] u16BlockCnt Block Count - ** \param [in] pu8Data Pointer to buffer which contains data to be send to SD Card. - ** \param [in] u32Timeout Transfer timeout - ** - ** \retval Ok Write successfully. - ** \retval Error Write unsuccessfully. - ** \retval ErrorInvalidParameter If one of following cases matches: - ** - handle == NULL - ** - pu8Data == NULL - ** - u16BlockCnt == 0 - ** - (u32BlockAddr + u16BlockCnt) out of range - ** - ******************************************************************************/ -en_result_t SDCARD_WriteBlocks(stc_sd_handle_t *handle, - uint32_t u32BlockAddr, - uint16_t u16BlockCnt, - uint8_t *pu8Data, - uint32_t u32Timeout) -{ - en_result_t enCmdRet; - stc_sdioc_data_cfg_t stcDataCfg; - uint8_t *pu8TempBuf = (uint8_t *)pu8Data; - uint32_t u32TimeCount = u32Timeout * (SystemCoreClock / 50ul / 1000ul); - __IO uint32_t u32Count = u32TimeCount; - en_sd_card_device_mode_t enDeviceMode = SDCARD_GetDeviceMode(handle); - en_flag_status_t enStatus = Reset; - en_flag_status_t enIrqFlag = Reset; - - if (NULL == handle) - { - return ErrorInvalidParameter; - } - - if ((NULL == pu8Data) || (0u == u16BlockCnt)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_PARAM; - return ErrorInvalidParameter; - } - - handle->u32ErrorCode = SD_CARD_ERROR_NONE; - - if ((u32BlockAddr + u16BlockCnt) > (handle->stcSdCardInfo.u32LogBlockNbr)) - { - handle->u32ErrorCode |= SD_CARD_ERROR_ADDR_OUT_OF_RANGE; - return ErrorInvalidParameter; - } - - /* Set Block Size for Card */ - enCmdRet = SDMMC_Cmd16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - stcDataCfg.u16BlkCnt = u16BlockCnt; - stcDataCfg.u16BlkSize = SD_CARD_BLOCK_SIZE; - stcDataCfg.enDataTimeOut = SdiocDtoSdclk_2_27; - stcDataCfg.enTransferDir = SdiocTransferToCard; - stcDataCfg.enAutoCmd12Enable = (u16BlockCnt > 1u) ? Enable:Disable; - stcDataCfg.enTransferMode = (u16BlockCnt > 1u) ? SdiocTransferMultiple:SdiocTransferSingle; - enCmdRet = SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (handle->stcSdCardInfo.u32CardType != SdCardSdhcSdxc) - { - u32BlockAddr *= SD_CARD_BLOCK_SIZE; - } - - if (enDeviceMode == SdCardDmaMode) - { - if (IS_DMA_CFG_VALID(handle)) - { - DmaSdiocTxConfig(DMA_Unit(handle), DMA_CH(handle), handle->SDIOCx, pu8TempBuf, u16BlockCnt * SD_CARD_BLOCK_SIZE); - } - } - - /* Write block(s) in polling mode */ - if (1u == u16BlockCnt) - { - /* Read Single Block command */ - enCmdRet = SDMMC_Cmd24_WriteSingleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - else - { - /* Read Multi Block command */ - enCmdRet = SDMMC_Cmd25_WriteMultipleBlock(handle->SDIOCx, u32BlockAddr, (uint32_t *)(&handle->stcCardStatus)); - } - - if (enCmdRet != Ok) - { - return enCmdRet; - } - - if (SdCardPollingMode == enDeviceMode) - { - /* Poll on SDIO flags */ - while (u16BlockCnt) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocBufferWriteEnble); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocBufferWriteReady); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - /* Write data to SDIO Tx Buffer */ - SDIOC_WriteBuffer(handle->SDIOCx, pu8TempBuf, SD_CARD_BLOCK_SIZE); - - u16BlockCnt--; - u32Count = u32TimeCount; - pu8TempBuf += SD_CARD_BLOCK_SIZE; - } - - if (u32Count-- == 0ul) - { - return ErrorTimeout; - } - } - } - - for (u32Count = u32TimeCount; u32Count > 0ul; u32Count--) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocData0PinLvl); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - break; - } - } - - if (0u == u32Count) - { - return ErrorTimeout; - } - else - { - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - } - - enCmdRet = SdCardCheckReayForData(handle, u32TimeCount); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* check whether Data transfer stops */ - if(Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocErrorInt)) - { - return Error; - } - - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocBufferWriteReady); - - return Ok; -} - -/** - ****************************************************************************** - ** \brief Set SD bus width. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Set SD bus width successfully. - ** \retval Error Set SD bus width unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcCfg - ** - enBusWidth is invalid. - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardSetBusWidth(stc_sd_handle_t *handle) -{ - uint32_t u32CmdArg = 0ul; - en_result_t enCmdRet = Ok; - - if ((NULL == handle) || (NULL == handle->pstcCardInitCfg)) - { - return ErrorInvalidParameter; - } - - switch (handle->pstcCardInitCfg->enBusWidth) - { - case SdiocBusWidth1Bit: - u32CmdArg = 0u; - break; - case SdiocBusWidth4Bit: - u32CmdArg = 2u; - break; - default: - enCmdRet = ErrorInvalidParameter; - break; - } - - if (Ok != enCmdRet) - { - return enCmdRet; - } - - enCmdRet = SDMMC_Cmd55_AppCmd(handle->SDIOCx, (RelCardAddress(handle) << 16u), (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SDMMC_Acmd6_SetBusWidth(handle->SDIOCx, u32CmdArg, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - enCmdRet = SDIOC_SetBusWidth(handle->SDIOCx, handle->pstcCardInitCfg->enBusWidth); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - return Ok; -} - -/** - ****************************************************************************** - ** \brief Set SD high speed mode. - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Set SD bus width successfully. - ** \retval Ok Set SD bus width unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcCfg - ** - u32Freq is invalid. - ** - ******************************************************************************/ -static en_result_t SdCardSetSpeed(stc_sd_handle_t *handle) -{ - uint8_t au8TempBuf[64] = {0}; - uint32_t u32TimeCount = 2000 * (SystemCoreClock / 8u / 1000u); - __IO uint32_t u32Count = u32TimeCount; - en_flag_status_t enStatus = Reset; - en_flag_status_t enIrqFlag = Reset; - - en_result_t enCmdRet = ErrorInvalidParameter; - stc_sdioc_data_cfg_t stcDataCfg; - uint32_t u32Arg = SD_SET_FUNCTION_HIGH_SPEED; - - if ((NULL != handle) && (NULL != handle->pstcCardInitCfg)) - { - enCmdRet = Ok; - if (SdiocHighSpeedMode == handle->pstcCardInitCfg->enSpeedMode) - { - /* Set Block Size for Card */ - enCmdRet = SDMMC_Cmd16_SetBlockLength(handle->SDIOCx, 64u, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet == Ok) - { - stcDataCfg.u16BlkCnt = 1u; - stcDataCfg.u16BlkSize = 64u; - stcDataCfg.enDataTimeOut = SdiocDtoSdclk_2_27; - stcDataCfg.enTransferDir = SdiocTransferToHost; - stcDataCfg.enAutoCmd12Enable = Disable; - stcDataCfg.enTransferMode = SdiocTransferSingle; - enCmdRet = SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); - if (enCmdRet == Ok) - { - enCmdRet = SDMMC_Cmd6_SwitchFunc(handle->SDIOCx, u32Arg, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet == Ok) - { - while (u32Count--) - { - enStatus = SDIOC_GetStatus(handle->SDIOCx, SdiocBufferReadEnble); - enIrqFlag = SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocBufferReadReady); - if ((Set == enStatus) && (Set == enIrqFlag)) - { - SDIOC_ReadBuffer(handle->SDIOCx, au8TempBuf, sizeof(au8TempBuf)); - break; - } - } - - if (0ul == u32Count) - { - return ErrorTimeout; - } - - u32Count = u32TimeCount; - while (u32Count--) - { - if (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete)) - { - SDIOC_ClearNormalIrqFlag(handle->SDIOCx, SdiocTransferComplete); - break; - } - } - - if (0ul == u32Count) - { - return ErrorTimeout; - } - - /* Check whether switch function with error or transfer error occur */ - if ((!(au8TempBuf[16] & 0x01)) || - (Set == SDIOC_GetNormalIrqFlag(handle->SDIOCx, SdiocErrorInt))) - { - enCmdRet = Error; - } - } - } - } - } - - if (enCmdRet == Ok) - { - SDIOC_SetSpeedMode(handle->SDIOCx, handle->pstcCardInitCfg->enSpeedMode); - - enCmdRet = SDIOC_SetClk(handle->SDIOCx, handle->pstcCardInitCfg->enClkFreq); - } - } - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Initialize SDIO Host - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok SDIO host initialized successfully - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcInitCfg - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardInitHost(const stc_sd_handle_t *handle) -{ - en_result_t enRet = Ok; - - if ((NULL == handle) || (NULL == handle->pstcCardInitCfg)) - { - return ErrorInvalidParameter; - } - - /* Enable SD clock supply */ - if (M4_SDIOC1 == handle->SDIOCx) - { - PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_SDIOC1, Enable); - } - else if (M4_SDIOC2 == handle->SDIOCx) - { - PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_SDIOC2, Enable); - } - else - { - return ErrorInvalidParameter; - } - - /* Set mode: SD */ - SDIOC_SetMode(handle->SDIOCx, SdiocModeSD); - - enRet = SDIOC_Init(handle->SDIOCx, handle->pstcCardInitCfg->pstcInitCfg); - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Initialize SD bus - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok SDIO bus cmd operate successfully. - ** \retval Error SDIO bus cmd operate unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == pstcCfg - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardInitSd(stc_sd_handle_t *handle) -{ - en_result_t enCmdRet = Ok; - - if(NULL == handle) - { - return ErrorInvalidParameter; - } - - if (handle->stcSdCardInfo.u32CardType != SdCardSecured) - { - /* Send CMD2 ALL_SEND_CID */ - enCmdRet = SDMMC_Cmd2_AllSendCID(handle->SDIOCx, handle->CID); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* Send CMD3 SET_REL_ADDR with argument 0 */ - /* SD Card publishes its RCA. */ - enCmdRet = SDMMC_Cmd3_SendRelativeAddr(handle->SDIOCx, &(handle->RCA)); - if (enCmdRet != Ok) - { - return enCmdRet; - } - - /* Get the SD card RCA */ - RelCardAddress(handle) = handle->RCA; - - /* Send CMD9 SEND_CSD with argument as card's RCA */ - enCmdRet = SDMMC_Cmd9_SendCSD(handle->SDIOCx, RelCardAddress(handle), handle->CSD); - if (enCmdRet != Ok) - { - return enCmdRet; - } - } - - /* Get CSD parameters */ - enCmdRet = SDCARD_GetCardCSD(handle); - if (enCmdRet == Ok) - { - /* Select the Card */ - enCmdRet = SDMMC_Cmd7_SelectDeselectCard(handle->SDIOCx, RelCardAddress(handle), (uint32_t *)(&handle->stcCardStatus)); - } - - return enCmdRet; -} - -/** - ******************************************************************************* - ** \brief Activate SD in power-on stage - ** - ** \param [in] handle Pointer to SD handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** - ** \retval Ok Activate successfully. - ** \retval Error Activate unsuccessfully. - ** \retval ErrorInvalidParameter If one of following conditions matches: - ** - NULL == handle - ** - Other invalid configuration - ** - ******************************************************************************/ -static en_result_t SdCardPowerON(stc_sd_handle_t *handle) -{ - uint32_t u32IfCond = 0u; - __IO uint32_t u32Count = 0ul; - en_result_t enCmdRet = Error; - - if (NULL == handle) - { - return ErrorInvalidParameter; - } - - handle->u32ErrorCode = SD_CARD_ERROR_NONE; - - /* CMD0: GO_IDLE_STATE */ - enCmdRet = SDMMC_Cmd0_GoIdleState(handle->SDIOCx); - if (enCmdRet != Ok) - { - handle->u32ErrorCode |= SD_CARD_ERROR_GENERAL_UNKNOWN_ERR; - return enCmdRet; - } - - /* Reset OCR valude */ - handle->OCR = 0ul; - - /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */ - enCmdRet = SDMMC_Cmd8_SendIfCond(handle->SDIOCx, &u32IfCond); - if (enCmdRet != Ok) - { - handle->stcSdCardInfo.u32CardVersion = SdCardVer1x; - - /* Send ACMD41 SD_APP_OP_COND with Argument 0x00100000 */ - while (SD_CARD_OCR_BUSY != (handle->OCR & SD_CARD_OCR_BUSY)) - { - if (SD_CARD_MAX_VOLT_TRIAL == u32Count++) - { - handle->u32ErrorCode |= SD_CARD_ERROR_INVALID_VOLTRANGE; - return enCmdRet; - } - - /* SEND CMD55 APP_CMD with RCA as 0 */ - enCmdRet = SDMMC_Cmd55_AppCmd(handle->SDIOCx, 0u, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - continue; - } - - /* Send CMD41 */ - enCmdRet = SDMMC_Acmd41_SdSendOpCond(handle->SDIOCx, SdmmcStanderdCapacity, &handle->OCR); - if (enCmdRet == Error) - { - handle->u32ErrorCode |= SD_CARD_ERROR_UNSUPPORTED_FEATURE; - return enCmdRet; - } - } - - /* Card type is SDSC */ - handle->stcSdCardInfo.u32CardType = SdCardSdsc; - } - else - { - handle->stcSdCardInfo.u32CardVersion = SdCardVer2x; - - /* Send ACMD41 SD_APP_OP_COND with Argument 0x40100000 */ - while (SD_CARD_OCR_BUSY != (handle->OCR & SD_CARD_OCR_BUSY)) - { - if (SD_CARD_MAX_VOLT_TRIAL == u32Count++) - { - handle->u32ErrorCode |= SD_CARD_ERROR_INVALID_VOLTRANGE; - return Error; - } - - /* SEND CMD55 APP_CMD with RCA as 0 */ - enCmdRet = SDMMC_Cmd55_AppCmd(handle->SDIOCx, 0u, (uint32_t *)(&handle->stcCardStatus)); - if (enCmdRet != Ok) - { - continue; - } - - /* Send CMD41 */ - enCmdRet = SDMMC_Acmd41_SdSendOpCond(handle->SDIOCx, SdmmcHighCapacity, &handle->OCR); - if (enCmdRet == Error) - { - handle->u32ErrorCode |= SD_CARD_ERROR_UNSUPPORTED_FEATURE; - return enCmdRet; - } - } - - if ((handle->OCR & SdmmcHighCapacity) == SdmmcHighCapacity) - { - handle->stcSdCardInfo.u32CardType = SdCardSdhcSdxc; - } - else - { - handle->stcSdCardInfo.u32CardType = SdCardSdsc; - } - } - - return Ok; -} - -/** - ******************************************************************************* - ** \brief Checks if the SD card is ready for data. - ** - ** \param [in] handle Pointer to SD Card handle - ** \arg This parameter detail refer @ref stc_sd_handle_t - ** \param [in] u32Timeout Retry to get card status time - ** - ** \retval Ok Card is ready for data - ** \retval Error Card is not ready for data - ** \retval ErrorInvalidParameter NULL == handle - ** - ******************************************************************************/ -static en_result_t SdCardCheckReayForData(stc_sd_handle_t *handle, uint32_t u32Timeout) -{ - en_result_t enRet = ErrorInvalidParameter; - - if (NULL != handle) - { - do - { - enRet = SDMMC_Cmd13_SendStatus(handle->SDIOCx, RelCardAddress(handle), (uint32_t *)(&handle->stcCardStatus)); - if (Ok != enRet) - { - break; - } - } while ((--u32Timeout) && (false == IsCardReadyForData(handle))); - - if (0u == u32Timeout) - { - enRet = ErrorTimeout; - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Configures the DMA Channel for SDIO Tx request. - ** - ** \param [in] DMAx The pointer to DMAC register base - ** \arg M4_DMA1 DMAC unit 1 instance register base - ** \arg M4_DMA2 DMAC unit 2 instance register base - ** \param [in] enCh The specified DMAC channel. - ** \arg DmaCh0 DMAC channel 0 - ** \arg DmaCh1 DMAC channel 1 - ** \arg DmaCh2 DMAC channel 2 - ** \arg DmaCh3 DMAC channel 3 - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu8TxBuf Pointer to the Tx buffer - ** \param [in] u16len Tx buffer size - ** - ** \retval Ok Set successfully. - ** \retval ErrorInvalidParameter Set unsuccessfully. - ** - ******************************************************************************/ -static en_result_t DmaSdiocTxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8TxBuf, - uint16_t u16len) -{ - stc_dma_config_t stcDmaInit; - uint32_t u32Fcg0Periph = (M4_DMA1 == DMAx) ? PWC_FCG0_PERIPH_DMA1 : PWC_FCG0_PERIPH_DMA2; - en_event_src_t enEvtSrc = (M4_SDIOC1 == SDIOCx) ? EVT_SDIOC1_DMAW : EVT_SDIOC2_DMAW; - en_result_t enRet = ErrorInvalidParameter; - - if ((NULL != pu8TxBuf) && \ - (IS_VALID_TRANSFER_BUF_LEN(u16len)) && \ - (IS_VALID_TRANSFER_BUF_ALIGN(pu8TxBuf))) - { - /* Enable peripheral clock */ - PWC_Fcg0PeriphClockCmd(u32Fcg0Periph, Enable); - - /* Enable DMA. */ - DMA_Cmd(DMAx, Enable); - - /* Initialize DMA. */ - MEM_ZERO_STRUCT(stcDmaInit); - stcDmaInit.u16BlockSize = SD_CARD_BLOCK_SIZE/4u; /* Set data block size. */ - stcDmaInit.u16TransferCnt = u16len/SD_CARD_BLOCK_SIZE; /* Set transfer count. */ - stcDmaInit.u32SrcAddr = (uint32_t)(&pu8TxBuf[0]); /* Set source address. */ - stcDmaInit.u32DesAddr = (uint32_t)(&SDIOCx->BUF0); /* Set destination address. */ - stcDmaInit.stcDmaChCfg.enSrcInc = AddressIncrease; /* Set source address mode. */ - stcDmaInit.stcDmaChCfg.enDesInc = AddressFix; /* Set destination address mode. */ - stcDmaInit.stcDmaChCfg.enTrnWidth = Dma32Bit; /* Set data width 8bit. */ - DMA_InitChannel(DMAx, enCh, &stcDmaInit); - - /* Enable the specified DMA channel. */ - DMA_ChannelCmd(DMAx, enCh, Enable); - - /* Clear DMA flag. */ - DMA_ClearIrqFlag(DMAx, enCh, TrnCpltIrq); - DMA_ClearIrqFlag(DMAx, enCh, BlkTrnCpltIrq); - - /* Enable peripheral circuit trigger function. */ - PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable); - - /* Set DMA trigger source. */ - DMA_SetTriggerSrc(DMAx, enCh, enEvtSrc); - - enRet = Ok; - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Configures the DMA Channel for SDIO Rx request. - ** - ** \param [in] DMAx The pointer to DMAC register base - ** \arg M4_DMA1 DMAC unit 1 instance register base - ** \arg M4_DMA2 DMAC unit 2 instance register base - ** \param [in] enCh The specified DMAC channel. - ** \arg DmaCh0 DMAC channel 0 - ** \arg DmaCh1 DMAC channel 1 - ** \arg DmaCh2 DMAC channel 2 - ** \arg DmaCh3 DMAC channel 3 - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu8RxBuf Pointer to the Rx buffer - ** \param [in] u16len Rx buffer size - ** - ** \retval Ok Set successfully. - ** \retval ErrorInvalidParameter Set unsuccessfully. - ** - ******************************************************************************/ -static en_result_t DmaSdiocRxConfig(M4_DMA_TypeDef* DMAx, - en_dma_channel_t enCh, - M4_SDIOC_TypeDef *SDIOCx, - uint8_t *pu8RxBuf, - uint16_t u16len) -{ - stc_dma_config_t stcDmaInit; - uint32_t u32Fcg0Periph = (M4_DMA1 == DMAx) ? PWC_FCG0_PERIPH_DMA1 : PWC_FCG0_PERIPH_DMA2; - en_event_src_t enEvtSrc = (M4_SDIOC1 == SDIOCx) ? EVT_SDIOC1_DMAR : EVT_SDIOC2_DMAR; - en_result_t enRet = ErrorInvalidParameter; - - if ((NULL != pu8RxBuf) && \ - (IS_VALID_TRANSFER_BUF_LEN(u16len)) && \ - (IS_VALID_TRANSFER_BUF_ALIGN(pu8RxBuf))) - { - /* Enable peripheral clock */ - PWC_Fcg0PeriphClockCmd(u32Fcg0Periph,Enable); - - /* Enable DMA. */ - DMA_Cmd(DMAx, Enable); - - /* Initialize DMA. */ - MEM_ZERO_STRUCT(stcDmaInit); - stcDmaInit.u16BlockSize = SD_CARD_BLOCK_SIZE/4u; /* Set data block size. */ - stcDmaInit.u16TransferCnt = u16len/SD_CARD_BLOCK_SIZE; /* Set transfer count. */ - stcDmaInit.u32SrcAddr = (uint32_t)(&SDIOCx->BUF0); /* Set source address. */ - stcDmaInit.u32DesAddr = (uint32_t)(&pu8RxBuf[0]); /* Set destination address. */ - stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix; /* Set source address mode. */ - stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease; /* Set destination address mode. */ - stcDmaInit.stcDmaChCfg.enTrnWidth = Dma32Bit; /* Set data width 8bit. */ - DMA_InitChannel(DMAx, enCh, &stcDmaInit); - - /* Enable the specified DMA channel. */ - DMA_ChannelCmd(DMAx, enCh, Enable); - - /* Clear DMA flag. */ - DMA_ClearIrqFlag(DMAx, enCh, TrnCpltIrq); - DMA_ClearIrqFlag(DMAx, enCh, BlkTrnCpltIrq); - - /* Enable peripheral circuit trigger function. */ - PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable); - - /* Set DMA trigger source. */ - DMA_SetTriggerSrc(DMAx, enCh, enEvtSrc); - - enRet = Ok; - } - - return enRet; -} - -//@} // SdiocGroup - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Project/GateWay/source/Module/SDCard/sdmmc_cmd.c b/Project/GateWay/source/Module/SDCard/sdmmc_cmd.c deleted file mode 100644 index 2bdaa1b..0000000 --- a/Project/GateWay/source/Module/SDCard/sdmmc_cmd.c +++ /dev/null @@ -1,1641 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - */ -/******************************************************************************/ -/** \file sdmmc_cmd.c - ** - ** A detailed description is available at - ** @link SdiocGroup SDIOC description @endlink - ** - ** - 2018-11-15 CDT First version for Device Driver Library of SDIOC. - ** - ******************************************************************************/ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "sdmmc_cmd.h" - -/** - ******************************************************************************* - ** \addtogroup SdiocGroup - ******************************************************************************/ -//@{ - -/******************************************************************************* - * Local type definitions ('typedef') - ******************************************************************************/ - -/******************************************************************************* - * Local pre-processor symbols/macros ('#define') - ******************************************************************************/ - -/*!< Parameter valid check for SDIOC Instances. */ -#define IS_VALID_SDIOC(__SDIOCx__) \ -( (M4_SDIOC1 == (__SDIOCx__)) || \ - (M4_SDIOC2 == (__SDIOCx__))) - -/*!< Parameter valid check for SDIOC Instances. */ -#define IS_VALID_SD_TYPE(x) \ -( (SdmmcHighCapacity == (x)) || \ - (SdmmcStanderdCapacity == (x))) - -/*!< CMDBSY bit loop count */ -#define SDIOC_FLAG_CMDBUSY_LOOPS (200000ul) - -/*!< Command send and response timeout */ -#define SDMMC_CMD_TIMEOUT (10000ul) - -/*!< OCR register bit */ -#define SDMMC_SD_OCR_HCS (0x40000000ul) /* High Capacity Support */ -#define SDMMC_SD_OCR_BUSY (0x80000000ul) /* Card power up status bit (busy) */ - - -#define SDMMC_BUS_WIDTH_1BIT (0x00000000ul) -#define SDMMC_BUS_WIDTH_4BIT (0x00000002ul) - -#define SDMMC_CMD8_CHECK_PATTERN (0x000000AAul) -#define SDMMC_CMD8_VOLTAGE_SUPPLIED (0x00000100ul) /* 2.7 - 3.6v*/ -#define SDMMC_CMD8_ARGUEMENT (SDMMC_CMD8_VOLTAGE_SUPPLIED | SDMMC_CMD8_CHECK_PATTERN) -#define SDMMC_ACMD41_VOLTAGE (SDMMC_SD_VOLT_3_3) -#define SDMMC_ACMD41_HCS (1ul << 30u) - -/*!< Masks for R1 Response (SD Card Status Register) */ -#define SDMMC_R1_AKE_SEQ_ERROR (0x1ul << 3u ) -#define SDMMC_R1_ERASE_RESET (0x1ul << 13u) -#define SDMMC_R1_CARD_ECC_DISABLED (0x1ul << 14u) -#define SDMMC_R1_WP_ERASE_SKIP (0x1ul << 15u) -#define SDMMC_R1_CID_CSD_OVERWRITE (0x1ul << 16u) -#define SDMMC_R1_STREAM_WRITE_OVERRUN (0x1ul << 17u) -#define SDMMC_R1_STREAM_READ_UNDERRUN (0x1ul << 18u) -#define SDMMC_R1_GENERAL_UNKNOWN_ERROR (0x1ul << 19u) -#define SDMMC_R1_CC_ERROR (0x1ul << 20u) -#define SDMMC_R1_CARD_ECC_FAILED (0x1ul << 21u) -#define SDMMC_R1_ILLEGAL_COMMAND (0x1ul << 22u) -#define SDMMC_R1_COM_CRC_ERROR (0x1ul << 23u) -#define SDMMC_R1_LOCK_UNLOCK_FAILED (0x1ul << 24u) -#define SDMMC_R1_WP_VIOLATION (0x1ul << 26u) -#define SDMMC_R1_ERASE_PARAM_ERROR (0x1ul << 27u) -#define SDMMC_R1_ERASE_SEQ_ERROR (0x1ul << 28u) -#define SDMMC_R1_BLOCK_LEN_ERROR (0x1ul << 29u) -#define SDMMC_R1_ADDRESS_ERROR (0x1ul << 30u) -#define SDMMC_R1_OUT_OF_RANGE (0x1ul << 31u) -#define SDMMC_R1_ERRORS (0xFDFFE008ul) - -/*!< Masks for R6 Response. */ -#define SDMMC_R6_GENERAL_UNKNOWN_ERROR (0x1ul << 13u) -#define SDMMC_R6_ILLEGAL_CMD (0x1ul << 14u) -#define SDMMC_R6_COM_CRC_ERROR (0x1ul << 15u) - -/******************************************************************************* - * Global variable definitions (declared in header file with 'extern') - ******************************************************************************/ - -/******************************************************************************* - * Local function prototypes ('static') - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp1(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout); -static en_result_t SDMMC_GetCmdResp1b(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout); -static en_result_t SDMMC_GetCmdResp2(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32CID_CSD[4]); -static en_result_t SDMMC_GetCmdResp3(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32OCR); -static en_result_t SDMMC_GetCmdResp6(M4_SDIOC_TypeDef *SDIOx, - uint32_t *pu32RCA); -static en_result_t SDMMC_GetCmdResp7(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32IfCond); -static en_result_t SDMMC_WaitBusIdle(M4_SDIOC_TypeDef *SDIOCx); -static en_result_t SDMMC_WaitResponse(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32Timeout); -static bool SDMMC_GetCardDetection(M4_SDIOC_TypeDef *SDIOCx); - -/******************************************************************************* - * Local variable definitions ('static') - ******************************************************************************/ - -/******************************************************************************* - * Function implementation - global ('extern') and local ('static') - ******************************************************************************/ -/** - ******************************************************************************* - ** \brief Send the GO_IDLE_STATE command which will reset all cards to idle state - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd0_GoIdleState(M4_SDIOC_TypeDef *SDIOCx) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD0_GO_IDLE_STATE; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdNoRsp; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_OP_COND command. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Argument Argument used for the command. - ** \param [in] pu32OCR Pointer to buffer which will store OCR content. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd1_SendOpCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32OCR) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD1_SEND_OP_COND; - stcCmdCfg.u32Argument = u32Argument; - stcCmdCfg.enRspIndex = SdiocCmdRspR3; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp3(SDIOCx, pu32OCR); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ALL_SEND_CID command for asking any card to send the CID numbers - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32CID Pointer to buffer which will store CID content. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd2_AllSendCID(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32CID[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD2_ALL_SEND_CID; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR2; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp2(SDIOCx, u32CID); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_RELATIVE_ADDR command for asking the card to publish a - ** new relative address(RCA) - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32RCA Pointer to buffer which will store RCA. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd3_SendRelativeAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32RCA) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD3_SEND_RELATIVE_ADDR; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR6; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp6(SDIOCx, pu32RCA); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SWITCH_FUNC command. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Argument Argument used for the command. - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd6_SwitchFunc(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD6_SWITCH_FUNC; - stcCmdCfg.u32Argument = u32Argument; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SELECT/DESELECT_CARD command for toggling a card between the - ** stand-by and transfer states or between the programming and disconnect states. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Sdcard Address. - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd7_SelectDeselectCard(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD7_SEL_DESEL_CARD; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_IF_COND command. Sends SD Memory Card interface - ** condition, which includes host supply voltage information and asks - ** the card whether card supports voltage - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32IfCond Pointer to buffers for storing interface condition. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd8_SendIfCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32IfCond) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Send CMD8 to verify SD card interface operating condition */ - /* Argument: - [31:12]: Reserved (shall be set to '0') - - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) - - [7:0]: Check Pattern (recommended 0xAA) */ - /* CMD Response: R7 */ - stcCmdCfg.u8CmdIndex = CMD8_SEND_IF_COND; - stcCmdCfg.u32Argument = SDMMC_CMD8_ARGUEMENT; - stcCmdCfg.enRspIndex = SdiocCmdRspR7; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); /* Set command and argument. */ - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp7(SDIOCx, pu32IfCond); - if (enRet == Ok) - { - if((*pu32IfCond & 0xFFu) != SDMMC_CMD8_CHECK_PATTERN) - { - enRet = Error; - } - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_CSD command to addressed card which will sends its - ** card-specificdata (CSD). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Card Address - ** \param [in] u32CSD Pointer to buffers for storing CSD contents. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd9_SendCSD(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t u32CSD[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD9_SEND_CSD; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR2; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp2(SDIOCx, u32CSD); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_CID command to addressed card which will sends its card - ** identification(CID). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Card Address - ** \param [in] u32CID Pointer to buffers for storing CID contents. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd10_SendCID(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t u32CID[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD10_SEND_CID; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR2; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp2(SDIOCx, u32CID); - } - } - } - - return enRet; -} - -/******************************************************************************* -** \brief Send the STOP_TRANSMISSION command to force the card to stop transmission. -** -** \param [in] SDIOCx Pointer to SDIOC instance register base -** \arg M4_SDIOC1 SDIOC unit 1 instance register base -** \arg M4_SDIOC2 SDIOC unit 2 instance register base -** -** \retval Ok Send successfully. -** \retval Error Send unsuccessfully. -** -*******************************************************************************/ -en_result_t SDMMC_Cmd12_StopTransmission(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD12_STOP_TRANSMISSION; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_STATUS to addressed card which will send its status - ** register contents - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Card Address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd13_SendStatus(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD13_SEND_STATUS; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SET_BLOCKLEN command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32BlockLen Block length - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd16_SetBlockLength(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32BlockLen, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD16_SET_BLOCKLEN; - stcCmdCfg.u32Argument = u32BlockLen; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the READ_SINGLE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32ReadAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd17_ReadSingleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ReadAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD17_READ_SINGLE_BLOCK; - stcCmdCfg.u32Argument = u32ReadAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the READ_MULTIPLE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32ReadAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd18_ReadMultipleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ReadAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD18_READ_MULTIPLE_BLOCK; - stcCmdCfg.u32Argument = u32ReadAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the WRITE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32WriteAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd24_WriteSingleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32WriteAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD24_WRITE_SINGLE_BLOCK; - stcCmdCfg.u32Argument = u32WriteAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the WRITE_MULTIPLE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32WriteAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd25_WriteMultipleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32WriteAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD25_WRITE_MULTIPLE_BLOCK; - stcCmdCfg.u32Argument = u32WriteAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_WR_BLK_START command for setting the address of the - ** first write block to be erased. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32StartAddr The start address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd32_EraseWrBlkStart(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32StartAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD32_ERASE_WR_BLK_START; - stcCmdCfg.u32Argument = u32StartAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_WR_BLK_END command for setting the address of the - ** last write block of the continuous range to be erased. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32EndAddr The last address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd33_EraseWrBlkEnd(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32EndAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD33_ERASE_WR_BLK_END; - stcCmdCfg.u32Argument = u32EndAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_GRP_START command and check the response. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32StartAddr The start address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd35_SetEraseStartAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32StartAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD35_ERASE_GRP_START; - stcCmdCfg.u32Argument = u32StartAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_GRP_END command and check the response. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32EndAddr The end address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd36_SetEraseEndAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32EndAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD36_ERASE_GRP_END; - stcCmdCfg.u32Argument = u32EndAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE command for erasing all previously selected write blocks. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd38_Erase(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - SDIOC_SetDataTimeout(SDIOCx, SdiocDtoSdclk_2_27); - - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD38_ERASE; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1b; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1b(SDIOCx, pu32Resp1, 50u * SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the APP_CMD Command to interpret the following command as an - ** application-specific command(ACMD). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Argument Command argument(RCA) - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd55_AppCmd(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD55_APP_CMD; - stcCmdCfg.u32Argument = u32Argument; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SET_BUS_WIDTH(ACMD6) Command to set bus width. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32BusWidth The data bus width, '00'= 1bit or '10' = 4bits bus - ** \arg SDMMC_BUS_WIDTH_1BIT 1 bits bus - ** \arg SDMMC_BUS_WIDTH_4BIT 4 bits bus - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd6_SetBusWidth(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32BusWidth, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD6_APP_SD_SET_BUSWIDTH; - stcCmdCfg.u32Argument = u32BusWidth; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SD_STATUS(ACMD13) Command to ask the Status Register. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd13_SdStatus(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD13_SD_APP_STATUS; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SD_SEND_OP_COND(ACMD41) command to negotiate the operation - ** voltage range and get OCR. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32SdType Sdcard type - ** \arg SdmmcHighCapacity SD memory card: Standard capacity - ** \arg SdmmcHighCapacity SD memory card: High capacity - ** \param [in] pu32OCR Pointer to the variable that will contain - ** the OCR register contents. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd41_SdSendOpCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32SdType, uint32_t *pu32OCR) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32OCR)) - { - DDL_ASSERT(IS_VALID_SD_TYPE(u32SdType)); - - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD41_SD_SEND_OP_COND; - stcCmdCfg.u32Argument = SDMMC_ACMD41_VOLTAGE | u32SdType; - stcCmdCfg.enRspIndex = SdiocCmdRspR3; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp3(SDIOCx, pu32OCR); - if (enRet == Ok) - { - if (!(*pu32OCR & SDMMC_SD_OCR_BUSY)) - { - enRet = ErrorOperationInProgress; - } - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_SCR(ACMD51) command to read the SD Configuration Register(SCR). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd51_SendSCR(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD51_SD_APP_SEND_SCR; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R1(normal response command). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32CmdResp1 received response value - ** \param [in] u32Timeout timeout for waiting SDIOC idle - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32CmdResp1 == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp1(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout) -{ - uint32_t u32R1 = 0u; - en_result_t enRet = ErrorInvalidParameter; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitResponse(SDIOCx, u32Timeout); - if (enRet == Ok) - { - /* received response, retrieve it for analysis */ - u32R1 = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - if (u32R1 & SDMMC_R1_ERRORS) - { - enRet = Error; - } - - if (pu32CmdResp1 != NULL) - { - *pu32CmdResp1 = u32R1; - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R1(normal response command) with busy signal. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32CmdResp1 received response value - ** \param [in] u32Timeout timeout for waiting SDIOC idle - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32CmdResp1 == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp1b(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout) -{ - uint32_t u32R1 = 0u; - en_result_t enRet = ErrorInvalidParameter; - __IO uint32_t u32TmpCnt = u32Timeout; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitResponse(SDIOCx, u32Timeout); - if (enRet == Ok) - { - do - { - if (u32TmpCnt-- == 0u) - { - enRet = ErrorTimeout; - } - } while (Reset == SDIOC_GetStatus(SDIOCx, SdiocData0PinLvl)); - - if (enRet == Ok) - { - /* received response, retrieve it for analysis */ - u32R1 = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - if (u32R1 & SDMMC_R1_ERRORS) - { - enRet = Error; - } - - if (pu32CmdResp1 != NULL) - { - *pu32CmdResp1 = u32R1; - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R2(CID, CSD register). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32CID_CSD Pointer to the variable that will contain the - ** CID or CSD register contents - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter u32CID_CSD == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp2(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32CID_CSD[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != u32CID_CSD)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - /* received response */ - u32CID_CSD[0] = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - u32CID_CSD[1] = SDIOC_GetResponse(SDIOCx, SdiocRegResp23); - u32CID_CSD[2] = SDIOC_GetResponse(SDIOCx, SdiocRegResp45); - u32CID_CSD[3] = SDIOC_GetResponse(SDIOCx, SdiocRegResp67); - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R3(OCR register). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32OCR Pointer to the variable that will contain - ** the OCR register contents. - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32OCR == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp3(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32OCR) -{ - en_result_t enRet = ErrorInvalidParameter; - - if((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32OCR)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - /* received response, retrieve it for analysis */ - *pu32OCR = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R6(Published RCA response). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32RCA Pointer to the variable that will contain - ** published RCA number - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32RCA == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp6(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32RCA) -{ - uint32_t u32R6 = 0ul; - en_result_t enRet = ErrorInvalidParameter; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32RCA)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - /* received response, retrieve it. */ - u32R6 = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - if (!(u32R6 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_ERROR))) - { - *pu32RCA = (u32R6 >> 16); - } - else - { - enRet = Error; - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R7. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32IfCond Pointer to the variable that will contain - ** interface condition. - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32IfCond == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp7(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32IfCond) -{ - en_result_t enRet = ErrorInvalidParameter; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32IfCond)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - *pu32IfCond = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Wait for bus line idle - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** - ** \retval Ok Command&Data line is free within a certain time - ** \retval ErrorTimeout Command&Data line is still busy after a certain time. - ** \retval ErrorInvalidParameter SDIOCx == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_WaitBusIdle(M4_SDIOC_TypeDef *SDIOCx) -{ - en_result_t enRet = ErrorInvalidParameter; - uint32_t u32Retry = SDIOC_FLAG_CMDBUSY_LOOPS; - en_flag_status_t enInhibitCmdStatus = Set; - en_flag_status_t enInhibitDataStatus = Set; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = ErrorTimeout; - while (u32Retry-- > 0ul) - { - enInhibitCmdStatus = SDIOC_GetStatus(SDIOCx, SdiocCommandInhibitCmd); - enInhibitDataStatus = SDIOC_GetStatus(SDIOCx, SdiocCommandInhibitData); - if ((Reset == enInhibitCmdStatus) || (Reset == enInhibitDataStatus)) - { - enRet = Ok; - break; - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Wait response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Timeout timeout times - ** - ** \retval Ok Respond normal - ** \retval ErrorTimeout Respond timeout. - ** \retval ErrorInvalidParameter SDIOCx == NULL - ** \retval ErrorAccessRights Card is removed. - ** - ******************************************************************************/ -static en_result_t SDMMC_WaitResponse(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32Timeout) -{ - /* 8 is the number of required instructions cycles for the below loop statement. - The Timeout is expressed in ms */ - __IO uint32_t u32Count = u32Timeout * (SystemCoreClock / 8u /1000u); - en_flag_status_t enErrorInt = Set; - en_flag_status_t enCommandComplete = Set; - en_result_t enRet = ErrorInvalidParameter; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = Ok; - do - { - if (u32Count-- == 0u) - { - enRet = ErrorTimeout; - break; - } - enErrorInt = SDIOC_GetNormalIrqFlag(SDIOCx, SdiocErrorInt); - enCommandComplete = SDIOC_GetNormalIrqFlag(SDIOCx, SdiocCommandComplete); - } while ((Reset == enErrorInt) && (Reset == enCommandComplete)); - - if (enRet == Ok) - { - if (Set == SDIOC_GetNormalIrqFlag(SDIOCx, SdiocErrorInt)) - { - enRet = Error; - } - else - { - if (false == SDMMC_GetCardDetection(SDIOCx)) - { - enRet = ErrorAccessRights; - } - else - { - if (Set == SDIOC_GetNormalIrqFlag(SDIOCx, SdiocCommandComplete)) - { - SDIOC_ClearNormalIrqFlag(SDIOCx, SdiocCommandComplete); - } - - if (Set == SDIOC_GetNormalIrqFlag(SDIOCx, SdiocTransferComplete)) - { - SDIOC_ClearNormalIrqFlag(SDIOCx, SdiocTransferComplete); - } - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get card insertion status - ** - ** This function checks card is inserted or not. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** - ** \retval true Card is inserted - ** \retval false Card is removed - ** - ******************************************************************************/ -static bool SDMMC_GetCardDetection(M4_SDIOC_TypeDef *SDIOCx) -{ - bool bRet = false; - __IO uint32_t u32Count = 5000ul * (SystemCoreClock / 8ul /1000ul); - - /* Wait until card is stable */ - do - { - if (Set == SDIOC_GetStatus(SDIOCx, SdiocCardStateStable)) - { - break; - } - } while (u32Count--); - - if (u32Count != 0ul) - { - bRet = true;//(Set == SDIOC_GetStatus(SDIOCx, SdiocCardInserted)) ? true : false; - } - - return bRet; -} - -//@} // SdiocGroup - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Project/GateWay/source/Module/SDCard/sdmmc_cmd.h b/Project/GateWay/source/Module/SDCard/sdmmc_cmd.h deleted file mode 100644 index 9890e53..0000000 --- a/Project/GateWay/source/Module/SDCard/sdmmc_cmd.h +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - */ -/******************************************************************************/ -/** \file sdmmc_cmd.h - ** - ** A detailed description is available at - ** @link SdiocGroup SDIOC description @endlink - ** - ** - 2018-11-15 CDT First version for Device Driver Library of SDIOC. - ** - ******************************************************************************/ -#ifndef __SDMMC_CMD_H__ -#define __SDMMC_CMD_H__ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "hc32_ddl.h" -#include "hc32f460_utility.h" - -/* C binding of definitions if building with C++ compiler */ -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - ******************************************************************************* - ** \defgroup SdiocGroup Secure Digital Input and Output Controller(SDIOC) - ** - ******************************************************************************/ -//@{ - -/******************************************************************************* - * Global type definitions ('typedef') - ******************************************************************************/ -/** - ******************************************************************************* - ** \brief SD/eMMC/SDIO card status - ** - ******************************************************************************/ -typedef enum en_sdmmc_card_state -{ - SdmmcCardStateIdle = 0u, ///< Card state: Idle State - SdmmcCardStateReady = 1u, ///< Card state: Ready State - SdmmcCardStateIdent = 2u, ///< Card state: Identification State - SdmmcCardStateStby = 3u, ///< Card state: Stand-by State - SdmmcCardStateTran = 4u, ///< Card state: Transfer State - SdmmcCardStateSendData = 5u, ///< Card state: Sending-data State - SdmmcCardStateRcvData = 6u, ///< Card state: Receive-data State - SdmmcCardStatePgm = 7u, ///< Card state: Programming State - SdmmcCardStateDis = 8u, ///< Card state: Disconnect State -} en_sdmmc_card_state_t; - -/** - ******************************************************************************* - ** \brief SD/eMMC/SDIO card capacity. - ** - ******************************************************************************/ -typedef enum sdmmc_capacity -{ - SdmmcStanderdCapacity = 0x00000000u, ///< Card capacity: Standard Capacity - SdmmcHighCapacity = 0x40000000u, ///< Card capacity: High Capacity -} sdmmc_capacity_t; - -/** - ******************************************************************************* - ** \brief SD/eMMC/SDIO card response data structure. - ** - ******************************************************************************/ -typedef struct stc_sdmmc_resp_card_status -{ - uint32_t RESERVE1 :3; ///< RESERVE - uint32_t AKE_SEQ_ERROR :1; ///< Error in the sequence of the authentication process - uint32_t RESERVE2 :1; ///< RESERVE - uint32_t APP_CMD :1; ///< The card will expect ACMD, or an indication that the command has been interpreted as ACMD - uint32_t RESERVE3 :2; ///< RESERVE - uint32_t READY_FOR_DATA :1; ///< Corresponds to buffer empty signaling on the bus - uint32_t CURRENT_STATE :4; ///< The state of the card when receiving the command. - - uint32_t ERASE_RESET :1; ///< An erase sequence was cleared before executing because an out of erase sequence command was received - uint32_t CARD_ECC_DISABLE :1; ///< The command has been executed without using the internal ECC. - uint32_t WP_ERASE_SKIP :1; ///< Set when only partial address space was erased due to existing write protected blocks or the temporary or permanent write protected card was erased. - uint32_t CSD_OVERWRITE :1; ///< - The read only section of the CSD does not match the card content. - ///< - An attempt to reverse the copy (set as original) or permanent WP (unprotected) bits was made. - uint32_t RESERVE4 :2; ///< RESERVE - uint32_t ERRORR :1; ///< A general or an unknown error occurred during the operation. - uint32_t CC_ERROR :1; ///< Internal card controller error - uint32_t CARD_ECC_FAIL :1; ///< Card internal ECC was applied but failed to correct the data. - uint32_t ILLEGAL_CMD :1; ///< Command not legal for the card state - uint32_t COM_CRC_ERROR :1; ///< The CRC check of the previous command failed. - uint32_t LOCK_UNLOCK_FAIL :1; ///< Set when a sequence or password error has been detected in lock/unlock card command. - uint32_t CARD_IS_LOCKED :1; ///< When set, signals that the card is locked by the host - uint32_t WP_VIOLATION :1; ///< Set when the host attempts to write to a protected block or to the temporary or permanent write protected card. - uint32_t ERASE_PARAM :1; ///< An invalid selection of write-blocks for erase occurred. - uint32_t ERASE_SEQ_ERR :1; ///< An error in the sequence of erase commands occurred. - uint32_t BLOCK_LEN_ERR :1; ///< The transferred block length is not allowed for this card, or the number of transferred bytes does not match the block length. - uint32_t ADDRESS_ERROR :1; ///< A misaligned address which did not match the block length was used in the command. - uint32_t OUT_OF_RANGE :1; ///< The command鈥檚 argument was out of the allowed range for this card. -} stc_sdmmc_resp_card_status_t; - -/******************************************************************************* - * Global pre-processor symbols/macros ('#define') - ******************************************************************************/ -/** - ******************************************************************************* - ** \brief SDMMC Commands Index - ** - ******************************************************************************/ -#define CMD0_GO_IDLE_STATE (0u) /*!< Resets the SD memory card. */ -#define CMD1_SEND_OP_COND (1u) /*!< Sends host capacity support information and activates the card's initialization process. */ -#define CMD2_ALL_SEND_CID (2u) /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */ -#define CMD3_SEND_RELATIVE_ADDR (3u) /*!< Asks the card to publish a new relative address (RCA). */ -#define CMD_SET_DSR (4u) /*!< Programs the DSR of all cards. */ -#define CMD_SDMMC_SEN_OP_COND (5u) /*!< Sends host capacity support information (HCS) and asks the accessed card to send its - operating condition register (OCR) content in the response on the CMD line. */ -#define CMD6_SWITCH_FUNC (6u) /*!< Checks switchable function (mode 0) and switch card function (mode 1). */ -#define CMD7_SEL_DESEL_CARD (7u) /*!< Selects the card by its own relative address and gets deselected by any other address */ -#define CMD8_SEND_IF_COND (8u) /*!< Sends SD Memory Card interface condition, which includes host supply voltage information - and asks the card whether card supports voltage. */ -#define CMD9_SEND_CSD (9u) /*!< Addressed card sends its card specific data (CSD) on the CMD line. */ -#define CMD10_SEND_CID (10u) /*!< Addressed card sends its card identification (CID) on the CMD line. */ -#define CMD11_READ_DAT_UNTIL_STOP (11u) /*!< SD card doesn't support it. */ -#define CMD12_STOP_TRANSMISSION (12u) /*!< Forces the card to stop transmission. */ -#define CMD13_SEND_STATUS (13u) /*!< Addressed card sends its status register. */ -#define CMD14_HS_BUSTEST_READ (14u) /*!< Reserved */ -#define CMD15_GO_INACTIVE_STATE (15u) /*!< Sends an addressed card into the inactive state. */ -#define CMD16_SET_BLOCKLEN (16u) /*!< Sets the block length (in bytes for SDSC) for all following block commands - (read, write, lock). Default block length is fixed to 512 Bytes. Not effective - for SDHS and SDXC. */ -#define CMD17_READ_SINGLE_BLOCK (17u) /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of - fixed 512 bytes in case of SDHC and SDXC. */ -#define CMD18_READ_MULTIPLE_BLOCK (18u) /*!< Continuously transfers data blocks from card to host until interrupted by - STOP_TRANSMISSION command. */ -#define CMD19_HS_BUSTEST_WRITE (19u) /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */ -#define CMD20_WRITE_DAT_UNTIL_STOP (20u) /*!< Speed class control command. */ -#define CMD23_SET_BLOCK_COUNT (23u) /*!< Specify block count for CMD18 and CMD25. */ -#define CMD24_WRITE_SINGLE_BLOCK (24u) /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of - fixed 512 bytes in case of SDHC and SDXC. */ -#define CMD25_WRITE_MULTIPLE_BLOCK (25u) /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */ -#define CMD26_PROG_CID (26u) /*!< Reserved for manufacturers. */ -#define CMD27_PROG_CSD (27u) /*!< Programming of the programmable bits of the CSD. */ -#define CMD28_SET_WRITE_PROT (28u) /*!< Sets the write protection bit of the addressed group. */ -#define CMD29_CLR_WRITE_PROT (29u) /*!< Clears the write protection bit of the addressed group. */ -#define CMD30_SEND_WRITE_PROT (30u) /*!< Asks the card to send the status of the write protection bits. */ -#define CMD32_ERASE_WR_BLK_START (32u) /*!< Sets the address of the first write block to be erased. (For SD card only). */ -#define CMD33_ERASE_WR_BLK_END (33u) /*!< Sets the address of the last write block of the continuous range to be erased. */ -#define CMD35_ERASE_GRP_START (35u) /*!< Sets the address of the first write block to be erased. Reserved for each command - system set by switch function command (CMD6). */ -#define CMD36_ERASE_GRP_END (36u) /*!< Sets the address of the last write block of the continuous range to be erased. - Reserved for each command system set by switch function command (CMD6). */ -#define CMD38_ERASE (38u) /*!< Reserved for SD security applications. */ -#define CMD39_FAST_IO (39u) /*!< SD card doesn't support it (Reserved). */ -#define CMD40_GO_IRQ_STATE (40u) /*!< SD card doesn't support it (Reserved). */ -#define CMD42_LOCK_UNLOCK (42u) /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by - the SET_BLOCK_LEN command. */ -#define CMD55_APP_CMD (55u) /*!< Indicates to the card that the next command is an application specific command rather - than a standard command. */ -#define CMD56_GEN_CMD (56u) /*!< Used either to transfer a data block to the card or to get a data block from the card - for general purpose/application specific commands. */ -#define CMD64_NO_CMD (64u) /*!< No command */ - -/** - ******************************************************************************* - ** \brief SDMMC_APP_CMD Commands Index - ** - ******************************************************************************/ -#define ACMD6_APP_SD_SET_BUSWIDTH (6u) /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus - widths are given in SCR register. */ -#define ACMD13_SD_APP_STATUS (13u) /*!< (ACMD13) Sends the SD status. */ -#define ACMD22_SD_APP_SEND_NUM_WRITE_BLOCKS (22u) /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with - 32bit+CRC data block. */ -#define ACMD41_SD_SEND_OP_COND (41u) /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to - send its operating condition register (OCR) content in the response on the CMD line. */ -#define ACMD42_SET_CLR_CARD_DETECT (42u) /*!< (ACMD42) Connect/Disconnect the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card */ -#define ACMD51_SD_APP_SEND_SCR (51u) /*!< Reads the SD Configuration Register (SCR). */ -#define ACMD52_RW_DIRECT (52u) /*!< For SD I/O card only, reserved for security specification. */ -#define ACMD53_RW_EXTENDED (53u) /*!< For SD I/O card only, reserved for security specification. */ - -/** - ******************************************************************************* - ** \brief SD Card Specific security commands Commands Index - ** - ******************************************************************************/ -#define ACMD43_GET_MKB (43u) -#define ACMD44_GET_MID (44u) -#define ACMD45_SET_CER_RN1 (45u) -#define ACMD46_GET_CER_RN2 (46u) -#define ACMD47_SET_CER_RES2 (47u) -#define ACMD48_GET_CER_RES1 (48u) -#define ACMD18_SECURE_READ_MULTIPLE_BLOCK (18u) -#define ACMD25_SECURE_WRITE_MULTIPLE_BLOCK (25u) -#define ACMD38_SECURE_ERASE (38u) -#define ACMD49_CHANGE_SECURE_AREA (49u) -#define ACMD48_SECURE_WRITE_MKB (48u) - -/** - ******************************************************************************* - ** \brief Media voltage supported. - ** - ******************************************************************************/ -#define SDMMC_SD_VOLT_1_7 (0x00000010ul) /* Low voltage card minimum */ -#define SDMMC_SD_VOLT_1_8 (0x00000020ul) -#define SDMMC_SD_VOLT_1_9 (0x00000040ul) -#define SDMMC_SD_VOLT_2_0 (0x00000080ul) -#define SDMMC_SD_VOLT_2_1 (0x00000100ul) /* Basic communication minimum */ -#define SDMMC_SD_VOLT_2_2 (0x00000200ul) -#define SDMMC_SD_VOLT_2_3 (0x00000400ul) -#define SDMMC_SD_VOLT_2_4 (0x00000800ul) -#define SDMMC_SD_VOLT_2_5 (0x00001000ul) -#define SDMMC_SD_VOLT_2_6 (0x00002000ul) -#define SDMMC_SD_VOLT_2_7 (0x00004000ul) -#define SDMMC_SD_VOLT_2_8 (0x00008000ul) /* Memory access minimum */ -#define SDMMC_SD_VOLT_2_9 (0x00010000ul) -#define SDMMC_SD_VOLT_3_0 (0x00020000ul) -#define SDMMC_SD_VOLT_3_1 (0x00040000ul) -#define SDMMC_SD_VOLT_3_2 (0x00080000ul) -#define SDMMC_SD_VOLT_3_3 (0x00100000ul) -#define SDMMC_SD_VOLT_3_4 (0x00200000ul) -#define SDMMC_SD_VOLT_3_5 (0x00400000ul) -#define SDMMC_SD_VOLT_3_6 (0x00800000ul) - - -#define SDMMC_ERROR_NONE (0x00000000ul) /*!< No error */ -#define SDMMC_ERROR_CMD_CRC_FAIL (0x00000001ul) /*!< Command response received (but CRC check failed) */ -#define SDMMC_ERROR_DATA_CRC_FAIL (0x00000002ul) /*!< Data block sent/received (CRC check failed) */ -#define SDMMC_ERROR_CMD_RSP_TIMEOUT (0x00000004ul) /*!< Command response timeout */ -#define SDMMC_ERROR_DATA_TIMEOUT (0x00000008ul) /*!< Data timeout */ -#define SDMMC_ERROR_TX_UNDERRUN (0x00000010ul) /*!< Transmit FIFO underrun */ -#define SDMMC_ERROR_RX_OVERRUN (0x00000020ul) /*!< Receive FIFO overrun */ -#define SDMMC_ERROR_ADDR_MISALIGNED (0x00000040ul) /*!< Misaligned address */ -#define SDMMC_ERROR_BLOCK_LEN_ERR (0x00000080ul) /*!< Transferred block length is not allowed for the card or the - number of transferred bytes does not match the block length */ -#define SDMMC_ERROR_ERASE_SEQ_ERR (0x00000100ul) /*!< An error in the sequence of erase command occurs */ -#define SDMMC_ERROR_BAD_ERASE_PARAM (0x00000200ul) /*!< An invalid selection for erase groups */ -#define SDMMC_ERROR_WRITE_PROT_VIOLATION (0x00000400ul) /*!< Attempt to program a write protect block */ -#define SDMMC_ERROR_LOCK_UNLOCK_FAILED (0x00000800ul) /*!< Sequence or password error has been detected in unlock - command or if there was an attempt to access a locked card */ -#define SDMMC_ERROR_COM_CRC_FAILED (0x00001000ul) /*!< CRC check of the previous command failed */ -#define SDMMC_ERROR_ILLEGAL_CMD (0x00002000ul) /*!< Command is not legal for the card state */ -#define SDMMC_ERROR_CARD_ECC_FAILED (0x00004000ul) /*!< Card internal ECC was applied but failed to correct the data */ -#define SDMMC_ERROR_CC_ERR (0x00008000ul) /*!< Internal card controller error */ -#define SDMMC_ERROR_GENERAL_UNKNOWN_ERR (0x00010000ul) /*!< General or unknown error */ -#define SDMMC_ERROR_STREAM_READ_UNDERRUN (0x00020000ul) /*!< The card could not sustain data reading in stream rmode */ -#define SDMMC_ERROR_STREAM_WRITE_OVERRUN (0x00040000ul) /*!< The card could not sustain data programming in stream mode */ -#define SDMMC_ERROR_CID_CSD_OVERWRITE (0x00080000ul) /*!< CID/CSD overwrite error */ -#define SDMMC_ERROR_WP_ERASE_SKIP (0x00100000ul) /*!< Only partial address space was erased */ -#define SDMMC_ERROR_CARD_ECC_DISABLED (0x00200000ul) /*!< Command has been executed without using internal ECC */ -#define SDMMC_ERROR_ERASE_RESET (0x00400000ul) /*!< Erase sequence was cleared before executing because an out - of erase sequence command was received */ -#define SDMMC_ERROR_AKE_SEQ_ERR (0x00800000ul) /*!< Error in sequence of authentication */ -#define SDMMC_ERROR_INVALID_VOLTRANGE (0x01000000ul) /*!< Error in case of invalid voltage range */ -#define SDMMC_ERROR_ADDR_OUT_OF_RANGE (0x02000000ul) /*!< Error when addressed block is out of range */ -#define SDMMC_ERROR_REQUEST_NOT_APPLICABLE (0x04000000ul) /*!< Error when command request is not applicable */ -#define SDMMC_ERROR_INVALID_PARAMETER (0x08000000ul) /*!< the used parameter is not valid */ -#define SDMMC_ERROR_UNSUPPORTED_FEATURE (0x10000000ul) /*!< Error when feature is not insupported */ -#define SDMMC_ERROR_BUSY (0x20000000ul) /*!< Error when transfer process is busy */ -#define SDMMC_ERROR_DMA (0x40000000ul) /*!< Error while DMA transfer */ -#define SDMMC_ERROR_TIMEOUT (0x80000000ul) /*!< Timeout error */ - -/******************************************************************************* - * Global variable definitions ('extern') - ******************************************************************************/ - -/******************************************************************************* - * Global function prototypes (definition in C source) - ******************************************************************************/ -en_result_t SDMMC_Cmd0_GoIdleState(M4_SDIOC_TypeDef *SDIOCx); -en_result_t SDMMC_Cmd1_SendOpCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32OCR); -en_result_t SDMMC_Cmd2_AllSendCID(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32CID[4]); -en_result_t SDMMC_Cmd3_SendRelativeAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32RCA); -en_result_t SDMMC_Cmd6_SwitchFunc(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd7_SelectDeselectCard(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd8_SendIfCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32IfCond); -en_result_t SDMMC_Cmd9_SendCSD(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t u32CSD[4]); -en_result_t SDMMC_Cmd10_SendCID(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t u32CID[4]); -en_result_t SDMMC_Cmd12_StopTransmission(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd13_SendStatus(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd16_SetBlockLength(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32BlockLen, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd17_ReadSingleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ReadAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd18_ReadMultipleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ReadAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd24_WriteSingleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32WriteAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd25_WriteMultipleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32WriteAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd32_EraseWrBlkStart(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32StartAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd33_EraseWrBlkEnd(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32EndAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd35_SetEraseStartAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32StartAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd36_SetEraseEndAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32EndAddr, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd38_Erase(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1); -en_result_t SDMMC_Cmd55_AppCmd(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32Resp1); -en_result_t SDMMC_Acmd6_SetBusWidth(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32BusWidth, uint32_t *pu32Resp1); -en_result_t SDMMC_Acmd13_SdStatus(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1); -en_result_t SDMMC_Acmd41_SdSendOpCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32SdType, uint32_t *pu32OCR); -en_result_t SDMMC_Acmd51_SendSCR(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1); - -//@} // SdiocGroup - -#ifdef __cplusplus -} -#endif - -#endif /* __SDMMC_CMD_H__ */ - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Project/GateWay/source/Module/SDCard/sdmmc_cmd_1.c b/Project/GateWay/source/Module/SDCard/sdmmc_cmd_1.c deleted file mode 100644 index 6b0d673..0000000 --- a/Project/GateWay/source/Module/SDCard/sdmmc_cmd_1.c +++ /dev/null @@ -1,1641 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - */ -/******************************************************************************/ -/** \file sdmmc_cmd.c - ** - ** A detailed description is available at - ** @link SdiocGroup SDIOC description @endlink - ** - ** - 2018-11-15 CDT First version for Device Driver Library of SDIOC. - ** - ******************************************************************************/ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "sdmmc_cmd.h" - -/** - ******************************************************************************* - ** \addtogroup SdiocGroup - ******************************************************************************/ -//@{ - -/******************************************************************************* - * Local type definitions ('typedef') - ******************************************************************************/ - -/******************************************************************************* - * Local pre-processor symbols/macros ('#define') - ******************************************************************************/ - -/*!< Parameter valid check for SDIOC Instances. */ -#define IS_VALID_SDIOC(__SDIOCx__) \ -( (M4_SDIOC1 == (__SDIOCx__)) || \ - (M4_SDIOC2 == (__SDIOCx__))) - -/*!< Parameter valid check for SDIOC Instances. */ -#define IS_VALID_SD_TYPE(x) \ -( (SdmmcHighCapacity == (x)) || \ - (SdmmcStanderdCapacity == (x))) - -/*!< CMDBSY bit loop count */ -#define SDIOC_FLAG_CMDBUSY_LOOPS (200000ul) - -/*!< Command send and response timeout */ -#define SDMMC_CMD_TIMEOUT (10000ul) - -/*!< OCR register bit */ -#define SDMMC_SD_OCR_HCS (0x40000000ul) /* High Capacity Support */ -#define SDMMC_SD_OCR_BUSY (0x80000000ul) /* Card power up status bit (busy) */ - - -#define SDMMC_BUS_WIDTH_1BIT (0x00000000ul) -#define SDMMC_BUS_WIDTH_4BIT (0x00000002ul) - -#define SDMMC_CMD8_CHECK_PATTERN (0x000000AAul) -#define SDMMC_CMD8_VOLTAGE_SUPPLIED (0x00000100ul) /* 2.7 - 3.6v*/ -#define SDMMC_CMD8_ARGUEMENT (SDMMC_CMD8_VOLTAGE_SUPPLIED | SDMMC_CMD8_CHECK_PATTERN) -#define SDMMC_ACMD41_VOLTAGE (SDMMC_SD_VOLT_3_3) -#define SDMMC_ACMD41_HCS (1ul << 30u) - -/*!< Masks for R1 Response (SD Card Status Register) */ -#define SDMMC_R1_AKE_SEQ_ERROR (0x1ul << 3u ) -#define SDMMC_R1_ERASE_RESET (0x1ul << 13u) -#define SDMMC_R1_CARD_ECC_DISABLED (0x1ul << 14u) -#define SDMMC_R1_WP_ERASE_SKIP (0x1ul << 15u) -#define SDMMC_R1_CID_CSD_OVERWRITE (0x1ul << 16u) -#define SDMMC_R1_STREAM_WRITE_OVERRUN (0x1ul << 17u) -#define SDMMC_R1_STREAM_READ_UNDERRUN (0x1ul << 18u) -#define SDMMC_R1_GENERAL_UNKNOWN_ERROR (0x1ul << 19u) -#define SDMMC_R1_CC_ERROR (0x1ul << 20u) -#define SDMMC_R1_CARD_ECC_FAILED (0x1ul << 21u) -#define SDMMC_R1_ILLEGAL_COMMAND (0x1ul << 22u) -#define SDMMC_R1_COM_CRC_ERROR (0x1ul << 23u) -#define SDMMC_R1_LOCK_UNLOCK_FAILED (0x1ul << 24u) -#define SDMMC_R1_WP_VIOLATION (0x1ul << 26u) -#define SDMMC_R1_ERASE_PARAM_ERROR (0x1ul << 27u) -#define SDMMC_R1_ERASE_SEQ_ERROR (0x1ul << 28u) -#define SDMMC_R1_BLOCK_LEN_ERROR (0x1ul << 29u) -#define SDMMC_R1_ADDRESS_ERROR (0x1ul << 30u) -#define SDMMC_R1_OUT_OF_RANGE (0x1ul << 31u) -#define SDMMC_R1_ERRORS (0xFDFFE008ul) - -/*!< Masks for R6 Response. */ -#define SDMMC_R6_GENERAL_UNKNOWN_ERROR (0x1ul << 13u) -#define SDMMC_R6_ILLEGAL_CMD (0x1ul << 14u) -#define SDMMC_R6_COM_CRC_ERROR (0x1ul << 15u) - -/******************************************************************************* - * Global variable definitions (declared in header file with 'extern') - ******************************************************************************/ - -/******************************************************************************* - * Local function prototypes ('static') - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp1(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout); -static en_result_t SDMMC_GetCmdResp1b(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout); -static en_result_t SDMMC_GetCmdResp2(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32CID_CSD[4]); -static en_result_t SDMMC_GetCmdResp3(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32OCR); -static en_result_t SDMMC_GetCmdResp6(M4_SDIOC_TypeDef *SDIOx, - uint32_t *pu32RCA); -static en_result_t SDMMC_GetCmdResp7(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32IfCond); -static en_result_t SDMMC_WaitBusIdle(M4_SDIOC_TypeDef *SDIOCx); -static en_result_t SDMMC_WaitResponse(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32Timeout); -static bool SDMMC_GetCardDetection(M4_SDIOC_TypeDef *SDIOCx); - -/******************************************************************************* - * Local variable definitions ('static') - ******************************************************************************/ - -/******************************************************************************* - * Function implementation - global ('extern') and local ('static') - ******************************************************************************/ -/** - ******************************************************************************* - ** \brief Send the GO_IDLE_STATE command which will reset all cards to idle state - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd0_GoIdleState(M4_SDIOC_TypeDef *SDIOCx) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD0_GO_IDLE_STATE; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdNoRsp; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_OP_COND command. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Argument Argument used for the command. - ** \param [in] pu32OCR Pointer to buffer which will store OCR content. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd1_SendOpCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32OCR) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD1_SEND_OP_COND; - stcCmdCfg.u32Argument = u32Argument; - stcCmdCfg.enRspIndex = SdiocCmdRspR3; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp3(SDIOCx, pu32OCR); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ALL_SEND_CID command for asking any card to send the CID numbers - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32CID Pointer to buffer which will store CID content. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd2_AllSendCID(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32CID[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD2_ALL_SEND_CID; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR2; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp2(SDIOCx, u32CID); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_RELATIVE_ADDR command for asking the card to publish a - ** new relative address(RCA) - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32RCA Pointer to buffer which will store RCA. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd3_SendRelativeAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32RCA) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD3_SEND_RELATIVE_ADDR; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR6; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp6(SDIOCx, pu32RCA); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SWITCH_FUNC command. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Argument Argument used for the command. - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd6_SwitchFunc(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - stcCmdCfg.u8CmdIndex = CMD6_SWITCH_FUNC; - stcCmdCfg.u32Argument = u32Argument; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - - /* Set command and argument. */ - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SELECT/DESELECT_CARD command for toggling a card between the - ** stand-by and transfer states or between the programming and disconnect states. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Sdcard Address. - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd7_SelectDeselectCard(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD7_SEL_DESEL_CARD; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_IF_COND command. Sends SD Memory Card interface - ** condition, which includes host supply voltage information and asks - ** the card whether card supports voltage - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32IfCond Pointer to buffers for storing interface condition. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd8_SendIfCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32IfCond) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Send CMD8 to verify SD card interface operating condition */ - /* Argument: - [31:12]: Reserved (shall be set to '0') - - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) - - [7:0]: Check Pattern (recommended 0xAA) */ - /* CMD Response: R7 */ - stcCmdCfg.u8CmdIndex = CMD8_SEND_IF_COND; - stcCmdCfg.u32Argument = SDMMC_CMD8_ARGUEMENT; - stcCmdCfg.enRspIndex = SdiocCmdRspR7; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); /* Set command and argument. */ - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp7(SDIOCx, pu32IfCond); - if (enRet == Ok) - { - if((*pu32IfCond & 0xFFu) != SDMMC_CMD8_CHECK_PATTERN) - { - enRet = Error; - } - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_CSD command to addressed card which will sends its - ** card-specificdata (CSD). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Card Address - ** \param [in] u32CSD Pointer to buffers for storing CSD contents. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd9_SendCSD(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t u32CSD[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD9_SEND_CSD; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR2; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp2(SDIOCx, u32CSD); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_CID command to addressed card which will sends its card - ** identification(CID). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Card Address - ** \param [in] u32CID Pointer to buffers for storing CID contents. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd10_SendCID(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t u32CID[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD10_SEND_CID; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR2; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp2(SDIOCx, u32CID); - } - } - } - - return enRet; -} - -/******************************************************************************* -** \brief Send the STOP_TRANSMISSION command to force the card to stop transmission. -** -** \param [in] SDIOCx Pointer to SDIOC instance register base -** \arg M4_SDIOC1 SDIOC unit 1 instance register base -** \arg M4_SDIOC2 SDIOC unit 2 instance register base -** -** \retval Ok Send successfully. -** \retval Error Send unsuccessfully. -** -*******************************************************************************/ -en_result_t SDMMC_Cmd12_StopTransmission(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD12_STOP_TRANSMISSION; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_STATUS to addressed card which will send its status - ** register contents - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32RCA Relative Card Address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd13_SendStatus(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32RCA, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD13_SEND_STATUS; - stcCmdCfg.u32Argument = (u32RCA << 16u); - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SET_BLOCKLEN command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32BlockLen Block length - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd16_SetBlockLength(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32BlockLen, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD16_SET_BLOCKLEN; - stcCmdCfg.u32Argument = u32BlockLen; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the READ_SINGLE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32ReadAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd17_ReadSingleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ReadAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD17_READ_SINGLE_BLOCK; - stcCmdCfg.u32Argument = u32ReadAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the READ_MULTIPLE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32ReadAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd18_ReadMultipleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ReadAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD18_READ_MULTIPLE_BLOCK; - stcCmdCfg.u32Argument = u32ReadAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the WRITE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32WriteAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd24_WriteSingleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32WriteAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD24_WRITE_SINGLE_BLOCK; - stcCmdCfg.u32Argument = u32WriteAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the WRITE_MULTIPLE_BLOCK command and check the response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32WriteAddr Data address - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd25_WriteMultipleBlock(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32WriteAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD25_WRITE_MULTIPLE_BLOCK; - stcCmdCfg.u32Argument = u32WriteAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Enable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_WR_BLK_START command for setting the address of the - ** first write block to be erased. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32StartAddr The start address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd32_EraseWrBlkStart(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32StartAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD32_ERASE_WR_BLK_START; - stcCmdCfg.u32Argument = u32StartAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_WR_BLK_END command for setting the address of the - ** last write block of the continuous range to be erased. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32EndAddr The last address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd33_EraseWrBlkEnd(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32EndAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD33_ERASE_WR_BLK_END; - stcCmdCfg.u32Argument = u32EndAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_GRP_START command and check the response. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32StartAddr The start address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd35_SetEraseStartAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32StartAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD35_ERASE_GRP_START; - stcCmdCfg.u32Argument = u32StartAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE_GRP_END command and check the response. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32EndAddr The end address will be erased - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd36_SetEraseEndAddr(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32EndAddr, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD36_ERASE_GRP_END; - stcCmdCfg.u32Argument = u32EndAddr; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the ERASE command for erasing all previously selected write blocks. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd38_Erase(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - SDIOC_SetDataTimeout(SDIOCx, SdiocDtoSdclk_2_27); - - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD38_ERASE; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1b; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1b(SDIOCx, pu32Resp1, 50u * SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the APP_CMD Command to interpret the following command as an - ** application-specific command(ACMD). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Argument Command argument(RCA) - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Cmd55_AppCmd(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32Argument, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = CMD55_APP_CMD; - stcCmdCfg.u32Argument = u32Argument; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SET_BUS_WIDTH(ACMD6) Command to set bus width. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32BusWidth The data bus width, '00'= 1bit or '10' = 4bits bus - ** \arg SDMMC_BUS_WIDTH_1BIT 1 bits bus - ** \arg SDMMC_BUS_WIDTH_4BIT 4 bits bus - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd6_SetBusWidth(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32BusWidth, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD6_APP_SD_SET_BUSWIDTH; - stcCmdCfg.u32Argument = u32BusWidth; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SD_STATUS(ACMD13) Command to ask the Status Register. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd13_SdStatus(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD13_SD_APP_STATUS; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SD_SEND_OP_COND(ACMD41) command to negotiate the operation - ** voltage range and get OCR. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32SdType Sdcard type - ** \arg SdmmcHighCapacity SD memory card: Standard capacity - ** \arg SdmmcHighCapacity SD memory card: High capacity - ** \param [in] pu32OCR Pointer to the variable that will contain - ** the OCR register contents. - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd41_SdSendOpCond(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32SdType, uint32_t *pu32OCR) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32OCR)) - { - DDL_ASSERT(IS_VALID_SD_TYPE(u32SdType)); - - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD41_SD_SEND_OP_COND; - stcCmdCfg.u32Argument = SDMMC_ACMD41_VOLTAGE | u32SdType; - stcCmdCfg.enRspIndex = SdiocCmdRspR3; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp3(SDIOCx, pu32OCR); - if (enRet == Ok) - { - if (!(*pu32OCR & SDMMC_SD_OCR_BUSY)) - { - enRet = ErrorOperationInProgress; - } - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Send the SEND_SCR(ACMD51) command to read the SD Configuration Register(SCR). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32Resp1 Pointer to response data buffer - ** - ** \retval Ok Send successfully. - ** \retval Error Send unsuccessfully. - ** - ******************************************************************************/ -en_result_t SDMMC_Acmd51_SendSCR(M4_SDIOC_TypeDef *SDIOCx, uint32_t *pu32Resp1) -{ - en_result_t enRet = ErrorInvalidParameter; - stc_sdioc_cmd_cfg_t stcCmdCfg = {0}; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitBusIdle(SDIOCx); - if (enRet == Ok) - { - /* Set command and argument. */ - stcCmdCfg.u8CmdIndex = ACMD51_SD_APP_SEND_SCR; - stcCmdCfg.u32Argument = 0u; - stcCmdCfg.enRspIndex = SdiocCmdRspR1; - stcCmdCfg.enDataPresentEnable = Disable; - stcCmdCfg.enCmdType = SdiocCmdNormal; - enRet = SDIOC_SendCommand(SDIOCx, &stcCmdCfg); - if (enRet == Ok) - { - /* Check for error conditions */ - enRet = SDMMC_GetCmdResp1(SDIOCx, pu32Resp1, SDMMC_CMD_TIMEOUT); - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R1(normal response command). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32CmdResp1 received response value - ** \param [in] u32Timeout timeout for waiting SDIOC idle - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32CmdResp1 == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp1(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout) -{ - uint32_t u32R1 = 0u; - en_result_t enRet = ErrorInvalidParameter; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitResponse(SDIOCx, u32Timeout); - if (enRet == Ok) - { - /* received response, retrieve it for analysis */ - u32R1 = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - if (u32R1 & SDMMC_R1_ERRORS) - { - enRet = Error; - } - - if (pu32CmdResp1 != NULL) - { - *pu32CmdResp1 = u32R1; - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R1(normal response command) with busy signal. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [out] pu32CmdResp1 received response value - ** \param [in] u32Timeout timeout for waiting SDIOC idle - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32CmdResp1 == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp1b(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32CmdResp1, - uint32_t u32Timeout) -{ - uint32_t u32R1 = 0u; - en_result_t enRet = ErrorInvalidParameter; - __IO uint32_t u32TmpCnt = u32Timeout; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = SDMMC_WaitResponse(SDIOCx, u32Timeout); - if (enRet == Ok) - { - do - { - if (u32TmpCnt-- == 0u) - { - enRet = ErrorTimeout; - } - } while (Reset == SDIOC_GetStatus(SDIOCx, SdiocData0PinLvl)); - - if (enRet == Ok) - { - /* received response, retrieve it for analysis */ - u32R1 = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - if (u32R1 & SDMMC_R1_ERRORS) - { - enRet = Error; - } - - if (pu32CmdResp1 != NULL) - { - *pu32CmdResp1 = u32R1; - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R2(CID, CSD register). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32CID_CSD Pointer to the variable that will contain the - ** CID or CSD register contents - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter u32CID_CSD == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp2(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32CID_CSD[4]) -{ - en_result_t enRet = ErrorInvalidParameter; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != u32CID_CSD)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - /* received response */ - u32CID_CSD[0] = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - u32CID_CSD[1] = SDIOC_GetResponse(SDIOCx, SdiocRegResp23); - u32CID_CSD[2] = SDIOC_GetResponse(SDIOCx, SdiocRegResp45); - u32CID_CSD[3] = SDIOC_GetResponse(SDIOCx, SdiocRegResp67); - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R3(OCR register). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32OCR Pointer to the variable that will contain - ** the OCR register contents. - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32OCR == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp3(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32OCR) -{ - en_result_t enRet = ErrorInvalidParameter; - - if((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32OCR)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - /* received response, retrieve it for analysis */ - *pu32OCR = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R6(Published RCA response). - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32RCA Pointer to the variable that will contain - ** published RCA number - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32RCA == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp6(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32RCA) -{ - uint32_t u32R6 = 0ul; - en_result_t enRet = ErrorInvalidParameter; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32RCA)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - /* received response, retrieve it. */ - u32R6 = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - if (!(u32R6 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_ERROR))) - { - *pu32RCA = (u32R6 >> 16); - } - else - { - enRet = Error; - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get Response R7. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] pu32IfCond Pointer to the variable that will contain - ** interface condition. - ** - ** \retval Ok Get successfully. - ** \retval Error Get unsuccessfully. - ** \retval ErrorInvalidParameter pu32IfCond == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_GetCmdResp7(M4_SDIOC_TypeDef *SDIOCx, - uint32_t *pu32IfCond) -{ - en_result_t enRet = ErrorInvalidParameter; - - if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pu32IfCond)) - { - enRet = SDMMC_WaitResponse(SDIOCx, SDMMC_CMD_TIMEOUT); - if (enRet == Ok) - { - *pu32IfCond = SDIOC_GetResponse(SDIOCx, SdiocRegResp01); - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Wait for bus line idle - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** - ** \retval Ok Command&Data line is free within a certain time - ** \retval ErrorTimeout Command&Data line is still busy after a certain time. - ** \retval ErrorInvalidParameter SDIOCx == NULL - ** - ******************************************************************************/ -static en_result_t SDMMC_WaitBusIdle(M4_SDIOC_TypeDef *SDIOCx) -{ - en_result_t enRet = ErrorInvalidParameter; - uint32_t u32Retry = SDIOC_FLAG_CMDBUSY_LOOPS; - en_flag_status_t enInhibitCmdStatus = Set; - en_flag_status_t enInhibitDataStatus = Set; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = ErrorTimeout; - while (u32Retry-- > 0ul) - { - enInhibitCmdStatus = SDIOC_GetStatus(SDIOCx, SdiocCommandInhibitCmd); - enInhibitDataStatus = SDIOC_GetStatus(SDIOCx, SdiocCommandInhibitData); - if ((Reset == enInhibitCmdStatus) || (Reset == enInhibitDataStatus)) - { - enRet = Ok; - break; - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Wait response - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** \param [in] u32Timeout timeout times - ** - ** \retval Ok Respond normal - ** \retval ErrorTimeout Respond timeout. - ** \retval ErrorInvalidParameter SDIOCx == NULL - ** \retval ErrorAccessRights Card is removed. - ** - ******************************************************************************/ -static en_result_t SDMMC_WaitResponse(M4_SDIOC_TypeDef *SDIOCx, - uint32_t u32Timeout) -{ - /* 8 is the number of required instructions cycles for the below loop statement. - The Timeout is expressed in ms */ - __IO uint32_t u32Count = u32Timeout * (SystemCoreClock / 8u /1000u); - en_flag_status_t enErrorInt = Set; - en_flag_status_t enCommandComplete = Set; - en_result_t enRet = ErrorInvalidParameter; - - if (IS_VALID_SDIOC(SDIOCx)) - { - enRet = Ok; - do - { - if (u32Count-- == 0u) - { - enRet = ErrorTimeout; - break; - } - enErrorInt = SDIOC_GetNormalIrqFlag(SDIOCx, SdiocErrorInt); - enCommandComplete = SDIOC_GetNormalIrqFlag(SDIOCx, SdiocCommandComplete); - } while ((Reset == enErrorInt) && (Reset == enCommandComplete)); - - if (enRet == Ok) - { - if (Set == SDIOC_GetNormalIrqFlag(SDIOCx, SdiocErrorInt)) - { - enRet = Error; - } - else - { - if (false == SDMMC_GetCardDetection(SDIOCx)) - { - enRet = ErrorAccessRights; - } - else - { - if (Set == SDIOC_GetNormalIrqFlag(SDIOCx, SdiocCommandComplete)) - { - SDIOC_ClearNormalIrqFlag(SDIOCx, SdiocCommandComplete); - } - - if (Set == SDIOC_GetNormalIrqFlag(SDIOCx, SdiocTransferComplete)) - { - SDIOC_ClearNormalIrqFlag(SDIOCx, SdiocTransferComplete); - } - } - } - } - } - - return enRet; -} - -/** - ******************************************************************************* - ** \brief Get card insertion status - ** - ** This function checks card is inserted or not. - ** - ** \param [in] SDIOCx Pointer to SDIOC instance register base - ** \arg M4_SDIOC1 SDIOC unit 1 instance register base - ** \arg M4_SDIOC2 SDIOC unit 2 instance register base - ** - ** \retval true Card is inserted - ** \retval false Card is removed - ** - ******************************************************************************/ -static bool SDMMC_GetCardDetection(M4_SDIOC_TypeDef *SDIOCx) -{ - bool bRet = false; - __IO uint32_t u32Count = 5000ul * (SystemCoreClock / 8ul /1000ul); - - /* Wait until card is stable */ - do - { - if (Set == SDIOC_GetStatus(SDIOCx, SdiocCardStateStable)) - { - break; - } - } while (u32Count--); - - if (u32Count != 0ul) - { - bRet = (Set == SDIOC_GetStatus(SDIOCx, SdiocCardInserted)) ? true : false; - } - - return bRet; -} - -//@} // SdiocGroup - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Project/GateWay/source/Module/SHT20/SHT20.C b/Project/GateWay/source/Module/SHT20/SHT20.C deleted file mode 100644 index a5193e4..0000000 --- a/Project/GateWay/source/Module/SHT20/SHT20.C +++ /dev/null @@ -1,615 +0,0 @@ -#include "SHT20.h" - - -SHT20Var_t SHT20; - -//---------- Defines ----------------------------------------------------------- -// CRC 累加和校验常量 -const uint32_t POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001 - -/* -************************************************************ -* 函数名称: SHT2x_CheckCrc -* -* 函数功能: 检查数据正确性 -* -* 入口参数: data:读取到的数据 -* nbrOfBytes:需要校验的数量 -* checksum:读取到的校对比验值 -* -* 返回参数: 校验结果 -* -* 说明: 0-成功 1-失败 -************************************************************ -*/ -uint8_t SHT2x_CheckCrc(uint8_t *data, uint8_t nbrOfBytes, uint8_t checksum) -{ - uint8_t crc = 0; - uint8_t bit = 0; - uint8_t byteCtr = 0; - - //calculates 8-Bit checksum with given polynomial - for(byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr) { - crc ^= (data[byteCtr]); - for ( bit = 8; bit > 0; --bit) { - if (crc & 0x80) - crc = (crc << 1) ^ POLYNOMIAL; - else - crc = (crc << 1); - } - } - - if(crc != checksum) - return 1; - return 0; - -} - -void delay_us(int dlycnt) -{ - for(int i = 0; i < dlycnt; i++) { - uint8_t temp = 10; - while(temp--); - } -} - -#ifdef I2C_SOFTWARE -#define ACK 0 //应答信号 -#define NACK 1 //非应答信号 -#define SHT20_IN_SDA SHT20_I2C_SDA_Read() //读取SDA值 -#define IIC_Delay() delay_us(10) //时钟延时 - -/*================================================================ -[ Name ]void IO_I2CInit(void) -[Function]I2C初始化 空闲状态 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void IO_I2CInit(void) -{ - // -} - -// -/*================================================================ -[ Name ]SHT20_I2C_SDA_Read -[Function]读取SDA数据线上值 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -uint8_t SHT20_I2C_SDA_Read(void) -{ - SHT20_SDA_IN(); - if(SHT20_SDA_GET()) - return 1; - else - return 0; -} - -/*================================================================ -[ Name ]I2CStart -[Function]开始 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void I2CStart(void) -{ - //uint8_t retval; - SHT20_SDA_OUT(); //设置成输出 - //SHT20_SCL_OUT(); - SHT20_I2C_SDA_HIGH(); //为SDA下降启动做准备 - SHT20_I2C_SCL_HIGH(); //在SCL高电平时,SDA为下降沿时候总线启动 - - IIC_Delay(); - SHT20_I2C_SDA_LOW(); //突变,总线启动 - IIC_Delay(); - SHT20_I2C_SCL_LOW(); - IIC_Delay(); - -//SHT20_SDA_IN(); //设置成输入 -// if(SHT20_IN_SDA) -// { -// retval= NACK; -// } -// else -// { -// retval= ACK; -// } -// retval=retval; -} - -/*================================================================ -[ Name ]I2CStop -[Function]结束 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void I2CStop(void) -{ - SHT20_SDA_OUT(); //设置成输出 - SHT20_I2C_SDA_LOW(); //为SDA上升做准备 - SHT20_I2C_SCL_LOW(); - - IIC_Delay(); - SHT20_I2C_SCL_HIGH(); //在SCL高电平时,SDA为上升沿时候总线停止 - IIC_Delay(); - SHT20_I2C_SDA_HIGH(); //突变,总线停止 - IIC_Delay(); -} - -/*================================================================ -[ Name ]I2C_Write_Byte -[Function]写一个字节 返回ACK或NACK -[ Notes ]从高到低发 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -uint8_t I2C_Write_Byte(uint8_t Write_Byte) //Sendbyte -{ - uint8_t i,retval=3; - - SHT20_SDA_OUT(); //设置成输出 - //SHT20_SCL_OUT() ; - for(i = 0;i < 8;i++) { - if(Write_Byte & 0x80) - SHT20_I2C_SDA_HIGH(); //判断发送位,先发送高位 - else - SHT20_I2C_SDA_LOW(); - - //IIC_Delay(); - SHT20_I2C_SCL_HIGH(); //为SCL下降做准备 - IIC_Delay(); - SHT20_I2C_SCL_LOW(); //突变,将数据位发送过去 - IIC_Delay(); - Write_Byte<<=1; //数据左移一位 - } //字节发送完成,开始接收应答信号 - IIC_Delay(); - SHT20_I2C_SDA_HIGH(); //释放数据线 - IIC_Delay(); - SHT20_SDA_IN(); //设置成输入 - //IIC_Delay(); - SHT20_I2C_SCL_HIGH(); //为SCL下降做准备 - IIC_Delay(); - - if(SHT20_IN_SDA) - retval= NACK; - else - retval= ACK; - - SHT20_I2C_SCL_LOW(); - IIC_Delay(); - return retval; -} -// -/*================================================================ -[ Name ]I2C_Read_Byte -[Function]读一个字节,入库参数用于控制应答状态 ACK或NAC -[ Notes ]从高到低 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -uint8_t I2C_Read_Byte(uint8_t AckValue)//receivebyte -{ - uint8_t i; - uint8_t RXDATA=0; -// SHT20_SDA_OUT(); //设置成输出 -// SHT20_I2C_SDA_HIGH(); //首先置数据线为高电平 -// SHT20_I2C_SCL_LOW(); - SHT20_SDA_IN(); //设置成输入 - - for(i = 0;i < 8;i++) { - SHT20_I2C_SCL_HIGH(); //突变 - IIC_Delay(); - RXDATA <<= 1; //读入数据,高位在前 - if(SHT20_IN_SDA) RXDATA |= 0x01; //收到高电平 - else RXDATA &= 0xfe; - IIC_Delay(); - SHT20_I2C_SCL_LOW(); - IIC_Delay(); - } //数据接收完成 - - SHT20_SDA_OUT(); - if(AckValue) - SHT20_I2C_SDA_HIGH(); - else - SHT20_I2C_SDA_LOW(); - - IIC_Delay(); - SHT20_I2C_SCL_HIGH(); - IIC_Delay(); - SHT20_I2C_SCL_LOW(); - IIC_Delay(); - - return RXDATA; //返回读取到的数据 -} - -/*================================================================ -[ Name ]SHT20_SoftReset -[Function]SHT20软件复位 -[ Notes ]从高到低 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void SHT20_Reset(void) -{ - // IO_I2CInit(); //I2C initialize - I2CStart(); //start I2C - I2C_Write_Byte(SHT20_ADDRESS&0xfe); //I2C address + write - I2C_Write_Byte(0xfe); //soft reset - I2CStop(); //stop I2C -} - -/*================================================================ -[ Name ]SET_Resolution -[Function]写寄存器 设置分辨率 -[ Notes ]从高到低 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void SET_Resolution(void) -{ - I2CStart(); //Start I2C - if(I2C_Write_Byte(SHT20_ADDRESS&0xfe) == ACK) { //I2C address + write + ACK - if(I2C_Write_Byte(0xe6) == ACK) { //写用户寄存器 - if(I2C_Write_Byte(0x83) == ACK) - __NOP(); //设置分辨率 11bit RH% 测量时间:12ms(typ.) & 11bit T测量时间:9ms(typ.) - } - } - I2CStop(); //Stop I2C -} - -/*================================================================ -[ Name ]ReadSht20 -[Function]非主机模式,读取温湿度值 -[ Notes ]入口控制读取温度或湿度 复位需要15ms 温度转换最大需要85ms -[ Author ]LZH SHT20上电后等待20ms 再读取sht20 -[ Data ]2016.06.22 -================================================================*/ -float SHT2x_MeasureHM(uint8_t whatdo) -{ - float temp; - uint8_t MSB,LSB,checksum=0,checktemp[2]; - float Humidity,Temperature; - uint32_t waitt= 1000; - //SET_Resolution(); //此处之前出过问题 所以屏蔽掉 - - I2CStart(); - if(I2C_Write_Byte(SHT20_ADDRESS&0xfe)==ACK) { //I2C address + write + ACK - if(I2C_Write_Byte(whatdo)==ACK) { //Command - do{ - delay_us(100); //加入超时 - I2CStart(); - if(--waitt==0) - break; - } while(I2C_Write_Byte(SHT20_ADDRESS|0x01) == NACK); //I2C address + read + NACK - - if(waitt != 0) { - MSB = I2C_Read_Byte(ACK); //Data(MSB) - LSB = I2C_Read_Byte(ACK); //Data(LSB) - checksum=I2C_Read_Byte(NACK); //Checksum + NACK 累加和校验值 - I2CStop(); //Stop I2C - checktemp[0]=MSB; - checktemp[1]=LSB; - if(SHT2x_CheckCrc(checktemp,2,checksum)) { //累加和校验成功 - LSB &= 0xfc; //Data (LSB) 后两位清零 - temp = MSB*256 + LSB; //十六进制转十进制 - if (whatdo==((uint8_t)0xf5)) { //No Hold Master Mode,read humidity - /*-- calculate relative humidity [%RH] --*/ - Humidity =(temp*125)/65536-6; //公式: RH%= -6 + 125 * SRH/2^16 - return Humidity; //返回:humidity - } - else{ //No Hold Master Mode,read temperature - /*-- calculate temperature [℃] --*/ - Temperature = (temp*175.72)/65536-46.85; //公式:T= -46.85 + 175.72 * ST/2^16 - return Temperature; //返回:temperature - } - } - } - } - } - I2CStop(); //CT add - return 0; -} -// -/******************************************************** -[ Name ]GetMiddleNum -[Function] 中值滤波 -[ Notes ] 传入数据buf bArray, iFilterLen滤波数据长度 -[ Author ] CSDN -[ Data ]2018.10.25 - -**********************************************************/ - -float GetMiddleNum(float * bArray, uint8_t iFilterLen) -{ - uint8_t i,j;// 循环变量 - float bTemp; - - if(iFilterLen>100) - return 0; - // 用冒泡法对数组进行排序 - for (j = 0; j < iFilterLen - 1; j ++) { - for (i = 0; i < iFilterLen - j - 1; i ++) { - if (bArray[i] > bArray[i + 1]) { - // 互换 - bTemp = bArray[i]; - bArray[i] = bArray[i + 1]; - bArray[i + 1] = bTemp; - } - } - } - // 计算中值 - if ((iFilterLen & 1) > 0) { - // 数组有奇数个元素,返回中间一个元素 - bTemp = bArray[(iFilterLen -1) / 2]; - } - else { - // 数组有偶数个元素,返回中间两个元素平均值 - bTemp = (bArray[iFilterLen / 2-1] + bArray[iFilterLen / 2 ]) / 2; - } - return bTemp; -} -// -/******************************************************** -[ Name ]ReadSht20_Medium -[Function] 获取中值 -[ Notes ] 读取完后关闭上拉 设为低 (解决干扰问题) -[ Author ] -[ Data ]2018.10.25 - -**********************************************************/ -float ReadSht20_Medium (void) -{ - float arry3[3]; - //SHT20_I2C_SET_PULL_UP(); //开启引脚上拉 - for(uint8_t ui=0; ui<3; ui++) { - arry3[ui]= SHT2x_MeasureHM(SHT20_Measurement_T_HM); - delay_us(20); - //printf("sht origin %.2f \r\n",arry3[ui]); - } - float retv = GetMiddleNum(arry3, 3); - -#ifdef I2C_SOFTWARE - //SHT20_I2C_SET_PULL_NO(); //关闭上拉 - SHT20_I2C_LOW(); //读取完温度后拉低 -#endif - return retv; -} - -#else - -/* -************************************************************ -* 函数名称: SHT20_reset -* -* 函数功能: SHT20复位 -* -* 入口参数: 无 -* -* 返回参数: 无 -* -* 说明: -************************************************************ -*/ -void SHT20_Reset(void) -{ - uint8_t Data = SHT20_SOFT_RESET; - Sht20_Reg_Write(SHT20_ADDRESS, &Data, 1); - Sht20_Delay(15); -} - -/* -************************************************************ -* 函数名称: SHT20_read_user_reg -* -* 函数功能: SHT20读取用户寄存器 -* -* 入口参数: 无 -* -* 返回参数: 读取到的用户寄存器的值 -* -* 说明: -************************************************************ -*/ -uint8_t SHT20_read_user_reg(void) -{ - uint8_t val = 0; - uint8_t reg = SHT20_READ_REG; - Sht20_Read(SHT20_ADDRESS, ®, &val, 1); - return val; -} - -/* -************************************************************ -* 函数名称: SHT2x_CalcTemperatureC -* -* 函数功能: 温度计算 -* -* 入口参数: u16sT:读取到的温度原始数据 -* -* 返回参数: 计算后的温度数据 -* -* 说明: -************************************************************ -*/ -float SHT2x_CalcTemperatureC(uint16_t u16sT) -{ - float temperatureC = 0; // variable for result - - u16sT &= ~0x0003; // clear bits [1..0] (status bits) - //-- calculate temperature [℃] -- - temperatureC = -46.85 + 175.72 / 65536 * (float)u16sT; //T= -46.85 + 175.72 * ST/2^16 - - return temperatureC; -} - -/* -************************************************************ -* 函数名称: SHT2x_CalcRH -* -* 函数功能: 湿度计算 -* -* 入口参数: u16sRH:读取到的湿度原始数据 -* -* 返回参数: 计算后的湿度数据 -* -* 说明: -************************************************************ -*/ -float SHT2x_CalcRH(uint16_t u16sRH) -{ - float humidityRH = 0; // variable for result - - u16sRH &= ~0x0003; // clear bits [1..0] (status bits) - //-- calculate relative humidity [%RH] -- - //humidityRH = -6.0 + 125.0/65536 * (float)u16sRH; // RH= -6 + 125 * SRH/2^16 - humidityRH = ((float)u16sRH * 0.00190735) - 6; - - return humidityRH; -} - -/* -************************************************************ -* 函数名称: SHT2x_MeasureHM -* -* 函数功能: 测量温湿度 -* -* 入口参数: cmd:测量温度还是湿度 -* -* 返回参数: 测量结果 -* -* 说明: -************************************************************ -*/ -float SHT2x_MeasureHM(uint8_t cmd) -{ - uint8_t checksum = 0; //checksum - uint8_t data[3]; //data array for checksum verification - uint16_t tmp = 0; - float t = 0; - - Sht20_Read(SHT20_ADDRESS, &cmd, data, 3); - checksum = data[2]; - if(SHT2x_CheckCrc(data, 2, checksum) == 0) { - tmp = (data[0] << 8) + data[1]; - if(cmd == SHT20_Measurement_T_NHM) - t = SHT2x_CalcTemperatureC(tmp); - else - t = SHT2x_CalcRH(tmp); - } - - return t; -} - - -#endif - -/* -************************************************************ -* 函数名称: SHT20_GetValue -* -* 函数功能: 获取温湿度数据 -* -* 入口参数: 无 -* -* 返回参数: 无 -* -* 说明: 温湿度结果保存在SHT20结构体里 -************************************************************ -*/ -void SHT20_GetValue(float *Tempreture, float *Humidity) -{ - if(Tempreture != NULL) { - *Tempreture = SHT20.Tempreture; - } - if(Humidity != NULL) { - *Humidity = SHT20.Humidity; - } - //SHT20_reset(); -} - -void SHT20Start(void) -{ - memset(&SHT20, 0x00, sizeof(SHT20)); - SHT20.Sht20Status = SHT20_INIT; -} -void SHT20LoopHandler(void) -{ - uint8_t ret; - uint8_t rData[3]; - - switch(SHT20.Sht20Status) { - case SHT20_IDLE: - break; - - case SHT20_INIT: - SHT20_Reset(); - SHT20.Sht201mSDelayCnt = 200; - SHT20.Sht20Status = SHT20_READ_HUMI; - break; - - case SHT20_READ_TEMPR: - if(SHT20.Sht201mSDelayCnt > 0) - break; - SHT20.Cmd = SHT20_Measurement_T_NHM; - ret = SHT20_StartMeas(SHT20_ADDRESS, &SHT20.Cmd); - if(ret == true) { - SHT20.Sht201mSDelayCnt = 90; - SHT20.Sht20Status = SHT20_READ_DATA; - } - else { - SHT20.Sht201mSDelayCnt = 1000; - SHT20.Sht20Status = SHT20_INIT; - } - break; - - case SHT20_READ_HUMI: - if(SHT20.Sht201mSDelayCnt > 0) - break; - SHT20.Cmd = SHT20_Measurement_RH_NHM; - ret = SHT20_StartMeas(SHT20_ADDRESS, &SHT20.Cmd); - if(ret == true) { - SHT20.Sht201mSDelayCnt = 90; - SHT20.Sht20Status = SHT20_READ_DATA; - } - else { - SHT20.Sht201mSDelayCnt = 1000; - SHT20.Sht20Status = SHT20_INIT; - } - break; - - case SHT20_READ_DATA: - if(SHT20.Sht201mSDelayCnt > 0) - break; - ret = SHT20_Readata(SHT20_ADDRESS, rData, 3); - if(ret == true) { - if(SHT2x_CheckCrc(rData, 2, rData[2]) == 0) { - uint16_t tmp = (rData[0] << 8) + rData[1]; - if(SHT20.Cmd == SHT20_Measurement_T_NHM) { - SHT20.Tempreture = SHT2x_CalcTemperatureC(tmp); - SHT20.Sht20Status = SHT20_READ_HUMI; - } - else { - SHT20.Humidity = SHT2x_CalcRH(tmp); - SHT20.Sht20Status = SHT20_READ_TEMPR; - } - SHT20.Sht201mSDelayCnt = 5; - } - } - else { - SHT20.Sht201mSDelayCnt = 1000; - SHT20.Sht20Status = SHT20_INIT; - } - } -} - -void SHT201mSRoutine(void) -{ - if(SHT20.Sht201mSDelayCnt > 0) - SHT20.Sht201mSDelayCnt--; -} - diff --git a/Project/GateWay/source/Module/SHT20/SHT20.H b/Project/GateWay/source/Module/SHT20/SHT20.H deleted file mode 100644 index b62142b..0000000 --- a/Project/GateWay/source/Module/SHT20/SHT20.H +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************** -* File name : SHT20.h -* Description : SHT20 Humidity and Temperature Sensors -* M C U : STM32L051XX -* Compiler : Keil uVision V5.00a -* Created by : -* Copyright : Copyright(c) 2018 -* Created data : 2018.03.16 -* Modified data: 2018.03.16 -* Vision : V1.0 -*****************************************************************/ - -/*****************Function Declaration*************************/ -/*----define to easier to use-----*/ -#include -#include "bsp.h" - -typedef enum { - SHT20_IDLE, - SHT20_INIT, - SHT20_READ_TEMPR, - SHT20_READ_HUMI, - SHT20_READ_DATA -}SHT20Status_m; - -typedef struct { - SHT20Status_m Sht20Status; - int Sht201mSDelayCnt; - float Tempreture; - float Humidity; - uint8_t Cmd; -}SHT20Var_t; - -#define SHT20_Write_Add 0x80 -#define SHT20_Read_Add 0x81 -#define SHT20_Measurement_RH_HM 0XE5 -#define SHT20_Measurement_T_HM 0XE3 -#define SHT20_Measurement_RH_NHM 0XF5 //非主机模式地址 -#define SHT20_Measurement_T_NHM 0XF3 //非主机模式地址 -#define SHT20_READ_REG 0XE7 -#define SHT20_WRITE_REG 0XE6 -#define SHT20_SOFT_RESET 0XFE - -//#define I2C_SOFTWARE - -#ifdef I2C_SOFTWARE - -#define SHT20_ADDRESS 0X80 - -#define SHT20_SDA_IN() I2C_SDA_IN() //设置引脚输入模式 -#define SHT20_SDA_OUT() I2C_SDA_OUT() //设置引脚输出模式 -#define SHT20_SDA_GET() I2C_SDA_GET() - -#define SHT20_I2C_SDA_LOW() I2C_SDA_LOW() -#define SHT20_I2C_SCL_LOW() I2C_SCL_LOW() -#define SHT20_I2C_SDA_HIGH() I2C_SDA_HIGH() -#define SHT20_I2C_SCL_HIGH() I2C_SCL_HIGH() - - -#define SHT20_I2C_LOW() {SHT20_I2C_SDA_LOW();SHT20_I2C_SCL_LOW();} - -/*================================================================ -[ Name ]void IO_I2CInit(void) -[Function]I2C初始化 空闲状态 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void IO_I2CInit(void); - -/*================================================================ -[ Name ]I2CStart -[Function]开始 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void I2CStart(void); - -/*================================================================ -[ Name ]I2CStop -[Function]结束 -[ Notes ] -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void I2CStop(void); - -/*================================================================ -[ Name ]I2C_Write_Byte -[Function]写一个字节 返回ACK或NACK -[ Notes ]从高到低发 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -uint8_t I2C_Write_Byte(uint8_t Write_Byte); - -/*================================================================ -[ Name ]I2C_Read_Byte -[Function]读一个字节,入库参数用于控制应答状态 ACK或NAC -[ Notes ]从高到低 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -uint8_t I2C_Read_Byte(uint8_t AckValue); - - -/*================================================================ -[ Name ]SHT20_SoftReset -[Function]SHT20软件复位 -[ Notes ]从高到低 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void SHT20_SoftReset(void); - -/*================================================================ -[ Name ]SET_Resolution -[Function]写寄存器 设置分辨率 -[ Notes ]从高到低 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -void SET_Resolution(void); - -/*================================================================ -[ Name ]ReadSht20 -[Function]非主机模式,读取温湿度值 -[ Notes ]入口控制读取温度或湿度 -[ Author ]LZH -[ Data ]2016.06.22 -================================================================*/ -float ReadSht20(char whatdo); - -float ReadSht20_Medium (void); - -#else - -#define SHT20_ADDRESS 0X40 - -#define Sht20_Reg_Write(DevAddr, RegData, rLen) I2C_Write(DevAddr, NULL, RegData, rLen) -#define Sht20_Read(DevAddr, RegAddr, rData, rLen) I2C_Read(DevAddr, RegAddr, rData, rLen) -#define Sht20_Delay(x) - -void SHT20_reset(void); - - -#endif -void SHT20_GetValue(float *Tempreture, float *Humidity); -void SHT20Start(void); -void SHT20LoopHandler(void); -void SHT201mSRoutine(void); - - - -