SPKT

Dependents:   WAV

Committer:
phungductung
Date:
Tue Jun 04 21:51:46 2019 +0000
Revision:
0:e87aa4c49e95
libray

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phungductung 0:e87aa4c49e95 1 /**
phungductung 0:e87aa4c49e95 2 ******************************************************************************
phungductung 0:e87aa4c49e95 3 * @file stm32f7xx_hal_sd.c
phungductung 0:e87aa4c49e95 4 * @author MCD Application Team
phungductung 0:e87aa4c49e95 5 * @version V1.0.4
phungductung 0:e87aa4c49e95 6 * @date 09-December-2015
phungductung 0:e87aa4c49e95 7 * @brief SD card HAL module driver.
phungductung 0:e87aa4c49e95 8 * This file provides firmware functions to manage the following
phungductung 0:e87aa4c49e95 9 * functionalities of the Secure Digital (SD) peripheral:
phungductung 0:e87aa4c49e95 10 * + Initialization and de-initialization functions
phungductung 0:e87aa4c49e95 11 * + IO operation functions
phungductung 0:e87aa4c49e95 12 * + Peripheral Control functions
phungductung 0:e87aa4c49e95 13 * + Peripheral State functions
phungductung 0:e87aa4c49e95 14 *
phungductung 0:e87aa4c49e95 15 @verbatim
phungductung 0:e87aa4c49e95 16 ==============================================================================
phungductung 0:e87aa4c49e95 17 ##### How to use this driver #####
phungductung 0:e87aa4c49e95 18 ==============================================================================
phungductung 0:e87aa4c49e95 19 [..]
phungductung 0:e87aa4c49e95 20 This driver implements a high level communication layer for read and write from/to
phungductung 0:e87aa4c49e95 21 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
phungductung 0:e87aa4c49e95 22 the user in HAL_SD_MspInit() function (MSP layer).
phungductung 0:e87aa4c49e95 23 Basically, the MSP layer configuration should be the same as we provide in the
phungductung 0:e87aa4c49e95 24 examples.
phungductung 0:e87aa4c49e95 25 You can easily tailor this configuration according to hardware resources.
phungductung 0:e87aa4c49e95 26
phungductung 0:e87aa4c49e95 27 [..]
phungductung 0:e87aa4c49e95 28 This driver is a generic layered driver for SDMMC memories which uses the HAL
phungductung 0:e87aa4c49e95 29 SDMMC driver functions to interface with SD and uSD cards devices.
phungductung 0:e87aa4c49e95 30 It is used as follows:
phungductung 0:e87aa4c49e95 31
phungductung 0:e87aa4c49e95 32 (#)Initialize the SDMMC low level resources by implement the HAL_SD_MspInit() API:
phungductung 0:e87aa4c49e95 33 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
phungductung 0:e87aa4c49e95 34 (##) SDMMC pins configuration for SD card
phungductung 0:e87aa4c49e95 35 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
phungductung 0:e87aa4c49e95 36 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
phungductung 0:e87aa4c49e95 37 and according to your pin assignment;
phungductung 0:e87aa4c49e95 38 (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()
phungductung 0:e87aa4c49e95 39 and HAL_SD_WriteBlocks_DMA() APIs).
phungductung 0:e87aa4c49e95 40 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
phungductung 0:e87aa4c49e95 41 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
phungductung 0:e87aa4c49e95 42 (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
phungductung 0:e87aa4c49e95 43 (+++) Configure the SDMMC and DMA interrupt priorities using functions
phungductung 0:e87aa4c49e95 44 HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority
phungductung 0:e87aa4c49e95 45 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
phungductung 0:e87aa4c49e95 46 (+++) SDMMC interrupts are managed using the macros __HAL_SD_SDMMC_ENABLE_IT()
phungductung 0:e87aa4c49e95 47 and __HAL_SD_SDMMC_DISABLE_IT() inside the communication process.
phungductung 0:e87aa4c49e95 48 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SD_SDMMC_GET_IT()
phungductung 0:e87aa4c49e95 49 and __HAL_SD_SDMMC_CLEAR_IT()
phungductung 0:e87aa4c49e95 50 (#) At this stage, you can perform SD read/write/erase operations after SD card initialization
phungductung 0:e87aa4c49e95 51
phungductung 0:e87aa4c49e95 52
phungductung 0:e87aa4c49e95 53 *** SD Card Initialization and configuration ***
phungductung 0:e87aa4c49e95 54 ================================================
phungductung 0:e87aa4c49e95 55 [..]
phungductung 0:e87aa4c49e95 56 To initialize the SD Card, use the HAL_SD_Init() function. It Initializes
phungductung 0:e87aa4c49e95 57 the SD Card and put it into StandBy State (Ready for data transfer).
phungductung 0:e87aa4c49e95 58 This function provide the following operations:
phungductung 0:e87aa4c49e95 59
phungductung 0:e87aa4c49e95 60 (#) Apply the SD Card initialization process at 400KHz and check the SD Card
phungductung 0:e87aa4c49e95 61 type (Standard Capacity or High Capacity). You can change or adapt this
phungductung 0:e87aa4c49e95 62 frequency by adjusting the "ClockDiv" field.
phungductung 0:e87aa4c49e95 63 The SD Card frequency (SDMMC_CK) is computed as follows:
phungductung 0:e87aa4c49e95 64
phungductung 0:e87aa4c49e95 65 SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
phungductung 0:e87aa4c49e95 66
phungductung 0:e87aa4c49e95 67 In initialization mode and according to the SD Card standard,
phungductung 0:e87aa4c49e95 68 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
phungductung 0:e87aa4c49e95 69
phungductung 0:e87aa4c49e95 70 (#) Get the SD CID and CSD data. All these information are managed by the SDCardInfo
phungductung 0:e87aa4c49e95 71 structure. This structure provide also ready computed SD Card capacity
phungductung 0:e87aa4c49e95 72 and Block size.
phungductung 0:e87aa4c49e95 73
phungductung 0:e87aa4c49e95 74 -@- These information are stored in SD handle structure in case of future use.
phungductung 0:e87aa4c49e95 75
phungductung 0:e87aa4c49e95 76 (#) Configure the SD Card Data transfer frequency. By Default, the card transfer
phungductung 0:e87aa4c49e95 77 frequency is set to 24MHz. You can change or adapt this frequency by adjusting
phungductung 0:e87aa4c49e95 78 the "ClockDiv" field.
phungductung 0:e87aa4c49e95 79 In transfer mode and according to the SD Card standard, make sure that the
phungductung 0:e87aa4c49e95 80 SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
phungductung 0:e87aa4c49e95 81 To be able to use a frequency higher than 24MHz, you should use the SDMMC
phungductung 0:e87aa4c49e95 82 peripheral in bypass mode. Refer to the corresponding reference manual
phungductung 0:e87aa4c49e95 83 for more details.
phungductung 0:e87aa4c49e95 84
phungductung 0:e87aa4c49e95 85 (#) Select the corresponding SD Card according to the address read with the step 2.
phungductung 0:e87aa4c49e95 86
phungductung 0:e87aa4c49e95 87 (#) Configure the SD Card in wide bus mode: 4-bits data.
phungductung 0:e87aa4c49e95 88
phungductung 0:e87aa4c49e95 89 *** SD Card Read operation ***
phungductung 0:e87aa4c49e95 90 ==============================
phungductung 0:e87aa4c49e95 91 [..]
phungductung 0:e87aa4c49e95 92 (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
phungductung 0:e87aa4c49e95 93 This function support only 512-bytes block length (the block size should be
phungductung 0:e87aa4c49e95 94 chosen as 512 bytes).
phungductung 0:e87aa4c49e95 95 You can choose either one block read operation or multiple block read operation
phungductung 0:e87aa4c49e95 96 by adjusting the "NumberOfBlocks" parameter.
phungductung 0:e87aa4c49e95 97
phungductung 0:e87aa4c49e95 98 (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
phungductung 0:e87aa4c49e95 99 This function support only 512-bytes block length (the block size should be
phungductung 0:e87aa4c49e95 100 chosen as 512 bytes).
phungductung 0:e87aa4c49e95 101 You can choose either one block read operation or multiple block read operation
phungductung 0:e87aa4c49e95 102 by adjusting the "NumberOfBlocks" parameter.
phungductung 0:e87aa4c49e95 103 After this, you have to call the function HAL_SD_CheckReadOperation(), to insure
phungductung 0:e87aa4c49e95 104 that the read transfer is done correctly in both DMA and SD sides.
phungductung 0:e87aa4c49e95 105
phungductung 0:e87aa4c49e95 106 *** SD Card Write operation ***
phungductung 0:e87aa4c49e95 107 ===============================
phungductung 0:e87aa4c49e95 108 [..]
phungductung 0:e87aa4c49e95 109 (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks().
phungductung 0:e87aa4c49e95 110 This function support only 512-bytes block length (the block size should be
phungductung 0:e87aa4c49e95 111 chosen as 512 bytes).
phungductung 0:e87aa4c49e95 112 You can choose either one block read operation or multiple block read operation
phungductung 0:e87aa4c49e95 113 by adjusting the "NumberOfBlocks" parameter.
phungductung 0:e87aa4c49e95 114
phungductung 0:e87aa4c49e95 115 (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().
phungductung 0:e87aa4c49e95 116 This function support only 512-bytes block length (the block size should be
phungductung 0:e87aa4c49e95 117 chosen as 512 byte).
phungductung 0:e87aa4c49e95 118 You can choose either one block read operation or multiple block read operation
phungductung 0:e87aa4c49e95 119 by adjusting the "NumberOfBlocks" parameter.
phungductung 0:e87aa4c49e95 120 After this, you have to call the function HAL_SD_CheckWriteOperation(), to insure
phungductung 0:e87aa4c49e95 121 that the write transfer is done correctly in both DMA and SD sides.
phungductung 0:e87aa4c49e95 122
phungductung 0:e87aa4c49e95 123 *** SD card status ***
phungductung 0:e87aa4c49e95 124 ======================
phungductung 0:e87aa4c49e95 125 [..]
phungductung 0:e87aa4c49e95 126 (+) At any time, you can check the SD Card status and get the SD card state
phungductung 0:e87aa4c49e95 127 by using the HAL_SD_GetStatus() function. This function checks first if the
phungductung 0:e87aa4c49e95 128 SD card is still connected and then get the internal SD Card transfer state.
phungductung 0:e87aa4c49e95 129 (+) You can also get the SD card SD Status register by using the HAL_SD_SendSDStatus()
phungductung 0:e87aa4c49e95 130 function.
phungductung 0:e87aa4c49e95 131
phungductung 0:e87aa4c49e95 132 *** SD HAL driver macros list ***
phungductung 0:e87aa4c49e95 133 ==================================
phungductung 0:e87aa4c49e95 134 [..]
phungductung 0:e87aa4c49e95 135 Below the list of most used macros in SD HAL driver.
phungductung 0:e87aa4c49e95 136
phungductung 0:e87aa4c49e95 137 (+) __HAL_SD_SDMMC_ENABLE : Enable the SD device
phungductung 0:e87aa4c49e95 138 (+) __HAL_SD_SDMMC_DISABLE : Disable the SD device
phungductung 0:e87aa4c49e95 139 (+) __HAL_SD_SDMMC_DMA_ENABLE: Enable the SDMMC DMA transfer
phungductung 0:e87aa4c49e95 140 (+) __HAL_SD_SDMMC_DMA_DISABLE: Disable the SDMMC DMA transfer
phungductung 0:e87aa4c49e95 141 (+) __HAL_SD_SDMMC_ENABLE_IT: Enable the SD device interrupt
phungductung 0:e87aa4c49e95 142 (+) __HAL_SD_SDMMC_DISABLE_IT: Disable the SD device interrupt
phungductung 0:e87aa4c49e95 143 (+) __HAL_SD_SDMMC_GET_FLAG:Check whether the specified SD flag is set or not
phungductung 0:e87aa4c49e95 144 (+) __HAL_SD_SDMMC_CLEAR_FLAG: Clear the SD's pending flags
phungductung 0:e87aa4c49e95 145
phungductung 0:e87aa4c49e95 146 (@) You can refer to the SD HAL driver header file for more useful macros
phungductung 0:e87aa4c49e95 147
phungductung 0:e87aa4c49e95 148 @endverbatim
phungductung 0:e87aa4c49e95 149 ******************************************************************************
phungductung 0:e87aa4c49e95 150 * @attention
phungductung 0:e87aa4c49e95 151 *
phungductung 0:e87aa4c49e95 152 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
phungductung 0:e87aa4c49e95 153 *
phungductung 0:e87aa4c49e95 154 * Redistribution and use in source and binary forms, with or without modification,
phungductung 0:e87aa4c49e95 155 * are permitted provided that the following conditions are met:
phungductung 0:e87aa4c49e95 156 * 1. Redistributions of source code must retain the above copyright notice,
phungductung 0:e87aa4c49e95 157 * this list of conditions and the following disclaimer.
phungductung 0:e87aa4c49e95 158 * 2. Redistributions in binary form must reproduce the above copyright notice,
phungductung 0:e87aa4c49e95 159 * this list of conditions and the following disclaimer in the documentation
phungductung 0:e87aa4c49e95 160 * and/or other materials provided with the distribution.
phungductung 0:e87aa4c49e95 161 * 3. Neither the name of STMicroelectronics nor the names of its contributors
phungductung 0:e87aa4c49e95 162 * may be used to endorse or promote products derived from this software
phungductung 0:e87aa4c49e95 163 * without specific prior written permission.
phungductung 0:e87aa4c49e95 164 *
phungductung 0:e87aa4c49e95 165 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
phungductung 0:e87aa4c49e95 166 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
phungductung 0:e87aa4c49e95 167 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
phungductung 0:e87aa4c49e95 168 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
phungductung 0:e87aa4c49e95 169 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
phungductung 0:e87aa4c49e95 170 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
phungductung 0:e87aa4c49e95 171 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
phungductung 0:e87aa4c49e95 172 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
phungductung 0:e87aa4c49e95 173 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
phungductung 0:e87aa4c49e95 174 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
phungductung 0:e87aa4c49e95 175 *
phungductung 0:e87aa4c49e95 176 ******************************************************************************
phungductung 0:e87aa4c49e95 177 */
phungductung 0:e87aa4c49e95 178
phungductung 0:e87aa4c49e95 179 /* Includes ------------------------------------------------------------------*/
phungductung 0:e87aa4c49e95 180 #include "stm32f7xx_hal.h"
phungductung 0:e87aa4c49e95 181
phungductung 0:e87aa4c49e95 182 /** @addtogroup STM32F7xx_HAL_Driver
phungductung 0:e87aa4c49e95 183 * @{
phungductung 0:e87aa4c49e95 184 */
phungductung 0:e87aa4c49e95 185
phungductung 0:e87aa4c49e95 186 /** @addtogroup SD
phungductung 0:e87aa4c49e95 187 * @{
phungductung 0:e87aa4c49e95 188 */
phungductung 0:e87aa4c49e95 189
phungductung 0:e87aa4c49e95 190 #ifdef HAL_SD_MODULE_ENABLED
phungductung 0:e87aa4c49e95 191
phungductung 0:e87aa4c49e95 192 /* Private typedef -----------------------------------------------------------*/
phungductung 0:e87aa4c49e95 193 /* Private define ------------------------------------------------------------*/
phungductung 0:e87aa4c49e95 194 /** @addtogroup SD_Private_Defines
phungductung 0:e87aa4c49e95 195 * @{
phungductung 0:e87aa4c49e95 196 */
phungductung 0:e87aa4c49e95 197 /**
phungductung 0:e87aa4c49e95 198 * @brief SDMMC Data block size
phungductung 0:e87aa4c49e95 199 */
phungductung 0:e87aa4c49e95 200 #define DATA_BLOCK_SIZE ((uint32_t)(9 << 4))
phungductung 0:e87aa4c49e95 201 /**
phungductung 0:e87aa4c49e95 202 * @brief SDMMC Static flags, Timeout, FIFO Address
phungductung 0:e87aa4c49e95 203 */
phungductung 0:e87aa4c49e95 204 #define SDMMC_STATIC_FLAGS ((uint32_t)(SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_CTIMEOUT |\
phungductung 0:e87aa4c49e95 205 SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_RXOVERR |\
phungductung 0:e87aa4c49e95 206 SDMMC_FLAG_CMDREND | SDMMC_FLAG_CMDSENT | SDMMC_FLAG_DATAEND |\
phungductung 0:e87aa4c49e95 207 SDMMC_FLAG_DBCKEND))
phungductung 0:e87aa4c49e95 208
phungductung 0:e87aa4c49e95 209 #define SDMMC_CMD0TIMEOUT ((uint32_t)0x00010000)
phungductung 0:e87aa4c49e95 210
phungductung 0:e87aa4c49e95 211 /**
phungductung 0:e87aa4c49e95 212 * @brief Mask for errors Card Status R1 (OCR Register)
phungductung 0:e87aa4c49e95 213 */
phungductung 0:e87aa4c49e95 214 #define SD_OCR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000)
phungductung 0:e87aa4c49e95 215 #define SD_OCR_ADDR_MISALIGNED ((uint32_t)0x40000000)
phungductung 0:e87aa4c49e95 216 #define SD_OCR_BLOCK_LEN_ERR ((uint32_t)0x20000000)
phungductung 0:e87aa4c49e95 217 #define SD_OCR_ERASE_SEQ_ERR ((uint32_t)0x10000000)
phungductung 0:e87aa4c49e95 218 #define SD_OCR_BAD_ERASE_PARAM ((uint32_t)0x08000000)
phungductung 0:e87aa4c49e95 219 #define SD_OCR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000)
phungductung 0:e87aa4c49e95 220 #define SD_OCR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000)
phungductung 0:e87aa4c49e95 221 #define SD_OCR_COM_CRC_FAILED ((uint32_t)0x00800000)
phungductung 0:e87aa4c49e95 222 #define SD_OCR_ILLEGAL_CMD ((uint32_t)0x00400000)
phungductung 0:e87aa4c49e95 223 #define SD_OCR_CARD_ECC_FAILED ((uint32_t)0x00200000)
phungductung 0:e87aa4c49e95 224 #define SD_OCR_CC_ERROR ((uint32_t)0x00100000)
phungductung 0:e87aa4c49e95 225 #define SD_OCR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000)
phungductung 0:e87aa4c49e95 226 #define SD_OCR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000)
phungductung 0:e87aa4c49e95 227 #define SD_OCR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000)
phungductung 0:e87aa4c49e95 228 #define SD_OCR_CID_CSD_OVERWRITE ((uint32_t)0x00010000)
phungductung 0:e87aa4c49e95 229 #define SD_OCR_WP_ERASE_SKIP ((uint32_t)0x00008000)
phungductung 0:e87aa4c49e95 230 #define SD_OCR_CARD_ECC_DISABLED ((uint32_t)0x00004000)
phungductung 0:e87aa4c49e95 231 #define SD_OCR_ERASE_RESET ((uint32_t)0x00002000)
phungductung 0:e87aa4c49e95 232 #define SD_OCR_AKE_SEQ_ERROR ((uint32_t)0x00000008)
phungductung 0:e87aa4c49e95 233 #define SD_OCR_ERRORBITS ((uint32_t)0xFDFFE008)
phungductung 0:e87aa4c49e95 234
phungductung 0:e87aa4c49e95 235 /**
phungductung 0:e87aa4c49e95 236 * @brief Masks for R6 Response
phungductung 0:e87aa4c49e95 237 */
phungductung 0:e87aa4c49e95 238 #define SD_R6_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00002000)
phungductung 0:e87aa4c49e95 239 #define SD_R6_ILLEGAL_CMD ((uint32_t)0x00004000)
phungductung 0:e87aa4c49e95 240 #define SD_R6_COM_CRC_FAILED ((uint32_t)0x00008000)
phungductung 0:e87aa4c49e95 241
phungductung 0:e87aa4c49e95 242 #define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x80100000)
phungductung 0:e87aa4c49e95 243 #define SD_HIGH_CAPACITY ((uint32_t)0x40000000)
phungductung 0:e87aa4c49e95 244 #define SD_STD_CAPACITY ((uint32_t)0x00000000)
phungductung 0:e87aa4c49e95 245 #define SD_CHECK_PATTERN ((uint32_t)0x000001AA)
phungductung 0:e87aa4c49e95 246
phungductung 0:e87aa4c49e95 247 #define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF)
phungductung 0:e87aa4c49e95 248 #define SD_ALLZERO ((uint32_t)0x00000000)
phungductung 0:e87aa4c49e95 249
phungductung 0:e87aa4c49e95 250 #define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000)
phungductung 0:e87aa4c49e95 251 #define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000)
phungductung 0:e87aa4c49e95 252 #define SD_CARD_LOCKED ((uint32_t)0x02000000)
phungductung 0:e87aa4c49e95 253
phungductung 0:e87aa4c49e95 254 #define SD_DATATIMEOUT ((uint32_t)0xFFFFFFFF)
phungductung 0:e87aa4c49e95 255 #define SD_0TO7BITS ((uint32_t)0x000000FF)
phungductung 0:e87aa4c49e95 256 #define SD_8TO15BITS ((uint32_t)0x0000FF00)
phungductung 0:e87aa4c49e95 257 #define SD_16TO23BITS ((uint32_t)0x00FF0000)
phungductung 0:e87aa4c49e95 258 #define SD_24TO31BITS ((uint32_t)0xFF000000)
phungductung 0:e87aa4c49e95 259 #define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF)
phungductung 0:e87aa4c49e95 260
phungductung 0:e87aa4c49e95 261 #define SD_HALFFIFO ((uint32_t)0x00000008)
phungductung 0:e87aa4c49e95 262 #define SD_HALFFIFOBYTES ((uint32_t)0x00000020)
phungductung 0:e87aa4c49e95 263
phungductung 0:e87aa4c49e95 264 /**
phungductung 0:e87aa4c49e95 265 * @brief Command Class Supported
phungductung 0:e87aa4c49e95 266 */
phungductung 0:e87aa4c49e95 267 #define SD_CCCC_LOCK_UNLOCK ((uint32_t)0x00000080)
phungductung 0:e87aa4c49e95 268 #define SD_CCCC_WRITE_PROT ((uint32_t)0x00000040)
phungductung 0:e87aa4c49e95 269 #define SD_CCCC_ERASE ((uint32_t)0x00000020)
phungductung 0:e87aa4c49e95 270
phungductung 0:e87aa4c49e95 271 /**
phungductung 0:e87aa4c49e95 272 * @brief Following commands are SD Card Specific commands.
phungductung 0:e87aa4c49e95 273 * SDMMC_APP_CMD should be sent before sending these commands.
phungductung 0:e87aa4c49e95 274 */
phungductung 0:e87aa4c49e95 275 #define SD_SDMMC_SEND_IF_COND ((uint32_t)SD_CMD_HS_SEND_EXT_CSD)
phungductung 0:e87aa4c49e95 276 /**
phungductung 0:e87aa4c49e95 277 * @}
phungductung 0:e87aa4c49e95 278 */
phungductung 0:e87aa4c49e95 279
phungductung 0:e87aa4c49e95 280 /* Private macro -------------------------------------------------------------*/
phungductung 0:e87aa4c49e95 281 /* Private variables ---------------------------------------------------------*/
phungductung 0:e87aa4c49e95 282 /* Private function prototypes -----------------------------------------------*/
phungductung 0:e87aa4c49e95 283 /* Private functions ---------------------------------------------------------*/
phungductung 0:e87aa4c49e95 284 /** @defgroup SD_Private_Functions SD Private Functions
phungductung 0:e87aa4c49e95 285 * @{
phungductung 0:e87aa4c49e95 286 */
phungductung 0:e87aa4c49e95 287 static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 288 static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr);
phungductung 0:e87aa4c49e95 289 static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 290 static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 291 static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);
phungductung 0:e87aa4c49e95 292 static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 293 static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus);
phungductung 0:e87aa4c49e95 294 static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 295 static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD);
phungductung 0:e87aa4c49e95 296 static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 297 static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 298 static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 299 static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA);
phungductung 0:e87aa4c49e95 300 static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 301 static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd);
phungductung 0:e87aa4c49e95 302 static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);
phungductung 0:e87aa4c49e95 303 static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma);
phungductung 0:e87aa4c49e95 304 static void SD_DMA_RxError(DMA_HandleTypeDef *hdma);
phungductung 0:e87aa4c49e95 305 static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma);
phungductung 0:e87aa4c49e95 306 static void SD_DMA_TxError(DMA_HandleTypeDef *hdma);
phungductung 0:e87aa4c49e95 307 /**
phungductung 0:e87aa4c49e95 308 * @}
phungductung 0:e87aa4c49e95 309 */
phungductung 0:e87aa4c49e95 310 /* Exported functions --------------------------------------------------------*/
phungductung 0:e87aa4c49e95 311 /** @addtogroup SD_Exported_Functions
phungductung 0:e87aa4c49e95 312 * @{
phungductung 0:e87aa4c49e95 313 */
phungductung 0:e87aa4c49e95 314
phungductung 0:e87aa4c49e95 315 /** @addtogroup SD_Exported_Functions_Group1
phungductung 0:e87aa4c49e95 316 * @brief Initialization and de-initialization functions
phungductung 0:e87aa4c49e95 317 *
phungductung 0:e87aa4c49e95 318 @verbatim
phungductung 0:e87aa4c49e95 319 ==============================================================================
phungductung 0:e87aa4c49e95 320 ##### Initialization and de-initialization functions #####
phungductung 0:e87aa4c49e95 321 ==============================================================================
phungductung 0:e87aa4c49e95 322 [..]
phungductung 0:e87aa4c49e95 323 This section provides functions allowing to initialize/de-initialize the SD
phungductung 0:e87aa4c49e95 324 card device to be ready for use.
phungductung 0:e87aa4c49e95 325
phungductung 0:e87aa4c49e95 326
phungductung 0:e87aa4c49e95 327 @endverbatim
phungductung 0:e87aa4c49e95 328 * @{
phungductung 0:e87aa4c49e95 329 */
phungductung 0:e87aa4c49e95 330
phungductung 0:e87aa4c49e95 331 /**
phungductung 0:e87aa4c49e95 332 * @brief Initializes the SD card according to the specified parameters in the
phungductung 0:e87aa4c49e95 333 SD_HandleTypeDef and create the associated handle.
phungductung 0:e87aa4c49e95 334 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 335 * @param SDCardInfo: HAL_SD_CardInfoTypedef structure for SD card information
phungductung 0:e87aa4c49e95 336 * @retval HAL SD error state
phungductung 0:e87aa4c49e95 337 */
phungductung 0:e87aa4c49e95 338 HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo)
phungductung 0:e87aa4c49e95 339 {
phungductung 0:e87aa4c49e95 340 __IO HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 341 SD_InitTypeDef tmpinit;
phungductung 0:e87aa4c49e95 342
phungductung 0:e87aa4c49e95 343 /* Allocate lock resource and initialize it */
phungductung 0:e87aa4c49e95 344 hsd->Lock = HAL_UNLOCKED;
phungductung 0:e87aa4c49e95 345
phungductung 0:e87aa4c49e95 346 /* Initialize the low level hardware (MSP) */
phungductung 0:e87aa4c49e95 347 HAL_SD_MspInit(hsd);
phungductung 0:e87aa4c49e95 348
phungductung 0:e87aa4c49e95 349 /* Default SDMMC peripheral configuration for SD card initialization */
phungductung 0:e87aa4c49e95 350 tmpinit.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
phungductung 0:e87aa4c49e95 351 tmpinit.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
phungductung 0:e87aa4c49e95 352 tmpinit.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
phungductung 0:e87aa4c49e95 353 tmpinit.BusWide = SDMMC_BUS_WIDE_1B;
phungductung 0:e87aa4c49e95 354 tmpinit.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
phungductung 0:e87aa4c49e95 355 tmpinit.ClockDiv = SDMMC_INIT_CLK_DIV;
phungductung 0:e87aa4c49e95 356
phungductung 0:e87aa4c49e95 357 /* Initialize SDMMC peripheral interface with default configuration */
phungductung 0:e87aa4c49e95 358 SDMMC_Init(hsd->Instance, tmpinit);
phungductung 0:e87aa4c49e95 359
phungductung 0:e87aa4c49e95 360 /* Identify card operating voltage */
phungductung 0:e87aa4c49e95 361 errorstate = SD_PowerON(hsd);
phungductung 0:e87aa4c49e95 362
phungductung 0:e87aa4c49e95 363 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 364 {
phungductung 0:e87aa4c49e95 365 return errorstate;
phungductung 0:e87aa4c49e95 366 }
phungductung 0:e87aa4c49e95 367
phungductung 0:e87aa4c49e95 368 /* Initialize the present SDMMC card(s) and put them in idle state */
phungductung 0:e87aa4c49e95 369 errorstate = SD_Initialize_Cards(hsd);
phungductung 0:e87aa4c49e95 370
phungductung 0:e87aa4c49e95 371 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 372 {
phungductung 0:e87aa4c49e95 373 return errorstate;
phungductung 0:e87aa4c49e95 374 }
phungductung 0:e87aa4c49e95 375
phungductung 0:e87aa4c49e95 376 /* Read CSD/CID MSD registers */
phungductung 0:e87aa4c49e95 377 errorstate = HAL_SD_Get_CardInfo(hsd, SDCardInfo);
phungductung 0:e87aa4c49e95 378
phungductung 0:e87aa4c49e95 379 if (errorstate == SD_OK)
phungductung 0:e87aa4c49e95 380 {
phungductung 0:e87aa4c49e95 381 /* Select the Card */
phungductung 0:e87aa4c49e95 382 errorstate = SD_Select_Deselect(hsd, (uint32_t)(((uint32_t)SDCardInfo->RCA) << 16));
phungductung 0:e87aa4c49e95 383 }
phungductung 0:e87aa4c49e95 384
phungductung 0:e87aa4c49e95 385 /* Configure SDMMC peripheral interface */
phungductung 0:e87aa4c49e95 386 SDMMC_Init(hsd->Instance, hsd->Init);
phungductung 0:e87aa4c49e95 387
phungductung 0:e87aa4c49e95 388 return errorstate;
phungductung 0:e87aa4c49e95 389 }
phungductung 0:e87aa4c49e95 390
phungductung 0:e87aa4c49e95 391 /**
phungductung 0:e87aa4c49e95 392 * @brief De-Initializes the SD card.
phungductung 0:e87aa4c49e95 393 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 394 * @retval HAL status
phungductung 0:e87aa4c49e95 395 */
phungductung 0:e87aa4c49e95 396 HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 397 {
phungductung 0:e87aa4c49e95 398
phungductung 0:e87aa4c49e95 399 /* Set SD power state to off */
phungductung 0:e87aa4c49e95 400 SD_PowerOFF(hsd);
phungductung 0:e87aa4c49e95 401
phungductung 0:e87aa4c49e95 402 /* De-Initialize the MSP layer */
phungductung 0:e87aa4c49e95 403 HAL_SD_MspDeInit(hsd);
phungductung 0:e87aa4c49e95 404
phungductung 0:e87aa4c49e95 405 return HAL_OK;
phungductung 0:e87aa4c49e95 406 }
phungductung 0:e87aa4c49e95 407
phungductung 0:e87aa4c49e95 408
phungductung 0:e87aa4c49e95 409 /**
phungductung 0:e87aa4c49e95 410 * @brief Initializes the SD MSP.
phungductung 0:e87aa4c49e95 411 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 412 * @retval None
phungductung 0:e87aa4c49e95 413 */
phungductung 0:e87aa4c49e95 414 __weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 415 {
phungductung 0:e87aa4c49e95 416 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 417 UNUSED(hsd);
phungductung 0:e87aa4c49e95 418
phungductung 0:e87aa4c49e95 419 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 420 the HAL_SD_MspInit could be implemented in the user file
phungductung 0:e87aa4c49e95 421 */
phungductung 0:e87aa4c49e95 422 }
phungductung 0:e87aa4c49e95 423
phungductung 0:e87aa4c49e95 424 /**
phungductung 0:e87aa4c49e95 425 * @brief De-Initialize SD MSP.
phungductung 0:e87aa4c49e95 426 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 427 * @retval None
phungductung 0:e87aa4c49e95 428 */
phungductung 0:e87aa4c49e95 429 __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 430 {
phungductung 0:e87aa4c49e95 431 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 432 UNUSED(hsd);
phungductung 0:e87aa4c49e95 433
phungductung 0:e87aa4c49e95 434 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 435 the HAL_SD_MspDeInit could be implemented in the user file
phungductung 0:e87aa4c49e95 436 */
phungductung 0:e87aa4c49e95 437 }
phungductung 0:e87aa4c49e95 438
phungductung 0:e87aa4c49e95 439 /**
phungductung 0:e87aa4c49e95 440 * @}
phungductung 0:e87aa4c49e95 441 */
phungductung 0:e87aa4c49e95 442
phungductung 0:e87aa4c49e95 443 /** @addtogroup SD_Exported_Functions_Group2
phungductung 0:e87aa4c49e95 444 * @brief Data transfer functions
phungductung 0:e87aa4c49e95 445 *
phungductung 0:e87aa4c49e95 446 @verbatim
phungductung 0:e87aa4c49e95 447 ==============================================================================
phungductung 0:e87aa4c49e95 448 ##### IO operation functions #####
phungductung 0:e87aa4c49e95 449 ==============================================================================
phungductung 0:e87aa4c49e95 450 [..]
phungductung 0:e87aa4c49e95 451 This subsection provides a set of functions allowing to manage the data
phungductung 0:e87aa4c49e95 452 transfer from/to SD card.
phungductung 0:e87aa4c49e95 453
phungductung 0:e87aa4c49e95 454 @endverbatim
phungductung 0:e87aa4c49e95 455 * @{
phungductung 0:e87aa4c49e95 456 */
phungductung 0:e87aa4c49e95 457
phungductung 0:e87aa4c49e95 458 /**
phungductung 0:e87aa4c49e95 459 * @brief Reads block(s) from a specified address in a card. The Data transfer
phungductung 0:e87aa4c49e95 460 * is managed by polling mode.
phungductung 0:e87aa4c49e95 461 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 462 * @param pReadBuffer: pointer to the buffer that will contain the received data
phungductung 0:e87aa4c49e95 463 * @param ReadAddr: Address from where data is to be read
phungductung 0:e87aa4c49e95 464 * @param BlockSize: SD card Data block size
phungductung 0:e87aa4c49e95 465 * @note BlockSize must be 512 bytes.
phungductung 0:e87aa4c49e95 466 * @param NumberOfBlocks: Number of SD blocks to read
phungductung 0:e87aa4c49e95 467 * @retval SD Card error state
phungductung 0:e87aa4c49e95 468 */
phungductung 0:e87aa4c49e95 469 HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
phungductung 0:e87aa4c49e95 470 {
phungductung 0:e87aa4c49e95 471 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 472 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 473 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 474 uint32_t count = 0, *tempbuff = (uint32_t *)pReadBuffer;
phungductung 0:e87aa4c49e95 475
phungductung 0:e87aa4c49e95 476 /* Initialize data control register */
phungductung 0:e87aa4c49e95 477 hsd->Instance->DCTRL = 0;
phungductung 0:e87aa4c49e95 478
phungductung 0:e87aa4c49e95 479 if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
phungductung 0:e87aa4c49e95 480 {
phungductung 0:e87aa4c49e95 481 BlockSize = 512;
phungductung 0:e87aa4c49e95 482 ReadAddr /= 512;
phungductung 0:e87aa4c49e95 483 }
phungductung 0:e87aa4c49e95 484
phungductung 0:e87aa4c49e95 485 /* Set Block Size for Card */
phungductung 0:e87aa4c49e95 486 sdmmc_cmdinitstructure.Argument = (uint32_t) BlockSize;
phungductung 0:e87aa4c49e95 487 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 488 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 489 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 490 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 491 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 492
phungductung 0:e87aa4c49e95 493 /* Check for error conditions */
phungductung 0:e87aa4c49e95 494 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 495
phungductung 0:e87aa4c49e95 496 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 497 {
phungductung 0:e87aa4c49e95 498 return errorstate;
phungductung 0:e87aa4c49e95 499 }
phungductung 0:e87aa4c49e95 500
phungductung 0:e87aa4c49e95 501 /* Configure the SD DPSM (Data Path State Machine) */
phungductung 0:e87aa4c49e95 502 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 503 sdmmc_datainitstructure.DataLength = NumberOfBlocks * BlockSize;
phungductung 0:e87aa4c49e95 504 sdmmc_datainitstructure.DataBlockSize = DATA_BLOCK_SIZE;
phungductung 0:e87aa4c49e95 505 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
phungductung 0:e87aa4c49e95 506 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 507 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 508 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 509
phungductung 0:e87aa4c49e95 510 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 511 {
phungductung 0:e87aa4c49e95 512 /* Send CMD18 READ_MULT_BLOCK with argument data address */
phungductung 0:e87aa4c49e95 513 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;
phungductung 0:e87aa4c49e95 514 }
phungductung 0:e87aa4c49e95 515 else
phungductung 0:e87aa4c49e95 516 {
phungductung 0:e87aa4c49e95 517 /* Send CMD17 READ_SINGLE_BLOCK */
phungductung 0:e87aa4c49e95 518 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
phungductung 0:e87aa4c49e95 519 }
phungductung 0:e87aa4c49e95 520
phungductung 0:e87aa4c49e95 521 sdmmc_cmdinitstructure.Argument = (uint32_t)ReadAddr;
phungductung 0:e87aa4c49e95 522 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 523
phungductung 0:e87aa4c49e95 524 /* Read block(s) in polling mode */
phungductung 0:e87aa4c49e95 525 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 526 {
phungductung 0:e87aa4c49e95 527 /* Check for error conditions */
phungductung 0:e87aa4c49e95 528 errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);
phungductung 0:e87aa4c49e95 529
phungductung 0:e87aa4c49e95 530 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 531 {
phungductung 0:e87aa4c49e95 532 return errorstate;
phungductung 0:e87aa4c49e95 533 }
phungductung 0:e87aa4c49e95 534
phungductung 0:e87aa4c49e95 535 /* Poll on SDMMC flags */
phungductung 0:e87aa4c49e95 536 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
phungductung 0:e87aa4c49e95 537 {
phungductung 0:e87aa4c49e95 538 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))
phungductung 0:e87aa4c49e95 539 {
phungductung 0:e87aa4c49e95 540 /* Read data from SDMMC Rx FIFO */
phungductung 0:e87aa4c49e95 541 for (count = 0; count < 8; count++)
phungductung 0:e87aa4c49e95 542 {
phungductung 0:e87aa4c49e95 543 *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 544 }
phungductung 0:e87aa4c49e95 545
phungductung 0:e87aa4c49e95 546 tempbuff += 8;
phungductung 0:e87aa4c49e95 547 }
phungductung 0:e87aa4c49e95 548 }
phungductung 0:e87aa4c49e95 549 }
phungductung 0:e87aa4c49e95 550 else
phungductung 0:e87aa4c49e95 551 {
phungductung 0:e87aa4c49e95 552 /* Check for error conditions */
phungductung 0:e87aa4c49e95 553 errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK);
phungductung 0:e87aa4c49e95 554
phungductung 0:e87aa4c49e95 555 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 556 {
phungductung 0:e87aa4c49e95 557 return errorstate;
phungductung 0:e87aa4c49e95 558 }
phungductung 0:e87aa4c49e95 559
phungductung 0:e87aa4c49e95 560 /* In case of single block transfer, no need of stop transfer at all */
phungductung 0:e87aa4c49e95 561 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
phungductung 0:e87aa4c49e95 562 {
phungductung 0:e87aa4c49e95 563 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))
phungductung 0:e87aa4c49e95 564 {
phungductung 0:e87aa4c49e95 565 /* Read data from SDMMC Rx FIFO */
phungductung 0:e87aa4c49e95 566 for (count = 0; count < 8; count++)
phungductung 0:e87aa4c49e95 567 {
phungductung 0:e87aa4c49e95 568 *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 569 }
phungductung 0:e87aa4c49e95 570
phungductung 0:e87aa4c49e95 571 tempbuff += 8;
phungductung 0:e87aa4c49e95 572 }
phungductung 0:e87aa4c49e95 573 }
phungductung 0:e87aa4c49e95 574 }
phungductung 0:e87aa4c49e95 575
phungductung 0:e87aa4c49e95 576 /* Send stop transmission command in case of multiblock read */
phungductung 0:e87aa4c49e95 577 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1))
phungductung 0:e87aa4c49e95 578 {
phungductung 0:e87aa4c49e95 579 if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) ||\
phungductung 0:e87aa4c49e95 580 (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
phungductung 0:e87aa4c49e95 581 (hsd->CardType == HIGH_CAPACITY_SD_CARD))
phungductung 0:e87aa4c49e95 582 {
phungductung 0:e87aa4c49e95 583 /* Send stop transmission command */
phungductung 0:e87aa4c49e95 584 errorstate = HAL_SD_StopTransfer(hsd);
phungductung 0:e87aa4c49e95 585 }
phungductung 0:e87aa4c49e95 586 }
phungductung 0:e87aa4c49e95 587
phungductung 0:e87aa4c49e95 588 /* Get error state */
phungductung 0:e87aa4c49e95 589 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))
phungductung 0:e87aa4c49e95 590 {
phungductung 0:e87aa4c49e95 591 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);
phungductung 0:e87aa4c49e95 592
phungductung 0:e87aa4c49e95 593 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 594
phungductung 0:e87aa4c49e95 595 return errorstate;
phungductung 0:e87aa4c49e95 596 }
phungductung 0:e87aa4c49e95 597 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))
phungductung 0:e87aa4c49e95 598 {
phungductung 0:e87aa4c49e95 599 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);
phungductung 0:e87aa4c49e95 600
phungductung 0:e87aa4c49e95 601 errorstate = SD_DATA_CRC_FAIL;
phungductung 0:e87aa4c49e95 602
phungductung 0:e87aa4c49e95 603 return errorstate;
phungductung 0:e87aa4c49e95 604 }
phungductung 0:e87aa4c49e95 605 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))
phungductung 0:e87aa4c49e95 606 {
phungductung 0:e87aa4c49e95 607 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);
phungductung 0:e87aa4c49e95 608
phungductung 0:e87aa4c49e95 609 errorstate = SD_RX_OVERRUN;
phungductung 0:e87aa4c49e95 610
phungductung 0:e87aa4c49e95 611 return errorstate;
phungductung 0:e87aa4c49e95 612 }
phungductung 0:e87aa4c49e95 613 else
phungductung 0:e87aa4c49e95 614 {
phungductung 0:e87aa4c49e95 615 /* No error flag set */
phungductung 0:e87aa4c49e95 616 }
phungductung 0:e87aa4c49e95 617
phungductung 0:e87aa4c49e95 618 count = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 619
phungductung 0:e87aa4c49e95 620 /* Empty FIFO if there is still any data */
phungductung 0:e87aa4c49e95 621 while ((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) && (count > 0))
phungductung 0:e87aa4c49e95 622 {
phungductung 0:e87aa4c49e95 623 *tempbuff = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 624 tempbuff++;
phungductung 0:e87aa4c49e95 625 count--;
phungductung 0:e87aa4c49e95 626 }
phungductung 0:e87aa4c49e95 627
phungductung 0:e87aa4c49e95 628 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 629 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 630
phungductung 0:e87aa4c49e95 631 return errorstate;
phungductung 0:e87aa4c49e95 632 }
phungductung 0:e87aa4c49e95 633
phungductung 0:e87aa4c49e95 634 /**
phungductung 0:e87aa4c49e95 635 * @brief Allows to write block(s) to a specified address in a card. The Data
phungductung 0:e87aa4c49e95 636 * transfer is managed by polling mode.
phungductung 0:e87aa4c49e95 637 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 638 * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
phungductung 0:e87aa4c49e95 639 * @param WriteAddr: Address from where data is to be written
phungductung 0:e87aa4c49e95 640 * @param BlockSize: SD card Data block size
phungductung 0:e87aa4c49e95 641 * @note BlockSize must be 512 bytes.
phungductung 0:e87aa4c49e95 642 * @param NumberOfBlocks: Number of SD blocks to write
phungductung 0:e87aa4c49e95 643 * @retval SD Card error state
phungductung 0:e87aa4c49e95 644 */
phungductung 0:e87aa4c49e95 645 HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
phungductung 0:e87aa4c49e95 646 {
phungductung 0:e87aa4c49e95 647 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 648 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 649 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 650 uint32_t totalnumberofbytes = 0, bytestransferred = 0, count = 0, restwords = 0;
phungductung 0:e87aa4c49e95 651 uint32_t *tempbuff = (uint32_t *)pWriteBuffer;
phungductung 0:e87aa4c49e95 652 uint8_t cardstate = 0;
phungductung 0:e87aa4c49e95 653
phungductung 0:e87aa4c49e95 654 /* Initialize data control register */
phungductung 0:e87aa4c49e95 655 hsd->Instance->DCTRL = 0;
phungductung 0:e87aa4c49e95 656
phungductung 0:e87aa4c49e95 657 if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
phungductung 0:e87aa4c49e95 658 {
phungductung 0:e87aa4c49e95 659 BlockSize = 512;
phungductung 0:e87aa4c49e95 660 WriteAddr /= 512;
phungductung 0:e87aa4c49e95 661 }
phungductung 0:e87aa4c49e95 662
phungductung 0:e87aa4c49e95 663 /* Set Block Size for Card */
phungductung 0:e87aa4c49e95 664 sdmmc_cmdinitstructure.Argument = (uint32_t)BlockSize;
phungductung 0:e87aa4c49e95 665 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 666 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 667 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 668 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 669 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 670
phungductung 0:e87aa4c49e95 671 /* Check for error conditions */
phungductung 0:e87aa4c49e95 672 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 673
phungductung 0:e87aa4c49e95 674 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 675 {
phungductung 0:e87aa4c49e95 676 return errorstate;
phungductung 0:e87aa4c49e95 677 }
phungductung 0:e87aa4c49e95 678
phungductung 0:e87aa4c49e95 679 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 680 {
phungductung 0:e87aa4c49e95 681 /* Send CMD25 WRITE_MULT_BLOCK with argument data address */
phungductung 0:e87aa4c49e95 682 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
phungductung 0:e87aa4c49e95 683 }
phungductung 0:e87aa4c49e95 684 else
phungductung 0:e87aa4c49e95 685 {
phungductung 0:e87aa4c49e95 686 /* Send CMD24 WRITE_SINGLE_BLOCK */
phungductung 0:e87aa4c49e95 687 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
phungductung 0:e87aa4c49e95 688 }
phungductung 0:e87aa4c49e95 689
phungductung 0:e87aa4c49e95 690 sdmmc_cmdinitstructure.Argument = (uint32_t)WriteAddr;
phungductung 0:e87aa4c49e95 691 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 692
phungductung 0:e87aa4c49e95 693 /* Check for error conditions */
phungductung 0:e87aa4c49e95 694 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 695 {
phungductung 0:e87aa4c49e95 696 errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);
phungductung 0:e87aa4c49e95 697 }
phungductung 0:e87aa4c49e95 698 else
phungductung 0:e87aa4c49e95 699 {
phungductung 0:e87aa4c49e95 700 errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);
phungductung 0:e87aa4c49e95 701 }
phungductung 0:e87aa4c49e95 702
phungductung 0:e87aa4c49e95 703 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 704 {
phungductung 0:e87aa4c49e95 705 return errorstate;
phungductung 0:e87aa4c49e95 706 }
phungductung 0:e87aa4c49e95 707
phungductung 0:e87aa4c49e95 708 /* Set total number of bytes to write */
phungductung 0:e87aa4c49e95 709 totalnumberofbytes = NumberOfBlocks * BlockSize;
phungductung 0:e87aa4c49e95 710
phungductung 0:e87aa4c49e95 711 /* Configure the SD DPSM (Data Path State Machine) */
phungductung 0:e87aa4c49e95 712 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 713 sdmmc_datainitstructure.DataLength = NumberOfBlocks * BlockSize;
phungductung 0:e87aa4c49e95 714 sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
phungductung 0:e87aa4c49e95 715 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
phungductung 0:e87aa4c49e95 716 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 717 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 718 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 719
phungductung 0:e87aa4c49e95 720 /* Write block(s) in polling mode */
phungductung 0:e87aa4c49e95 721 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 722 {
phungductung 0:e87aa4c49e95 723 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
phungductung 0:e87aa4c49e95 724 {
phungductung 0:e87aa4c49e95 725 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE))
phungductung 0:e87aa4c49e95 726 {
phungductung 0:e87aa4c49e95 727 if ((totalnumberofbytes - bytestransferred) < 32)
phungductung 0:e87aa4c49e95 728 {
phungductung 0:e87aa4c49e95 729 restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes - bytestransferred) / 4 + 1);
phungductung 0:e87aa4c49e95 730
phungductung 0:e87aa4c49e95 731 /* Write data to SDMMC Tx FIFO */
phungductung 0:e87aa4c49e95 732 for (count = 0; count < restwords; count++)
phungductung 0:e87aa4c49e95 733 {
phungductung 0:e87aa4c49e95 734 SDMMC_WriteFIFO(hsd->Instance, tempbuff);
phungductung 0:e87aa4c49e95 735 tempbuff++;
phungductung 0:e87aa4c49e95 736 bytestransferred += 4;
phungductung 0:e87aa4c49e95 737 }
phungductung 0:e87aa4c49e95 738 }
phungductung 0:e87aa4c49e95 739 else
phungductung 0:e87aa4c49e95 740 {
phungductung 0:e87aa4c49e95 741 /* Write data to SDMMC Tx FIFO */
phungductung 0:e87aa4c49e95 742 for (count = 0; count < 8; count++)
phungductung 0:e87aa4c49e95 743 {
phungductung 0:e87aa4c49e95 744 SDMMC_WriteFIFO(hsd->Instance, (tempbuff + count));
phungductung 0:e87aa4c49e95 745 }
phungductung 0:e87aa4c49e95 746
phungductung 0:e87aa4c49e95 747 tempbuff += 8;
phungductung 0:e87aa4c49e95 748 bytestransferred += 32;
phungductung 0:e87aa4c49e95 749 }
phungductung 0:e87aa4c49e95 750 }
phungductung 0:e87aa4c49e95 751 }
phungductung 0:e87aa4c49e95 752 }
phungductung 0:e87aa4c49e95 753 else
phungductung 0:e87aa4c49e95 754 {
phungductung 0:e87aa4c49e95 755 /* In case of single data block transfer no need of stop command at all */
phungductung 0:e87aa4c49e95 756 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
phungductung 0:e87aa4c49e95 757 {
phungductung 0:e87aa4c49e95 758 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE))
phungductung 0:e87aa4c49e95 759 {
phungductung 0:e87aa4c49e95 760 if ((totalnumberofbytes - bytestransferred) < 32)
phungductung 0:e87aa4c49e95 761 {
phungductung 0:e87aa4c49e95 762 restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes - bytestransferred) / 4 + 1);
phungductung 0:e87aa4c49e95 763
phungductung 0:e87aa4c49e95 764 /* Write data to SDMMC Tx FIFO */
phungductung 0:e87aa4c49e95 765 for (count = 0; count < restwords; count++)
phungductung 0:e87aa4c49e95 766 {
phungductung 0:e87aa4c49e95 767 SDMMC_WriteFIFO(hsd->Instance, tempbuff);
phungductung 0:e87aa4c49e95 768 tempbuff++;
phungductung 0:e87aa4c49e95 769 bytestransferred += 4;
phungductung 0:e87aa4c49e95 770 }
phungductung 0:e87aa4c49e95 771 }
phungductung 0:e87aa4c49e95 772 else
phungductung 0:e87aa4c49e95 773 {
phungductung 0:e87aa4c49e95 774 /* Write data to SDMMC Tx FIFO */
phungductung 0:e87aa4c49e95 775 for (count = 0; count < 8; count++)
phungductung 0:e87aa4c49e95 776 {
phungductung 0:e87aa4c49e95 777 SDMMC_WriteFIFO(hsd->Instance, (tempbuff + count));
phungductung 0:e87aa4c49e95 778 }
phungductung 0:e87aa4c49e95 779
phungductung 0:e87aa4c49e95 780 tempbuff += 8;
phungductung 0:e87aa4c49e95 781 bytestransferred += 32;
phungductung 0:e87aa4c49e95 782 }
phungductung 0:e87aa4c49e95 783 }
phungductung 0:e87aa4c49e95 784 }
phungductung 0:e87aa4c49e95 785 }
phungductung 0:e87aa4c49e95 786
phungductung 0:e87aa4c49e95 787 /* Send stop transmission command in case of multiblock write */
phungductung 0:e87aa4c49e95 788 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1))
phungductung 0:e87aa4c49e95 789 {
phungductung 0:e87aa4c49e95 790 if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
phungductung 0:e87aa4c49e95 791 (hsd->CardType == HIGH_CAPACITY_SD_CARD))
phungductung 0:e87aa4c49e95 792 {
phungductung 0:e87aa4c49e95 793 /* Send stop transmission command */
phungductung 0:e87aa4c49e95 794 errorstate = HAL_SD_StopTransfer(hsd);
phungductung 0:e87aa4c49e95 795 }
phungductung 0:e87aa4c49e95 796 }
phungductung 0:e87aa4c49e95 797
phungductung 0:e87aa4c49e95 798 /* Get error state */
phungductung 0:e87aa4c49e95 799 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))
phungductung 0:e87aa4c49e95 800 {
phungductung 0:e87aa4c49e95 801 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);
phungductung 0:e87aa4c49e95 802
phungductung 0:e87aa4c49e95 803 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 804
phungductung 0:e87aa4c49e95 805 return errorstate;
phungductung 0:e87aa4c49e95 806 }
phungductung 0:e87aa4c49e95 807 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))
phungductung 0:e87aa4c49e95 808 {
phungductung 0:e87aa4c49e95 809 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);
phungductung 0:e87aa4c49e95 810
phungductung 0:e87aa4c49e95 811 errorstate = SD_DATA_CRC_FAIL;
phungductung 0:e87aa4c49e95 812
phungductung 0:e87aa4c49e95 813 return errorstate;
phungductung 0:e87aa4c49e95 814 }
phungductung 0:e87aa4c49e95 815 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR))
phungductung 0:e87aa4c49e95 816 {
phungductung 0:e87aa4c49e95 817 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_TXUNDERR);
phungductung 0:e87aa4c49e95 818
phungductung 0:e87aa4c49e95 819 errorstate = SD_TX_UNDERRUN;
phungductung 0:e87aa4c49e95 820
phungductung 0:e87aa4c49e95 821 return errorstate;
phungductung 0:e87aa4c49e95 822 }
phungductung 0:e87aa4c49e95 823 else
phungductung 0:e87aa4c49e95 824 {
phungductung 0:e87aa4c49e95 825 /* No error flag set */
phungductung 0:e87aa4c49e95 826 }
phungductung 0:e87aa4c49e95 827
phungductung 0:e87aa4c49e95 828 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 829 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 830
phungductung 0:e87aa4c49e95 831 /* Wait till the card is in programming state */
phungductung 0:e87aa4c49e95 832 errorstate = SD_IsCardProgramming(hsd, &cardstate);
phungductung 0:e87aa4c49e95 833
phungductung 0:e87aa4c49e95 834 while ((errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
phungductung 0:e87aa4c49e95 835 {
phungductung 0:e87aa4c49e95 836 errorstate = SD_IsCardProgramming(hsd, &cardstate);
phungductung 0:e87aa4c49e95 837 }
phungductung 0:e87aa4c49e95 838
phungductung 0:e87aa4c49e95 839 return errorstate;
phungductung 0:e87aa4c49e95 840 }
phungductung 0:e87aa4c49e95 841
phungductung 0:e87aa4c49e95 842 /**
phungductung 0:e87aa4c49e95 843 * @brief Reads block(s) from a specified address in a card. The Data transfer
phungductung 0:e87aa4c49e95 844 * is managed by DMA mode.
phungductung 0:e87aa4c49e95 845 * @note This API should be followed by the function HAL_SD_CheckReadOperation()
phungductung 0:e87aa4c49e95 846 * to check the completion of the read process
phungductung 0:e87aa4c49e95 847 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 848 * @param pReadBuffer: Pointer to the buffer that will contain the received data
phungductung 0:e87aa4c49e95 849 * @param ReadAddr: Address from where data is to be read
phungductung 0:e87aa4c49e95 850 * @param BlockSize: SD card Data block size
phungductung 0:e87aa4c49e95 851 * @note BlockSize must be 512 bytes.
phungductung 0:e87aa4c49e95 852 * @param NumberOfBlocks: Number of blocks to read.
phungductung 0:e87aa4c49e95 853 * @retval SD Card error state
phungductung 0:e87aa4c49e95 854 */
phungductung 0:e87aa4c49e95 855 HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
phungductung 0:e87aa4c49e95 856 {
phungductung 0:e87aa4c49e95 857 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 858 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 859 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 860
phungductung 0:e87aa4c49e95 861 /* Initialize data control register */
phungductung 0:e87aa4c49e95 862 hsd->Instance->DCTRL = 0;
phungductung 0:e87aa4c49e95 863
phungductung 0:e87aa4c49e95 864 /* Initialize handle flags */
phungductung 0:e87aa4c49e95 865 hsd->SdTransferCplt = 0;
phungductung 0:e87aa4c49e95 866 hsd->DmaTransferCplt = 0;
phungductung 0:e87aa4c49e95 867 hsd->SdTransferErr = SD_OK;
phungductung 0:e87aa4c49e95 868
phungductung 0:e87aa4c49e95 869 /* Initialize SD Read operation */
phungductung 0:e87aa4c49e95 870 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 871 {
phungductung 0:e87aa4c49e95 872 hsd->SdOperation = SD_READ_MULTIPLE_BLOCK;
phungductung 0:e87aa4c49e95 873 }
phungductung 0:e87aa4c49e95 874 else
phungductung 0:e87aa4c49e95 875 {
phungductung 0:e87aa4c49e95 876 hsd->SdOperation = SD_READ_SINGLE_BLOCK;
phungductung 0:e87aa4c49e95 877 }
phungductung 0:e87aa4c49e95 878
phungductung 0:e87aa4c49e95 879 /* Enable transfer interrupts */
phungductung 0:e87aa4c49e95 880 __HAL_SD_SDMMC_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL |\
phungductung 0:e87aa4c49e95 881 SDMMC_IT_DTIMEOUT |\
phungductung 0:e87aa4c49e95 882 SDMMC_IT_DATAEND |\
phungductung 0:e87aa4c49e95 883 SDMMC_IT_RXOVERR));
phungductung 0:e87aa4c49e95 884
phungductung 0:e87aa4c49e95 885 /* Enable SDMMC DMA transfer */
phungductung 0:e87aa4c49e95 886 __HAL_SD_SDMMC_DMA_ENABLE(hsd);
phungductung 0:e87aa4c49e95 887
phungductung 0:e87aa4c49e95 888 /* Configure DMA user callbacks */
phungductung 0:e87aa4c49e95 889 hsd->hdmarx->XferCpltCallback = SD_DMA_RxCplt;
phungductung 0:e87aa4c49e95 890 hsd->hdmarx->XferErrorCallback = SD_DMA_RxError;
phungductung 0:e87aa4c49e95 891
phungductung 0:e87aa4c49e95 892 /* Enable the DMA Channel */
phungductung 0:e87aa4c49e95 893 HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks)/4);
phungductung 0:e87aa4c49e95 894
phungductung 0:e87aa4c49e95 895 if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
phungductung 0:e87aa4c49e95 896 {
phungductung 0:e87aa4c49e95 897 BlockSize = 512;
phungductung 0:e87aa4c49e95 898 ReadAddr /= 512;
phungductung 0:e87aa4c49e95 899 }
phungductung 0:e87aa4c49e95 900
phungductung 0:e87aa4c49e95 901 /* Set Block Size for Card */
phungductung 0:e87aa4c49e95 902 sdmmc_cmdinitstructure.Argument = (uint32_t)BlockSize;
phungductung 0:e87aa4c49e95 903 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 904 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 905 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 906 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 907 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 908
phungductung 0:e87aa4c49e95 909 /* Check for error conditions */
phungductung 0:e87aa4c49e95 910 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 911
phungductung 0:e87aa4c49e95 912 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 913 {
phungductung 0:e87aa4c49e95 914 return errorstate;
phungductung 0:e87aa4c49e95 915 }
phungductung 0:e87aa4c49e95 916
phungductung 0:e87aa4c49e95 917 /* Configure the SD DPSM (Data Path State Machine) */
phungductung 0:e87aa4c49e95 918 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 919 sdmmc_datainitstructure.DataLength = BlockSize * NumberOfBlocks;
phungductung 0:e87aa4c49e95 920 sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
phungductung 0:e87aa4c49e95 921 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
phungductung 0:e87aa4c49e95 922 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 923 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 924 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 925
phungductung 0:e87aa4c49e95 926 /* Check number of blocks command */
phungductung 0:e87aa4c49e95 927 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 928 {
phungductung 0:e87aa4c49e95 929 /* Send CMD18 READ_MULT_BLOCK with argument data address */
phungductung 0:e87aa4c49e95 930 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK;
phungductung 0:e87aa4c49e95 931 }
phungductung 0:e87aa4c49e95 932 else
phungductung 0:e87aa4c49e95 933 {
phungductung 0:e87aa4c49e95 934 /* Send CMD17 READ_SINGLE_BLOCK */
phungductung 0:e87aa4c49e95 935 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
phungductung 0:e87aa4c49e95 936 }
phungductung 0:e87aa4c49e95 937
phungductung 0:e87aa4c49e95 938 sdmmc_cmdinitstructure.Argument = (uint32_t)ReadAddr;
phungductung 0:e87aa4c49e95 939 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 940
phungductung 0:e87aa4c49e95 941 /* Check for error conditions */
phungductung 0:e87aa4c49e95 942 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 943 {
phungductung 0:e87aa4c49e95 944 errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK);
phungductung 0:e87aa4c49e95 945 }
phungductung 0:e87aa4c49e95 946 else
phungductung 0:e87aa4c49e95 947 {
phungductung 0:e87aa4c49e95 948 errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK);
phungductung 0:e87aa4c49e95 949 }
phungductung 0:e87aa4c49e95 950
phungductung 0:e87aa4c49e95 951 /* Update the SD transfer error in SD handle */
phungductung 0:e87aa4c49e95 952 hsd->SdTransferErr = errorstate;
phungductung 0:e87aa4c49e95 953
phungductung 0:e87aa4c49e95 954 return errorstate;
phungductung 0:e87aa4c49e95 955 }
phungductung 0:e87aa4c49e95 956
phungductung 0:e87aa4c49e95 957
phungductung 0:e87aa4c49e95 958 /**
phungductung 0:e87aa4c49e95 959 * @brief Writes block(s) to a specified address in a card. The Data transfer
phungductung 0:e87aa4c49e95 960 * is managed by DMA mode.
phungductung 0:e87aa4c49e95 961 * @note This API should be followed by the function HAL_SD_CheckWriteOperation()
phungductung 0:e87aa4c49e95 962 * to check the completion of the write process (by SD current status polling).
phungductung 0:e87aa4c49e95 963 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 964 * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit
phungductung 0:e87aa4c49e95 965 * @param WriteAddr: Address from where data is to be read
phungductung 0:e87aa4c49e95 966 * @param BlockSize: the SD card Data block size
phungductung 0:e87aa4c49e95 967 * @note BlockSize must be 512 bytes.
phungductung 0:e87aa4c49e95 968 * @param NumberOfBlocks: Number of blocks to write
phungductung 0:e87aa4c49e95 969 * @retval SD Card error state
phungductung 0:e87aa4c49e95 970 */
phungductung 0:e87aa4c49e95 971 HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
phungductung 0:e87aa4c49e95 972 {
phungductung 0:e87aa4c49e95 973 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 974 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 975 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 976
phungductung 0:e87aa4c49e95 977 /* Initialize data control register */
phungductung 0:e87aa4c49e95 978 hsd->Instance->DCTRL = 0;
phungductung 0:e87aa4c49e95 979
phungductung 0:e87aa4c49e95 980 /* Initialize handle flags */
phungductung 0:e87aa4c49e95 981 hsd->SdTransferCplt = 0;
phungductung 0:e87aa4c49e95 982 hsd->DmaTransferCplt = 0;
phungductung 0:e87aa4c49e95 983 hsd->SdTransferErr = SD_OK;
phungductung 0:e87aa4c49e95 984
phungductung 0:e87aa4c49e95 985 /* Initialize SD Write operation */
phungductung 0:e87aa4c49e95 986 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 987 {
phungductung 0:e87aa4c49e95 988 hsd->SdOperation = SD_WRITE_MULTIPLE_BLOCK;
phungductung 0:e87aa4c49e95 989 }
phungductung 0:e87aa4c49e95 990 else
phungductung 0:e87aa4c49e95 991 {
phungductung 0:e87aa4c49e95 992 hsd->SdOperation = SD_WRITE_SINGLE_BLOCK;
phungductung 0:e87aa4c49e95 993 }
phungductung 0:e87aa4c49e95 994
phungductung 0:e87aa4c49e95 995 /* Enable transfer interrupts */
phungductung 0:e87aa4c49e95 996 __HAL_SD_SDMMC_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL |\
phungductung 0:e87aa4c49e95 997 SDMMC_IT_DTIMEOUT |\
phungductung 0:e87aa4c49e95 998 SDMMC_IT_DATAEND |\
phungductung 0:e87aa4c49e95 999 SDMMC_IT_TXUNDERR));
phungductung 0:e87aa4c49e95 1000
phungductung 0:e87aa4c49e95 1001 /* Configure DMA user callbacks */
phungductung 0:e87aa4c49e95 1002 hsd->hdmatx->XferCpltCallback = SD_DMA_TxCplt;
phungductung 0:e87aa4c49e95 1003 hsd->hdmatx->XferErrorCallback = SD_DMA_TxError;
phungductung 0:e87aa4c49e95 1004
phungductung 0:e87aa4c49e95 1005 /* Enable the DMA Channel */
phungductung 0:e87aa4c49e95 1006 HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pWriteBuffer, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BlockSize * NumberOfBlocks)/4);
phungductung 0:e87aa4c49e95 1007
phungductung 0:e87aa4c49e95 1008 /* Enable SDMMC DMA transfer */
phungductung 0:e87aa4c49e95 1009 __HAL_SD_SDMMC_DMA_ENABLE(hsd);
phungductung 0:e87aa4c49e95 1010
phungductung 0:e87aa4c49e95 1011 if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
phungductung 0:e87aa4c49e95 1012 {
phungductung 0:e87aa4c49e95 1013 BlockSize = 512;
phungductung 0:e87aa4c49e95 1014 WriteAddr /= 512;
phungductung 0:e87aa4c49e95 1015 }
phungductung 0:e87aa4c49e95 1016
phungductung 0:e87aa4c49e95 1017 /* Set Block Size for Card */
phungductung 0:e87aa4c49e95 1018 sdmmc_cmdinitstructure.Argument = (uint32_t)BlockSize;
phungductung 0:e87aa4c49e95 1019 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 1020 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 1021 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 1022 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 1023 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1024
phungductung 0:e87aa4c49e95 1025 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1026 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 1027
phungductung 0:e87aa4c49e95 1028 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1029 {
phungductung 0:e87aa4c49e95 1030 return errorstate;
phungductung 0:e87aa4c49e95 1031 }
phungductung 0:e87aa4c49e95 1032
phungductung 0:e87aa4c49e95 1033 /* Check number of blocks command */
phungductung 0:e87aa4c49e95 1034 if(NumberOfBlocks <= 1)
phungductung 0:e87aa4c49e95 1035 {
phungductung 0:e87aa4c49e95 1036 /* Send CMD24 WRITE_SINGLE_BLOCK */
phungductung 0:e87aa4c49e95 1037 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
phungductung 0:e87aa4c49e95 1038 }
phungductung 0:e87aa4c49e95 1039 else
phungductung 0:e87aa4c49e95 1040 {
phungductung 0:e87aa4c49e95 1041 /* Send CMD25 WRITE_MULT_BLOCK with argument data address */
phungductung 0:e87aa4c49e95 1042 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
phungductung 0:e87aa4c49e95 1043 }
phungductung 0:e87aa4c49e95 1044
phungductung 0:e87aa4c49e95 1045 sdmmc_cmdinitstructure.Argument = (uint32_t)WriteAddr;
phungductung 0:e87aa4c49e95 1046 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1047
phungductung 0:e87aa4c49e95 1048 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1049 if(NumberOfBlocks > 1)
phungductung 0:e87aa4c49e95 1050 {
phungductung 0:e87aa4c49e95 1051 errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK);
phungductung 0:e87aa4c49e95 1052 }
phungductung 0:e87aa4c49e95 1053 else
phungductung 0:e87aa4c49e95 1054 {
phungductung 0:e87aa4c49e95 1055 errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK);
phungductung 0:e87aa4c49e95 1056 }
phungductung 0:e87aa4c49e95 1057
phungductung 0:e87aa4c49e95 1058 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1059 {
phungductung 0:e87aa4c49e95 1060 return errorstate;
phungductung 0:e87aa4c49e95 1061 }
phungductung 0:e87aa4c49e95 1062
phungductung 0:e87aa4c49e95 1063 /* Configure the SD DPSM (Data Path State Machine) */
phungductung 0:e87aa4c49e95 1064 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 1065 sdmmc_datainitstructure.DataLength = BlockSize * NumberOfBlocks;
phungductung 0:e87aa4c49e95 1066 sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
phungductung 0:e87aa4c49e95 1067 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
phungductung 0:e87aa4c49e95 1068 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 1069 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 1070 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 1071
phungductung 0:e87aa4c49e95 1072 hsd->SdTransferErr = errorstate;
phungductung 0:e87aa4c49e95 1073
phungductung 0:e87aa4c49e95 1074 return errorstate;
phungductung 0:e87aa4c49e95 1075 }
phungductung 0:e87aa4c49e95 1076
phungductung 0:e87aa4c49e95 1077 /**
phungductung 0:e87aa4c49e95 1078 * @brief This function waits until the SD DMA data read transfer is finished.
phungductung 0:e87aa4c49e95 1079 * This API should be called after HAL_SD_ReadBlocks_DMA() function
phungductung 0:e87aa4c49e95 1080 * to insure that all data sent by the card is already transferred by the
phungductung 0:e87aa4c49e95 1081 * DMA controller.
phungductung 0:e87aa4c49e95 1082 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1083 * @param Timeout: Timeout duration
phungductung 0:e87aa4c49e95 1084 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1085 */
phungductung 0:e87aa4c49e95 1086 HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)
phungductung 0:e87aa4c49e95 1087 {
phungductung 0:e87aa4c49e95 1088 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1089 uint32_t timeout = Timeout;
phungductung 0:e87aa4c49e95 1090 uint32_t tmp1, tmp2;
phungductung 0:e87aa4c49e95 1091 HAL_SD_ErrorTypedef tmp3;
phungductung 0:e87aa4c49e95 1092
phungductung 0:e87aa4c49e95 1093 /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */
phungductung 0:e87aa4c49e95 1094 tmp1 = hsd->DmaTransferCplt;
phungductung 0:e87aa4c49e95 1095 tmp2 = hsd->SdTransferCplt;
phungductung 0:e87aa4c49e95 1096 tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
phungductung 0:e87aa4c49e95 1097
phungductung 0:e87aa4c49e95 1098 while (((tmp1 & tmp2) == 0) && (tmp3 == SD_OK) && (timeout > 0))
phungductung 0:e87aa4c49e95 1099 {
phungductung 0:e87aa4c49e95 1100 tmp1 = hsd->DmaTransferCplt;
phungductung 0:e87aa4c49e95 1101 tmp2 = hsd->SdTransferCplt;
phungductung 0:e87aa4c49e95 1102 tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
phungductung 0:e87aa4c49e95 1103 timeout--;
phungductung 0:e87aa4c49e95 1104 }
phungductung 0:e87aa4c49e95 1105
phungductung 0:e87aa4c49e95 1106 timeout = Timeout;
phungductung 0:e87aa4c49e95 1107
phungductung 0:e87aa4c49e95 1108 /* Wait until the Rx transfer is no longer active */
phungductung 0:e87aa4c49e95 1109 while((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXACT)) && (timeout > 0))
phungductung 0:e87aa4c49e95 1110 {
phungductung 0:e87aa4c49e95 1111 timeout--;
phungductung 0:e87aa4c49e95 1112 }
phungductung 0:e87aa4c49e95 1113
phungductung 0:e87aa4c49e95 1114 /* Send stop command in multiblock read */
phungductung 0:e87aa4c49e95 1115 if (hsd->SdOperation == SD_READ_MULTIPLE_BLOCK)
phungductung 0:e87aa4c49e95 1116 {
phungductung 0:e87aa4c49e95 1117 errorstate = HAL_SD_StopTransfer(hsd);
phungductung 0:e87aa4c49e95 1118 }
phungductung 0:e87aa4c49e95 1119
phungductung 0:e87aa4c49e95 1120 if ((timeout == 0) && (errorstate == SD_OK))
phungductung 0:e87aa4c49e95 1121 {
phungductung 0:e87aa4c49e95 1122 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 1123 }
phungductung 0:e87aa4c49e95 1124
phungductung 0:e87aa4c49e95 1125 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 1126 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 1127
phungductung 0:e87aa4c49e95 1128 /* Return error state */
phungductung 0:e87aa4c49e95 1129 if (hsd->SdTransferErr != SD_OK)
phungductung 0:e87aa4c49e95 1130 {
phungductung 0:e87aa4c49e95 1131 return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);
phungductung 0:e87aa4c49e95 1132 }
phungductung 0:e87aa4c49e95 1133
phungductung 0:e87aa4c49e95 1134 return errorstate;
phungductung 0:e87aa4c49e95 1135 }
phungductung 0:e87aa4c49e95 1136
phungductung 0:e87aa4c49e95 1137 /**
phungductung 0:e87aa4c49e95 1138 * @brief This function waits until the SD DMA data write transfer is finished.
phungductung 0:e87aa4c49e95 1139 * This API should be called after HAL_SD_WriteBlocks_DMA() function
phungductung 0:e87aa4c49e95 1140 * to insure that all data sent by the card is already transferred by the
phungductung 0:e87aa4c49e95 1141 * DMA controller.
phungductung 0:e87aa4c49e95 1142 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1143 * @param Timeout: Timeout duration
phungductung 0:e87aa4c49e95 1144 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1145 */
phungductung 0:e87aa4c49e95 1146 HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout)
phungductung 0:e87aa4c49e95 1147 {
phungductung 0:e87aa4c49e95 1148 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1149 uint32_t timeout = Timeout;
phungductung 0:e87aa4c49e95 1150 uint32_t tmp1, tmp2;
phungductung 0:e87aa4c49e95 1151 HAL_SD_ErrorTypedef tmp3;
phungductung 0:e87aa4c49e95 1152
phungductung 0:e87aa4c49e95 1153 /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */
phungductung 0:e87aa4c49e95 1154 tmp1 = hsd->DmaTransferCplt;
phungductung 0:e87aa4c49e95 1155 tmp2 = hsd->SdTransferCplt;
phungductung 0:e87aa4c49e95 1156 tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
phungductung 0:e87aa4c49e95 1157
phungductung 0:e87aa4c49e95 1158 while (((tmp1 & tmp2) == 0) && (tmp3 == SD_OK) && (timeout > 0))
phungductung 0:e87aa4c49e95 1159 {
phungductung 0:e87aa4c49e95 1160 tmp1 = hsd->DmaTransferCplt;
phungductung 0:e87aa4c49e95 1161 tmp2 = hsd->SdTransferCplt;
phungductung 0:e87aa4c49e95 1162 tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
phungductung 0:e87aa4c49e95 1163 timeout--;
phungductung 0:e87aa4c49e95 1164 }
phungductung 0:e87aa4c49e95 1165
phungductung 0:e87aa4c49e95 1166 timeout = Timeout;
phungductung 0:e87aa4c49e95 1167
phungductung 0:e87aa4c49e95 1168 /* Wait until the Tx transfer is no longer active */
phungductung 0:e87aa4c49e95 1169 while((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_TXACT)) && (timeout > 0))
phungductung 0:e87aa4c49e95 1170 {
phungductung 0:e87aa4c49e95 1171 timeout--;
phungductung 0:e87aa4c49e95 1172 }
phungductung 0:e87aa4c49e95 1173
phungductung 0:e87aa4c49e95 1174 /* Send stop command in multiblock write */
phungductung 0:e87aa4c49e95 1175 if (hsd->SdOperation == SD_WRITE_MULTIPLE_BLOCK)
phungductung 0:e87aa4c49e95 1176 {
phungductung 0:e87aa4c49e95 1177 errorstate = HAL_SD_StopTransfer(hsd);
phungductung 0:e87aa4c49e95 1178 }
phungductung 0:e87aa4c49e95 1179
phungductung 0:e87aa4c49e95 1180 if ((timeout == 0) && (errorstate == SD_OK))
phungductung 0:e87aa4c49e95 1181 {
phungductung 0:e87aa4c49e95 1182 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 1183 }
phungductung 0:e87aa4c49e95 1184
phungductung 0:e87aa4c49e95 1185 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 1186 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 1187
phungductung 0:e87aa4c49e95 1188 /* Return error state */
phungductung 0:e87aa4c49e95 1189 if (hsd->SdTransferErr != SD_OK)
phungductung 0:e87aa4c49e95 1190 {
phungductung 0:e87aa4c49e95 1191 return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);
phungductung 0:e87aa4c49e95 1192 }
phungductung 0:e87aa4c49e95 1193
phungductung 0:e87aa4c49e95 1194 /* Wait until write is complete */
phungductung 0:e87aa4c49e95 1195 while(HAL_SD_GetStatus(hsd) != SD_TRANSFER_OK)
phungductung 0:e87aa4c49e95 1196 {
phungductung 0:e87aa4c49e95 1197 }
phungductung 0:e87aa4c49e95 1198
phungductung 0:e87aa4c49e95 1199 return errorstate;
phungductung 0:e87aa4c49e95 1200 }
phungductung 0:e87aa4c49e95 1201
phungductung 0:e87aa4c49e95 1202 /**
phungductung 0:e87aa4c49e95 1203 * @brief Erases the specified memory area of the given SD card.
phungductung 0:e87aa4c49e95 1204 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1205 * @param startaddr: Start byte address
phungductung 0:e87aa4c49e95 1206 * @param endaddr: End byte address
phungductung 0:e87aa4c49e95 1207 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1208 */
phungductung 0:e87aa4c49e95 1209 HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr)
phungductung 0:e87aa4c49e95 1210 {
phungductung 0:e87aa4c49e95 1211 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1212 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 1213
phungductung 0:e87aa4c49e95 1214 uint32_t delay = 0;
phungductung 0:e87aa4c49e95 1215 __IO uint32_t maxdelay = 0;
phungductung 0:e87aa4c49e95 1216 uint8_t cardstate = 0;
phungductung 0:e87aa4c49e95 1217
phungductung 0:e87aa4c49e95 1218 /* Check if the card command class supports erase command */
phungductung 0:e87aa4c49e95 1219 if (((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0)
phungductung 0:e87aa4c49e95 1220 {
phungductung 0:e87aa4c49e95 1221 errorstate = SD_REQUEST_NOT_APPLICABLE;
phungductung 0:e87aa4c49e95 1222
phungductung 0:e87aa4c49e95 1223 return errorstate;
phungductung 0:e87aa4c49e95 1224 }
phungductung 0:e87aa4c49e95 1225
phungductung 0:e87aa4c49e95 1226 /* Get max delay value */
phungductung 0:e87aa4c49e95 1227 maxdelay = 120000 / (((hsd->Instance->CLKCR) & 0xFF) + 2);
phungductung 0:e87aa4c49e95 1228
phungductung 0:e87aa4c49e95 1229 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
phungductung 0:e87aa4c49e95 1230 {
phungductung 0:e87aa4c49e95 1231 errorstate = SD_LOCK_UNLOCK_FAILED;
phungductung 0:e87aa4c49e95 1232
phungductung 0:e87aa4c49e95 1233 return errorstate;
phungductung 0:e87aa4c49e95 1234 }
phungductung 0:e87aa4c49e95 1235
phungductung 0:e87aa4c49e95 1236 /* Get start and end block for high capacity cards */
phungductung 0:e87aa4c49e95 1237 if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
phungductung 0:e87aa4c49e95 1238 {
phungductung 0:e87aa4c49e95 1239 startaddr /= 512;
phungductung 0:e87aa4c49e95 1240 endaddr /= 512;
phungductung 0:e87aa4c49e95 1241 }
phungductung 0:e87aa4c49e95 1242
phungductung 0:e87aa4c49e95 1243 /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
phungductung 0:e87aa4c49e95 1244 if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
phungductung 0:e87aa4c49e95 1245 (hsd->CardType == HIGH_CAPACITY_SD_CARD))
phungductung 0:e87aa4c49e95 1246 {
phungductung 0:e87aa4c49e95 1247 /* Send CMD32 SD_ERASE_GRP_START with argument as addr */
phungductung 0:e87aa4c49e95 1248 sdmmc_cmdinitstructure.Argument =(uint32_t)startaddr;
phungductung 0:e87aa4c49e95 1249 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SD_ERASE_GRP_START;
phungductung 0:e87aa4c49e95 1250 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 1251 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 1252 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 1253 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1254
phungductung 0:e87aa4c49e95 1255 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1256 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_START);
phungductung 0:e87aa4c49e95 1257
phungductung 0:e87aa4c49e95 1258 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1259 {
phungductung 0:e87aa4c49e95 1260 return errorstate;
phungductung 0:e87aa4c49e95 1261 }
phungductung 0:e87aa4c49e95 1262
phungductung 0:e87aa4c49e95 1263 /* Send CMD33 SD_ERASE_GRP_END with argument as addr */
phungductung 0:e87aa4c49e95 1264 sdmmc_cmdinitstructure.Argument = (uint32_t)endaddr;
phungductung 0:e87aa4c49e95 1265 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SD_ERASE_GRP_END;
phungductung 0:e87aa4c49e95 1266 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1267
phungductung 0:e87aa4c49e95 1268 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1269 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_END);
phungductung 0:e87aa4c49e95 1270
phungductung 0:e87aa4c49e95 1271 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1272 {
phungductung 0:e87aa4c49e95 1273 return errorstate;
phungductung 0:e87aa4c49e95 1274 }
phungductung 0:e87aa4c49e95 1275 }
phungductung 0:e87aa4c49e95 1276
phungductung 0:e87aa4c49e95 1277 /* Send CMD38 ERASE */
phungductung 0:e87aa4c49e95 1278 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 1279 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_ERASE;
phungductung 0:e87aa4c49e95 1280 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1281
phungductung 0:e87aa4c49e95 1282 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1283 errorstate = SD_CmdResp1Error(hsd, SD_CMD_ERASE);
phungductung 0:e87aa4c49e95 1284
phungductung 0:e87aa4c49e95 1285 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1286 {
phungductung 0:e87aa4c49e95 1287 return errorstate;
phungductung 0:e87aa4c49e95 1288 }
phungductung 0:e87aa4c49e95 1289
phungductung 0:e87aa4c49e95 1290 for (; delay < maxdelay; delay++)
phungductung 0:e87aa4c49e95 1291 {
phungductung 0:e87aa4c49e95 1292 }
phungductung 0:e87aa4c49e95 1293
phungductung 0:e87aa4c49e95 1294 /* Wait until the card is in programming state */
phungductung 0:e87aa4c49e95 1295 errorstate = SD_IsCardProgramming(hsd, &cardstate);
phungductung 0:e87aa4c49e95 1296
phungductung 0:e87aa4c49e95 1297 delay = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 1298
phungductung 0:e87aa4c49e95 1299 while ((delay > 0) && (errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
phungductung 0:e87aa4c49e95 1300 {
phungductung 0:e87aa4c49e95 1301 errorstate = SD_IsCardProgramming(hsd, &cardstate);
phungductung 0:e87aa4c49e95 1302 delay--;
phungductung 0:e87aa4c49e95 1303 }
phungductung 0:e87aa4c49e95 1304
phungductung 0:e87aa4c49e95 1305 return errorstate;
phungductung 0:e87aa4c49e95 1306 }
phungductung 0:e87aa4c49e95 1307
phungductung 0:e87aa4c49e95 1308 /**
phungductung 0:e87aa4c49e95 1309 * @brief This function handles SD card interrupt request.
phungductung 0:e87aa4c49e95 1310 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1311 * @retval None
phungductung 0:e87aa4c49e95 1312 */
phungductung 0:e87aa4c49e95 1313 void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 1314 {
phungductung 0:e87aa4c49e95 1315 /* Check for SDMMC interrupt flags */
phungductung 0:e87aa4c49e95 1316 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_DATAEND))
phungductung 0:e87aa4c49e95 1317 {
phungductung 0:e87aa4c49e95 1318 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_IT_DATAEND);
phungductung 0:e87aa4c49e95 1319
phungductung 0:e87aa4c49e95 1320 /* SD transfer is complete */
phungductung 0:e87aa4c49e95 1321 hsd->SdTransferCplt = 1;
phungductung 0:e87aa4c49e95 1322
phungductung 0:e87aa4c49e95 1323 /* No transfer error */
phungductung 0:e87aa4c49e95 1324 hsd->SdTransferErr = SD_OK;
phungductung 0:e87aa4c49e95 1325
phungductung 0:e87aa4c49e95 1326 HAL_SD_XferCpltCallback(hsd);
phungductung 0:e87aa4c49e95 1327 }
phungductung 0:e87aa4c49e95 1328 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_DCRCFAIL))
phungductung 0:e87aa4c49e95 1329 {
phungductung 0:e87aa4c49e95 1330 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);
phungductung 0:e87aa4c49e95 1331
phungductung 0:e87aa4c49e95 1332 hsd->SdTransferErr = SD_DATA_CRC_FAIL;
phungductung 0:e87aa4c49e95 1333
phungductung 0:e87aa4c49e95 1334 HAL_SD_XferErrorCallback(hsd);
phungductung 0:e87aa4c49e95 1335
phungductung 0:e87aa4c49e95 1336 }
phungductung 0:e87aa4c49e95 1337 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_DTIMEOUT))
phungductung 0:e87aa4c49e95 1338 {
phungductung 0:e87aa4c49e95 1339 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);
phungductung 0:e87aa4c49e95 1340
phungductung 0:e87aa4c49e95 1341 hsd->SdTransferErr = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 1342
phungductung 0:e87aa4c49e95 1343 HAL_SD_XferErrorCallback(hsd);
phungductung 0:e87aa4c49e95 1344 }
phungductung 0:e87aa4c49e95 1345 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_RXOVERR))
phungductung 0:e87aa4c49e95 1346 {
phungductung 0:e87aa4c49e95 1347 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);
phungductung 0:e87aa4c49e95 1348
phungductung 0:e87aa4c49e95 1349 hsd->SdTransferErr = SD_RX_OVERRUN;
phungductung 0:e87aa4c49e95 1350
phungductung 0:e87aa4c49e95 1351 HAL_SD_XferErrorCallback(hsd);
phungductung 0:e87aa4c49e95 1352 }
phungductung 0:e87aa4c49e95 1353 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_IT_TXUNDERR))
phungductung 0:e87aa4c49e95 1354 {
phungductung 0:e87aa4c49e95 1355 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_TXUNDERR);
phungductung 0:e87aa4c49e95 1356
phungductung 0:e87aa4c49e95 1357 hsd->SdTransferErr = SD_TX_UNDERRUN;
phungductung 0:e87aa4c49e95 1358
phungductung 0:e87aa4c49e95 1359 HAL_SD_XferErrorCallback(hsd);
phungductung 0:e87aa4c49e95 1360 }
phungductung 0:e87aa4c49e95 1361 else
phungductung 0:e87aa4c49e95 1362 {
phungductung 0:e87aa4c49e95 1363 /* No error flag set */
phungductung 0:e87aa4c49e95 1364 }
phungductung 0:e87aa4c49e95 1365
phungductung 0:e87aa4c49e95 1366 /* Disable all SDMMC peripheral interrupt sources */
phungductung 0:e87aa4c49e95 1367 __HAL_SD_SDMMC_DISABLE_IT(hsd, SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_DATAEND |\
phungductung 0:e87aa4c49e95 1368 SDMMC_IT_TXFIFOHE | SDMMC_IT_RXFIFOHF | SDMMC_IT_TXUNDERR |\
phungductung 0:e87aa4c49e95 1369 SDMMC_IT_RXOVERR);
phungductung 0:e87aa4c49e95 1370 }
phungductung 0:e87aa4c49e95 1371
phungductung 0:e87aa4c49e95 1372
phungductung 0:e87aa4c49e95 1373 /**
phungductung 0:e87aa4c49e95 1374 * @brief SD end of transfer callback.
phungductung 0:e87aa4c49e95 1375 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1376 * @retval None
phungductung 0:e87aa4c49e95 1377 */
phungductung 0:e87aa4c49e95 1378 __weak void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 1379 {
phungductung 0:e87aa4c49e95 1380 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 1381 UNUSED(hsd);
phungductung 0:e87aa4c49e95 1382
phungductung 0:e87aa4c49e95 1383 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 1384 the HAL_SD_XferCpltCallback could be implemented in the user file
phungductung 0:e87aa4c49e95 1385 */
phungductung 0:e87aa4c49e95 1386 }
phungductung 0:e87aa4c49e95 1387
phungductung 0:e87aa4c49e95 1388 /**
phungductung 0:e87aa4c49e95 1389 * @brief SD Transfer Error callback.
phungductung 0:e87aa4c49e95 1390 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1391 * @retval None
phungductung 0:e87aa4c49e95 1392 */
phungductung 0:e87aa4c49e95 1393 __weak void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 1394 {
phungductung 0:e87aa4c49e95 1395 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 1396 UNUSED(hsd);
phungductung 0:e87aa4c49e95 1397
phungductung 0:e87aa4c49e95 1398 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 1399 the HAL_SD_XferErrorCallback could be implemented in the user file
phungductung 0:e87aa4c49e95 1400 */
phungductung 0:e87aa4c49e95 1401 }
phungductung 0:e87aa4c49e95 1402
phungductung 0:e87aa4c49e95 1403 /**
phungductung 0:e87aa4c49e95 1404 * @brief SD Transfer complete Rx callback in non blocking mode.
phungductung 0:e87aa4c49e95 1405 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 1406 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 1407 * @retval None
phungductung 0:e87aa4c49e95 1408 */
phungductung 0:e87aa4c49e95 1409 __weak void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 1410 {
phungductung 0:e87aa4c49e95 1411 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 1412 UNUSED(hdma);
phungductung 0:e87aa4c49e95 1413
phungductung 0:e87aa4c49e95 1414 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 1415 the HAL_SD_DMA_RxCpltCallback could be implemented in the user file
phungductung 0:e87aa4c49e95 1416 */
phungductung 0:e87aa4c49e95 1417 }
phungductung 0:e87aa4c49e95 1418
phungductung 0:e87aa4c49e95 1419 /**
phungductung 0:e87aa4c49e95 1420 * @brief SD DMA transfer complete Rx error callback.
phungductung 0:e87aa4c49e95 1421 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 1422 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 1423 * @retval None
phungductung 0:e87aa4c49e95 1424 */
phungductung 0:e87aa4c49e95 1425 __weak void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 1426 {
phungductung 0:e87aa4c49e95 1427 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 1428 UNUSED(hdma);
phungductung 0:e87aa4c49e95 1429
phungductung 0:e87aa4c49e95 1430 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 1431 the HAL_SD_DMA_RxErrorCallback could be implemented in the user file
phungductung 0:e87aa4c49e95 1432 */
phungductung 0:e87aa4c49e95 1433 }
phungductung 0:e87aa4c49e95 1434
phungductung 0:e87aa4c49e95 1435 /**
phungductung 0:e87aa4c49e95 1436 * @brief SD Transfer complete Tx callback in non blocking mode.
phungductung 0:e87aa4c49e95 1437 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 1438 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 1439 * @retval None
phungductung 0:e87aa4c49e95 1440 */
phungductung 0:e87aa4c49e95 1441 __weak void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 1442 {
phungductung 0:e87aa4c49e95 1443 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 1444 UNUSED(hdma);
phungductung 0:e87aa4c49e95 1445
phungductung 0:e87aa4c49e95 1446 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 1447 the HAL_SD_DMA_TxCpltCallback could be implemented in the user file
phungductung 0:e87aa4c49e95 1448 */
phungductung 0:e87aa4c49e95 1449 }
phungductung 0:e87aa4c49e95 1450
phungductung 0:e87aa4c49e95 1451 /**
phungductung 0:e87aa4c49e95 1452 * @brief SD DMA transfer complete error Tx callback.
phungductung 0:e87aa4c49e95 1453 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 1454 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 1455 * @retval None
phungductung 0:e87aa4c49e95 1456 */
phungductung 0:e87aa4c49e95 1457 __weak void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 1458 {
phungductung 0:e87aa4c49e95 1459 /* Prevent unused argument(s) compilation warning */
phungductung 0:e87aa4c49e95 1460 UNUSED(hdma);
phungductung 0:e87aa4c49e95 1461
phungductung 0:e87aa4c49e95 1462 /* NOTE : This function Should not be modified, when the callback is needed,
phungductung 0:e87aa4c49e95 1463 the HAL_SD_DMA_TxErrorCallback could be implemented in the user file
phungductung 0:e87aa4c49e95 1464 */
phungductung 0:e87aa4c49e95 1465 }
phungductung 0:e87aa4c49e95 1466
phungductung 0:e87aa4c49e95 1467 /**
phungductung 0:e87aa4c49e95 1468 * @}
phungductung 0:e87aa4c49e95 1469 */
phungductung 0:e87aa4c49e95 1470
phungductung 0:e87aa4c49e95 1471 /** @addtogroup SD_Exported_Functions_Group3
phungductung 0:e87aa4c49e95 1472 * @brief management functions
phungductung 0:e87aa4c49e95 1473 *
phungductung 0:e87aa4c49e95 1474 @verbatim
phungductung 0:e87aa4c49e95 1475 ==============================================================================
phungductung 0:e87aa4c49e95 1476 ##### Peripheral Control functions #####
phungductung 0:e87aa4c49e95 1477 ==============================================================================
phungductung 0:e87aa4c49e95 1478 [..]
phungductung 0:e87aa4c49e95 1479 This subsection provides a set of functions allowing to control the SD card
phungductung 0:e87aa4c49e95 1480 operations.
phungductung 0:e87aa4c49e95 1481
phungductung 0:e87aa4c49e95 1482 @endverbatim
phungductung 0:e87aa4c49e95 1483 * @{
phungductung 0:e87aa4c49e95 1484 */
phungductung 0:e87aa4c49e95 1485
phungductung 0:e87aa4c49e95 1486 /**
phungductung 0:e87aa4c49e95 1487 * @brief Returns information about specific card.
phungductung 0:e87aa4c49e95 1488 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1489 * @param pCardInfo: Pointer to a HAL_SD_CardInfoTypedef structure that
phungductung 0:e87aa4c49e95 1490 * contains all SD cardinformation
phungductung 0:e87aa4c49e95 1491 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1492 */
phungductung 0:e87aa4c49e95 1493 HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo)
phungductung 0:e87aa4c49e95 1494 {
phungductung 0:e87aa4c49e95 1495 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1496 uint32_t tmp = 0;
phungductung 0:e87aa4c49e95 1497
phungductung 0:e87aa4c49e95 1498 pCardInfo->CardType = (uint8_t)(hsd->CardType);
phungductung 0:e87aa4c49e95 1499 pCardInfo->RCA = (uint16_t)(hsd->RCA);
phungductung 0:e87aa4c49e95 1500
phungductung 0:e87aa4c49e95 1501 /* Byte 0 */
phungductung 0:e87aa4c49e95 1502 tmp = (hsd->CSD[0] & 0xFF000000) >> 24;
phungductung 0:e87aa4c49e95 1503 pCardInfo->SD_csd.CSDStruct = (uint8_t)((tmp & 0xC0) >> 6);
phungductung 0:e87aa4c49e95 1504 pCardInfo->SD_csd.SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2);
phungductung 0:e87aa4c49e95 1505 pCardInfo->SD_csd.Reserved1 = tmp & 0x03;
phungductung 0:e87aa4c49e95 1506
phungductung 0:e87aa4c49e95 1507 /* Byte 1 */
phungductung 0:e87aa4c49e95 1508 tmp = (hsd->CSD[0] & 0x00FF0000) >> 16;
phungductung 0:e87aa4c49e95 1509 pCardInfo->SD_csd.TAAC = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 1510
phungductung 0:e87aa4c49e95 1511 /* Byte 2 */
phungductung 0:e87aa4c49e95 1512 tmp = (hsd->CSD[0] & 0x0000FF00) >> 8;
phungductung 0:e87aa4c49e95 1513 pCardInfo->SD_csd.NSAC = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 1514
phungductung 0:e87aa4c49e95 1515 /* Byte 3 */
phungductung 0:e87aa4c49e95 1516 tmp = hsd->CSD[0] & 0x000000FF;
phungductung 0:e87aa4c49e95 1517 pCardInfo->SD_csd.MaxBusClkFrec = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 1518
phungductung 0:e87aa4c49e95 1519 /* Byte 4 */
phungductung 0:e87aa4c49e95 1520 tmp = (hsd->CSD[1] & 0xFF000000) >> 24;
phungductung 0:e87aa4c49e95 1521 pCardInfo->SD_csd.CardComdClasses = (uint16_t)(tmp << 4);
phungductung 0:e87aa4c49e95 1522
phungductung 0:e87aa4c49e95 1523 /* Byte 5 */
phungductung 0:e87aa4c49e95 1524 tmp = (hsd->CSD[1] & 0x00FF0000) >> 16;
phungductung 0:e87aa4c49e95 1525 pCardInfo->SD_csd.CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4);
phungductung 0:e87aa4c49e95 1526 pCardInfo->SD_csd.RdBlockLen = (uint8_t)(tmp & 0x0F);
phungductung 0:e87aa4c49e95 1527
phungductung 0:e87aa4c49e95 1528 /* Byte 6 */
phungductung 0:e87aa4c49e95 1529 tmp = (hsd->CSD[1] & 0x0000FF00) >> 8;
phungductung 0:e87aa4c49e95 1530 pCardInfo->SD_csd.PartBlockRead = (uint8_t)((tmp & 0x80) >> 7);
phungductung 0:e87aa4c49e95 1531 pCardInfo->SD_csd.WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6);
phungductung 0:e87aa4c49e95 1532 pCardInfo->SD_csd.RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5);
phungductung 0:e87aa4c49e95 1533 pCardInfo->SD_csd.DSRImpl = (uint8_t)((tmp & 0x10) >> 4);
phungductung 0:e87aa4c49e95 1534 pCardInfo->SD_csd.Reserved2 = 0; /*!< Reserved */
phungductung 0:e87aa4c49e95 1535
phungductung 0:e87aa4c49e95 1536 if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0))
phungductung 0:e87aa4c49e95 1537 {
phungductung 0:e87aa4c49e95 1538 pCardInfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;
phungductung 0:e87aa4c49e95 1539
phungductung 0:e87aa4c49e95 1540 /* Byte 7 */
phungductung 0:e87aa4c49e95 1541 tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);
phungductung 0:e87aa4c49e95 1542 pCardInfo->SD_csd.DeviceSize |= (tmp) << 2;
phungductung 0:e87aa4c49e95 1543
phungductung 0:e87aa4c49e95 1544 /* Byte 8 */
phungductung 0:e87aa4c49e95 1545 tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1546 pCardInfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;
phungductung 0:e87aa4c49e95 1547
phungductung 0:e87aa4c49e95 1548 pCardInfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;
phungductung 0:e87aa4c49e95 1549 pCardInfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);
phungductung 0:e87aa4c49e95 1550
phungductung 0:e87aa4c49e95 1551 /* Byte 9 */
phungductung 0:e87aa4c49e95 1552 tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1553 pCardInfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
phungductung 0:e87aa4c49e95 1554 pCardInfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
phungductung 0:e87aa4c49e95 1555 pCardInfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;
phungductung 0:e87aa4c49e95 1556 /* Byte 10 */
phungductung 0:e87aa4c49e95 1557 tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);
phungductung 0:e87aa4c49e95 1558 pCardInfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;
phungductung 0:e87aa4c49e95 1559
phungductung 0:e87aa4c49e95 1560 pCardInfo->CardCapacity = (pCardInfo->SD_csd.DeviceSize + 1) ;
phungductung 0:e87aa4c49e95 1561 pCardInfo->CardCapacity *= (1 << (pCardInfo->SD_csd.DeviceSizeMul + 2));
phungductung 0:e87aa4c49e95 1562 pCardInfo->CardBlockSize = 1 << (pCardInfo->SD_csd.RdBlockLen);
phungductung 0:e87aa4c49e95 1563 pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
phungductung 0:e87aa4c49e95 1564 }
phungductung 0:e87aa4c49e95 1565 else if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
phungductung 0:e87aa4c49e95 1566 {
phungductung 0:e87aa4c49e95 1567 /* Byte 7 */
phungductung 0:e87aa4c49e95 1568 tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF);
phungductung 0:e87aa4c49e95 1569 pCardInfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16;
phungductung 0:e87aa4c49e95 1570
phungductung 0:e87aa4c49e95 1571 /* Byte 8 */
phungductung 0:e87aa4c49e95 1572 tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1573
phungductung 0:e87aa4c49e95 1574 pCardInfo->SD_csd.DeviceSize |= (tmp << 8);
phungductung 0:e87aa4c49e95 1575
phungductung 0:e87aa4c49e95 1576 /* Byte 9 */
phungductung 0:e87aa4c49e95 1577 tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1578
phungductung 0:e87aa4c49e95 1579 pCardInfo->SD_csd.DeviceSize |= (tmp);
phungductung 0:e87aa4c49e95 1580
phungductung 0:e87aa4c49e95 1581 /* Byte 10 */
phungductung 0:e87aa4c49e95 1582 tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8);
phungductung 0:e87aa4c49e95 1583
phungductung 0:e87aa4c49e95 1584 pCardInfo->CardCapacity = (uint64_t)(((uint64_t)pCardInfo->SD_csd.DeviceSize + 1) * 512 * 1024);
phungductung 0:e87aa4c49e95 1585 pCardInfo->CardBlockSize = 512;
phungductung 0:e87aa4c49e95 1586 }
phungductung 0:e87aa4c49e95 1587 else
phungductung 0:e87aa4c49e95 1588 {
phungductung 0:e87aa4c49e95 1589 /* Not supported card type */
phungductung 0:e87aa4c49e95 1590 errorstate = SD_ERROR;
phungductung 0:e87aa4c49e95 1591 }
phungductung 0:e87aa4c49e95 1592
phungductung 0:e87aa4c49e95 1593 pCardInfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;
phungductung 0:e87aa4c49e95 1594 pCardInfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1;
phungductung 0:e87aa4c49e95 1595
phungductung 0:e87aa4c49e95 1596 /* Byte 11 */
phungductung 0:e87aa4c49e95 1597 tmp = (uint8_t)(hsd->CSD[2] & 0x000000FF);
phungductung 0:e87aa4c49e95 1598 pCardInfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7;
phungductung 0:e87aa4c49e95 1599 pCardInfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);
phungductung 0:e87aa4c49e95 1600
phungductung 0:e87aa4c49e95 1601 /* Byte 12 */
phungductung 0:e87aa4c49e95 1602 tmp = (uint8_t)((hsd->CSD[3] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1603 pCardInfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;
phungductung 0:e87aa4c49e95 1604 pCardInfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5;
phungductung 0:e87aa4c49e95 1605 pCardInfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2;
phungductung 0:e87aa4c49e95 1606 pCardInfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2;
phungductung 0:e87aa4c49e95 1607
phungductung 0:e87aa4c49e95 1608 /* Byte 13 */
phungductung 0:e87aa4c49e95 1609 tmp = (uint8_t)((hsd->CSD[3] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1610 pCardInfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6;
phungductung 0:e87aa4c49e95 1611 pCardInfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;
phungductung 0:e87aa4c49e95 1612 pCardInfo->SD_csd.Reserved3 = 0;
phungductung 0:e87aa4c49e95 1613 pCardInfo->SD_csd.ContentProtectAppli = (tmp & 0x01);
phungductung 0:e87aa4c49e95 1614
phungductung 0:e87aa4c49e95 1615 /* Byte 14 */
phungductung 0:e87aa4c49e95 1616 tmp = (uint8_t)((hsd->CSD[3] & 0x0000FF00) >> 8);
phungductung 0:e87aa4c49e95 1617 pCardInfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;
phungductung 0:e87aa4c49e95 1618 pCardInfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6;
phungductung 0:e87aa4c49e95 1619 pCardInfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5;
phungductung 0:e87aa4c49e95 1620 pCardInfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4;
phungductung 0:e87aa4c49e95 1621 pCardInfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2;
phungductung 0:e87aa4c49e95 1622 pCardInfo->SD_csd.ECC = (tmp & 0x03);
phungductung 0:e87aa4c49e95 1623
phungductung 0:e87aa4c49e95 1624 /* Byte 15 */
phungductung 0:e87aa4c49e95 1625 tmp = (uint8_t)(hsd->CSD[3] & 0x000000FF);
phungductung 0:e87aa4c49e95 1626 pCardInfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1;
phungductung 0:e87aa4c49e95 1627 pCardInfo->SD_csd.Reserved4 = 1;
phungductung 0:e87aa4c49e95 1628
phungductung 0:e87aa4c49e95 1629 /* Byte 0 */
phungductung 0:e87aa4c49e95 1630 tmp = (uint8_t)((hsd->CID[0] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1631 pCardInfo->SD_cid.ManufacturerID = tmp;
phungductung 0:e87aa4c49e95 1632
phungductung 0:e87aa4c49e95 1633 /* Byte 1 */
phungductung 0:e87aa4c49e95 1634 tmp = (uint8_t)((hsd->CID[0] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1635 pCardInfo->SD_cid.OEM_AppliID = tmp << 8;
phungductung 0:e87aa4c49e95 1636
phungductung 0:e87aa4c49e95 1637 /* Byte 2 */
phungductung 0:e87aa4c49e95 1638 tmp = (uint8_t)((hsd->CID[0] & 0x000000FF00) >> 8);
phungductung 0:e87aa4c49e95 1639 pCardInfo->SD_cid.OEM_AppliID |= tmp;
phungductung 0:e87aa4c49e95 1640
phungductung 0:e87aa4c49e95 1641 /* Byte 3 */
phungductung 0:e87aa4c49e95 1642 tmp = (uint8_t)(hsd->CID[0] & 0x000000FF);
phungductung 0:e87aa4c49e95 1643 pCardInfo->SD_cid.ProdName1 = tmp << 24;
phungductung 0:e87aa4c49e95 1644
phungductung 0:e87aa4c49e95 1645 /* Byte 4 */
phungductung 0:e87aa4c49e95 1646 tmp = (uint8_t)((hsd->CID[1] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1647 pCardInfo->SD_cid.ProdName1 |= tmp << 16;
phungductung 0:e87aa4c49e95 1648
phungductung 0:e87aa4c49e95 1649 /* Byte 5 */
phungductung 0:e87aa4c49e95 1650 tmp = (uint8_t)((hsd->CID[1] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1651 pCardInfo->SD_cid.ProdName1 |= tmp << 8;
phungductung 0:e87aa4c49e95 1652
phungductung 0:e87aa4c49e95 1653 /* Byte 6 */
phungductung 0:e87aa4c49e95 1654 tmp = (uint8_t)((hsd->CID[1] & 0x0000FF00) >> 8);
phungductung 0:e87aa4c49e95 1655 pCardInfo->SD_cid.ProdName1 |= tmp;
phungductung 0:e87aa4c49e95 1656
phungductung 0:e87aa4c49e95 1657 /* Byte 7 */
phungductung 0:e87aa4c49e95 1658 tmp = (uint8_t)(hsd->CID[1] & 0x000000FF);
phungductung 0:e87aa4c49e95 1659 pCardInfo->SD_cid.ProdName2 = tmp;
phungductung 0:e87aa4c49e95 1660
phungductung 0:e87aa4c49e95 1661 /* Byte 8 */
phungductung 0:e87aa4c49e95 1662 tmp = (uint8_t)((hsd->CID[2] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1663 pCardInfo->SD_cid.ProdRev = tmp;
phungductung 0:e87aa4c49e95 1664
phungductung 0:e87aa4c49e95 1665 /* Byte 9 */
phungductung 0:e87aa4c49e95 1666 tmp = (uint8_t)((hsd->CID[2] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1667 pCardInfo->SD_cid.ProdSN = tmp << 24;
phungductung 0:e87aa4c49e95 1668
phungductung 0:e87aa4c49e95 1669 /* Byte 10 */
phungductung 0:e87aa4c49e95 1670 tmp = (uint8_t)((hsd->CID[2] & 0x0000FF00) >> 8);
phungductung 0:e87aa4c49e95 1671 pCardInfo->SD_cid.ProdSN |= tmp << 16;
phungductung 0:e87aa4c49e95 1672
phungductung 0:e87aa4c49e95 1673 /* Byte 11 */
phungductung 0:e87aa4c49e95 1674 tmp = (uint8_t)(hsd->CID[2] & 0x000000FF);
phungductung 0:e87aa4c49e95 1675 pCardInfo->SD_cid.ProdSN |= tmp << 8;
phungductung 0:e87aa4c49e95 1676
phungductung 0:e87aa4c49e95 1677 /* Byte 12 */
phungductung 0:e87aa4c49e95 1678 tmp = (uint8_t)((hsd->CID[3] & 0xFF000000) >> 24);
phungductung 0:e87aa4c49e95 1679 pCardInfo->SD_cid.ProdSN |= tmp;
phungductung 0:e87aa4c49e95 1680
phungductung 0:e87aa4c49e95 1681 /* Byte 13 */
phungductung 0:e87aa4c49e95 1682 tmp = (uint8_t)((hsd->CID[3] & 0x00FF0000) >> 16);
phungductung 0:e87aa4c49e95 1683 pCardInfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4;
phungductung 0:e87aa4c49e95 1684 pCardInfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;
phungductung 0:e87aa4c49e95 1685
phungductung 0:e87aa4c49e95 1686 /* Byte 14 */
phungductung 0:e87aa4c49e95 1687 tmp = (uint8_t)((hsd->CID[3] & 0x0000FF00) >> 8);
phungductung 0:e87aa4c49e95 1688 pCardInfo->SD_cid.ManufactDate |= tmp;
phungductung 0:e87aa4c49e95 1689
phungductung 0:e87aa4c49e95 1690 /* Byte 15 */
phungductung 0:e87aa4c49e95 1691 tmp = (uint8_t)(hsd->CID[3] & 0x000000FF);
phungductung 0:e87aa4c49e95 1692 pCardInfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1;
phungductung 0:e87aa4c49e95 1693 pCardInfo->SD_cid.Reserved2 = 1;
phungductung 0:e87aa4c49e95 1694
phungductung 0:e87aa4c49e95 1695 return errorstate;
phungductung 0:e87aa4c49e95 1696 }
phungductung 0:e87aa4c49e95 1697
phungductung 0:e87aa4c49e95 1698 /**
phungductung 0:e87aa4c49e95 1699 * @brief Enables wide bus operation for the requested card if supported by
phungductung 0:e87aa4c49e95 1700 * card.
phungductung 0:e87aa4c49e95 1701 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1702 * @param WideMode: Specifies the SD card wide bus mode
phungductung 0:e87aa4c49e95 1703 * This parameter can be one of the following values:
phungductung 0:e87aa4c49e95 1704 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer (Only for MMC)
phungductung 0:e87aa4c49e95 1705 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
phungductung 0:e87aa4c49e95 1706 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
phungductung 0:e87aa4c49e95 1707 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1708 */
phungductung 0:e87aa4c49e95 1709 HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode)
phungductung 0:e87aa4c49e95 1710 {
phungductung 0:e87aa4c49e95 1711 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1712 SDMMC_InitTypeDef tmpinit;
phungductung 0:e87aa4c49e95 1713
phungductung 0:e87aa4c49e95 1714 /* MMC Card does not support this feature */
phungductung 0:e87aa4c49e95 1715 if (hsd->CardType == MULTIMEDIA_CARD)
phungductung 0:e87aa4c49e95 1716 {
phungductung 0:e87aa4c49e95 1717 errorstate = SD_UNSUPPORTED_FEATURE;
phungductung 0:e87aa4c49e95 1718
phungductung 0:e87aa4c49e95 1719 return errorstate;
phungductung 0:e87aa4c49e95 1720 }
phungductung 0:e87aa4c49e95 1721 else if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
phungductung 0:e87aa4c49e95 1722 (hsd->CardType == HIGH_CAPACITY_SD_CARD))
phungductung 0:e87aa4c49e95 1723 {
phungductung 0:e87aa4c49e95 1724 if (WideMode == SDMMC_BUS_WIDE_8B)
phungductung 0:e87aa4c49e95 1725 {
phungductung 0:e87aa4c49e95 1726 errorstate = SD_UNSUPPORTED_FEATURE;
phungductung 0:e87aa4c49e95 1727 }
phungductung 0:e87aa4c49e95 1728 else if (WideMode == SDMMC_BUS_WIDE_4B)
phungductung 0:e87aa4c49e95 1729 {
phungductung 0:e87aa4c49e95 1730 errorstate = SD_WideBus_Enable(hsd);
phungductung 0:e87aa4c49e95 1731 }
phungductung 0:e87aa4c49e95 1732 else if (WideMode == SDMMC_BUS_WIDE_1B)
phungductung 0:e87aa4c49e95 1733 {
phungductung 0:e87aa4c49e95 1734 errorstate = SD_WideBus_Disable(hsd);
phungductung 0:e87aa4c49e95 1735 }
phungductung 0:e87aa4c49e95 1736 else
phungductung 0:e87aa4c49e95 1737 {
phungductung 0:e87aa4c49e95 1738 /* WideMode is not a valid argument*/
phungductung 0:e87aa4c49e95 1739 errorstate = SD_INVALID_PARAMETER;
phungductung 0:e87aa4c49e95 1740 }
phungductung 0:e87aa4c49e95 1741
phungductung 0:e87aa4c49e95 1742 if (errorstate == SD_OK)
phungductung 0:e87aa4c49e95 1743 {
phungductung 0:e87aa4c49e95 1744 /* Configure the SDMMC peripheral */
phungductung 0:e87aa4c49e95 1745 tmpinit.ClockEdge = hsd->Init.ClockEdge;
phungductung 0:e87aa4c49e95 1746 tmpinit.ClockBypass = hsd->Init.ClockBypass;
phungductung 0:e87aa4c49e95 1747 tmpinit.ClockPowerSave = hsd->Init.ClockPowerSave;
phungductung 0:e87aa4c49e95 1748 tmpinit.BusWide = WideMode;
phungductung 0:e87aa4c49e95 1749 tmpinit.HardwareFlowControl = hsd->Init.HardwareFlowControl;
phungductung 0:e87aa4c49e95 1750 tmpinit.ClockDiv = hsd->Init.ClockDiv;
phungductung 0:e87aa4c49e95 1751 SDMMC_Init(hsd->Instance, tmpinit);
phungductung 0:e87aa4c49e95 1752 }
phungductung 0:e87aa4c49e95 1753 }
phungductung 0:e87aa4c49e95 1754
phungductung 0:e87aa4c49e95 1755 return errorstate;
phungductung 0:e87aa4c49e95 1756 }
phungductung 0:e87aa4c49e95 1757
phungductung 0:e87aa4c49e95 1758 /**
phungductung 0:e87aa4c49e95 1759 * @brief Aborts an ongoing data transfer.
phungductung 0:e87aa4c49e95 1760 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1761 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1762 */
phungductung 0:e87aa4c49e95 1763 HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 1764 {
phungductung 0:e87aa4c49e95 1765 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 1766 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1767
phungductung 0:e87aa4c49e95 1768 /* Send CMD12 STOP_TRANSMISSION */
phungductung 0:e87aa4c49e95 1769 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 1770 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_STOP_TRANSMISSION;
phungductung 0:e87aa4c49e95 1771 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 1772 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 1773 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 1774 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1775
phungductung 0:e87aa4c49e95 1776 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1777 errorstate = SD_CmdResp1Error(hsd, SD_CMD_STOP_TRANSMISSION);
phungductung 0:e87aa4c49e95 1778
phungductung 0:e87aa4c49e95 1779 return errorstate;
phungductung 0:e87aa4c49e95 1780 }
phungductung 0:e87aa4c49e95 1781
phungductung 0:e87aa4c49e95 1782 /**
phungductung 0:e87aa4c49e95 1783 * @brief Switches the SD card to High Speed mode.
phungductung 0:e87aa4c49e95 1784 * This API must be used after "Transfer State"
phungductung 0:e87aa4c49e95 1785 * @note This operation should be followed by the configuration
phungductung 0:e87aa4c49e95 1786 * of PLL to have SDMMCCK clock between 67 and 75 MHz
phungductung 0:e87aa4c49e95 1787 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1788 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1789 */
phungductung 0:e87aa4c49e95 1790 HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 1791 {
phungductung 0:e87aa4c49e95 1792 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1793 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 1794 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 1795
phungductung 0:e87aa4c49e95 1796 uint8_t SD_hs[64] = {0};
phungductung 0:e87aa4c49e95 1797 uint32_t SD_scr[2] = {0, 0};
phungductung 0:e87aa4c49e95 1798 uint32_t SD_SPEC = 0 ;
phungductung 0:e87aa4c49e95 1799 uint32_t count = 0, *tempbuff = (uint32_t *)SD_hs;
phungductung 0:e87aa4c49e95 1800
phungductung 0:e87aa4c49e95 1801 /* Initialize the Data control register */
phungductung 0:e87aa4c49e95 1802 hsd->Instance->DCTRL = 0;
phungductung 0:e87aa4c49e95 1803
phungductung 0:e87aa4c49e95 1804 /* Get SCR Register */
phungductung 0:e87aa4c49e95 1805 errorstate = SD_FindSCR(hsd, SD_scr);
phungductung 0:e87aa4c49e95 1806
phungductung 0:e87aa4c49e95 1807 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1808 {
phungductung 0:e87aa4c49e95 1809 return errorstate;
phungductung 0:e87aa4c49e95 1810 }
phungductung 0:e87aa4c49e95 1811
phungductung 0:e87aa4c49e95 1812 /* Test the Version supported by the card*/
phungductung 0:e87aa4c49e95 1813 SD_SPEC = (SD_scr[1] & 0x01000000) | (SD_scr[1] & 0x02000000);
phungductung 0:e87aa4c49e95 1814
phungductung 0:e87aa4c49e95 1815 if (SD_SPEC != SD_ALLZERO)
phungductung 0:e87aa4c49e95 1816 {
phungductung 0:e87aa4c49e95 1817 /* Set Block Size for Card */
phungductung 0:e87aa4c49e95 1818 sdmmc_cmdinitstructure.Argument = (uint32_t)64;
phungductung 0:e87aa4c49e95 1819 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 1820 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 1821 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 1822 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 1823 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1824
phungductung 0:e87aa4c49e95 1825 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1826 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 1827
phungductung 0:e87aa4c49e95 1828 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1829 {
phungductung 0:e87aa4c49e95 1830 return errorstate;
phungductung 0:e87aa4c49e95 1831 }
phungductung 0:e87aa4c49e95 1832
phungductung 0:e87aa4c49e95 1833 /* Configure the SD DPSM (Data Path State Machine) */
phungductung 0:e87aa4c49e95 1834 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 1835 sdmmc_datainitstructure.DataLength = 64;
phungductung 0:e87aa4c49e95 1836 sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ;
phungductung 0:e87aa4c49e95 1837 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
phungductung 0:e87aa4c49e95 1838 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 1839 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 1840 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 1841
phungductung 0:e87aa4c49e95 1842 /* Send CMD6 switch mode */
phungductung 0:e87aa4c49e95 1843 sdmmc_cmdinitstructure.Argument = 0x80FFFF01;
phungductung 0:e87aa4c49e95 1844 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_HS_SWITCH;
phungductung 0:e87aa4c49e95 1845 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1846
phungductung 0:e87aa4c49e95 1847 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1848 errorstate = SD_CmdResp1Error(hsd, SD_CMD_HS_SWITCH);
phungductung 0:e87aa4c49e95 1849
phungductung 0:e87aa4c49e95 1850 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1851 {
phungductung 0:e87aa4c49e95 1852 return errorstate;
phungductung 0:e87aa4c49e95 1853 }
phungductung 0:e87aa4c49e95 1854
phungductung 0:e87aa4c49e95 1855 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
phungductung 0:e87aa4c49e95 1856 {
phungductung 0:e87aa4c49e95 1857 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))
phungductung 0:e87aa4c49e95 1858 {
phungductung 0:e87aa4c49e95 1859 for (count = 0; count < 8; count++)
phungductung 0:e87aa4c49e95 1860 {
phungductung 0:e87aa4c49e95 1861 *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 1862 }
phungductung 0:e87aa4c49e95 1863
phungductung 0:e87aa4c49e95 1864 tempbuff += 8;
phungductung 0:e87aa4c49e95 1865 }
phungductung 0:e87aa4c49e95 1866 }
phungductung 0:e87aa4c49e95 1867
phungductung 0:e87aa4c49e95 1868 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))
phungductung 0:e87aa4c49e95 1869 {
phungductung 0:e87aa4c49e95 1870 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);
phungductung 0:e87aa4c49e95 1871
phungductung 0:e87aa4c49e95 1872 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 1873
phungductung 0:e87aa4c49e95 1874 return errorstate;
phungductung 0:e87aa4c49e95 1875 }
phungductung 0:e87aa4c49e95 1876 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))
phungductung 0:e87aa4c49e95 1877 {
phungductung 0:e87aa4c49e95 1878 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);
phungductung 0:e87aa4c49e95 1879
phungductung 0:e87aa4c49e95 1880 errorstate = SD_DATA_CRC_FAIL;
phungductung 0:e87aa4c49e95 1881
phungductung 0:e87aa4c49e95 1882 return errorstate;
phungductung 0:e87aa4c49e95 1883 }
phungductung 0:e87aa4c49e95 1884 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))
phungductung 0:e87aa4c49e95 1885 {
phungductung 0:e87aa4c49e95 1886 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);
phungductung 0:e87aa4c49e95 1887
phungductung 0:e87aa4c49e95 1888 errorstate = SD_RX_OVERRUN;
phungductung 0:e87aa4c49e95 1889
phungductung 0:e87aa4c49e95 1890 return errorstate;
phungductung 0:e87aa4c49e95 1891 }
phungductung 0:e87aa4c49e95 1892 else
phungductung 0:e87aa4c49e95 1893 {
phungductung 0:e87aa4c49e95 1894 /* No error flag set */
phungductung 0:e87aa4c49e95 1895 }
phungductung 0:e87aa4c49e95 1896
phungductung 0:e87aa4c49e95 1897 count = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 1898
phungductung 0:e87aa4c49e95 1899 while ((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) && (count > 0))
phungductung 0:e87aa4c49e95 1900 {
phungductung 0:e87aa4c49e95 1901 *tempbuff = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 1902 tempbuff++;
phungductung 0:e87aa4c49e95 1903 count--;
phungductung 0:e87aa4c49e95 1904 }
phungductung 0:e87aa4c49e95 1905
phungductung 0:e87aa4c49e95 1906 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 1907 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 1908
phungductung 0:e87aa4c49e95 1909 /* Test if the switch mode HS is ok */
phungductung 0:e87aa4c49e95 1910 if ((SD_hs[13]& 2) != 2)
phungductung 0:e87aa4c49e95 1911 {
phungductung 0:e87aa4c49e95 1912 errorstate = SD_UNSUPPORTED_FEATURE;
phungductung 0:e87aa4c49e95 1913 }
phungductung 0:e87aa4c49e95 1914 }
phungductung 0:e87aa4c49e95 1915
phungductung 0:e87aa4c49e95 1916 return errorstate;
phungductung 0:e87aa4c49e95 1917 }
phungductung 0:e87aa4c49e95 1918
phungductung 0:e87aa4c49e95 1919 /**
phungductung 0:e87aa4c49e95 1920 * @}
phungductung 0:e87aa4c49e95 1921 */
phungductung 0:e87aa4c49e95 1922
phungductung 0:e87aa4c49e95 1923 /** @addtogroup SD_Exported_Functions_Group4
phungductung 0:e87aa4c49e95 1924 * @brief Peripheral State functions
phungductung 0:e87aa4c49e95 1925 *
phungductung 0:e87aa4c49e95 1926 @verbatim
phungductung 0:e87aa4c49e95 1927 ==============================================================================
phungductung 0:e87aa4c49e95 1928 ##### Peripheral State functions #####
phungductung 0:e87aa4c49e95 1929 ==============================================================================
phungductung 0:e87aa4c49e95 1930 [..]
phungductung 0:e87aa4c49e95 1931 This subsection permits to get in runtime the status of the peripheral
phungductung 0:e87aa4c49e95 1932 and the data flow.
phungductung 0:e87aa4c49e95 1933
phungductung 0:e87aa4c49e95 1934 @endverbatim
phungductung 0:e87aa4c49e95 1935 * @{
phungductung 0:e87aa4c49e95 1936 */
phungductung 0:e87aa4c49e95 1937
phungductung 0:e87aa4c49e95 1938 /**
phungductung 0:e87aa4c49e95 1939 * @brief Returns the current SD card's status.
phungductung 0:e87aa4c49e95 1940 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 1941 * @param pSDstatus: Pointer to the buffer that will contain the SD card status
phungductung 0:e87aa4c49e95 1942 * SD Status register)
phungductung 0:e87aa4c49e95 1943 * @retval SD Card error state
phungductung 0:e87aa4c49e95 1944 */
phungductung 0:e87aa4c49e95 1945 HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)
phungductung 0:e87aa4c49e95 1946 {
phungductung 0:e87aa4c49e95 1947 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 1948 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 1949 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 1950 uint32_t count = 0;
phungductung 0:e87aa4c49e95 1951
phungductung 0:e87aa4c49e95 1952 /* Check SD response */
phungductung 0:e87aa4c49e95 1953 if ((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
phungductung 0:e87aa4c49e95 1954 {
phungductung 0:e87aa4c49e95 1955 errorstate = SD_LOCK_UNLOCK_FAILED;
phungductung 0:e87aa4c49e95 1956
phungductung 0:e87aa4c49e95 1957 return errorstate;
phungductung 0:e87aa4c49e95 1958 }
phungductung 0:e87aa4c49e95 1959
phungductung 0:e87aa4c49e95 1960 /* Set block size for card if it is not equal to current block size for card */
phungductung 0:e87aa4c49e95 1961 sdmmc_cmdinitstructure.Argument = 64;
phungductung 0:e87aa4c49e95 1962 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 1963 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 1964 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 1965 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 1966 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1967
phungductung 0:e87aa4c49e95 1968 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1969 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 1970
phungductung 0:e87aa4c49e95 1971 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1972 {
phungductung 0:e87aa4c49e95 1973 return errorstate;
phungductung 0:e87aa4c49e95 1974 }
phungductung 0:e87aa4c49e95 1975
phungductung 0:e87aa4c49e95 1976 /* Send CMD55 */
phungductung 0:e87aa4c49e95 1977 sdmmc_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
phungductung 0:e87aa4c49e95 1978 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
phungductung 0:e87aa4c49e95 1979 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 1980
phungductung 0:e87aa4c49e95 1981 /* Check for error conditions */
phungductung 0:e87aa4c49e95 1982 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
phungductung 0:e87aa4c49e95 1983
phungductung 0:e87aa4c49e95 1984 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 1985 {
phungductung 0:e87aa4c49e95 1986 return errorstate;
phungductung 0:e87aa4c49e95 1987 }
phungductung 0:e87aa4c49e95 1988
phungductung 0:e87aa4c49e95 1989 /* Configure the SD DPSM (Data Path State Machine) */
phungductung 0:e87aa4c49e95 1990 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 1991 sdmmc_datainitstructure.DataLength = 64;
phungductung 0:e87aa4c49e95 1992 sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B;
phungductung 0:e87aa4c49e95 1993 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
phungductung 0:e87aa4c49e95 1994 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 1995 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 1996 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 1997
phungductung 0:e87aa4c49e95 1998 /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */
phungductung 0:e87aa4c49e95 1999 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 2000 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_STATUS;
phungductung 0:e87aa4c49e95 2001 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2002
phungductung 0:e87aa4c49e95 2003 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2004 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_STATUS);
phungductung 0:e87aa4c49e95 2005
phungductung 0:e87aa4c49e95 2006 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2007 {
phungductung 0:e87aa4c49e95 2008 return errorstate;
phungductung 0:e87aa4c49e95 2009 }
phungductung 0:e87aa4c49e95 2010
phungductung 0:e87aa4c49e95 2011 /* Get status data */
phungductung 0:e87aa4c49e95 2012 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
phungductung 0:e87aa4c49e95 2013 {
phungductung 0:e87aa4c49e95 2014 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))
phungductung 0:e87aa4c49e95 2015 {
phungductung 0:e87aa4c49e95 2016 for (count = 0; count < 8; count++)
phungductung 0:e87aa4c49e95 2017 {
phungductung 0:e87aa4c49e95 2018 *(pSDstatus + count) = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 2019 }
phungductung 0:e87aa4c49e95 2020
phungductung 0:e87aa4c49e95 2021 pSDstatus += 8;
phungductung 0:e87aa4c49e95 2022 }
phungductung 0:e87aa4c49e95 2023 }
phungductung 0:e87aa4c49e95 2024
phungductung 0:e87aa4c49e95 2025 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))
phungductung 0:e87aa4c49e95 2026 {
phungductung 0:e87aa4c49e95 2027 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);
phungductung 0:e87aa4c49e95 2028
phungductung 0:e87aa4c49e95 2029 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 2030
phungductung 0:e87aa4c49e95 2031 return errorstate;
phungductung 0:e87aa4c49e95 2032 }
phungductung 0:e87aa4c49e95 2033 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))
phungductung 0:e87aa4c49e95 2034 {
phungductung 0:e87aa4c49e95 2035 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);
phungductung 0:e87aa4c49e95 2036
phungductung 0:e87aa4c49e95 2037 errorstate = SD_DATA_CRC_FAIL;
phungductung 0:e87aa4c49e95 2038
phungductung 0:e87aa4c49e95 2039 return errorstate;
phungductung 0:e87aa4c49e95 2040 }
phungductung 0:e87aa4c49e95 2041 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))
phungductung 0:e87aa4c49e95 2042 {
phungductung 0:e87aa4c49e95 2043 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);
phungductung 0:e87aa4c49e95 2044
phungductung 0:e87aa4c49e95 2045 errorstate = SD_RX_OVERRUN;
phungductung 0:e87aa4c49e95 2046
phungductung 0:e87aa4c49e95 2047 return errorstate;
phungductung 0:e87aa4c49e95 2048 }
phungductung 0:e87aa4c49e95 2049 else
phungductung 0:e87aa4c49e95 2050 {
phungductung 0:e87aa4c49e95 2051 /* No error flag set */
phungductung 0:e87aa4c49e95 2052 }
phungductung 0:e87aa4c49e95 2053
phungductung 0:e87aa4c49e95 2054 count = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 2055 while ((__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) && (count > 0))
phungductung 0:e87aa4c49e95 2056 {
phungductung 0:e87aa4c49e95 2057 *pSDstatus = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 2058 pSDstatus++;
phungductung 0:e87aa4c49e95 2059 count--;
phungductung 0:e87aa4c49e95 2060 }
phungductung 0:e87aa4c49e95 2061
phungductung 0:e87aa4c49e95 2062 /* Clear all the static status flags*/
phungductung 0:e87aa4c49e95 2063 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 2064
phungductung 0:e87aa4c49e95 2065 return errorstate;
phungductung 0:e87aa4c49e95 2066 }
phungductung 0:e87aa4c49e95 2067
phungductung 0:e87aa4c49e95 2068 /**
phungductung 0:e87aa4c49e95 2069 * @brief Gets the current sd card data status.
phungductung 0:e87aa4c49e95 2070 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2071 * @retval Data Transfer state
phungductung 0:e87aa4c49e95 2072 */
phungductung 0:e87aa4c49e95 2073 HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2074 {
phungductung 0:e87aa4c49e95 2075 HAL_SD_CardStateTypedef cardstate = SD_CARD_TRANSFER;
phungductung 0:e87aa4c49e95 2076
phungductung 0:e87aa4c49e95 2077 /* Get SD card state */
phungductung 0:e87aa4c49e95 2078 cardstate = SD_GetState(hsd);
phungductung 0:e87aa4c49e95 2079
phungductung 0:e87aa4c49e95 2080 /* Find SD status according to card state*/
phungductung 0:e87aa4c49e95 2081 if (cardstate == SD_CARD_TRANSFER)
phungductung 0:e87aa4c49e95 2082 {
phungductung 0:e87aa4c49e95 2083 return SD_TRANSFER_OK;
phungductung 0:e87aa4c49e95 2084 }
phungductung 0:e87aa4c49e95 2085 else if(cardstate == SD_CARD_ERROR)
phungductung 0:e87aa4c49e95 2086 {
phungductung 0:e87aa4c49e95 2087 return SD_TRANSFER_ERROR;
phungductung 0:e87aa4c49e95 2088 }
phungductung 0:e87aa4c49e95 2089 else
phungductung 0:e87aa4c49e95 2090 {
phungductung 0:e87aa4c49e95 2091 return SD_TRANSFER_BUSY;
phungductung 0:e87aa4c49e95 2092 }
phungductung 0:e87aa4c49e95 2093 }
phungductung 0:e87aa4c49e95 2094
phungductung 0:e87aa4c49e95 2095 /**
phungductung 0:e87aa4c49e95 2096 * @brief Gets the SD card status.
phungductung 0:e87aa4c49e95 2097 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2098 * @param pCardStatus: Pointer to the HAL_SD_CardStatusTypedef structure that
phungductung 0:e87aa4c49e95 2099 * will contain the SD card status information
phungductung 0:e87aa4c49e95 2100 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2101 */
phungductung 0:e87aa4c49e95 2102 HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus)
phungductung 0:e87aa4c49e95 2103 {
phungductung 0:e87aa4c49e95 2104 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2105 uint32_t tmp = 0;
phungductung 0:e87aa4c49e95 2106 uint32_t sd_status[16];
phungductung 0:e87aa4c49e95 2107
phungductung 0:e87aa4c49e95 2108 errorstate = HAL_SD_SendSDStatus(hsd, sd_status);
phungductung 0:e87aa4c49e95 2109
phungductung 0:e87aa4c49e95 2110 if (errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2111 {
phungductung 0:e87aa4c49e95 2112 return errorstate;
phungductung 0:e87aa4c49e95 2113 }
phungductung 0:e87aa4c49e95 2114
phungductung 0:e87aa4c49e95 2115 /* Byte 0 */
phungductung 0:e87aa4c49e95 2116 tmp = (sd_status[0] & 0xC0) >> 6;
phungductung 0:e87aa4c49e95 2117 pCardStatus->DAT_BUS_WIDTH = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2118
phungductung 0:e87aa4c49e95 2119 /* Byte 0 */
phungductung 0:e87aa4c49e95 2120 tmp = (sd_status[0] & 0x20) >> 5;
phungductung 0:e87aa4c49e95 2121 pCardStatus->SECURED_MODE = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2122
phungductung 0:e87aa4c49e95 2123 /* Byte 2 */
phungductung 0:e87aa4c49e95 2124 tmp = (sd_status[2] & 0xFF);
phungductung 0:e87aa4c49e95 2125 pCardStatus->SD_CARD_TYPE = (uint8_t)(tmp << 8);
phungductung 0:e87aa4c49e95 2126
phungductung 0:e87aa4c49e95 2127 /* Byte 3 */
phungductung 0:e87aa4c49e95 2128 tmp = (sd_status[3] & 0xFF);
phungductung 0:e87aa4c49e95 2129 pCardStatus->SD_CARD_TYPE |= (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2130
phungductung 0:e87aa4c49e95 2131 /* Byte 4 */
phungductung 0:e87aa4c49e95 2132 tmp = (sd_status[4] & 0xFF);
phungductung 0:e87aa4c49e95 2133 pCardStatus->SIZE_OF_PROTECTED_AREA = (uint8_t)(tmp << 24);
phungductung 0:e87aa4c49e95 2134
phungductung 0:e87aa4c49e95 2135 /* Byte 5 */
phungductung 0:e87aa4c49e95 2136 tmp = (sd_status[5] & 0xFF);
phungductung 0:e87aa4c49e95 2137 pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 16);
phungductung 0:e87aa4c49e95 2138
phungductung 0:e87aa4c49e95 2139 /* Byte 6 */
phungductung 0:e87aa4c49e95 2140 tmp = (sd_status[6] & 0xFF);
phungductung 0:e87aa4c49e95 2141 pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 8);
phungductung 0:e87aa4c49e95 2142
phungductung 0:e87aa4c49e95 2143 /* Byte 7 */
phungductung 0:e87aa4c49e95 2144 tmp = (sd_status[7] & 0xFF);
phungductung 0:e87aa4c49e95 2145 pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2146
phungductung 0:e87aa4c49e95 2147 /* Byte 8 */
phungductung 0:e87aa4c49e95 2148 tmp = (sd_status[8] & 0xFF);
phungductung 0:e87aa4c49e95 2149 pCardStatus->SPEED_CLASS = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2150
phungductung 0:e87aa4c49e95 2151 /* Byte 9 */
phungductung 0:e87aa4c49e95 2152 tmp = (sd_status[9] & 0xFF);
phungductung 0:e87aa4c49e95 2153 pCardStatus->PERFORMANCE_MOVE = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2154
phungductung 0:e87aa4c49e95 2155 /* Byte 10 */
phungductung 0:e87aa4c49e95 2156 tmp = (sd_status[10] & 0xF0) >> 4;
phungductung 0:e87aa4c49e95 2157 pCardStatus->AU_SIZE = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2158
phungductung 0:e87aa4c49e95 2159 /* Byte 11 */
phungductung 0:e87aa4c49e95 2160 tmp = (sd_status[11] & 0xFF);
phungductung 0:e87aa4c49e95 2161 pCardStatus->ERASE_SIZE = (uint8_t)(tmp << 8);
phungductung 0:e87aa4c49e95 2162
phungductung 0:e87aa4c49e95 2163 /* Byte 12 */
phungductung 0:e87aa4c49e95 2164 tmp = (sd_status[12] & 0xFF);
phungductung 0:e87aa4c49e95 2165 pCardStatus->ERASE_SIZE |= (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2166
phungductung 0:e87aa4c49e95 2167 /* Byte 13 */
phungductung 0:e87aa4c49e95 2168 tmp = (sd_status[13] & 0xFC) >> 2;
phungductung 0:e87aa4c49e95 2169 pCardStatus->ERASE_TIMEOUT = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2170
phungductung 0:e87aa4c49e95 2171 /* Byte 13 */
phungductung 0:e87aa4c49e95 2172 tmp = (sd_status[13] & 0x3);
phungductung 0:e87aa4c49e95 2173 pCardStatus->ERASE_OFFSET = (uint8_t)tmp;
phungductung 0:e87aa4c49e95 2174
phungductung 0:e87aa4c49e95 2175 return errorstate;
phungductung 0:e87aa4c49e95 2176 }
phungductung 0:e87aa4c49e95 2177
phungductung 0:e87aa4c49e95 2178 /**
phungductung 0:e87aa4c49e95 2179 * @}
phungductung 0:e87aa4c49e95 2180 */
phungductung 0:e87aa4c49e95 2181
phungductung 0:e87aa4c49e95 2182 /**
phungductung 0:e87aa4c49e95 2183 * @}
phungductung 0:e87aa4c49e95 2184 */
phungductung 0:e87aa4c49e95 2185
phungductung 0:e87aa4c49e95 2186 /* Private function ----------------------------------------------------------*/
phungductung 0:e87aa4c49e95 2187 /** @addtogroup SD_Private_Functions
phungductung 0:e87aa4c49e95 2188 * @{
phungductung 0:e87aa4c49e95 2189 */
phungductung 0:e87aa4c49e95 2190
phungductung 0:e87aa4c49e95 2191 /**
phungductung 0:e87aa4c49e95 2192 * @brief SD DMA transfer complete Rx callback.
phungductung 0:e87aa4c49e95 2193 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 2194 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 2195 * @retval None
phungductung 0:e87aa4c49e95 2196 */
phungductung 0:e87aa4c49e95 2197 static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 2198 {
phungductung 0:e87aa4c49e95 2199 SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
phungductung 0:e87aa4c49e95 2200
phungductung 0:e87aa4c49e95 2201 /* DMA transfer is complete */
phungductung 0:e87aa4c49e95 2202 hsd->DmaTransferCplt = 1;
phungductung 0:e87aa4c49e95 2203
phungductung 0:e87aa4c49e95 2204 /* Wait until SD transfer is complete */
phungductung 0:e87aa4c49e95 2205 while(hsd->SdTransferCplt == 0)
phungductung 0:e87aa4c49e95 2206 {
phungductung 0:e87aa4c49e95 2207 }
phungductung 0:e87aa4c49e95 2208
phungductung 0:e87aa4c49e95 2209 /* Disable the DMA channel */
phungductung 0:e87aa4c49e95 2210 HAL_DMA_Abort(hdma);
phungductung 0:e87aa4c49e95 2211
phungductung 0:e87aa4c49e95 2212 /* Transfer complete user callback */
phungductung 0:e87aa4c49e95 2213 HAL_SD_DMA_RxCpltCallback(hsd->hdmarx);
phungductung 0:e87aa4c49e95 2214 }
phungductung 0:e87aa4c49e95 2215
phungductung 0:e87aa4c49e95 2216 /**
phungductung 0:e87aa4c49e95 2217 * @brief SD DMA transfer Error Rx callback.
phungductung 0:e87aa4c49e95 2218 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 2219 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 2220 * @retval None
phungductung 0:e87aa4c49e95 2221 */
phungductung 0:e87aa4c49e95 2222 static void SD_DMA_RxError(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 2223 {
phungductung 0:e87aa4c49e95 2224 SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
phungductung 0:e87aa4c49e95 2225
phungductung 0:e87aa4c49e95 2226 /* Transfer complete user callback */
phungductung 0:e87aa4c49e95 2227 HAL_SD_DMA_RxErrorCallback(hsd->hdmarx);
phungductung 0:e87aa4c49e95 2228 }
phungductung 0:e87aa4c49e95 2229
phungductung 0:e87aa4c49e95 2230 /**
phungductung 0:e87aa4c49e95 2231 * @brief SD DMA transfer complete Tx callback.
phungductung 0:e87aa4c49e95 2232 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 2233 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 2234 * @retval None
phungductung 0:e87aa4c49e95 2235 */
phungductung 0:e87aa4c49e95 2236 static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 2237 {
phungductung 0:e87aa4c49e95 2238 SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
phungductung 0:e87aa4c49e95 2239
phungductung 0:e87aa4c49e95 2240 /* DMA transfer is complete */
phungductung 0:e87aa4c49e95 2241 hsd->DmaTransferCplt = 1;
phungductung 0:e87aa4c49e95 2242
phungductung 0:e87aa4c49e95 2243 /* Wait until SD transfer is complete */
phungductung 0:e87aa4c49e95 2244 while(hsd->SdTransferCplt == 0)
phungductung 0:e87aa4c49e95 2245 {
phungductung 0:e87aa4c49e95 2246 }
phungductung 0:e87aa4c49e95 2247
phungductung 0:e87aa4c49e95 2248 /* Disable the DMA channel */
phungductung 0:e87aa4c49e95 2249 HAL_DMA_Abort(hdma);
phungductung 0:e87aa4c49e95 2250
phungductung 0:e87aa4c49e95 2251 /* Transfer complete user callback */
phungductung 0:e87aa4c49e95 2252 HAL_SD_DMA_TxCpltCallback(hsd->hdmatx);
phungductung 0:e87aa4c49e95 2253 }
phungductung 0:e87aa4c49e95 2254
phungductung 0:e87aa4c49e95 2255 /**
phungductung 0:e87aa4c49e95 2256 * @brief SD DMA transfer Error Tx callback.
phungductung 0:e87aa4c49e95 2257 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
phungductung 0:e87aa4c49e95 2258 * the configuration information for the specified DMA module.
phungductung 0:e87aa4c49e95 2259 * @retval None
phungductung 0:e87aa4c49e95 2260 */
phungductung 0:e87aa4c49e95 2261 static void SD_DMA_TxError(DMA_HandleTypeDef *hdma)
phungductung 0:e87aa4c49e95 2262 {
phungductung 0:e87aa4c49e95 2263 SD_HandleTypeDef *hsd = ( SD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
phungductung 0:e87aa4c49e95 2264
phungductung 0:e87aa4c49e95 2265 /* Transfer complete user callback */
phungductung 0:e87aa4c49e95 2266 HAL_SD_DMA_TxErrorCallback(hsd->hdmatx);
phungductung 0:e87aa4c49e95 2267 }
phungductung 0:e87aa4c49e95 2268
phungductung 0:e87aa4c49e95 2269 /**
phungductung 0:e87aa4c49e95 2270 * @brief Returns the SD current state.
phungductung 0:e87aa4c49e95 2271 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2272 * @retval SD card current state
phungductung 0:e87aa4c49e95 2273 */
phungductung 0:e87aa4c49e95 2274 static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2275 {
phungductung 0:e87aa4c49e95 2276 uint32_t resp1 = 0;
phungductung 0:e87aa4c49e95 2277
phungductung 0:e87aa4c49e95 2278 if (SD_SendStatus(hsd, &resp1) != SD_OK)
phungductung 0:e87aa4c49e95 2279 {
phungductung 0:e87aa4c49e95 2280 return SD_CARD_ERROR;
phungductung 0:e87aa4c49e95 2281 }
phungductung 0:e87aa4c49e95 2282 else
phungductung 0:e87aa4c49e95 2283 {
phungductung 0:e87aa4c49e95 2284 return (HAL_SD_CardStateTypedef)((resp1 >> 9) & 0x0F);
phungductung 0:e87aa4c49e95 2285 }
phungductung 0:e87aa4c49e95 2286 }
phungductung 0:e87aa4c49e95 2287
phungductung 0:e87aa4c49e95 2288 /**
phungductung 0:e87aa4c49e95 2289 * @brief Initializes all cards or single card as the case may be Card(s) come
phungductung 0:e87aa4c49e95 2290 * into standby state.
phungductung 0:e87aa4c49e95 2291 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2292 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2293 */
phungductung 0:e87aa4c49e95 2294 static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2295 {
phungductung 0:e87aa4c49e95 2296 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 2297 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2298 uint16_t sd_rca = 1;
phungductung 0:e87aa4c49e95 2299
phungductung 0:e87aa4c49e95 2300 if(SDMMC_GetPowerState(hsd->Instance) == 0) /* Power off */
phungductung 0:e87aa4c49e95 2301 {
phungductung 0:e87aa4c49e95 2302 errorstate = SD_REQUEST_NOT_APPLICABLE;
phungductung 0:e87aa4c49e95 2303
phungductung 0:e87aa4c49e95 2304 return errorstate;
phungductung 0:e87aa4c49e95 2305 }
phungductung 0:e87aa4c49e95 2306
phungductung 0:e87aa4c49e95 2307 if(hsd->CardType != SECURE_DIGITAL_IO_CARD)
phungductung 0:e87aa4c49e95 2308 {
phungductung 0:e87aa4c49e95 2309 /* Send CMD2 ALL_SEND_CID */
phungductung 0:e87aa4c49e95 2310 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 2311 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_ALL_SEND_CID;
phungductung 0:e87aa4c49e95 2312 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_LONG;
phungductung 0:e87aa4c49e95 2313 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 2314 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 2315 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2316
phungductung 0:e87aa4c49e95 2317 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2318 errorstate = SD_CmdResp2Error(hsd);
phungductung 0:e87aa4c49e95 2319
phungductung 0:e87aa4c49e95 2320 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2321 {
phungductung 0:e87aa4c49e95 2322 return errorstate;
phungductung 0:e87aa4c49e95 2323 }
phungductung 0:e87aa4c49e95 2324
phungductung 0:e87aa4c49e95 2325 /* Get Card identification number data */
phungductung 0:e87aa4c49e95 2326 hsd->CID[0] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 2327 hsd->CID[1] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2);
phungductung 0:e87aa4c49e95 2328 hsd->CID[2] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3);
phungductung 0:e87aa4c49e95 2329 hsd->CID[3] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4);
phungductung 0:e87aa4c49e95 2330 }
phungductung 0:e87aa4c49e95 2331
phungductung 0:e87aa4c49e95 2332 if((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\
phungductung 0:e87aa4c49e95 2333 (hsd->CardType == SECURE_DIGITAL_IO_COMBO_CARD) || (hsd->CardType == HIGH_CAPACITY_SD_CARD))
phungductung 0:e87aa4c49e95 2334 {
phungductung 0:e87aa4c49e95 2335 /* Send CMD3 SET_REL_ADDR with argument 0 */
phungductung 0:e87aa4c49e95 2336 /* SD Card publishes its RCA. */
phungductung 0:e87aa4c49e95 2337 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_REL_ADDR;
phungductung 0:e87aa4c49e95 2338 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 2339 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2340
phungductung 0:e87aa4c49e95 2341 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2342 errorstate = SD_CmdResp6Error(hsd, SD_CMD_SET_REL_ADDR, &sd_rca);
phungductung 0:e87aa4c49e95 2343
phungductung 0:e87aa4c49e95 2344 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2345 {
phungductung 0:e87aa4c49e95 2346 return errorstate;
phungductung 0:e87aa4c49e95 2347 }
phungductung 0:e87aa4c49e95 2348 }
phungductung 0:e87aa4c49e95 2349
phungductung 0:e87aa4c49e95 2350 if (hsd->CardType != SECURE_DIGITAL_IO_CARD)
phungductung 0:e87aa4c49e95 2351 {
phungductung 0:e87aa4c49e95 2352 /* Get the SD card RCA */
phungductung 0:e87aa4c49e95 2353 hsd->RCA = sd_rca;
phungductung 0:e87aa4c49e95 2354
phungductung 0:e87aa4c49e95 2355 /* Send CMD9 SEND_CSD with argument as card's RCA */
phungductung 0:e87aa4c49e95 2356 sdmmc_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
phungductung 0:e87aa4c49e95 2357 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SEND_CSD;
phungductung 0:e87aa4c49e95 2358 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_LONG;
phungductung 0:e87aa4c49e95 2359 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2360
phungductung 0:e87aa4c49e95 2361 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2362 errorstate = SD_CmdResp2Error(hsd);
phungductung 0:e87aa4c49e95 2363
phungductung 0:e87aa4c49e95 2364 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2365 {
phungductung 0:e87aa4c49e95 2366 return errorstate;
phungductung 0:e87aa4c49e95 2367 }
phungductung 0:e87aa4c49e95 2368
phungductung 0:e87aa4c49e95 2369 /* Get Card Specific Data */
phungductung 0:e87aa4c49e95 2370 hsd->CSD[0] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 2371 hsd->CSD[1] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2);
phungductung 0:e87aa4c49e95 2372 hsd->CSD[2] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3);
phungductung 0:e87aa4c49e95 2373 hsd->CSD[3] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4);
phungductung 0:e87aa4c49e95 2374 }
phungductung 0:e87aa4c49e95 2375
phungductung 0:e87aa4c49e95 2376 /* All cards are initialized */
phungductung 0:e87aa4c49e95 2377 return errorstate;
phungductung 0:e87aa4c49e95 2378 }
phungductung 0:e87aa4c49e95 2379
phungductung 0:e87aa4c49e95 2380 /**
phungductung 0:e87aa4c49e95 2381 * @brief Selects od Deselects the corresponding card.
phungductung 0:e87aa4c49e95 2382 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2383 * @param addr: Address of the card to be selected
phungductung 0:e87aa4c49e95 2384 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2385 */
phungductung 0:e87aa4c49e95 2386 static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr)
phungductung 0:e87aa4c49e95 2387 {
phungductung 0:e87aa4c49e95 2388 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 2389 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2390
phungductung 0:e87aa4c49e95 2391 /* Send CMD7 SDMMC_SEL_DESEL_CARD */
phungductung 0:e87aa4c49e95 2392 sdmmc_cmdinitstructure.Argument = (uint32_t)addr;
phungductung 0:e87aa4c49e95 2393 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SEL_DESEL_CARD;
phungductung 0:e87aa4c49e95 2394 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 2395 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 2396 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 2397 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2398
phungductung 0:e87aa4c49e95 2399 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2400 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEL_DESEL_CARD);
phungductung 0:e87aa4c49e95 2401
phungductung 0:e87aa4c49e95 2402 return errorstate;
phungductung 0:e87aa4c49e95 2403 }
phungductung 0:e87aa4c49e95 2404
phungductung 0:e87aa4c49e95 2405 /**
phungductung 0:e87aa4c49e95 2406 * @brief Enquires cards about their operating voltage and configures clock
phungductung 0:e87aa4c49e95 2407 * controls and stores SD information that will be needed in future
phungductung 0:e87aa4c49e95 2408 * in the SD handle.
phungductung 0:e87aa4c49e95 2409 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2410 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2411 */
phungductung 0:e87aa4c49e95 2412 static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2413 {
phungductung 0:e87aa4c49e95 2414 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 2415 __IO HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2416 uint32_t response = 0, count = 0, validvoltage = 0;
phungductung 0:e87aa4c49e95 2417 uint32_t sdtype = SD_STD_CAPACITY;
phungductung 0:e87aa4c49e95 2418
phungductung 0:e87aa4c49e95 2419 /* Power ON Sequence -------------------------------------------------------*/
phungductung 0:e87aa4c49e95 2420 /* Disable SDMMC Clock */
phungductung 0:e87aa4c49e95 2421 __HAL_SD_SDMMC_DISABLE(hsd);
phungductung 0:e87aa4c49e95 2422
phungductung 0:e87aa4c49e95 2423 /* Set Power State to ON */
phungductung 0:e87aa4c49e95 2424 SDMMC_PowerState_ON(hsd->Instance);
phungductung 0:e87aa4c49e95 2425
phungductung 0:e87aa4c49e95 2426 /* 1ms: required power up waiting time before starting the SD initialization
phungductung 0:e87aa4c49e95 2427 sequence */
phungductung 0:e87aa4c49e95 2428 HAL_Delay(1);
phungductung 0:e87aa4c49e95 2429
phungductung 0:e87aa4c49e95 2430 /* Enable SDMMC Clock */
phungductung 0:e87aa4c49e95 2431 __HAL_SD_SDMMC_ENABLE(hsd);
phungductung 0:e87aa4c49e95 2432
phungductung 0:e87aa4c49e95 2433 /* CMD0: GO_IDLE_STATE -----------------------------------------------------*/
phungductung 0:e87aa4c49e95 2434 /* No CMD response required */
phungductung 0:e87aa4c49e95 2435 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 2436 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_GO_IDLE_STATE;
phungductung 0:e87aa4c49e95 2437 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_NO;
phungductung 0:e87aa4c49e95 2438 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 2439 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 2440 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2441
phungductung 0:e87aa4c49e95 2442 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2443 errorstate = SD_CmdError(hsd);
phungductung 0:e87aa4c49e95 2444
phungductung 0:e87aa4c49e95 2445 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2446 {
phungductung 0:e87aa4c49e95 2447 /* CMD Response Timeout (wait for CMDSENT flag) */
phungductung 0:e87aa4c49e95 2448 return errorstate;
phungductung 0:e87aa4c49e95 2449 }
phungductung 0:e87aa4c49e95 2450
phungductung 0:e87aa4c49e95 2451 /* CMD8: SEND_IF_COND ------------------------------------------------------*/
phungductung 0:e87aa4c49e95 2452 /* Send CMD8 to verify SD card interface operating condition */
phungductung 0:e87aa4c49e95 2453 /* Argument: - [31:12]: Reserved (shall be set to '0')
phungductung 0:e87aa4c49e95 2454 - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
phungductung 0:e87aa4c49e95 2455 - [7:0]: Check Pattern (recommended 0xAA) */
phungductung 0:e87aa4c49e95 2456 /* CMD Response: R7 */
phungductung 0:e87aa4c49e95 2457 sdmmc_cmdinitstructure.Argument = SD_CHECK_PATTERN;
phungductung 0:e87aa4c49e95 2458 sdmmc_cmdinitstructure.CmdIndex = SD_SDMMC_SEND_IF_COND;
phungductung 0:e87aa4c49e95 2459 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 2460 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2461
phungductung 0:e87aa4c49e95 2462 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2463 errorstate = SD_CmdResp7Error(hsd);
phungductung 0:e87aa4c49e95 2464
phungductung 0:e87aa4c49e95 2465 if (errorstate == SD_OK)
phungductung 0:e87aa4c49e95 2466 {
phungductung 0:e87aa4c49e95 2467 /* SD Card 2.0 */
phungductung 0:e87aa4c49e95 2468 hsd->CardType = STD_CAPACITY_SD_CARD_V2_0;
phungductung 0:e87aa4c49e95 2469 sdtype = SD_HIGH_CAPACITY;
phungductung 0:e87aa4c49e95 2470 }
phungductung 0:e87aa4c49e95 2471
phungductung 0:e87aa4c49e95 2472 /* Send CMD55 */
phungductung 0:e87aa4c49e95 2473 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 2474 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
phungductung 0:e87aa4c49e95 2475 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2476
phungductung 0:e87aa4c49e95 2477 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2478 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
phungductung 0:e87aa4c49e95 2479
phungductung 0:e87aa4c49e95 2480 /* If errorstate is Command Timeout, it is a MMC card */
phungductung 0:e87aa4c49e95 2481 /* If errorstate is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)
phungductung 0:e87aa4c49e95 2482 or SD card 1.x */
phungductung 0:e87aa4c49e95 2483 if(errorstate == SD_OK)
phungductung 0:e87aa4c49e95 2484 {
phungductung 0:e87aa4c49e95 2485 /* SD CARD */
phungductung 0:e87aa4c49e95 2486 /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
phungductung 0:e87aa4c49e95 2487 while((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))
phungductung 0:e87aa4c49e95 2488 {
phungductung 0:e87aa4c49e95 2489
phungductung 0:e87aa4c49e95 2490 /* SEND CMD55 APP_CMD with RCA as 0 */
phungductung 0:e87aa4c49e95 2491 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 2492 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
phungductung 0:e87aa4c49e95 2493 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 2494 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 2495 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 2496 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2497
phungductung 0:e87aa4c49e95 2498 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2499 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
phungductung 0:e87aa4c49e95 2500
phungductung 0:e87aa4c49e95 2501 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2502 {
phungductung 0:e87aa4c49e95 2503 return errorstate;
phungductung 0:e87aa4c49e95 2504 }
phungductung 0:e87aa4c49e95 2505
phungductung 0:e87aa4c49e95 2506 /* Send CMD41 */
phungductung 0:e87aa4c49e95 2507 sdmmc_cmdinitstructure.Argument = SD_VOLTAGE_WINDOW_SD | sdtype;
phungductung 0:e87aa4c49e95 2508 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_OP_COND;
phungductung 0:e87aa4c49e95 2509 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 2510 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 2511 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 2512 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2513
phungductung 0:e87aa4c49e95 2514 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2515 errorstate = SD_CmdResp3Error(hsd);
phungductung 0:e87aa4c49e95 2516
phungductung 0:e87aa4c49e95 2517 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2518 {
phungductung 0:e87aa4c49e95 2519 return errorstate;
phungductung 0:e87aa4c49e95 2520 }
phungductung 0:e87aa4c49e95 2521
phungductung 0:e87aa4c49e95 2522 /* Get command response */
phungductung 0:e87aa4c49e95 2523 response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 2524
phungductung 0:e87aa4c49e95 2525 /* Get operating voltage*/
phungductung 0:e87aa4c49e95 2526 validvoltage = (((response >> 31) == 1) ? 1 : 0);
phungductung 0:e87aa4c49e95 2527
phungductung 0:e87aa4c49e95 2528 count++;
phungductung 0:e87aa4c49e95 2529 }
phungductung 0:e87aa4c49e95 2530
phungductung 0:e87aa4c49e95 2531 if(count >= SD_MAX_VOLT_TRIAL)
phungductung 0:e87aa4c49e95 2532 {
phungductung 0:e87aa4c49e95 2533 errorstate = SD_INVALID_VOLTRANGE;
phungductung 0:e87aa4c49e95 2534
phungductung 0:e87aa4c49e95 2535 return errorstate;
phungductung 0:e87aa4c49e95 2536 }
phungductung 0:e87aa4c49e95 2537
phungductung 0:e87aa4c49e95 2538 if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */
phungductung 0:e87aa4c49e95 2539 {
phungductung 0:e87aa4c49e95 2540 hsd->CardType = HIGH_CAPACITY_SD_CARD;
phungductung 0:e87aa4c49e95 2541 }
phungductung 0:e87aa4c49e95 2542
phungductung 0:e87aa4c49e95 2543 } /* else MMC Card */
phungductung 0:e87aa4c49e95 2544
phungductung 0:e87aa4c49e95 2545 return errorstate;
phungductung 0:e87aa4c49e95 2546 }
phungductung 0:e87aa4c49e95 2547
phungductung 0:e87aa4c49e95 2548 /**
phungductung 0:e87aa4c49e95 2549 * @brief Turns the SDMMC output signals off.
phungductung 0:e87aa4c49e95 2550 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2551 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2552 */
phungductung 0:e87aa4c49e95 2553 static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2554 {
phungductung 0:e87aa4c49e95 2555 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2556
phungductung 0:e87aa4c49e95 2557 /* Set Power State to OFF */
phungductung 0:e87aa4c49e95 2558 SDMMC_PowerState_OFF(hsd->Instance);
phungductung 0:e87aa4c49e95 2559
phungductung 0:e87aa4c49e95 2560 return errorstate;
phungductung 0:e87aa4c49e95 2561 }
phungductung 0:e87aa4c49e95 2562
phungductung 0:e87aa4c49e95 2563 /**
phungductung 0:e87aa4c49e95 2564 * @brief Returns the current card's status.
phungductung 0:e87aa4c49e95 2565 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2566 * @param pCardStatus: pointer to the buffer that will contain the SD card
phungductung 0:e87aa4c49e95 2567 * status (Card Status register)
phungductung 0:e87aa4c49e95 2568 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2569 */
phungductung 0:e87aa4c49e95 2570 static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)
phungductung 0:e87aa4c49e95 2571 {
phungductung 0:e87aa4c49e95 2572 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 2573 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2574
phungductung 0:e87aa4c49e95 2575 if(pCardStatus == NULL)
phungductung 0:e87aa4c49e95 2576 {
phungductung 0:e87aa4c49e95 2577 errorstate = SD_INVALID_PARAMETER;
phungductung 0:e87aa4c49e95 2578
phungductung 0:e87aa4c49e95 2579 return errorstate;
phungductung 0:e87aa4c49e95 2580 }
phungductung 0:e87aa4c49e95 2581
phungductung 0:e87aa4c49e95 2582 /* Send Status command */
phungductung 0:e87aa4c49e95 2583 sdmmc_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
phungductung 0:e87aa4c49e95 2584 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SEND_STATUS;
phungductung 0:e87aa4c49e95 2585 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 2586 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 2587 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 2588 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 2589
phungductung 0:e87aa4c49e95 2590 /* Check for error conditions */
phungductung 0:e87aa4c49e95 2591 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEND_STATUS);
phungductung 0:e87aa4c49e95 2592
phungductung 0:e87aa4c49e95 2593 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2594 {
phungductung 0:e87aa4c49e95 2595 return errorstate;
phungductung 0:e87aa4c49e95 2596 }
phungductung 0:e87aa4c49e95 2597
phungductung 0:e87aa4c49e95 2598 /* Get SD card status */
phungductung 0:e87aa4c49e95 2599 *pCardStatus = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 2600
phungductung 0:e87aa4c49e95 2601 return errorstate;
phungductung 0:e87aa4c49e95 2602 }
phungductung 0:e87aa4c49e95 2603
phungductung 0:e87aa4c49e95 2604 /**
phungductung 0:e87aa4c49e95 2605 * @brief Checks for error conditions for CMD0.
phungductung 0:e87aa4c49e95 2606 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2607 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2608 */
phungductung 0:e87aa4c49e95 2609 static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2610 {
phungductung 0:e87aa4c49e95 2611 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2612 uint32_t timeout, tmp;
phungductung 0:e87aa4c49e95 2613
phungductung 0:e87aa4c49e95 2614 timeout = SDMMC_CMD0TIMEOUT;
phungductung 0:e87aa4c49e95 2615
phungductung 0:e87aa4c49e95 2616 tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CMDSENT);
phungductung 0:e87aa4c49e95 2617
phungductung 0:e87aa4c49e95 2618 while((timeout > 0) && (!tmp))
phungductung 0:e87aa4c49e95 2619 {
phungductung 0:e87aa4c49e95 2620 tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CMDSENT);
phungductung 0:e87aa4c49e95 2621 timeout--;
phungductung 0:e87aa4c49e95 2622 }
phungductung 0:e87aa4c49e95 2623
phungductung 0:e87aa4c49e95 2624 if(timeout == 0)
phungductung 0:e87aa4c49e95 2625 {
phungductung 0:e87aa4c49e95 2626 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 2627 return errorstate;
phungductung 0:e87aa4c49e95 2628 }
phungductung 0:e87aa4c49e95 2629
phungductung 0:e87aa4c49e95 2630 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 2631 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 2632
phungductung 0:e87aa4c49e95 2633 return errorstate;
phungductung 0:e87aa4c49e95 2634 }
phungductung 0:e87aa4c49e95 2635
phungductung 0:e87aa4c49e95 2636 /**
phungductung 0:e87aa4c49e95 2637 * @brief Checks for error conditions for R7 response.
phungductung 0:e87aa4c49e95 2638 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2639 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2640 */
phungductung 0:e87aa4c49e95 2641 static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2642 {
phungductung 0:e87aa4c49e95 2643 HAL_SD_ErrorTypedef errorstate = SD_ERROR;
phungductung 0:e87aa4c49e95 2644 uint32_t timeout = SDMMC_CMD0TIMEOUT, tmp;
phungductung 0:e87aa4c49e95 2645
phungductung 0:e87aa4c49e95 2646 tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2647
phungductung 0:e87aa4c49e95 2648 while((!tmp) && (timeout > 0))
phungductung 0:e87aa4c49e95 2649 {
phungductung 0:e87aa4c49e95 2650 tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2651 timeout--;
phungductung 0:e87aa4c49e95 2652 }
phungductung 0:e87aa4c49e95 2653
phungductung 0:e87aa4c49e95 2654 tmp = __HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2655
phungductung 0:e87aa4c49e95 2656 if((timeout == 0) || tmp)
phungductung 0:e87aa4c49e95 2657 {
phungductung 0:e87aa4c49e95 2658 /* Card is not V2.0 compliant or card does not support the set voltage range */
phungductung 0:e87aa4c49e95 2659 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 2660
phungductung 0:e87aa4c49e95 2661 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2662
phungductung 0:e87aa4c49e95 2663 return errorstate;
phungductung 0:e87aa4c49e95 2664 }
phungductung 0:e87aa4c49e95 2665
phungductung 0:e87aa4c49e95 2666 if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CMDREND))
phungductung 0:e87aa4c49e95 2667 {
phungductung 0:e87aa4c49e95 2668 /* Card is SD V2.0 compliant */
phungductung 0:e87aa4c49e95 2669 errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2670
phungductung 0:e87aa4c49e95 2671 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CMDREND);
phungductung 0:e87aa4c49e95 2672
phungductung 0:e87aa4c49e95 2673 return errorstate;
phungductung 0:e87aa4c49e95 2674 }
phungductung 0:e87aa4c49e95 2675
phungductung 0:e87aa4c49e95 2676 return errorstate;
phungductung 0:e87aa4c49e95 2677 }
phungductung 0:e87aa4c49e95 2678
phungductung 0:e87aa4c49e95 2679 /**
phungductung 0:e87aa4c49e95 2680 * @brief Checks for error conditions for R1 response.
phungductung 0:e87aa4c49e95 2681 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2682 * @param SD_CMD: The sent command index
phungductung 0:e87aa4c49e95 2683 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2684 */
phungductung 0:e87aa4c49e95 2685 static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD)
phungductung 0:e87aa4c49e95 2686 {
phungductung 0:e87aa4c49e95 2687 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2688 uint32_t response_r1;
phungductung 0:e87aa4c49e95 2689
phungductung 0:e87aa4c49e95 2690 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2691 {
phungductung 0:e87aa4c49e95 2692 }
phungductung 0:e87aa4c49e95 2693
phungductung 0:e87aa4c49e95 2694 if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2695 {
phungductung 0:e87aa4c49e95 2696 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 2697
phungductung 0:e87aa4c49e95 2698 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2699
phungductung 0:e87aa4c49e95 2700 return errorstate;
phungductung 0:e87aa4c49e95 2701 }
phungductung 0:e87aa4c49e95 2702 else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))
phungductung 0:e87aa4c49e95 2703 {
phungductung 0:e87aa4c49e95 2704 errorstate = SD_CMD_CRC_FAIL;
phungductung 0:e87aa4c49e95 2705
phungductung 0:e87aa4c49e95 2706 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);
phungductung 0:e87aa4c49e95 2707
phungductung 0:e87aa4c49e95 2708 return errorstate;
phungductung 0:e87aa4c49e95 2709 }
phungductung 0:e87aa4c49e95 2710
phungductung 0:e87aa4c49e95 2711 /* Check response received is of desired command */
phungductung 0:e87aa4c49e95 2712 if(SDMMC_GetCommandResponse(hsd->Instance) != SD_CMD)
phungductung 0:e87aa4c49e95 2713 {
phungductung 0:e87aa4c49e95 2714 errorstate = SD_ILLEGAL_CMD;
phungductung 0:e87aa4c49e95 2715
phungductung 0:e87aa4c49e95 2716 return errorstate;
phungductung 0:e87aa4c49e95 2717 }
phungductung 0:e87aa4c49e95 2718
phungductung 0:e87aa4c49e95 2719 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 2720 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 2721
phungductung 0:e87aa4c49e95 2722 /* We have received response, retrieve it for analysis */
phungductung 0:e87aa4c49e95 2723 response_r1 = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 2724
phungductung 0:e87aa4c49e95 2725 if((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO)
phungductung 0:e87aa4c49e95 2726 {
phungductung 0:e87aa4c49e95 2727 return errorstate;
phungductung 0:e87aa4c49e95 2728 }
phungductung 0:e87aa4c49e95 2729
phungductung 0:e87aa4c49e95 2730 if((response_r1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)
phungductung 0:e87aa4c49e95 2731 {
phungductung 0:e87aa4c49e95 2732 return(SD_ADDR_OUT_OF_RANGE);
phungductung 0:e87aa4c49e95 2733 }
phungductung 0:e87aa4c49e95 2734
phungductung 0:e87aa4c49e95 2735 if((response_r1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)
phungductung 0:e87aa4c49e95 2736 {
phungductung 0:e87aa4c49e95 2737 return(SD_ADDR_MISALIGNED);
phungductung 0:e87aa4c49e95 2738 }
phungductung 0:e87aa4c49e95 2739
phungductung 0:e87aa4c49e95 2740 if((response_r1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)
phungductung 0:e87aa4c49e95 2741 {
phungductung 0:e87aa4c49e95 2742 return(SD_BLOCK_LEN_ERR);
phungductung 0:e87aa4c49e95 2743 }
phungductung 0:e87aa4c49e95 2744
phungductung 0:e87aa4c49e95 2745 if((response_r1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)
phungductung 0:e87aa4c49e95 2746 {
phungductung 0:e87aa4c49e95 2747 return(SD_ERASE_SEQ_ERR);
phungductung 0:e87aa4c49e95 2748 }
phungductung 0:e87aa4c49e95 2749
phungductung 0:e87aa4c49e95 2750 if((response_r1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)
phungductung 0:e87aa4c49e95 2751 {
phungductung 0:e87aa4c49e95 2752 return(SD_BAD_ERASE_PARAM);
phungductung 0:e87aa4c49e95 2753 }
phungductung 0:e87aa4c49e95 2754
phungductung 0:e87aa4c49e95 2755 if((response_r1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)
phungductung 0:e87aa4c49e95 2756 {
phungductung 0:e87aa4c49e95 2757 return(SD_WRITE_PROT_VIOLATION);
phungductung 0:e87aa4c49e95 2758 }
phungductung 0:e87aa4c49e95 2759
phungductung 0:e87aa4c49e95 2760 if((response_r1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)
phungductung 0:e87aa4c49e95 2761 {
phungductung 0:e87aa4c49e95 2762 return(SD_LOCK_UNLOCK_FAILED);
phungductung 0:e87aa4c49e95 2763 }
phungductung 0:e87aa4c49e95 2764
phungductung 0:e87aa4c49e95 2765 if((response_r1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)
phungductung 0:e87aa4c49e95 2766 {
phungductung 0:e87aa4c49e95 2767 return(SD_COM_CRC_FAILED);
phungductung 0:e87aa4c49e95 2768 }
phungductung 0:e87aa4c49e95 2769
phungductung 0:e87aa4c49e95 2770 if((response_r1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)
phungductung 0:e87aa4c49e95 2771 {
phungductung 0:e87aa4c49e95 2772 return(SD_ILLEGAL_CMD);
phungductung 0:e87aa4c49e95 2773 }
phungductung 0:e87aa4c49e95 2774
phungductung 0:e87aa4c49e95 2775 if((response_r1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)
phungductung 0:e87aa4c49e95 2776 {
phungductung 0:e87aa4c49e95 2777 return(SD_CARD_ECC_FAILED);
phungductung 0:e87aa4c49e95 2778 }
phungductung 0:e87aa4c49e95 2779
phungductung 0:e87aa4c49e95 2780 if((response_r1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)
phungductung 0:e87aa4c49e95 2781 {
phungductung 0:e87aa4c49e95 2782 return(SD_CC_ERROR);
phungductung 0:e87aa4c49e95 2783 }
phungductung 0:e87aa4c49e95 2784
phungductung 0:e87aa4c49e95 2785 if((response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)
phungductung 0:e87aa4c49e95 2786 {
phungductung 0:e87aa4c49e95 2787 return(SD_GENERAL_UNKNOWN_ERROR);
phungductung 0:e87aa4c49e95 2788 }
phungductung 0:e87aa4c49e95 2789
phungductung 0:e87aa4c49e95 2790 if((response_r1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)
phungductung 0:e87aa4c49e95 2791 {
phungductung 0:e87aa4c49e95 2792 return(SD_STREAM_READ_UNDERRUN);
phungductung 0:e87aa4c49e95 2793 }
phungductung 0:e87aa4c49e95 2794
phungductung 0:e87aa4c49e95 2795 if((response_r1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)
phungductung 0:e87aa4c49e95 2796 {
phungductung 0:e87aa4c49e95 2797 return(SD_STREAM_WRITE_OVERRUN);
phungductung 0:e87aa4c49e95 2798 }
phungductung 0:e87aa4c49e95 2799
phungductung 0:e87aa4c49e95 2800 if((response_r1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE)
phungductung 0:e87aa4c49e95 2801 {
phungductung 0:e87aa4c49e95 2802 return(SD_CID_CSD_OVERWRITE);
phungductung 0:e87aa4c49e95 2803 }
phungductung 0:e87aa4c49e95 2804
phungductung 0:e87aa4c49e95 2805 if((response_r1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)
phungductung 0:e87aa4c49e95 2806 {
phungductung 0:e87aa4c49e95 2807 return(SD_WP_ERASE_SKIP);
phungductung 0:e87aa4c49e95 2808 }
phungductung 0:e87aa4c49e95 2809
phungductung 0:e87aa4c49e95 2810 if((response_r1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)
phungductung 0:e87aa4c49e95 2811 {
phungductung 0:e87aa4c49e95 2812 return(SD_CARD_ECC_DISABLED);
phungductung 0:e87aa4c49e95 2813 }
phungductung 0:e87aa4c49e95 2814
phungductung 0:e87aa4c49e95 2815 if((response_r1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)
phungductung 0:e87aa4c49e95 2816 {
phungductung 0:e87aa4c49e95 2817 return(SD_ERASE_RESET);
phungductung 0:e87aa4c49e95 2818 }
phungductung 0:e87aa4c49e95 2819
phungductung 0:e87aa4c49e95 2820 if((response_r1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)
phungductung 0:e87aa4c49e95 2821 {
phungductung 0:e87aa4c49e95 2822 return(SD_AKE_SEQ_ERROR);
phungductung 0:e87aa4c49e95 2823 }
phungductung 0:e87aa4c49e95 2824
phungductung 0:e87aa4c49e95 2825 return errorstate;
phungductung 0:e87aa4c49e95 2826 }
phungductung 0:e87aa4c49e95 2827
phungductung 0:e87aa4c49e95 2828 /**
phungductung 0:e87aa4c49e95 2829 * @brief Checks for error conditions for R3 (OCR) response.
phungductung 0:e87aa4c49e95 2830 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2831 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2832 */
phungductung 0:e87aa4c49e95 2833 static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2834 {
phungductung 0:e87aa4c49e95 2835 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2836
phungductung 0:e87aa4c49e95 2837 while (!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2838 {
phungductung 0:e87aa4c49e95 2839 }
phungductung 0:e87aa4c49e95 2840
phungductung 0:e87aa4c49e95 2841 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2842 {
phungductung 0:e87aa4c49e95 2843 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 2844
phungductung 0:e87aa4c49e95 2845 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2846
phungductung 0:e87aa4c49e95 2847 return errorstate;
phungductung 0:e87aa4c49e95 2848 }
phungductung 0:e87aa4c49e95 2849
phungductung 0:e87aa4c49e95 2850 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 2851 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 2852
phungductung 0:e87aa4c49e95 2853 return errorstate;
phungductung 0:e87aa4c49e95 2854 }
phungductung 0:e87aa4c49e95 2855
phungductung 0:e87aa4c49e95 2856 /**
phungductung 0:e87aa4c49e95 2857 * @brief Checks for error conditions for R2 (CID or CSD) response.
phungductung 0:e87aa4c49e95 2858 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2859 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2860 */
phungductung 0:e87aa4c49e95 2861 static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2862 {
phungductung 0:e87aa4c49e95 2863 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2864
phungductung 0:e87aa4c49e95 2865 while (!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2866 {
phungductung 0:e87aa4c49e95 2867 }
phungductung 0:e87aa4c49e95 2868
phungductung 0:e87aa4c49e95 2869 if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2870 {
phungductung 0:e87aa4c49e95 2871 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 2872
phungductung 0:e87aa4c49e95 2873 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2874
phungductung 0:e87aa4c49e95 2875 return errorstate;
phungductung 0:e87aa4c49e95 2876 }
phungductung 0:e87aa4c49e95 2877 else if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))
phungductung 0:e87aa4c49e95 2878 {
phungductung 0:e87aa4c49e95 2879 errorstate = SD_CMD_CRC_FAIL;
phungductung 0:e87aa4c49e95 2880
phungductung 0:e87aa4c49e95 2881 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);
phungductung 0:e87aa4c49e95 2882
phungductung 0:e87aa4c49e95 2883 return errorstate;
phungductung 0:e87aa4c49e95 2884 }
phungductung 0:e87aa4c49e95 2885 else
phungductung 0:e87aa4c49e95 2886 {
phungductung 0:e87aa4c49e95 2887 /* No error flag set */
phungductung 0:e87aa4c49e95 2888 }
phungductung 0:e87aa4c49e95 2889
phungductung 0:e87aa4c49e95 2890 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 2891 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 2892
phungductung 0:e87aa4c49e95 2893 return errorstate;
phungductung 0:e87aa4c49e95 2894 }
phungductung 0:e87aa4c49e95 2895
phungductung 0:e87aa4c49e95 2896 /**
phungductung 0:e87aa4c49e95 2897 * @brief Checks for error conditions for R6 (RCA) response.
phungductung 0:e87aa4c49e95 2898 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2899 * @param SD_CMD: The sent command index
phungductung 0:e87aa4c49e95 2900 * @param pRCA: Pointer to the variable that will contain the SD card relative
phungductung 0:e87aa4c49e95 2901 * address RCA
phungductung 0:e87aa4c49e95 2902 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2903 */
phungductung 0:e87aa4c49e95 2904 static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA)
phungductung 0:e87aa4c49e95 2905 {
phungductung 0:e87aa4c49e95 2906 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2907 uint32_t response_r1;
phungductung 0:e87aa4c49e95 2908
phungductung 0:e87aa4c49e95 2909 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2910 {
phungductung 0:e87aa4c49e95 2911 }
phungductung 0:e87aa4c49e95 2912
phungductung 0:e87aa4c49e95 2913 if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 2914 {
phungductung 0:e87aa4c49e95 2915 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 2916
phungductung 0:e87aa4c49e95 2917 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 2918
phungductung 0:e87aa4c49e95 2919 return errorstate;
phungductung 0:e87aa4c49e95 2920 }
phungductung 0:e87aa4c49e95 2921 else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))
phungductung 0:e87aa4c49e95 2922 {
phungductung 0:e87aa4c49e95 2923 errorstate = SD_CMD_CRC_FAIL;
phungductung 0:e87aa4c49e95 2924
phungductung 0:e87aa4c49e95 2925 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);
phungductung 0:e87aa4c49e95 2926
phungductung 0:e87aa4c49e95 2927 return errorstate;
phungductung 0:e87aa4c49e95 2928 }
phungductung 0:e87aa4c49e95 2929 else
phungductung 0:e87aa4c49e95 2930 {
phungductung 0:e87aa4c49e95 2931 /* No error flag set */
phungductung 0:e87aa4c49e95 2932 }
phungductung 0:e87aa4c49e95 2933
phungductung 0:e87aa4c49e95 2934 /* Check response received is of desired command */
phungductung 0:e87aa4c49e95 2935 if(SDMMC_GetCommandResponse(hsd->Instance) != SD_CMD)
phungductung 0:e87aa4c49e95 2936 {
phungductung 0:e87aa4c49e95 2937 errorstate = SD_ILLEGAL_CMD;
phungductung 0:e87aa4c49e95 2938
phungductung 0:e87aa4c49e95 2939 return errorstate;
phungductung 0:e87aa4c49e95 2940 }
phungductung 0:e87aa4c49e95 2941
phungductung 0:e87aa4c49e95 2942 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 2943 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 2944
phungductung 0:e87aa4c49e95 2945 /* We have received response, retrieve it. */
phungductung 0:e87aa4c49e95 2946 response_r1 = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 2947
phungductung 0:e87aa4c49e95 2948 if((response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)) == SD_ALLZERO)
phungductung 0:e87aa4c49e95 2949 {
phungductung 0:e87aa4c49e95 2950 *pRCA = (uint16_t) (response_r1 >> 16);
phungductung 0:e87aa4c49e95 2951
phungductung 0:e87aa4c49e95 2952 return errorstate;
phungductung 0:e87aa4c49e95 2953 }
phungductung 0:e87aa4c49e95 2954
phungductung 0:e87aa4c49e95 2955 if((response_r1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR)
phungductung 0:e87aa4c49e95 2956 {
phungductung 0:e87aa4c49e95 2957 return(SD_GENERAL_UNKNOWN_ERROR);
phungductung 0:e87aa4c49e95 2958 }
phungductung 0:e87aa4c49e95 2959
phungductung 0:e87aa4c49e95 2960 if((response_r1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD)
phungductung 0:e87aa4c49e95 2961 {
phungductung 0:e87aa4c49e95 2962 return(SD_ILLEGAL_CMD);
phungductung 0:e87aa4c49e95 2963 }
phungductung 0:e87aa4c49e95 2964
phungductung 0:e87aa4c49e95 2965 if((response_r1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED)
phungductung 0:e87aa4c49e95 2966 {
phungductung 0:e87aa4c49e95 2967 return(SD_COM_CRC_FAILED);
phungductung 0:e87aa4c49e95 2968 }
phungductung 0:e87aa4c49e95 2969
phungductung 0:e87aa4c49e95 2970 return errorstate;
phungductung 0:e87aa4c49e95 2971 }
phungductung 0:e87aa4c49e95 2972
phungductung 0:e87aa4c49e95 2973 /**
phungductung 0:e87aa4c49e95 2974 * @brief Enables the SDMMC wide bus mode.
phungductung 0:e87aa4c49e95 2975 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 2976 * @retval SD Card error state
phungductung 0:e87aa4c49e95 2977 */
phungductung 0:e87aa4c49e95 2978 static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 2979 {
phungductung 0:e87aa4c49e95 2980 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 2981 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 2982
phungductung 0:e87aa4c49e95 2983 uint32_t scr[2] = {0, 0};
phungductung 0:e87aa4c49e95 2984
phungductung 0:e87aa4c49e95 2985 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
phungductung 0:e87aa4c49e95 2986 {
phungductung 0:e87aa4c49e95 2987 errorstate = SD_LOCK_UNLOCK_FAILED;
phungductung 0:e87aa4c49e95 2988
phungductung 0:e87aa4c49e95 2989 return errorstate;
phungductung 0:e87aa4c49e95 2990 }
phungductung 0:e87aa4c49e95 2991
phungductung 0:e87aa4c49e95 2992 /* Get SCR Register */
phungductung 0:e87aa4c49e95 2993 errorstate = SD_FindSCR(hsd, scr);
phungductung 0:e87aa4c49e95 2994
phungductung 0:e87aa4c49e95 2995 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 2996 {
phungductung 0:e87aa4c49e95 2997 return errorstate;
phungductung 0:e87aa4c49e95 2998 }
phungductung 0:e87aa4c49e95 2999
phungductung 0:e87aa4c49e95 3000 /* If requested card supports wide bus operation */
phungductung 0:e87aa4c49e95 3001 if((scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO)
phungductung 0:e87aa4c49e95 3002 {
phungductung 0:e87aa4c49e95 3003 /* Send CMD55 APP_CMD with argument as card's RCA.*/
phungductung 0:e87aa4c49e95 3004 sdmmc_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
phungductung 0:e87aa4c49e95 3005 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
phungductung 0:e87aa4c49e95 3006 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 3007 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 3008 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 3009 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3010
phungductung 0:e87aa4c49e95 3011 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3012 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
phungductung 0:e87aa4c49e95 3013
phungductung 0:e87aa4c49e95 3014 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3015 {
phungductung 0:e87aa4c49e95 3016 return errorstate;
phungductung 0:e87aa4c49e95 3017 }
phungductung 0:e87aa4c49e95 3018
phungductung 0:e87aa4c49e95 3019 /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
phungductung 0:e87aa4c49e95 3020 sdmmc_cmdinitstructure.Argument = 2;
phungductung 0:e87aa4c49e95 3021 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
phungductung 0:e87aa4c49e95 3022 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3023
phungductung 0:e87aa4c49e95 3024 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3025 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);
phungductung 0:e87aa4c49e95 3026
phungductung 0:e87aa4c49e95 3027 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3028 {
phungductung 0:e87aa4c49e95 3029 return errorstate;
phungductung 0:e87aa4c49e95 3030 }
phungductung 0:e87aa4c49e95 3031
phungductung 0:e87aa4c49e95 3032 return errorstate;
phungductung 0:e87aa4c49e95 3033 }
phungductung 0:e87aa4c49e95 3034 else
phungductung 0:e87aa4c49e95 3035 {
phungductung 0:e87aa4c49e95 3036 errorstate = SD_REQUEST_NOT_APPLICABLE;
phungductung 0:e87aa4c49e95 3037
phungductung 0:e87aa4c49e95 3038 return errorstate;
phungductung 0:e87aa4c49e95 3039 }
phungductung 0:e87aa4c49e95 3040 }
phungductung 0:e87aa4c49e95 3041
phungductung 0:e87aa4c49e95 3042 /**
phungductung 0:e87aa4c49e95 3043 * @brief Disables the SDMMC wide bus mode.
phungductung 0:e87aa4c49e95 3044 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 3045 * @retval SD Card error state
phungductung 0:e87aa4c49e95 3046 */
phungductung 0:e87aa4c49e95 3047 static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd)
phungductung 0:e87aa4c49e95 3048 {
phungductung 0:e87aa4c49e95 3049 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 3050 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 3051
phungductung 0:e87aa4c49e95 3052 uint32_t scr[2] = {0, 0};
phungductung 0:e87aa4c49e95 3053
phungductung 0:e87aa4c49e95 3054 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED)
phungductung 0:e87aa4c49e95 3055 {
phungductung 0:e87aa4c49e95 3056 errorstate = SD_LOCK_UNLOCK_FAILED;
phungductung 0:e87aa4c49e95 3057
phungductung 0:e87aa4c49e95 3058 return errorstate;
phungductung 0:e87aa4c49e95 3059 }
phungductung 0:e87aa4c49e95 3060
phungductung 0:e87aa4c49e95 3061 /* Get SCR Register */
phungductung 0:e87aa4c49e95 3062 errorstate = SD_FindSCR(hsd, scr);
phungductung 0:e87aa4c49e95 3063
phungductung 0:e87aa4c49e95 3064 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3065 {
phungductung 0:e87aa4c49e95 3066 return errorstate;
phungductung 0:e87aa4c49e95 3067 }
phungductung 0:e87aa4c49e95 3068
phungductung 0:e87aa4c49e95 3069 /* If requested card supports 1 bit mode operation */
phungductung 0:e87aa4c49e95 3070 if((scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO)
phungductung 0:e87aa4c49e95 3071 {
phungductung 0:e87aa4c49e95 3072 /* Send CMD55 APP_CMD with argument as card's RCA */
phungductung 0:e87aa4c49e95 3073 sdmmc_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
phungductung 0:e87aa4c49e95 3074 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
phungductung 0:e87aa4c49e95 3075 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 3076 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 3077 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 3078 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3079
phungductung 0:e87aa4c49e95 3080 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3081 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
phungductung 0:e87aa4c49e95 3082
phungductung 0:e87aa4c49e95 3083 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3084 {
phungductung 0:e87aa4c49e95 3085 return errorstate;
phungductung 0:e87aa4c49e95 3086 }
phungductung 0:e87aa4c49e95 3087
phungductung 0:e87aa4c49e95 3088 /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */
phungductung 0:e87aa4c49e95 3089 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 3090 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
phungductung 0:e87aa4c49e95 3091 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3092
phungductung 0:e87aa4c49e95 3093 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3094 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH);
phungductung 0:e87aa4c49e95 3095
phungductung 0:e87aa4c49e95 3096 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3097 {
phungductung 0:e87aa4c49e95 3098 return errorstate;
phungductung 0:e87aa4c49e95 3099 }
phungductung 0:e87aa4c49e95 3100
phungductung 0:e87aa4c49e95 3101 return errorstate;
phungductung 0:e87aa4c49e95 3102 }
phungductung 0:e87aa4c49e95 3103 else
phungductung 0:e87aa4c49e95 3104 {
phungductung 0:e87aa4c49e95 3105 errorstate = SD_REQUEST_NOT_APPLICABLE;
phungductung 0:e87aa4c49e95 3106
phungductung 0:e87aa4c49e95 3107 return errorstate;
phungductung 0:e87aa4c49e95 3108 }
phungductung 0:e87aa4c49e95 3109 }
phungductung 0:e87aa4c49e95 3110
phungductung 0:e87aa4c49e95 3111
phungductung 0:e87aa4c49e95 3112 /**
phungductung 0:e87aa4c49e95 3113 * @brief Finds the SD card SCR register value.
phungductung 0:e87aa4c49e95 3114 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 3115 * @param pSCR: pointer to the buffer that will contain the SCR value
phungductung 0:e87aa4c49e95 3116 * @retval SD Card error state
phungductung 0:e87aa4c49e95 3117 */
phungductung 0:e87aa4c49e95 3118 static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
phungductung 0:e87aa4c49e95 3119 {
phungductung 0:e87aa4c49e95 3120 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 3121 SDMMC_DataInitTypeDef sdmmc_datainitstructure;
phungductung 0:e87aa4c49e95 3122 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 3123 uint32_t index = 0;
phungductung 0:e87aa4c49e95 3124 uint32_t tempscr[2] = {0, 0};
phungductung 0:e87aa4c49e95 3125
phungductung 0:e87aa4c49e95 3126 /* Set Block Size To 8 Bytes */
phungductung 0:e87aa4c49e95 3127 /* Send CMD55 APP_CMD with argument as card's RCA */
phungductung 0:e87aa4c49e95 3128 sdmmc_cmdinitstructure.Argument = (uint32_t)8;
phungductung 0:e87aa4c49e95 3129 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN;
phungductung 0:e87aa4c49e95 3130 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 3131 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 3132 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 3133 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3134
phungductung 0:e87aa4c49e95 3135 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3136 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN);
phungductung 0:e87aa4c49e95 3137
phungductung 0:e87aa4c49e95 3138 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3139 {
phungductung 0:e87aa4c49e95 3140 return errorstate;
phungductung 0:e87aa4c49e95 3141 }
phungductung 0:e87aa4c49e95 3142
phungductung 0:e87aa4c49e95 3143 /* Send CMD55 APP_CMD with argument as card's RCA */
phungductung 0:e87aa4c49e95 3144 sdmmc_cmdinitstructure.Argument = (uint32_t)((hsd->RCA) << 16);
phungductung 0:e87aa4c49e95 3145 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD;
phungductung 0:e87aa4c49e95 3146 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3147
phungductung 0:e87aa4c49e95 3148 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3149 errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD);
phungductung 0:e87aa4c49e95 3150
phungductung 0:e87aa4c49e95 3151 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3152 {
phungductung 0:e87aa4c49e95 3153 return errorstate;
phungductung 0:e87aa4c49e95 3154 }
phungductung 0:e87aa4c49e95 3155 sdmmc_datainitstructure.DataTimeOut = SD_DATATIMEOUT;
phungductung 0:e87aa4c49e95 3156 sdmmc_datainitstructure.DataLength = 8;
phungductung 0:e87aa4c49e95 3157 sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_8B;
phungductung 0:e87aa4c49e95 3158 sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
phungductung 0:e87aa4c49e95 3159 sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
phungductung 0:e87aa4c49e95 3160 sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE;
phungductung 0:e87aa4c49e95 3161 SDMMC_DataConfig(hsd->Instance, &sdmmc_datainitstructure);
phungductung 0:e87aa4c49e95 3162
phungductung 0:e87aa4c49e95 3163 /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
phungductung 0:e87aa4c49e95 3164 sdmmc_cmdinitstructure.Argument = 0;
phungductung 0:e87aa4c49e95 3165 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_SEND_SCR;
phungductung 0:e87aa4c49e95 3166 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3167
phungductung 0:e87aa4c49e95 3168 /* Check for error conditions */
phungductung 0:e87aa4c49e95 3169 errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_SEND_SCR);
phungductung 0:e87aa4c49e95 3170
phungductung 0:e87aa4c49e95 3171 if(errorstate != SD_OK)
phungductung 0:e87aa4c49e95 3172 {
phungductung 0:e87aa4c49e95 3173 return errorstate;
phungductung 0:e87aa4c49e95 3174 }
phungductung 0:e87aa4c49e95 3175
phungductung 0:e87aa4c49e95 3176 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
phungductung 0:e87aa4c49e95 3177 {
phungductung 0:e87aa4c49e95 3178 if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL))
phungductung 0:e87aa4c49e95 3179 {
phungductung 0:e87aa4c49e95 3180 *(tempscr + index) = SDMMC_ReadFIFO(hsd->Instance);
phungductung 0:e87aa4c49e95 3181 index++;
phungductung 0:e87aa4c49e95 3182 }
phungductung 0:e87aa4c49e95 3183 }
phungductung 0:e87aa4c49e95 3184
phungductung 0:e87aa4c49e95 3185 if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT))
phungductung 0:e87aa4c49e95 3186 {
phungductung 0:e87aa4c49e95 3187 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT);
phungductung 0:e87aa4c49e95 3188
phungductung 0:e87aa4c49e95 3189 errorstate = SD_DATA_TIMEOUT;
phungductung 0:e87aa4c49e95 3190
phungductung 0:e87aa4c49e95 3191 return errorstate;
phungductung 0:e87aa4c49e95 3192 }
phungductung 0:e87aa4c49e95 3193 else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL))
phungductung 0:e87aa4c49e95 3194 {
phungductung 0:e87aa4c49e95 3195 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL);
phungductung 0:e87aa4c49e95 3196
phungductung 0:e87aa4c49e95 3197 errorstate = SD_DATA_CRC_FAIL;
phungductung 0:e87aa4c49e95 3198
phungductung 0:e87aa4c49e95 3199 return errorstate;
phungductung 0:e87aa4c49e95 3200 }
phungductung 0:e87aa4c49e95 3201 else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR))
phungductung 0:e87aa4c49e95 3202 {
phungductung 0:e87aa4c49e95 3203 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR);
phungductung 0:e87aa4c49e95 3204
phungductung 0:e87aa4c49e95 3205 errorstate = SD_RX_OVERRUN;
phungductung 0:e87aa4c49e95 3206
phungductung 0:e87aa4c49e95 3207 return errorstate;
phungductung 0:e87aa4c49e95 3208 }
phungductung 0:e87aa4c49e95 3209 else
phungductung 0:e87aa4c49e95 3210 {
phungductung 0:e87aa4c49e95 3211 /* No error flag set */
phungductung 0:e87aa4c49e95 3212 }
phungductung 0:e87aa4c49e95 3213
phungductung 0:e87aa4c49e95 3214 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 3215 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 3216
phungductung 0:e87aa4c49e95 3217 *(pSCR + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) |\
phungductung 0:e87aa4c49e95 3218 ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24);
phungductung 0:e87aa4c49e95 3219
phungductung 0:e87aa4c49e95 3220 *(pSCR) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) |\
phungductung 0:e87aa4c49e95 3221 ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24);
phungductung 0:e87aa4c49e95 3222
phungductung 0:e87aa4c49e95 3223 return errorstate;
phungductung 0:e87aa4c49e95 3224 }
phungductung 0:e87aa4c49e95 3225
phungductung 0:e87aa4c49e95 3226 /**
phungductung 0:e87aa4c49e95 3227 * @brief Checks if the SD card is in programming state.
phungductung 0:e87aa4c49e95 3228 * @param hsd: SD handle
phungductung 0:e87aa4c49e95 3229 * @param pStatus: pointer to the variable that will contain the SD card state
phungductung 0:e87aa4c49e95 3230 * @retval SD Card error state
phungductung 0:e87aa4c49e95 3231 */
phungductung 0:e87aa4c49e95 3232 static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus)
phungductung 0:e87aa4c49e95 3233 {
phungductung 0:e87aa4c49e95 3234 SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
phungductung 0:e87aa4c49e95 3235 HAL_SD_ErrorTypedef errorstate = SD_OK;
phungductung 0:e87aa4c49e95 3236 __IO uint32_t responseR1 = 0;
phungductung 0:e87aa4c49e95 3237
phungductung 0:e87aa4c49e95 3238 sdmmc_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16);
phungductung 0:e87aa4c49e95 3239 sdmmc_cmdinitstructure.CmdIndex = SD_CMD_SEND_STATUS;
phungductung 0:e87aa4c49e95 3240 sdmmc_cmdinitstructure.Response = SDMMC_RESPONSE_SHORT;
phungductung 0:e87aa4c49e95 3241 sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
phungductung 0:e87aa4c49e95 3242 sdmmc_cmdinitstructure.CPSM = SDMMC_CPSM_ENABLE;
phungductung 0:e87aa4c49e95 3243 SDMMC_SendCommand(hsd->Instance, &sdmmc_cmdinitstructure);
phungductung 0:e87aa4c49e95 3244
phungductung 0:e87aa4c49e95 3245 while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 3246 {
phungductung 0:e87aa4c49e95 3247 }
phungductung 0:e87aa4c49e95 3248
phungductung 0:e87aa4c49e95 3249 if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CTIMEOUT))
phungductung 0:e87aa4c49e95 3250 {
phungductung 0:e87aa4c49e95 3251 errorstate = SD_CMD_RSP_TIMEOUT;
phungductung 0:e87aa4c49e95 3252
phungductung 0:e87aa4c49e95 3253 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CTIMEOUT);
phungductung 0:e87aa4c49e95 3254
phungductung 0:e87aa4c49e95 3255 return errorstate;
phungductung 0:e87aa4c49e95 3256 }
phungductung 0:e87aa4c49e95 3257 else if(__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_CCRCFAIL))
phungductung 0:e87aa4c49e95 3258 {
phungductung 0:e87aa4c49e95 3259 errorstate = SD_CMD_CRC_FAIL;
phungductung 0:e87aa4c49e95 3260
phungductung 0:e87aa4c49e95 3261 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_FLAG_CCRCFAIL);
phungductung 0:e87aa4c49e95 3262
phungductung 0:e87aa4c49e95 3263 return errorstate;
phungductung 0:e87aa4c49e95 3264 }
phungductung 0:e87aa4c49e95 3265 else
phungductung 0:e87aa4c49e95 3266 {
phungductung 0:e87aa4c49e95 3267 /* No error flag set */
phungductung 0:e87aa4c49e95 3268 }
phungductung 0:e87aa4c49e95 3269
phungductung 0:e87aa4c49e95 3270 /* Check response received is of desired command */
phungductung 0:e87aa4c49e95 3271 if((uint32_t)SDMMC_GetCommandResponse(hsd->Instance) != SD_CMD_SEND_STATUS)
phungductung 0:e87aa4c49e95 3272 {
phungductung 0:e87aa4c49e95 3273 errorstate = SD_ILLEGAL_CMD;
phungductung 0:e87aa4c49e95 3274
phungductung 0:e87aa4c49e95 3275 return errorstate;
phungductung 0:e87aa4c49e95 3276 }
phungductung 0:e87aa4c49e95 3277
phungductung 0:e87aa4c49e95 3278 /* Clear all the static flags */
phungductung 0:e87aa4c49e95 3279 __HAL_SD_SDMMC_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
phungductung 0:e87aa4c49e95 3280
phungductung 0:e87aa4c49e95 3281
phungductung 0:e87aa4c49e95 3282 /* We have received response, retrieve it for analysis */
phungductung 0:e87aa4c49e95 3283 responseR1 = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1);
phungductung 0:e87aa4c49e95 3284
phungductung 0:e87aa4c49e95 3285 /* Find out card status */
phungductung 0:e87aa4c49e95 3286 *pStatus = (uint8_t)((responseR1 >> 9) & 0x0000000F);
phungductung 0:e87aa4c49e95 3287
phungductung 0:e87aa4c49e95 3288 if((responseR1 & SD_OCR_ERRORBITS) == SD_ALLZERO)
phungductung 0:e87aa4c49e95 3289 {
phungductung 0:e87aa4c49e95 3290 return errorstate;
phungductung 0:e87aa4c49e95 3291 }
phungductung 0:e87aa4c49e95 3292
phungductung 0:e87aa4c49e95 3293 if((responseR1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE)
phungductung 0:e87aa4c49e95 3294 {
phungductung 0:e87aa4c49e95 3295 return(SD_ADDR_OUT_OF_RANGE);
phungductung 0:e87aa4c49e95 3296 }
phungductung 0:e87aa4c49e95 3297
phungductung 0:e87aa4c49e95 3298 if((responseR1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED)
phungductung 0:e87aa4c49e95 3299 {
phungductung 0:e87aa4c49e95 3300 return(SD_ADDR_MISALIGNED);
phungductung 0:e87aa4c49e95 3301 }
phungductung 0:e87aa4c49e95 3302
phungductung 0:e87aa4c49e95 3303 if((responseR1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR)
phungductung 0:e87aa4c49e95 3304 {
phungductung 0:e87aa4c49e95 3305 return(SD_BLOCK_LEN_ERR);
phungductung 0:e87aa4c49e95 3306 }
phungductung 0:e87aa4c49e95 3307
phungductung 0:e87aa4c49e95 3308 if((responseR1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR)
phungductung 0:e87aa4c49e95 3309 {
phungductung 0:e87aa4c49e95 3310 return(SD_ERASE_SEQ_ERR);
phungductung 0:e87aa4c49e95 3311 }
phungductung 0:e87aa4c49e95 3312
phungductung 0:e87aa4c49e95 3313 if((responseR1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM)
phungductung 0:e87aa4c49e95 3314 {
phungductung 0:e87aa4c49e95 3315 return(SD_BAD_ERASE_PARAM);
phungductung 0:e87aa4c49e95 3316 }
phungductung 0:e87aa4c49e95 3317
phungductung 0:e87aa4c49e95 3318 if((responseR1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION)
phungductung 0:e87aa4c49e95 3319 {
phungductung 0:e87aa4c49e95 3320 return(SD_WRITE_PROT_VIOLATION);
phungductung 0:e87aa4c49e95 3321 }
phungductung 0:e87aa4c49e95 3322
phungductung 0:e87aa4c49e95 3323 if((responseR1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED)
phungductung 0:e87aa4c49e95 3324 {
phungductung 0:e87aa4c49e95 3325 return(SD_LOCK_UNLOCK_FAILED);
phungductung 0:e87aa4c49e95 3326 }
phungductung 0:e87aa4c49e95 3327
phungductung 0:e87aa4c49e95 3328 if((responseR1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED)
phungductung 0:e87aa4c49e95 3329 {
phungductung 0:e87aa4c49e95 3330 return(SD_COM_CRC_FAILED);
phungductung 0:e87aa4c49e95 3331 }
phungductung 0:e87aa4c49e95 3332
phungductung 0:e87aa4c49e95 3333 if((responseR1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)
phungductung 0:e87aa4c49e95 3334 {
phungductung 0:e87aa4c49e95 3335 return(SD_ILLEGAL_CMD);
phungductung 0:e87aa4c49e95 3336 }
phungductung 0:e87aa4c49e95 3337
phungductung 0:e87aa4c49e95 3338 if((responseR1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED)
phungductung 0:e87aa4c49e95 3339 {
phungductung 0:e87aa4c49e95 3340 return(SD_CARD_ECC_FAILED);
phungductung 0:e87aa4c49e95 3341 }
phungductung 0:e87aa4c49e95 3342
phungductung 0:e87aa4c49e95 3343 if((responseR1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR)
phungductung 0:e87aa4c49e95 3344 {
phungductung 0:e87aa4c49e95 3345 return(SD_CC_ERROR);
phungductung 0:e87aa4c49e95 3346 }
phungductung 0:e87aa4c49e95 3347
phungductung 0:e87aa4c49e95 3348 if((responseR1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR)
phungductung 0:e87aa4c49e95 3349 {
phungductung 0:e87aa4c49e95 3350 return(SD_GENERAL_UNKNOWN_ERROR);
phungductung 0:e87aa4c49e95 3351 }
phungductung 0:e87aa4c49e95 3352
phungductung 0:e87aa4c49e95 3353 if((responseR1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN)
phungductung 0:e87aa4c49e95 3354 {
phungductung 0:e87aa4c49e95 3355 return(SD_STREAM_READ_UNDERRUN);
phungductung 0:e87aa4c49e95 3356 }
phungductung 0:e87aa4c49e95 3357
phungductung 0:e87aa4c49e95 3358 if((responseR1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN)
phungductung 0:e87aa4c49e95 3359 {
phungductung 0:e87aa4c49e95 3360 return(SD_STREAM_WRITE_OVERRUN);
phungductung 0:e87aa4c49e95 3361 }
phungductung 0:e87aa4c49e95 3362
phungductung 0:e87aa4c49e95 3363 if((responseR1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE)
phungductung 0:e87aa4c49e95 3364 {
phungductung 0:e87aa4c49e95 3365 return(SD_CID_CSD_OVERWRITE);
phungductung 0:e87aa4c49e95 3366 }
phungductung 0:e87aa4c49e95 3367
phungductung 0:e87aa4c49e95 3368 if((responseR1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP)
phungductung 0:e87aa4c49e95 3369 {
phungductung 0:e87aa4c49e95 3370 return(SD_WP_ERASE_SKIP);
phungductung 0:e87aa4c49e95 3371 }
phungductung 0:e87aa4c49e95 3372
phungductung 0:e87aa4c49e95 3373 if((responseR1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED)
phungductung 0:e87aa4c49e95 3374 {
phungductung 0:e87aa4c49e95 3375 return(SD_CARD_ECC_DISABLED);
phungductung 0:e87aa4c49e95 3376 }
phungductung 0:e87aa4c49e95 3377
phungductung 0:e87aa4c49e95 3378 if((responseR1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET)
phungductung 0:e87aa4c49e95 3379 {
phungductung 0:e87aa4c49e95 3380 return(SD_ERASE_RESET);
phungductung 0:e87aa4c49e95 3381 }
phungductung 0:e87aa4c49e95 3382
phungductung 0:e87aa4c49e95 3383 if((responseR1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR)
phungductung 0:e87aa4c49e95 3384 {
phungductung 0:e87aa4c49e95 3385 return(SD_AKE_SEQ_ERROR);
phungductung 0:e87aa4c49e95 3386 }
phungductung 0:e87aa4c49e95 3387
phungductung 0:e87aa4c49e95 3388 return errorstate;
phungductung 0:e87aa4c49e95 3389 }
phungductung 0:e87aa4c49e95 3390
phungductung 0:e87aa4c49e95 3391 /**
phungductung 0:e87aa4c49e95 3392 * @}
phungductung 0:e87aa4c49e95 3393 */
phungductung 0:e87aa4c49e95 3394
phungductung 0:e87aa4c49e95 3395 #endif /* HAL_SD_MODULE_ENABLED */
phungductung 0:e87aa4c49e95 3396
phungductung 0:e87aa4c49e95 3397 /**
phungductung 0:e87aa4c49e95 3398 * @}
phungductung 0:e87aa4c49e95 3399 */
phungductung 0:e87aa4c49e95 3400
phungductung 0:e87aa4c49e95 3401 /**
phungductung 0:e87aa4c49e95 3402 * @}
phungductung 0:e87aa4c49e95 3403 */
phungductung 0:e87aa4c49e95 3404
phungductung 0:e87aa4c49e95 3405 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/