L4 HAL Drivers

Committer:
EricLew
Date:
Mon Nov 02 19:37:23 2015 +0000
Revision:
0:80ee8f3b695e
Errors are with definitions of LCD and QSPI functions. I believe all .h and .c files are  uploaded, but there may need to be certain functions called.

Who changed what in which revision?

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